diff options
author | Federico Mena Quintero <federico@nuclecu.unam.mx> | 1998-04-18 07:22:50 +0800 |
---|---|---|
committer | Arturo Espinosa <unammx@src.gnome.org> | 1998-04-18 07:22:50 +0800 |
commit | 4b926012c0cae01569d71d178dc651d9e4b2c8e8 (patch) | |
tree | 0e8bb67d40b658bd6b867b15e909db1846d76908 /calendar | |
parent | 470866a2577773301742e2c1c83413c83249328a (diff) | |
download | gsoc2013-evolution-4b926012c0cae01569d71d178dc651d9e4b2c8e8.tar gsoc2013-evolution-4b926012c0cae01569d71d178dc651d9e4b2c8e8.tar.gz gsoc2013-evolution-4b926012c0cae01569d71d178dc651d9e4b2c8e8.tar.bz2 gsoc2013-evolution-4b926012c0cae01569d71d178dc651d9e4b2c8e8.tar.lz gsoc2013-evolution-4b926012c0cae01569d71d178dc651d9e4b2c8e8.tar.xz gsoc2013-evolution-4b926012c0cae01569d71d178dc651d9e4b2c8e8.tar.zst gsoc2013-evolution-4b926012c0cae01569d71d178dc651d9e4b2c8e8.zip |
The event dialog is beautified, recurrences are saner.
1998-04-17 Federico Mena Quintero <federico@nuclecu.unam.mx>
* eventedit.c (ee_init_recurrence_page): New function that creates
the recurrence page in the toplevel notebook.
(ee_store_recur_values_to_ical): Now we can also store the recurrences.
svn path=/trunk/; revision=151
Diffstat (limited to 'calendar')
-rw-r--r-- | calendar/ChangeLog | 6 | ||||
-rw-r--r-- | calendar/TODO | 2 | ||||
-rw-r--r-- | calendar/cal-util/calobj.c | 7 | ||||
-rw-r--r-- | calendar/cal-util/calobj.h | 5 | ||||
-rw-r--r-- | calendar/calobj.c | 7 | ||||
-rw-r--r-- | calendar/calobj.h | 5 | ||||
-rw-r--r-- | calendar/eventedit.c | 851 | ||||
-rw-r--r-- | calendar/eventedit.h | 35 | ||||
-rw-r--r-- | calendar/gncal-full-day.c | 8 | ||||
-rw-r--r-- | calendar/gnome-cal.c | 2 | ||||
-rw-r--r-- | calendar/gui/eventedit.c | 851 | ||||
-rw-r--r-- | calendar/gui/eventedit.h | 35 | ||||
-rw-r--r-- | calendar/gui/gncal-full-day.c | 8 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.c | 2 | ||||
-rw-r--r-- | calendar/gui/main.c | 5 | ||||
-rw-r--r-- | calendar/gui/year-view.c | 26 | ||||
-rw-r--r-- | calendar/main.c | 5 | ||||
-rw-r--r-- | calendar/pcs/calobj.c | 7 | ||||
-rw-r--r-- | calendar/pcs/calobj.h | 5 | ||||
-rw-r--r-- | calendar/year-view.c | 26 |
20 files changed, 1456 insertions, 442 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index a99da410da..f637e41c1e 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,9 @@ +1998-04-17 Federico Mena Quintero <federico@nuclecu.unam.mx> + + * eventedit.c (ee_init_recurrence_page): New function that creates + the recurrence page in the toplevel notebook. + (ee_store_recur_values_to_ical): Now we can also store the recurrences. + 1998-04-17 Miguel de Icaza <miguel@nuclecu.unam.mx> * calobj.c (ical_object_generate_events): Implement diff --git a/calendar/TODO b/calendar/TODO index 7fffd51365..d9f4592125 100644 --- a/calendar/TODO +++ b/calendar/TODO @@ -12,6 +12,8 @@ Event editor dialog: - Resize the window and fix whatever is resized in an ugly fashion. +- Don't allow deleting exceptions when there are none in the list. + Full day view widget: - Display alarm/whatever flags somewhere. diff --git a/calendar/cal-util/calobj.c b/calendar/cal-util/calobj.c index 2ff626c469..73406b9a5f 100644 --- a/calendar/cal-util/calobj.c +++ b/calendar/cal-util/calobj.c @@ -12,8 +12,6 @@ #include "timeutil.h" #include "versit/vcc.h" -static void ical_object_compute_end (iCalObject *ico); - iCalObject * ical_object_new (void) { @@ -1004,7 +1002,7 @@ duration_callback (iCalObject *ico, time_t start, time_t end, void *closure) int *count = closure; (*count)++; - if (ico->recur->duration == *count){ + if (ico->recur->duration == *count) { ico->recur->enddate = end; return 0; } @@ -1019,7 +1017,6 @@ ical_object_compute_end (iCalObject *ico) g_return_if_fail (ico->recur != NULL); + ico->recur->_enddate = 0; ical_object_generate_events (ico, ico->dtstart, 0, duration_callback, &count); } - - diff --git a/calendar/cal-util/calobj.h b/calendar/cal-util/calobj.h index c499568bf7..48b3012695 100644 --- a/calendar/cal-util/calobj.h +++ b/calendar/cal-util/calobj.h @@ -176,7 +176,10 @@ void ical_object_destroy (iCalObject *ico); iCalObject *ical_object_create_from_vobject (VObject *obj, const char *object_name); VObject *ical_object_to_vobject (iCalObject *ical); void ical_foreach (GList *events, calendarfn fn, void *closure); -void ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendarfn cb, void *closure); +void ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendarfn cb, void *closure); + +/* Computes the enddate field of the recurrence based on the duration */ +void ical_object_compute_end (iCalObject *ico); END_GNOME_DECLS diff --git a/calendar/calobj.c b/calendar/calobj.c index 2ff626c469..73406b9a5f 100644 --- a/calendar/calobj.c +++ b/calendar/calobj.c @@ -12,8 +12,6 @@ #include "timeutil.h" #include "versit/vcc.h" -static void ical_object_compute_end (iCalObject *ico); - iCalObject * ical_object_new (void) { @@ -1004,7 +1002,7 @@ duration_callback (iCalObject *ico, time_t start, time_t end, void *closure) int *count = closure; (*count)++; - if (ico->recur->duration == *count){ + if (ico->recur->duration == *count) { ico->recur->enddate = end; return 0; } @@ -1019,7 +1017,6 @@ ical_object_compute_end (iCalObject *ico) g_return_if_fail (ico->recur != NULL); + ico->recur->_enddate = 0; ical_object_generate_events (ico, ico->dtstart, 0, duration_callback, &count); } - - diff --git a/calendar/calobj.h b/calendar/calobj.h index c499568bf7..48b3012695 100644 --- a/calendar/calobj.h +++ b/calendar/calobj.h @@ -176,7 +176,10 @@ void ical_object_destroy (iCalObject *ico); iCalObject *ical_object_create_from_vobject (VObject *obj, const char *object_name); VObject *ical_object_to_vobject (iCalObject *ical); void ical_foreach (GList *events, calendarfn fn, void *closure); -void ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendarfn cb, void *closure); +void ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendarfn cb, void *closure); + +/* Computes the enddate field of the recurrence based on the duration */ +void ical_object_compute_end (iCalObject *ico); END_GNOME_DECLS diff --git a/calendar/eventedit.c b/calendar/eventedit.c index ff36d77507..7a1a582729 100644 --- a/calendar/eventedit.c +++ b/calendar/eventedit.c @@ -23,6 +23,11 @@ static char *class_names [] = { "PUBLIC", "PRIVATE", "CONFIDENTIAL" }; static GtkWindowClass *parent_class; +struct numbered_item { + char *text; + int num; +}; + guint event_editor_get_type (void) @@ -63,6 +68,19 @@ adjust (GtkWidget *w, gfloat x, gfloat y, gfloat xs, gfloat ys) return a; } +static GtkWidget * +make_spin_button (int val, int low, int high) +{ + GtkAdjustment *adj; + GtkWidget *spin; + + adj = GTK_ADJUSTMENT (gtk_adjustment_new (val, low, high, 1, 10, 10)); + spin = gtk_spin_button_new (adj, 0.5, 0); + gtk_widget_set_usize (spin, 60, 0); + + return spin; +} + /* * Checks if the day range occupies all the day, and if so, check the * box accordingly @@ -191,6 +209,13 @@ set_all_day (GtkToggleButton *toggle, EventEditor *ee) gnome_date_edit_set_time (GNOME_DATE_EDIT (ee->end_time), mktime (tm)); } +static void +recur_check_toggled (GtkToggleButton *toggle, EventEditor *ee) +{ + gtk_widget_set_sensitive (ee->recur_page_label, toggle->active); + gtk_widget_set_sensitive (ee->recur_table, toggle->active); +} + static GtkWidget * event_editor_setup_time_frame (EventEditor *ee) { @@ -206,7 +231,7 @@ event_editor_setup_time_frame (EventEditor *ee) 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->start_time = start_time = gnome_date_edit_new (ee->ical->dtstart, TRUE); gnome_date_edit_set_popup_range ((GnomeDateEdit *) start_time, day_begin, day_end); gtk_signal_connect (GTK_OBJECT (start_time), "date_changed", GTK_SIGNAL_FUNC (check_dates), ee); @@ -222,7 +247,7 @@ event_editor_setup_time_frame (EventEditor *ee) 0, 0); /* 2. End time */ - ee->end_time = end_time = gnome_date_edit_new (ee->ical->dtend); + ee->end_time = end_time = gnome_date_edit_new (ee->ical->dtend, TRUE); gnome_date_edit_set_popup_range ((GnomeDateEdit *) end_time, day_begin, day_end); gtk_signal_connect (GTK_OBJECT (end_time), "date_changed", GTK_SIGNAL_FUNC (check_dates), ee); @@ -304,8 +329,6 @@ alarm_toggle (GtkToggleButton *toggle, CalendarAlarm *alarm) static void ee_create_ae (GtkTable *table, char *str, CalendarAlarm *alarm, enum AlarmType type, int y) { - char buffer [40]; - 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); @@ -313,11 +336,8 @@ ee_create_ae (GtkTable *table, char *str, CalendarAlarm *alarm, enum AlarmType t 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); + alarm->w_count = make_spin_button (alarm->count, 0, 10000); gtk_table_attach (table, alarm->w_count, 1, 2, y, y+1, FS, FS, 0, 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); @@ -438,15 +458,11 @@ ee_store_alarm (CalendarAlarm *alarm, enum AlarmType type) idx++; alarm->units = idx; - alarm->count = atoi (gtk_entry_get_text (GTK_ENTRY (alarm->w_count))); + alarm->count = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (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) +ee_store_general_values_to_ical (EventEditor *ee) { GtkRadioButton *radio = GTK_RADIO_BUTTON (ee->general_radios); iCalObject *ical = ee->ical; @@ -475,12 +491,204 @@ ee_store_dlg_values_to_ical (EventEditor *ee) } g_free (ical->class); ical->class = g_strdup (class_names [idx]); +} + +static int +option_menu_active_number (GtkWidget *omenu) +{ + GtkWidget *menu; + GtkWidget *item; + struct numbered_item *ni; + + menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (omenu)); + item = gtk_menu_get_active (GTK_MENU (menu)); + + ni = gtk_object_get_user_data (GTK_OBJECT (item)); + + return ni->num; +} + +static void +ee_store_recur_rule_to_ical (EventEditor *ee) +{ + iCalObject *ical; + int i, j; + GSList *list; + + ical = ee->ical; + + for (i = 0, list = ee->recur_rr_group; list; i++, list = list->next) + if (GTK_TOGGLE_BUTTON (list->data)->active) + break; + + i = g_slist_length (ee->recur_rr_group) - i - 1; /* buttons are stored in reverse order of insertion */ + + switch (i) { + case 0: + /* Daily */ + ical->recur->type = RECUR_DAILY; + ical->recur->interval = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ee->recur_rr_day_period)); + break; + + case 1: + /* Weekly */ + ical->recur->type = RECUR_WEEKLY; + ical->recur->interval = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ee->recur_rr_week_period)); + ical->recur->weekday = 0; + + for (j = 0; j < 7; j++) + if (GTK_TOGGLE_BUTTON (ee->recur_rr_week_days[j])->active) { + if (j == 6) + ical->recur->weekday |= 1 << 0; /* sunday is at bit 0 */ + else + ical->recur->weekday |= 1 << (j + 1); + } + + break; + + case 2: + /* Monthly */ + + if (GTK_WIDGET_SENSITIVE (ee->recur_rr_month_date)) { + /* by day */ + + ical->recur->type = RECUR_MONTHLY_BY_DAY; + ical->recur->u.month_day = + gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ee->recur_rr_month_date)); + } else { + /* by position */ + + ical->recur->type = RECUR_MONTHLY_BY_POS; + + ical->recur->u.month_pos = option_menu_active_number (ee->recur_rr_month_day); + ical->recur->u.month_day = option_menu_active_number (ee->recur_rr_month_weekday); + } + + ical->recur->interval = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ee->recur_rr_month_period)); + + break; + + case 3: + /* Yearly */ + ical->recur->type = RECUR_YEARLY_BY_DAY; + /* FIXME: need to specify anything else? I am assuming the code will look at the dtstart + * to figure out when to recur. - Federico + */ + break; + + default: + g_assert_not_reached (); + } +} + +static void +ee_store_recur_end_to_ical (EventEditor *ee) +{ + iCalObject *ical; + GSList *list; + int i; + + /* Ending date of recurrence */ + + ical = ee->ical; + + for (i = 0, list = ee->recur_ed_group; list; i++, list = list->next) + if (GTK_TOGGLE_BUTTON (list->data)->active) + break; + + i = g_slist_length (ee->recur_ed_group) - i - 1; /* the list is stored in reverse order of insertion */ + + switch (i) { + case 0: + /* repeat forever */ + ical->recur->_enddate = 0; + ical->recur->enddate = 0; + ical->recur->duration = 0; + break; + + case 1: + /* end date */ + ical->recur->_enddate = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->recur_ed_end_on)); + ical->recur->enddate = ical->recur->enddate; + ical->recur->duration = 0; + break; + + case 2: + /* end after n occurrences */ + ical->recur->duration = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ee->recur_ed_end_after)); + ical_object_compute_end (ical); + break; + + default: + g_assert_not_reached (); + break; + } +} + +static void +free_exdate (iCalObject *ical) +{ + GList *list; + + if (!ical->exdate) + return; + + for (list = ical->exdate; list; list = list->next) + g_free (list->data); + + g_list_free (ical->exdate); + ical->exdate = NULL; +} + +static void +ee_store_recur_exceptions_to_ical (EventEditor *ee) +{ + iCalObject *ical; + GtkCList *clist; + int i; + time_t *t; + + ical = ee->ical; + clist = GTK_CLIST (ee->recur_ex_clist); + + free_exdate (ical); + + for (i = 0; i < clist->rows; i++) { + t = gtk_clist_get_row_data (clist, i); + ical->exdate = g_list_prepend (ical->exdate, t); + } +} + +static void +ee_store_recur_values_to_ical (EventEditor *ee) +{ + if (!ee->ical->recur) + ee->ical->recur = g_new0 (Recurrence, 1); + + ee_store_recur_rule_to_ical (ee); + ee_store_recur_end_to_ical (ee); + ee_store_recur_exceptions_to_ical (ee); +} + +/* + * Retrieves all of the information from the different widgets and updates + * the iCalObject accordingly. + */ +static void +ee_store_dlg_values_to_ical (EventEditor *ee) +{ + time_t now; + + ee_store_general_values_to_ical (ee); + ee_store_recur_values_to_ical (ee); + + now = time (NULL); /* FIXME: This is not entirely correct; we should check if the values actually changed */ - ical->last_mod = now; + ee->ical->last_mod = now; if (ee->ical->new) - ical->created = now; + ee->ical->created = now; } static void @@ -554,13 +762,15 @@ ee_init_general_page (EventEditor *ee) GtkWidget *l; GtkWidget *hbox; - ee->general_table = (GtkTable *) gtk_table_new (1, 1, 0); + ee->general_table = gtk_table_new (1, 1, FALSE); gtk_container_border_width (GTK_CONTAINER (ee->general_table), 4); + gtk_table_set_row_spacings (GTK_TABLE (ee->general_table), 4); + gtk_table_set_col_spacings (GTK_TABLE (ee->general_table), 4); gtk_notebook_append_page (GTK_NOTEBOOK (ee->notebook), GTK_WIDGET (ee->general_table), gtk_label_new (_("General"))); hbox = gtk_hbox_new (FALSE, 0); - gtk_table_attach (ee->general_table, hbox, + gtk_table_attach (GTK_TABLE (ee->general_table), hbox, 0, 1, OWNER_LINE, OWNER_LINE + 1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, @@ -575,7 +785,7 @@ ee_init_general_page (EventEditor *ee) l = gtk_label_new (_("Description:")); gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5); - gtk_table_attach (ee->general_table, l, + gtk_table_attach (GTK_TABLE (ee->general_table), l, 0, 1, DESC_LINE, DESC_LINE + 1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, @@ -587,28 +797,28 @@ ee_init_general_page (EventEditor *ee) GTK_SIGNAL_FUNC (ee_fill_summary), ee); gtk_widget_set_usize (ee->general_summary, 0, 60); gtk_text_set_editable (GTK_TEXT (ee->general_summary), 1); - gtk_table_attach (ee->general_table, ee->general_summary, + gtk_table_attach (GTK_TABLE (ee->general_table), ee->general_summary, 0, 1, SUMMARY_LINE, SUMMARY_LINE+1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0); l = ee_alarm_widgets (ee); - gtk_table_attach (ee->general_table, l, + gtk_table_attach (GTK_TABLE (ee->general_table), l, 0, 1, ALARM_LINE, ALARM_LINE + 1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0); l = event_editor_setup_time_frame (ee); - gtk_table_attach (ee->general_table, l, + gtk_table_attach (GTK_TABLE (ee->general_table), l, 0, 1, TIME_LINE, TIME_LINE + 1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0); l = ee_classification_widgets (ee); - gtk_table_attach (ee->general_table, l, + gtk_table_attach (GTK_TABLE (ee->general_table), l, 0, 1, CLASS_LINE, CLASS_LINE + 1, GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_SHRINK, @@ -633,106 +843,72 @@ struct { static void recurrence_toggled (GtkRadioButton *radio, EventEditor *ee) { - GSList *list = ee->recur_group; + GSList *list = ee->recur_rr_group; int which; - + if (!GTK_TOGGLE_BUTTON (radio)->active) return; - - for (which = 0; list; list = list->next, which++){ - if (list->data == radio){ - gtk_notebook_set_page (GTK_NOTEBOOK (ee->recur_content), 3-which); + + for (which = 0; list; list = list->next, which++) { + if (list->data == radio) { + gtk_notebook_set_page (GTK_NOTEBOOK (ee->recur_rr_notebook), 3 - which); return; } } } -static GtkWidget * -small_entry (int v) -{ - GtkWidget *entry = gtk_entry_new (); - char buffer [40]; - - sprintf (buffer, "%d", v); - gtk_widget_set_usize (GTK_WIDGET (entry), gdk_string_width (entry->style->font, "WWW"), 0); - gtk_entry_set_text (GTK_ENTRY (entry), buffer); - gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1); - return entry; -} - -static char *numeral_day_names [] = { - N_("1st"), - N_("2nd"), - N_("3rd"), - N_("4th"), - N_("5th"), - N_("6th"), - N_("7th"), - N_("8th"), - N_("9th"), - N_("10th"), - N_("11th"), - N_("12th"), - N_("13th"), - N_("14th"), - N_("15th"), - N_("16th"), - N_("17th"), - N_("18th"), - N_("19th"), - N_("20th"), - N_("21th"), - N_("22th"), - N_("23th"), - N_("24th"), - N_("25th"), - N_("26th"), - N_("27th"), - N_("28th"), - N_("29th"), - N_("30th"), - N_("31th"), - NULL +static struct numbered_item weekday_positions[] = { + { N_("1st"), 1 }, + { N_("2nd"), 2 }, + { N_("3rd"), 3 }, + { N_("4th"), 4 }, + { N_("5th"), 5 }, + { 0 } }; -static char *weekday_names [] = { - N_("Monday"), - N_("Tuesday"), - N_("Wednesday"), - N_("Thursday"), - N_("Friday"), - N_("Saturday"), - N_("Sunday"), - NULL +static struct numbered_item weekday_names[] = { + { N_("Monday"), 1 }, + { N_("Tuesday"), 2 }, + { N_("Wednesday"), 3 }, + { N_("Thursday"), 4 }, + { N_("Friday"), 5 }, + { N_("Saturday"), 6 }, + { N_("Sunday"), 0 }, /* on the spec, Sunday is zero */ + { 0 } }; static GtkWidget * -make_day_list_widget (char **array, int sel) +make_numbered_menu (struct numbered_item *items, int sel) { GtkWidget *option_menu, *menu; int i; option_menu = gtk_option_menu_new (); menu = gtk_menu_new (); - for (i = 0; array [i]; i++){ + + for (i = 0; items[i].text; i++) { GtkWidget *item; - item = gtk_menu_item_new_with_label (_(array [i])); + item = gtk_menu_item_new_with_label (_(items[i].text)); + gtk_object_set_user_data (GTK_OBJECT (item), &items[i]); gtk_menu_append (GTK_MENU (menu), item); gtk_widget_show (item); } + gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu); gtk_option_menu_set_history (GTK_OPTION_MENU (option_menu), sel); + return option_menu; } static void month_sensitize (EventEditor *ee, int state) { - gtk_widget_set_sensitive (ee->recur_month_date, state); + gtk_widget_set_sensitive (ee->recur_rr_month_date, state); + gtk_widget_set_sensitive (ee->recur_rr_month_date_label, state); - gtk_widget_set_sensitive (ee->recur_month_day, !state); - gtk_widget_set_sensitive (ee->recur_month_weekday, !state); + gtk_widget_set_sensitive (ee->recur_rr_month_day, !state); + gtk_widget_set_sensitive (ee->recur_rr_month_weekday, !state); } static void @@ -742,31 +918,35 @@ recur_month_enable_date (GtkToggleButton *button, EventEditor *ee) } static void -ee_rp_init_frequency (EventEditor *ee) +ee_rp_init_rule (EventEditor *ee) { - char *day_names [] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; - GtkWidget *r, *re, *r1, *f, *vbox, *hbox, *week_hbox, *week_day, *w; - GtkWidget *daily, *weekly, *monthly, *yearly; + static char *day_names [] = { N_("Mon"), N_("Tue"), N_("Wed"), N_("Thu"), N_("Fri"), N_("Sat"), N_("Sun") }; + GtkWidget *r, *re, *r1, *f, *vbox, *hbox, *b, *week_hbox, *week_day, *w; + GtkWidget *daily, *weekly, *monthly, *yearly; GtkNotebook *notebook; - GSList *group; - int i, page, day_period, week_period, month_period, year_period; - int week_vector, default_day, def_pos, def_off; - time_t now; - struct tm *tm; - + GSList *group; + int i, page, day_period, week_period, month_period, year_period; + int week_vector, default_day, def_pos, def_off; + time_t now; + struct tm *tm; + now = time (NULL); tm = localtime (&now); - - f = gtk_frame_new (_("Frequency")); - vbox = gtk_vbox_new (0, 0); - hbox = gtk_hbox_new (0, 0); - ee->recur_content = gtk_notebook_new (); - notebook = (GtkNotebook *) ee->recur_content; - + + f = gtk_frame_new (_("Recurrence rule")); + + hbox = gtk_hbox_new (FALSE, 4); + gtk_container_border_width (GTK_CONTAINER (hbox), 4); gtk_container_add (GTK_CONTAINER (f), hbox); - gtk_box_pack_start (GTK_BOX (hbox), vbox, 0, 0, 0); - gtk_box_pack_start (GTK_BOX (hbox), gtk_vseparator_new (), 0, 0, 0); - gtk_box_pack_start (GTK_BOX (hbox), ee->recur_content, TRUE, TRUE, 10); + + vbox = gtk_vbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); + + gtk_box_pack_start (GTK_BOX (hbox), gtk_vseparator_new (), FALSE, FALSE, 0); + + ee->recur_rr_notebook = gtk_notebook_new (); + notebook = GTK_NOTEBOOK (ee->recur_rr_notebook); + gtk_box_pack_start (GTK_BOX (hbox), ee->recur_rr_notebook, TRUE, TRUE, 0); day_period = 1; week_period = 1; @@ -774,123 +954,143 @@ ee_rp_init_frequency (EventEditor *ee) year_period = 1; /* Default to today */ + week_vector = 1 << tm->tm_wday; default_day = tm->tm_mday - 1; def_pos = 0; def_off = 0; /* Determine which should be the default selection */ - if (ee->ical->recur){ + + if (ee->ical->recur) { enum RecurType type = ee->ical->recur->type; int interval = ee->ical->recur->interval; - switch (type){ + switch (type) { case RECUR_DAILY: page = 0; day_period = interval; break; - + case RECUR_WEEKLY: page = 1; week_period = interval; week_vector = ee->ical->recur->weekday; break; - + case RECUR_MONTHLY_BY_POS: page = 2; month_period = interval; def_pos = ee->ical->recur->u.month_pos; break; - + case RECUR_MONTHLY_BY_DAY: page = 2; month_period = interval; default_day = ee->ical->recur->u.month_day; break; - + case RECUR_YEARLY_BY_MONTH: page = 3; year_period = interval; break; - + case RECUR_YEARLY_BY_DAY: page = 4; year_period = interval; break; } - } else { - page = 0; - } - - /* The recureency selector */ - for (i = 0, group = NULL; recurrence_types [i].name; i++){ + } else + page = 0; + + /* The recurrency selector */ + + for (i = 0, group = NULL; recurrence_types [i].name; i++) { r = gtk_radio_button_new_with_label (group, _(recurrence_types [i].name)); group = gtk_radio_button_group (GTK_RADIO_BUTTON (r)); - + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (r), i == page); gtk_signal_connect (GTK_OBJECT (r), "toggled", GTK_SIGNAL_FUNC (recurrence_toggled), ee); - gtk_box_pack_start_defaults (GTK_BOX (vbox), r); + gtk_box_pack_start (GTK_BOX (vbox), r, FALSE, FALSE, 0); } - ee->recur_group = group; + + ee->recur_rr_group = group; /* 1. The daily recurrence */ - daily = gtk_hbox_new (0, 0); - ee->recur_day_period = small_entry (day_period); - gtk_box_pack_start (GTK_BOX (daily), gtk_label_new (_("Every")), 0, 0, 0); - gtk_box_pack_start (GTK_BOX (daily), ee->recur_day_period, 0, 0, 5); - gtk_box_pack_start (GTK_BOX (daily), gtk_label_new (_("day(s)")), 0, 0, 0); + + daily = gtk_vbox_new (FALSE, 0); + + b = gtk_hbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (daily), b, FALSE, FALSE, 0); + + ee->recur_rr_day_period = make_spin_button (day_period, 1, 10000); + gtk_box_pack_start (GTK_BOX (b), gtk_label_new (_("Every")), FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (b), ee->recur_rr_day_period, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (b), gtk_label_new (_("day(s)")), FALSE, FALSE, 0); /* 2. The weekly recurrence */ - weekly = gtk_vbox_new (0, 0); - week_hbox = gtk_hbox_new (0, 0); + + weekly = gtk_vbox_new (FALSE, 4); + + week_hbox = gtk_hbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (weekly), week_hbox, FALSE, FALSE, 0); /* 2.1 The week period selector */ - ee->recur_week_period = small_entry (week_period); - gtk_box_pack_start (GTK_BOX (week_hbox), gtk_label_new _("Every"), 0, 0, 0); - gtk_box_pack_start (GTK_BOX (week_hbox), ee->recur_week_period, 0, 0, 5); - gtk_box_pack_start (GTK_BOX (week_hbox), gtk_label_new (_("week(s)")), 0, 0, 0); - gtk_box_pack_start (GTK_BOX (weekly), week_hbox, 1, 1, 0); + + ee->recur_rr_week_period = make_spin_button (week_period, 1, 10000); + gtk_box_pack_start (GTK_BOX (week_hbox), gtk_label_new _("Every"), FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (week_hbox), ee->recur_rr_week_period, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (week_hbox), gtk_label_new (_("week(s)")), FALSE, FALSE, 0); /* 2.2 The week day selector */ - week_day = gtk_hbox_new (0, 0); - for (i = 0; i < 7; i++){ - ee->recur_week_days [i] = gtk_check_button_new_with_label (_(day_names [i])); - gtk_box_pack_start (GTK_BOX (week_day), ee->recur_week_days [i], 1, 1, 5); + + week_day = gtk_hbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (weekly), week_day, FALSE, FALSE, 0); + + for (i = 0; i < 7; i++) { + ee->recur_rr_week_days [i] = gtk_check_button_new_with_label (_(day_names [i])); + gtk_box_pack_start (GTK_BOX (week_day), ee->recur_rr_week_days [i], FALSE, FALSE, 0); + if (week_vector & (1 << i)) - gtk_toggle_button_toggled (GTK_TOGGLE_BUTTON (ee->recur_week_days [i])); + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (ee->recur_rr_week_days [i]), TRUE); } - gtk_box_pack_start (GTK_BOX (weekly), week_day, 1, 1, 0); - /* 3. The monthly recurrence */ + monthly = gtk_table_new (0, 0, 0); + gtk_table_set_row_spacings (GTK_TABLE (monthly), 4); + gtk_table_set_col_spacings (GTK_TABLE (monthly), 4); + re = gtk_radio_button_new_with_label (NULL, _("Recur on the")); - ee->recur_month_date = make_day_list_widget (numeral_day_names, default_day); - w = gtk_label_new (_("day")); + ee->recur_rr_month_date = make_spin_button (1, 1, 31); /* FIXME: set the day */ + ee->recur_rr_month_date_label = w = gtk_label_new (_("th day of the month")); + gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5); gtk_table_attach (GTK_TABLE (monthly), re, - 0, 1, 0, 1, 0, 0, 0, 0); - gtk_table_attach (GTK_TABLE (monthly), ee->recur_month_date, - 1, 2, 0, 1, 0, 0, 5, 0); + 0, 1, 0, 1, FS, FS, 0, 0); + gtk_table_attach (GTK_TABLE (monthly), ee->recur_rr_month_date, + 1, 2, 0, 1, FS, FS, 0, 0); gtk_table_attach (GTK_TABLE (monthly), w, - 2, 3, 0, 1, 0, 0, 0, 0); + 2, 3, 0, 1, FS, FS, 0, 0); gtk_signal_connect (GTK_OBJECT (re), "toggled", GTK_SIGNAL_FUNC (recur_month_enable_date), ee); - + r1 = gtk_radio_button_new_with_label (gtk_radio_button_group (GTK_RADIO_BUTTON (re)), _("Recur on the")); - ee->recur_month_day = make_day_list_widget (numeral_day_names, 0); - ee->recur_month_weekday = make_day_list_widget (weekday_names, def_pos); + ee->recur_rr_month_day = make_numbered_menu (weekday_positions, 0); + ee->recur_rr_month_weekday = make_numbered_menu (weekday_names, def_pos); gtk_table_attach (GTK_TABLE (monthly), r1, - 0, 1, 1, 2, 0, 0, 0, 0); - gtk_table_attach (GTK_TABLE (monthly), ee->recur_month_day, - 1, 2, 1, 2, 0, 0, 5, 0); - gtk_table_attach (GTK_TABLE (monthly), ee->recur_month_weekday, - 2, 3, 1, 2, 0, 0, 5, 0); + 0, 1, 1, 2, FS, FS, 0, 0); + gtk_table_attach (GTK_TABLE (monthly), ee->recur_rr_month_day, + 1, 2, 1, 2, FS, FS, 0, 0); + gtk_table_attach (GTK_TABLE (monthly), ee->recur_rr_month_weekday, + 2, 3, 1, 2, FS, FS, 0, 0); + gtk_table_attach (GTK_TABLE (monthly), gtk_label_new (_("Every")), - 3, 4, 0, 2, 0, 0, 0, 0); - ee->recur_month_period = small_entry (month_period); - gtk_table_attach (GTK_TABLE (monthly), ee->recur_month_period, - 4, 5, 0, 2, 0, 0, 5, 0); + 3, 4, 0, 2, FS, FS, 0, 0); + ee->recur_rr_month_period = make_spin_button (month_period, 1, 10000); + gtk_table_attach (GTK_TABLE (monthly), ee->recur_rr_month_period, + 4, 5, 0, 2, FS, FS, 0, 0); gtk_table_attach (GTK_TABLE (monthly), gtk_label_new (_("month(s)")), - 5, 6, 0, 2, 0, 0, 0, 0); + 5, 6, 0, 2, FS, FS, 0, 0); + if (ee->ical->recur) { if (ee->ical->recur->type == RECUR_MONTHLY_BY_POS) gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (r1), 1); @@ -898,13 +1098,19 @@ ee_rp_init_frequency (EventEditor *ee) recur_month_enable_date (GTK_TOGGLE_BUTTON (re), ee); /* 4. The yearly recurrence */ - yearly = gtk_hbox_new (0, 0); - ee->recur_year_period = small_entry (year_period); - gtk_box_pack_start (GTK_BOX (yearly), gtk_label_new (_("Every")), 0, 0, 0); - gtk_box_pack_start (GTK_BOX (yearly), ee->recur_year_period, 0, 0, 5); - gtk_box_pack_start (GTK_BOX (yearly), gtk_label_new (_("year(s)")), 0, 0, 0); - + + yearly = gtk_vbox_new (FALSE, 0); + + b = gtk_hbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (yearly), b, FALSE, FALSE, 0); + + ee->recur_rr_year_period = make_spin_button (year_period, 1, 10000); + gtk_box_pack_start (GTK_BOX (b), gtk_label_new (_("Every")), FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (b), ee->recur_rr_year_period, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (b), gtk_label_new (_("year(s)")), FALSE, FALSE, 0); + /* Finish setting this up */ + gtk_notebook_append_page (notebook, daily, gtk_label_new ("")); gtk_notebook_append_page (notebook, weekly, gtk_label_new ("")); gtk_notebook_append_page (notebook, monthly, gtk_label_new ("")); @@ -913,18 +1119,292 @@ ee_rp_init_frequency (EventEditor *ee) gtk_notebook_set_show_border (notebook, FALSE); gtk_notebook_set_page (notebook, page); - + /* Attach to the main table */ - gtk_box_pack_start (GTK_BOX (ee->recur_table), f, 1, 0, 0); -}; + + gtk_table_attach (GTK_TABLE (ee->recur_table), f, + 0, 2, 0, 1, + GTK_FILL | GTK_SHRINK, + GTK_FILL | GTK_SHRINK, + 0, 0); +} static void -ee_init_recurrent_page (EventEditor *ee) +sensitize_by_toggle (GtkToggleButton *toggle, gpointer data) { - ee->recur_table = gtk_vbox_new (0, 0); - gtk_notebook_append_page (GTK_NOTEBOOK (ee->notebook), GTK_WIDGET (ee->recur_table), - gtk_label_new (_("Repeating"))); - ee_rp_init_frequency (ee); + gtk_widget_set_sensitive (GTK_WIDGET (data), toggle->active); +} + +static void +ee_rp_init_ending_date (EventEditor *ee) +{ + GtkWidget *frame; + GtkWidget *vbox; + GSList *group; + GtkWidget *radio0, *radio1, *radio2; + GtkWidget *hbox; + GtkWidget *ihbox; + GtkWidget *widget; + time_t enddate; + + frame = gtk_frame_new (_("Ending date")); + + vbox = gtk_vbox_new (TRUE, 4); + gtk_container_border_width (GTK_CONTAINER (vbox), 4); + gtk_container_add (GTK_CONTAINER (frame), vbox); + + group = NULL; + + /* repeat forever */ + + hbox = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + + radio0 = gtk_radio_button_new_with_label (group, _("Repeat forever")); + group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio0)); + gtk_box_pack_start (GTK_BOX (hbox), radio0, FALSE, FALSE, 0); + + /* end on date */ + + hbox = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + + radio1 = gtk_radio_button_new_with_label (group, _("End on")); + group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio1)); + gtk_box_pack_start (GTK_BOX (hbox), radio1, FALSE, FALSE, 0); + + ihbox = gtk_hbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (hbox), ihbox, FALSE, FALSE, 0); + + if (ee->ical->recur) + enddate = ee->ical->recur->enddate; + else + enddate = ee->ical->dtend; + + ee->recur_ed_end_on = widget = gnome_date_edit_new (enddate, FALSE); + gtk_box_pack_start (GTK_BOX (ihbox), widget, FALSE, FALSE, 0); + + gtk_signal_connect (GTK_OBJECT (radio1), "toggled", + (GtkSignalFunc) sensitize_by_toggle, + ihbox); + + gtk_widget_set_sensitive (ihbox, FALSE); + + /* end after n occurrences */ + + hbox = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + + radio2 = gtk_radio_button_new_with_label (group, _("End after")); + group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio2)); + gtk_box_pack_start (GTK_BOX (hbox), radio2, FALSE, FALSE, 0); + + ihbox = gtk_hbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (hbox), ihbox, FALSE, FALSE, 0); + + ee->recur_ed_end_after = widget = make_spin_button (2, 1, 10000); + gtk_box_pack_start (GTK_BOX (ihbox), widget, FALSE, FALSE, 0); + + widget = gtk_label_new (_("occurrence(s)")); + gtk_box_pack_start (GTK_BOX (ihbox), widget, FALSE, FALSE, 0); + + gtk_signal_connect (GTK_OBJECT (radio2), "toggled", + (GtkSignalFunc) sensitize_by_toggle, + ihbox); + + gtk_widget_set_sensitive (ihbox, FALSE); + + /* Activate appropriate item */ + + if (ee->ical->recur) { + if (ee->ical->recur->_enddate == 0) { + if (ee->ical->recur->duration == 0) + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (radio0), TRUE); + else { + gtk_spin_button_set_value (GTK_SPIN_BUTTON (ee->recur_ed_end_after), + ee->ical->recur->duration); + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (radio2), TRUE); + } + } else { + gnome_date_edit_set_time (GNOME_DATE_EDIT (ee->recur_ed_end_on), ee->ical->recur->enddate); + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (radio1), TRUE); + } + } + + /* Done, add to main table */ + + ee->recur_ed_group = group; + + gtk_table_attach (GTK_TABLE (ee->recur_table), frame, + 0, 1, 1, 2, + GTK_FILL | GTK_SHRINK, + GTK_FILL | GTK_SHRINK, + 0, 0); +} + +static char * +get_exception_string (time_t t) +{ + static char buf[256]; + + strftime (buf, 256, "%a %b %d %Y", localtime (&t)); /* FIXME: how to i18n this? */ + return buf; +} + +static void +append_exception (EventEditor *ee, time_t t) +{ + time_t *tt; + char *c[1]; + int i; + + c[0] = get_exception_string (t); + + tt = g_new (time_t, 1); + *tt = t; + + i = gtk_clist_append (GTK_CLIST (ee->recur_ex_clist), c); + gtk_clist_set_row_data (GTK_CLIST (ee->recur_ex_clist), i, tt); + + gtk_widget_set_sensitive (ee->recur_ex_vbox, TRUE); +} + +static void +fill_exception_clist (EventEditor *ee) +{ + GList *list; + + for (list = ee->ical->exdate; list; list = list->next) + append_exception (ee, *((time_t *) list->data)); +} + +static void +add_exception (GtkWidget *widget, EventEditor *ee) +{ + time_t t; + + t = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->recur_ex_date)); + append_exception (ee, t); +} + +static void +change_exception (GtkWidget *widget, EventEditor *ee) +{ + GtkCList *clist; + time_t *t; + int sel; + + clist = GTK_CLIST (ee->recur_ex_clist); + sel = (gint) clist->selection->data; + + t = gtk_clist_get_row_data (clist, sel); + *t = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->recur_ex_date)); + + gtk_clist_set_text (clist, sel, 0, get_exception_string (*t)); +} + +static void +delete_exception (GtkWidget *widget, EventEditor *ee) +{ + GtkCList *clist; + int sel; + + clist = GTK_CLIST (ee->recur_ex_clist); + sel = (gint) clist->selection->data; + + g_free (gtk_clist_get_row_data (clist, sel)); /* free the time_t stored there */ + + gtk_clist_remove (clist, sel); + + if (clist->rows == 0) + gtk_widget_set_sensitive (ee->recur_ex_vbox, FALSE); +} + +static void +ee_rp_init_exceptions (EventEditor *ee) +{ + GtkWidget *frame; + GtkWidget *hbox; + GtkWidget *vbox; + GtkWidget *ivbox; + GtkWidget *widget; + + frame = gtk_frame_new (_("Exceptions")); + + hbox = gtk_hbox_new (FALSE, 4); + gtk_container_border_width (GTK_CONTAINER (hbox), 4); + gtk_container_add (GTK_CONTAINER (frame), hbox); + + vbox = gtk_vbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); + + ee->recur_ex_date = widget = gnome_date_edit_new (time (NULL), FALSE); + gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0); + + widget = gtk_button_new_with_label (_("Add exception")); + gtk_signal_connect (GTK_OBJECT (widget), "clicked", + (GtkSignalFunc) add_exception, + ee); + gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0); + + ee->recur_ex_vbox = ivbox = gtk_vbox_new (FALSE, 4); + gtk_widget_set_sensitive (ivbox, FALSE); /* at first there are no items to change or delete */ + gtk_box_pack_start (GTK_BOX (vbox), ivbox, FALSE, FALSE, 0); + + widget = gtk_button_new_with_label (_("Change selected")); + gtk_signal_connect (GTK_OBJECT (widget), "clicked", + (GtkSignalFunc) change_exception, + ee); + gtk_box_pack_start (GTK_BOX (ivbox), widget, FALSE, FALSE, 0); + + widget = gtk_button_new_with_label (_("Delete selected")); + gtk_signal_connect (GTK_OBJECT (widget), "clicked", + (GtkSignalFunc) delete_exception, + ee); + gtk_box_pack_start (GTK_BOX (ivbox), widget, FALSE, FALSE, 0); + + ee->recur_ex_clist = widget = gtk_clist_new (1); + gtk_clist_set_selection_mode (GTK_CLIST (widget), GTK_SELECTION_BROWSE); + gtk_clist_set_policy (GTK_CLIST (widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + fill_exception_clist (ee); + gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0); + + /* Done, add to main table */ + + gtk_table_attach (GTK_TABLE (ee->recur_table), frame, + 1, 2, 1, 2, + GTK_EXPAND | GTK_FILL | GTK_SHRINK, + GTK_FILL | GTK_SHRINK, + 0, 0); +} + +static void +ee_init_recurrence_page (EventEditor *ee) +{ + ee->recur_table = gtk_table_new (2, 2, FALSE); + gtk_container_border_width (GTK_CONTAINER (ee->recur_table), 4); + gtk_table_set_row_spacings (GTK_TABLE (ee->recur_table), 4); + gtk_table_set_col_spacings (GTK_TABLE (ee->recur_table), 4); + + ee->recur_page_label = gtk_label_new (_("Recurrence")); + + gtk_notebook_append_page (GTK_NOTEBOOK (ee->notebook), ee->recur_table, + ee->recur_page_label); + + ee_rp_init_rule (ee); + ee_rp_init_ending_date (ee); + ee_rp_init_exceptions (ee); + + /* Make the recurrence button sensitize the recurrence page */ + + recur_check_toggled (GTK_TOGGLE_BUTTON (ee->general_recur), ee); + + gtk_signal_connect (GTK_OBJECT (ee->general_recur), "toggled", + (GtkSignalFunc) recur_check_toggled, + ee); + + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (ee->general_recur), + (ee->ical->recur != NULL)); } static void @@ -940,7 +1420,7 @@ event_editor_init_widgets (EventEditor *ee) /* Init the various configuration pages */ ee_init_general_page (ee); ee_init_summary_page (ee); - ee_init_recurrent_page (ee); + ee_init_recurrence_page (ee); /* Separator */ gtk_box_pack_start (GTK_BOX (ee->vbox), gtk_hseparator_new (), 0, 0, 0); @@ -949,9 +1429,7 @@ event_editor_init_widgets (EventEditor *ee) gtk_box_pack_start (GTK_BOX (ee->vbox), ee_create_buttons (ee), 0, 0, 5); /* We show all of the contained widgets */ - gtk_widget_show_all (GTK_WIDGET (ee)); - /* And we hide the toplevel, to be consistent with the rest of Gtk */ - gtk_widget_hide (GTK_WIDGET (ee)); + gtk_widget_show_all (GTK_BIN (ee)->child); } static void @@ -971,7 +1449,7 @@ event_editor_destroy (GtkObject *object) ee = EVENT_EDITOR (object); if (ee->ical) - ee->ical->user_data = NULL;/* we are no longer editing it */ + ee->ical->user_data = NULL; /* we are no longer editing it */ } GtkWidget * @@ -991,7 +1469,7 @@ event_editor_new (GnomeCalendar *gcal, iCalObject *ical) ical->new = 1; } - ical->user_data = ee; /* so that the world can know we are editing it */ + ical->user_data = ee; /* so that the world can know we are editing it */ ee->ical = ical; ee->gnome_cal = gcal; @@ -999,8 +1477,3 @@ event_editor_new (GnomeCalendar *gcal, iCalObject *ical) return retval; } - -/* - * New event: Create iCal, edit, check result: Ok: insert; Cancel: destroy iCal - * Edit event: fetch iCal, edit, check result: Ok: remove from calendar, add to calendar; Cancel: nothing - */ diff --git a/calendar/eventedit.h b/calendar/eventedit.h index b1af11060f..ccb2224450 100644 --- a/calendar/eventedit.h +++ b/calendar/eventedit.h @@ -24,7 +24,7 @@ typedef struct { GtkWidget *vbox; GtkWidget *general; - GtkTable *general_table; + GtkWidget *general_table; GtkWidget *general_time_table; GtkWidget *general_allday; GtkWidget *general_recur; @@ -33,21 +33,28 @@ typedef struct { GtkWidget *start_time, *end_time; GtkWidget *general_radios; + GtkWidget *recur_page_label; GtkWidget *recur_table; - GSList *recur_group; - GtkWidget *recur_content; - GtkWidget *recur_day_period; /* GtkEntry */ - - GtkWidget *recur_week_period; /* GtkEntry */ - GtkWidget *recur_week_days [7]; - - GtkWidget *recur_month_date; - GtkWidget *recur_month_day; - GtkWidget *recur_month_weekday; - GtkWidget *recur_month_period; /* GtkEntry */ - - GtkWidget *recur_year_period; /* GtkEntry */ + GSList *recur_rr_group; + GtkWidget *recur_rr_notebook; + GtkWidget *recur_rr_day_period; + GtkWidget *recur_rr_week_period; + GtkWidget *recur_rr_week_days [7]; + GtkWidget *recur_rr_month_date; + GtkWidget *recur_rr_month_date_label; + GtkWidget *recur_rr_month_day; + GtkWidget *recur_rr_month_weekday; + GtkWidget *recur_rr_month_period; + GtkWidget *recur_rr_year_period; + + GSList *recur_ed_group; + GtkWidget *recur_ed_end_on; + GtkWidget *recur_ed_end_after; + + GtkWidget *recur_ex_date; + GtkWidget *recur_ex_vbox; + GtkWidget *recur_ex_clist; /* The associated ical object */ iCalObject *ical; diff --git a/calendar/gncal-full-day.c b/calendar/gncal-full-day.c index c3151f6dcf..7a20b3789d 100644 --- a/calendar/gncal-full-day.c +++ b/calendar/gncal-full-day.c @@ -340,6 +340,7 @@ static void new_appointment (GtkWidget *widget, gpointer data) { GncalFullDay *fullday; + GtkWidget *ee; fullday = GNCAL_FULL_DAY (data); @@ -349,17 +350,20 @@ new_appointment (GtkWidget *widget, gpointer data) * at which the button was clicked on when popping up the menu. */ - event_editor_new (fullday->calendar, NULL); + ee = event_editor_new (fullday->calendar, NULL); + gtk_widget_show (ee); } static void edit_appointment (GtkWidget *widget, gpointer data) { Child *child; + GtkWidget *ee; child = data; - event_editor_new (GNCAL_FULL_DAY (child->widget->parent)->calendar, child->ico); + ee = event_editor_new (GNCAL_FULL_DAY (child->widget->parent)->calendar, child->ico); + gtk_widget_show (ee); } static void diff --git a/calendar/gnome-cal.c b/calendar/gnome-cal.c index c6ca54331f..14c9a53975 100644 --- a/calendar/gnome-cal.c +++ b/calendar/gnome-cal.c @@ -130,7 +130,7 @@ gnome_calendar_goto (GnomeCalendar *gcal, time_t new_time) time_start_of_day (new_time), time_end_of_day (new_time)); } else if (current == gcal->year_view) - printf ("updating year view\n"); + gncal_year_view_set (GNCAL_YEAR_VIEW (gcal->year_view), new_time); else printf ("My penguin is gone!\n"); gcal->current_display = new_time; diff --git a/calendar/gui/eventedit.c b/calendar/gui/eventedit.c index ff36d77507..7a1a582729 100644 --- a/calendar/gui/eventedit.c +++ b/calendar/gui/eventedit.c @@ -23,6 +23,11 @@ static char *class_names [] = { "PUBLIC", "PRIVATE", "CONFIDENTIAL" }; static GtkWindowClass *parent_class; +struct numbered_item { + char *text; + int num; +}; + guint event_editor_get_type (void) @@ -63,6 +68,19 @@ adjust (GtkWidget *w, gfloat x, gfloat y, gfloat xs, gfloat ys) return a; } +static GtkWidget * +make_spin_button (int val, int low, int high) +{ + GtkAdjustment *adj; + GtkWidget *spin; + + adj = GTK_ADJUSTMENT (gtk_adjustment_new (val, low, high, 1, 10, 10)); + spin = gtk_spin_button_new (adj, 0.5, 0); + gtk_widget_set_usize (spin, 60, 0); + + return spin; +} + /* * Checks if the day range occupies all the day, and if so, check the * box accordingly @@ -191,6 +209,13 @@ set_all_day (GtkToggleButton *toggle, EventEditor *ee) gnome_date_edit_set_time (GNOME_DATE_EDIT (ee->end_time), mktime (tm)); } +static void +recur_check_toggled (GtkToggleButton *toggle, EventEditor *ee) +{ + gtk_widget_set_sensitive (ee->recur_page_label, toggle->active); + gtk_widget_set_sensitive (ee->recur_table, toggle->active); +} + static GtkWidget * event_editor_setup_time_frame (EventEditor *ee) { @@ -206,7 +231,7 @@ event_editor_setup_time_frame (EventEditor *ee) 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->start_time = start_time = gnome_date_edit_new (ee->ical->dtstart, TRUE); gnome_date_edit_set_popup_range ((GnomeDateEdit *) start_time, day_begin, day_end); gtk_signal_connect (GTK_OBJECT (start_time), "date_changed", GTK_SIGNAL_FUNC (check_dates), ee); @@ -222,7 +247,7 @@ event_editor_setup_time_frame (EventEditor *ee) 0, 0); /* 2. End time */ - ee->end_time = end_time = gnome_date_edit_new (ee->ical->dtend); + ee->end_time = end_time = gnome_date_edit_new (ee->ical->dtend, TRUE); gnome_date_edit_set_popup_range ((GnomeDateEdit *) end_time, day_begin, day_end); gtk_signal_connect (GTK_OBJECT (end_time), "date_changed", GTK_SIGNAL_FUNC (check_dates), ee); @@ -304,8 +329,6 @@ alarm_toggle (GtkToggleButton *toggle, CalendarAlarm *alarm) static void ee_create_ae (GtkTable *table, char *str, CalendarAlarm *alarm, enum AlarmType type, int y) { - char buffer [40]; - 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); @@ -313,11 +336,8 @@ ee_create_ae (GtkTable *table, char *str, CalendarAlarm *alarm, enum AlarmType t 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); + alarm->w_count = make_spin_button (alarm->count, 0, 10000); gtk_table_attach (table, alarm->w_count, 1, 2, y, y+1, FS, FS, 0, 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); @@ -438,15 +458,11 @@ ee_store_alarm (CalendarAlarm *alarm, enum AlarmType type) idx++; alarm->units = idx; - alarm->count = atoi (gtk_entry_get_text (GTK_ENTRY (alarm->w_count))); + alarm->count = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (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) +ee_store_general_values_to_ical (EventEditor *ee) { GtkRadioButton *radio = GTK_RADIO_BUTTON (ee->general_radios); iCalObject *ical = ee->ical; @@ -475,12 +491,204 @@ ee_store_dlg_values_to_ical (EventEditor *ee) } g_free (ical->class); ical->class = g_strdup (class_names [idx]); +} + +static int +option_menu_active_number (GtkWidget *omenu) +{ + GtkWidget *menu; + GtkWidget *item; + struct numbered_item *ni; + + menu = gtk_option_menu_get_menu (GTK_OPTION_MENU (omenu)); + item = gtk_menu_get_active (GTK_MENU (menu)); + + ni = gtk_object_get_user_data (GTK_OBJECT (item)); + + return ni->num; +} + +static void +ee_store_recur_rule_to_ical (EventEditor *ee) +{ + iCalObject *ical; + int i, j; + GSList *list; + + ical = ee->ical; + + for (i = 0, list = ee->recur_rr_group; list; i++, list = list->next) + if (GTK_TOGGLE_BUTTON (list->data)->active) + break; + + i = g_slist_length (ee->recur_rr_group) - i - 1; /* buttons are stored in reverse order of insertion */ + + switch (i) { + case 0: + /* Daily */ + ical->recur->type = RECUR_DAILY; + ical->recur->interval = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ee->recur_rr_day_period)); + break; + + case 1: + /* Weekly */ + ical->recur->type = RECUR_WEEKLY; + ical->recur->interval = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ee->recur_rr_week_period)); + ical->recur->weekday = 0; + + for (j = 0; j < 7; j++) + if (GTK_TOGGLE_BUTTON (ee->recur_rr_week_days[j])->active) { + if (j == 6) + ical->recur->weekday |= 1 << 0; /* sunday is at bit 0 */ + else + ical->recur->weekday |= 1 << (j + 1); + } + + break; + + case 2: + /* Monthly */ + + if (GTK_WIDGET_SENSITIVE (ee->recur_rr_month_date)) { + /* by day */ + + ical->recur->type = RECUR_MONTHLY_BY_DAY; + ical->recur->u.month_day = + gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ee->recur_rr_month_date)); + } else { + /* by position */ + + ical->recur->type = RECUR_MONTHLY_BY_POS; + + ical->recur->u.month_pos = option_menu_active_number (ee->recur_rr_month_day); + ical->recur->u.month_day = option_menu_active_number (ee->recur_rr_month_weekday); + } + + ical->recur->interval = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ee->recur_rr_month_period)); + + break; + + case 3: + /* Yearly */ + ical->recur->type = RECUR_YEARLY_BY_DAY; + /* FIXME: need to specify anything else? I am assuming the code will look at the dtstart + * to figure out when to recur. - Federico + */ + break; + + default: + g_assert_not_reached (); + } +} + +static void +ee_store_recur_end_to_ical (EventEditor *ee) +{ + iCalObject *ical; + GSList *list; + int i; + + /* Ending date of recurrence */ + + ical = ee->ical; + + for (i = 0, list = ee->recur_ed_group; list; i++, list = list->next) + if (GTK_TOGGLE_BUTTON (list->data)->active) + break; + + i = g_slist_length (ee->recur_ed_group) - i - 1; /* the list is stored in reverse order of insertion */ + + switch (i) { + case 0: + /* repeat forever */ + ical->recur->_enddate = 0; + ical->recur->enddate = 0; + ical->recur->duration = 0; + break; + + case 1: + /* end date */ + ical->recur->_enddate = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->recur_ed_end_on)); + ical->recur->enddate = ical->recur->enddate; + ical->recur->duration = 0; + break; + + case 2: + /* end after n occurrences */ + ical->recur->duration = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (ee->recur_ed_end_after)); + ical_object_compute_end (ical); + break; + + default: + g_assert_not_reached (); + break; + } +} + +static void +free_exdate (iCalObject *ical) +{ + GList *list; + + if (!ical->exdate) + return; + + for (list = ical->exdate; list; list = list->next) + g_free (list->data); + + g_list_free (ical->exdate); + ical->exdate = NULL; +} + +static void +ee_store_recur_exceptions_to_ical (EventEditor *ee) +{ + iCalObject *ical; + GtkCList *clist; + int i; + time_t *t; + + ical = ee->ical; + clist = GTK_CLIST (ee->recur_ex_clist); + + free_exdate (ical); + + for (i = 0; i < clist->rows; i++) { + t = gtk_clist_get_row_data (clist, i); + ical->exdate = g_list_prepend (ical->exdate, t); + } +} + +static void +ee_store_recur_values_to_ical (EventEditor *ee) +{ + if (!ee->ical->recur) + ee->ical->recur = g_new0 (Recurrence, 1); + + ee_store_recur_rule_to_ical (ee); + ee_store_recur_end_to_ical (ee); + ee_store_recur_exceptions_to_ical (ee); +} + +/* + * Retrieves all of the information from the different widgets and updates + * the iCalObject accordingly. + */ +static void +ee_store_dlg_values_to_ical (EventEditor *ee) +{ + time_t now; + + ee_store_general_values_to_ical (ee); + ee_store_recur_values_to_ical (ee); + + now = time (NULL); /* FIXME: This is not entirely correct; we should check if the values actually changed */ - ical->last_mod = now; + ee->ical->last_mod = now; if (ee->ical->new) - ical->created = now; + ee->ical->created = now; } static void @@ -554,13 +762,15 @@ ee_init_general_page (EventEditor *ee) GtkWidget *l; GtkWidget *hbox; - ee->general_table = (GtkTable *) gtk_table_new (1, 1, 0); + ee->general_table = gtk_table_new (1, 1, FALSE); gtk_container_border_width (GTK_CONTAINER (ee->general_table), 4); + gtk_table_set_row_spacings (GTK_TABLE (ee->general_table), 4); + gtk_table_set_col_spacings (GTK_TABLE (ee->general_table), 4); gtk_notebook_append_page (GTK_NOTEBOOK (ee->notebook), GTK_WIDGET (ee->general_table), gtk_label_new (_("General"))); hbox = gtk_hbox_new (FALSE, 0); - gtk_table_attach (ee->general_table, hbox, + gtk_table_attach (GTK_TABLE (ee->general_table), hbox, 0, 1, OWNER_LINE, OWNER_LINE + 1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, @@ -575,7 +785,7 @@ ee_init_general_page (EventEditor *ee) l = gtk_label_new (_("Description:")); gtk_misc_set_alignment (GTK_MISC (l), 0.0, 0.5); - gtk_table_attach (ee->general_table, l, + gtk_table_attach (GTK_TABLE (ee->general_table), l, 0, 1, DESC_LINE, DESC_LINE + 1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, @@ -587,28 +797,28 @@ ee_init_general_page (EventEditor *ee) GTK_SIGNAL_FUNC (ee_fill_summary), ee); gtk_widget_set_usize (ee->general_summary, 0, 60); gtk_text_set_editable (GTK_TEXT (ee->general_summary), 1); - gtk_table_attach (ee->general_table, ee->general_summary, + gtk_table_attach (GTK_TABLE (ee->general_table), ee->general_summary, 0, 1, SUMMARY_LINE, SUMMARY_LINE+1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0); l = ee_alarm_widgets (ee); - gtk_table_attach (ee->general_table, l, + gtk_table_attach (GTK_TABLE (ee->general_table), l, 0, 1, ALARM_LINE, ALARM_LINE + 1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0); l = event_editor_setup_time_frame (ee); - gtk_table_attach (ee->general_table, l, + gtk_table_attach (GTK_TABLE (ee->general_table), l, 0, 1, TIME_LINE, TIME_LINE + 1, GTK_EXPAND | GTK_FILL | GTK_SHRINK, GTK_FILL | GTK_SHRINK, 0, 0); l = ee_classification_widgets (ee); - gtk_table_attach (ee->general_table, l, + gtk_table_attach (GTK_TABLE (ee->general_table), l, 0, 1, CLASS_LINE, CLASS_LINE + 1, GTK_EXPAND | GTK_SHRINK, GTK_FILL | GTK_SHRINK, @@ -633,106 +843,72 @@ struct { static void recurrence_toggled (GtkRadioButton *radio, EventEditor *ee) { - GSList *list = ee->recur_group; + GSList *list = ee->recur_rr_group; int which; - + if (!GTK_TOGGLE_BUTTON (radio)->active) return; - - for (which = 0; list; list = list->next, which++){ - if (list->data == radio){ - gtk_notebook_set_page (GTK_NOTEBOOK (ee->recur_content), 3-which); + + for (which = 0; list; list = list->next, which++) { + if (list->data == radio) { + gtk_notebook_set_page (GTK_NOTEBOOK (ee->recur_rr_notebook), 3 - which); return; } } } -static GtkWidget * -small_entry (int v) -{ - GtkWidget *entry = gtk_entry_new (); - char buffer [40]; - - sprintf (buffer, "%d", v); - gtk_widget_set_usize (GTK_WIDGET (entry), gdk_string_width (entry->style->font, "WWW"), 0); - gtk_entry_set_text (GTK_ENTRY (entry), buffer); - gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1); - return entry; -} - -static char *numeral_day_names [] = { - N_("1st"), - N_("2nd"), - N_("3rd"), - N_("4th"), - N_("5th"), - N_("6th"), - N_("7th"), - N_("8th"), - N_("9th"), - N_("10th"), - N_("11th"), - N_("12th"), - N_("13th"), - N_("14th"), - N_("15th"), - N_("16th"), - N_("17th"), - N_("18th"), - N_("19th"), - N_("20th"), - N_("21th"), - N_("22th"), - N_("23th"), - N_("24th"), - N_("25th"), - N_("26th"), - N_("27th"), - N_("28th"), - N_("29th"), - N_("30th"), - N_("31th"), - NULL +static struct numbered_item weekday_positions[] = { + { N_("1st"), 1 }, + { N_("2nd"), 2 }, + { N_("3rd"), 3 }, + { N_("4th"), 4 }, + { N_("5th"), 5 }, + { 0 } }; -static char *weekday_names [] = { - N_("Monday"), - N_("Tuesday"), - N_("Wednesday"), - N_("Thursday"), - N_("Friday"), - N_("Saturday"), - N_("Sunday"), - NULL +static struct numbered_item weekday_names[] = { + { N_("Monday"), 1 }, + { N_("Tuesday"), 2 }, + { N_("Wednesday"), 3 }, + { N_("Thursday"), 4 }, + { N_("Friday"), 5 }, + { N_("Saturday"), 6 }, + { N_("Sunday"), 0 }, /* on the spec, Sunday is zero */ + { 0 } }; static GtkWidget * -make_day_list_widget (char **array, int sel) +make_numbered_menu (struct numbered_item *items, int sel) { GtkWidget *option_menu, *menu; int i; option_menu = gtk_option_menu_new (); menu = gtk_menu_new (); - for (i = 0; array [i]; i++){ + + for (i = 0; items[i].text; i++) { GtkWidget *item; - item = gtk_menu_item_new_with_label (_(array [i])); + item = gtk_menu_item_new_with_label (_(items[i].text)); + gtk_object_set_user_data (GTK_OBJECT (item), &items[i]); gtk_menu_append (GTK_MENU (menu), item); gtk_widget_show (item); } + gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu); gtk_option_menu_set_history (GTK_OPTION_MENU (option_menu), sel); + return option_menu; } static void month_sensitize (EventEditor *ee, int state) { - gtk_widget_set_sensitive (ee->recur_month_date, state); + gtk_widget_set_sensitive (ee->recur_rr_month_date, state); + gtk_widget_set_sensitive (ee->recur_rr_month_date_label, state); - gtk_widget_set_sensitive (ee->recur_month_day, !state); - gtk_widget_set_sensitive (ee->recur_month_weekday, !state); + gtk_widget_set_sensitive (ee->recur_rr_month_day, !state); + gtk_widget_set_sensitive (ee->recur_rr_month_weekday, !state); } static void @@ -742,31 +918,35 @@ recur_month_enable_date (GtkToggleButton *button, EventEditor *ee) } static void -ee_rp_init_frequency (EventEditor *ee) +ee_rp_init_rule (EventEditor *ee) { - char *day_names [] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; - GtkWidget *r, *re, *r1, *f, *vbox, *hbox, *week_hbox, *week_day, *w; - GtkWidget *daily, *weekly, *monthly, *yearly; + static char *day_names [] = { N_("Mon"), N_("Tue"), N_("Wed"), N_("Thu"), N_("Fri"), N_("Sat"), N_("Sun") }; + GtkWidget *r, *re, *r1, *f, *vbox, *hbox, *b, *week_hbox, *week_day, *w; + GtkWidget *daily, *weekly, *monthly, *yearly; GtkNotebook *notebook; - GSList *group; - int i, page, day_period, week_period, month_period, year_period; - int week_vector, default_day, def_pos, def_off; - time_t now; - struct tm *tm; - + GSList *group; + int i, page, day_period, week_period, month_period, year_period; + int week_vector, default_day, def_pos, def_off; + time_t now; + struct tm *tm; + now = time (NULL); tm = localtime (&now); - - f = gtk_frame_new (_("Frequency")); - vbox = gtk_vbox_new (0, 0); - hbox = gtk_hbox_new (0, 0); - ee->recur_content = gtk_notebook_new (); - notebook = (GtkNotebook *) ee->recur_content; - + + f = gtk_frame_new (_("Recurrence rule")); + + hbox = gtk_hbox_new (FALSE, 4); + gtk_container_border_width (GTK_CONTAINER (hbox), 4); gtk_container_add (GTK_CONTAINER (f), hbox); - gtk_box_pack_start (GTK_BOX (hbox), vbox, 0, 0, 0); - gtk_box_pack_start (GTK_BOX (hbox), gtk_vseparator_new (), 0, 0, 0); - gtk_box_pack_start (GTK_BOX (hbox), ee->recur_content, TRUE, TRUE, 10); + + vbox = gtk_vbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); + + gtk_box_pack_start (GTK_BOX (hbox), gtk_vseparator_new (), FALSE, FALSE, 0); + + ee->recur_rr_notebook = gtk_notebook_new (); + notebook = GTK_NOTEBOOK (ee->recur_rr_notebook); + gtk_box_pack_start (GTK_BOX (hbox), ee->recur_rr_notebook, TRUE, TRUE, 0); day_period = 1; week_period = 1; @@ -774,123 +954,143 @@ ee_rp_init_frequency (EventEditor *ee) year_period = 1; /* Default to today */ + week_vector = 1 << tm->tm_wday; default_day = tm->tm_mday - 1; def_pos = 0; def_off = 0; /* Determine which should be the default selection */ - if (ee->ical->recur){ + + if (ee->ical->recur) { enum RecurType type = ee->ical->recur->type; int interval = ee->ical->recur->interval; - switch (type){ + switch (type) { case RECUR_DAILY: page = 0; day_period = interval; break; - + case RECUR_WEEKLY: page = 1; week_period = interval; week_vector = ee->ical->recur->weekday; break; - + case RECUR_MONTHLY_BY_POS: page = 2; month_period = interval; def_pos = ee->ical->recur->u.month_pos; break; - + case RECUR_MONTHLY_BY_DAY: page = 2; month_period = interval; default_day = ee->ical->recur->u.month_day; break; - + case RECUR_YEARLY_BY_MONTH: page = 3; year_period = interval; break; - + case RECUR_YEARLY_BY_DAY: page = 4; year_period = interval; break; } - } else { - page = 0; - } - - /* The recureency selector */ - for (i = 0, group = NULL; recurrence_types [i].name; i++){ + } else + page = 0; + + /* The recurrency selector */ + + for (i = 0, group = NULL; recurrence_types [i].name; i++) { r = gtk_radio_button_new_with_label (group, _(recurrence_types [i].name)); group = gtk_radio_button_group (GTK_RADIO_BUTTON (r)); - + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (r), i == page); gtk_signal_connect (GTK_OBJECT (r), "toggled", GTK_SIGNAL_FUNC (recurrence_toggled), ee); - gtk_box_pack_start_defaults (GTK_BOX (vbox), r); + gtk_box_pack_start (GTK_BOX (vbox), r, FALSE, FALSE, 0); } - ee->recur_group = group; + + ee->recur_rr_group = group; /* 1. The daily recurrence */ - daily = gtk_hbox_new (0, 0); - ee->recur_day_period = small_entry (day_period); - gtk_box_pack_start (GTK_BOX (daily), gtk_label_new (_("Every")), 0, 0, 0); - gtk_box_pack_start (GTK_BOX (daily), ee->recur_day_period, 0, 0, 5); - gtk_box_pack_start (GTK_BOX (daily), gtk_label_new (_("day(s)")), 0, 0, 0); + + daily = gtk_vbox_new (FALSE, 0); + + b = gtk_hbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (daily), b, FALSE, FALSE, 0); + + ee->recur_rr_day_period = make_spin_button (day_period, 1, 10000); + gtk_box_pack_start (GTK_BOX (b), gtk_label_new (_("Every")), FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (b), ee->recur_rr_day_period, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (b), gtk_label_new (_("day(s)")), FALSE, FALSE, 0); /* 2. The weekly recurrence */ - weekly = gtk_vbox_new (0, 0); - week_hbox = gtk_hbox_new (0, 0); + + weekly = gtk_vbox_new (FALSE, 4); + + week_hbox = gtk_hbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (weekly), week_hbox, FALSE, FALSE, 0); /* 2.1 The week period selector */ - ee->recur_week_period = small_entry (week_period); - gtk_box_pack_start (GTK_BOX (week_hbox), gtk_label_new _("Every"), 0, 0, 0); - gtk_box_pack_start (GTK_BOX (week_hbox), ee->recur_week_period, 0, 0, 5); - gtk_box_pack_start (GTK_BOX (week_hbox), gtk_label_new (_("week(s)")), 0, 0, 0); - gtk_box_pack_start (GTK_BOX (weekly), week_hbox, 1, 1, 0); + + ee->recur_rr_week_period = make_spin_button (week_period, 1, 10000); + gtk_box_pack_start (GTK_BOX (week_hbox), gtk_label_new _("Every"), FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (week_hbox), ee->recur_rr_week_period, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (week_hbox), gtk_label_new (_("week(s)")), FALSE, FALSE, 0); /* 2.2 The week day selector */ - week_day = gtk_hbox_new (0, 0); - for (i = 0; i < 7; i++){ - ee->recur_week_days [i] = gtk_check_button_new_with_label (_(day_names [i])); - gtk_box_pack_start (GTK_BOX (week_day), ee->recur_week_days [i], 1, 1, 5); + + week_day = gtk_hbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (weekly), week_day, FALSE, FALSE, 0); + + for (i = 0; i < 7; i++) { + ee->recur_rr_week_days [i] = gtk_check_button_new_with_label (_(day_names [i])); + gtk_box_pack_start (GTK_BOX (week_day), ee->recur_rr_week_days [i], FALSE, FALSE, 0); + if (week_vector & (1 << i)) - gtk_toggle_button_toggled (GTK_TOGGLE_BUTTON (ee->recur_week_days [i])); + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (ee->recur_rr_week_days [i]), TRUE); } - gtk_box_pack_start (GTK_BOX (weekly), week_day, 1, 1, 0); - /* 3. The monthly recurrence */ + monthly = gtk_table_new (0, 0, 0); + gtk_table_set_row_spacings (GTK_TABLE (monthly), 4); + gtk_table_set_col_spacings (GTK_TABLE (monthly), 4); + re = gtk_radio_button_new_with_label (NULL, _("Recur on the")); - ee->recur_month_date = make_day_list_widget (numeral_day_names, default_day); - w = gtk_label_new (_("day")); + ee->recur_rr_month_date = make_spin_button (1, 1, 31); /* FIXME: set the day */ + ee->recur_rr_month_date_label = w = gtk_label_new (_("th day of the month")); + gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5); gtk_table_attach (GTK_TABLE (monthly), re, - 0, 1, 0, 1, 0, 0, 0, 0); - gtk_table_attach (GTK_TABLE (monthly), ee->recur_month_date, - 1, 2, 0, 1, 0, 0, 5, 0); + 0, 1, 0, 1, FS, FS, 0, 0); + gtk_table_attach (GTK_TABLE (monthly), ee->recur_rr_month_date, + 1, 2, 0, 1, FS, FS, 0, 0); gtk_table_attach (GTK_TABLE (monthly), w, - 2, 3, 0, 1, 0, 0, 0, 0); + 2, 3, 0, 1, FS, FS, 0, 0); gtk_signal_connect (GTK_OBJECT (re), "toggled", GTK_SIGNAL_FUNC (recur_month_enable_date), ee); - + r1 = gtk_radio_button_new_with_label (gtk_radio_button_group (GTK_RADIO_BUTTON (re)), _("Recur on the")); - ee->recur_month_day = make_day_list_widget (numeral_day_names, 0); - ee->recur_month_weekday = make_day_list_widget (weekday_names, def_pos); + ee->recur_rr_month_day = make_numbered_menu (weekday_positions, 0); + ee->recur_rr_month_weekday = make_numbered_menu (weekday_names, def_pos); gtk_table_attach (GTK_TABLE (monthly), r1, - 0, 1, 1, 2, 0, 0, 0, 0); - gtk_table_attach (GTK_TABLE (monthly), ee->recur_month_day, - 1, 2, 1, 2, 0, 0, 5, 0); - gtk_table_attach (GTK_TABLE (monthly), ee->recur_month_weekday, - 2, 3, 1, 2, 0, 0, 5, 0); + 0, 1, 1, 2, FS, FS, 0, 0); + gtk_table_attach (GTK_TABLE (monthly), ee->recur_rr_month_day, + 1, 2, 1, 2, FS, FS, 0, 0); + gtk_table_attach (GTK_TABLE (monthly), ee->recur_rr_month_weekday, + 2, 3, 1, 2, FS, FS, 0, 0); + gtk_table_attach (GTK_TABLE (monthly), gtk_label_new (_("Every")), - 3, 4, 0, 2, 0, 0, 0, 0); - ee->recur_month_period = small_entry (month_period); - gtk_table_attach (GTK_TABLE (monthly), ee->recur_month_period, - 4, 5, 0, 2, 0, 0, 5, 0); + 3, 4, 0, 2, FS, FS, 0, 0); + ee->recur_rr_month_period = make_spin_button (month_period, 1, 10000); + gtk_table_attach (GTK_TABLE (monthly), ee->recur_rr_month_period, + 4, 5, 0, 2, FS, FS, 0, 0); gtk_table_attach (GTK_TABLE (monthly), gtk_label_new (_("month(s)")), - 5, 6, 0, 2, 0, 0, 0, 0); + 5, 6, 0, 2, FS, FS, 0, 0); + if (ee->ical->recur) { if (ee->ical->recur->type == RECUR_MONTHLY_BY_POS) gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (r1), 1); @@ -898,13 +1098,19 @@ ee_rp_init_frequency (EventEditor *ee) recur_month_enable_date (GTK_TOGGLE_BUTTON (re), ee); /* 4. The yearly recurrence */ - yearly = gtk_hbox_new (0, 0); - ee->recur_year_period = small_entry (year_period); - gtk_box_pack_start (GTK_BOX (yearly), gtk_label_new (_("Every")), 0, 0, 0); - gtk_box_pack_start (GTK_BOX (yearly), ee->recur_year_period, 0, 0, 5); - gtk_box_pack_start (GTK_BOX (yearly), gtk_label_new (_("year(s)")), 0, 0, 0); - + + yearly = gtk_vbox_new (FALSE, 0); + + b = gtk_hbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (yearly), b, FALSE, FALSE, 0); + + ee->recur_rr_year_period = make_spin_button (year_period, 1, 10000); + gtk_box_pack_start (GTK_BOX (b), gtk_label_new (_("Every")), FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (b), ee->recur_rr_year_period, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (b), gtk_label_new (_("year(s)")), FALSE, FALSE, 0); + /* Finish setting this up */ + gtk_notebook_append_page (notebook, daily, gtk_label_new ("")); gtk_notebook_append_page (notebook, weekly, gtk_label_new ("")); gtk_notebook_append_page (notebook, monthly, gtk_label_new ("")); @@ -913,18 +1119,292 @@ ee_rp_init_frequency (EventEditor *ee) gtk_notebook_set_show_border (notebook, FALSE); gtk_notebook_set_page (notebook, page); - + /* Attach to the main table */ - gtk_box_pack_start (GTK_BOX (ee->recur_table), f, 1, 0, 0); -}; + + gtk_table_attach (GTK_TABLE (ee->recur_table), f, + 0, 2, 0, 1, + GTK_FILL | GTK_SHRINK, + GTK_FILL | GTK_SHRINK, + 0, 0); +} static void -ee_init_recurrent_page (EventEditor *ee) +sensitize_by_toggle (GtkToggleButton *toggle, gpointer data) { - ee->recur_table = gtk_vbox_new (0, 0); - gtk_notebook_append_page (GTK_NOTEBOOK (ee->notebook), GTK_WIDGET (ee->recur_table), - gtk_label_new (_("Repeating"))); - ee_rp_init_frequency (ee); + gtk_widget_set_sensitive (GTK_WIDGET (data), toggle->active); +} + +static void +ee_rp_init_ending_date (EventEditor *ee) +{ + GtkWidget *frame; + GtkWidget *vbox; + GSList *group; + GtkWidget *radio0, *radio1, *radio2; + GtkWidget *hbox; + GtkWidget *ihbox; + GtkWidget *widget; + time_t enddate; + + frame = gtk_frame_new (_("Ending date")); + + vbox = gtk_vbox_new (TRUE, 4); + gtk_container_border_width (GTK_CONTAINER (vbox), 4); + gtk_container_add (GTK_CONTAINER (frame), vbox); + + group = NULL; + + /* repeat forever */ + + hbox = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + + radio0 = gtk_radio_button_new_with_label (group, _("Repeat forever")); + group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio0)); + gtk_box_pack_start (GTK_BOX (hbox), radio0, FALSE, FALSE, 0); + + /* end on date */ + + hbox = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + + radio1 = gtk_radio_button_new_with_label (group, _("End on")); + group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio1)); + gtk_box_pack_start (GTK_BOX (hbox), radio1, FALSE, FALSE, 0); + + ihbox = gtk_hbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (hbox), ihbox, FALSE, FALSE, 0); + + if (ee->ical->recur) + enddate = ee->ical->recur->enddate; + else + enddate = ee->ical->dtend; + + ee->recur_ed_end_on = widget = gnome_date_edit_new (enddate, FALSE); + gtk_box_pack_start (GTK_BOX (ihbox), widget, FALSE, FALSE, 0); + + gtk_signal_connect (GTK_OBJECT (radio1), "toggled", + (GtkSignalFunc) sensitize_by_toggle, + ihbox); + + gtk_widget_set_sensitive (ihbox, FALSE); + + /* end after n occurrences */ + + hbox = gtk_hbox_new (FALSE, 0); + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); + + radio2 = gtk_radio_button_new_with_label (group, _("End after")); + group = gtk_radio_button_group (GTK_RADIO_BUTTON (radio2)); + gtk_box_pack_start (GTK_BOX (hbox), radio2, FALSE, FALSE, 0); + + ihbox = gtk_hbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (hbox), ihbox, FALSE, FALSE, 0); + + ee->recur_ed_end_after = widget = make_spin_button (2, 1, 10000); + gtk_box_pack_start (GTK_BOX (ihbox), widget, FALSE, FALSE, 0); + + widget = gtk_label_new (_("occurrence(s)")); + gtk_box_pack_start (GTK_BOX (ihbox), widget, FALSE, FALSE, 0); + + gtk_signal_connect (GTK_OBJECT (radio2), "toggled", + (GtkSignalFunc) sensitize_by_toggle, + ihbox); + + gtk_widget_set_sensitive (ihbox, FALSE); + + /* Activate appropriate item */ + + if (ee->ical->recur) { + if (ee->ical->recur->_enddate == 0) { + if (ee->ical->recur->duration == 0) + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (radio0), TRUE); + else { + gtk_spin_button_set_value (GTK_SPIN_BUTTON (ee->recur_ed_end_after), + ee->ical->recur->duration); + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (radio2), TRUE); + } + } else { + gnome_date_edit_set_time (GNOME_DATE_EDIT (ee->recur_ed_end_on), ee->ical->recur->enddate); + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (radio1), TRUE); + } + } + + /* Done, add to main table */ + + ee->recur_ed_group = group; + + gtk_table_attach (GTK_TABLE (ee->recur_table), frame, + 0, 1, 1, 2, + GTK_FILL | GTK_SHRINK, + GTK_FILL | GTK_SHRINK, + 0, 0); +} + +static char * +get_exception_string (time_t t) +{ + static char buf[256]; + + strftime (buf, 256, "%a %b %d %Y", localtime (&t)); /* FIXME: how to i18n this? */ + return buf; +} + +static void +append_exception (EventEditor *ee, time_t t) +{ + time_t *tt; + char *c[1]; + int i; + + c[0] = get_exception_string (t); + + tt = g_new (time_t, 1); + *tt = t; + + i = gtk_clist_append (GTK_CLIST (ee->recur_ex_clist), c); + gtk_clist_set_row_data (GTK_CLIST (ee->recur_ex_clist), i, tt); + + gtk_widget_set_sensitive (ee->recur_ex_vbox, TRUE); +} + +static void +fill_exception_clist (EventEditor *ee) +{ + GList *list; + + for (list = ee->ical->exdate; list; list = list->next) + append_exception (ee, *((time_t *) list->data)); +} + +static void +add_exception (GtkWidget *widget, EventEditor *ee) +{ + time_t t; + + t = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->recur_ex_date)); + append_exception (ee, t); +} + +static void +change_exception (GtkWidget *widget, EventEditor *ee) +{ + GtkCList *clist; + time_t *t; + int sel; + + clist = GTK_CLIST (ee->recur_ex_clist); + sel = (gint) clist->selection->data; + + t = gtk_clist_get_row_data (clist, sel); + *t = gnome_date_edit_get_date (GNOME_DATE_EDIT (ee->recur_ex_date)); + + gtk_clist_set_text (clist, sel, 0, get_exception_string (*t)); +} + +static void +delete_exception (GtkWidget *widget, EventEditor *ee) +{ + GtkCList *clist; + int sel; + + clist = GTK_CLIST (ee->recur_ex_clist); + sel = (gint) clist->selection->data; + + g_free (gtk_clist_get_row_data (clist, sel)); /* free the time_t stored there */ + + gtk_clist_remove (clist, sel); + + if (clist->rows == 0) + gtk_widget_set_sensitive (ee->recur_ex_vbox, FALSE); +} + +static void +ee_rp_init_exceptions (EventEditor *ee) +{ + GtkWidget *frame; + GtkWidget *hbox; + GtkWidget *vbox; + GtkWidget *ivbox; + GtkWidget *widget; + + frame = gtk_frame_new (_("Exceptions")); + + hbox = gtk_hbox_new (FALSE, 4); + gtk_container_border_width (GTK_CONTAINER (hbox), 4); + gtk_container_add (GTK_CONTAINER (frame), hbox); + + vbox = gtk_vbox_new (FALSE, 4); + gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0); + + ee->recur_ex_date = widget = gnome_date_edit_new (time (NULL), FALSE); + gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0); + + widget = gtk_button_new_with_label (_("Add exception")); + gtk_signal_connect (GTK_OBJECT (widget), "clicked", + (GtkSignalFunc) add_exception, + ee); + gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, FALSE, 0); + + ee->recur_ex_vbox = ivbox = gtk_vbox_new (FALSE, 4); + gtk_widget_set_sensitive (ivbox, FALSE); /* at first there are no items to change or delete */ + gtk_box_pack_start (GTK_BOX (vbox), ivbox, FALSE, FALSE, 0); + + widget = gtk_button_new_with_label (_("Change selected")); + gtk_signal_connect (GTK_OBJECT (widget), "clicked", + (GtkSignalFunc) change_exception, + ee); + gtk_box_pack_start (GTK_BOX (ivbox), widget, FALSE, FALSE, 0); + + widget = gtk_button_new_with_label (_("Delete selected")); + gtk_signal_connect (GTK_OBJECT (widget), "clicked", + (GtkSignalFunc) delete_exception, + ee); + gtk_box_pack_start (GTK_BOX (ivbox), widget, FALSE, FALSE, 0); + + ee->recur_ex_clist = widget = gtk_clist_new (1); + gtk_clist_set_selection_mode (GTK_CLIST (widget), GTK_SELECTION_BROWSE); + gtk_clist_set_policy (GTK_CLIST (widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + fill_exception_clist (ee); + gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0); + + /* Done, add to main table */ + + gtk_table_attach (GTK_TABLE (ee->recur_table), frame, + 1, 2, 1, 2, + GTK_EXPAND | GTK_FILL | GTK_SHRINK, + GTK_FILL | GTK_SHRINK, + 0, 0); +} + +static void +ee_init_recurrence_page (EventEditor *ee) +{ + ee->recur_table = gtk_table_new (2, 2, FALSE); + gtk_container_border_width (GTK_CONTAINER (ee->recur_table), 4); + gtk_table_set_row_spacings (GTK_TABLE (ee->recur_table), 4); + gtk_table_set_col_spacings (GTK_TABLE (ee->recur_table), 4); + + ee->recur_page_label = gtk_label_new (_("Recurrence")); + + gtk_notebook_append_page (GTK_NOTEBOOK (ee->notebook), ee->recur_table, + ee->recur_page_label); + + ee_rp_init_rule (ee); + ee_rp_init_ending_date (ee); + ee_rp_init_exceptions (ee); + + /* Make the recurrence button sensitize the recurrence page */ + + recur_check_toggled (GTK_TOGGLE_BUTTON (ee->general_recur), ee); + + gtk_signal_connect (GTK_OBJECT (ee->general_recur), "toggled", + (GtkSignalFunc) recur_check_toggled, + ee); + + gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (ee->general_recur), + (ee->ical->recur != NULL)); } static void @@ -940,7 +1420,7 @@ event_editor_init_widgets (EventEditor *ee) /* Init the various configuration pages */ ee_init_general_page (ee); ee_init_summary_page (ee); - ee_init_recurrent_page (ee); + ee_init_recurrence_page (ee); /* Separator */ gtk_box_pack_start (GTK_BOX (ee->vbox), gtk_hseparator_new (), 0, 0, 0); @@ -949,9 +1429,7 @@ event_editor_init_widgets (EventEditor *ee) gtk_box_pack_start (GTK_BOX (ee->vbox), ee_create_buttons (ee), 0, 0, 5); /* We show all of the contained widgets */ - gtk_widget_show_all (GTK_WIDGET (ee)); - /* And we hide the toplevel, to be consistent with the rest of Gtk */ - gtk_widget_hide (GTK_WIDGET (ee)); + gtk_widget_show_all (GTK_BIN (ee)->child); } static void @@ -971,7 +1449,7 @@ event_editor_destroy (GtkObject *object) ee = EVENT_EDITOR (object); if (ee->ical) - ee->ical->user_data = NULL;/* we are no longer editing it */ + ee->ical->user_data = NULL; /* we are no longer editing it */ } GtkWidget * @@ -991,7 +1469,7 @@ event_editor_new (GnomeCalendar *gcal, iCalObject *ical) ical->new = 1; } - ical->user_data = ee; /* so that the world can know we are editing it */ + ical->user_data = ee; /* so that the world can know we are editing it */ ee->ical = ical; ee->gnome_cal = gcal; @@ -999,8 +1477,3 @@ event_editor_new (GnomeCalendar *gcal, iCalObject *ical) return retval; } - -/* - * New event: Create iCal, edit, check result: Ok: insert; Cancel: destroy iCal - * Edit event: fetch iCal, edit, check result: Ok: remove from calendar, add to calendar; Cancel: nothing - */ diff --git a/calendar/gui/eventedit.h b/calendar/gui/eventedit.h index b1af11060f..ccb2224450 100644 --- a/calendar/gui/eventedit.h +++ b/calendar/gui/eventedit.h @@ -24,7 +24,7 @@ typedef struct { GtkWidget *vbox; GtkWidget *general; - GtkTable *general_table; + GtkWidget *general_table; GtkWidget *general_time_table; GtkWidget *general_allday; GtkWidget *general_recur; @@ -33,21 +33,28 @@ typedef struct { GtkWidget *start_time, *end_time; GtkWidget *general_radios; + GtkWidget *recur_page_label; GtkWidget *recur_table; - GSList *recur_group; - GtkWidget *recur_content; - GtkWidget *recur_day_period; /* GtkEntry */ - - GtkWidget *recur_week_period; /* GtkEntry */ - GtkWidget *recur_week_days [7]; - - GtkWidget *recur_month_date; - GtkWidget *recur_month_day; - GtkWidget *recur_month_weekday; - GtkWidget *recur_month_period; /* GtkEntry */ - - GtkWidget *recur_year_period; /* GtkEntry */ + GSList *recur_rr_group; + GtkWidget *recur_rr_notebook; + GtkWidget *recur_rr_day_period; + GtkWidget *recur_rr_week_period; + GtkWidget *recur_rr_week_days [7]; + GtkWidget *recur_rr_month_date; + GtkWidget *recur_rr_month_date_label; + GtkWidget *recur_rr_month_day; + GtkWidget *recur_rr_month_weekday; + GtkWidget *recur_rr_month_period; + GtkWidget *recur_rr_year_period; + + GSList *recur_ed_group; + GtkWidget *recur_ed_end_on; + GtkWidget *recur_ed_end_after; + + GtkWidget *recur_ex_date; + GtkWidget *recur_ex_vbox; + GtkWidget *recur_ex_clist; /* The associated ical object */ iCalObject *ical; diff --git a/calendar/gui/gncal-full-day.c b/calendar/gui/gncal-full-day.c index c3151f6dcf..7a20b3789d 100644 --- a/calendar/gui/gncal-full-day.c +++ b/calendar/gui/gncal-full-day.c @@ -340,6 +340,7 @@ static void new_appointment (GtkWidget *widget, gpointer data) { GncalFullDay *fullday; + GtkWidget *ee; fullday = GNCAL_FULL_DAY (data); @@ -349,17 +350,20 @@ new_appointment (GtkWidget *widget, gpointer data) * at which the button was clicked on when popping up the menu. */ - event_editor_new (fullday->calendar, NULL); + ee = event_editor_new (fullday->calendar, NULL); + gtk_widget_show (ee); } static void edit_appointment (GtkWidget *widget, gpointer data) { Child *child; + GtkWidget *ee; child = data; - event_editor_new (GNCAL_FULL_DAY (child->widget->parent)->calendar, child->ico); + ee = event_editor_new (GNCAL_FULL_DAY (child->widget->parent)->calendar, child->ico); + gtk_widget_show (ee); } static void diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index c6ca54331f..14c9a53975 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -130,7 +130,7 @@ gnome_calendar_goto (GnomeCalendar *gcal, time_t new_time) time_start_of_day (new_time), time_end_of_day (new_time)); } else if (current == gcal->year_view) - printf ("updating year view\n"); + gncal_year_view_set (GNCAL_YEAR_VIEW (gcal->year_view), new_time); else printf ("My penguin is gone!\n"); gcal->current_display = new_time; diff --git a/calendar/gui/main.c b/calendar/gui/main.c index 6075cc0f7d..089b544ebc 100644 --- a/calendar/gui/main.c +++ b/calendar/gui/main.c @@ -114,7 +114,10 @@ about_calendar_cmd (GtkWidget *widget, void *data) void display_objedit (GtkWidget *widget, GnomeCalendar *gcal) { - event_editor_new (gcal, NULL); + GtkWidget *ee; + + ee = event_editor_new (gcal, NULL); + gtk_widget_show (ee); } void diff --git a/calendar/gui/year-view.c b/calendar/gui/year-view.c index a8972a7558..a922ac2748 100644 --- a/calendar/gui/year-view.c +++ b/calendar/gui/year-view.c @@ -9,11 +9,23 @@ */ #include "gncal-year-view.h" +#include "calendar.h" #include "timeutil.h" static void gncal_year_view_init (GncalYearView *yview); static void +double_click(GtkWidget *widget, gpointer data) +{ + printf("Recieved double click.\n"); +} + +static void +do_nothing(GtkCalendarClass *c) +{ +} + +static void select_day(GtkWidget *widget, gpointer data) { int i; @@ -68,6 +80,7 @@ gncal_year_view_init (GncalYearView *yview) yview->handler [i] = 0; } + yview->gcal = NULL; yview->year_label = NULL; yview->year = 0; } @@ -102,16 +115,19 @@ gncal_year_view_new (GnomeCalendar *calendar, time_t date) i = y * 3 + x; yview->calendar[i] = gtk_calendar_new(); - gtk_calendar_display_options(GTK_CALENDAR(yview->calendar[i]), GTK_CALENDAR_SHOW_DAY_NAMES); + gtk_calendar_display_options(GTK_CALENDAR(yview->calendar[i]), + GTK_CALENDAR_SHOW_DAY_NAMES | + GTK_CALENDAR_NO_MONTH_CHANGE); frame = gtk_frame_new(NULL); vbox = gtk_vbox_new(0,0); yview->handler[i] = - gtk_signal_connect(GTK_OBJECT(yview->calendar[i]), - "day_selected", - GTK_SIGNAL_FUNC(select_day), - (gpointer *) yview); + gtk_signal_connect(GTK_OBJECT(yview->calendar[i]), "day_selected", + GTK_SIGNAL_FUNC(select_day), (gpointer *) yview); + gtk_signal_connect(GTK_OBJECT(yview->calendar[i]), "day_selected_double_click", + GTK_SIGNAL_FUNC(double_click), (gpointer *) yview); + my_tm.tm_mon = i; strftime(monthbuff, 40, "%B", &my_tm); label = gtk_label_new(monthbuff); diff --git a/calendar/main.c b/calendar/main.c index 6075cc0f7d..089b544ebc 100644 --- a/calendar/main.c +++ b/calendar/main.c @@ -114,7 +114,10 @@ about_calendar_cmd (GtkWidget *widget, void *data) void display_objedit (GtkWidget *widget, GnomeCalendar *gcal) { - event_editor_new (gcal, NULL); + GtkWidget *ee; + + ee = event_editor_new (gcal, NULL); + gtk_widget_show (ee); } void diff --git a/calendar/pcs/calobj.c b/calendar/pcs/calobj.c index 2ff626c469..73406b9a5f 100644 --- a/calendar/pcs/calobj.c +++ b/calendar/pcs/calobj.c @@ -12,8 +12,6 @@ #include "timeutil.h" #include "versit/vcc.h" -static void ical_object_compute_end (iCalObject *ico); - iCalObject * ical_object_new (void) { @@ -1004,7 +1002,7 @@ duration_callback (iCalObject *ico, time_t start, time_t end, void *closure) int *count = closure; (*count)++; - if (ico->recur->duration == *count){ + if (ico->recur->duration == *count) { ico->recur->enddate = end; return 0; } @@ -1019,7 +1017,6 @@ ical_object_compute_end (iCalObject *ico) g_return_if_fail (ico->recur != NULL); + ico->recur->_enddate = 0; ical_object_generate_events (ico, ico->dtstart, 0, duration_callback, &count); } - - diff --git a/calendar/pcs/calobj.h b/calendar/pcs/calobj.h index c499568bf7..48b3012695 100644 --- a/calendar/pcs/calobj.h +++ b/calendar/pcs/calobj.h @@ -176,7 +176,10 @@ void ical_object_destroy (iCalObject *ico); iCalObject *ical_object_create_from_vobject (VObject *obj, const char *object_name); VObject *ical_object_to_vobject (iCalObject *ical); void ical_foreach (GList *events, calendarfn fn, void *closure); -void ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendarfn cb, void *closure); +void ical_object_generate_events (iCalObject *ico, time_t start, time_t end, calendarfn cb, void *closure); + +/* Computes the enddate field of the recurrence based on the duration */ +void ical_object_compute_end (iCalObject *ico); END_GNOME_DECLS diff --git a/calendar/year-view.c b/calendar/year-view.c index a8972a7558..a922ac2748 100644 --- a/calendar/year-view.c +++ b/calendar/year-view.c @@ -9,11 +9,23 @@ */ #include "gncal-year-view.h" +#include "calendar.h" #include "timeutil.h" static void gncal_year_view_init (GncalYearView *yview); static void +double_click(GtkWidget *widget, gpointer data) +{ + printf("Recieved double click.\n"); +} + +static void +do_nothing(GtkCalendarClass *c) +{ +} + +static void select_day(GtkWidget *widget, gpointer data) { int i; @@ -68,6 +80,7 @@ gncal_year_view_init (GncalYearView *yview) yview->handler [i] = 0; } + yview->gcal = NULL; yview->year_label = NULL; yview->year = 0; } @@ -102,16 +115,19 @@ gncal_year_view_new (GnomeCalendar *calendar, time_t date) i = y * 3 + x; yview->calendar[i] = gtk_calendar_new(); - gtk_calendar_display_options(GTK_CALENDAR(yview->calendar[i]), GTK_CALENDAR_SHOW_DAY_NAMES); + gtk_calendar_display_options(GTK_CALENDAR(yview->calendar[i]), + GTK_CALENDAR_SHOW_DAY_NAMES | + GTK_CALENDAR_NO_MONTH_CHANGE); frame = gtk_frame_new(NULL); vbox = gtk_vbox_new(0,0); yview->handler[i] = - gtk_signal_connect(GTK_OBJECT(yview->calendar[i]), - "day_selected", - GTK_SIGNAL_FUNC(select_day), - (gpointer *) yview); + gtk_signal_connect(GTK_OBJECT(yview->calendar[i]), "day_selected", + GTK_SIGNAL_FUNC(select_day), (gpointer *) yview); + gtk_signal_connect(GTK_OBJECT(yview->calendar[i]), "day_selected_double_click", + GTK_SIGNAL_FUNC(double_click), (gpointer *) yview); + my_tm.tm_mon = i; strftime(monthbuff, 40, "%B", &my_tm); label = gtk_label_new(monthbuff); |