[evolution-patches] calendar main menu patch




Ok this might need some feedback before I commit it.

I wasn't sure where to hook in updating the context, and i haven't had a chance to test any of it yet, but i'm pretty sure what i've done will be adequate.  To make it consistent with the popup stuff I didn't do 100% identical logic with some of it - that should probably be verified/checked to make sense.

To handle both view areas I have two separate 'menu's to hook into, one is the taskpad the other is the main calendar view.  They both activate together but update based on the same logic the calendar does.

But the big problem stems from my last message to evolution-hackers about knowing the current state, the focus tracking (in calendar-commands.c) never switches to the taskpad, even when it has the focus.  In the work-week view, when you click on a different appointment it never gets a "selection changed" event either, leaving the target pointing at the first thing you clicked on - until you change focus and then it moves it.

Most of this isn't an issue with the calendar code since it just queries the current state but the plugin stuff needs to snapshot the state when it changes instead.

--
Michael Zucchi <notzed ximian com>
"born to die, live to work, it's all downhill from here"
Novell's Evolution and Free Software Developer
Index: calendar/ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution/calendar/ChangeLog,v
retrieving revision 1.2534
diff -u -p -r1.2534 ChangeLog
--- calendar/ChangeLog	12 Oct 2004 09:22:58 -0000	1.2534
+++ calendar/ChangeLog	14 Oct 2004 04:07:24 -0000
@@ -1,3 +1,29 @@
+2004-10-14  Not Zed  <NotZed Ximian com>
+
+	* gui/e-cal-menu.c (e_cal_menu_target_new_select): dont access a
+	NULL client.
+
+	* gui/gnome-cal.c (gnome_calendar_get_taskpad_menu)
+	(gnome_calendar_get_calendar_menu): accessors to get the menu
+	managers.
+	(gnome_calendar_init): setup menu managers.
+
+2004-10-13  Not Zed  <NotZed Ximian com>
+
+	* gui/calendar-commands.c (calendar_control_activate)
+	(calendar_control_deactivate): activate and deactivate the
+	calendar and taskpad menu handlers.
+	(sensitize_items): helper to sensitise items based on target
+	masks.
+	(calendar_control_sensitize_calendar_commands): update the
+	calendar menu manager target appropriately.
+	(sensitize_taskpad_commands): same for the taskpad.
+
+	* gui/e-cal-menu.[ch]: Targets for main menu management.
+
+	* gui/e-cal-popup.c (e_cal_popup_target_new_select): fix cast.
+	Also include the tasks stuff in the hook metadata.
+
 2004-10-12  Not Zed  <NotZed Ximian com>
 
 	* gui/dialogs/meeting-page.c (button_press_event): convert menu to
Index: calendar/gui/Makefile.am
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/Makefile.am,v
retrieving revision 1.298
diff -u -p -r1.298 Makefile.am
--- calendar/gui/Makefile.am	6 Oct 2004 03:22:38 -0000	1.298
+++ calendar/gui/Makefile.am	14 Oct 2004 04:07:24 -0000
@@ -115,6 +115,8 @@ libevolution_calendar_la_SOURCES =		\
 	e-alarm-list.h				\
 	e-cal-component-preview.c		\
 	e-cal-component-preview.h		\
+	e-cal-menu.c				\
+	e-cal-menu.h				\
 	e-cal-model-calendar.h			\
 	e-cal-model-calendar.c			\
 	e-cal-model-calendar.h			\
Index: calendar/gui/calendar-commands.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/calendar-commands.c,v
retrieving revision 1.154
diff -u -p -r1.154 calendar-commands.c
--- calendar/gui/calendar-commands.c	12 Oct 2004 06:58:11 -0000	1.154
+++ calendar/gui/calendar-commands.c	14 Oct 2004 04:07:24 -0000
@@ -66,6 +66,7 @@
 #include "e-cal-list-view.h"
 #include "evolution-shell-component-utils.h"
 #include "e-util/e-icon-factory.h"
+#include "e-cal-menu.h"
 
 /* Focusing information for the calendar view.  We have to keep track of this
  * ourselves because with Bonobo controls, we may get unpaired focus_out events.
@@ -487,6 +488,40 @@ calendar_get_text_for_folder_bar_label (
 }
 
 
+struct _sensitize_item {
+	char *command;
+	guint32 enable;
+};
+
+static void
+sensitize_items(BonoboUIComponent *uic, struct _sensitize_item *items, guint32 mask)
+{
+	while (items->command) {
+		char command[32];
+
+		g_assert(strlen(items->command)<21);
+		sprintf(command, "/commands/%s", items->command);
+
+		printf(" '%s' = %s\n", command, (items->enable & mask) == 0 ? "enable" : "disable");
+
+		bonobo_ui_component_set_prop (uic, command, "sensitive",
+					      (items->enable & mask) == 0 ? "1" : "0",
+					      NULL);
+		items++;
+	}
+}
+
+static struct _sensitize_item calendar_sensitize_table[] = {
+	{ "EventOpen", E_CAL_MENU_SELECT_ONE },
+	{ "Cut", E_CAL_MENU_SELECT_EDITABLE },
+	{ "Copy", E_CAL_MENU_SELECT_ANY },
+	{ "Paste", E_CAL_MENU_SELECT_EDITABLE },
+	{ "Delete", E_CAL_MENU_SELECT_EDITABLE|E_CAL_MENU_SELECT_NONRECURRING },
+	{ "DeleteOccurrence", E_CAL_MENU_SELECT_EDITABLE|E_CAL_MENU_SELECT_RECURRING },
+	{ "DeleteAllOccurrences", E_CAL_MENU_SELECT_EDITABLE|E_CAL_MENU_SELECT_RECURRING },
+	{ 0 }
+};
+
 /* Sensitizes the UI Component menu/toolbar calendar commands based on the
  * number of selected events. (This will always be 0 or 1 currently.)  If enable
  * is FALSE, all will be disabled.  Otherwise, the currently-selected number of
@@ -496,13 +531,13 @@ void
 calendar_control_sensitize_calendar_commands (BonoboControl *control, GnomeCalendar *gcal, gboolean enable)
 {
 	BonoboUIComponent *uic;
-	ECalendarViewEvent *event;
-	GList *list;
-	int n_selected;
 	GtkWidget *view;
-	ECal *e_cal;
-	gboolean selected_read_only = FALSE, default_read_only = FALSE, has_recurrences;
-	
+	ECalMenu *menu;
+	ECalModel *model;
+	GPtrArray *events;
+	GList *selected, *l;
+	ECalMenuTargetSelect *t;
+
 	uic = bonobo_control_get_ui_component (control);
 	g_assert (uic != NULL);
 
@@ -510,61 +545,43 @@ calendar_control_sensitize_calendar_comm
 		return;
 	
 	view = gnome_calendar_get_current_view_widget (gcal);
-	list = e_calendar_view_get_selected_events (E_CALENDAR_VIEW (view));
 
-	n_selected = enable ? g_list_length (list) : 0;
+	menu = gnome_calendar_get_calendar_menu (gcal);
+	model = e_calendar_view_get_model((ECalendarView *)view);
+	events = g_ptr_array_new();
+	selected = e_calendar_view_get_selected_events((ECalendarView *)view);
+	for (l=selected;l;l=g_list_next(l)) {
+		ECalendarViewEvent *event = l->data;
+		if (event)
+			g_ptr_array_add(events, e_cal_model_copy_component_data(event->comp_data));
+	}
+	g_list_free(selected);
 
-	event = (ECalendarViewEvent *) list ? list->data : NULL;
-	if (event && event->comp_data)
-		e_cal_is_read_only (event->comp_data->client, &selected_read_only, NULL);
-	else
-		selected_read_only = TRUE;
+	t = e_cal_menu_target_new_select(menu, model, events);
+	if (!enable)
+		t->target.mask = ~0;
 
+	sensitize_items(uic, calendar_sensitize_table, t->target.mask);
+#if 0
 	/* retrieve read-onlyness of the default client */
 	e_cal = e_cal_model_get_default_client (gnome_calendar_get_calendar_model (gcal));
 	if (e_cal)
 		e_cal_is_read_only (e_cal, &default_read_only, NULL);
 	else
 		default_read_only = TRUE;
+#endif
 
-	bonobo_ui_component_set_prop (uic, "/commands/EventOpen", "sensitive",
-				      n_selected != 1 ? "0" : "1",
-				      NULL);
-	bonobo_ui_component_set_prop (uic, "/commands/Cut", "sensitive",
-				      n_selected == 0 || selected_read_only ? "0" : "1",
-				      NULL);
-	bonobo_ui_component_set_prop (uic, "/commands/Copy", "sensitive",
-				      n_selected == 0 ? "0" : "1",
-				      NULL);
-	bonobo_ui_component_set_prop (uic, "/commands/Paste", "sensitive",
-				      default_read_only ? "0" : "1",
-				      NULL);
-
-	/* occurrence-related menu items */
-	has_recurrences = FALSE;
-	if (n_selected > 0 && !selected_read_only) {
-		if (list) {
-			event = (ECalendarViewEvent *) list->data;
-			if (e_cal_util_component_has_recurrences (event->comp_data->icalcomp))
-				has_recurrences = TRUE;
-		}
-	}
-
-	bonobo_ui_component_set_prop (uic, "/commands/Delete", "sensitive",
-				      n_selected == 0 || selected_read_only || has_recurrences ? "0" : "1",
-				      NULL);
-	bonobo_ui_component_set_prop (uic, "/commands/DeleteOccurrence", "sensitive",
-				      has_recurrences ? "1" : "0",
-				      NULL);
-	bonobo_ui_component_set_prop (uic, "/commands/DeleteAllOccurrences", "sensitive",
-				      has_recurrences ? "1" : "0",
-				      NULL);
-
-	/* free memory */
-	if (list)
-		g_list_free (list);
+	e_menu_update_target((EMenu *)menu, (EMenuTarget *)t);
 }
 
+static struct _sensitize_item taskpad_sensitize_table[] = {
+	{ "Cut", E_CAL_MENU_SELECT_EDITABLE },
+	{ "Copy", E_CAL_MENU_SELECT_ANY },
+	{ "Paste", E_CAL_MENU_SELECT_EDITABLE },
+	{ "Delete", E_CAL_MENU_SELECT_EDITABLE },
+	{ 0 }
+};
+
 /* Sensitizes the UI Component menu/toolbar tasks commands based on the number
  * of selected tasks.  If enable is FALSE, all will be disabled.  Otherwise, the
  * currently-selected number of tasks will be used.
@@ -573,37 +590,30 @@ static void
 sensitize_taskpad_commands (GnomeCalendar *gcal, BonoboControl *control, gboolean enable)
 {
 	BonoboUIComponent *uic;
-	int n_selected;
 	ECalendarTable *task_pad;
 	ECalModel *model;
-	ECal *e_cal;
-	gboolean read_only = TRUE;
-	
+	GSList *selected, *l;
+	ECalMenu *menu;
+	GPtrArray *events;
+	ECalMenuTargetSelect *t;
+
 	uic = bonobo_control_get_ui_component (control);
 	g_assert (uic != NULL);
 
-	n_selected = enable ? gnome_calendar_get_num_tasks_selected (gcal) : 0;
-	task_pad = gnome_calendar_get_task_pad (gcal);
+	menu = gnome_calendar_get_calendar_menu (gcal);
+	task_pad = gnome_calendar_get_task_pad(gcal);
 	model = e_calendar_table_get_model (task_pad);
-	e_cal = e_cal_model_get_default_client (model);
-	
-	if (e_cal)
-		e_cal_is_read_only (e_cal, &read_only, NULL);
-	else
-		read_only = TRUE;
+	selected = e_calendar_table_get_selected(task_pad);
+	events = g_ptr_array_new();
+	for (l=selected;l;l=g_slist_next(l))
+		g_ptr_array_add(events, e_cal_model_copy_component_data((ECalModelComponent *)l->data));
+	g_slist_free(selected);
+
+	t = e_cal_menu_target_new_select(menu, model, events);
+	if (!enable)
+		t->target.mask = ~0;
 
-	bonobo_ui_component_set_prop (uic, "/commands/Cut", "sensitive",
-				      n_selected == 0 || read_only ? "0" : "1",
-				      NULL);
-	bonobo_ui_component_set_prop (uic, "/commands/Copy", "sensitive",
-				      n_selected == 0 ? "0" : "1",
-				      NULL);
-	bonobo_ui_component_set_prop (uic, "/commands/Paste", "sensitive",
-				      enable && !read_only ? "1" : "0",
-				      NULL);
-	bonobo_ui_component_set_prop (uic, "/commands/Delete", "sensitive",
-				      n_selected == 0 || read_only ? "0" : "1",
-				      NULL);
+	sensitize_items(uic, taskpad_sensitize_table, t->target.mask);
 }
 
 /* Callback used when the selection in the calendar views changes */
@@ -614,6 +624,8 @@ gcal_calendar_selection_changed_cb (Gnom
 
 	control = BONOBO_CONTROL (data);
 
+	printf("calendar selection changed\n");
+
 	calendar_control_sensitize_calendar_commands (control, gcal, TRUE);
 }
 
@@ -762,6 +774,9 @@ calendar_control_activate (BonoboControl
 	g_signal_connect (gcal, "taskpad_focus_change",
 			  G_CALLBACK (gcal_taskpad_focus_change_cb), control);
 
+	e_menu_activate((EMenu *)gnome_calendar_get_calendar_menu (gcal), uic, 1);
+	e_menu_activate((EMenu *)gnome_calendar_get_taskpad_menu (gcal), uic, 1);
+
 	calendar_control_sensitize_calendar_commands (control, gcal, TRUE);
 	sensitize_taskpad_commands (gcal, control, TRUE);
 
@@ -789,6 +804,9 @@ calendar_control_deactivate (BonoboContr
 
 	uic = bonobo_control_get_ui_component (control);
 	g_assert (uic != NULL);
+
+	e_menu_activate((EMenu *)gnome_calendar_get_calendar_menu (gcal), uic, 0);
+	e_menu_activate((EMenu *)gnome_calendar_get_taskpad_menu (gcal), uic, 0);
 
 	gnome_calendar_set_ui_component (gcal, NULL);
 
Index: calendar/gui/e-cal-menu.c
===================================================================
RCS file: calendar/gui/e-cal-menu.c
diff -N calendar/gui/e-cal-menu.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/e-cal-menu.c	14 Oct 2004 04:07:24 -0000
@@ -0,0 +1,286 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ *  Authors: Michael Zucchi <notzed ximian com>
+ *
+ *  Copyright 2004 Ximian, Inc. (www.ximian.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; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  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-menu.h"
+#include "gui/e-cal-model.h"
+#include "itip-utils.h"
+
+static void ecalm_standard_menu_factory(EMenu *emp, void *data);
+
+static GObjectClass *ecalm_parent;
+
+static void
+ecalm_init(GObject *o)
+{
+	/*ECalMenu *emp = (ECalMenu *)o; */
+}
+
+static void
+ecalm_finalise(GObject *o)
+{
+	((GObjectClass *)ecalm_parent)->finalize(o);
+}
+
+static void
+ecalm_target_free(EMenu *ep, EMenuTarget *t)
+{
+	switch (t->type) {
+	case E_CAL_MENU_TARGET_SELECT: {
+		ECalMenuTargetSelect *s = (ECalMenuTargetSelect *)t;
+		int i;
+
+		for (i=0;i<s->events->len;i++)
+			e_cal_model_free_component_data(s->events->pdata[i]);
+		g_ptr_array_free(s->events, TRUE);
+		g_object_unref(s->model);
+		break; }
+	}
+
+	((EMenuClass *)ecalm_parent)->target_free(ep, t);
+}
+
+static void
+ecalm_class_init(GObjectClass *klass)
+{
+	klass->finalize = ecalm_finalise;
+	((EMenuClass *)klass)->target_free = ecalm_target_free;
+
+	e_menu_class_add_factory((EMenuClass *)klass, NULL, (EMenuFactoryFunc)ecalm_standard_menu_factory, NULL);
+}
+
+GType
+e_cal_menu_get_type(void)
+{
+	static GType type = 0;
+
+	if (type == 0) {
+		static const GTypeInfo info = {
+			sizeof(ECalMenuClass),
+			NULL, NULL,
+			(GClassInitFunc)ecalm_class_init,
+			NULL, NULL,
+			sizeof(ECalMenu), 0,
+			(GInstanceInitFunc)ecalm_init
+		};
+		ecalm_parent = g_type_class_ref(e_menu_get_type());
+		type = g_type_register_static(e_menu_get_type(), "ECalMenu", &info, 0);
+	}
+
+	return type;
+}
+
+ECalMenu *e_cal_menu_new(const char *menuid)
+{
+	ECalMenu *emp = g_object_new(e_cal_menu_get_type(), 0);
+
+	e_menu_construct(&emp->menu, menuid);
+
+	return emp;
+}
+
+/**
+ * e_cal_menu_target_new_select:
+ * @folder: The selection will ref this for the life of it.
+ * @folder_uri: 
+ * @uids: The selection will free this when done with it.
+ * 
+ * Create a new selection popup target.
+ * 
+ * Return value: 
+ **/
+ECalMenuTargetSelect *
+e_cal_menu_target_new_select(ECalMenu *eabp, struct _ECalModel *model, GPtrArray *events)
+{
+	ECalMenuTargetSelect *t = e_menu_target_new(&eabp->menu, E_CAL_MENU_TARGET_SELECT, sizeof(*t));
+	guint32 mask = ~0;
+	ECal *client;
+	gboolean read_only;
+
+	/* FIXME: This is duplicated in e-cal-popup */
+
+	t->model = model;
+	g_object_ref(t->model);
+	t->events = events;
+
+	if (t->events->len == 0) {
+		client = e_cal_model_get_default_client(t->model);
+	} else {
+		ECalModelComponent *comp_data = (ECalModelComponent *)t->events->pdata[0];
+
+		mask &= ~E_CAL_MENU_SELECT_ANY;
+		if (t->events->len == 1)
+			mask &= ~E_CAL_MENU_SELECT_ONE;
+		else
+			mask &= ~E_CAL_MENU_SELECT_MANY;
+
+		if (icalcomponent_get_first_property (comp_data->icalcomp, ICAL_URL_PROPERTY))
+			mask &= ~E_CAL_MENU_SELECT_HASURL;
+
+		if (e_cal_util_component_has_recurrences (comp_data->icalcomp))
+			mask &= ~E_CAL_MENU_SELECT_RECURRING;
+		else
+			mask &= ~E_CAL_MENU_SELECT_NONRECURRING;
+
+		if (e_cal_util_component_is_instance (comp_data->icalcomp))
+			mask &= ~E_CAL_MENU_SELECT_INSTANCE;
+
+		if (e_cal_util_component_has_organizer (comp_data->icalcomp)) {
+			ECalComponent *comp;
+
+			comp = e_cal_component_new ();
+			e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp));
+			if (!itip_organizer_is_user (comp, comp_data->client))
+				mask &= ~E_CAL_MENU_SELECT_ORGANIZER;
+
+			g_object_unref (comp);
+		} else {
+			/* organiser is synonym for owner in this case */
+			mask &= ~(E_CAL_MENU_SELECT_ORGANIZER|E_CAL_MENU_SELECT_NOTMEETING);
+		}
+
+		client = comp_data->client;
+	}
+
+	if (client) {
+		e_cal_is_read_only(client, &read_only, NULL);
+		if (!read_only)
+			mask &= ~E_CAL_MENU_SELECT_EDITABLE;
+
+		if (!e_cal_get_static_capability (client, CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT)
+		    && !e_cal_get_static_capability (client, CAL_STATIC_CAPABILITY_NO_CONV_TO_ASSIGN_TASK))
+			mask &= ~E_CAL_MENU_SELECT_ASSIGNABLE;
+	}
+
+	/* This bit isn't implemented ... */
+	mask &= ~E_CAL_MENU_SELECT_NOTEDITING;
+
+	t->target.mask = mask;
+
+	return t;
+}
+
+static void
+ecalm_standard_menu_factory(EMenu *emp, void *data)
+{
+	/* noop */
+}
+
+/* ********************************************************************** */
+
+/* menu plugin handler */
+
+/*
+<e-plugin
+  class="com.ximian.mail.plugin.popup:1.0"
+  id="com.ximian.mail.plugin.popup.item: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">
+   <item
+    type="item|toggle|radio|image|submenu|bar"
+    active
+    path="foo/bar"
+    label="label"
+    icon="foo"
+    mask="select_one"
+    activate="ecalm_view_emacs"/>
+  </menu>
+  </extension>
+
+*/
+
+static void *ecalph_parent_class;
+#define ecalph ((ECalMenuHook *)eph)
+
+static const EMenuHookTargetMask ecalph_select_masks[] = {
+	{ "one", E_CAL_MENU_SELECT_ONE },
+	{ "many", E_CAL_MENU_SELECT_MANY },
+	{ "editable", E_CAL_MENU_SELECT_EDITABLE },
+	{ "recurring", E_CAL_MENU_SELECT_RECURRING },
+	{ "non-recurring", E_CAL_MENU_SELECT_NONRECURRING },
+	{ "instance", E_CAL_MENU_SELECT_INSTANCE },
+	{ "organizer", E_CAL_MENU_SELECT_ORGANIZER },
+	{ "not-editing", E_CAL_MENU_SELECT_NOTEDITING },
+	{ "not-meeting", E_CAL_MENU_SELECT_NOTMEETING },
+	{ "assignable", E_CAL_MENU_SELECT_ASSIGNABLE },
+	{ "hasurl", E_CAL_MENU_SELECT_HASURL },
+	{ 0 }
+};
+
+static const EMenuHookTargetMap ecalph_targets[] = {
+	{ "select", E_CAL_MENU_TARGET_SELECT, ecalph_select_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.novell.evolution.calendar.bonobomenu:1.0";
+
+	for (i=0;ecalph_targets[i].type;i++)
+		e_menu_hook_class_add_target_map((EMenuHookClass *)klass, &ecalph_targets[i]);
+
+	/* FIXME: leaks parent set class? */
+	((EMenuHookClass *)klass)->menu_class = g_type_class_ref(e_cal_menu_get_type());
+}
+
+GType
+e_cal_menu_hook_get_type(void)
+{
+	static GType type = 0;
+	
+	if (!type) {
+		static const GTypeInfo info = {
+			sizeof(ECalMenuHookClass), NULL, NULL, (GClassInitFunc) ecalph_class_init, NULL, NULL,
+			sizeof(ECalMenuHook), 0, (GInstanceInitFunc) NULL,
+		};
+
+		ecalph_parent_class = g_type_class_ref(e_menu_hook_get_type());
+		type = g_type_register_static(e_menu_hook_get_type(), "ECalMenuHook", &info, 0);
+	}
+	
+	return type;
+}
Index: calendar/gui/e-cal-menu.h
===================================================================
RCS file: calendar/gui/e-cal-menu.h
diff -N calendar/gui/e-cal-menu.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ calendar/gui/e-cal-menu.h	14 Oct 2004 04:07:24 -0000
@@ -0,0 +1,124 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
+ *
+ *  Authors: Michel 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; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  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_MENU_H__
+#define __E_CAL_MENU_H__
+
+#include <glib-object.h>
+
+#include "e-util/e-menu.h"
+
+#ifdef __cplusplus
+extern "C" {
+#pragma }
+#endif /* __cplusplus */
+
+typedef struct _ECalMenu ECalMenu;
+typedef struct _ECalMenuClass ECalMenuClass;
+
+/* Current target description */
+/* Types of popup tagets */
+enum _e_cal_menu_target_t {
+	E_CAL_MENU_TARGET_SELECT,
+};
+
+/**
+ * enum _e_cal_menu_target_select_t - ECalPopupTargetSelect qualifiers.
+ * 
+ * @E_CAL_MENU_SELECT_ONE: Only one item is selected.
+ * @E_CAL_MENU_SELECT_MANY: More than one item selected.
+ * @E_CAL_MENU_SELECT_ANY: One or more items selected.
+ * @E_CAL_MENU_SELECT_EDITABLE: The selection is editable.
+ * @E_CAL_MENU_SELECT_RECURRING: Is a recurring event.
+ * @E_CAL_MENU_SELECT_NONRECURRING: Is not a recurring event.
+ * @E_CAL_MENU_SELECT_INSTANCE: This is an instance event.
+ * @E_CAL_MENU_SELECT_ORGANIZER: The user is the organiser of the event.
+ * @E_CAL_MENU_SELECT_NOTEDITING: The event is not being edited already.  Not implemented.
+ * @E_CAL_MENU_SELECT_NOTMEETING: The event is not a meeting.
+ * @E_CAL_MENU_SELECT_ASSIGNABLE: An assignable task.
+ * @E_CAL_MENU_SELECT_HASURL: A task that contains a URL.
+ **/
+enum _e_cal_menu_target_select_t {
+	E_CAL_MENU_SELECT_ONE = 1<<0,
+	E_CAL_MENU_SELECT_MANY = 1<<1,
+	E_CAL_MENU_SELECT_ANY = 1<<2,
+	E_CAL_MENU_SELECT_EDITABLE = 1<<3,
+	E_CAL_MENU_SELECT_RECURRING = 1<<4,
+	E_CAL_MENU_SELECT_NONRECURRING = 1<<5,
+	E_CAL_MENU_SELECT_INSTANCE = 1<<6,
+
+	E_CAL_MENU_SELECT_ORGANIZER = 1<<7,
+	E_CAL_MENU_SELECT_NOTEDITING = 1<<8,
+	E_CAL_MENU_SELECT_NOTMEETING = 1<<9,
+
+	E_CAL_MENU_SELECT_ASSIGNABLE = 1<<10,
+	E_CAL_MENU_SELECT_HASURL = 1<<11,
+};
+
+typedef struct _ECalMenuTargetSelect ECalMenuTargetSelect;
+
+struct _ECalMenuTargetSelect {
+	EMenuTarget target;
+
+	struct _ECalModel *model;
+	GPtrArray *events;
+};
+
+typedef struct _EMenuItem ECalMenuItem;
+
+/* The object */
+struct _ECalMenu {
+	EMenu menu;
+
+	struct _ECalMenuPrivate *priv;
+};
+
+struct _ECalMenuClass {
+	EMenuClass menu_class;
+};
+
+GType e_cal_menu_get_type(void);
+
+ECalMenu *e_cal_menu_new(const char *menuid);
+
+ECalMenuTargetSelect *e_cal_menu_target_new_select(ECalMenu *emp, struct _ECalModel *model, GPtrArray *events);
+
+/* ********************************************************************** */
+
+typedef struct _ECalMenuHook ECalMenuHook;
+typedef struct _ECalMenuHookClass ECalMenuHookClass;
+
+struct _ECalMenuHook {
+	EMenuHook hook;
+};
+
+struct _ECalMenuHookClass {
+	EMenuHookClass hook_class;
+};
+
+GType e_cal_menu_hook_get_type(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __E_CAL_MENU_H__ */
Index: calendar/gui/e-cal-popup.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-cal-popup.c,v
retrieving revision 1.3
diff -u -p -r1.3 e-cal-popup.c
--- calendar/gui/e-cal-popup.c	12 Oct 2004 07:45:09 -0000	1.3
+++ calendar/gui/e-cal-popup.c	14 Oct 2004 04:07:24 -0000
@@ -129,6 +129,8 @@ e_cal_popup_target_new_select(ECalPopup 
 	ECal *client;
 	gboolean read_only;
 
+	/* FIXME: This is duplicated in e-cal-menu */
+
 	t->model = model;
 	g_object_ref(t->model);
 	t->events = events;
@@ -136,8 +138,9 @@ e_cal_popup_target_new_select(ECalPopup 
 	if (t->events->len == 0) {
 		client = e_cal_model_get_default_client(t->model);
 	} else {
-		ECalModelComponent *comp_data = (ECalendarViewEvent *)t->events->pdata[0];
+		ECalModelComponent *comp_data = (ECalModelComponent *)t->events->pdata[0];
 
+		mask &= ~E_CAL_POPUP_SELECT_ANY;
 		if (t->events->len == 1)
 			mask &= ~E_CAL_POPUP_SELECT_ONE;
 		else
@@ -257,6 +260,8 @@ static const EPopupHookTargetMask ecalph
 	{ "organizer", E_CAL_POPUP_SELECT_ORGANIZER },
 	{ "not-editing", E_CAL_POPUP_SELECT_NOTEDITING },
 	{ "not-meeting", E_CAL_POPUP_SELECT_NOTMEETING },
+	{ "assignable", E_CAL_POPUP_SELECT_ASSIGNABLE },
+	{ "hasurl", E_CAL_POPUP_SELECT_HASURL },
 	{ 0 }
 };
 
Index: calendar/gui/e-cal-popup.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-cal-popup.h,v
retrieving revision 1.3
diff -u -p -r1.3 e-cal-popup.h
--- calendar/gui/e-cal-popup.h	12 Oct 2004 07:45:09 -0000	1.3
+++ calendar/gui/e-cal-popup.h	14 Oct 2004 04:07:24 -0000
@@ -53,7 +53,8 @@ enum _e_cal_popup_target_t {
  * 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.
+ * @E_CAL_POPUP_SELECT_MANY: More than one item selected.
+ * @E_CAL_POPUP_SELECT_ANY: One ore more items are selected.
  * @E_CAL_POPUP_SELECT_EDITABLE: The selection is editable.
  * @E_CAL_POPUP_SELECT_RECURRING: Is a recurring event.
  * @E_CAL_POPUP_SELECT_NONRECURRING: Is not a recurring event.
@@ -61,22 +62,24 @@ enum _e_cal_popup_target_t {
  * @E_CAL_POPUP_SELECT_ORGANIZER: The user is the organiser of the event.
  * @E_CAL_POPUP_SELECT_NOTEDITING: The event is not being edited already.  Not implemented.
  * @E_CAL_POPUP_SELECT_NOTMEETING: The event is not a meeting.
- * 
+ * @E_CAL_POPUP_SELECT_ASSIGNABLE: An assignable task.
+ * @E_CAL_POPUP_SELECT_HASURL: A task that contains a URL.
  **/
 enum _e_cal_popup_target_select_t {
 	E_CAL_POPUP_SELECT_ONE = 1<<0,
 	E_CAL_POPUP_SELECT_MANY = 1<<1,
-	E_CAL_POPUP_SELECT_EDITABLE = 1<<2,
-	E_CAL_POPUP_SELECT_RECURRING = 1<<3,
-	E_CAL_POPUP_SELECT_NONRECURRING = 1<<4,
-	E_CAL_POPUP_SELECT_INSTANCE = 1<<5,
+	E_CAL_POPUP_SELECT_ANY = 1<<2,
+	E_CAL_POPUP_SELECT_EDITABLE = 1<<3,
+	E_CAL_POPUP_SELECT_RECURRING = 1<<4,
+	E_CAL_POPUP_SELECT_NONRECURRING = 1<<5,
+	E_CAL_POPUP_SELECT_INSTANCE = 1<<6,
 
-	E_CAL_POPUP_SELECT_ORGANIZER = 1<<6,
-	E_CAL_POPUP_SELECT_NOTEDITING = 1<<7,
-	E_CAL_POPUP_SELECT_NOTMEETING = 1<<8,
+	E_CAL_POPUP_SELECT_ORGANIZER = 1<<7,
+	E_CAL_POPUP_SELECT_NOTEDITING = 1<<8,
+	E_CAL_POPUP_SELECT_NOTMEETING = 1<<9,
 
-	E_CAL_POPUP_SELECT_ASSIGNABLE = 1<<9,
-	E_CAL_POPUP_SELECT_HASURL = 1<<10,
+	E_CAL_POPUP_SELECT_ASSIGNABLE = 1<<10,
+	E_CAL_POPUP_SELECT_HASURL = 1<<11,
 };
 
 /**
Index: calendar/gui/e-calendar-table.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-calendar-table.c,v
retrieving revision 1.124
diff -u -p -r1.124 e-calendar-table.c
--- calendar/gui/e-calendar-table.c	12 Oct 2004 07:45:09 -0000	1.124
+++ calendar/gui/e-calendar-table.c	14 Oct 2004 04:07:25 -0000
@@ -746,6 +746,21 @@ e_calendar_table_delete_selected (ECalen
 }
 
 /**
+ * e_calendar_table_get_selected:
+ * @cal_table: 
+ * 
+ * Get the currently selected ECalModelComponent's on the table.
+ * 
+ * Return value: A GSList of the components, which should be
+ * g_slist_free'd when finished with.
+ **/
+GSList *
+e_calendar_table_get_selected (ECalendarTable *cal_table)
+{
+	return get_selected_objects(cal_table);
+}
+
+/**
  * e_calendar_table_cut_clipboard:
  * @cal_table: A calendar table.
  *
Index: calendar/gui/e-calendar-table.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/e-calendar-table.h,v
retrieving revision 1.23
diff -u -p -r1.23 e-calendar-table.h
--- calendar/gui/e-calendar-table.h	14 Jul 2004 02:20:55 -0000	1.23
+++ calendar/gui/e-calendar-table.h	14 Oct 2004 04:07:25 -0000
@@ -85,6 +85,8 @@ void       e_calendar_table_open_selecte
 void       e_calendar_table_complete_selected (ECalendarTable *cal_table);
 void       e_calendar_table_delete_selected (ECalendarTable *cal_table);
 
+GSList    *e_calendar_table_get_selected (ECalendarTable *cal_table);
+
 /* Clipboard related functions */
 void       e_calendar_table_cut_clipboard       (ECalendarTable *cal_table);
 void       e_calendar_table_copy_clipboard      (ECalendarTable *cal_table);
Index: calendar/gui/gnome-cal.c
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/gnome-cal.c,v
retrieving revision 1.352
diff -u -p -r1.352 gnome-cal.c
--- calendar/gui/gnome-cal.c	7 Oct 2004 01:42:50 -0000	1.352
+++ calendar/gui/gnome-cal.c	14 Oct 2004 04:07:27 -0000
@@ -79,6 +79,7 @@
 #include "ea-calendar.h"
 #include "common/authentication.h"
 #include "e-cal-popup.h"
+#include "e-cal-menu.h"
 
 /* FIXME glib 2.4 and above has this */
 #ifndef G_MAXINT32
@@ -127,7 +128,11 @@ struct _GnomeCalendarPrivate {
 
 	/* Activity */
 	EActivityHandler *activity_handler;
-	
+
+	/* plugin menu managers */
+	ECalMenu    *calendar_menu;
+	ECalMenu    *taskpad_menu;
+
 	/* Calendar query for the date navigator */
 	GList       *dn_queries; /* list of CalQueries */
 	char        *sexp;
@@ -1372,6 +1377,9 @@ gnome_calendar_init (GnomeCalendar *gcal
 	setup_config (gcal);
 	setup_widgets (gcal);
 
+	priv->calendar_menu = e_cal_menu_new("com.novell.evolution.calendar.view");
+	priv->taskpad_menu = e_cal_menu_new("com.novell.evolution.calendar.taskpad");
+
 	priv->dn_queries = NULL;	
 	priv->sexp = g_strdup ("#t"); /* Match all */
 	priv->todo_sexp = g_strdup ("#t");
@@ -1497,6 +1505,16 @@ gnome_calendar_destroy (GtkObject *objec
 			priv->view_menus = NULL;
 		}
 
+		if (priv->calendar_menu) {
+			g_object_unref (priv->calendar_menu);
+			priv->calendar_menu = NULL;
+		}
+
+		if (priv->taskpad_menu) {
+			g_object_unref (priv->taskpad_menu);
+			priv->taskpad_menu = NULL;
+		}
+
 		g_free (priv);
 		gcal->priv = NULL;
 	}
@@ -3343,4 +3361,18 @@ gnome_calendar_get_view_notebook_widget 
  	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
  
  	return GTK_WIDGET(gcal->priv->notebook);
+}
+
+ECalMenu *gnome_calendar_get_taskpad_menu (GnomeCalendar *gcal)
+{
+ 	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
+ 
+ 	return gcal->priv->taskpad_menu;
+}
+
+ECalMenu *gnome_calendar_get_calendar_menu (GnomeCalendar *gcal)
+{
+ 	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
+ 
+ 	return gcal->priv->calendar_menu;
 }
Index: calendar/gui/gnome-cal.h
===================================================================
RCS file: /cvs/gnome/evolution/calendar/gui/gnome-cal.h,v
retrieving revision 1.101
diff -u -p -r1.101 gnome-cal.h
--- calendar/gui/gnome-cal.h	7 Oct 2004 01:42:50 -0000	1.101
+++ calendar/gui/gnome-cal.h	14 Oct 2004 04:07:27 -0000
@@ -135,6 +135,9 @@ GtkWidget *gnome_calendar_get_e_calendar
 GtkWidget *gnome_calendar_get_search_bar_widget (GnomeCalendar *gcal);
 GtkWidget *gnome_calendar_get_view_notebook_widget (GnomeCalendar *gcal);
 
+struct _ECalMenu *gnome_calendar_get_taskpad_menu (GnomeCalendar *gcal);
+struct _ECalMenu *gnome_calendar_get_calendar_menu (GnomeCalendar *gcal);
+
 void gnome_calendar_setup_view_menus (GnomeCalendar *gcal, BonoboUIComponent *uic);
 void gnome_calendar_discard_view_menus (GnomeCalendar *gcal);
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]