aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--calendar/ChangeLog28
-rw-r--r--calendar/gui/dialogs/delete-comp.c136
-rw-r--r--calendar/gui/dialogs/delete-comp.h7
-rw-r--r--calendar/gui/e-calendar-table.c263
-rw-r--r--calendar/gui/e-day-view.c5
-rw-r--r--calendar/gui/e-week-view.c5
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);