aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--calendar/ChangeLog33
-rw-r--r--calendar/calendar-errors.xml14
-rw-r--r--calendar/calendar-errors.xml.h8
-rw-r--r--calendar/gui/Makefile.am2
-rw-r--r--calendar/gui/calendar-component.c161
-rw-r--r--calendar/gui/e-cal-popup.c241
-rw-r--r--calendar/gui/e-cal-popup.h145
-rw-r--r--calendar/gui/tasks-component.c169
8 files changed, 586 insertions, 187 deletions
diff --git a/calendar/ChangeLog b/calendar/ChangeLog
index 76770d4892..59b2b204dd 100644
--- a/calendar/ChangeLog
+++ b/calendar/ChangeLog
@@ -1,3 +1,36 @@
+2004-10-01 Not Zed <NotZed@Ximian.com>
+
+ * gui/tasks-component.c (create_component_view): cast warning
+ away.
+ (create_component_view): connect to popup_event rather than
+ fill_popup_menu.
+
+ * gui/calendar-component.c (create_component_view): cast a warning
+ away.
+
+ * calendar-errors.xml: add prompt-delete-task-list.
+
+ * gui/tasks-component.c (fill_popup_menu_cb): renamed to
+ popup_event_cb, make use e-cal-popup.
+ (edit_task_list_cb, new_task_list_cb, delete_task_list_cb)
+ (copy_task_list_cb): deja-vu. update for api.
+ (add_popup_menu_item): killed. murdered. drawn and quatered.
+ (delete_task_list_cb): use e-error for the delete prompt.
+
+ * gui/calendar-component.c (create_component_view): hook onto
+ popup event instead of fill_popup_menu.
+
+ * calendar-errors.xml: added prompt-delete-calendar.
+
+ * gui/calendar-component.c (fill_popup_menu_cb): rename to
+ popup_event_cb, make use e-cal-popup.
+ (edit_calendar_cb, new_calendar_cb, delete_calendar_cb)
+ (copy_calendar_cb): fix for api changes.
+ (add_popup_menu_item): removed.
+ (delete_calendar_cb): use e-error for the delete thing.
+
+ * gui/e-cal-popup.[ch]: calendar popup driver.
+
2004-09-29 Rodrigo Moya <rodrigo@novell.com>
Fixes #64683
diff --git a/calendar/calendar-errors.xml b/calendar/calendar-errors.xml
index 3e38b7e71a..9ed07ca503 100644
--- a/calendar/calendar-errors.xml
+++ b/calendar/calendar-errors.xml
@@ -163,4 +163,18 @@
<secondary>Your calendars will not be available until Evolution is restarted.</secondary>
</error>
+ <error id="prompt-delete-calendar" type="question" modal="true" default="GTK_RESPONSE_CANCEL">
+ <primary>Delete calendar '{0}'?</primary>
+ <secondary>This calendar will be removed permanently.</secondary>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
+
+ <error id="prompt-delete-task-list" type="question" modal="true" default="GTK_RESPONSE_CANCEL">
+ <primary>Delete task list '{0}'?</primary>
+ <secondary>This task list will be removed permanently.</secondary>
+ <button stock="gtk-cancel" response="GTK_RESPONSE_CANCEL"/>
+ <button stock="gtk-delete" response="GTK_RESPONSE_YES"/>
+ </error>
+
</error-list>
diff --git a/calendar/calendar-errors.xml.h b/calendar/calendar-errors.xml.h
index 85f62a501a..6e9df6221f 100644
--- a/calendar/calendar-errors.xml.h
+++ b/calendar/calendar-errors.xml.h
@@ -112,3 +112,11 @@ char *s = N_("Your tasks will not be available until Evolution is restarted.");
char *s = N_("The Evolution calendar has quit unexpectedly.");
/* calendar:calendar-crashed secondary */
char *s = N_("Your calendars will not be available until Evolution is restarted.");
+/* calendar:prompt-delete-calendar primary */
+char *s = N_("Delete calendar '{0}'?");
+/* calendar:prompt-delete-calendar secondary */
+char *s = N_("This calendar will be removed permanently.");
+/* calendar:prompt-delete-task-list primary */
+char *s = N_("Delete task list '{0}'?");
+/* calendar:prompt-delete-task-list secondary */
+char *s = N_("This task list will be removed permanently.");
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am
index 3272226955..d1b343a5c6 100644
--- a/calendar/gui/Makefile.am
+++ b/calendar/gui/Makefile.am
@@ -122,6 +122,8 @@ libevolution_calendar_la_SOURCES = \
e-cal-model-tasks.h \
e-cal-model.c \
e-cal-model.h \
+ e-cal-popup.h \
+ e-cal-popup.c \
e-calendar-view.c \
e-calendar-view.h \
e-cal-list-view.c \
diff --git a/calendar/gui/calendar-component.c b/calendar/gui/calendar-component.c
index 41d5a0c8ab..14f7aff23a 100644
--- a/calendar/gui/calendar-component.c
+++ b/calendar/gui/calendar-component.c
@@ -51,7 +51,9 @@
#include "dialogs/event-editor.h"
#include "widgets/misc/e-source-selector.h"
#include "widgets/misc/e-info-label.h"
+#include "widgets/misc/e-error.h"
#include "e-util/e-icon-factory.h"
+#include "e-cal-popup.h"
/* IDs for user creatable items */
#define CREATE_EVENT_ID "event"
@@ -308,133 +310,110 @@ update_primary_task_selection (CalendarComponentView *component_view)
/* Callbacks. */
static void
-add_popup_menu_item (GtkMenu *menu, const char *label, const char *icon_name,
- GCallback callback, gpointer user_data, gboolean sensitive)
-{
- GtkWidget *item, *image;
- GdkPixbuf *pixbuf;
-
- if (icon_name) {
- item = gtk_image_menu_item_new_with_label (label);
-
- /* load the image */
- pixbuf = e_icon_factory_get_icon (icon_name, E_ICON_SIZE_MENU);
- image = gtk_image_new_from_pixbuf (pixbuf);
-
- if (image) {
- gtk_widget_show (image);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
- }
- } else {
- item = gtk_menu_item_new_with_label (label);
- }
-
- if (callback)
- g_signal_connect (G_OBJECT (item), "activate", callback, user_data);
-
- if (!sensitive)
- gtk_widget_set_sensitive (item, FALSE);
-
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-}
-
-static void
-copy_calendar_cb (GtkWidget *widget, CalendarComponentView *component_view)
+copy_calendar_cb (EPopup *ep, EPopupItem *pitem, void *data)
{
+ CalendarComponentView *component_view = data;
ESource *selected_source;
selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
if (!selected_source)
return;
- copy_source_dialog (GTK_WINDOW (gtk_widget_get_toplevel (widget)), selected_source, E_CAL_SOURCE_TYPE_EVENT);
+ copy_source_dialog (GTK_WINDOW (gtk_widget_get_toplevel (ep->target->widget)), selected_source, E_CAL_SOURCE_TYPE_EVENT);
}
static void
-delete_calendar_cb (GtkWidget *widget, CalendarComponentView *component_view)
+delete_calendar_cb (EPopup *ep, EPopupItem *pitem, void *data)
{
+ CalendarComponentView *component_view = data;
ESource *selected_source;
- GtkWidget *dialog;
+ ECal *cal;
+ char *uri;
selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
if (!selected_source)
return;
- /* create the confirmation dialog */
- dialog = gtk_message_dialog_new (
- GTK_WINDOW (gtk_widget_get_toplevel (widget)),
- GTK_DIALOG_MODAL,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_YES_NO,
- _("Calendar '%s' will be removed. Are you sure you want to continue?"),
- e_source_peek_name (selected_source));
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES) {
- ECal *cal;
- char *uri;
-
- /* first, ask the backend to remove the calendar */
- uri = e_source_get_uri (selected_source);
- cal = e_cal_model_get_client_for_uri (gnome_calendar_get_calendar_model (component_view->calendar), uri);
- if (!cal)
- cal = e_cal_new_from_uri (uri, E_CAL_SOURCE_TYPE_EVENT);
- g_free (uri);
- if (cal) {
- if (e_cal_remove (cal, NULL)) {
- if (e_source_selector_source_is_selected (E_SOURCE_SELECTOR (component_view->source_selector),
- selected_source)) {
- gnome_calendar_remove_source (component_view->calendar, E_CAL_SOURCE_TYPE_EVENT, selected_source);
- e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector),
- selected_source);
- }
-
- e_source_group_remove_source (e_source_peek_group (selected_source), selected_source);
- e_source_list_sync (component_view->source_list, NULL);
+ if (e_error_run((GtkWindow *)gtk_widget_get_toplevel(ep->target->widget),
+ "calendar:prompt-delete-calendar", e_source_peek_name(selected_source)) != GTK_RESPONSE_YES)
+ return;
+
+ /* first, ask the backend to remove the calendar */
+ uri = e_source_get_uri (selected_source);
+ cal = e_cal_model_get_client_for_uri (gnome_calendar_get_calendar_model (component_view->calendar), uri);
+ if (!cal)
+ cal = e_cal_new_from_uri (uri, E_CAL_SOURCE_TYPE_EVENT);
+ g_free (uri);
+ if (cal) {
+ if (e_cal_remove (cal, NULL)) {
+ if (e_source_selector_source_is_selected (E_SOURCE_SELECTOR (component_view->source_selector),
+ selected_source)) {
+ gnome_calendar_remove_source (component_view->calendar, E_CAL_SOURCE_TYPE_EVENT, selected_source);
+ e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector),
+ selected_source);
}
+
+ e_source_group_remove_source (e_source_peek_group (selected_source), selected_source);
+ e_source_list_sync (component_view->source_list, NULL);
}
}
-
- gtk_widget_destroy (dialog);
}
static void
-new_calendar_cb (GtkWidget *widget, CalendarComponentView *component_view)
+new_calendar_cb (EPopup *ep, EPopupItem *pitem, void *data)
{
- calendar_setup_new_calendar (GTK_WINDOW (gtk_widget_get_toplevel (widget)));
+ calendar_setup_new_calendar (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)));
}
static void
-edit_calendar_cb (GtkWidget *widget, CalendarComponentView *component_view)
+edit_calendar_cb (EPopup *ep, EPopupItem *pitem, void *data)
{
+ CalendarComponentView *component_view = data;
ESource *selected_source;
selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
if (!selected_source)
return;
- calendar_setup_edit_calendar (GTK_WINDOW (gtk_widget_get_toplevel (widget)), selected_source);
+ calendar_setup_edit_calendar (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)), selected_source);
}
+static EPopupItem ecc_source_popups[] = {
+ { E_POPUP_ITEM, "10.new", N_("New Calendar"), new_calendar_cb, NULL, "stock_calendar", 0 },
+ { E_POPUP_ITEM, "15.copy", N_("Copy"), copy_calendar_cb, NULL, "stock_folder-copy", E_CAL_POPUP_SOURCE_PRIMARY },
+ { E_POPUP_ITEM, "20.delete", N_("Delete"), delete_calendar_cb, NULL, "stock_delete", E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY },
+ { E_POPUP_ITEM, "30.properties", N_("Properties..."), edit_calendar_cb, NULL, NULL, E_CAL_POPUP_SOURCE_PRIMARY },
+};
+
static void
-fill_popup_menu_cb (ESourceSelector *selector, GtkMenu *menu, CalendarComponentView *component_view)
+ecc_source_popup_free(EPopup *ep, GSList *list, void *data)
{
- ESource *source;
- gboolean sensitive, system;
- const char *source_uri;
-
- source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
- sensitive = source ? TRUE : FALSE;
+ g_slist_free(list);
+}
- /* FIXME Gross hack, should have a property or something */
- source_uri = e_source_peek_relative_uri (source);
- system = source_uri && !strcmp ("system", source_uri);
-
- add_popup_menu_item (menu, _("New Calendar"), "stock_calendar",
- G_CALLBACK (new_calendar_cb), component_view, TRUE);
- add_popup_menu_item (menu, _("Copy"), "stock_folder-copy",
- G_CALLBACK (copy_calendar_cb), component_view, sensitive);
- add_popup_menu_item (menu, _("Delete"), "stock_delete", G_CALLBACK (delete_calendar_cb), component_view, sensitive && !system);
- add_popup_menu_item (menu, _("Properties..."), NULL, G_CALLBACK (edit_calendar_cb), component_view, sensitive);
+static gboolean
+popup_event_cb(ESourceSelector *selector, ESource *insource, GdkEventButton *event, CalendarComponentView *component_view)
+{
+ ECalPopup *ep;
+ ECalPopupTargetSource *t;
+ GSList *menus = NULL;
+ int i;
+ GtkMenu *menu;
+
+ ep = e_cal_popup_new("com.novell.evolution.calendar.source.popup");
+ t = e_cal_popup_target_new_source(ep, selector);
+ t->target.widget = (GtkWidget *)component_view->calendar;
+
+ for (i=0;i<sizeof(ecc_source_popups)/sizeof(ecc_source_popups[0]);i++)
+ menus = g_slist_prepend(menus, &ecc_source_popups[i]);
+
+ e_popup_add_items((EPopup *)ep, menus, ecc_source_popup_free, component_view);
+
+ /* visibility is disabled, we only disable menu items */
+ menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0, t->target.mask);
+ gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event?event->button:0, event?event->time:gtk_get_current_event_time());
+
+ return TRUE;
}
static void
@@ -1057,7 +1036,7 @@ create_component_view (CalendarComponent *calendar_component)
/* Create sidebar selector */
component_view->source_selector = e_source_selector_new (calendar_component->priv->source_list);
- e_source_selector_set_select_new (component_view->source_selector, TRUE);
+ e_source_selector_set_select_new ((ESourceSelector *)component_view->source_selector, TRUE);
g_signal_connect (component_view->source_selector, "drag-motion", G_CALLBACK (selector_tree_drag_motion),
calendar_component);
@@ -1124,8 +1103,8 @@ create_component_view (CalendarComponent *calendar_component)
G_CALLBACK (source_selection_changed_cb), component_view);
g_signal_connect (component_view->source_selector, "primary_selection_changed",
G_CALLBACK (primary_source_selection_changed_cb), component_view);
- g_signal_connect (component_view->source_selector, "fill_popup_menu",
- G_CALLBACK (fill_popup_menu_cb), component_view);
+ g_signal_connect (component_view->source_selector, "popup_event",
+ G_CALLBACK (popup_event_cb), component_view);
/* Set up the "new" item handler */
component_view->creatable_items_handler = e_user_creatable_items_handler_new ("calendar", create_local_item_cb, calendar_component);
diff --git a/calendar/gui/e-cal-popup.c b/calendar/gui/e-cal-popup.c
new file mode 100644
index 0000000000..d0a751fce1
--- /dev/null
+++ b/calendar/gui/e-cal-popup.c
@@ -0,0 +1,241 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Michael Zucchi <notzed@ximian.com>
+ *
+ * Copyright 2004 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+#include <glib.h>
+
+#include "e-cal-popup.h"
+#include "widgets/misc/e-source-selector.h"
+
+static GObjectClass *ecalp_parent;
+
+static void
+ecalp_init(GObject *o)
+{
+ /*ECalPopup *eabp = (ECalPopup *)o; */
+}
+
+static void
+ecalp_finalise(GObject *o)
+{
+ ((GObjectClass *)ecalp_parent)->finalize(o);
+}
+
+static void
+ecalp_target_free(EPopup *ep, EPopupTarget *t)
+{
+ switch (t->type) {
+ case E_CAL_POPUP_TARGET_SELECT: {
+ ECalPopupTargetSelect *s = (ECalPopupTargetSelect *)t;
+
+ /* FIXME: implement */
+ s = s;
+ break; }
+ case E_CAL_POPUP_TARGET_SOURCE: {
+ ECalPopupTargetSource *s = (ECalPopupTargetSource *)t;
+
+ g_object_unref(s->selector);
+ break; }
+ }
+
+ ((EPopupClass *)ecalp_parent)->target_free(ep, t);
+}
+
+static void
+ecalp_class_init(GObjectClass *klass)
+{
+ klass->finalize = ecalp_finalise;
+ ((EPopupClass *)klass)->target_free = ecalp_target_free;
+}
+
+GType
+e_cal_popup_get_type(void)
+{
+ static GType type = 0;
+
+ if (type == 0) {
+ static const GTypeInfo info = {
+ sizeof(ECalPopupClass),
+ NULL, NULL,
+ (GClassInitFunc)ecalp_class_init,
+ NULL, NULL,
+ sizeof(ECalPopup), 0,
+ (GInstanceInitFunc)ecalp_init
+ };
+ ecalp_parent = g_type_class_ref(e_popup_get_type());
+ type = g_type_register_static(e_popup_get_type(), "ECalPopup", &info, 0);
+ }
+
+ return type;
+}
+
+ECalPopup *e_cal_popup_new(const char *menuid)
+{
+ ECalPopup *eabp = g_object_new(e_cal_popup_get_type(), 0);
+
+ e_popup_construct(&eabp->popup, menuid);
+
+ return eabp;
+}
+
+/**
+ * e_cal_popup_target_new_select:
+ *
+ * Create a new selection popup target.
+ *
+ * Return value:
+ **/
+ECalPopupTargetSelect *
+e_cal_popup_target_new_select(ECalPopup *eabp)
+{
+ ECalPopupTargetSelect *t = e_popup_target_new(&eabp->popup, E_CAL_POPUP_TARGET_SELECT, sizeof(*t));
+ guint32 mask = ~0;
+
+ /* FIXME: impelement */
+
+ t->target.mask = mask;
+
+ return t;
+}
+
+ECalPopupTargetSource *
+e_cal_popup_target_new_source(ECalPopup *eabp, ESourceSelector *selector)
+{
+ ECalPopupTargetSource *t = e_popup_target_new(&eabp->popup, E_CAL_POPUP_TARGET_SOURCE, sizeof(*t));
+ guint32 mask = ~0;
+ const char *source_uri;
+ ESource *source;
+
+ /* TODO: this is duplicated for addressbook too */
+
+ t->selector = selector;
+ g_object_ref(selector);
+
+ /* TODO: perhaps we need to copy this so it doesn't change during the lifecycle */
+ source = e_source_selector_peek_primary_selection(selector);
+ if (source)
+ mask &= ~E_CAL_POPUP_SOURCE_PRIMARY;
+
+ /* FIXME Gross hack, should have a property or something */
+ source_uri = e_source_peek_relative_uri(source);
+ if (source_uri && !strcmp("system", source_uri))
+ mask &= ~E_CAL_POPUP_SOURCE_SYSTEM;
+ else
+ mask &= ~E_CAL_POPUP_SOURCE_USER;
+
+ t->target.mask = mask;
+
+ return t;
+}
+
+/* ********************************************************************** */
+/* Popup menu plugin handler */
+
+/*
+<e-plugin
+ class="com.ximian.mail.plugin.popup:1.0"
+ id="com.ximian.mail.plugin.popup.iteab:1.0"
+ type="shlib"
+ location="/opt/gnome2/lib/camel/1.0/libcamelimap.so"
+ name="imap"
+ description="IMAP4 and IMAP4v1 mail store">
+ <hook class="com.ximian.mail.popupMenu:1.0"
+ handler="HandlePopup">
+ <menu id="any" target="select">
+ <iteab
+ type="iteab|toggle|radio|image|submenu|bar"
+ active
+ path="foo/bar"
+ label="label"
+ icon="foo"
+ mask="select_one"
+ activate="ecalp_view_eabacs"/>
+ </menu>
+ </extension>
+
+*/
+
+static void *ecalph_parent_class;
+#define ecalph ((ECalPopupHook *)eph)
+
+static const EPopupHookTargetMask ecalph_select_masks[] = {
+ { "one", E_CAL_POPUP_SELECT_ONE },
+ { "many", E_CAL_POPUP_SELECT_MANY },
+ { 0 }
+};
+
+static const EPopupHookTargetMask ecalph_source_masks[] = {
+ { "primary", E_CAL_POPUP_SOURCE_PRIMARY },
+ { "system", E_CAL_POPUP_SOURCE_SYSTEM },
+ { 0 }
+};
+
+static const EPopupHookTargetMap ecalph_targets[] = {
+ { "select", E_CAL_POPUP_TARGET_SELECT, ecalph_select_masks },
+ { "source", E_CAL_POPUP_TARGET_SOURCE, ecalph_source_masks },
+ { 0 }
+};
+
+static void
+ecalph_finalise(GObject *o)
+{
+ /*EPluginHook *eph = (EPluginHook *)o;*/
+
+ ((GObjectClass *)ecalph_parent_class)->finalize(o);
+}
+
+static void
+ecalph_class_init(EPluginHookClass *klass)
+{
+ int i;
+
+ ((GObjectClass *)klass)->finalize = ecalph_finalise;
+ ((EPluginHookClass *)klass)->id = "com.ximian.evolution.addressbook.popup:1.0";
+
+ for (i=0;ecalph_targets[i].type;i++)
+ e_popup_hook_class_add_target_map((EPopupHookClass *)klass, &ecalph_targets[i]);
+
+ ((EPopupHookClass *)klass)->popup_class = g_type_class_ref(e_cal_popup_get_type());
+}
+
+GType
+e_cal_popup_hook_get_type(void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static const GTypeInfo info = {
+ sizeof(ECalPopupHookClass), NULL, NULL, (GClassInitFunc) ecalph_class_init, NULL, NULL,
+ sizeof(ECalPopupHook), 0, (GInstanceInitFunc) NULL,
+ };
+
+ ecalph_parent_class = g_type_class_ref(e_popup_hook_get_type());
+ type = g_type_register_static(e_popup_hook_get_type(), "ECalPopupHook", &info, 0);
+ }
+
+ return type;
+}
diff --git a/calendar/gui/e-cal-popup.h b/calendar/gui/e-cal-popup.h
new file mode 100644
index 0000000000..81d2d51976
--- /dev/null
+++ b/calendar/gui/e-cal-popup.h
@@ -0,0 +1,145 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Authors: Michael Zucchi <notzed@ximian.com>
+ *
+ * Copyright 2004 Novell, Inc. (www.novell.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#ifndef __E_CAL_POPUP_H__
+#define __E_CAL_POPUP_H__
+
+#include <glib-object.h>
+
+#include "e-util/e-popup.h"
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+typedef struct _ECalPopup ECalPopup;
+typedef struct _ECalPopupClass ECalPopupClass;
+
+/**
+ * enum _e_cal_popup_target_t - A list of mail popup target types.
+ *
+ * @E_CAL_POPUP_TARGET_SELECT: A selection of cards
+ * @E_CAL_POPUP_TARGET_SOURCE: A source selection.
+ *
+ * Defines the value of the targetid for all ECalPopup target types.
+ **/
+enum _e_cal_popup_target_t {
+ E_CAL_POPUP_TARGET_SELECT,
+ E_CAL_POPUP_TARGET_SOURCE,
+};
+
+/**
+ * enum _e_cal_popup_target_select_t - ECalPopupTargetSelect qualifiers.
+ *
+ * @E_CAL_POPUP_SELECT_ONE: Only one item is selected.
+ * @E_CAL_POPUP_SELECT_MANY: One ore more items are selected.
+ *
+ **/
+enum _e_cal_popup_target_select_t {
+ E_CAL_POPUP_SELECT_ONE = 1<<1,
+ E_CAL_POPUP_SELECT_MANY = 1<<2,
+};
+
+/**
+ * enum _e_cal_popup_target_source_t - ECalPopupTargetSource qualifiers.
+ *
+ * @E_CAL_POPUP_SOURCE_PRIMARY: Has a primary selection.
+ * @E_CAL_POPUP_SOURCE_SYSTEM: Is a 'system' folder.
+ *
+ **/
+enum _e_cal_popup_target_source_t {
+ E_CAL_POPUP_SOURCE_PRIMARY = 1<<0,
+ E_CAL_POPUP_SOURCE_SYSTEM = 1<<1, /* system folder */
+ E_CAL_POPUP_SOURCE_USER = 1<<2, /* user folder (!system) */
+};
+
+typedef struct _ECalPopupTargetSelect ECalPopupTargetSelect;
+typedef struct _ECalPopupTargetSource ECalPopupTargetSource;
+
+/**
+ * struct _ECalPopupTargetSelect - A list of address cards.
+ *
+ * @target: Superclass.
+ *
+ * Used to represent a selection of appointments as context for a popup
+ * menu.
+ *
+ * FIXME: impelemnt me
+ **/
+struct _ECalPopupTargetSelect {
+ EPopupTarget target;
+};
+
+/**
+ * struct _ECalPopupTargetSource - A source target.
+ *
+ * @target: Superclass.
+ * @selector: Selector holding the source selection.
+ *
+ * This target is used to represent a source selection.
+ **/
+struct _ECalPopupTargetSource {
+ EPopupTarget target;
+
+ struct _ESourceSelector *selector;
+};
+
+typedef struct _EPopupItem ECalPopupItem;
+
+/* The object */
+struct _ECalPopup {
+ EPopup popup;
+
+ struct _ECalPopupPrivate *priv;
+};
+
+struct _ECalPopupClass {
+ EPopupClass popup_class;
+};
+
+GType e_cal_popup_get_type(void);
+
+ECalPopup *e_cal_popup_new(const char *menuid);
+
+ECalPopupTargetSelect *e_cal_popup_target_new_select(ECalPopup *eabp);
+ECalPopupTargetSource *e_cal_popup_target_new_source(ECalPopup *eabp, struct _ESourceSelector *selector);
+
+/* ********************************************************************** */
+
+typedef struct _ECalPopupHook ECalPopupHook;
+typedef struct _ECalPopupHookClass ECalPopupHookClass;
+
+struct _ECalPopupHook {
+ EPopupHook hook;
+};
+
+struct _ECalPopupHookClass {
+ EPopupHookClass hook_class;
+};
+
+GType e_cal_popup_hook_get_type(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __E_CAL_POPUP_H__ */
diff --git a/calendar/gui/tasks-component.c b/calendar/gui/tasks-component.c
index a817ca8546..23482dc33f 100644
--- a/calendar/gui/tasks-component.c
+++ b/calendar/gui/tasks-component.c
@@ -40,6 +40,7 @@
#include "migration.h"
#include "comp-util.h"
#include "calendar-config.h"
+#include "e-cal-popup.h"
#include "common/authentication.h"
#include "dialogs/calendar-setup.h"
#include "dialogs/comp-editor.h"
@@ -47,6 +48,7 @@
#include "dialogs/task-editor.h"
#include "widgets/misc/e-source-selector.h"
#include "widgets/misc/e-info-label.h"
+#include "widgets/misc/e-error.h"
#include "e-util/e-icon-factory.h"
#define CREATE_TASK_ID "task"
@@ -252,137 +254,112 @@ update_primary_selection (TasksComponentView *component_view)
/* Callbacks. */
static void
-add_popup_menu_item (GtkMenu *menu, const char *label, const char *icon_name,
- GCallback callback, gpointer user_data, gboolean sensitive)
-{
- GtkWidget *item, *image;
- GdkPixbuf *pixbuf;
-
- if (icon_name) {
- item = gtk_image_menu_item_new_with_label (label);
-
- /* load the image */
- pixbuf = e_icon_factory_get_icon (icon_name, E_ICON_SIZE_MENU);
- image = gtk_image_new_from_pixbuf (pixbuf);
-
- if (image) {
- gtk_widget_show (image);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
- }
- } else {
- item = gtk_menu_item_new_with_label (label);
- }
-
- if (callback)
- g_signal_connect (G_OBJECT (item), "activate", callback, user_data);
-
- if (!sensitive)
- gtk_widget_set_sensitive (item, FALSE);
-
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
- gtk_widget_show (item);
-}
-
-static void
-copy_task_list_cb (GtkWidget *widget, TasksComponentView *component_view)
+copy_task_list_cb (EPopup *ep, EPopupItem *pitem, void *data)
{
+ TasksComponentView *component_view = data;
ESource *selected_source;
selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
if (!selected_source)
return;
- copy_source_dialog (GTK_WINDOW (gtk_widget_get_toplevel (widget)), selected_source, E_CAL_SOURCE_TYPE_TODO);
+ copy_source_dialog (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)), selected_source, E_CAL_SOURCE_TYPE_TODO);
}
static void
-delete_task_list_cb (GtkWidget *widget, TasksComponentView *component_view)
+delete_task_list_cb (EPopup *ep, EPopupItem *pitem, void *data)
{
+ TasksComponentView *component_view = data;
ESource *selected_source;
- GtkWidget *dialog;
+ ECal *cal;
+ char *uri;
selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
if (!selected_source)
return;
- /* create the confirmation dialog */
- dialog = gtk_message_dialog_new (
- GTK_WINDOW (gtk_widget_get_toplevel (widget)),
- GTK_DIALOG_MODAL,
- GTK_MESSAGE_QUESTION,
- GTK_BUTTONS_YES_NO,
- _("Task List '%s' will be removed. Are you sure you want to continue?"),
- e_source_peek_name (selected_source));
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_YES) {
- ECal *cal;
- char *uri;
-
- /* first, ask the backend to remove the task list */
- uri = e_source_get_uri (selected_source);
- cal = e_cal_model_get_client_for_uri (
- e_calendar_table_get_model (E_CALENDAR_TABLE (e_tasks_get_calendar_table (component_view->tasks))),
- uri);
- if (!cal)
- cal = e_cal_new_from_uri (uri, E_CAL_SOURCE_TYPE_TODO);
- g_free (uri);
- if (cal) {
- if (e_cal_remove (cal, NULL)) {
- if (e_source_selector_source_is_selected (E_SOURCE_SELECTOR (component_view->source_selector),
- selected_source)) {
- e_tasks_remove_todo_source (component_view->tasks, selected_source);
- e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector),
- selected_source);
- }
-
- e_source_group_remove_source (e_source_peek_group (selected_source), selected_source);
- e_source_list_sync (component_view->source_list, NULL);
+ if (e_error_run((GtkWindow *)gtk_widget_get_toplevel(ep->target->widget),
+ "calendar:prompt-delete-task-list", e_source_peek_name(selected_source)) != GTK_RESPONSE_YES)
+ return;
+
+ /* first, ask the backend to remove the task list */
+ uri = e_source_get_uri (selected_source);
+ cal = e_cal_model_get_client_for_uri (
+ e_calendar_table_get_model (E_CALENDAR_TABLE (e_tasks_get_calendar_table (component_view->tasks))),
+ uri);
+ if (!cal)
+ cal = e_cal_new_from_uri (uri, E_CAL_SOURCE_TYPE_TODO);
+ g_free (uri);
+ if (cal) {
+ if (e_cal_remove (cal, NULL)) {
+ if (e_source_selector_source_is_selected (E_SOURCE_SELECTOR (component_view->source_selector),
+ selected_source)) {
+ e_tasks_remove_todo_source (component_view->tasks, selected_source);
+ e_source_selector_unselect_source (E_SOURCE_SELECTOR (component_view->source_selector),
+ selected_source);
}
+
+ e_source_group_remove_source (e_source_peek_group (selected_source), selected_source);
+ e_source_list_sync (component_view->source_list, NULL);
}
}
-
- gtk_widget_destroy (dialog);
}
static void
-new_task_list_cb (GtkWidget *widget, TasksComponentView *component_view)
+new_task_list_cb (EPopup *ep, EPopupItem *pitem, void *data)
{
- calendar_setup_new_task_list (GTK_WINDOW (gtk_widget_get_toplevel (widget)));
+ calendar_setup_new_task_list (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)));
}
static void
-edit_task_list_cb (GtkWidget *widget, TasksComponentView *component_view)
+edit_task_list_cb (EPopup *ep, EPopupItem *pitem, void *data)
{
+ TasksComponentView *component_view = data;
ESource *selected_source;
selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
if (!selected_source)
return;
- calendar_setup_edit_task_list (GTK_WINDOW (gtk_widget_get_toplevel (widget)), selected_source);
+ calendar_setup_edit_task_list (GTK_WINDOW (gtk_widget_get_toplevel(ep->target->widget)), selected_source);
}
+static EPopupItem etc_source_popups[] = {
+ { E_POPUP_ITEM, "10.new", N_("New Task List"), new_task_list_cb, NULL, "stock_todo", 0 },
+ { E_POPUP_ITEM, "15.copy", N_("Copy"), copy_task_list_cb, NULL, "stock_folder-copy", E_CAL_POPUP_SOURCE_PRIMARY },
+ { E_POPUP_ITEM, "20.delete", N_("Delete"), delete_task_list_cb, NULL, "stock_delete", E_CAL_POPUP_SOURCE_USER|E_CAL_POPUP_SOURCE_PRIMARY },
+ { E_POPUP_ITEM, "30.properties", N_("Properties..."), edit_task_list_cb, NULL, NULL, E_CAL_POPUP_SOURCE_PRIMARY },
+};
+
static void
-fill_popup_menu_cb (ESourceSelector *selector, GtkMenu *menu, TasksComponentView *component_view)
+etc_source_popup_free(EPopup *ep, GSList *list, void *data)
{
- ESource *source;
- gboolean sensitive, system;
- const char *source_uri;
-
- source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (component_view->source_selector));
- sensitive = source ? TRUE : FALSE;
-
- /* FIXME Gross hack, should have a property or something */
- source_uri = e_source_peek_relative_uri (source);
- system = source_uri && !strcmp ("system", source_uri);
-
- add_popup_menu_item (menu, _("New Task List"), "stock_todo",
- G_CALLBACK (new_task_list_cb), component_view, TRUE);
- add_popup_menu_item (menu, _("Copy"), "stock_folder-copy",
- G_CALLBACK (copy_task_list_cb), component_view, sensitive);
- add_popup_menu_item (menu, _("Delete"), "stock_delete", G_CALLBACK (delete_task_list_cb),
- component_view, sensitive && !system);
- add_popup_menu_item (menu, _("Properties..."), NULL, G_CALLBACK (edit_task_list_cb),
- component_view, sensitive);
+ g_slist_free(list);
+}
+
+static gboolean
+popup_event_cb(ESourceSelector *selector, ESource *insource, GdkEventButton *event, TasksComponentView *component_view)
+{
+ ECalPopup *ep;
+ ECalPopupTargetSource *t;
+ GSList *menus = NULL;
+ int i;
+ GtkMenu *menu;
+
+ ep = e_cal_popup_new("com.novell.evolution.tasks.source.popup");
+ t = e_cal_popup_target_new_source(ep, selector);
+ t->target.widget = (GtkWidget *)component_view->tasks;
+
+ for (i=0;i<sizeof(etc_source_popups)/sizeof(etc_source_popups[0]);i++)
+ menus = g_slist_prepend(menus, &etc_source_popups[i]);
+
+ e_popup_add_items((EPopup *)ep, menus, etc_source_popup_free, component_view);
+
+ /* visibility is disabled, we only disable menu items */
+ menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0, t->target.mask);
+ gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event?event->button:0, event?event->time:gtk_get_current_event_time());
+
+ return TRUE;
}
static void
@@ -867,7 +844,7 @@ create_component_view (TasksComponent *tasks_component)
/* Create sidebar selector */
component_view->source_selector = e_source_selector_new (tasks_component->priv->source_list);
- e_source_selector_set_select_new (component_view->source_selector, TRUE);
+ e_source_selector_set_select_new ((ESourceSelector *)component_view->source_selector, TRUE);
g_signal_connect (component_view->source_selector, "drag-motion", G_CALLBACK (selector_tree_drag_motion),
tasks_component);
@@ -936,8 +913,8 @@ create_component_view (TasksComponent *tasks_component)
G_CALLBACK (source_selection_changed_cb), component_view);
g_signal_connect (component_view->source_selector, "primary_selection_changed",
G_CALLBACK (primary_source_selection_changed_cb), component_view);
- g_signal_connect (component_view->source_selector, "fill_popup_menu",
- G_CALLBACK (fill_popup_menu_cb), component_view);
+ g_signal_connect (component_view->source_selector, "popup_event",
+ G_CALLBACK (popup_event_cb), component_view);
/* Set up the "new" item handler */
component_view->creatable_items_handler = e_user_creatable_items_handler_new ("tasks", create_local_item_cb, tasks_component);