diff options
-rw-r--r-- | calendar/ChangeLog | 28 | ||||
-rw-r--r-- | calendar/gui/dialogs/delete-comp.c | 136 | ||||
-rw-r--r-- | calendar/gui/dialogs/delete-comp.h | 7 | ||||
-rw-r--r-- | calendar/gui/e-calendar-table.c | 263 | ||||
-rw-r--r-- | calendar/gui/e-day-view.c | 5 | ||||
-rw-r--r-- | calendar/gui/e-week-view.c | 5 |
6 files changed, 303 insertions, 141 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 371bddf744..62bb518bd7 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,31 @@ +2001-05-18 Federico Mena Quintero <federico@ximian.com> + + Fix bug #2829. + + * gui/dialogs/delete-comp.c (delete_component_dialog): Allow the + caller to specify whether just one or many components are to be + deleted. + + * gui/e-calendar-table.c (tasks_popup_one): Popup menu definition + for when one and only one task is selected. + (tasks_popup_many): Likewise, for more than one task. + (e_calendar_table_on_right_click): Do not create a structure for + the closure data; we can simply pass the cal_table. Use a + different menu depending on the number of selected tasks. + (mark_as_complete_cb): Renamed; now iterates over the selected + rows. + (delete_selected_components): New function to delete all the + selected components. + (delete_cb): Adjusted for delete_component_dialog(). + (open_task): New function, simply open a CalComponent in the task + editor. + (open_task_by_row): Renamed; use open_task(). + + * gui/e-week-view.c (e_week_view_on_delete_appointment): Updated + for delete_component_dialog(). + + * gui/e-day-view.c (e_day_view_on_delete_appointment): Likewise. + 2001-05-16 Duncan Mak <duncan@ximian.com> * gui/Makefile.am (evolution_calendar_SOURCES): removed diff --git a/calendar/gui/dialogs/delete-comp.c b/calendar/gui/dialogs/delete-comp.c index f24c3493fb..a5ba1162db 100644 --- a/calendar/gui/dialogs/delete-comp.c +++ b/calendar/gui/dialogs/delete-comp.c @@ -1,7 +1,6 @@ /* Evolution calendar - Delete calendar component dialog * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. + * Copyright (C) 2001 Ximian, Inc. * * Author: Federico Mena-Quintero <federico@ximian.com> * @@ -37,68 +36,109 @@ /** * delete_component_dialog: - * @comp: A calendar component. + * @comp: A calendar component if a single component is to be deleted, or NULL + * if more that one component is to be deleted. + * @n_comps: Number of components that are to be deleted. + * @vtype: Type of the components that are to be deleted. This is ignored + * if only one component is to be deleted, and the vtype is extracted from + * the component instead. * @widget: A widget to use as a basis for conversion from UTF8 into font * encoding. * - * Pops up a dialog box asking the user whether he wants to delete a particular - * calendar component. + * Pops up a dialog box asking the user whether he wants to delete a number + * of calendar components. * * Return value: TRUE if the user clicked Yes, FALSE otherwise. **/ gboolean -delete_component_dialog (CalComponent *comp, GtkWidget *widget) +delete_component_dialog (CalComponent *comp, + int n_comps, CalComponentVType vtype, + GtkWidget *widget) { - CalComponentText summary; - CalComponentVType vtype; - char *str, *tmp; + char *str; GtkWidget *dialog; - g_return_val_if_fail (comp != NULL, FALSE); - g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE); + if (comp) { + g_return_val_if_fail (IS_CAL_COMPONENT (comp), FALSE); + g_return_val_if_fail (n_comps == 1, FALSE); + } else { + g_return_val_if_fail (n_comps > 1, FALSE); + g_return_val_if_fail (vtype != CAL_COMPONENT_NO_TYPE, FALSE); + } + g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE); - vtype = cal_component_get_vtype (comp); - cal_component_get_summary (comp, &summary); - - tmp = e_utf8_to_gtk_string (widget, summary.value); - - switch (vtype) { - case CAL_COMPONENT_EVENT: - if (tmp) - str = g_strdup_printf (_("Are you sure you want to delete the appointment " - "`%s'?"), tmp); - else - str = g_strdup (_("Are you sure you want to delete this " - "untitled appointment?")); - break; - - case CAL_COMPONENT_TODO: - if (tmp) - str = g_strdup_printf (_("Are you sure you want to delete the task " - "`%s'?"), tmp); - else - str = g_strdup (_("Are you sure you want to delete this " - "untitled task?")); - break; - - case CAL_COMPONENT_JOURNAL: - if (tmp) - str = g_strdup_printf (_("Are you sure you want to delete the journal entry " - "`%s'?"), tmp); - else - str = g_strdup (_("Are you sure want to delete this " - "untitled journal entry?")); - break; - - default: - g_message ("delete_component_dialog(): Cannot handle object of type %d", vtype); - return FALSE; + if (comp) { + CalComponentText summary; + char *tmp; + + vtype = cal_component_get_vtype (comp); + cal_component_get_summary (comp, &summary); + + tmp = e_utf8_to_gtk_string (widget, summary.value); + + switch (vtype) { + case CAL_COMPONENT_EVENT: + if (tmp) + str = g_strdup_printf (_("Are you sure you want to delete " + "the appointment `%s'?"), tmp); + else + str = g_strdup (_("Are you sure you want to delete this " + "untitled appointment?")); + break; + + case CAL_COMPONENT_TODO: + if (tmp) + str = g_strdup_printf (_("Are you sure you want to delete " + "the task `%s'?"), tmp); + else + str = g_strdup (_("Are you sure you want to delete this " + "untitled task?")); + break; + + case CAL_COMPONENT_JOURNAL: + if (tmp) + str = g_strdup_printf (_("Are you sure you want to delete " + "the journal entry `%s'?"), tmp); + else + str = g_strdup (_("Are you sure want to delete this " + "untitled journal entry?")); + break; + + default: + g_message ("delete_component_dialog(): Cannot handle object of type %d", + vtype); + g_free (tmp); + return FALSE; + } + + g_free (tmp); + } else { + switch (vtype) { + case CAL_COMPONENT_EVENT: + str = g_strdup_printf (_("Are you sure you want to delete " + "%d appointments?"), n_comps); + break; + + case CAL_COMPONENT_TODO: + str = g_strdup_printf (_("Are you sure you want to delete " + "%d tasks?"), n_comps); + break; + + case CAL_COMPONENT_JOURNAL: + str = g_strdup_printf (_("Are you sure you want to delete " + "%d journal entries?"), n_comps); + break; + + default: + g_message ("delete_component_dialog(): Cannot handle objects of type %d", + vtype); + return FALSE; + } } dialog = gnome_question_dialog_modal (str, NULL, NULL); - g_free (tmp); g_free (str); if (gnome_dialog_run (GNOME_DIALOG (dialog)) == GNOME_YES) diff --git a/calendar/gui/dialogs/delete-comp.h b/calendar/gui/dialogs/delete-comp.h index d7243e75c4..3b728a3f7e 100644 --- a/calendar/gui/dialogs/delete-comp.h +++ b/calendar/gui/dialogs/delete-comp.h @@ -1,7 +1,6 @@ /* Evolution calendar - Delete calendar component dialog * - * Copyright (C) 2000 Helix Code, Inc. - * Copyright (C) 2000 Ximian, Inc. + * Copyright (C) 2001 Ximian, Inc. * * Author: Federico Mena-Quintero <federico@ximian.com> * @@ -26,6 +25,8 @@ #include <gtk/gtkwidget.h> #include <cal-util/cal-component.h> -gboolean delete_component_dialog (CalComponent *comp, GtkWidget *widget); +gboolean delete_component_dialog (CalComponent *comp, + int n_comps, CalComponentVType vtype, + GtkWidget *widget); #endif diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c index 83f54160c6..23104866ca 100644 --- a/calendar/gui/e-calendar-table.c +++ b/calendar/gui/e-calendar-table.c @@ -67,19 +67,12 @@ static gint e_calendar_table_on_right_click (ETable *table, ECalendarTable *cal_table); static void e_calendar_table_on_open_task (GtkWidget *menuitem, gpointer data); -static void e_calendar_table_on_mark_task_complete (GtkWidget *menuitem, - gpointer data); -static void e_calendar_table_on_delete_task (GtkWidget *menuitem, - gpointer data); static gint e_calendar_table_on_key_press (ETable *table, gint row, gint col, GdkEventKey *event, ECalendarTable *cal_table); -static void e_calendar_table_open_task (ECalendarTable *cal_table, - gint row); - static void e_calendar_table_apply_filter (ECalendarTable *cal_table); static void e_calendar_table_on_model_changed (ETableModel *model, ECalendarTable *cal_table); @@ -534,6 +527,28 @@ e_calendar_table_set_cal_client (ECalendarTable *cal_table, } +/* Opens a task in the task editor */ +static void +open_task (ECalendarTable *cal_table, CalComponent *comp) +{ + TaskEditor *tedit; + + tedit = task_editor_new (); + task_editor_set_cal_client (tedit, calendar_model_get_cal_client (cal_table->model)); + task_editor_set_todo_object (tedit, comp); + task_editor_focus (tedit); +} + +/* Opens the task in the specified row */ +static void +open_task_by_row (ECalendarTable *cal_table, int row) +{ + CalComponent *comp; + + comp = calendar_model_get_component (cal_table->model, row); + open_task (cal_table, comp); +} + static void e_calendar_table_on_double_click (ETable *table, gint row, @@ -541,147 +556,219 @@ e_calendar_table_on_double_click (ETable *table, GdkEvent *event, ECalendarTable *cal_table) { - g_print ("In e_calendar_table_on_double_click\n"); - - e_calendar_table_open_task (cal_table, row); + open_task_by_row (cal_table, row); } +/* Used from e_table_selected_row_foreach() */ +static void +mark_row_complete_cb (int model_row, gpointer data) +{ + ECalendarTable *cal_table; -static GnomeUIInfo e_calendar_table_popup_uiinfo[] = { - { GNOME_APP_UI_ITEM, N_("Mark Complete"), - N_("Mark the task complete"), e_calendar_table_on_mark_task_complete, - NULL, NULL, 0, 0, 0, 0 }, + cal_table = E_CALENDAR_TABLE (data); + calendar_model_mark_task_complete (cal_table->model, model_row); +} - GNOMEUIINFO_SEPARATOR, +/* Callback used for the "mark tasks as complete" menu item */ +static void +mark_as_complete_cb (GtkWidget *menuitem, gpointer data) +{ + ECalendarTable *cal_table; + ETable *etable; - { GNOME_APP_UI_ITEM, N_("Edit this task..."), - N_("Edit the task"), e_calendar_table_on_open_task, - NULL, NULL, 0, 0, 0, 0 }, - { GNOME_APP_UI_ITEM, N_("Delete this task"), - N_("Delete the task"), e_calendar_table_on_delete_task, - NULL, NULL, 0, 0, 0, 0 }, + cal_table = E_CALENDAR_TABLE (data); - GNOMEUIINFO_END -}; + etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); + e_table_selected_row_foreach (etable, mark_row_complete_cb, cal_table); +} +/* Used from e_table_selected_row_foreach(); puts the selected row number in an + * int pointed to by the closure data. + */ +static void +get_selected_row_cb (int model_row, gpointer data) +{ + int *row; -typedef struct _ECalendarMenuData ECalendarMenuData; -struct _ECalendarMenuData { - ECalendarTable *cal_table; - gint row; -}; + row = data; + *row = model_row; +} -static gint -e_calendar_table_on_right_click (ETable *table, - gint row, - gint col, - GdkEventButton *event, - ECalendarTable *cal_table) +/* Returns the component that is selected in the table; only works if there is + * one and only one selected row. + */ +static CalComponent * +get_selected_comp (ECalendarTable *cal_table) { - ECalendarMenuData menu_data; - GtkWidget *popup_menu; + ETable *etable; + int row; - menu_data.cal_table = cal_table; - menu_data.row = row; + etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); + g_assert (e_table_selected_count (etable) == 1); - popup_menu = gnome_popup_menu_new (e_calendar_table_popup_uiinfo); - gnome_popup_menu_do_popup_modal (popup_menu, NULL, NULL, event, - &menu_data); + row = -1; + e_table_selected_row_foreach (etable, + get_selected_row_cb, + &row); + g_assert (row != -1); - gtk_widget_destroy (popup_menu); - - return TRUE; + return calendar_model_get_component (cal_table->model, row); } +struct get_selected_uids_closure { + ECalendarTable *cal_table; + GSList *uids; +}; +/* Used from e_table_selected_row_foreach(), builds a list of the selected UIDs */ static void -e_calendar_table_on_open_task (GtkWidget *menuitem, - gpointer data) +add_uid_cb (int model_row, gpointer data) { - ECalendarMenuData *menu_data = (ECalendarMenuData*) data; + struct get_selected_uids_closure *closure; + CalComponent *comp; + const char *uid; - e_calendar_table_open_task (menu_data->cal_table, - menu_data->row); -} + closure = data; + comp = calendar_model_get_component (closure->cal_table->model, model_row); + cal_component_get_uid (comp, &uid); -static void -e_calendar_table_on_mark_task_complete (GtkWidget *menuitem, - gpointer data) + closure->uids = g_slist_prepend (closure->uids, (char *) uid); +} + +static GSList * +get_selected_uids (ECalendarTable *cal_table) { - ECalendarMenuData *menu_data = (ECalendarMenuData*) data; + struct get_selected_uids_closure closure; + ETable *etable; - calendar_model_mark_task_complete (menu_data->cal_table->model, - menu_data->row); -} + closure.cal_table = cal_table; + closure.uids = NULL; + + etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); + e_table_selected_row_foreach (etable, add_uid_cb, &closure); + return closure.uids; +} -/* Deletes a component from the table */ +/* Deletes all of the selected components in the table */ static void -delete_component (CalendarModel *model, int row, GtkWidget *widget) +delete_selected_components (ECalendarTable *cal_table) { - CalComponent *comp; + CalClient *client; + GSList *uids, *l; - comp = calendar_model_get_component (model, row); + uids = get_selected_uids (cal_table); - if (delete_component_dialog (comp, widget)) { - CalClient *client; + client = calendar_model_get_cal_client (cal_table->model); + + for (l = uids; l; l = l->next) { const char *uid; - client = calendar_model_get_cal_client (model); - cal_component_get_uid (comp, &uid); + uid = l->data; /* We don't check the return value; FALSE can mean the object * was not in the server anyways. */ cal_client_remove_object (client, uid); } + + g_slist_free (uids); } +/* Callback for the "delete tasks" menu item */ static void -e_calendar_table_on_delete_task (GtkWidget *menuitem, - gpointer data) +delete_cb (GtkWidget *menuitem, gpointer data) { - ECalendarMenuData *menu_data = (ECalendarMenuData*) data; + ECalendarTable *cal_table; + ETable *etable; + int n_selected; + CalComponent *comp; + + cal_table = E_CALENDAR_TABLE (data); + + etable = e_table_scrolled_get_table (E_TABLE_SCROLLED (cal_table->etable)); - delete_component (menu_data->cal_table->model, menu_data->row, menuitem); + n_selected = e_table_selected_count (etable); + g_assert (n_selected > 0); + + if (n_selected == 1) + comp = get_selected_comp (cal_table); + else + comp = NULL; + + if (delete_component_dialog (comp, n_selected, CAL_COMPONENT_TODO, GTK_WIDGET (cal_table))) + delete_selected_components (cal_table); } +static GnomeUIInfo tasks_popup_one[] = { + GNOMEUIINFO_ITEM_NONE (N_("Edit this task"), NULL, e_calendar_table_on_open_task), + GNOMEUIINFO_SEPARATOR, + GNOMEUIINFO_ITEM_NONE (N_("Mark as complete"), NULL, mark_as_complete_cb), + GNOMEUIINFO_ITEM_NONE (N_("Delete this task"), NULL, delete_cb), + GNOMEUIINFO_END +}; +static GnomeUIInfo tasks_popup_many[] = { + GNOMEUIINFO_ITEM_NONE (N_("Mark tasks as complete"), NULL, mark_as_complete_cb), + GNOMEUIINFO_ITEM_NONE (N_("Delete selected tasks"), NULL, delete_cb), + GNOMEUIINFO_END +}; static gint -e_calendar_table_on_key_press (ETable *table, - gint row, - gint col, - GdkEventKey *event, - ECalendarTable *cal_table) +e_calendar_table_on_right_click (ETable *table, + gint row, + gint col, + GdkEventButton *event, + ECalendarTable *cal_table) { - if (event->keyval == GDK_Delete) { - delete_component (cal_table->model, row, GTK_WIDGET (table)); - return TRUE; - } + GtkWidget *popup_menu; + int n_selected; - return FALSE; + n_selected = e_table_selected_count (table); + g_assert (n_selected > 0); + + if (n_selected == 1) + popup_menu = gnome_popup_menu_new (tasks_popup_one); + else + popup_menu = gnome_popup_menu_new (tasks_popup_many); + + gnome_popup_menu_do_popup_modal (popup_menu, NULL, NULL, event, cal_table); + gtk_widget_destroy (popup_menu); + + return TRUE; } static void -e_calendar_table_open_task (ECalendarTable *cal_table, - gint row) +e_calendar_table_on_open_task (GtkWidget *menuitem, + gpointer data) { - TaskEditor *tedit; + ECalendarTable *cal_table; CalComponent *comp; - tedit = task_editor_new (); - task_editor_set_cal_client (tedit, calendar_model_get_cal_client (cal_table->model)); + cal_table = E_CALENDAR_TABLE (data); - comp = calendar_model_get_component (cal_table->model, row); - task_editor_set_todo_object (tedit, comp); - - task_editor_focus (tedit); + comp = get_selected_comp (cal_table); + open_task (cal_table, comp); } +static gint +e_calendar_table_on_key_press (ETable *table, + gint row, + gint col, + GdkEventKey *event, + ECalendarTable *cal_table) +{ + if (event->keyval == GDK_Delete) { + delete_cb (NULL, cal_table); + return TRUE; + } + + return FALSE; +} + /* Loads the state of the table (headers shown etc.) from the given file. */ void e_calendar_table_load_state (ECalendarTable *cal_table, diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c index b19c7ff310..eac99a18aa 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -3321,6 +3321,7 @@ e_day_view_on_delete_appointment (GtkWidget *widget, gpointer data) { EDayView *day_view; EDayViewEvent *event; + CalComponentVType vtype; day_view = E_DAY_VIEW (data); @@ -3331,7 +3332,9 @@ 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); - if (delete_component_dialog (event->comp, widget)) { + vtype = cal_component_get_vtype (event->comp); + + if (delete_component_dialog (event->comp, 1, vtype, widget)) { const char *uid; cal_component_get_uid (event->comp, &uid); diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c index 96270c04aa..447fce8b77 100644 --- a/calendar/gui/e-week-view.c +++ b/calendar/gui/e-week-view.c @@ -3450,6 +3450,7 @@ e_week_view_on_delete_appointment (GtkWidget *widget, gpointer data) { EWeekView *week_view; EWeekViewEvent *event; + CalComponentVType vtype; week_view = E_WEEK_VIEW (data); @@ -3459,7 +3460,9 @@ e_week_view_on_delete_appointment (GtkWidget *widget, gpointer data) event = &g_array_index (week_view->events, EWeekViewEvent, week_view->popup_event_num); - if (delete_component_dialog (event->comp, widget)) { + vtype = cal_component_get_vtype (event->comp); + + if (delete_component_dialog (event->comp, 1, vtype, widget)) { const char *uid; cal_component_get_uid (event->comp, &uid); |