From e4e894969ece81b2ed434c7d66e4b2d1b42244d3 Mon Sep 17 00:00:00 2001 From: Damon Chaplin Date: Thu, 25 Oct 2001 23:28:15 +0000 Subject: subtract 1 from any positive BYSETPOS value, since our array is 0-based. 2001-10-25 Damon Chaplin * cal-util/cal-recur.c (cal_obj_bysetpos_filter): subtract 1 from any positive BYSETPOS value, since our array is 0-based. * gui/dialogs/recurrence-page.c (simple_recur_to_comp): (recurrence_page_fill_widgets): Outlook (2000) will not accept monthly recurrences like BYDAY=2TU. Instead it uses BYDAY=TU;BYSETPOS=2. So to be compatable with it we now do the same, although we still accept and convert the old format. * cal-client/cal-client.c (cal_client_get_component_as_string): new function to return a complete VCALENDAR string containing a VEVENT or VTODO with all the VTIMEZONEs it uses. * gui/dialogs/comp-editor.c (save_as_ok): use above function so we save the VTIMEZONE data with the VEVENT/VTODO. Fixes bug #????. Also made sure we output "METHOD:PUBLISH" since Outlook (2000) will not import it otherwise. * gui/dialogs/comp-editor.c (page_mapped_cb): (page_unmapped_cb): install/uninstall the GtkAccelGroup for the page. (comp_editor_append_page): connect to the map/unmap signals to install/uninstall the accelerators. (This is all for bug #11609, though of course it doesn't work too well in GTK+ 1.2 anyway.) * gui/dialogs/task-page.c (get_widgets): * gui/dialogs/task-details-page.c (get_widgets): * gui/dialogs/schedule-page.c (get_widgets): * gui/dialogs/recurrence-page.c (get_widgets): * gui/dialogs/meeting-page.c (get_widgets): * gui/dialogs/event-page.c (get_widgets): * gui/dialogs/alarm-page.c (get_widgets): got the GtkAccelGroup from the original window, ref'ed it and placed it in the CompEditorPage struct. * gui/dialogs/comp-editor-page.c (comp_editor_page_destroy): unref any GtkAccelGroup for the page. * gui/dialogs/task-page.glade: changed '_Confidential' to 'Con_fidential' as it clashed with '_Contacts'. It now matches the event editor as well. * gui/dialogs/event-page.glade: * gui/dialogs/task-page.glade: Set CAN_FOCUS to TRUE for the custom EDateEdit widgets, and set them as the accel targets of the labels. svn path=/trunk/; revision=14108 --- calendar/ChangeLog | 47 +++++++++++++++++ calendar/cal-client/cal-client.c | 89 +++++++++++++++++++++++++------- calendar/cal-client/cal-client.h | 5 ++ calendar/cal-util/cal-recur.c | 10 ++-- calendar/gui/dialogs/alarm-page.c | 12 +++++ calendar/gui/dialogs/comp-editor-page.c | 6 +++ calendar/gui/dialogs/comp-editor-page.h | 6 +++ calendar/gui/dialogs/comp-editor.c | 70 +++++++++++++++---------- calendar/gui/dialogs/event-page.c | 12 +++++ calendar/gui/dialogs/event-page.glade | 6 +++ calendar/gui/dialogs/meeting-page.c | 12 +++++ calendar/gui/dialogs/recurrence-page.c | 63 ++++++++++++++++------ calendar/gui/dialogs/schedule-page.c | 12 +++++ calendar/gui/dialogs/task-details-page.c | 12 +++++ calendar/gui/dialogs/task-page.c | 12 +++++ calendar/gui/dialogs/task-page.glade | 8 ++- 16 files changed, 317 insertions(+), 65 deletions(-) diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 254798af66..ab865715e4 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,50 @@ +2001-10-25 Damon Chaplin + + * cal-util/cal-recur.c (cal_obj_bysetpos_filter): subtract 1 from + any positive BYSETPOS value, since our array is 0-based. + + * gui/dialogs/recurrence-page.c (simple_recur_to_comp): + (recurrence_page_fill_widgets): Outlook (2000) will not accept monthly + recurrences like BYDAY=2TU. Instead it uses BYDAY=TU;BYSETPOS=2. + So to be compatable with it we now do the same, although we still + accept and convert the old format. + + * cal-client/cal-client.c (cal_client_get_component_as_string): new + function to return a complete VCALENDAR string containing a VEVENT + or VTODO with all the VTIMEZONEs it uses. + + * gui/dialogs/comp-editor.c (save_as_ok): use above function so we + save the VTIMEZONE data with the VEVENT/VTODO. Fixes bug #????. + Also made sure we output "METHOD:PUBLISH" since Outlook (2000) will + not import it otherwise. + + * gui/dialogs/comp-editor.c (page_mapped_cb): + (page_unmapped_cb): install/uninstall the GtkAccelGroup for the page. + (comp_editor_append_page): connect to the map/unmap signals to + install/uninstall the accelerators. (This is all for bug #11609, + though of course it doesn't work too well in GTK+ 1.2 anyway.) + + * gui/dialogs/task-page.c (get_widgets): + * gui/dialogs/task-details-page.c (get_widgets): + * gui/dialogs/schedule-page.c (get_widgets): + * gui/dialogs/recurrence-page.c (get_widgets): + * gui/dialogs/meeting-page.c (get_widgets): + * gui/dialogs/event-page.c (get_widgets): + * gui/dialogs/alarm-page.c (get_widgets): got the GtkAccelGroup from + the original window, ref'ed it and placed it in the CompEditorPage + struct. + + * gui/dialogs/comp-editor-page.c (comp_editor_page_destroy): unref + any GtkAccelGroup for the page. + + * gui/dialogs/task-page.glade: changed '_Confidential' to + 'Con_fidential' as it clashed with '_Contacts'. It now matches the + event editor as well. + + * gui/dialogs/event-page.glade: + * gui/dialogs/task-page.glade: Set CAN_FOCUS to TRUE for the custom + EDateEdit widgets, and set them as the accel targets of the labels. + 2001-10-25 Rodrigo Moya * gui/dialogs/comp-editor.c (save_comp): show an error message when diff --git a/calendar/cal-client/cal-client.c b/calendar/cal-client/cal-client.c index 79bfae2b1a..1590e0c1e8 100644 --- a/calendar/cal-client/cal-client.c +++ b/calendar/cal-client/cal-client.c @@ -1983,6 +1983,8 @@ typedef struct _ForeachTZIDCallbackData ForeachTZIDCallbackData; struct _ForeachTZIDCallbackData { CalClient *client; GHashTable *timezone_hash; + gboolean include_all_timezones; + gboolean success; }; /* This adds the VTIMEZONE given by the TZID parameter to the GHashTable in @@ -2004,19 +2006,29 @@ foreach_tzid_callback (icalparameter *param, void *cbdata) if (!tzid) return; - /* Check if it is in our cache. If it is, it must already be on the - server so return. */ - if (g_hash_table_lookup (priv->timezones, tzid)) - return; - /* Check if we've already added it to the GHashTable. */ if (g_hash_table_lookup (data->timezone_hash, tzid)) return; - /* Check if it is a builtin timezone. If it isn't, return. */ - zone = icaltimezone_get_builtin_timezone_from_tzid (tzid); - if (!zone) - return; + if (data->include_all_timezones) { + CalClientGetStatus status; + + status = cal_client_get_timezone (data->client, tzid, &zone); + if (status != CAL_CLIENT_GET_SUCCESS) { + data->success = FALSE; + return; + } + } else { + /* Check if it is in our cache. If it is, it must already be + on the server so return. */ + if (g_hash_table_lookup (priv->timezones, tzid)) + return; + + /* Check if it is a builtin timezone. If it isn't, return. */ + zone = icaltimezone_get_builtin_timezone_from_tzid (tzid); + if (!zone) + return; + } /* Convert it to a string and add it to the hash. */ vtimezone_comp = icaltimezone_get_component (zone); @@ -2040,8 +2052,18 @@ append_timezone_string (gpointer key, gpointer value, gpointer data) } -/* This converts the VEVENT/VTODO to a string. It checks if we need to send - any builtin timezones to the server along with the object. +/* This simply frees the hash values. */ +static void +free_timezone_string (gpointer key, gpointer value, gpointer data) +{ + g_free (value); +} + + +/* This converts the VEVENT/VTODO to a string. If include_all_timezones is + TRUE, it includes all the VTIMEZONE components needed for the VEVENT/VTODO. + If not, it only includes builtin timezones that may not be on the server. + To do that we check every TZID in the component to see if it is a builtin timezone. If it is, we see if it it in our cache. If it is in our cache, then we know the server already has it and we don't need to send it. @@ -2050,8 +2072,9 @@ append_timezone_string (gpointer key, gpointer value, gpointer data) complete VCALENDAR object, otherwise we can just send a single VEVENT/VTODO as before. */ static char* -cal_client_get_component_as_string (CalClient *client, - CalComponent *comp) +cal_client_get_component_as_string_internal (CalClient *client, + CalComponent *comp, + gboolean include_all_timezones) { GHashTable *timezone_hash; GString *vcal_string; @@ -2065,12 +2088,19 @@ cal_client_get_component_as_string (CalClient *client, timezone_hash = g_hash_table_new (g_str_hash, g_str_equal); - /* Add any builtin timezones needed to the hash. We use a hash since - we only want to add each timezone once at most. */ + /* Add any timezones needed to the hash. We use a hash since we only + want to add each timezone once at most. */ cbdata.client = client; cbdata.timezone_hash = timezone_hash; + cbdata.include_all_timezones = include_all_timezones; + cbdata.success = TRUE; icalcomponent_foreach_tzid (cal_component_get_icalcomponent (comp), foreach_tzid_callback, &cbdata); + if (!cbdata.success) { + g_hash_table_foreach (timezone_hash, free_timezone_string, + NULL); + return NULL; + } /* Create the start of a VCALENDAR, to add the VTIMEZONES to, and remember its length so we know if any VTIMEZONEs get added. */ @@ -2078,7 +2108,8 @@ cal_client_get_component_as_string (CalClient *client, g_string_append (vcal_string, "BEGIN:VCALENDAR\n" "PRODID:-//Ximian//NONSGML Evolution Calendar//EN\n" - "VERSION:2.0\n"); + "VERSION:2.0\n" + "METHOD:PUBLISH\n"); initial_vcal_string_len = vcal_string->len; /* Now concatenate all the timezone strings. This also frees the @@ -2091,7 +2122,8 @@ cal_client_get_component_as_string (CalClient *client, /* If there were any timezones to send, create a complete VCALENDAR, else just send the VEVENT/VTODO string. */ - if (vcal_string->len == initial_vcal_string_len) { + if (!include_all_timezones + && vcal_string->len == initial_vcal_string_len) { g_string_free (vcal_string, TRUE); } else { g_string_append (vcal_string, obj_string); @@ -2106,6 +2138,26 @@ cal_client_get_component_as_string (CalClient *client, return obj_string; } +/** + * cal_client_get_component_as_string: + * @client: A calendar client. + * @comp: A calendar component object. + * + * Gets a calendar component as an iCalendar string, with a toplevel + * VCALENDAR component and all VTIMEZONEs needed for the component. + * + * Return value: the component as a complete iCalendar string, or NULL on + * failure. The string should be freed after use. + **/ +char* +cal_client_get_component_as_string (CalClient *client, + CalComponent *comp) +{ + return cal_client_get_component_as_string_internal (client, comp, + TRUE); +} + + /** * cal_client_update_object: * @client: A calendar client. @@ -2138,7 +2190,8 @@ cal_client_update_object (CalClient *client, CalComponent *comp) cal_component_commit_sequence (comp); - obj_string = cal_client_get_component_as_string (client, comp); + obj_string = cal_client_get_component_as_string_internal (client, + comp, FALSE); if (obj_string == NULL) return FALSE; diff --git a/calendar/cal-client/cal-client.h b/calendar/cal-client/cal-client.h index 36ff410fe1..5ed95b75c3 100644 --- a/calendar/cal-client/cal-client.h +++ b/calendar/cal-client/cal-client.h @@ -168,6 +168,11 @@ CalQuery *cal_client_get_query (CalClient *client, const char *sexp); /* Resolves TZIDs for the recurrence generator. */ icaltimezone *cal_client_resolve_tzid_cb (const char *tzid, gpointer data); +/* Returns a complete VCALENDAR for a VEVENT/VTODO including all VTIMEZONEs + used by the component. It also includes a 'METHOD:PUBLISH' property. */ +char* cal_client_get_component_as_string (CalClient *client, + CalComponent *comp); + diff --git a/calendar/cal-util/cal-recur.c b/calendar/cal-util/cal-recur.c index 28b1be9aec..1f11e89c0f 100644 --- a/calendar/cal-util/cal-recur.c +++ b/calendar/cal-util/cal-recur.c @@ -677,7 +677,9 @@ cal_recur_generate_instances_of_rule (CalComponent *comp, g_return_if_fail (start >= -1); g_return_if_fail (end >= -1); - /* Get dtstart, dtend, recurrences, and exceptions */ + /* Get dtstart, dtend, recurrences, and exceptions. Note that + cal_component_get_dtend() will convert a DURATION property to a + DTEND so we don't need to worry about that. */ cal_component_get_dtstart (comp, &dtstart); cal_component_get_dtend (comp, &dtend); @@ -706,8 +708,6 @@ cal_recur_generate_instances_of_rule (CalComponent *comp, if (start == -1) start = dtstart_time; - /* FIXME: DURATION could be used instead, couldn't it? - Damon */ - /* If there is no DTEND, then use the same as the DTSTART. For DATE-TIME values that means we will just have a single point in time. For DATE values it means we end up with the entire day. */ @@ -2049,6 +2049,10 @@ cal_obj_bysetpos_filter (CalRecurrence *recur, /* Negative values count back from the end of the array. */ if (pos < 0) pos += len; + /* Positive values need to be decremented since the array is + 0-based. */ + else + pos--; if (pos >= 0 && pos < len) { occ = &g_array_index (occs, CalObjTime, pos); diff --git a/calendar/gui/dialogs/alarm-page.c b/calendar/gui/dialogs/alarm-page.c index 276f6c3a24..023dfac55c 100644 --- a/calendar/gui/dialogs/alarm-page.c +++ b/calendar/gui/dialogs/alarm-page.c @@ -623,7 +623,10 @@ alarm_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates) static gboolean get_widgets (AlarmPage *apage) { + CompEditorPage *page = COMP_EDITOR_PAGE (apage); AlarmPagePrivate *priv; + GSList *accel_groups; + GtkWidget *toplevel; priv = apage->priv; @@ -633,6 +636,15 @@ get_widgets (AlarmPage *apage) if (!priv->main) return FALSE; + /* Get the GtkAccelGroup from the toplevel window, so we can install + it when the notebook page is mapped. */ + toplevel = gtk_widget_get_toplevel (priv->main); + accel_groups = gtk_accel_groups_from_object (GTK_OBJECT (toplevel)); + if (accel_groups) { + page->accel_group = accel_groups->data; + gtk_accel_group_ref (page->accel_group); + } + gtk_widget_ref (priv->main); gtk_widget_unparent (priv->main); diff --git a/calendar/gui/dialogs/comp-editor-page.c b/calendar/gui/dialogs/comp-editor-page.c index 9f006a9979..7834ddccef 100644 --- a/calendar/gui/dialogs/comp-editor-page.c +++ b/calendar/gui/dialogs/comp-editor-page.c @@ -153,6 +153,7 @@ static void comp_editor_page_init (CompEditorPage *page) { page->client = NULL; + page->accel_group = NULL; } @@ -171,6 +172,11 @@ comp_editor_page_destroy (GtkObject *object) page->client = NULL; } + if (page->accel_group) { + gtk_accel_group_unref (page->accel_group); + page->accel_group = NULL; + } + if (GTK_OBJECT_CLASS (parent_class)->destroy) (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); } diff --git a/calendar/gui/dialogs/comp-editor-page.h b/calendar/gui/dialogs/comp-editor-page.h index caf0486337..28b75866a6 100644 --- a/calendar/gui/dialogs/comp-editor-page.h +++ b/calendar/gui/dialogs/comp-editor-page.h @@ -50,6 +50,12 @@ typedef struct { /* Some of the pages need the CalClient to access timezone data. */ CalClient *client; + + /* The GtkAccelGroup for the page. We install this when the page is + mapped, and uninstall when it is unmapped. libglade would do this + normally, but we create our pages individually so have to do it + ourselves. */ + GtkAccelGroup *accel_group; } CompEditorPage; typedef struct { diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c index bcb104fe85..077bff879c 100644 --- a/calendar/gui/dialogs/comp-editor.c +++ b/calendar/gui/dialogs/comp-editor.c @@ -461,6 +461,36 @@ comp_editor_get_needs_send (CompEditor *editor) return priv->needs_send; } +static void page_mapped_cb (GtkWidget *page_widget, + CompEditorPage *page) +{ + GtkWidget *toplevel; + + toplevel = gtk_widget_get_toplevel (page_widget); + if (!GTK_IS_WINDOW (toplevel)) + return; + + if (page->accel_group) { + gtk_window_add_accel_group (GTK_WINDOW (toplevel), + page->accel_group); + } +} + +static void page_unmapped_cb (GtkWidget *page_widget, + CompEditorPage *page) +{ + GtkWidget *toplevel; + + toplevel = gtk_widget_get_toplevel (page_widget); + if (!GTK_IS_WINDOW (toplevel)) + return; + + if (page->accel_group) { + gtk_window_remove_accel_group (GTK_WINDOW (toplevel), + page->accel_group); + } +} + /** * comp_editor_append_page: * @editor: A component editor @@ -518,6 +548,13 @@ comp_editor_append_page (CompEditor *editor, gtk_signal_connect (GTK_OBJECT (page), "dates_changed", GTK_SIGNAL_FUNC (page_dates_changed_cb), editor); + /* Listen for when the page is mapped/unmapped so we can + install/uninstall the appropriate GtkAccelGroup. */ + gtk_signal_connect (GTK_OBJECT (page_widget), "map", + GTK_SIGNAL_FUNC (page_mapped_cb), page); + gtk_signal_connect (GTK_OBJECT (page_widget), "unmap", + GTK_SIGNAL_FUNC (page_unmapped_cb), page); + /* The first page is the main page of the editor, so we ask it to focus * its main widget. */ @@ -1023,32 +1060,12 @@ save_as_ok (GtkWidget *widget, gpointer data) FILE *file; gchar *ical_string; - icalcomponent *top_level; - icalcomponent *icalcomp; - icalproperty *prop; - - top_level = icalcomponent_new (ICAL_VCALENDAR_COMPONENT); - - /* RFC 2445, section 4.7.1 */ - prop = icalproperty_new_calscale ("GREGORIAN"); - icalcomponent_add_property (top_level, prop); - - /* RFC 2445, section 4.7.3 */ - prop = icalproperty_new_prodid ("-//Ximian//NONSGML Evolution Calendar//EN"); - icalcomponent_add_property (top_level, prop); - - /* RFC 2445, section 4.7.4. This is the iCalendar spec version, *NOT* - * the product version! Do not change this! - */ - prop = icalproperty_new_version ("2.0"); - icalcomponent_add_property (top_level, prop); - - icalcomp = cal_component_get_icalcomponent (priv->comp); - g_assert (icalcomp != NULL); - - icalcomponent_add_component (top_level, icalcomp); - - ical_string = icalcomponent_as_ical_string (top_level); + ical_string = cal_client_get_component_as_string (priv->client, priv->comp); + if (ical_string == NULL) { + g_warning ("Couldn't convert item to a string"); + gtk_main_quit (); + return; + } file = fopen (path, "w"); if (file == NULL) { @@ -1058,6 +1075,7 @@ save_as_ok (GtkWidget *widget, gpointer data) } fprintf (file, ical_string); + g_free (ical_string); fclose (file); gtk_main_quit (); diff --git a/calendar/gui/dialogs/event-page.c b/calendar/gui/dialogs/event-page.c index f4a849db11..9c89fbdf53 100644 --- a/calendar/gui/dialogs/event-page.c +++ b/calendar/gui/dialogs/event-page.c @@ -715,7 +715,10 @@ event_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates) static gboolean get_widgets (EventPage *epage) { + CompEditorPage *page = COMP_EDITOR_PAGE (epage); EventPagePrivate *priv; + GSList *accel_groups; + GtkWidget *toplevel; priv = epage->priv; @@ -725,6 +728,15 @@ get_widgets (EventPage *epage) if (!priv->main) return FALSE; + /* Get the GtkAccelGroup from the toplevel window, so we can install + it when the notebook page is mapped. */ + toplevel = gtk_widget_get_toplevel (priv->main); + accel_groups = gtk_accel_groups_from_object (GTK_OBJECT (toplevel)); + if (accel_groups) { + page->accel_group = accel_groups->data; + gtk_accel_group_ref (page->accel_group); + } + gtk_widget_ref (priv->main); gtk_widget_unparent (priv->main); diff --git a/calendar/gui/dialogs/event-page.glade b/calendar/gui/dialogs/event-page.glade index e90490dd03..0e591b0663 100644 --- a/calendar/gui/dialogs/event-page.glade +++ b/calendar/gui/dialogs/event-page.glade @@ -132,6 +132,7 @@ 0.5 0 0 + start-time 0 1 @@ -158,6 +159,7 @@ 0.5 0 0 + end-time 0 1 @@ -177,6 +179,7 @@ Custom start-time + True make_date_edit @@ -202,6 +205,7 @@ Custom end-time + True make_date_edit 0 0 @@ -467,6 +471,7 @@ GtkButton contacts-button True + GTK_RELIEF_NORMAL 0 False @@ -504,6 +509,7 @@ GtkButton categories-button True + GTK_RELIEF_NORMAL 0 False diff --git a/calendar/gui/dialogs/meeting-page.c b/calendar/gui/dialogs/meeting-page.c index 447022e81c..3ae487c31d 100644 --- a/calendar/gui/dialogs/meeting-page.c +++ b/calendar/gui/dialogs/meeting-page.c @@ -456,7 +456,10 @@ meeting_page_fill_component (CompEditorPage *page, CalComponent *comp) static gboolean get_widgets (MeetingPage *mpage) { + CompEditorPage *page = COMP_EDITOR_PAGE (mpage); MeetingPagePrivate *priv; + GSList *accel_groups; + GtkWidget *toplevel; priv = mpage->priv; @@ -466,6 +469,15 @@ get_widgets (MeetingPage *mpage) if (!priv->main) return FALSE; + /* Get the GtkAccelGroup from the toplevel window, so we can install + it when the notebook page is mapped. */ + toplevel = gtk_widget_get_toplevel (priv->main); + accel_groups = gtk_accel_groups_from_object (GTK_OBJECT (toplevel)); + if (accel_groups) { + page->accel_group = accel_groups->data; + gtk_accel_group_ref (page->accel_group); + } + gtk_widget_ref (priv->main); gtk_widget_unparent (priv->main); diff --git a/calendar/gui/dialogs/recurrence-page.c b/calendar/gui/dialogs/recurrence-page.c index 28858bd950..c76b6dd970 100644 --- a/calendar/gui/dialogs/recurrence-page.c +++ b/calendar/gui/dialogs/recurrence-page.c @@ -582,8 +582,9 @@ sensitize_recur_widgets (RecurrencePage *rpage) } } +#if 0 /* Encondes a position/weekday pair into the proper format for - * icalrecurrencetype.by_day. + * icalrecurrencetype.by_day. Not needed at present. */ static short nth_weekday (int pos, icalrecurrencetype_weekday weekday) @@ -592,6 +593,7 @@ nth_weekday (int pos, icalrecurrencetype_weekday weekday) return (pos << 3) | (int) weekday; } +#endif /* Gets the simple recurrence data from the recurrence widgets and stores it in * the calendar component. @@ -678,39 +680,42 @@ simple_recur_to_comp (RecurrencePage *rpage, CalComponent *comp) r.by_month_day[0] = day_index; break; + /* Outlook 2000 uses BYDAY=TU;BYSETPOS=2, and will not + accept BYDAY=2TU. So we now use the same as Outlook + by default. */ case MONTH_DAY_MON: - r.by_day[0] = nth_weekday (day_index, - ICAL_MONDAY_WEEKDAY); + r.by_day[0] = ICAL_MONDAY_WEEKDAY; + r.by_set_pos[0] = day_index; break; case MONTH_DAY_TUE: - r.by_day[0] = nth_weekday (day_index, - ICAL_TUESDAY_WEEKDAY); + r.by_day[0] = ICAL_TUESDAY_WEEKDAY; + r.by_set_pos[0] = day_index; break; case MONTH_DAY_WED: - r.by_day[0] = nth_weekday (day_index, - ICAL_WEDNESDAY_WEEKDAY); + r.by_day[0] = ICAL_WEDNESDAY_WEEKDAY; + r.by_set_pos[0] = day_index; break; case MONTH_DAY_THU: - r.by_day[0] = nth_weekday (day_index, - ICAL_THURSDAY_WEEKDAY); + r.by_day[0] = ICAL_THURSDAY_WEEKDAY; + r.by_set_pos[0] = day_index; break; case MONTH_DAY_FRI: - r.by_day[0] = nth_weekday (day_index, - ICAL_FRIDAY_WEEKDAY); + r.by_day[0] = ICAL_FRIDAY_WEEKDAY; + r.by_set_pos[0] = day_index; break; case MONTH_DAY_SAT: - r.by_day[0] = nth_weekday (day_index, - ICAL_SATURDAY_WEEKDAY); + r.by_day[0] = ICAL_SATURDAY_WEEKDAY; + r.by_set_pos[0] = day_index; break; case MONTH_DAY_SUN: - r.by_day[0] = nth_weekday (day_index, - ICAL_SUNDAY_WEEKDAY); + r.by_day[0] = ICAL_SUNDAY_WEEKDAY; + r.by_set_pos[0] = day_index; break; default: @@ -1577,12 +1582,15 @@ recurrence_page_fill_widgets (CompEditorPage *page, CalComponent *comp) if (n_by_year_day != 0 || n_by_week_no != 0 || n_by_month != 0 - || n_by_set_pos != 0) + || n_by_set_pos > 1) goto custom; if (n_by_month_day == 1) { int nth; + if (n_by_set_pos != 0) + goto custom; + nth = r->by_month_day[0]; if (nth < 1) goto custom; @@ -1594,11 +1602,20 @@ recurrence_page_fill_widgets (CompEditorPage *page, CalComponent *comp) int pos; enum month_day_options month_day; + /* Outlook 2000 uses BYDAY=TU;BYSETPOS=2, and will not + accept BYDAY=2TU. So we now use the same as Outlook + by default. */ + weekday = icalrecurrencetype_day_day_of_week (r->by_day[0]); pos = icalrecurrencetype_day_position (r->by_day[0]); - if (pos < 1) + if (pos == 0) { + if (n_by_set_pos != 1) + goto custom; + pos = r->by_set_pos[0]; + } else if (pos < 0) { goto custom; + } switch (weekday) { case ICAL_MONDAY_WEEKDAY: @@ -1799,7 +1816,10 @@ recurrence_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates) static gboolean get_widgets (RecurrencePage *rpage) { + CompEditorPage *page = COMP_EDITOR_PAGE (rpage); RecurrencePagePrivate *priv; + GSList *accel_groups; + GtkWidget *toplevel; priv = rpage->priv; @@ -1809,6 +1829,15 @@ get_widgets (RecurrencePage *rpage) if (!priv->main) return FALSE; + /* Get the GtkAccelGroup from the toplevel window, so we can install + it when the notebook page is mapped. */ + toplevel = gtk_widget_get_toplevel (priv->main); + accel_groups = gtk_accel_groups_from_object (GTK_OBJECT (toplevel)); + if (accel_groups) { + page->accel_group = accel_groups->data; + gtk_accel_group_ref (page->accel_group); + } + gtk_widget_ref (priv->main); gtk_widget_unparent (priv->main); diff --git a/calendar/gui/dialogs/schedule-page.c b/calendar/gui/dialogs/schedule-page.c index 3da74ad6a1..577190b619 100644 --- a/calendar/gui/dialogs/schedule-page.c +++ b/calendar/gui/dialogs/schedule-page.c @@ -336,7 +336,10 @@ schedule_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates) static gboolean get_widgets (SchedulePage *spage) { + CompEditorPage *page = COMP_EDITOR_PAGE (spage); SchedulePagePrivate *priv; + GSList *accel_groups; + GtkWidget *toplevel; priv = spage->priv; @@ -346,6 +349,15 @@ get_widgets (SchedulePage *spage) if (!priv->main) return FALSE; + /* Get the GtkAccelGroup from the toplevel window, so we can install + it when the notebook page is mapped. */ + toplevel = gtk_widget_get_toplevel (priv->main); + accel_groups = gtk_accel_groups_from_object (GTK_OBJECT (toplevel)); + if (accel_groups) { + page->accel_group = accel_groups->data; + gtk_accel_group_ref (page->accel_group); + } + gtk_widget_ref (priv->main); gtk_widget_unparent (priv->main); diff --git a/calendar/gui/dialogs/task-details-page.c b/calendar/gui/dialogs/task-details-page.c index 474b80da12..fda85f0aa5 100644 --- a/calendar/gui/dialogs/task-details-page.c +++ b/calendar/gui/dialogs/task-details-page.c @@ -446,7 +446,10 @@ task_details_page_fill_component (CompEditorPage *page, CalComponent *comp) static gboolean get_widgets (TaskDetailsPage *tdpage) { + CompEditorPage *page = COMP_EDITOR_PAGE (tdpage); TaskDetailsPagePrivate *priv; + GSList *accel_groups; + GtkWidget *toplevel; priv = tdpage->priv; @@ -456,6 +459,15 @@ get_widgets (TaskDetailsPage *tdpage) if (!priv->main) return FALSE; + /* Get the GtkAccelGroup from the toplevel window, so we can install + it when the notebook page is mapped. */ + toplevel = gtk_widget_get_toplevel (priv->main); + accel_groups = gtk_accel_groups_from_object (GTK_OBJECT (toplevel)); + if (accel_groups) { + page->accel_group = accel_groups->data; + gtk_accel_group_ref (page->accel_group); + } + gtk_widget_ref (priv->main); gtk_widget_unparent (priv->main); diff --git a/calendar/gui/dialogs/task-page.c b/calendar/gui/dialogs/task-page.c index dd2b3839cc..d60ca5ba5b 100644 --- a/calendar/gui/dialogs/task-page.c +++ b/calendar/gui/dialogs/task-page.c @@ -599,7 +599,10 @@ task_page_set_dates (CompEditorPage *page, CompEditorPageDates *dates) static gboolean get_widgets (TaskPage *tpage) { + CompEditorPage *page = COMP_EDITOR_PAGE (tpage); TaskPagePrivate *priv; + GSList *accel_groups; + GtkWidget *toplevel; priv = tpage->priv; @@ -609,6 +612,15 @@ get_widgets (TaskPage *tpage) if (!priv->main) return FALSE; + /* Get the GtkAccelGroup from the toplevel window, so we can install + it when the notebook page is mapped. */ + toplevel = gtk_widget_get_toplevel (priv->main); + accel_groups = gtk_accel_groups_from_object (GTK_OBJECT (toplevel)); + if (accel_groups) { + page->accel_group = accel_groups->data; + gtk_accel_group_ref (page->accel_group); + } + gtk_widget_ref (priv->main); gtk_widget_unparent (priv->main); diff --git a/calendar/gui/dialogs/task-page.glade b/calendar/gui/dialogs/task-page.glade index 10e0180eff..31a7ba2cbe 100644 --- a/calendar/gui/dialogs/task-page.glade +++ b/calendar/gui/dialogs/task-page.glade @@ -140,6 +140,7 @@ 0.5 0 0 + start-date 0 1 @@ -166,6 +167,7 @@ 0.5 0 0 + due-date 0 1 @@ -185,6 +187,7 @@ Custom due-date + True task_page_create_date_edit 0 0 @@ -208,6 +211,7 @@ Custom start-date + True task_page_create_date_edit 0 0 @@ -382,7 +386,7 @@ GtkRadioButton classification-confidential True - + False True classification_radio_group @@ -410,6 +414,7 @@ GtkButton contacts-button True + GTK_RELIEF_NORMAL 0 False @@ -447,6 +452,7 @@ GtkButton categories-button True + GTK_RELIEF_NORMAL 0 False -- cgit