aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--calendar/Makefile20
-rw-r--r--calendar/cal_struct.h14
-rw-r--r--calendar/calcs.c273
-rw-r--r--calendar/calcs.h53
-rw-r--r--calendar/gncal.c449
-rw-r--r--calendar/gncal.h6
-rw-r--r--calendar/gui/cal_struct.h14
-rw-r--r--calendar/lexer.c389
-rw-r--r--calendar/menus.c147
-rw-r--r--calendar/menus.h17
10 files changed, 1382 insertions, 0 deletions
diff --git a/calendar/Makefile b/calendar/Makefile
new file mode 100644
index 0000000000..39c4753d89
--- /dev/null
+++ b/calendar/Makefile
@@ -0,0 +1,20 @@
+CC = gcc
+PROF = -g
+C_FLAGS = -Wall $(PROF) -L/usr/local/include -DDEBUG -I../apps -I../lib
+L_FLAGS = $(PROF) -L/usr/X11R6/lib -L/usr/local/lib
+L_POSTFLAGS = -lgnomeui -lgnome -lgtk -lgdk -lglib -lXext -lX11 -lm
+PROGNAME = gncal
+
+O_FILES = gncal.o menus.o calcs.o
+
+$(PROGNAME): $(O_FILES)
+ rm -f $(PROGNAME)
+ $(CC) $(L_FLAGS) -o $(PROGNAME) $(O_FILES) $(L_POSTFLAGS)
+
+.c.o:
+ $(CC) -c $(C_FLAGS) $<
+
+clean:
+ rm -f core *.o $(PROGNAME) nohup.out
+distclean: clean
+ rm -f *~
diff --git a/calendar/cal_struct.h b/calendar/cal_struct.h
new file mode 100644
index 0000000000..77420cf9ff
--- /dev/null
+++ b/calendar/cal_struct.h
@@ -0,0 +1,14 @@
+struct actionitem {
+ char date[MAX_SZ];
+ char time[MAX_SZ];
+}
+
+struct event {
+ struct actionitem start;
+ struct actionitem end;
+
+ char description[MAX_SZ];
+ char subtype[MAX_SZ];
+ GList *properties;
+}
+
diff --git a/calendar/calcs.c b/calendar/calcs.c
new file mode 100644
index 0000000000..002ffbf28b
--- /dev/null
+++ b/calendar/calcs.c
@@ -0,0 +1,273 @@
+/*
+ * calc.c Calculations to work out what day it is etc for the Calendar
+ *
+ * Most of this stuff was taken from the gcal source by Thomas Esken.
+ * <esken@uni-muenster.de>
+ * gcal is a text-based calendar program
+ */
+
+#include <time.h>
+#include <glib.h>
+#include <ctype.h>
+#include "calcs.h"
+
+/* Number of days in a month */
+static const int dvec[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+/* Number of past days of a month */
+static const int mvec[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
+Greg_struct greg_reform_date[6] = {
+/* {int year, int month, int f_day, int l_day} */
+ { 1582, 10, 5, 14 },
+ { 1700, 2, 19, 28 },
+ { 1752, 9, 3, 13 },
+ { 1753, 2, 18, 28 },
+/* must be left with all zeroes */
+ { 0,0,0,0 }
+};
+Greg_struct *greg=greg_reform_date;
+
+
+
+/*
+ * Computes the number of days in February and returns them,
+ */
+int days_of_february(const int year)
+{
+ return((year&3) ? 28 : (!(year%100)&&(year%400)) ? 28 : 29);
+}
+
+int is_leap_year(const int year)
+{
+ return (days_of_february(year) == 29);
+}
+
+/*
+ * Check wether a given date is calid.
+ */
+int valid_date(const int day, const int month, const int year)
+{
+ if ( day < 1
+ || month < MONTH_MIN
+ || month > MONTH_MAX
+ || ( (month != 2)
+ && (day > dvec[month-1]))
+ || ( (month == 2)
+ && (day > days_of_february (year))))
+ return(FALSE);
+
+ return(TRUE);
+}
+
+/*
+ * Set a date back one day (to yesterday's date)
+ */
+void prev_date(int *day, int *month, int *year)
+{
+ (*day)--;
+ if ( !*day || !valid_date(*day, *month, *year)) {
+ (*month)--;
+ if (*month < MONTH_MIN) {
+ *month = MONTH_MAX;
+ (*year)--;
+ }
+ if (*month ==2)
+ *day = days_of_february(*year);
+ else
+ *day = dvec[*month-1];
+ }
+} /* prev_date */
+
+/*
+ * Set a date forward one day (to tomorrow's date)
+ */
+void next_date(int *day, int *month, int *year)
+{
+ (*day)++;
+ if (!valid_date(*day, *month, *year)) {
+ *day = DAY_MIN;
+ if (*month == MONTH_MAX) {
+ *month = MONTH_MIN;
+ (*year)++;
+ } else
+ (*month)++;
+ }
+} /* next_date */
+
+/*
+ * Get date from the system
+ */
+void get_system_date(int *day, int *month, int *year)
+{
+ auto struct tm *sys_date;
+ auto time_t sys_time;
+
+
+ sys_time = time((time_t *)NULL);
+ sys_date = localtime(&sys_time);
+ *day = sys_date->tm_mday;
+ *month = sys_date->tm_mon + 1;
+ *year = sys_date->tm_year;
+ if (*year < CENTURY)
+ *year += CENTURY;
+} /* get_system_date */
+
+
+/*
+ * Given a string with the name of a month, return 1..12 or 0 if not found
+ */
+int month_atoi(const char *string)
+{
+ int i, j;
+ int len;
+ char *ptr;
+
+ len = strlen(string);
+
+ for(i= MONTH_MIN; i <= MONTH_MAX; i++) {
+ ptr = (char*)month_name(i);
+ j = 0;
+ while ( *(ptr + j) && string[j])
+ if (tolower((ptr+j)) == tolower(string[j]))
+ j++;
+ else
+ break;
+ if (j == len || !*(ptr + j))
+ return(i);
+ }
+ return 0;
+} /* month_atoi */
+
+int day_atoi(const char *string)
+{
+ int i, j;
+ int len;
+ char *ptr;
+
+ len = strlen(string);
+
+ for(i= DAY_MIN; i <= DAY_MAX; i++) {
+ ptr = (char*)day_name(i);
+ j = 0;
+ while ( *(ptr + j) && string[j])
+ if (tolower((ptr+j)) == tolower(string[j]))
+ j++;
+ else
+ break;
+ if (j == len || !*(ptr + j))
+ return(i);
+ }
+ return 0;
+} /* day_atoi */
+
+/*
+ * Returns ordinal suffix (st, nd, rd, th) for a day
+ */
+const char *day_suffix(int day)
+{
+ static const char *suffix[]={"th", "st", "nd", "rd"};
+ register int i;
+
+ i = 0;
+
+ if (day > 100)
+ day %= 100;
+ if (day < 11 || day > 13)
+ i = day % 10;
+ if (i > 3)
+ i = 0;
+
+ return(suffix[i]);
+} /* day_suffix */
+
+/*
+ * Returns the short name of the day of week, format "%-3s"
+ */
+const char *short3_day_name(const int day)
+{
+ static const char *name[]={"invalid day", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
+
+ return(((day<DAY_MIN)||(day>DAY_MAX)) ? name[0] : name[day]);
+} /* short3_day_name */
+
+/*
+ * Returns the short name of day of week
+ */
+const char *short_day_name(const int day)
+{
+ static const char *name[]={"invalid day", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"};
+
+ return(((day<DAY_MIN)||(day>DAY_MAX)) ? name[0] : name[day]);
+} /* short_day_name */
+
+/*
+ * Returns the complete name of the day
+ */
+const char *day_name(const int day)
+{
+ static const char *name[]={"invalid day", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
+
+ return(((day<DAY_MIN)||(day>DAY_MAX)) ? name[0] : name[day]);
+} /* day_name */
+
+/*
+ * Returns the short name of the month
+ */
+const char *short_month_name(const int month)
+{
+ static const char *name[]={ "invalid month", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
+
+ return(((month<MONTH_MIN)||(month>MONTH_MAX)) ? name[0] : name[month]);
+} /* short_month_name() */
+
+/*
+ * Returns the name of the month
+ */
+const char *month_name(const int month)
+{
+ static const char *name[]={ "invalid month", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
+
+ return(((month<MONTH_MIN)||(month>MONTH_MAX)) ? name[0] : name[month]);
+} /* month_name() */
+
+/*
+ * Compute the absolute number of days of the given date since 1 Jan 0001
+ * respecting the missing period of the Gregorian Reformation
+ * I am glad someone else worked this one out!! - cs
+ */
+unsigned long int date2num(const int day, const int month, const int year)
+{
+ auto unsigned long int julian_days;
+
+ julian_days = (unsigned long int)((year-1)*(unsigned long int)(DAY_LAST)+((year-1)>>2));
+
+ if (year > greg->year
+ || ( (year == greg->year)
+ && ( month > greg->month
+ || ( (month == greg->month)
+ && (day > greg->last_day)))))
+ julian_days -= (unsigned long int)(greg->last_day - greg->first_day + 1);
+ if (year > greg->year) {
+ julian_days += (((year-1) / 400) - (greg->year / 400));
+ julian_days -= (((year-1) / 100) - (greg->year / 100));
+ if (!(greg->year % 100) && (greg->year % 400))
+ julian_days--;
+ }
+ julian_days += (unsigned long int)mvec[month-1];
+ julian_days += day;
+ if ( (days_of_february(year) == 29) && (month > 2))
+ julian_days++;
+
+ return(julian_days);
+} /* date2num */
+
+/*
+ * Computes the weekday of a Gregorian/Julian calendar date
+ * (month must be 1..12) returns 1..7 (mo..su)
+ */
+int weekday_of_date(const int day, const int month, const int year)
+{
+ auto unsigned long int julian_days=date2num(day, month,year)%DAY_MAX;
+
+ return((julian_days>2) ? (int)julian_days-2 : (int)julian_days+5);
+} /* weekday_of_date() */
+
diff --git a/calendar/calcs.h b/calendar/calcs.h
new file mode 100644
index 0000000000..e5e6a09b23
--- /dev/null
+++ b/calendar/calcs.h
@@ -0,0 +1,53 @@
+/*
+ * function prototypes
+ */
+int days_of_february(const int year);
+int is_leap_year(const int year);
+int valid_date(const int day, const int month, const int year);
+void get_system_date(int *day, int *month, int *year);
+void prev_date(int *day, int *month, int *year);
+void next_date(int *day, int *month, int *year);
+int month_atoi(const char *string);
+int day_atoi(const char *string);
+const char *day_suffix(int day);
+const char *short3_day_name(int day);
+const char *short_day_name(int day);
+const char *day_name(int day);
+const char *short_month_name(int month);
+const char *month_name(int month);
+unsigned long int date2num(const int day, const int month, const int year);
+int weekday_of_date(const int day, const int month, const int year);
+
+
+/*
+ * Important preprocessor symbols for the internal ranges.
+ */
+#define DAY_LAST 365 /* Last day in a NON leap year */
+#define DAY_MIN 1 /* Minimum day of week/month/year */
+#define DAY_MAX 7 /* Maximum day/amount of days of week */
+#define WEEK_MAX 52 /* Maximum week number of year */
+#define MONTH_LAST 31 /* Highest day number in a month */
+#define MONTH_MIN 1 /* Minimum month of year */
+#define MONTH_MAX 12 /* Maximum month of year */
+#define YEAR_MIN 1 /* Minimum year able to compute */
+#define YEAR_MAX 9999 /* Maximum year able to compute */
+#define EASTER_MIN 30 /* Minimum year for computing Easter Sunday (29+1) */
+#define EASTER_MAX YEAR_MAX /* Maximum year for computing Easter Sunday */
+#define MONTH_COLS 6 /* Maximum number of columns of a month */
+#define VEC_BLOCK 42 /* Maximum number of elements per month (7*6) */
+#define VEC_ELEMS 504 /* Maximum number of elements per year (42*12) */
+#define CENTURY 1900 /* Operating system standard starting century, DON'T change ! */
+
+/*
+* The Gregorian Reformation date record.
+*/
+typedef
+ struct greg_type
+ {
+ int year; /* Year of Gregorian Reformation */
+ int month; /* Month of Gregorian Reformation */
+ int first_day; /* First missing day of Reformation period */
+ int last_day; /* Last missing day of Reformation period */
+ }
+ Greg_struct;
+
diff --git a/calendar/gncal.c b/calendar/gncal.c
new file mode 100644
index 0000000000..09bd007587
--- /dev/null
+++ b/calendar/gncal.c
@@ -0,0 +1,449 @@
+/*
+ * gnlp.c: LPQ/LPR stuff
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include <gnome.h>
+
+#include "gncal.h"
+#include "menus.h"
+#include "calcs.h"
+
+
+#define DAY_ARRAY_MAX 35
+/* The naughty global variables */
+int curr_day, old_day;
+int curr_month, old_month;
+int curr_year, old_year;
+GtkWidget *month_label;
+GtkWidget *year_label;
+GtkWidget *dailylist;
+GtkWidget *calendar_days[DAY_ARRAY_MAX];
+GtkWidget *calendar_buttons[DAY_ARRAY_MAX];
+
+
+
+/* place marker until i get get something better */
+void print_error(char *text)
+{
+ GtkWidget *msgbox;
+ char buf[512];
+
+ if (errno == 0)
+ sprintf(buf, "%s", text);
+ else
+ sprintf(buf, "%s (%s)", text, g_strerror(errno));
+
+ g_warning("%s\n", buf);
+ msgbox = gnome_messagebox_new(buf, "error", "OK", NULL, NULL);
+
+ gtk_widget_show(msgbox);
+}
+
+
+void menu_file_quit(GtkWidget *widget, gpointer data)
+{
+ gtk_exit(0);
+}
+
+void menu_help_about(GtkWidget *widget, gpointer data)
+{
+ GtkWidget *msgbox;
+ msgbox = gnome_messagebox_new("gncal v0.01 by Craig Small <csmall@small.dropbear.id.au>", "info", "OK", NULL, NULL);
+ gtk_widget_show(msgbox);
+}
+
+void dailylist_item_select(GtkWidget *widget, gpointer data)
+{
+ int *x = (int*)data;
+
+ g_print("Selected %d\n", x);
+}
+
+void update_today_list(void)
+{
+ GtkWidget *listitem;
+ GtkWidget *list_hbox;
+ GtkWidget *hour_label;
+ GtkWidget *event_label;
+ char buf[50];
+ int tmphr, tmpmin,i;
+
+}
+
+/*
+ * updates the calendar that appears in the left collumn
+ */
+void update_calendar()
+{
+ int tmpday;
+ int i;
+ char buf[50];
+ int month_changed;
+ static int offset;
+
+ /* Only update the whole calendar if the year or month has changed */
+ tmpday=1;
+ month_changed = FALSE;
+ if (curr_month != old_month || curr_year != old_year) {
+ month_changed = TRUE;
+ offset = weekday_of_date(tmpday, curr_month, curr_year) - 1;
+ }
+
+ for(i=0; i < DAY_ARRAY_MAX; i++) {
+ tmpday = i - offset +1;
+ if (valid_date(tmpday, curr_month, curr_year)) {
+ sprintf(buf, "%2d", tmpday);
+ /*if (month_changed) {*/
+ gtk_label_set(GTK_LABEL(calendar_days[i]), buf);
+ gtk_widget_show(calendar_buttons[i]);
+ /*}*/
+ if (tmpday == curr_day) {
+ gtk_container_border_width(GTK_CONTAINER(calendar_buttons[i]), 2);
+ gtk_widget_show(calendar_buttons[i]);
+ } else {
+ gtk_container_border_width(GTK_CONTAINER(calendar_buttons[i]), 0);
+ }
+ } else if (month_changed) {
+ gtk_label_set(GTK_LABEL(calendar_days[i]), "");
+ gtk_widget_hide(calendar_buttons[i]);
+ gtk_container_border_width(GTK_CONTAINER(calendar_buttons[i]), 0);
+ }
+ } /* for i */
+
+}
+
+/*
+ * Updates all the main window widgets when the current day of interest is
+ * changed
+ */
+void update_today(void)
+{
+ char buf[50];
+
+ /* This needs to be fixed to get the right date order for the country*/
+ if (curr_month != old_month) {
+ gtk_label_set(GTK_LABEL(month_label), month_name(curr_month));
+ }
+ if (curr_year != old_year) {
+ sprintf(buf, "%4d", curr_year);
+ gtk_label_set(GTK_LABEL(year_label), buf);
+ }
+ update_today_list();
+ update_calendar();
+}
+
+void next_day_but_clicked(GtkWidget *widget, gpointer data)
+{
+ old_day = curr_day;
+ old_month = curr_month;
+ old_year = curr_year;
+ next_date(&curr_day, &curr_month, &curr_year);
+ update_today();
+}
+
+void prev_day_but_clicked(GtkWidget *widget, gpointer data)
+{
+ old_day = curr_day;
+ old_month = curr_month;
+ old_year = curr_year;
+ prev_date(&curr_day, &curr_month, &curr_year);
+ update_today();
+}
+
+void today_but_clicked(GtkWidget *widget, gpointer data)
+{
+ old_day = curr_day;
+ old_month = curr_month;
+ old_year = curr_year;
+ get_system_date(&curr_day, &curr_month, &curr_year);
+ update_today();
+}
+
+void prev_month_but_clicked(GtkWidget *widget, gpointer data)
+{
+ if (curr_year == 0 && curr_month == MONTH_MIN)
+ return;
+ old_day = curr_day;
+ old_month = curr_month;
+ old_year = curr_year;
+ curr_month--;
+ if (curr_month < MONTH_MIN) {
+ curr_month = MONTH_MAX;
+ curr_year--;
+ }
+ update_today();
+}
+
+void next_month_but_clicked(GtkWidget *widget, gpointer data)
+{
+ if (curr_year == 3000 && curr_month == MONTH_MAX)
+ return;
+ old_day = curr_day;
+ old_month = curr_month;
+ old_year = curr_year;
+ curr_month++;
+ if (curr_month > MONTH_MAX ) {
+ curr_month = MONTH_MIN;
+ curr_year++;
+ }
+ update_today();
+}
+
+void prev_year_but_clicked(GtkWidget *widget, gpointer data)
+{
+ if (curr_year == 0)
+ return;
+
+ old_day = curr_day;
+ old_month = curr_month;
+ old_year = curr_year;
+ curr_year--;
+ update_today();
+}
+
+
+void next_year_but_clicked(GtkWidget *widget, gpointer data)
+{
+ if (curr_year == 3000)
+ return;
+
+ old_day = curr_day;
+ old_month = curr_month;
+ old_year = curr_year;
+ curr_year++;
+ update_today();
+}
+
+
+void calendar_but_clicked(GtkWidget *widget, gpointer data)
+{
+ char *ptr;
+ int x;
+
+ ptr = GTK_LABEL(GTK_BUTTON(widget)->child)->label;
+ x = atoi(ptr);
+
+ if (valid_date(x, curr_month, curr_year)) {
+ old_day = curr_day;
+ old_month = curr_month;
+ old_year = curr_year;
+ curr_day = x;
+ update_today();
+ }
+}
+
+void test_foreach(GtkWidget *widget, gpointer data)
+{
+ char *ptr;
+
+ ptr = GTK_LABEL(GTK_BUTTON(widget)->child)->label;
+ g_print("%s\n", ptr);
+}
+
+void show_main_window()
+{
+ GtkWidget *window;
+ GtkWidget *main_vbox;
+ GtkWidget *menubar;
+ GtkAcceleratorTable *accel;
+ GtkWidget *main_hbox;
+ GtkWidget *left_vbox;
+ GtkWidget *right_vbox;
+ GtkWidget *date_hbox;
+ GtkWidget *prev_mth_but;
+ GtkWidget *next_mth_but;
+ GtkWidget *prev_year_but;
+ GtkWidget *next_year_but;
+ GtkWidget *day_but_hbox;
+ GtkWidget *prev_day_but;
+ GtkWidget *today_but;
+ GtkWidget *next_day_but;
+ GtkWidget *separator;
+ GtkWidget *cal_table;
+ GtkWidget *day_name_label;
+ GtkWidget *scrolledwindow;
+ GtkWidget *scroll_hbox;
+ GtkWidget *hour_list;
+ GtkWidget *list_item;
+ GtkWidget *dailylist_item;
+ GtkWidget *event_label;
+ int i,j;
+ struct tm tm;
+ char buf[50];
+
+ bzero((char*)&tm, sizeof(struct tm));
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_signal_connect(GTK_OBJECT(window), "destroy",
+ GTK_SIGNAL_FUNC(menu_file_quit), NULL);
+ gtk_window_set_title(GTK_WINDOW(window), "Gnome Calendar");
+ gtk_widget_set_usize(GTK_WIDGET(window), 600, 400);
+
+ main_vbox = gtk_vbox_new(FALSE, 1);
+ gtk_container_add(GTK_CONTAINER(window), main_vbox);
+ gtk_widget_show(main_vbox);
+
+ get_main_menu(&menubar, &accel);
+ gtk_window_add_accelerator_table(GTK_WINDOW(window), accel);
+ gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, FALSE, 0);
+ gtk_widget_show(menubar);
+
+ main_hbox = gtk_hbox_new(FALSE,1);
+ gtk_box_pack_start(GTK_BOX(main_vbox), main_hbox, TRUE, TRUE, 0);
+ gtk_widget_show(main_hbox);
+
+ left_vbox = gtk_vbox_new(FALSE, 1);
+ gtk_box_pack_start(GTK_BOX(main_hbox), left_vbox, FALSE, TRUE,0);
+ gtk_widget_show(left_vbox);
+
+ separator = gtk_vseparator_new();
+ gtk_box_pack_start(GTK_BOX(main_hbox), separator, FALSE, TRUE, 0);
+ gtk_widget_show(separator);
+
+ right_vbox = gtk_vbox_new(FALSE, 1);
+ gtk_box_pack_start(GTK_BOX(main_hbox), right_vbox, TRUE, TRUE, 0);
+ gtk_widget_show(right_vbox);
+
+ date_hbox = gtk_hbox_new(FALSE, 1);
+ gtk_box_pack_start(GTK_BOX(left_vbox), date_hbox, FALSE, FALSE, 0);
+ gtk_widget_show(date_hbox);
+
+ prev_mth_but = gtk_button_new_with_label("<");
+ gtk_box_pack_start(GTK_BOX(date_hbox), prev_mth_but, FALSE, FALSE, 0);
+ gtk_signal_connect(GTK_OBJECT(prev_mth_but), "clicked", GTK_SIGNAL_FUNC(prev_month_but_clicked), NULL);
+ gtk_widget_show(prev_mth_but);
+
+ month_label = gtk_label_new("Fooary");
+ gtk_box_pack_start(GTK_BOX(date_hbox), month_label, TRUE, FALSE, 0);
+ gtk_widget_show(month_label);
+
+ next_mth_but = gtk_button_new_with_label(">");
+ gtk_box_pack_start(GTK_BOX(date_hbox), next_mth_but, FALSE, FALSE, 0);
+ gtk_signal_connect(GTK_OBJECT(next_mth_but), "clicked", GTK_SIGNAL_FUNC(next_month_but_clicked), NULL);
+ gtk_widget_show(next_mth_but);
+
+ prev_year_but = gtk_button_new_with_label("<");
+ gtk_box_pack_start(GTK_BOX(date_hbox), prev_year_but, FALSE, FALSE, 0);
+ gtk_signal_connect(GTK_OBJECT(prev_year_but), "clicked", GTK_SIGNAL_FUNC(prev_year_but_clicked), NULL);
+ gtk_widget_show(prev_year_but);
+
+ year_label = gtk_label_new("1971");
+ gtk_box_pack_start(GTK_BOX(date_hbox), year_label, TRUE, FALSE, 0);
+ gtk_widget_show(year_label);
+
+ next_year_but = gtk_button_new_with_label(">");
+ gtk_box_pack_start(GTK_BOX(date_hbox), next_year_but, FALSE, FALSE, 0);
+ gtk_signal_connect(GTK_OBJECT(next_year_but), "clicked", GTK_SIGNAL_FUNC(next_year_but_clicked), NULL);
+ gtk_widget_show(next_year_but);
+
+ /* Build up the calendar table */
+ cal_table = gtk_table_new(7,7,TRUE);
+ gtk_box_pack_start(GTK_BOX(left_vbox), cal_table, FALSE, FALSE, 0);
+ gtk_widget_show(cal_table);
+
+ for(i=DAY_MIN; i <= DAY_MAX; i++) {
+ day_name_label = gtk_label_new(short3_day_name(i));
+ gtk_table_attach_defaults(GTK_TABLE(cal_table), day_name_label, i-1, i, 0, 1);
+ gtk_widget_show(day_name_label);
+ }
+ for(j=0; j < 5; j++) {
+ for(i=0; i < 7; i++) {
+ calendar_buttons[i+j*7] = gtk_button_new();
+ gtk_container_border_width(GTK_CONTAINER(calendar_buttons[i+j*7]), 0);
+ gtk_table_attach_defaults(GTK_TABLE(cal_table), calendar_buttons[i+j*7], i, i+1, j+2, j+3);
+ gtk_signal_connect(GTK_OBJECT(calendar_buttons[i+j*7]), "clicked", GTK_SIGNAL_FUNC(calendar_but_clicked), NULL);
+ gtk_widget_show(calendar_buttons[i+j*7]);
+ calendar_days[i+j*7] = gtk_label_new("");
+ gtk_container_add(GTK_CONTAINER(calendar_buttons[i+j*7]), calendar_days[i+j*7]);
+ gtk_widget_show(calendar_days[i+j*7]);
+ }
+ }
+
+
+
+
+ day_but_hbox = gtk_hbox_new(TRUE, 1);
+ gtk_box_pack_start(GTK_BOX(left_vbox), day_but_hbox, FALSE, FALSE, 0);
+ gtk_widget_show(day_but_hbox);
+
+ prev_day_but = gtk_button_new_with_label("Prev");
+ gtk_box_pack_start(GTK_BOX(day_but_hbox), prev_day_but, TRUE, TRUE, 0);
+ gtk_signal_connect(GTK_OBJECT(prev_day_but), "clicked", GTK_SIGNAL_FUNC(prev_day_but_clicked), NULL);
+ gtk_widget_show(prev_day_but);
+
+ today_but = gtk_button_new_with_label("Today");
+ gtk_box_pack_start(GTK_BOX(day_but_hbox), today_but, TRUE, TRUE, 0);
+ gtk_signal_connect(GTK_OBJECT(today_but), "clicked", GTK_SIGNAL_FUNC(today_but_clicked), NULL);
+ gtk_widget_show(today_but);
+
+ next_day_but = gtk_button_new_with_label("Next");
+ gtk_box_pack_start(GTK_BOX(day_but_hbox), next_day_but, TRUE, TRUE, 0);
+ gtk_signal_connect(GTK_OBJECT(next_day_but), "clicked", GTK_SIGNAL_FUNC(next_day_but_clicked), NULL);
+ gtk_widget_show(next_day_but);
+
+ scrolledwindow = gtk_scrolled_window_new(NULL, NULL);
+ gtk_box_pack_start(GTK_BOX(right_vbox), scrolledwindow, TRUE, TRUE, 0);
+ gtk_widget_show(scrolledwindow);
+
+ scroll_hbox = gtk_hbox_new(FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(scrolledwindow), scroll_hbox);
+ gtk_widget_show(scroll_hbox);
+
+ hour_list = gtk_list_new();
+ gtk_box_pack_start(GTK_BOX(scroll_hbox), hour_list, FALSE, FALSE, 0);
+ gtk_widget_show(hour_list);
+
+ separator = gtk_vseparator_new();
+ gtk_box_pack_start(GTK_BOX(scroll_hbox), separator, FALSE, FALSE, 0);
+ gtk_widget_show(separator);
+
+ dailylist = gtk_list_new();
+ gtk_box_pack_start(GTK_BOX(scroll_hbox), dailylist, TRUE, TRUE, 0);
+ gtk_widget_show(dailylist);
+
+ for (i=0; i< 24 ; i++) {
+ sprintf(buf, "%d:00", i);
+ list_item = gtk_list_item_new_with_label(buf);
+ gtk_container_add(GTK_CONTAINER(hour_list), list_item);
+ gtk_widget_show(list_item);
+
+ dailylist_item = gtk_list_item_new();
+ gtk_container_add(GTK_CONTAINER(dailylist), dailylist_item);
+ gtk_signal_connect(GTK_OBJECT(dailylist_item), "selected", GTK_SIGNAL_FUNC(dailylist_item_select), list_item);
+ gtk_signal_connect_object(GTK_OBJECT(list_item), "selected", GTK_SIGNAL_FUNC(dailylist_item_select), GTK_OBJECT(dailylist_item));
+ gtk_widget_show(dailylist_item);
+ event_label = gtk_label_new("blah");
+ gtk_container_add(GTK_CONTAINER(dailylist_item), event_label);
+ gtk_widget_show(event_label);
+ }
+ gtk_widget_show(window);
+
+}
+
+
+int main(int argc, char *argv[])
+{
+
+ gnome_init(&argc, &argv);
+
+
+ show_main_window();
+
+ /* Initialse date to the current day */
+ old_day = old_month = old_year = 0;
+ get_system_date(&curr_day, &curr_month, &curr_year);
+ update_today();
+
+ gtk_main();
+
+ return 0;
+}
+
diff --git a/calendar/gncal.h b/calendar/gncal.h
new file mode 100644
index 0000000000..8d4790bf07
--- /dev/null
+++ b/calendar/gncal.h
@@ -0,0 +1,6 @@
+
+void menu_file_quit(GtkWidget *widget, gpointer data);
+#define MIN_DAILY_HOUR 8
+#define MAX_DAILY_HOUR 19
+#define DAILY_MINUTE_STEP 15
+void menu_help_about(GtkWidget *widget, gpointer data); \ No newline at end of file
diff --git a/calendar/gui/cal_struct.h b/calendar/gui/cal_struct.h
new file mode 100644
index 0000000000..77420cf9ff
--- /dev/null
+++ b/calendar/gui/cal_struct.h
@@ -0,0 +1,14 @@
+struct actionitem {
+ char date[MAX_SZ];
+ char time[MAX_SZ];
+}
+
+struct event {
+ struct actionitem start;
+ struct actionitem end;
+
+ char description[MAX_SZ];
+ char subtype[MAX_SZ];
+ GList *properties;
+}
+
diff --git a/calendar/lexer.c b/calendar/lexer.c
new file mode 100644
index 0000000000..264808a75d
--- /dev/null
+++ b/calendar/lexer.c
@@ -0,0 +1,389 @@
+/*
+ * lexer.c: Reads in the .calendar files
+ */
+#include <stdio.h>
+#include <glib.h>
+
+
+#define opener "["
+#define closer "]"
+#define VersionMajor 2
+
+
+int skip_chars(FILE *fp, char *terminator)
+{
+ int c;
+ int cnt;
+
+ cnt = 0;
+ while( (c = fgetc(fp)) != EOF) {
+ if (c == terminator[cnt]) {
+ cnt++;
+ if (terminator[cnt] == '\0')
+ return TRUE;
+ } else
+ cnt = 0;
+ }
+ return FALSE;
+}
+
+int peek_char(FILE *fp, char *c)
+{
+ if ( ((*c) = fgetc(fp)) != EOF) {
+ ungetc((*c), fp);
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+int skip_whitespace(FILE *fp)
+{
+ int c;
+
+ while( (c = fgetc(fp)) != EOF)
+ if (!isspace(c)) {
+ ungetc(c, fp);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int get_until(FILE *fp, char terminator, char *buf)
+{
+ int c;
+
+ while( (c = fgetc(fp)) != EOF) {
+ if (c == terminator)
+ return TRUE;
+ *buf = (char)c;
+ buf++;
+ }
+ return FALSE;
+}
+
+int get_number(FILE *fp, int *x)
+{
+ char buf[50];
+ int c;
+ int cnt;
+
+ cnt = 0;
+ buf[cnt] = '\0';
+ while( (c= fgetc(fp)) != EOF) {
+ if (!isdigit(c)) {
+ ungetc(c, fp);
+ *x = atoi(buf);
+ return TRUE;
+ }
+ buf[cnt++] = (char)c;
+ buf[cnt] = '\0';
+ }
+ *x = atoi(buf);
+ return FALSE;
+}
+
+int get_string(FILE *fp, char *string)
+{
+ int c;
+ int cnt;
+
+ cnt = 0;
+ while ( (c = fgetc(fp)) != EOF) {
+ if (c == closer[0]) {
+ string[cnt] = '\0';
+ ungetc((char)c, fp);
+ return TRUE;
+ }
+ string[cnt++] = (char)c;
+ }
+ return FALSE;
+}
+
+int getid(FILE *fp, char *string)
+{
+ int c;
+ int cnt;
+
+ cnt = 0;
+ while( (c =fgetc(fp)) != EOF) {
+ if (isalnum(c))
+ string[cnt++] = (char)c;
+ else {
+ string[cnt] = '\0';
+ return TRUE;
+ }
+ }
+ string[cnt] = '\0';
+ return FALSE;
+}
+
+int parse_appointment(FILE *fp, char keyword[])
+{
+ char buf[50];
+ int x,y,c;
+
+ if (strcmp(keyword, "Start") == 0) {
+ if ( ! skip_whitespace(fp) || ! get_number(fp, &x) ) {
+ g_error("Unable to get start time");
+ return FALSE;
+ }
+ g_print ("Appointment start = %d\n", x);
+ return TRUE;
+ }
+
+ if (strcmp(keyword, "Length") == 0) {
+ if ( ! skip_whitespace(fp) || ! get_number(fp, &x) ) {
+ g_error("Unable to get length");
+ return FALSE;
+ }
+ g_print ("Appointment length = %d\n", x);
+ return TRUE;
+ }
+
+ if (strcmp(keyword, "Alarms") == 0) {
+ while(TRUE) {
+ skip_whitespace(fp);
+ if (!peek_char(fp, (char*)&c)) {
+ g_error("Cannot read alarm list");
+ return FALSE;
+ }
+ if (!isdigit(c))
+ break;
+
+ if (! get_number(fp, &x))
+ return FALSE;
+
+ g_print("New alarm %d\n", x);
+ }
+ return TRUE;
+ }
+
+ g_print("Unknown keyword %s\n", keyword);
+ return FALSE;
+}
+
+int parse_item(FILE *fp, char keyword[])
+{
+ char buf[50];
+ int x, y, c;
+
+ if (strcmp(keyword, "Remind") == 0) {
+ if (! skip_whitespace(fp) || ! get_number(fp, &x)) {
+ g_error("Cannot get remind level");
+ return FALSE;
+ }
+ g_print("Remind level = %d\n", x);
+ return TRUE;
+ }
+
+ if (strcmp(keyword, "Owner") == 0) {
+ if (!get_string(fp, buf)) {
+ g_error("Cannot get owner information");
+ return FALSE;
+ }
+ g_print("Owner = %s\n", buf);
+ return TRUE;
+ }
+
+ if (strcmp(keyword, "Uid") == 0) {
+ if (!skip_whitespace(fp) || !get_until(fp, *closer, buf)) {
+ g_error("Cannot get unique ID");
+ return FALSE;
+ }
+ g_print("UID = %s\n", buf);
+ return TRUE;
+ }
+
+ if (strcmp(keyword, "Contents") == 0) {
+ if (!get_string(fp, buf)) {
+ g_error("Cannot get item text");
+ return FALSE;
+ }
+ g_print("Contents = %s\n", buf);
+ return TRUE;
+ }
+
+ if (strcmp(keyword, "Text") == 0) {
+ if (! skip_whitespace(fp) || ! get_number(fp, &x) ||
+ (x < 0) || ! skip_whitespace(fp) || ! skip_chars(fp, opener) ) {
+ g_error("Cannot get item text");
+ return FALSE;
+ }
+ y = 0;
+ while(y < x) {
+ if ( (c = fgetc(fp)) == EOF) {
+ g_error("Short item text");
+ return FALSE;
+ }
+ buf[y++] = (char)c;
+ }
+ buf[y] = '\0';
+ g_print("Text = %s\n", buf);
+ return TRUE;
+ }
+
+ if (strcmp(keyword, "Dates") == 0) {
+ if (! get_string(fp, buf)) {
+ g_error("Cannot get date");
+ return FALSE;
+ }
+ g_print("Date = %s\n", buf);
+ return TRUE;
+ }
+
+ if (strcmp(keyword, "Deleted") == 0) {
+ if (! skip_whitespace(fp) || ! get_number(fp, &x)) {
+ g_error("Cannot get deleted day");
+ return FALSE;
+ }
+ g_print("%d/", x);
+ if (! skip_whitespace(fp) || ! get_number(fp, &x)) {
+ g_error("Cannot get deleted month");
+ return FALSE;
+ }
+ g_print("%d/", x);
+ if (! skip_whitespace(fp) || ! get_number(fp, &x)) {
+ g_error("Cannot get deleted year");
+ return FALSE;
+ }
+ g_print("%d\n", x);
+ return TRUE;
+ }
+
+ if (strcmp(keyword, "Hilite") == 0) {
+ if (! get_string(fp, buf) ) {
+ g_error("Cannot get hilite data");
+ return FALSE;
+ }
+ g_print("Hilite = %s\n", buf);
+ return TRUE;
+ }
+
+ if (strcmp(keyword, "Todo") == 0) {
+ g_print("Todo\n");
+ return TRUE;
+ }
+
+
+ if (strcmp(keyword, "Done") == 0) {
+ g_print("Done\n");
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void parse_ical_file(char const *file)
+{
+ FILE *fp;
+ int finished;
+ char keyword[50];
+ int file_major, file_minor;
+ char c;
+ int item_type;
+ int incomplete_item;
+
+
+ if ( (fp = fopen(file, "r")) == NULL) {
+ g_error("couldn't open file");
+ return;
+ }
+
+ finished = FALSE;
+
+ if (!skip_whitespace(fp))
+ return;
+
+ if (! skip_chars(fp, "Calendar") || ! skip_whitespace(fp) ) {
+ g_error("unable to find calendar file");
+ fclose(fp);
+ return;
+ }
+
+ if (! skip_chars(fp, opener) || ! skip_chars(fp, "v") ) {
+ g_error("Unable to get version line");
+ fclose(fp);
+ return;
+ }
+ if (! get_number(fp, &file_major) || ! (file_major >=0) || (file_major > VersionMajor)) {
+ g_error("Missing/bad major version");
+ fclose(fp);
+ return;
+ }
+
+ if (! skip_chars(fp, ".") || ! get_number(fp, &file_minor) ||
+ ! skip_chars(fp, "]") || ! skip_whitespace(fp) ) {
+ g_error("Missing minor version");
+ fclose(fp);
+ return;
+ }
+ if (file_minor > 0) {
+ g_error("Bad minor version");
+ fclose(fp);
+ return;
+ }
+
+ while(TRUE) {
+ g_print("----------------------------------------\n");
+ item_type= 0;
+ skip_whitespace(fp);
+ if (! getid(fp,keyword) || ! skip_whitespace(fp) ||
+ ! skip_chars(fp, opener) || ! skip_whitespace(fp) ) {
+ fclose(fp);
+ return;
+ }
+
+ if (strcmp(keyword, "Appt") == 0) {
+ g_print("New Appointment\n");
+ item_type = 1;
+
+ } else if (strcmp(keyword, "Note") == 0) {
+ g_print("New Note\n");
+ item_type = 2;
+ } else
+ g_print("New ??? (%s)\n", keyword);
+
+ incomplete_item = TRUE;
+ while(incomplete_item) {
+ if (! skip_whitespace(fp) || ! peek_char(fp, &c)) {
+ g_warning("Incomplete item\n");
+ fclose(fp);
+ return;
+ }
+ if (c == closer[0]) {
+ (void)fgetc(fp);
+ g_print("done!\n");
+ incomplete_item = FALSE;
+ break;
+ }
+
+ if (! getid(fp,keyword) || ! skip_whitespace(fp) ||
+ ! skip_chars(fp, opener) ) {
+ g_error("Error reading item property name");
+ fclose(fp);
+ return;
+ }
+ if ( ! parse_item(fp, keyword) && ! parse_appointment(fp, keyword) ) {
+ g_warning("Unable to parse line\n");
+ fclose(fp);
+ return;
+ }
+ if ( ! skip_whitespace(fp) || ! skip_chars(fp, closer)) {
+ g_error("Error reading item property");
+ fclose(fp);
+ return;
+ }
+ } /* while */
+ } /* while */
+}
+
+
+
+
+int main(int argc, char *argv[])
+{
+
+ parse_ical_file("/home/csmall/.calendar");
+ return 0;
+}
+
diff --git a/calendar/menus.c b/calendar/menus.c
new file mode 100644
index 0000000000..1353f5b495
--- /dev/null
+++ b/calendar/menus.c
@@ -0,0 +1,147 @@
+#include <gtk/gtk.h>
+#include <strings.h>
+
+#include "gncal.h"
+
+
+static void menus_remove_accel(GtkWidget * widget, gchar * signal_name, gchar *
+ path);
+static gint menus_install_accel(GtkWidget * widget, gchar * signal_name, gchar
+key, gchar modifiers, gchar * path);
+void menus_init(void);
+void menus_create(GtkMenuEntry * entries, int nmenu_entries);
+
+
+/* this is the GtkMenuEntry structure used to create new menus. The
+ * first member is the menu definition string. The second, the
+ * default accelerator key used to access this menu function with
+ * the keyboard. The third is the callback function to call when
+ * this menu item is selected (by the accelerator key, or with the
+ * mouse.) The member is the data to pass to your callback function.
+ */
+
+static GtkMenuEntry menu_items[] =
+{
+ {"<Main>/File/Quit", "<control>Q", menu_file_quit, NULL},
+ {"<Main>/Help/About", NULL, menu_help_about, NULL},
+
+};
+
+static int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
+
+static int initialize = TRUE;
+static GtkMenuFactory *factory = NULL;
+static GtkMenuFactory *subfactory[1];
+static GHashTable *entry_ht = NULL;
+
+void get_main_menu(GtkWidget ** menubar, GtkAcceleratorTable ** table)
+{
+ if (initialize)
+ menus_init();
+
+ if (menubar)
+ *menubar = subfactory[0]->widget;
+ if (table)
+ *table = subfactory[0]->table;
+}
+
+void menus_init(void)
+{
+ if (initialize) {
+ initialize = FALSE;
+
+ factory = gtk_menu_factory_new(GTK_MENU_FACTORY_MENU_BAR);
+ subfactory[0] = gtk_menu_factory_new(GTK_MENU_FACTORY_MENU_BAR);
+
+ gtk_menu_factory_add_subfactory(factory, subfactory[0], "<Main>");
+ menus_create(menu_items, nmenu_items);
+ }
+}
+
+void menus_create(GtkMenuEntry * entries, int nmenu_entries)
+{
+ char *accelerator;
+ int i;
+
+ if (initialize)
+ menus_init();
+
+ if (entry_ht)
+ for (i = 0; i < nmenu_entries; i++) {
+ accelerator = g_hash_table_lookup(entry_ht, entries[i].path);
+ if (accelerator) {
+ if (accelerator[0] == '\0')
+ entries[i].accelerator = NULL;
+ else
+ entries[i].accelerator = accelerator;
+ }
+ }
+ gtk_menu_factory_add_entries(factory, entries, nmenu_entries);
+
+
+ for (i = 0; i < nmenu_entries; i++)
+ if (entries[i].widget) {
+ gtk_signal_connect(GTK_OBJECT(entries[i].widget), "install_accelerator",
+ (GtkSignalFunc) menus_install_accel,
+ entries[i].path);
+ gtk_signal_connect(GTK_OBJECT(entries[i].widget), "remove_accelerator",
+ (GtkSignalFunc) menus_remove_accel,
+ entries[i].path);
+ }
+}
+
+static gint menus_install_accel(GtkWidget * widget, gchar * signal_name, gchar
+key, gchar modifiers, gchar * path)
+{
+ char accel[64];
+ char *t1, t2[2];
+
+ accel[0] = '\0';
+ if (modifiers & GDK_CONTROL_MASK)
+ strcat(accel, "<control>");
+ if (modifiers & GDK_SHIFT_MASK)
+ strcat(accel, "<shift>");
+ if (modifiers & GDK_MOD1_MASK)
+ strcat(accel, "<alt>");
+
+ t2[0] = key;
+ t2[1] = '\0';
+ strcat(accel, t2);
+
+ if (entry_ht) {
+ t1 = g_hash_table_lookup(entry_ht, path);
+ g_free(t1);
+ } else
+ entry_ht = g_hash_table_new(g_string_hash, g_string_equal);
+
+ g_hash_table_insert(entry_ht, path, g_strdup(accel));
+
+ return TRUE;
+}
+
+static void menus_remove_accel(GtkWidget * widget, gchar * signal_name, gchar *
+ path)
+{
+ char *t;
+
+ if (entry_ht) {
+ t = g_hash_table_lookup(entry_ht, path);
+ g_free(t);
+
+ g_hash_table_insert(entry_ht, path, g_strdup(""));
+ }
+}
+
+void menus_set_sensitive(char *path, int sensitive)
+{
+ GtkMenuPath *menu_path;
+
+ if (initialize)
+ menus_init();
+
+ menu_path = gtk_menu_factory_find(factory, path);
+ if (menu_path)
+ gtk_widget_set_sensitive(menu_path->widget, sensitive);
+ else
+ g_warning("Unable to set sensitivity for menu which doesn't exist: %s", path);
+}
diff --git a/calendar/menus.h b/calendar/menus.h
new file mode 100644
index 0000000000..2cf5ab08e2
--- /dev/null
+++ b/calendar/menus.h
@@ -0,0 +1,17 @@
+#ifndef __MENUS_H__
+#define __MENUS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <gtk/gtk.h>
+
+void get_main_menu (GtkWidget **menubar, GtkAcceleratorTable **table);
+void menus_create(GtkMenuEntry *entries, int nmenu_entries);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __MENUS_H__ */