diff options
-rw-r--r-- | calendar/ChangeLog | 8 | ||||
-rw-r--r-- | calendar/cal-util/calobj.c | 61 | ||||
-rw-r--r-- | calendar/cal-util/calobj.h | 38 | ||||
-rw-r--r-- | calendar/calobj.c | 61 | ||||
-rw-r--r-- | calendar/calobj.h | 38 | ||||
-rw-r--r-- | calendar/eventedit.c | 303 | ||||
-rw-r--r-- | calendar/eventedit.h | 10 | ||||
-rw-r--r-- | calendar/gnome-cal.c | 64 | ||||
-rw-r--r-- | calendar/gnome-cal.h | 9 | ||||
-rw-r--r-- | calendar/gui/eventedit.c | 303 | ||||
-rw-r--r-- | calendar/gui/eventedit.h | 10 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.c | 64 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.h | 9 | ||||
-rw-r--r-- | calendar/gui/main.c | 41 | ||||
-rw-r--r-- | calendar/main.c | 41 | ||||
-rw-r--r-- | calendar/pcs/calobj.c | 61 | ||||
-rw-r--r-- | calendar/pcs/calobj.h | 38 | ||||
-rw-r--r-- | calendar/timeutil.c | 26 | ||||
-rw-r--r-- | calendar/timeutil.h | 5 |
19 files changed, 1001 insertions, 189 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 476871c505..fbd5003dc9 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,11 @@ +1998-04-03 Miguel de Icaza <miguel@nuclecu.unam.mx> + + * calobj.c (ical_object_destroy): Full destruction of the object. + + * eventedit.c: Finished the main event editor form; It still + lacks the details and the recurrence bits. It now adds events + and cancels. + 1998-04-03 Federico Mena Quintero <federico@nuclecu.unam.mx> * view-utils.c (view_utils_draw_events): The "better" format diff --git a/calendar/cal-util/calobj.c b/calendar/cal-util/calobj.c index f405dbe265..004ba7636d 100644 --- a/calendar/cal-util/calobj.c +++ b/calendar/cal-util/calobj.c @@ -24,6 +24,27 @@ ical_object_new (void) return ico; } +static void +default_alarm (iCalObject *ical, CalendarAlarm *alarm, char *def_mail, enum AlarmType type) +{ + alarm->enabled = 0; + alarm->type = type; + + if (type != ALARM_MAIL){ + alarm->count = 15; + alarm->units = ALARM_MINUTES; + } else { + printf ("uno!\n"); + alarm->count = 1; + alarm->units = ALARM_DAYS; + } + + if (type == ALARM_MAIL) + alarm->data = g_strdup (def_mail); + else + alarm->data = g_strdup (""); +} + iCalObject * ical_new (char *comment, char *organizer, char *summary) { @@ -34,18 +55,43 @@ ical_new (char *comment, char *organizer, char *summary) ico->comment = g_strdup (comment); ico->organizer = g_strdup (organizer); ico->summary = g_strdup (summary); + ico->class = g_strdup ("PUBLIC"); + default_alarm (ico, &ico->dalarm, organizer, ALARM_DISPLAY); + default_alarm (ico, &ico->palarm, organizer, ALARM_PROGRAM); + default_alarm (ico, &ico->malarm, organizer, ALARM_MAIL); + default_alarm (ico, &ico->aalarm, organizer, ALARM_AUDIO); + return ico; } -#define free_if_defined(x) if (x){ g_free (x); x = 0; } +static void +list_free (GList *list) +{ + g_list_foreach (list, g_free, 0); + g_list_free (list); +} +#define free_if_defined(x) if (x){ g_free (x); x = 0; } +#define lfree_if_defined(x) if (x){ list_free (x); x = 0; } void ical_object_destroy (iCalObject *ico) { - free_if_defined (ico->comment); - free_if_defined (ico->organizer); - free_if_defined (ico->summary); + /* Regular strings */ + free_if_defined (ico->comment); + free_if_defined (ico->organizer); + free_if_defined (ico->summary); + free_if_defined (ico->uid); + free_if_defined (ico->status); + free_if_defined (ico->class); + free_if_defined (ico->url); + + /* Lists */ + lfree_if_defined (ico->exdate); + lfree_if_defined (ico->categories); + lfree_if_defined (ico->resources); + lfree_if_defined (ico->related); + lfree_if_defined (ico->attach); g_free (ico); } @@ -83,6 +129,7 @@ ical_object_create_from_vobject (VObject *o, const char *object_name) ical->type = ICAL_TODO; else return 0; + /* uid */ if (has (o, VCUniqueStringProp)) ical->uid = g_strdup (str_val (vo)); @@ -123,9 +170,9 @@ ical_object_create_from_vobject (VObject *o, const char *object_name) if (has (o, VCExpDateProp)) ical->exdate = set_list (str_val (vo), ","); - /* description */ + /* description/comment */ if (has (o, VCDescriptionProp)) - ical->description = g_strdup (str_val (vo)); + ical->comment = g_strdup (str_val (vo)); /* summary */ if (has (o, VCSummaryProp)) @@ -142,7 +189,7 @@ ical_object_create_from_vobject (VObject *o, const char *object_name) if (has (o, VCClassProp)) ical->class = g_strdup (str_val (vo)); else - ical->status = g_strdup ("PUBLIC"); + ical->class = "PUBLIC"; /* categories */ if (has (o, VCCategoriesProp)) diff --git a/calendar/cal-util/calobj.h b/calendar/cal-util/calobj.h index b16fe5f850..00dbd5c63e 100644 --- a/calendar/cal-util/calobj.h +++ b/calendar/cal-util/calobj.h @@ -12,11 +12,32 @@ BEGIN_GNOME_DECLS +enum AlarmType { + ALARM_MAIL, + ALARM_PROGRAM, + ALARM_DISPLAY, + ALARM_AUDIO +}; + +enum AlarmUnit { + ALARM_MINUTES, + ALARM_HOURS, + ALARM_DAYS +}; + typedef struct { - char *alarm_audio_file; - char *alarm_script; - char *alarm_email; - char *alarm_text; /* Text to be displayed */ + enum AlarmType type; + int enabled; + int count; + enum AlarmUnit units; + char *data; + + /* Widgets */ + void *w_count; /* A GtkEntry */ + void *w_enabled; /* A GtkChecButton */ + void *w_timesel; /* A GtkMenu */ + void *w_entry; /* A GnomeEntryFile/GtkEntry for PROGRAM/MAIL */ + void *w_label; } CalendarAlarm; /* Calendar object type */ @@ -65,7 +86,6 @@ typedef struct { time_t completed; time_t created; GList *contact; /* type: one or more TEXT */ - char *description; time_t dtstamp; time_t dtstart; time_t dtend; @@ -90,10 +110,10 @@ typedef struct { char *url; time_t recurid; - CalendarAlarm *dalarm; - CalendarAlarm *aalarm; - CalendarAlarm *palarm; - CalendarAlarm *malarm; + CalendarAlarm dalarm; + CalendarAlarm aalarm; + CalendarAlarm palarm; + CalendarAlarm malarm; } iCalObject; iCalObject *ical_new (char *comment, char *organizer, char *summary); diff --git a/calendar/calobj.c b/calendar/calobj.c index f405dbe265..004ba7636d 100644 --- a/calendar/calobj.c +++ b/calendar/calobj.c @@ -24,6 +24,27 @@ ical_object_new (void) return ico; } +static void +default_alarm (iCalObject *ical, CalendarAlarm *alarm, char *def_mail, enum AlarmType type) +{ + alarm->enabled = 0; + alarm->type = type; + + if (type != ALARM_MAIL){ + alarm->count = 15; + alarm->units = ALARM_MINUTES; + } else { + printf ("uno!\n"); + alarm->count = 1; + alarm->units = ALARM_DAYS; + } + + if (type == ALARM_MAIL) + alarm->data = g_strdup (def_mail); + else + alarm->data = g_strdup (""); +} + iCalObject * ical_new (char *comment, char *organizer, char *summary) { @@ -34,18 +55,43 @@ ical_new (char *comment, char *organizer, char *summary) ico->comment = g_strdup (comment); ico->organizer = g_strdup (organizer); ico->summary = g_strdup (summary); + ico->class = g_strdup ("PUBLIC"); + default_alarm (ico, &ico->dalarm, organizer, ALARM_DISPLAY); + default_alarm (ico, &ico->palarm, organizer, ALARM_PROGRAM); + default_alarm (ico, &ico->malarm, organizer, ALARM_MAIL); + default_alarm (ico, &ico->aalarm, organizer, ALARM_AUDIO); + return ico; } -#define free_if_defined(x) if (x){ g_free (x); x = 0; } +static void +list_free (GList *list) +{ + g_list_foreach (list, g_free, 0); + g_list_free (list); +} +#define free_if_defined(x) if (x){ g_free (x); x = 0; } +#define lfree_if_defined(x) if (x){ list_free (x); x = 0; } void ical_object_destroy (iCalObject *ico) { - free_if_defined (ico->comment); - free_if_defined (ico->organizer); - free_if_defined (ico->summary); + /* Regular strings */ + free_if_defined (ico->comment); + free_if_defined (ico->organizer); + free_if_defined (ico->summary); + free_if_defined (ico->uid); + free_if_defined (ico->status); + free_if_defined (ico->class); + free_if_defined (ico->url); + + /* Lists */ + lfree_if_defined (ico->exdate); + lfree_if_defined (ico->categories); + lfree_if_defined (ico->resources); + lfree_if_defined (ico->related); + lfree_if_defined (ico->attach); g_free (ico); } @@ -83,6 +129,7 @@ ical_object_create_from_vobject (VObject *o, const char *object_name) ical->type = ICAL_TODO; else return 0; + /* uid */ if (has (o, VCUniqueStringProp)) ical->uid = g_strdup (str_val (vo)); @@ -123,9 +170,9 @@ ical_object_create_from_vobject (VObject *o, const char *object_name) if (has (o, VCExpDateProp)) ical->exdate = set_list (str_val (vo), ","); - /* description */ + /* description/comment */ if (has (o, VCDescriptionProp)) - ical->description = g_strdup (str_val (vo)); + ical->comment = g_strdup (str_val (vo)); /* summary */ if (has (o, VCSummaryProp)) @@ -142,7 +189,7 @@ ical_object_create_from_vobject (VObject *o, const char *object_name) if (has (o, VCClassProp)) ical->class = g_strdup (str_val (vo)); else - ical->status = g_strdup ("PUBLIC"); + ical->class = "PUBLIC"; /* categories */ if (has (o, VCCategoriesProp)) diff --git a/calendar/calobj.h b/calendar/calobj.h index b16fe5f850..00dbd5c63e 100644 --- a/calendar/calobj.h +++ b/calendar/calobj.h @@ -12,11 +12,32 @@ BEGIN_GNOME_DECLS +enum AlarmType { + ALARM_MAIL, + ALARM_PROGRAM, + ALARM_DISPLAY, + ALARM_AUDIO +}; + +enum AlarmUnit { + ALARM_MINUTES, + ALARM_HOURS, + ALARM_DAYS +}; + typedef struct { - char *alarm_audio_file; - char *alarm_script; - char *alarm_email; - char *alarm_text; /* Text to be displayed */ + enum AlarmType type; + int enabled; + int count; + enum AlarmUnit units; + char *data; + + /* Widgets */ + void *w_count; /* A GtkEntry */ + void *w_enabled; /* A GtkChecButton */ + void *w_timesel; /* A GtkMenu */ + void *w_entry; /* A GnomeEntryFile/GtkEntry for PROGRAM/MAIL */ + void *w_label; } CalendarAlarm; /* Calendar object type */ @@ -65,7 +86,6 @@ typedef struct { time_t completed; time_t created; GList *contact; /* type: one or more TEXT */ - char *description; time_t dtstamp; time_t dtstart; time_t dtend; @@ -90,10 +110,10 @@ typedef struct { char *url; time_t recurid; - CalendarAlarm *dalarm; - CalendarAlarm *aalarm; - CalendarAlarm *palarm; - CalendarAlarm *malarm; + CalendarAlarm dalarm; + CalendarAlarm aalarm; + CalendarAlarm palarm; + CalendarAlarm malarm; } iCalObject; iCalObject *ical_new (char *comment, char *organizer, char *summary); diff --git a/calendar/eventedit.c b/calendar/eventedit.c index ba821e1d41..1a63bd60f5 100644 --- a/calendar/eventedit.c +++ b/calendar/eventedit.c @@ -7,12 +7,16 @@ #include <gnome.h> #include "calendar.h" +#include "gnome-cal.h" #include "eventedit.h" #include "main.h" static void event_editor_init (EventEditor *ee); GtkWindow *parent_class; +/* Note: do not i18n these strings, they are part of the vCalendar protocol */ +char *class_names [] = { "PUBLIC", "PRIVATE", "CONFIDENTIAL" }; + guint event_editor_get_type (void) { @@ -59,77 +63,191 @@ adjust (GtkWidget *w, gfloat x, gfloat y, gfloat xs, gfloat ys) return a; } +/* + * Checks if the day range occupies all the day, and if so, check the + * box accordingly + */ +static void +ee_check_all_day (EventEditor *ee) +{ + time_t ev_start, ev_end; + + ev_start = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->start_time)); + ev_end = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->end_time)); + + if (get_time_t_hour (ev_start) <= day_begin && get_time_t_hour (ev_end) >= day_end){ + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (ee->general_allday), 1); + } else{ + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (ee->general_allday), 0); + } +} + +/* + * Callback: checks if the selected hour range spans all of the day + */ +static void +check_times (GtkWidget *widget, EventEditor *ee) +{ + ee_check_all_day (ee); +} + +/* + * Callback: all day event box clicked + */ +static void +set_all_day (GtkToggleButton *toggle, EventEditor *ee) +{ + struct tm *tm; + time_t start_t; + + start_t = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->start_time)); + tm = localtime (&start_t); + tm->tm_hour = day_begin; + tm->tm_min = 0; + tm->tm_sec = 0; + gnome_date_edit_set_time (GNOME_DATE_EDIT (ee->start_time), mktime (tm)); + + if (toggle->active) + tm->tm_hour = day_end; + else + tm->tm_hour++; + + gnome_date_edit_set_time (GNOME_DATE_EDIT (ee->end_time), mktime (tm)); +} + static GtkWidget * event_editor_setup_time_frame (EventEditor *ee) { GtkWidget *frame; - GtkWidget *start_time, *end_time, *allday, *recur; + GtkWidget *start_time, *end_time; GtkTable *t; frame = gtk_frame_new (_("Time")); t = GTK_TABLE (ee->general_time_table = gtk_table_new (1, 1, 0)); gtk_container_add (GTK_CONTAINER (frame), ee->general_time_table); - + + /* 1. Start time */ ee->start_time = start_time = gnome_date_edit_new (ee->ical->dtstart); - ee->end_time = end_time = gnome_date_edit_new (ee->ical->dtend); gnome_date_edit_set_popup_range ((GnomeDateEdit *) start_time, day_begin, day_end); - gnome_date_edit_set_popup_range ((GnomeDateEdit *) end_time, day_begin, day_end); gtk_signal_connect (GTK_OBJECT (start_time), "time_changed", GTK_SIGNAL_FUNC (adjust_end_time), ee); + gtk_signal_connect (GTK_OBJECT (start_time), "time_changed", + GTK_SIGNAL_FUNC (check_times), ee); gtk_table_attach (t, gtk_label_new (_("Start time")), 1, 2, 1, 2, 0, 0, 0, 0); - gtk_table_attach (t, gtk_label_new (_("End time")), 1, 2, 2, 3, 0, 0, 0, 0); - gtk_table_attach (t, start_time, 2, 3, 1, 2, GTK_EXPAND | GTK_FILL, 0, 0, 0); + + /* 2. End time */ + ee->end_time = end_time = gnome_date_edit_new (ee->ical->dtend); + gnome_date_edit_set_popup_range ((GnomeDateEdit *) end_time, day_begin, day_end); + gtk_signal_connect (GTK_OBJECT (end_time), "time_changed", + GTK_SIGNAL_FUNC (check_times), ee); + gtk_table_attach (t, gtk_label_new (_("End time")), 1, 2, 2, 3, 0, 0, 0, 0); gtk_table_attach (t, end_time, 2, 3, 2, 3, GTK_EXPAND | GTK_FILL, 0, 0, 0); - allday = gtk_check_button_new_with_label (_("All day event")); - gtk_table_attach (t, allday, 3, 4, 1, 2, 0, 0, 0, 0); + /* 3. All day checkbox */ + ee->general_allday = gtk_check_button_new_with_label (_("All day event")); + gtk_signal_connect (GTK_OBJECT (ee->general_allday), "toggled", + GTK_SIGNAL_FUNC (set_all_day), ee); + gtk_table_attach (t, ee->general_allday, 3, 4, 1, 2, 0, 0, 0, 0); + ee_check_all_day (ee); - recur = gtk_check_button_new_with_label (_("Recurring event")); - gtk_table_attach (t, recur, 3, 4, 2, 3, 0, 0, 0, 0); + /* 4. Recurring event checkbox */ + ee->general_recur = gtk_check_button_new_with_label (_("Recurring event")); + gtk_table_attach (t, ee->general_recur, 3, 4, 2, 3, 0, 0, 0, 0); gtk_container_border_width (GTK_CONTAINER (frame), 5); return frame; } -enum { - ALARM_MAIL, - ALARM_PROGRAM, - ALARM_DISPLAY, - ALARM_AUDIO -}; +static GtkWidget * +timesel_new (void) +{ + GtkWidget *menu, *option_menu; + char *items [] = { N_("Minutes"), N_("Hours"), N_("Days") }; + int i; + + option_menu = gtk_option_menu_new (); + menu = gtk_menu_new (); + for (i = 0; i < 3; i++){ + GtkWidget *item; + + item = gtk_menu_item_new_with_label (_(items [i])); + gtk_menu_append (GTK_MENU (menu), item); + gtk_widget_show (item); + } + gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu); + return option_menu; +} + +/* + * Set the sensitive state depending on whether the alarm enabled flag. + */ +static void +ee_alarm_setting (CalendarAlarm *alarm, int sensitive) +{ + gtk_widget_set_sensitive (GTK_WIDGET (alarm->w_count), sensitive); + gtk_widget_set_sensitive (GTK_WIDGET (alarm->w_timesel), sensitive); + + if (alarm->type == ALARM_PROGRAM || alarm->type == ALARM_MAIL){ + gtk_widget_set_sensitive (GTK_WIDGET (alarm->w_entry), sensitive); + gtk_widget_set_sensitive (GTK_WIDGET (alarm->w_label), sensitive); + } +} + +static void +alarm_toggle (GtkToggleButton *toggle, CalendarAlarm *alarm) +{ + ee_alarm_setting (alarm, toggle->active); +} #define FX GTK_FILL | GTK_EXPAND #define XCOL 6 static GtkWidget * -ee_create_ae (GtkTable *table, char *str, CalendarAlarm **alarm, int type, int y) +ee_create_ae (GtkTable *table, char *str, CalendarAlarm *alarm, enum AlarmType type, int y) { - GtkWidget *label, *entry; + GtkWidget *timesel; + char buffer [40]; - label = gtk_check_button_new_with_label (str); - gtk_table_attach (table, label, 2, 3, y, y+1, FX, 0, 0, 0); - - entry = gtk_entry_new (); - gtk_widget_set_usize (entry, 40, 0); - gtk_table_attach (table, entry, 3, 4, y, y+1, FX, 0, 5, 0); + alarm->w_enabled = gtk_check_button_new_with_label (str); + gtk_signal_connect (GTK_OBJECT (alarm->w_enabled), "toggled", + GTK_SIGNAL_FUNC (alarm_toggle), alarm); + gtk_table_attach (table, alarm->w_enabled, 2, 3, y, y+1, FX, 0, 0, 0); + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (alarm->w_enabled), alarm->enabled); + + alarm->w_count = gtk_entry_new (); + gtk_widget_set_usize (alarm->w_count, 40, 0); + gtk_table_attach (table, alarm->w_count, 3, 4, y, y+1, FX, 0, 5, 0); + sprintf (buffer, "%d", alarm->count); + gtk_entry_set_text (GTK_ENTRY (alarm->w_count), buffer); + + alarm->w_timesel = timesel_new (); + gtk_option_menu_set_history (GTK_OPTION_MENU (alarm->w_timesel), alarm->units); + gtk_table_attach (table, alarm->w_timesel, 4, 5, y, y+1, 0, 0, 0, 0); + switch (type){ case ALARM_MAIL: - label = gtk_label_new (_("Mail to:")); - gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); - gtk_table_attach (table, label, XCOL, XCOL+1, y, y+1, FX, 0, 5, 0); - entry = gtk_entry_new (); - gtk_table_attach (table, entry, XCOL+1, XCOL+2, y, y+1, FX, 0, 6, 0); + alarm->w_label = gtk_label_new (_("Mail to:")); + gtk_misc_set_alignment (GTK_MISC (alarm->w_label), 1.0, 0.5); + gtk_table_attach (table, alarm->w_label, XCOL, XCOL+1, y, y+1, FX, 0, 5, 0); + alarm->w_entry = gtk_entry_new (); + gtk_table_attach (table, alarm->w_entry, XCOL+1, XCOL+2, y, y+1, FX, 0, 6, 0); + gtk_entry_set_text (GTK_ENTRY (alarm->w_entry), alarm->data); break; case ALARM_PROGRAM: - label = gtk_label_new (_("Run program:")); - gtk_table_attach (table, label, XCOL, XCOL+1, y, y+1, FX, 0, 5, 0); - entry = gnome_file_entry_new ("alarm-program", _("Select program to run at alarm time")); - gtk_table_attach (table, entry, XCOL+1, XCOL+2, y, y+1, 0, 0, 6, 0); + alarm->w_label = gtk_label_new (_("Run program:")); + gtk_misc_set_alignment (GTK_MISC (alarm->w_label), 1.0, 0.5); + gtk_table_attach (table, alarm->w_label, XCOL, XCOL+1, y, y+1, FX, 0, 5, 0); + alarm->w_entry = gnome_file_entry_new ("alarm-program", _("Select program to run at alarm time")); + gtk_table_attach (table, alarm->w_entry, XCOL+1, XCOL+2, y, y+1, 0, 0, 6, 0); break; + + default: + /* Nothing */ } - + + ee_alarm_setting (alarm, alarm->enabled); } static GtkWidget * @@ -137,7 +255,7 @@ ee_alarm_widgets (EventEditor *ee) { GtkWidget *table, *aalarm, *dalarm, *palarm, *malarm, *mailto, *mailte, *l; - l = gtk_frame_new (_("Alarm")); + l = gtk_frame_new (_("Alarms")); table = gtk_table_new (1, 1, 0); gtk_table_set_row_spacings (GTK_TABLE (table), 3); @@ -147,13 +265,19 @@ ee_alarm_widgets (EventEditor *ee) mailte = gtk_entry_new (); ee_create_ae (GTK_TABLE (table), _("Display"), &ee->ical->dalarm, ALARM_DISPLAY, 1); - ee_create_ae (GTK_TABLE (table), _("Audio"), &ee->ical->dalarm, ALARM_AUDIO, 2); - ee_create_ae (GTK_TABLE (table), _("Program"), &ee->ical->dalarm, ALARM_PROGRAM, 3); - ee_create_ae (GTK_TABLE (table), _("Mail"), &ee->ical->dalarm, ALARM_MAIL, 4); + ee_create_ae (GTK_TABLE (table), _("Audio"), &ee->ical->aalarm, ALARM_AUDIO, 2); + ee_create_ae (GTK_TABLE (table), _("Program"), &ee->ical->palarm, ALARM_PROGRAM, 3); + ee_create_ae (GTK_TABLE (table), _("Mail"), &ee->ical->malarm, ALARM_MAIL, 4); return l; } +static void +connect_and_pack (EventEditor *ee, GtkWidget *hbox, GtkWidget *toggle, char *value) +{ + gtk_box_pack_start_defaults (GTK_BOX (hbox), toggle); +} + static GtkWidget * ee_classification_widgets (EventEditor *ee) { @@ -167,22 +291,110 @@ ee_classification_widgets (EventEditor *ee) rpub = gtk_radio_button_new_with_label (NULL, _("Public")); rpriv = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (rpub), _("Private")); conf = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (rpub), _("Confidential")); - - gtk_box_pack_start_defaults (GTK_BOX (hbox), rpub); - gtk_box_pack_start_defaults (GTK_BOX (hbox), rpriv); - gtk_box_pack_start_defaults (GTK_BOX (hbox), conf); + + connect_and_pack (ee, hbox, rpub, class_names [0]); + connect_and_pack (ee, hbox, rpriv, class_names [1]); + connect_and_pack (ee, hbox, conf, class_names [2]); + ee->general_radios = rpub; return frame; } +/* + * Retrieves the information from the CalendarAlarm widgets and stores them + * on the CalendarAlarm generic values + */ +ee_store_alarm (CalendarAlarm *alarm, enum AlarmType type) +{ + GtkWidget *item; + GtkMenu *menu; + GList *child; + int idx; + + if (alarm->data){ + g_free (alarm->data); + alarm->data = 0; + } + + alarm->enabled = GTK_TOGGLE_BUTTON (alarm->w_enabled)->active; + + if (!alarm->enabled) + return; + + if (type == ALARM_PROGRAM) + alarm->data = g_strdup (gtk_entry_get_text (GTK_ENTRY (gnome_file_entry_gtk_entry (alarm->w_entry)))); + if (type == ALARM_MAIL) + alarm->data = g_strdup (gtk_entry_get_text (GTK_ENTRY (alarm->w_entry))); + + /* Find out the index */ + menu = GTK_MENU (GTK_OPTION_MENU (alarm->w_timesel)->menu); + + item = gtk_menu_get_active (menu); + + for (idx = 0, child = menu->children; child->data != item; child = child->next) + idx++; + + alarm->units = idx; + alarm->count = atoi (gtk_entry_get_text (GTK_ENTRY (alarm->w_count))); +} + +/* + * Retrieves all of the information from the different widgets and updates + * the iCalObject accordingly. + */ +static void +ee_store_dlg_values_to_ical (EventEditor *ee) +{ + GtkRadioButton *radio = GTK_RADIO_BUTTON (ee->general_radios); + iCalObject *ical = ee->ical; + GSList *list = radio->group; + int idx; + time_t now; + + now = time (NULL); + ical->dtstart = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->start_time)); + ical->dtend = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->end_time)); + + ee_store_alarm (&ical->dalarm, ALARM_DISPLAY); + ee_store_alarm (&ical->aalarm, ALARM_AUDIO); + ee_store_alarm (&ical->palarm, ALARM_PROGRAM); + ee_store_alarm (&ical->malarm, ALARM_MAIL); + + for (idx = 0; list; list = list->next){ + if (GTK_TOGGLE_BUTTON (list->data)->active) + break; + idx++; + } + g_free (ical->class); + ical->class = g_strdup (class_names [idx]); + + /* FIXME: This is not entirely correct; we should check if the values actually changed */ + ical->last_mod = now; + + if (ee->new_ical) + ical->created = now; + + g_free (ical->summary); + ical->summary = gtk_editable_get_chars (GTK_EDITABLE (ee->general_summary), 0, -1); +} + static void ee_ok (GtkWidget *widget, EventEditor *ee) { + ee_store_dlg_values_to_ical (ee); + + if (ee->new_ical) + gnome_calendar_add_object (GNOME_CALENDAR (ee->gnome_cal), ee->ical); + + gtk_widget_destroy (GTK_WIDGET (ee)); } static void ee_cancel (GtkWidget *widget, EventEditor *ee) { + if (ee->new_ical) + ical_object_destroy (ee->ical); + gtk_widget_destroy (GTK_WIDGET (ee)); } static GtkWidget * @@ -210,8 +422,7 @@ static void ee_fill_summary (GtkWidget *widget, EventEditor *ee) { int pos = 0; - - gtk_text_freeze (GTK_TEXT (ee->general_summary)); + gtk_editable_insert_text (GTK_EDITABLE (ee->general_summary), ee->ical->summary, strlen (ee->ical->summary), &pos); gtk_text_thaw (GTK_TEXT (ee->general_summary)); @@ -257,6 +468,7 @@ event_editor_init_widgets (EventEditor *ee) 1, LABEL_SPAN, DESC_LINE, DESC_LINE + 1, GTK_FILL|GTK_EXPAND, 0, 0, 0); ee->general_summary = gtk_text_new (NULL, NULL); + gtk_text_freeze (GTK_TEXT (ee->general_summary)); gtk_signal_connect (GTK_OBJECT (ee->general_summary), "realize", GTK_SIGNAL_FUNC (ee_fill_summary), ee); gtk_widget_set_usize (ee->general_summary, 0, 60); @@ -297,7 +509,7 @@ event_editor_init (EventEditor *ee) } GtkWidget * -event_editor_new (iCalObject *ical) +event_editor_new (GnomeCalendar *gcal, iCalObject *ical) { GtkWidget *retval; EventEditor *ee; @@ -312,6 +524,7 @@ event_editor_new (iCalObject *ical) ee->new_ical = 0; ee->ical = ical; + ee->gnome_cal = gcal; event_editor_init_widgets (ee); return retval; diff --git a/calendar/eventedit.h b/calendar/eventedit.h index 85b5b86790..e726270877 100644 --- a/calendar/eventedit.h +++ b/calendar/eventedit.h @@ -23,20 +23,26 @@ typedef struct { GtkWidget *general; GtkTable *general_table; GtkWidget *general_time_table; + GtkWidget *general_allday; + GtkWidget *general_recur; GtkWidget *general_owner; GtkWidget *general_summary; GtkWidget *start_time, *end_time; - + GtkWidget *general_radios; + /* The associated ical object */ iCalObject *ical; int new_ical; + + /* The calendar owner of this event */ + GnomeCalendar *gnome_cal; } EventEditor; typedef struct { GnomePropertyBoxClass parent_class; } EventEditorClass; -GtkWidget *event_editor_new (iCalObject *); +GtkWidget *event_editor_new (GnomeCalendar *owner, iCalObject *); END_GNOME_DECLS #endif diff --git a/calendar/gnome-cal.c b/calendar/gnome-cal.c index 7fa7a5e40d..4c0806357d 100644 --- a/calendar/gnome-cal.c +++ b/calendar/gnome-cal.c @@ -39,18 +39,17 @@ gnome_calendar_get_type (void) static void setup_widgets (GnomeCalendar *gcal) { - GtkWidget *notebook; - GtkWidget *day_view, *year_view, *task_view; time_t now; now = time (NULL); - notebook = gtk_notebook_new (); - day_view = day_view_create (gcal); + gcal->notebook = gtk_notebook_new (); + gcal->day_view = day_view_create (gcal); gcal->week_view = gncal_week_view_new (gcal, now); - year_view = year_view_create (gcal); - task_view = tasks_create (gcal); + gcal->year_view = year_view_create (gcal); + gcal->task_view = tasks_create (gcal); + if (0) { struct tm tm; time_t a, b; @@ -66,17 +65,17 @@ setup_widgets (GnomeCalendar *gcal) b = mktime (&tm); - day_view = gncal_full_day_new (gcal, a, b); + gcal->day_view = gncal_full_day_new (gcal, a, b); } - gtk_notebook_append_page (GTK_NOTEBOOK (notebook), day_view, gtk_label_new (_("Day View"))); - gtk_notebook_append_page (GTK_NOTEBOOK (notebook), gcal->week_view, gtk_label_new (_("Week View"))); - gtk_notebook_append_page (GTK_NOTEBOOK (notebook), year_view, gtk_label_new (_("Year View"))); - gtk_notebook_append_page (GTK_NOTEBOOK (notebook), task_view, gtk_label_new (_("Todo"))); + gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->day_view, gtk_label_new (_("Day View"))); + gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->week_view, gtk_label_new (_("Week View"))); + gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->year_view, gtk_label_new (_("Year View"))); + gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->task_view, gtk_label_new (_("Todo"))); - gtk_widget_show_all (notebook); + gtk_widget_show_all (gcal->notebook); - gnome_app_set_contents (GNOME_APP (gcal), notebook); + gnome_app_set_contents (GNOME_APP (gcal), gcal->notebook); } @@ -88,6 +87,29 @@ gnome_calendar_init(GnomeCalendar *gcal) setup_widgets (gcal); } +static GtkWidget * +get_current_page (GnomeCalendar *gcal) +{ + return GTK_NOTEBOOK (gcal->notebook)->cur_page->child; +} + +GtkWidget * +gnome_calendar_next (GnomeCalendar *gcal) +{ + GtkWidget *cp = get_current_page (gcal); + time_t new_time; + + if (cp == gcal->week_view) + new_time = time_add_week (gcal->current_display, 1); + else if (cp == gcal->day_view) + new_time = time_add_day (gcal->current_display, 1); + else if (cp == gcal->year_view) + new_time = time_add_year (gcal->current_display, 1); + else + g_warning ("Weee! Where did the penguin go?"); + +} + GtkWidget * gnome_calendar_new (char *title) { @@ -104,13 +126,27 @@ gnome_calendar_new (char *title) gtk_window_set_title(GTK_WINDOW(retval), title); + gcal->current_display = time (NULL); gcal->cal = calendar_new (title); return retval; } void +gnome_calendar_update_all (GnomeCalendar *cal) +{ + gncal_week_view_update (GNCAL_WEEK_VIEW (cal->week_view)); +} + +void gnome_calendar_load (GnomeCalendar *gcal, char *file) { calendar_load (gcal->cal, file); - gncal_week_view_update (GNCAL_WEEK_VIEW (gcal->week_view)); + gnome_calendar_update_all (gcal); +} + +void +gnome_calendar_add_object (GnomeCalendar *gcal, iCalObject *obj) +{ + calendar_add_object (gcal->cal, obj); + gnome_calendar_update_all (gcal); } diff --git a/calendar/gnome-cal.h b/calendar/gnome-cal.h index 8a93d18450..8168c26ec8 100644 --- a/calendar/gnome-cal.h +++ b/calendar/gnome-cal.h @@ -20,7 +20,14 @@ BEGIN_GNOME_DECLS typedef struct { GnomeApp gnome_app; Calendar *cal; + + time_t current_display; + + GtkWidget *notebook; GtkWidget *week_view; + GtkWidget *day_view; + GtkWidget *year_view; + GtkWidget *task_view; void *event_editor; } GnomeCalendar; @@ -31,7 +38,7 @@ typedef struct { guint gnome_calendar_get_type (void); GtkWidget *gnome_calendar_new (char *title); void gnome_calendar_load (GnomeCalendar *gcal, char *file); - +void gnome_calendar_add_object (GnomeCalendar *gcal, iCalObject *obj); END_GNOME_DECLS #endif diff --git a/calendar/gui/eventedit.c b/calendar/gui/eventedit.c index ba821e1d41..1a63bd60f5 100644 --- a/calendar/gui/eventedit.c +++ b/calendar/gui/eventedit.c @@ -7,12 +7,16 @@ #include <gnome.h> #include "calendar.h" +#include "gnome-cal.h" #include "eventedit.h" #include "main.h" static void event_editor_init (EventEditor *ee); GtkWindow *parent_class; +/* Note: do not i18n these strings, they are part of the vCalendar protocol */ +char *class_names [] = { "PUBLIC", "PRIVATE", "CONFIDENTIAL" }; + guint event_editor_get_type (void) { @@ -59,77 +63,191 @@ adjust (GtkWidget *w, gfloat x, gfloat y, gfloat xs, gfloat ys) return a; } +/* + * Checks if the day range occupies all the day, and if so, check the + * box accordingly + */ +static void +ee_check_all_day (EventEditor *ee) +{ + time_t ev_start, ev_end; + + ev_start = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->start_time)); + ev_end = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->end_time)); + + if (get_time_t_hour (ev_start) <= day_begin && get_time_t_hour (ev_end) >= day_end){ + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (ee->general_allday), 1); + } else{ + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (ee->general_allday), 0); + } +} + +/* + * Callback: checks if the selected hour range spans all of the day + */ +static void +check_times (GtkWidget *widget, EventEditor *ee) +{ + ee_check_all_day (ee); +} + +/* + * Callback: all day event box clicked + */ +static void +set_all_day (GtkToggleButton *toggle, EventEditor *ee) +{ + struct tm *tm; + time_t start_t; + + start_t = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->start_time)); + tm = localtime (&start_t); + tm->tm_hour = day_begin; + tm->tm_min = 0; + tm->tm_sec = 0; + gnome_date_edit_set_time (GNOME_DATE_EDIT (ee->start_time), mktime (tm)); + + if (toggle->active) + tm->tm_hour = day_end; + else + tm->tm_hour++; + + gnome_date_edit_set_time (GNOME_DATE_EDIT (ee->end_time), mktime (tm)); +} + static GtkWidget * event_editor_setup_time_frame (EventEditor *ee) { GtkWidget *frame; - GtkWidget *start_time, *end_time, *allday, *recur; + GtkWidget *start_time, *end_time; GtkTable *t; frame = gtk_frame_new (_("Time")); t = GTK_TABLE (ee->general_time_table = gtk_table_new (1, 1, 0)); gtk_container_add (GTK_CONTAINER (frame), ee->general_time_table); - + + /* 1. Start time */ ee->start_time = start_time = gnome_date_edit_new (ee->ical->dtstart); - ee->end_time = end_time = gnome_date_edit_new (ee->ical->dtend); gnome_date_edit_set_popup_range ((GnomeDateEdit *) start_time, day_begin, day_end); - gnome_date_edit_set_popup_range ((GnomeDateEdit *) end_time, day_begin, day_end); gtk_signal_connect (GTK_OBJECT (start_time), "time_changed", GTK_SIGNAL_FUNC (adjust_end_time), ee); + gtk_signal_connect (GTK_OBJECT (start_time), "time_changed", + GTK_SIGNAL_FUNC (check_times), ee); gtk_table_attach (t, gtk_label_new (_("Start time")), 1, 2, 1, 2, 0, 0, 0, 0); - gtk_table_attach (t, gtk_label_new (_("End time")), 1, 2, 2, 3, 0, 0, 0, 0); - gtk_table_attach (t, start_time, 2, 3, 1, 2, GTK_EXPAND | GTK_FILL, 0, 0, 0); + + /* 2. End time */ + ee->end_time = end_time = gnome_date_edit_new (ee->ical->dtend); + gnome_date_edit_set_popup_range ((GnomeDateEdit *) end_time, day_begin, day_end); + gtk_signal_connect (GTK_OBJECT (end_time), "time_changed", + GTK_SIGNAL_FUNC (check_times), ee); + gtk_table_attach (t, gtk_label_new (_("End time")), 1, 2, 2, 3, 0, 0, 0, 0); gtk_table_attach (t, end_time, 2, 3, 2, 3, GTK_EXPAND | GTK_FILL, 0, 0, 0); - allday = gtk_check_button_new_with_label (_("All day event")); - gtk_table_attach (t, allday, 3, 4, 1, 2, 0, 0, 0, 0); + /* 3. All day checkbox */ + ee->general_allday = gtk_check_button_new_with_label (_("All day event")); + gtk_signal_connect (GTK_OBJECT (ee->general_allday), "toggled", + GTK_SIGNAL_FUNC (set_all_day), ee); + gtk_table_attach (t, ee->general_allday, 3, 4, 1, 2, 0, 0, 0, 0); + ee_check_all_day (ee); - recur = gtk_check_button_new_with_label (_("Recurring event")); - gtk_table_attach (t, recur, 3, 4, 2, 3, 0, 0, 0, 0); + /* 4. Recurring event checkbox */ + ee->general_recur = gtk_check_button_new_with_label (_("Recurring event")); + gtk_table_attach (t, ee->general_recur, 3, 4, 2, 3, 0, 0, 0, 0); gtk_container_border_width (GTK_CONTAINER (frame), 5); return frame; } -enum { - ALARM_MAIL, - ALARM_PROGRAM, - ALARM_DISPLAY, - ALARM_AUDIO -}; +static GtkWidget * +timesel_new (void) +{ + GtkWidget *menu, *option_menu; + char *items [] = { N_("Minutes"), N_("Hours"), N_("Days") }; + int i; + + option_menu = gtk_option_menu_new (); + menu = gtk_menu_new (); + for (i = 0; i < 3; i++){ + GtkWidget *item; + + item = gtk_menu_item_new_with_label (_(items [i])); + gtk_menu_append (GTK_MENU (menu), item); + gtk_widget_show (item); + } + gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu); + return option_menu; +} + +/* + * Set the sensitive state depending on whether the alarm enabled flag. + */ +static void +ee_alarm_setting (CalendarAlarm *alarm, int sensitive) +{ + gtk_widget_set_sensitive (GTK_WIDGET (alarm->w_count), sensitive); + gtk_widget_set_sensitive (GTK_WIDGET (alarm->w_timesel), sensitive); + + if (alarm->type == ALARM_PROGRAM || alarm->type == ALARM_MAIL){ + gtk_widget_set_sensitive (GTK_WIDGET (alarm->w_entry), sensitive); + gtk_widget_set_sensitive (GTK_WIDGET (alarm->w_label), sensitive); + } +} + +static void +alarm_toggle (GtkToggleButton *toggle, CalendarAlarm *alarm) +{ + ee_alarm_setting (alarm, toggle->active); +} #define FX GTK_FILL | GTK_EXPAND #define XCOL 6 static GtkWidget * -ee_create_ae (GtkTable *table, char *str, CalendarAlarm **alarm, int type, int y) +ee_create_ae (GtkTable *table, char *str, CalendarAlarm *alarm, enum AlarmType type, int y) { - GtkWidget *label, *entry; + GtkWidget *timesel; + char buffer [40]; - label = gtk_check_button_new_with_label (str); - gtk_table_attach (table, label, 2, 3, y, y+1, FX, 0, 0, 0); - - entry = gtk_entry_new (); - gtk_widget_set_usize (entry, 40, 0); - gtk_table_attach (table, entry, 3, 4, y, y+1, FX, 0, 5, 0); + alarm->w_enabled = gtk_check_button_new_with_label (str); + gtk_signal_connect (GTK_OBJECT (alarm->w_enabled), "toggled", + GTK_SIGNAL_FUNC (alarm_toggle), alarm); + gtk_table_attach (table, alarm->w_enabled, 2, 3, y, y+1, FX, 0, 0, 0); + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (alarm->w_enabled), alarm->enabled); + + alarm->w_count = gtk_entry_new (); + gtk_widget_set_usize (alarm->w_count, 40, 0); + gtk_table_attach (table, alarm->w_count, 3, 4, y, y+1, FX, 0, 5, 0); + sprintf (buffer, "%d", alarm->count); + gtk_entry_set_text (GTK_ENTRY (alarm->w_count), buffer); + + alarm->w_timesel = timesel_new (); + gtk_option_menu_set_history (GTK_OPTION_MENU (alarm->w_timesel), alarm->units); + gtk_table_attach (table, alarm->w_timesel, 4, 5, y, y+1, 0, 0, 0, 0); + switch (type){ case ALARM_MAIL: - label = gtk_label_new (_("Mail to:")); - gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); - gtk_table_attach (table, label, XCOL, XCOL+1, y, y+1, FX, 0, 5, 0); - entry = gtk_entry_new (); - gtk_table_attach (table, entry, XCOL+1, XCOL+2, y, y+1, FX, 0, 6, 0); + alarm->w_label = gtk_label_new (_("Mail to:")); + gtk_misc_set_alignment (GTK_MISC (alarm->w_label), 1.0, 0.5); + gtk_table_attach (table, alarm->w_label, XCOL, XCOL+1, y, y+1, FX, 0, 5, 0); + alarm->w_entry = gtk_entry_new (); + gtk_table_attach (table, alarm->w_entry, XCOL+1, XCOL+2, y, y+1, FX, 0, 6, 0); + gtk_entry_set_text (GTK_ENTRY (alarm->w_entry), alarm->data); break; case ALARM_PROGRAM: - label = gtk_label_new (_("Run program:")); - gtk_table_attach (table, label, XCOL, XCOL+1, y, y+1, FX, 0, 5, 0); - entry = gnome_file_entry_new ("alarm-program", _("Select program to run at alarm time")); - gtk_table_attach (table, entry, XCOL+1, XCOL+2, y, y+1, 0, 0, 6, 0); + alarm->w_label = gtk_label_new (_("Run program:")); + gtk_misc_set_alignment (GTK_MISC (alarm->w_label), 1.0, 0.5); + gtk_table_attach (table, alarm->w_label, XCOL, XCOL+1, y, y+1, FX, 0, 5, 0); + alarm->w_entry = gnome_file_entry_new ("alarm-program", _("Select program to run at alarm time")); + gtk_table_attach (table, alarm->w_entry, XCOL+1, XCOL+2, y, y+1, 0, 0, 6, 0); break; + + default: + /* Nothing */ } - + + ee_alarm_setting (alarm, alarm->enabled); } static GtkWidget * @@ -137,7 +255,7 @@ ee_alarm_widgets (EventEditor *ee) { GtkWidget *table, *aalarm, *dalarm, *palarm, *malarm, *mailto, *mailte, *l; - l = gtk_frame_new (_("Alarm")); + l = gtk_frame_new (_("Alarms")); table = gtk_table_new (1, 1, 0); gtk_table_set_row_spacings (GTK_TABLE (table), 3); @@ -147,13 +265,19 @@ ee_alarm_widgets (EventEditor *ee) mailte = gtk_entry_new (); ee_create_ae (GTK_TABLE (table), _("Display"), &ee->ical->dalarm, ALARM_DISPLAY, 1); - ee_create_ae (GTK_TABLE (table), _("Audio"), &ee->ical->dalarm, ALARM_AUDIO, 2); - ee_create_ae (GTK_TABLE (table), _("Program"), &ee->ical->dalarm, ALARM_PROGRAM, 3); - ee_create_ae (GTK_TABLE (table), _("Mail"), &ee->ical->dalarm, ALARM_MAIL, 4); + ee_create_ae (GTK_TABLE (table), _("Audio"), &ee->ical->aalarm, ALARM_AUDIO, 2); + ee_create_ae (GTK_TABLE (table), _("Program"), &ee->ical->palarm, ALARM_PROGRAM, 3); + ee_create_ae (GTK_TABLE (table), _("Mail"), &ee->ical->malarm, ALARM_MAIL, 4); return l; } +static void +connect_and_pack (EventEditor *ee, GtkWidget *hbox, GtkWidget *toggle, char *value) +{ + gtk_box_pack_start_defaults (GTK_BOX (hbox), toggle); +} + static GtkWidget * ee_classification_widgets (EventEditor *ee) { @@ -167,22 +291,110 @@ ee_classification_widgets (EventEditor *ee) rpub = gtk_radio_button_new_with_label (NULL, _("Public")); rpriv = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (rpub), _("Private")); conf = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (rpub), _("Confidential")); - - gtk_box_pack_start_defaults (GTK_BOX (hbox), rpub); - gtk_box_pack_start_defaults (GTK_BOX (hbox), rpriv); - gtk_box_pack_start_defaults (GTK_BOX (hbox), conf); + + connect_and_pack (ee, hbox, rpub, class_names [0]); + connect_and_pack (ee, hbox, rpriv, class_names [1]); + connect_and_pack (ee, hbox, conf, class_names [2]); + ee->general_radios = rpub; return frame; } +/* + * Retrieves the information from the CalendarAlarm widgets and stores them + * on the CalendarAlarm generic values + */ +ee_store_alarm (CalendarAlarm *alarm, enum AlarmType type) +{ + GtkWidget *item; + GtkMenu *menu; + GList *child; + int idx; + + if (alarm->data){ + g_free (alarm->data); + alarm->data = 0; + } + + alarm->enabled = GTK_TOGGLE_BUTTON (alarm->w_enabled)->active; + + if (!alarm->enabled) + return; + + if (type == ALARM_PROGRAM) + alarm->data = g_strdup (gtk_entry_get_text (GTK_ENTRY (gnome_file_entry_gtk_entry (alarm->w_entry)))); + if (type == ALARM_MAIL) + alarm->data = g_strdup (gtk_entry_get_text (GTK_ENTRY (alarm->w_entry))); + + /* Find out the index */ + menu = GTK_MENU (GTK_OPTION_MENU (alarm->w_timesel)->menu); + + item = gtk_menu_get_active (menu); + + for (idx = 0, child = menu->children; child->data != item; child = child->next) + idx++; + + alarm->units = idx; + alarm->count = atoi (gtk_entry_get_text (GTK_ENTRY (alarm->w_count))); +} + +/* + * Retrieves all of the information from the different widgets and updates + * the iCalObject accordingly. + */ +static void +ee_store_dlg_values_to_ical (EventEditor *ee) +{ + GtkRadioButton *radio = GTK_RADIO_BUTTON (ee->general_radios); + iCalObject *ical = ee->ical; + GSList *list = radio->group; + int idx; + time_t now; + + now = time (NULL); + ical->dtstart = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->start_time)); + ical->dtend = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->end_time)); + + ee_store_alarm (&ical->dalarm, ALARM_DISPLAY); + ee_store_alarm (&ical->aalarm, ALARM_AUDIO); + ee_store_alarm (&ical->palarm, ALARM_PROGRAM); + ee_store_alarm (&ical->malarm, ALARM_MAIL); + + for (idx = 0; list; list = list->next){ + if (GTK_TOGGLE_BUTTON (list->data)->active) + break; + idx++; + } + g_free (ical->class); + ical->class = g_strdup (class_names [idx]); + + /* FIXME: This is not entirely correct; we should check if the values actually changed */ + ical->last_mod = now; + + if (ee->new_ical) + ical->created = now; + + g_free (ical->summary); + ical->summary = gtk_editable_get_chars (GTK_EDITABLE (ee->general_summary), 0, -1); +} + static void ee_ok (GtkWidget *widget, EventEditor *ee) { + ee_store_dlg_values_to_ical (ee); + + if (ee->new_ical) + gnome_calendar_add_object (GNOME_CALENDAR (ee->gnome_cal), ee->ical); + + gtk_widget_destroy (GTK_WIDGET (ee)); } static void ee_cancel (GtkWidget *widget, EventEditor *ee) { + if (ee->new_ical) + ical_object_destroy (ee->ical); + gtk_widget_destroy (GTK_WIDGET (ee)); } static GtkWidget * @@ -210,8 +422,7 @@ static void ee_fill_summary (GtkWidget *widget, EventEditor *ee) { int pos = 0; - - gtk_text_freeze (GTK_TEXT (ee->general_summary)); + gtk_editable_insert_text (GTK_EDITABLE (ee->general_summary), ee->ical->summary, strlen (ee->ical->summary), &pos); gtk_text_thaw (GTK_TEXT (ee->general_summary)); @@ -257,6 +468,7 @@ event_editor_init_widgets (EventEditor *ee) 1, LABEL_SPAN, DESC_LINE, DESC_LINE + 1, GTK_FILL|GTK_EXPAND, 0, 0, 0); ee->general_summary = gtk_text_new (NULL, NULL); + gtk_text_freeze (GTK_TEXT (ee->general_summary)); gtk_signal_connect (GTK_OBJECT (ee->general_summary), "realize", GTK_SIGNAL_FUNC (ee_fill_summary), ee); gtk_widget_set_usize (ee->general_summary, 0, 60); @@ -297,7 +509,7 @@ event_editor_init (EventEditor *ee) } GtkWidget * -event_editor_new (iCalObject *ical) +event_editor_new (GnomeCalendar *gcal, iCalObject *ical) { GtkWidget *retval; EventEditor *ee; @@ -312,6 +524,7 @@ event_editor_new (iCalObject *ical) ee->new_ical = 0; ee->ical = ical; + ee->gnome_cal = gcal; event_editor_init_widgets (ee); return retval; diff --git a/calendar/gui/eventedit.h b/calendar/gui/eventedit.h index 85b5b86790..e726270877 100644 --- a/calendar/gui/eventedit.h +++ b/calendar/gui/eventedit.h @@ -23,20 +23,26 @@ typedef struct { GtkWidget *general; GtkTable *general_table; GtkWidget *general_time_table; + GtkWidget *general_allday; + GtkWidget *general_recur; GtkWidget *general_owner; GtkWidget *general_summary; GtkWidget *start_time, *end_time; - + GtkWidget *general_radios; + /* The associated ical object */ iCalObject *ical; int new_ical; + + /* The calendar owner of this event */ + GnomeCalendar *gnome_cal; } EventEditor; typedef struct { GnomePropertyBoxClass parent_class; } EventEditorClass; -GtkWidget *event_editor_new (iCalObject *); +GtkWidget *event_editor_new (GnomeCalendar *owner, iCalObject *); END_GNOME_DECLS #endif diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index 7fa7a5e40d..4c0806357d 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -39,18 +39,17 @@ gnome_calendar_get_type (void) static void setup_widgets (GnomeCalendar *gcal) { - GtkWidget *notebook; - GtkWidget *day_view, *year_view, *task_view; time_t now; now = time (NULL); - notebook = gtk_notebook_new (); - day_view = day_view_create (gcal); + gcal->notebook = gtk_notebook_new (); + gcal->day_view = day_view_create (gcal); gcal->week_view = gncal_week_view_new (gcal, now); - year_view = year_view_create (gcal); - task_view = tasks_create (gcal); + gcal->year_view = year_view_create (gcal); + gcal->task_view = tasks_create (gcal); + if (0) { struct tm tm; time_t a, b; @@ -66,17 +65,17 @@ setup_widgets (GnomeCalendar *gcal) b = mktime (&tm); - day_view = gncal_full_day_new (gcal, a, b); + gcal->day_view = gncal_full_day_new (gcal, a, b); } - gtk_notebook_append_page (GTK_NOTEBOOK (notebook), day_view, gtk_label_new (_("Day View"))); - gtk_notebook_append_page (GTK_NOTEBOOK (notebook), gcal->week_view, gtk_label_new (_("Week View"))); - gtk_notebook_append_page (GTK_NOTEBOOK (notebook), year_view, gtk_label_new (_("Year View"))); - gtk_notebook_append_page (GTK_NOTEBOOK (notebook), task_view, gtk_label_new (_("Todo"))); + gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->day_view, gtk_label_new (_("Day View"))); + gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->week_view, gtk_label_new (_("Week View"))); + gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->year_view, gtk_label_new (_("Year View"))); + gtk_notebook_append_page (GTK_NOTEBOOK (gcal->notebook), gcal->task_view, gtk_label_new (_("Todo"))); - gtk_widget_show_all (notebook); + gtk_widget_show_all (gcal->notebook); - gnome_app_set_contents (GNOME_APP (gcal), notebook); + gnome_app_set_contents (GNOME_APP (gcal), gcal->notebook); } @@ -88,6 +87,29 @@ gnome_calendar_init(GnomeCalendar *gcal) setup_widgets (gcal); } +static GtkWidget * +get_current_page (GnomeCalendar *gcal) +{ + return GTK_NOTEBOOK (gcal->notebook)->cur_page->child; +} + +GtkWidget * +gnome_calendar_next (GnomeCalendar *gcal) +{ + GtkWidget *cp = get_current_page (gcal); + time_t new_time; + + if (cp == gcal->week_view) + new_time = time_add_week (gcal->current_display, 1); + else if (cp == gcal->day_view) + new_time = time_add_day (gcal->current_display, 1); + else if (cp == gcal->year_view) + new_time = time_add_year (gcal->current_display, 1); + else + g_warning ("Weee! Where did the penguin go?"); + +} + GtkWidget * gnome_calendar_new (char *title) { @@ -104,13 +126,27 @@ gnome_calendar_new (char *title) gtk_window_set_title(GTK_WINDOW(retval), title); + gcal->current_display = time (NULL); gcal->cal = calendar_new (title); return retval; } void +gnome_calendar_update_all (GnomeCalendar *cal) +{ + gncal_week_view_update (GNCAL_WEEK_VIEW (cal->week_view)); +} + +void gnome_calendar_load (GnomeCalendar *gcal, char *file) { calendar_load (gcal->cal, file); - gncal_week_view_update (GNCAL_WEEK_VIEW (gcal->week_view)); + gnome_calendar_update_all (gcal); +} + +void +gnome_calendar_add_object (GnomeCalendar *gcal, iCalObject *obj) +{ + calendar_add_object (gcal->cal, obj); + gnome_calendar_update_all (gcal); } diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h index 8a93d18450..8168c26ec8 100644 --- a/calendar/gui/gnome-cal.h +++ b/calendar/gui/gnome-cal.h @@ -20,7 +20,14 @@ BEGIN_GNOME_DECLS typedef struct { GnomeApp gnome_app; Calendar *cal; + + time_t current_display; + + GtkWidget *notebook; GtkWidget *week_view; + GtkWidget *day_view; + GtkWidget *year_view; + GtkWidget *task_view; void *event_editor; } GnomeCalendar; @@ -31,7 +38,7 @@ typedef struct { guint gnome_calendar_get_type (void); GtkWidget *gnome_calendar_new (char *title); void gnome_calendar_load (GnomeCalendar *gcal, char *file); - +void gnome_calendar_add_object (GnomeCalendar *gcal, iCalObject *obj); END_GNOME_DECLS #endif diff --git a/calendar/gui/main.c b/calendar/gui/main.c index 54fdbaaa2b..eb272c1246 100644 --- a/calendar/gui/main.c +++ b/calendar/gui/main.c @@ -57,10 +57,13 @@ init_username (void) int range_check_hour (int hour) { + struct tm tm; + if (hour < 0) hour = 0; if (hour > 24) hour = 23; + return hour; } @@ -122,10 +125,7 @@ about_calendar_cmd (GtkWidget *widget, void *data) void display_objedit (GtkWidget *widget, GnomeCalendar *gcal) { - if (!gcal->event_editor){ - gcal->event_editor = event_editor_new (NULL); - gtk_widget_show (gcal->event_editor); - } + event_editor_new (gcal, NULL); } void @@ -151,6 +151,33 @@ close_cmd (GtkWidget *widget, GnomeCalendar *gcal) gtk_main_quit (); } +static GtkWidget * +get_current_page (GnomeCalendar *gcal) +{ + return GTK_NOTEBOOK (gcal->notebook)->cur_page->child; +} + +void +previous_clicked (GtkWidget *widget, GnomeCalendar *gcal) +{ + GtkWidget *current_page = get_current_page (gcal); + + if (current_page == gcal->week_view){ + } +} + +void +next_clicked (GtkWidget *widget, GnomeCalendar *gcal) +{ + GtkWidget *current_page = get_current_page (gcal); +} + +void +today_clicked (GtkWidget *widget, GnomeCalendar *gcal) +{ + GtkWidget *current_page = get_current_page (gcal); +} + GnomeUIInfo gnome_cal_file_menu [] = { { GNOME_APP_UI_ITEM, N_("New calendar"), NULL, new_calendar_cmd }, @@ -190,13 +217,13 @@ GnomeUIInfo gnome_cal_menu [] = { }; GnomeUIInfo gnome_toolbar [] = { - { GNOME_APP_UI_ITEM, N_("Prev"), N_("Previous"), /*previous_clicked*/0, 0, 0, + { GNOME_APP_UI_ITEM, N_("Prev"), N_("Previous"), previous_clicked, 0, 0, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BACK }, - { GNOME_APP_UI_ITEM, N_("Today"), N_("Today"), /*previous_clicked*/0, 0, 0, + { GNOME_APP_UI_ITEM, N_("Today"), N_("Today"), today_clicked, 0, 0, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BACK }, - { GNOME_APP_UI_ITEM, N_("Next"), N_("Next"), /*previous_clicked*/0, 0, 0, + { GNOME_APP_UI_ITEM, N_("Next"), N_("Next"), next_clicked, 0, 0, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_FORWARD }, GNOMEUIINFO_END diff --git a/calendar/main.c b/calendar/main.c index 54fdbaaa2b..eb272c1246 100644 --- a/calendar/main.c +++ b/calendar/main.c @@ -57,10 +57,13 @@ init_username (void) int range_check_hour (int hour) { + struct tm tm; + if (hour < 0) hour = 0; if (hour > 24) hour = 23; + return hour; } @@ -122,10 +125,7 @@ about_calendar_cmd (GtkWidget *widget, void *data) void display_objedit (GtkWidget *widget, GnomeCalendar *gcal) { - if (!gcal->event_editor){ - gcal->event_editor = event_editor_new (NULL); - gtk_widget_show (gcal->event_editor); - } + event_editor_new (gcal, NULL); } void @@ -151,6 +151,33 @@ close_cmd (GtkWidget *widget, GnomeCalendar *gcal) gtk_main_quit (); } +static GtkWidget * +get_current_page (GnomeCalendar *gcal) +{ + return GTK_NOTEBOOK (gcal->notebook)->cur_page->child; +} + +void +previous_clicked (GtkWidget *widget, GnomeCalendar *gcal) +{ + GtkWidget *current_page = get_current_page (gcal); + + if (current_page == gcal->week_view){ + } +} + +void +next_clicked (GtkWidget *widget, GnomeCalendar *gcal) +{ + GtkWidget *current_page = get_current_page (gcal); +} + +void +today_clicked (GtkWidget *widget, GnomeCalendar *gcal) +{ + GtkWidget *current_page = get_current_page (gcal); +} + GnomeUIInfo gnome_cal_file_menu [] = { { GNOME_APP_UI_ITEM, N_("New calendar"), NULL, new_calendar_cmd }, @@ -190,13 +217,13 @@ GnomeUIInfo gnome_cal_menu [] = { }; GnomeUIInfo gnome_toolbar [] = { - { GNOME_APP_UI_ITEM, N_("Prev"), N_("Previous"), /*previous_clicked*/0, 0, 0, + { GNOME_APP_UI_ITEM, N_("Prev"), N_("Previous"), previous_clicked, 0, 0, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BACK }, - { GNOME_APP_UI_ITEM, N_("Today"), N_("Today"), /*previous_clicked*/0, 0, 0, + { GNOME_APP_UI_ITEM, N_("Today"), N_("Today"), today_clicked, 0, 0, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_BACK }, - { GNOME_APP_UI_ITEM, N_("Next"), N_("Next"), /*previous_clicked*/0, 0, 0, + { GNOME_APP_UI_ITEM, N_("Next"), N_("Next"), next_clicked, 0, 0, GNOME_APP_PIXMAP_STOCK, GNOME_STOCK_MENU_FORWARD }, GNOMEUIINFO_END diff --git a/calendar/pcs/calobj.c b/calendar/pcs/calobj.c index f405dbe265..004ba7636d 100644 --- a/calendar/pcs/calobj.c +++ b/calendar/pcs/calobj.c @@ -24,6 +24,27 @@ ical_object_new (void) return ico; } +static void +default_alarm (iCalObject *ical, CalendarAlarm *alarm, char *def_mail, enum AlarmType type) +{ + alarm->enabled = 0; + alarm->type = type; + + if (type != ALARM_MAIL){ + alarm->count = 15; + alarm->units = ALARM_MINUTES; + } else { + printf ("uno!\n"); + alarm->count = 1; + alarm->units = ALARM_DAYS; + } + + if (type == ALARM_MAIL) + alarm->data = g_strdup (def_mail); + else + alarm->data = g_strdup (""); +} + iCalObject * ical_new (char *comment, char *organizer, char *summary) { @@ -34,18 +55,43 @@ ical_new (char *comment, char *organizer, char *summary) ico->comment = g_strdup (comment); ico->organizer = g_strdup (organizer); ico->summary = g_strdup (summary); + ico->class = g_strdup ("PUBLIC"); + default_alarm (ico, &ico->dalarm, organizer, ALARM_DISPLAY); + default_alarm (ico, &ico->palarm, organizer, ALARM_PROGRAM); + default_alarm (ico, &ico->malarm, organizer, ALARM_MAIL); + default_alarm (ico, &ico->aalarm, organizer, ALARM_AUDIO); + return ico; } -#define free_if_defined(x) if (x){ g_free (x); x = 0; } +static void +list_free (GList *list) +{ + g_list_foreach (list, g_free, 0); + g_list_free (list); +} +#define free_if_defined(x) if (x){ g_free (x); x = 0; } +#define lfree_if_defined(x) if (x){ list_free (x); x = 0; } void ical_object_destroy (iCalObject *ico) { - free_if_defined (ico->comment); - free_if_defined (ico->organizer); - free_if_defined (ico->summary); + /* Regular strings */ + free_if_defined (ico->comment); + free_if_defined (ico->organizer); + free_if_defined (ico->summary); + free_if_defined (ico->uid); + free_if_defined (ico->status); + free_if_defined (ico->class); + free_if_defined (ico->url); + + /* Lists */ + lfree_if_defined (ico->exdate); + lfree_if_defined (ico->categories); + lfree_if_defined (ico->resources); + lfree_if_defined (ico->related); + lfree_if_defined (ico->attach); g_free (ico); } @@ -83,6 +129,7 @@ ical_object_create_from_vobject (VObject *o, const char *object_name) ical->type = ICAL_TODO; else return 0; + /* uid */ if (has (o, VCUniqueStringProp)) ical->uid = g_strdup (str_val (vo)); @@ -123,9 +170,9 @@ ical_object_create_from_vobject (VObject *o, const char *object_name) if (has (o, VCExpDateProp)) ical->exdate = set_list (str_val (vo), ","); - /* description */ + /* description/comment */ if (has (o, VCDescriptionProp)) - ical->description = g_strdup (str_val (vo)); + ical->comment = g_strdup (str_val (vo)); /* summary */ if (has (o, VCSummaryProp)) @@ -142,7 +189,7 @@ ical_object_create_from_vobject (VObject *o, const char *object_name) if (has (o, VCClassProp)) ical->class = g_strdup (str_val (vo)); else - ical->status = g_strdup ("PUBLIC"); + ical->class = "PUBLIC"; /* categories */ if (has (o, VCCategoriesProp)) diff --git a/calendar/pcs/calobj.h b/calendar/pcs/calobj.h index b16fe5f850..00dbd5c63e 100644 --- a/calendar/pcs/calobj.h +++ b/calendar/pcs/calobj.h @@ -12,11 +12,32 @@ BEGIN_GNOME_DECLS +enum AlarmType { + ALARM_MAIL, + ALARM_PROGRAM, + ALARM_DISPLAY, + ALARM_AUDIO +}; + +enum AlarmUnit { + ALARM_MINUTES, + ALARM_HOURS, + ALARM_DAYS +}; + typedef struct { - char *alarm_audio_file; - char *alarm_script; - char *alarm_email; - char *alarm_text; /* Text to be displayed */ + enum AlarmType type; + int enabled; + int count; + enum AlarmUnit units; + char *data; + + /* Widgets */ + void *w_count; /* A GtkEntry */ + void *w_enabled; /* A GtkChecButton */ + void *w_timesel; /* A GtkMenu */ + void *w_entry; /* A GnomeEntryFile/GtkEntry for PROGRAM/MAIL */ + void *w_label; } CalendarAlarm; /* Calendar object type */ @@ -65,7 +86,6 @@ typedef struct { time_t completed; time_t created; GList *contact; /* type: one or more TEXT */ - char *description; time_t dtstamp; time_t dtstart; time_t dtend; @@ -90,10 +110,10 @@ typedef struct { char *url; time_t recurid; - CalendarAlarm *dalarm; - CalendarAlarm *aalarm; - CalendarAlarm *palarm; - CalendarAlarm *malarm; + CalendarAlarm dalarm; + CalendarAlarm aalarm; + CalendarAlarm palarm; + CalendarAlarm malarm; } iCalObject; iCalObject *ical_new (char *comment, char *organizer, char *summary); diff --git a/calendar/timeutil.c b/calendar/timeutil.c index b860c84b09..3a78bf2b4f 100644 --- a/calendar/timeutil.c +++ b/calendar/timeutil.c @@ -41,6 +41,14 @@ print_time_t (time_t t) tm->tm_hour, tm->tm_min, tm->tm_sec); } +int +get_time_t_hour (time_t t) +{ + struct tm *tm; + + tm = localtime (&t); + return tm->tm_hour; +} char * isodate_from_time_t (time_t t) @@ -50,7 +58,7 @@ isodate_from_time_t (time_t t) tm = localtime (&t); strftime (isotime, sizeof (isotime)-1, "%Y%m%dT%H%M%sZ", tm); - return &isotime; + return isotime; } time_t @@ -79,3 +87,19 @@ format_simple_hour (int hour, int use_am_pm) return buf; } + +time_t +time_add_week (time_t time, int weeks) +{ +} + +time_t +time_add_day (time_t time, int weeks) +{ +} + +time_t +time_add_year (time_t time, int years) +{ +} + diff --git a/calendar/timeutil.h b/calendar/timeutil.h index d33b65470b..1683df7527 100644 --- a/calendar/timeutil.h +++ b/calendar/timeutil.h @@ -13,9 +13,10 @@ #include <time.h> -time_t time_from_isodate (char *str); +time_t time_from_isodate (char *str); time_t time_from_start_duration (time_t start, char *duration); -char *isodate_from_time_t (time_t t); +char *isodate_from_time_t (time_t t); +int get_time_t_hour (time_t t); /* Returns pointer to a statically-allocated buffer with a string of the form * 3am, 4am, 12pm, 08h, 17h, etc. |