diff options
-rw-r--r-- | calendar/ChangeLog | 67 | ||||
-rw-r--r-- | calendar/gui/calendar-commands.c | 62 | ||||
-rw-r--r-- | calendar/gui/dialogs/alarm-page.c | 38 | ||||
-rw-r--r-- | calendar/gui/dialogs/comp-editor-util.c | 5 | ||||
-rw-r--r-- | calendar/gui/dialogs/comp-editor.c | 11 | ||||
-rw-r--r-- | calendar/gui/dialogs/event-page.c | 10 | ||||
-rw-r--r-- | calendar/gui/dialogs/meeting-page.c | 23 | ||||
-rw-r--r-- | calendar/gui/dialogs/recurrence-page.c | 40 | ||||
-rw-r--r-- | calendar/gui/dialogs/task-page.c | 10 | ||||
-rw-r--r-- | calendar/gui/e-day-view-top-item.c | 8 | ||||
-rw-r--r-- | calendar/gui/e-day-view.c | 131 | ||||
-rw-r--r-- | calendar/gui/e-day-view.h | 10 | ||||
-rw-r--r-- | calendar/gui/e-tasks.c | 2 | ||||
-rw-r--r-- | calendar/gui/e-week-view.c | 102 | ||||
-rw-r--r-- | calendar/gui/e-week-view.h | 7 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.c | 96 | ||||
-rw-r--r-- | calendar/gui/gnome-cal.h | 6 | ||||
-rw-r--r-- | calendar/gui/tasks-control.c | 5 |
18 files changed, 470 insertions, 163 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index f05cb7d0a4..27d8d7a82e 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,70 @@ +2001-09-03 Damon Chaplin <damon@ximian.com> + + * gui/calendar-commands.c (calendar_control_activate): + * gui/tasks-control.c (tasks_control_activate): don't call + calendar_config_check_timezone_set() now, since the startup wizard + handles that. + + * gui/e-tasks.c (e_tasks_class_init): changed selection_changed signal + to GTK_RUN_LAST. It has no reason to be GTK_RUN_FIRST. + + * gui/gnome-cal.c: + * gui/e-week-view.c: + * gui/e-day-view.c: added "selection_changed" signal, + XX_delete_event() and XX_get_num_events_selected(). + + * gui/e-day-view-top-item.c (e_day_view_top_item_draw): fix the shadow + around the dates at the top - it was 1 pixel off. + + * gui/calendar-commands.c: added sensitize_commands(), similar to in + tasks-control.c, so we only make Cut/Copy/Delete sensitive when an + event is selected. Also added delete_event_cmd(). + + * gui/dialogs/task-page.c (task_page_set_summary): + * gui/dialogs/event-page.c (event_page_set_summary): do nothing, + since the summary only gets changed on the main event/task page now. + Fixes bug #6939. + + * gui/e-day-view.c (e_day_view_on_main_canvas_drag_data_received): + (e_day_view_on_top_canvas_drag_data_received): check that we are + dragging an event from the same EDayView. We currently don't support + DnD from other widgets. + (e_day_view_update_top_canvas_drag): only get the summary if we + actually have an event. Fixes bug #5162. + + * gui/e-day-view.c (e_day_view_on_editing_stopped): if the text hasn't + changed we need to call e_day_view_update_event_label() to show the + times again if necessary. Fixes bug #1813. + + * gui/dialogs/comp-editor.c (comp_editor_destroy): destroy the + CompEditorPage objects here rather than in close_dialog(), after the + widgets have been destroyed. We do this because the widgets have lots + of signal handlers connected with the CompEditorPage objects as the + signal data, so we want to ensure that the data pointer is always + valid. (Alternatively we could disconnect all the handlers when the + CompEditorPage objects are destroyed, or use connect_while_alive()). + Fixes bug #7543. + + Note: there is still a small bug in that if you type in a time and + then hit 'Save and Close', the time won't be saved. I'm not sure + where this should be fixed - should the actions which close the + dialog grab the focus to the toplevel, so any widgets currently + being edited finish the edit and emit 'changed'? + + * gui/dialogs/recurrence-page.c (append_exception): use + gtk_clist_set_row_data_full() so freeing is handled automatically by + the GtkClist. This helps avoid problems at destroy-time. + (exception_delete_cb): just call gtk_clist_remove() now. No need to + free the row data as GtkCList now handles it. + (recurrence_page_destroy): no need to free the data in the clist. + + * gui/dialogs/alarm-page.c: ditto. + + * gui/dialogs/meeting-page.c: ditto. + (etable_destroy_cb): save the ETable state in this new handler cb + rather than in the destroy method, since the widget will already be + destroyed by then. + 2001-08-31 Damon Chaplin <damon@ximian.com> * gui/e-itip-control.c: changed 3 occurrences of 'Replyed' to 'replied' diff --git a/calendar/gui/calendar-commands.c b/calendar/gui/calendar-commands.c index 1f4017e56b..24e21d76f3 100644 --- a/calendar/gui/calendar-commands.c +++ b/calendar/gui/calendar-commands.c @@ -316,6 +316,18 @@ paste_event_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) } static void +delete_event_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) +{ + GnomeCalendar *gcal; + + gcal = GNOME_CALENDAR (data); + + set_clock_cursor (gcal); + gnome_calendar_delete_event (gcal); + set_normal_cursor (gcal); +} + +static void publish_freebusy_cmd (BonoboUIComponent *uic, gpointer data, const gchar *path) { GnomeCalendar *gcal; @@ -480,6 +492,42 @@ control_util_set_folder_bar_label (BonoboControl *control, char *label) CORBA_exception_free (&ev); } +/* Sensitizes the UI Component menu/toolbar commands based on the number of + * selected events. (This will always be 0 or 1 currently.) + */ +static void +sensitize_commands (GnomeCalendar *gcal, BonoboControl *control) +{ + BonoboUIComponent *uic; + int n_selected; + + uic = bonobo_control_get_ui_component (control); + g_assert (uic != NULL); + + n_selected = gnome_calendar_get_num_events_selected (gcal); + + bonobo_ui_component_set_prop (uic, "/commands/CutEvent", "sensitive", + n_selected == 0 ? "0" : "1", + NULL); + bonobo_ui_component_set_prop (uic, "/commands/CopyEvent", "sensitive", + n_selected == 0 ? "0" : "1", + NULL); + bonobo_ui_component_set_prop (uic, "/commands/DeleteEvent", "sensitive", + n_selected == 0 ? "0" : "1", + NULL); +} + +/* Callback used when the selection in the calendar views changes */ +static void +selection_changed_cb (GnomeCalendar *gcal, gpointer data) +{ + BonoboControl *control; + + control = BONOBO_CONTROL (data); + + sensitize_commands (gcal, control); +} + static BonoboUIVerb verbs [] = { BONOBO_UI_VERB ("CalendarPrint", file_print_cb), BONOBO_UI_VERB ("CalendarPrintPreview", file_print_preview_cb), @@ -493,6 +541,7 @@ static BonoboUIVerb verbs [] = { BONOBO_UI_VERB ("CutEvent", cut_event_cmd), BONOBO_UI_VERB ("CopyEvent", copy_event_cmd), BONOBO_UI_VERB ("PasteEvent", paste_event_cmd), + BONOBO_UI_VERB ("DeleteEvent", delete_event_cmd), BONOBO_UI_VERB ("CalendarPrev", previous_clicked), BONOBO_UI_VERB ("CalendarToday", today_clicked), @@ -566,11 +615,19 @@ calendar_control_activate (BonoboControl *control, gnome_calendar_setup_view_menus (gcal, uic); + gtk_signal_connect (GTK_OBJECT (gcal), "selection_changed", + GTK_SIGNAL_FUNC (selection_changed_cb), control); + + sensitize_commands (gcal, control); + bonobo_ui_component_thaw (uic, NULL); /* Show the dialog for setting the timezone if the user hasn't chosen - a default timezone already. */ + a default timezone already. This is done in the startup wizard now, + so we don't do it here. */ +#if 0 calendar_config_check_timezone_set (); +#endif calendar_set_folder_bar_label (gcal, control); } @@ -583,6 +640,9 @@ calendar_control_deactivate (BonoboControl *control, GnomeCalendar *gcal) gnome_calendar_discard_view_menus (gcal); + /* Stop monitoring the "selection_changed" signal */ + gtk_signal_disconnect_by_data (GTK_OBJECT (gcal), control); + bonobo_ui_component_rm (uic, "/", NULL); bonobo_ui_component_unset_container (uic); } diff --git a/calendar/gui/dialogs/alarm-page.c b/calendar/gui/dialogs/alarm-page.c index 9cf15bafd7..5ef9a2c15c 100644 --- a/calendar/gui/dialogs/alarm-page.c +++ b/calendar/gui/dialogs/alarm-page.c @@ -211,32 +211,6 @@ alarm_page_init (AlarmPage *apage) priv->updating = FALSE; } -/* Frees all the alarm data and empties the list */ -static void -free_alarms (AlarmPage *apage) -{ - AlarmPagePrivate *priv; - int i; - - priv = apage->priv; - - if (priv->list != NULL) { - GtkCList *clist = GTK_CLIST (priv->list); - - for (i = 0; i < clist->rows; i++) { - CalComponentAlarm *alarm; - - alarm = gtk_clist_get_row_data (clist, i); - g_assert (alarm != NULL); - cal_component_alarm_free (alarm); - - gtk_clist_set_row_data (clist, i, NULL); - } - - gtk_clist_clear (clist); - } -} - /* Destroy handler for the alarm page */ static void alarm_page_destroy (GtkObject *object) @@ -255,8 +229,6 @@ alarm_page_destroy (GtkObject *object) priv->xml = NULL; } - free_alarms (apage); - if (priv->alarm) { cal_component_alarm_free (priv->alarm); priv->alarm = NULL; @@ -319,7 +291,7 @@ clear_widgets (AlarmPage *apage) e_dialog_option_menu_set (priv->time, CAL_ALARM_TRIGGER_RELATIVE_START, time_map); /* List data */ - free_alarms (apage); + gtk_clist_clear (GTK_CLIST (priv->list)); } static char * @@ -453,7 +425,7 @@ append_reminder (AlarmPage *apage, CalComponentAlarm *alarm) c[0] = get_alarm_string (alarm); i = gtk_clist_append (clist, c); - gtk_clist_set_row_data (clist, i, alarm); + gtk_clist_set_row_data_full (clist, i, alarm, (GtkDestroyNotify) cal_component_alarm_free); gtk_clist_select_row (clist, i, 0); g_free (c[0]); @@ -704,7 +676,6 @@ delete_clicked_cb (GtkButton *button, gpointer data) AlarmPage *apage; AlarmPagePrivate *priv; GtkCList *clist; - CalComponentAlarm *alarm; int sel; apage = ALARM_PAGE (data); @@ -716,11 +687,6 @@ delete_clicked_cb (GtkButton *button, gpointer data) sel = GPOINTER_TO_INT (clist->selection->data); - alarm = gtk_clist_get_row_data (clist, sel); - g_assert (alarm != NULL); - cal_component_alarm_free (alarm); - gtk_clist_set_row_data (clist, sel, NULL); - gtk_clist_remove (clist, sel); if (sel >= clist->rows) sel--; diff --git a/calendar/gui/dialogs/comp-editor-util.c b/calendar/gui/dialogs/comp-editor-util.c index 630c6b78de..375d51918f 100644 --- a/calendar/gui/dialogs/comp-editor-util.c +++ b/calendar/gui/dialogs/comp-editor-util.c @@ -339,8 +339,9 @@ comp_editor_show_contacts_dialog (GNOME_Evolution_Addressbook_SelectNames corba_ } -/* A simple 'name <email>' parser. - FIXME: Should probably use camel functions or something. */ +/* A simple 'name <email>' parser. Input should be UTF8. + FIXME: Should probably use camel functions or something. + Also note that this is broken wrt UTF8 - can't use strchr etc. */ static void parse_contact_string (const char *value, char **name, char **email) { diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c index 5b80de6bee..433a9879aa 100644 --- a/calendar/gui/dialogs/comp-editor.c +++ b/calendar/gui/dialogs/comp-editor.c @@ -242,6 +242,7 @@ comp_editor_destroy (GtkObject *object) { CompEditor *editor; CompEditorPrivate *priv; + GList *l; editor = COMP_EDITOR (object); priv = editor->priv; @@ -251,6 +252,12 @@ comp_editor_destroy (GtkObject *object) priv->window = NULL; } + /* We want to destroy the pages after the widgets get destroyed, + since they have lots of signal handlers connected to the widgets + with the pages as the data. */ + for (l = priv->pages; l != NULL; l = l->next) + gtk_object_unref (GTK_OBJECT (l->data)); + gtk_signal_disconnect_by_data (GTK_OBJECT (priv->client), editor); g_free (priv); @@ -807,15 +814,11 @@ static void close_dialog (CompEditor *editor) { CompEditorPrivate *priv; - GList *l; priv = editor->priv; g_assert (priv->window != NULL); - for (l = priv->pages; l != NULL; l = l->next) - gtk_object_unref (GTK_OBJECT (l->data)); - gtk_object_destroy (GTK_OBJECT (editor)); } diff --git a/calendar/gui/dialogs/event-page.c b/calendar/gui/dialogs/event-page.c index a8ab66af6a..74fdecb6ee 100644 --- a/calendar/gui/dialogs/event-page.c +++ b/calendar/gui/dialogs/event-page.c @@ -696,15 +696,7 @@ event_page_fill_component (CompEditorPage *page, CalComponent *comp) static void event_page_set_summary (CompEditorPage *page, const char *summary) { - EventPage *epage; - EventPagePrivate *priv; - - epage = EVENT_PAGE (page); - priv = epage->priv; - - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->summary), epage); - e_utf8_gtk_entry_set_text (GTK_ENTRY (priv->summary), summary); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->summary), epage); + /* nothing */ } static void diff --git a/calendar/gui/dialogs/meeting-page.c b/calendar/gui/dialogs/meeting-page.c index 529ea63c6e..2af24d2400 100644 --- a/calendar/gui/dialogs/meeting-page.c +++ b/calendar/gui/dialogs/meeting-page.c @@ -291,8 +291,6 @@ meeting_page_destroy (GtkObject *object) { MeetingPage *mpage; MeetingPagePrivate *priv; - ETable *real_table; - char *filename; g_return_if_fail (object != NULL); g_return_if_fail (IS_MEETING_PAGE (object)); @@ -309,12 +307,6 @@ meeting_page_destroy (GtkObject *object) itip_addresses_free (priv->addresses); g_list_free (priv->address_strings); - filename = g_strdup_printf ("%s/config/et-header-meeting-page", - evolution_dir); - real_table = e_table_scrolled_get_table (E_TABLE_SCROLLED (priv->etable)); - e_table_save_state (real_table, filename); - g_free (filename); - if (priv->xml) { gtk_object_unref (GTK_OBJECT (priv->xml)); priv->xml = NULL; @@ -1227,6 +1219,17 @@ value_to_string (ETableModel *etm, int col, const void *val, void *data) } static void +etable_destroy_cb (ETable *real_table, MeetingPage *mpage) +{ + char *filename; + + filename = g_strdup_printf ("%s/config/et-header-meeting-page", + evolution_dir); + e_table_save_state (real_table, filename); + g_free (filename); +} + +static void build_etable (MeetingPage *mpage) { MeetingPagePrivate *priv; @@ -1330,6 +1333,10 @@ build_etable (MeetingPage *mpage) g_free (filename); gtk_signal_connect (GTK_OBJECT (real_table), + "destroy", GTK_SIGNAL_FUNC (etable_destroy_cb), + mpage); + + gtk_signal_connect (GTK_OBJECT (real_table), "right_click", GTK_SIGNAL_FUNC (right_click_cb), mpage); gtk_object_unref (GTK_OBJECT (extras)); diff --git a/calendar/gui/dialogs/recurrence-page.c b/calendar/gui/dialogs/recurrence-page.c index 586a291bfb..ff9485d8ff 100644 --- a/calendar/gui/dialogs/recurrence-page.c +++ b/calendar/gui/dialogs/recurrence-page.c @@ -277,30 +277,13 @@ recurrence_page_init (RecurrencePage *rpage) priv->comp = NULL; } -/* Frees the rows and the row data in the exceptions GtkCList */ +/* Frees the CalComponentDateTime stored in the GtkCList */ static void -free_exception_clist_data (RecurrencePage *rpage) +free_exception_date_time (CalComponentDateTime *dt) { - RecurrencePagePrivate *priv; - int i; - - priv = rpage->priv; - - if (priv->exception_list) { - GtkCList *clist = GTK_CLIST (priv->exception_list); - - for (i = 0; i < clist->rows; i++) { - CalComponentDateTime *dt; - - dt = gtk_clist_get_row_data (clist, i); - g_free (dt->value); - g_free ((char*)dt->tzid); - g_free (dt); - gtk_clist_set_row_data (clist, i, NULL); - } - - gtk_clist_clear (clist); - } + g_free (dt->value); + g_free ((char*)dt->tzid); + g_free (dt); } /* Destroy handler for the recurrence page */ @@ -321,8 +304,6 @@ recurrence_page_destroy (GtkObject *object) priv->xml = NULL; } - free_exception_clist_data (rpage); - g_free (priv); rpage->priv = NULL; @@ -411,7 +392,7 @@ clear_widgets (RecurrencePage *rpage) gtk_signal_handler_unblock_by_data (GTK_OBJECT (menu), rpage); /* Exceptions list */ - free_exception_clist_data (rpage); + gtk_clist_clear (GTK_CLIST (priv->exception_list)); } /* Builds a static string out of an exception date */ @@ -462,7 +443,7 @@ append_exception (RecurrencePage *rpage, CalComponentDateTime *datetime) c[0] = get_exception_string (dt); i = gtk_clist_append (clist, c); - gtk_clist_set_row_data (clist, i, dt); + gtk_clist_set_row_data_full (clist, i, dt, (GtkDestroyNotify) free_exception_date_time); gtk_clist_select_row (clist, i, 0); gtk_signal_handler_unblock_by_data (GTK_OBJECT (clist), rpage); @@ -2026,7 +2007,6 @@ exception_delete_cb (GtkWidget *widget, gpointer data) RecurrencePagePrivate *priv; GtkCList *clist; int sel; - CalComponentDateTime *dt; rpage = RECURRENCE_PAGE (data); priv = rpage->priv; @@ -2039,12 +2019,6 @@ exception_delete_cb (GtkWidget *widget, gpointer data) sel = GPOINTER_TO_INT (clist->selection->data); - dt = gtk_clist_get_row_data (clist, sel); - g_assert (dt != NULL); - g_free (dt->value); - g_free ((char*)dt->tzid); - g_free (dt); - gtk_clist_remove (clist, sel); if (sel >= clist->rows) sel--; diff --git a/calendar/gui/dialogs/task-page.c b/calendar/gui/dialogs/task-page.c index 729ec8c641..048adf31ad 100644 --- a/calendar/gui/dialogs/task-page.c +++ b/calendar/gui/dialogs/task-page.c @@ -571,15 +571,7 @@ task_page_fill_component (CompEditorPage *page, CalComponent *comp) static void task_page_set_summary (CompEditorPage *page, const char *summary) { - TaskPage *tpage; - TaskPagePrivate *priv; - - tpage = TASK_PAGE (page); - priv = tpage->priv; - - priv->updating = TRUE; - e_utf8_gtk_entry_set_text (GTK_ENTRY (priv->summary), summary); - priv->updating = FALSE; + /* nothing */ } static void diff --git a/calendar/gui/e-day-view-top-item.c b/calendar/gui/e-day-view-top-item.c index 121dacba03..f2b9379829 100644 --- a/calendar/gui/e-day-view-top-item.c +++ b/calendar/gui/e-day-view-top-item.c @@ -218,13 +218,13 @@ e_day_view_top_item_draw (GnomeCanvasItem *canvas_item, /* Draw the shadow around the dates. */ gdk_draw_line (drawable, light_gc, - left_edge + 1 - x, 1 - y, + left_edge - x, 1 - y, canvas_width - 2 - x, 1 - y); gdk_draw_line (drawable, light_gc, - left_edge + 1 - x, 2 - y, - left_edge + 1 - x, item_height - 1 - y); + left_edge - x, 2 - y, + left_edge - x, item_height - 2 - y); gdk_draw_line (drawable, dark_gc, - left_edge + 2 - x, item_height - 1 - y, + left_edge - x, item_height - 1 - y, canvas_width - 1 - x, item_height - 1 - y); gdk_draw_line (drawable, dark_gc, canvas_width - 1 - x, 1 - y, diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c index 4b11b89437..80b79bf2f5 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -97,6 +97,14 @@ #define E_DAY_VIEW_LAYOUT_TIMEOUT 100 +/* Signal IDs */ +enum { + SELECTION_CHANGED, + LAST_SIGNAL +}; +static guint e_day_view_signals[LAST_SIGNAL] = { 0 }; + + /* Drag and Drop stuff. */ enum { TARGET_CALENDAR_EVENT @@ -470,6 +478,16 @@ e_day_view_class_init (EDayViewClass *class) object_class = (GtkObjectClass *) class; widget_class = (GtkWidgetClass *) class; + e_day_view_signals[SELECTION_CHANGED] = + gtk_signal_new ("selection_changed", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (EDayViewClass, selection_changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, e_day_view_signals, LAST_SIGNAL); + /* Method override */ object_class->destroy = e_day_view_destroy; @@ -481,6 +499,8 @@ e_day_view_class_init (EDayViewClass *class) widget_class->focus_out_event = e_day_view_focus_out; widget_class->key_press_event = e_day_view_key_press; + class->selection_changed = NULL; + /* clipboard atom */ if (!clipboard_atom) clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); @@ -1889,7 +1909,7 @@ e_day_view_remove_event_cb (EDayView *day_view, event = &g_array_index (day_view->events[day], EDayViewEvent, event_num); - /* If we were editing this event, set editing_event_num to -1 so + /* If we were editing this event, set editing_event_day to -1 so on_editing_stopped doesn't try to update the event. */ if (day_view->editing_event_day == day && day_view->editing_event_num == event_num) @@ -2657,7 +2677,7 @@ get_current_event (EDayView *day_view) { g_return_val_if_fail (E_IS_DAY_VIEW (day_view), NULL); - if (day_view->editing_event_num == -1) + if (day_view->editing_event_day == -1) return NULL; if (day_view->editing_event_day == E_DAY_VIEW_LONG_EVENT) @@ -3582,13 +3602,31 @@ e_day_view_on_delete_occurrence (GtkWidget *widget, gpointer data) gtk_object_unref (GTK_OBJECT (comp)); } +static void +e_day_view_delete_event_internal (EDayView *day_view, EDayViewEvent *event) +{ + CalComponentVType vtype; + + vtype = cal_component_get_vtype (event->comp); + + if (delete_component_dialog (event->comp, 1, vtype, + GTK_WIDGET (day_view))) { + const char *uid; + + cal_component_get_uid (event->comp, &uid); + + /* We don't check the return value; FALSE can mean the object + * was not in the server anyways. + */ + cal_client_remove_object (day_view->client, uid); + } +} static void e_day_view_on_delete_appointment (GtkWidget *widget, gpointer data) { EDayView *day_view; EDayViewEvent *event; - CalComponentVType vtype; day_view = E_DAY_VIEW (data); @@ -3599,20 +3637,32 @@ e_day_view_on_delete_appointment (GtkWidget *widget, gpointer data) if (day_view->editing_event_day >= 0) e_day_view_stop_editing_event (day_view); - vtype = cal_component_get_vtype (event->comp); + e_day_view_delete_event_internal (day_view, event); +} - if (delete_component_dialog (event->comp, 1, vtype, widget)) { - const char *uid; +void +e_day_view_delete_event (EDayView *day_view) +{ + EDayViewEvent *event; - cal_component_get_uid (event->comp, &uid); + g_return_if_fail (E_IS_DAY_VIEW (day_view)); - /* We don't check the return value; FALSE can mean the object - * was not in the server anyways. - */ - cal_client_remove_object (day_view->client, uid); - } + if (day_view->editing_event_day == -1) + return; + + if (day_view->editing_event_day == E_DAY_VIEW_LONG_EVENT) + event = &g_array_index (day_view->long_events, + EDayViewEvent, + day_view->editing_event_num); + else + event = &g_array_index (day_view->events[day_view->editing_event_day], + EDayViewEvent, + day_view->editing_event_num); + + e_day_view_delete_event_internal (day_view, event); } + static void e_day_view_on_cut (GtkWidget *widget, gpointer data) { @@ -5032,10 +5082,8 @@ e_day_view_key_press (GtkWidget *widget, GdkEventKey *event) cal_component_set_categories (comp, day_view->default_category); - /* We add the event locally and start editing it. When we get the - "update_event" callback from the server, we basically ignore it. - If we were to wait for the "update_event" callback it wouldn't be - as responsive and we may lose a few keystrokes. */ + /* We add the event locally and start editing it. We don't send it + to the server until the user finishes editing it. */ e_day_view_add_event (comp, dtstart, dtend, day_view); e_day_view_check_layout (day_view); gtk_widget_queue_draw (day_view->top_canvas); @@ -5494,6 +5542,9 @@ e_day_view_on_editing_started (EDayView *day_view, e_day_view_update_event_label (day_view, day, event_num); e_day_view_reshape_main_canvas_resize_bars (day_view); } + + gtk_signal_emit (GTK_OBJECT (day_view), + e_day_view_signals[SELECTION_CHANGED]); } @@ -5545,28 +5596,29 @@ e_day_view_on_editing_stopped (EDayView *day_view, gtk_object_get (GTK_OBJECT (event->canvas_item), "text", &text, NULL); + g_assert (text != NULL); /* Only update the summary if necessary. */ cal_component_get_summary (event->comp, &summary); - if (text && summary.value && !strcmp (text, summary.value)) { - g_free (text); - + if (summary.value && !strcmp (text, summary.value)) { if (day == E_DAY_VIEW_LONG_EVENT) e_day_view_reshape_long_event (day_view, event_num); - return; - } - - if (text) { + else + e_day_view_update_event_label (day_view, day, + event_num); + } else { summary.value = text; summary.altrep = NULL; cal_component_set_summary (event->comp, &summary); - g_free (text); - } else - cal_component_set_summary (event->comp, NULL); + if (!cal_client_update_object (day_view->client, event->comp)) + g_message ("e_day_view_on_editing_stopped(): Could not update the object!"); + } - if (!cal_client_update_object (day_view->client, event->comp)) - g_message ("e_day_view_on_editing_stopped(): Could not update the object!"); + g_free (text); + + gtk_signal_emit (GTK_OBJECT (day_view), + e_day_view_signals[SELECTION_CHANGED]); } @@ -6164,7 +6216,6 @@ e_day_view_update_top_canvas_drag (EDayView *day_view, & GNOME_CANVAS_ITEM_VISIBLE)) { CalComponentText summary; - cal_component_get_summary (event->comp, &summary); if (event) { cal_component_get_summary (event->comp, &summary); text = g_strdup (summary.value); @@ -6500,7 +6551,9 @@ e_day_view_on_top_canvas_drag_data_received (GtkWidget *widget, struct icaltimetype itt; time_t dt; - if ((data->length >= 0) && (data->format == 8)) { + /* Note that we only support DnD within the EDayView at present. */ + if ((data->length >= 0) && (data->format == 8) + && (day_view->drag_event_day != -1)) { pos = e_day_view_convert_position_in_top_canvas (day_view, x, y, &day, NULL); @@ -6527,7 +6580,7 @@ e_day_view_on_top_canvas_drag_data_received (GtkWidget *widget, start_offset = event->start_minute; end_offset = event->end_minute; - } else if (day_view->drag_event_day != -1) { + } else { event = &g_array_index (day_view->events[day_view->drag_event_day], EDayViewEvent, day_view->drag_event_num); @@ -6613,7 +6666,9 @@ e_day_view_on_main_canvas_drag_data_received (GtkWidget *widget, x += scroll_x; y += scroll_y; - if ((data->length >= 0) && (data->format == 8)) { + /* Note that we only support DnD within the EDayView at present. */ + if ((data->length >= 0) && (data->format == 8) + && (day_view->drag_event_day != -1)) { pos = e_day_view_convert_position_in_main_canvas (day_view, x, y, &day, &row, NULL); @@ -6626,7 +6681,7 @@ e_day_view_on_main_canvas_drag_data_received (GtkWidget *widget, if (day_view->drag_event_day == E_DAY_VIEW_LONG_EVENT) { event = &g_array_index (day_view->long_events, EDayViewEvent, day_view->drag_event_num); - } else if (day_view->drag_event_day != -1) { + } else { event = &g_array_index (day_view->events[day_view->drag_event_day], EDayViewEvent, day_view->drag_event_num); @@ -6930,3 +6985,13 @@ e_day_view_layout_timeout_cb (gpointer data) day_view->layout_timeout_id = 0; return FALSE; } + + +/* Returns the number of selected events (0 or 1 at present). */ +gint +e_day_view_get_num_events_selected (EDayView *day_view) +{ + g_return_val_if_fail (E_IS_DAY_VIEW (day_view), 0); + + return (day_view->editing_event_day != -1) ? 1 : 0; +} diff --git a/calendar/gui/e-day-view.h b/calendar/gui/e-day-view.h index 1e57de4862..4b57a2e155 100644 --- a/calendar/gui/e-day-view.h +++ b/calendar/gui/e-day-view.h @@ -498,6 +498,9 @@ struct _EDayView struct _EDayViewClass { GtkTableClass parent_class; + + /* Notification signals */ + void (* selection_changed) (EDayView *day_view); }; @@ -597,6 +600,13 @@ void e_day_view_cut_clipboard (EDayView *day_view); void e_day_view_copy_clipboard (EDayView *day_view); void e_day_view_paste_clipboard (EDayView *day_view); +void e_day_view_delete_event (EDayView *day_view); + + +/* Returns the number of selected events (0 or 1 at present). */ +gint e_day_view_get_num_events_selected (EDayView *day_view); + + /* * Internal functions called by the associated canvas items. */ diff --git a/calendar/gui/e-tasks.c b/calendar/gui/e-tasks.c index ab59d80273..d79ae1cb90 100644 --- a/calendar/gui/e-tasks.c +++ b/calendar/gui/e-tasks.c @@ -96,7 +96,7 @@ e_tasks_class_init (ETasksClass *class) e_tasks_signals[SELECTION_CHANGED] = gtk_signal_new ("selection_changed", - GTK_RUN_FIRST, + GTK_RUN_LAST, object_class->type, GTK_SIGNAL_OFFSET (ETasksClass, selection_changed), gtk_marshal_NONE__INT, diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c index dfb03802b8..b9bc5199d1 100644 --- a/calendar/gui/e-week-view.c +++ b/calendar/gui/e-week-view.c @@ -80,6 +80,14 @@ #define E_WEEK_VIEW_LAYOUT_TIMEOUT 100 +/* Signal IDs */ +enum { + SELECTION_CHANGED, + LAST_SIGNAL +}; +static guint e_week_view_signals[LAST_SIGNAL] = { 0 }; + + static void e_week_view_class_init (EWeekViewClass *class); static void e_week_view_init (EWeekView *week_view); static void e_week_view_destroy (GtkObject *object); @@ -242,6 +250,16 @@ e_week_view_class_init (EWeekViewClass *class) object_class = (GtkObjectClass *) class; widget_class = (GtkWidgetClass *) class; + e_week_view_signals[SELECTION_CHANGED] = + gtk_signal_new ("selection_changed", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (EWeekViewClass, selection_changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, e_week_view_signals, LAST_SIGNAL); + /* Method override */ object_class->destroy = e_week_view_destroy; @@ -255,6 +273,8 @@ e_week_view_class_init (EWeekViewClass *class) widget_class->expose_event = e_week_view_expose_event; widget_class->draw = e_week_view_draw; + class->selection_changed = NULL; + /* clipboard atom */ if (!clipboard_atom) clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); @@ -2982,6 +3002,9 @@ e_week_view_on_editing_started (EWeekView *week_view, e_week_view_reshape_event_span (week_view, event_num, span_num); } + + gtk_signal_emit (GTK_OBJECT (week_view), + e_week_view_signals[SELECTION_CHANGED]); } @@ -3021,23 +3044,27 @@ e_week_view_on_editing_stopped (EWeekView *week_view, gtk_object_get (GTK_OBJECT (span->text_item), "text", &text, NULL); + g_assert (text != NULL); /* Only update the summary if necessary. */ cal_component_get_summary (event->comp, &summary); - if (text && summary.value && !strcmp (text, summary.value)) { - g_free (text); + if (summary.value && !strcmp (text, summary.value)) { if (!e_week_view_is_one_day_event (week_view, event_num)) e_week_view_reshape_event_span (week_view, event_num, span_num); - return; + } else { + summary.value = text; + summary.altrep = NULL; + cal_component_set_summary (event->comp, &summary); + + if (!cal_client_update_object (week_view->client, event->comp)) + g_message ("e_week_view_on_editing_stopped(): Could not update the object!"); } - summary.value = text; - cal_component_set_summary (event->comp, &summary); g_free (text); - if (!cal_client_update_object (week_view->client, event->comp)) - g_message ("e_week_view_on_editing_stopped(): Could not update the object!"); + gtk_signal_emit (GTK_OBJECT (week_view), + e_week_view_signals[SELECTION_CHANGED]); } @@ -3191,11 +3218,8 @@ e_week_view_key_press (GtkWidget *widget, GdkEventKey *event) cal_component_set_categories (comp, week_view->default_category); - /* We add the event locally and start editing it. We don't send the - new event to the server until the edit is finished. - FIXME: If we get an obj-updated or obj-removed signal while editing - the event, and we have to do a re-layout, we may lose this new - event. */ + /* We add the event locally and start editing it. We don't send it + to the server until the user finishes editing it. */ e_week_view_add_event (comp, dtstart, dtend, week_view); e_week_view_check_layout (week_view); gtk_widget_queue_draw (week_view->main_canvas); @@ -3428,23 +3452,18 @@ e_week_view_on_delete_occurrence (GtkWidget *widget, gpointer data) static void -e_week_view_on_delete_appointment (GtkWidget *widget, gpointer data) +e_week_view_delete_event_internal (EWeekView *week_view, gint event_num) { - EWeekView *week_view; - EWeekViewEvent *event; CalComponentVType vtype; - - week_view = E_WEEK_VIEW (data); - - if (week_view->popup_event_num == -1) - return; + EWeekViewEvent *event; event = &g_array_index (week_view->events, EWeekViewEvent, - week_view->popup_event_num); + event_num); vtype = cal_component_get_vtype (event->comp); - if (delete_component_dialog (event->comp, 1, vtype, widget)) { + if (delete_component_dialog (event->comp, 1, vtype, + GTK_WIDGET (week_view))) { const char *uid; cal_component_get_uid (event->comp, &uid); @@ -3456,6 +3475,35 @@ e_week_view_on_delete_appointment (GtkWidget *widget, gpointer data) } } + +static void +e_week_view_on_delete_appointment (GtkWidget *widget, gpointer data) +{ + EWeekView *week_view; + + week_view = E_WEEK_VIEW (data); + + if (week_view->popup_event_num == -1) + return; + + e_week_view_delete_event_internal (week_view, + week_view->popup_event_num); +} + + +void +e_week_view_delete_event (EWeekView *week_view) +{ + g_return_if_fail (E_IS_WEEK_VIEW (week_view)); + + if (week_view->editing_event_num == -1) + return; + + e_week_view_delete_event_internal (week_view, + week_view->editing_event_num); +} + + static void e_week_view_on_cut (GtkWidget *widget, gpointer data) { @@ -3839,3 +3887,13 @@ e_week_view_layout_timeout_cb (gpointer data) week_view->layout_timeout_id = 0; return FALSE; } + + +/* Returns the number of selected events (0 or 1 at present). */ +gint +e_week_view_get_num_events_selected (EWeekView *week_view) +{ + g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), 0); + + return (week_view->editing_event_num != -1) ? 1 : 0; +} diff --git a/calendar/gui/e-week-view.h b/calendar/gui/e-week-view.h index 07ff4770c3..9b4d4c817b 100644 --- a/calendar/gui/e-week-view.h +++ b/calendar/gui/e-week-view.h @@ -368,6 +368,9 @@ struct _EWeekView struct _EWeekViewClass { GtkTableClass parent_class; + + /* Notification signals */ + void (* selection_changed) (EWeekView *week_view); }; @@ -450,6 +453,10 @@ void e_week_view_cut_clipboard (EWeekView *week_view); void e_week_view_copy_clipboard (EWeekView *week_view); void e_week_view_paste_clipboard (EWeekView *week_view); +void e_week_view_delete_event (EWeekView *week_view); + +/* Returns the number of selected events (0 or 1 at present). */ +gint e_week_view_get_num_events_selected (EWeekView *week_view); /* * Internal functions called by the associated canvas items. diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index 01714db44b..a2282ba2f1 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -154,6 +154,7 @@ struct _GnomeCalendarPrivate { enum { DATES_SHOWN_CHANGED, + SELECTION_CHANGED, LAST_SIGNAL }; @@ -233,6 +234,15 @@ gnome_calendar_class_init (GnomeCalendarClass *class) gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); + gnome_calendar_signals[SELECTION_CHANGED] = + gtk_signal_new ("selection_changed", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (GnomeCalendarClass, + selection_changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + gtk_object_class_add_signals (object_class, gnome_calendar_signals, LAST_SIGNAL); @@ -240,6 +250,7 @@ gnome_calendar_class_init (GnomeCalendarClass *class) object_class->destroy = gnome_calendar_destroy; class->dates_shown_changed = NULL; + class->selection_changed = NULL; } /* Callback used when the calendar query reports of an updated object */ @@ -320,6 +331,35 @@ dn_query_eval_error_cb (CalQuery *query, const char *error_str, gpointer data) fprintf (stderr, "eval error: %s\n", error_str); } +/* Returns the current view widget, a EDayView or EWeekView. */ +static GtkWidget* +gnome_calendar_get_current_view_widget (GnomeCalendar *gcal) +{ + GnomeCalendarPrivate *priv; + GtkWidget *retval = NULL; + + priv = gcal->priv; + + switch (priv->current_view_type) { + case GNOME_CAL_DAY_VIEW: + retval = priv->day_view; + break; + case GNOME_CAL_WORK_WEEK_VIEW: + retval = priv->work_week_view; + break; + case GNOME_CAL_WEEK_VIEW: + retval = priv->week_view; + break; + case GNOME_CAL_MONTH_VIEW: + retval = priv->month_view; + break; + default: + g_assert_not_reached (); + } + + return retval; +} + /* Computes the range of time that the date navigator is showing */ static void get_date_navigator_range (GnomeCalendar *gcal, time_t *start_time, time_t *end_time) @@ -548,6 +588,16 @@ search_bar_category_changed_cb (CalSearchBar *cal_search, const char *category, } static void +view_selection_changed_cb (GtkWidget *view, GnomeCalendar *gcal) +{ + g_print ("In view_selection_changed_cb\n"); + + gtk_signal_emit (GTK_OBJECT (gcal), + gnome_calendar_signals[SELECTION_CHANGED]); +} + + +static void setup_widgets (GnomeCalendar *gcal) { GnomeCalendarPrivate *priv; @@ -630,6 +680,8 @@ setup_widgets (GnomeCalendar *gcal) gtk_widget_show (priv->day_view); gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->day_view, gtk_label_new ("")); + gtk_signal_connect (GTK_OBJECT (priv->day_view), "selection_changed", + GTK_SIGNAL_FUNC (view_selection_changed_cb), gcal); /* The Work Week View. */ priv->work_week_view = e_day_view_new (); @@ -640,6 +692,8 @@ setup_widgets (GnomeCalendar *gcal) gtk_widget_show (priv->work_week_view); gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->work_week_view, gtk_label_new ("")); + gtk_signal_connect (GTK_OBJECT (priv->work_week_view), "selection_changed", + GTK_SIGNAL_FUNC (view_selection_changed_cb), gcal); /* The Week View. */ priv->week_view = e_week_view_new (); @@ -647,6 +701,8 @@ setup_widgets (GnomeCalendar *gcal) gtk_widget_show (priv->week_view); gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->week_view, gtk_label_new ("")); + gtk_signal_connect (GTK_OBJECT (priv->week_view), "selection_changed", + GTK_SIGNAL_FUNC (view_selection_changed_cb), gcal); /* The Month View. */ priv->month_view = e_week_view_new (); @@ -655,6 +711,8 @@ setup_widgets (GnomeCalendar *gcal) gtk_widget_show (priv->month_view); gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), priv->month_view, gtk_label_new ("")); + gtk_signal_connect (GTK_OBJECT (priv->month_view), "selection_changed", + GTK_SIGNAL_FUNC (view_selection_changed_cb), gcal); gnome_calendar_update_config_settings (gcal, TRUE); } @@ -2077,6 +2135,8 @@ gnome_calendar_get_visible_time_range (GnomeCalendar *gcal, GnomeCalendarPrivate *priv; gboolean retval = FALSE; + g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE); + priv = gcal->priv; switch (priv->current_view_type) { @@ -2477,3 +2537,39 @@ gnome_calendar_notify_dates_shown_changed (GnomeCalendar *gcal) gnome_calendar_signals[DATES_SHOWN_CHANGED]); } } + + +/* Returns the number of selected events (0 or 1 at present). */ +gint +gnome_calendar_get_num_events_selected (GnomeCalendar *gcal) +{ + GtkWidget *view; + gint retval = 0; + + g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), 0); + + view = gnome_calendar_get_current_view_widget (gcal); + if (E_IS_DAY_VIEW (view)) + retval = e_day_view_get_num_events_selected (E_DAY_VIEW (view)); + else + retval = e_week_view_get_num_events_selected (E_WEEK_VIEW (view)); + + return retval; +} + + +void +gnome_calendar_delete_event (GnomeCalendar *gcal) +{ + GtkWidget *view; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + view = gnome_calendar_get_current_view_widget (gcal); + if (E_IS_DAY_VIEW (view)) + e_day_view_delete_event (E_DAY_VIEW (view)); + else + e_week_view_delete_event (E_WEEK_VIEW (view)); +} + + diff --git a/calendar/gui/gnome-cal.h b/calendar/gui/gnome-cal.h index 4bb232680c..e142ebec3c 100644 --- a/calendar/gui/gnome-cal.h +++ b/calendar/gui/gnome-cal.h @@ -68,6 +68,7 @@ struct _GnomeCalendarClass { /* Notification signals */ void (* dates_shown_changed) (GnomeCalendar *gcal); + void (* selection_changed) (GnomeCalendar *gcal); }; @@ -129,6 +130,9 @@ gboolean gnome_calendar_get_visible_time_range (GnomeCalendar *gcal, time_t *start_time, time_t *end_time); +/* Returns the number of selected events (0 or 1 at present). */ +gint gnome_calendar_get_num_events_selected (GnomeCalendar *gcal); + /* Tells the calendar to reload all config settings. initializing should be TRUE when we are setting the config settings for the first time. */ void gnome_calendar_update_config_settings (GnomeCalendar *gcal, @@ -143,6 +147,8 @@ void gnome_calendar_cut_clipboard (GnomeCalendar *gcal); void gnome_calendar_copy_clipboard (GnomeCalendar *gcal); void gnome_calendar_paste_clipboard (GnomeCalendar *gcal); +void gnome_calendar_delete_event (GnomeCalendar *gcal); + END_GNOME_DECLS diff --git a/calendar/gui/tasks-control.c b/calendar/gui/tasks-control.c index 327bc709a1..c6b9510d49 100644 --- a/calendar/gui/tasks-control.c +++ b/calendar/gui/tasks-control.c @@ -303,8 +303,11 @@ tasks_control_activate (BonoboControl *control, ETasks *tasks) bonobo_ui_component_thaw (uic, NULL); /* Show the dialog for setting the timezone if the user hasn't chosen - a default timezone already. */ + a default timezone already. This is done in the startup wizard now, + so we don't do it here. */ +#if 0 calendar_config_check_timezone_set (); +#endif control_util_set_folder_bar_label (control, ""); } |