evolution r36684 - in branches/kill-bonobo: addressbook/gui/component calendar/gui calendar/modules mail shell ui



Author: mbarnes
Date: Fri Oct 24 23:02:33 2008
New Revision: 36684
URL: http://svn.gnome.org/viewvc/evolution?rev=36684&view=rev

Log:
Commit recent work so I can merge from trunk.


Modified:
   branches/kill-bonobo/addressbook/gui/component/e-book-shell-content.c
   branches/kill-bonobo/addressbook/gui/component/e-book-shell-content.h
   branches/kill-bonobo/addressbook/gui/component/e-book-shell-sidebar.c
   branches/kill-bonobo/addressbook/gui/component/e-book-shell-sidebar.h
   branches/kill-bonobo/addressbook/gui/component/e-book-shell-view-actions.h
   branches/kill-bonobo/addressbook/gui/component/e-book-shell-view.c
   branches/kill-bonobo/calendar/gui/e-calendar-selector.c
   branches/kill-bonobo/calendar/modules/e-cal-shell-content.h
   branches/kill-bonobo/calendar/modules/e-cal-shell-sidebar.h
   branches/kill-bonobo/calendar/modules/e-memo-shell-content.c
   branches/kill-bonobo/calendar/modules/e-memo-shell-content.h
   branches/kill-bonobo/calendar/modules/e-memo-shell-sidebar.c
   branches/kill-bonobo/calendar/modules/e-memo-shell-sidebar.h
   branches/kill-bonobo/calendar/modules/e-memo-shell-view.c
   branches/kill-bonobo/calendar/modules/e-task-shell-content.c
   branches/kill-bonobo/calendar/modules/e-task-shell-content.h
   branches/kill-bonobo/calendar/modules/e-task-shell-sidebar.c
   branches/kill-bonobo/calendar/modules/e-task-shell-sidebar.h
   branches/kill-bonobo/calendar/modules/e-task-shell-view.c
   branches/kill-bonobo/mail/e-mail-shell-content.c
   branches/kill-bonobo/mail/e-mail-shell-content.h
   branches/kill-bonobo/mail/e-mail-shell-sidebar.c
   branches/kill-bonobo/mail/e-mail-shell-sidebar.h
   branches/kill-bonobo/mail/e-mail-shell-view-actions.c
   branches/kill-bonobo/mail/e-mail-shell-view-private.c
   branches/kill-bonobo/mail/e-mail-shell-view.c
   branches/kill-bonobo/mail/em-folder-selector.c
   branches/kill-bonobo/mail/em-folder-selector.h
   branches/kill-bonobo/mail/em-folder-tree.c
   branches/kill-bonobo/mail/em-folder-tree.h
   branches/kill-bonobo/mail/em-folder-utils.c
   branches/kill-bonobo/shell/e-shell-content.c
   branches/kill-bonobo/shell/e-shell-content.h
   branches/kill-bonobo/shell/e-shell-sidebar.c
   branches/kill-bonobo/shell/e-shell-sidebar.h
   branches/kill-bonobo/ui/evolution-mail.ui

Modified: branches/kill-bonobo/addressbook/gui/component/e-book-shell-content.c
==============================================================================
--- branches/kill-bonobo/addressbook/gui/component/e-book-shell-content.c	(original)
+++ branches/kill-bonobo/addressbook/gui/component/e-book-shell-content.c	Fri Oct 24 23:02:33 2008
@@ -185,10 +185,47 @@
 	gconf_bridge_bind_property_delayed (bridge, key, object, "position");
 }
 
+static guint32
+book_shell_content_check_state (EShellContent *shell_content)
+{
+	EBookShellContent *book_shell_content;
+	ESelectionModel *selection_model;
+	EAddressbookModel *model;
+	EAddressbookView *view;
+	guint32 state = 0;
+	gint n_contacts;
+	gint n_selected;
+
+	book_shell_content = E_BOOK_SHELL_CONTENT (shell_content);
+	view = e_book_shell_content_get_current_view (book_shell_content);
+	model = e_addressbook_view_get_model (view);
+
+	selection_model = e_addressbook_view_get_selection_model (view);
+	n_contacts = (selection_model != NULL) ?
+		e_selection_model_row_count (selection_model) : 0;
+	n_selected = (selection_model != NULL) ?
+		e_selection_model_selected_count (selection_model) : 0;
+
+	/* FIXME Finish the rest of the flags. */
+	if (n_selected == 1)
+		state |= E_BOOK_SHELL_CONTENT_SELECTION_SINGLE;
+	if (n_selected > 1)
+		state |= E_BOOK_SHELL_CONTENT_SELECTION_MULTIPLE;
+	if (e_addressbook_model_can_stop (model))
+		state |= E_BOOK_SHELL_CONTENT_SOURCE_IS_BUSY;
+	if (e_addressbook_model_get_editable (model))
+		state |= E_BOOK_SHELL_CONTENT_SOURCE_IS_EDITABLE;
+	if (n_contacts == 0)
+		state |= E_BOOK_SHELL_CONTENT_SOURCE_IS_EMPTY;
+
+	return state;
+}
+
 static void
 book_shell_content_class_init (EBookShellContentClass *class)
 {
 	GObjectClass *object_class;
+	EShellContentClass *shell_content_class;
 
 	parent_class = g_type_class_peek_parent (class);
 	g_type_class_add_private (class, sizeof (EBookShellContentPrivate));
@@ -199,6 +236,9 @@
 	object_class->dispose = book_shell_content_dispose;
 	object_class->constructed = book_shell_content_constructed;
 
+	shell_content_class = E_SHELL_CONTENT_CLASS (class);
+	shell_content_class->check_state = book_shell_content_check_state;
+
 	g_object_class_install_property (
 		object_class,
 		PROP_CURRENT_VIEW,

Modified: branches/kill-bonobo/addressbook/gui/component/e-book-shell-content.h
==============================================================================
--- branches/kill-bonobo/addressbook/gui/component/e-book-shell-content.h	(original)
+++ branches/kill-bonobo/addressbook/gui/component/e-book-shell-content.h	Fri Oct 24 23:02:33 2008
@@ -54,6 +54,18 @@
 typedef struct _EBookShellContentClass EBookShellContentClass;
 typedef struct _EBookShellContentPrivate EBookShellContentPrivate;
 
+enum {
+	E_BOOK_SHELL_CONTENT_SELECTION_SINGLE		= 1 << 0,
+	E_BOOK_SHELL_CONTENT_SELECTION_MULTIPLE		= 1 << 1,
+	E_BOOK_SHELL_CONTENT_SELECTION_HAS_EMAIL	= 1 << 2,
+	E_BOOK_SHELL_CONTENT_SELECTION_IS_CONTACT_LIST	= 1 << 3,
+	E_BOOK_SHELL_CONTENT_SELECTION_HAS_HTTP_URI	= 1 << 4,
+	E_BOOK_SHELL_CONTENT_SELECTION_HAS_MAILTO_URI	= 1 << 5,
+	E_BOOK_SHELL_CONTENT_SOURCE_IS_BUSY		= 1 << 6,
+	E_BOOK_SHELL_CONTENT_SOURCE_IS_EDITABLE		= 1 << 7,
+	E_BOOK_SHELL_CONTENT_SOURCE_IS_EMPTY		= 1 << 8
+};
+
 struct _EBookShellContent {
 	EShellContent parent;
 	EBookShellContentPrivate *priv;

Modified: branches/kill-bonobo/addressbook/gui/component/e-book-shell-sidebar.c
==============================================================================
--- branches/kill-bonobo/addressbook/gui/component/e-book-shell-sidebar.c	(original)
+++ branches/kill-bonobo/addressbook/gui/component/e-book-shell-sidebar.c	Fri Oct 24 23:02:33 2008
@@ -115,10 +115,41 @@
 	gtk_widget_show (widget);
 }
 
+static guint32
+book_shell_sidebar_check_state (EShellSidebar *shell_sidebar)
+{
+	EBookShellSidebar *book_shell_sidebar;
+	ESourceSelector *selector;
+	ESource *source;
+	gboolean is_system = FALSE;
+	guint32 state = 0;
+
+	priv = E_BOOK_SHELL_SIDEBAR_GET_PRIVATE (shell_sidebar);
+
+	book_shell_sidebar = E_BOOK_SHELL_SIDEBAR (shell_sidebar);
+	selector = e_book_shell_sidebar_get_selector (book_shell_sidebar);
+	source = e_source_selector_peek_primary_selection (selector);
+
+	if (source != NULL) {
+		const gchar *uri;
+
+		uri = e_source_peek_relative_uri (source);
+		is_system = (uri == NULL || strcmp (uri, "system") == 0);
+	}
+
+	if (source != NULL)
+		state |= E_BOOK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE;
+	if (is_system)
+		state |= E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM;
+
+	return state;
+}
+
 static void
 book_shell_sidebar_class_init (EBookShellSidebarClass *class)
 {
 	GObjectClass *object_class;
+	EShellSidebarClass *shell_sidebar_class;
 
 	parent_class = g_type_class_peek_parent (class);
 	g_type_class_add_private (class, sizeof (EBookShellSidebarPrivate));
@@ -128,6 +159,9 @@
 	object_class->dispose = book_shell_sidebar_dispose;
 	object_class->constructed = book_shell_sidebar_constructed;
 
+	shell_sidebar_class = E_SHELL_SIDEBAR_CLASS (class);
+	shell_sidebar_class->check_state = book_shell_sidebar_check_state;
+
 	g_object_class_install_property (
 		object_class,
 		PROP_SELECTOR,

Modified: branches/kill-bonobo/addressbook/gui/component/e-book-shell-sidebar.h
==============================================================================
--- branches/kill-bonobo/addressbook/gui/component/e-book-shell-sidebar.h	(original)
+++ branches/kill-bonobo/addressbook/gui/component/e-book-shell-sidebar.h	Fri Oct 24 23:02:33 2008
@@ -52,6 +52,11 @@
 typedef struct _EBookShellSidebarClass EBookShellSidebarClass;
 typedef struct _EBookShellSidebarPrivate EBookShellSidebarPrivate;
 
+enum {
+	E_BOOK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE		= 1 << 0,
+	E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM	= 1 << 1
+};
+
 struct _EBookShellSidebar {
 	EShellSidebar parent;
 	EBookShellSidebarPrivate *priv;

Modified: branches/kill-bonobo/addressbook/gui/component/e-book-shell-view-actions.h
==============================================================================
--- branches/kill-bonobo/addressbook/gui/component/e-book-shell-view-actions.h	(original)
+++ branches/kill-bonobo/addressbook/gui/component/e-book-shell-view-actions.h	Fri Oct 24 23:02:33 2008
@@ -31,6 +31,12 @@
 	E_SHELL_WINDOW_ACTION ((window), "address-book-delete")
 #define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_MOVE(window) \
 	E_SHELL_WINDOW_ACTION ((window), "address-book-move")
+#define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_POPUP_DELETE(window) \
+	E_SHELL_WINDOW_ACTION ((window), "address-book-popup-delete")
+#define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_POPUP_PROPERTIES(window) \
+	E_SHELL_WINDOW_ACTION ((window), "address-book-popup-properties")
+#define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_POPUP_SAVE_AS(window) \
+	E_SHELL_WINDOW_ACTION ((window), "address-book-popup-save-as")
 #define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_PROPERTIES(window) \
 	E_SHELL_WINDOW_ACTION ((window), "address-book-properties")
 #define E_SHELL_WINDOW_ACTION_ADDRESS_BOOK_RENAME(window) \

Modified: branches/kill-bonobo/addressbook/gui/component/e-book-shell-view.c
==============================================================================
--- branches/kill-bonobo/addressbook/gui/component/e-book-shell-view.c	(original)
+++ branches/kill-bonobo/addressbook/gui/component/e-book-shell-view.c	Fri Oct 24 23:02:33 2008
@@ -136,121 +136,134 @@
 book_shell_view_update_actions (EShellView *shell_view)
 {
 	EBookShellViewPrivate *priv;
-	EBookShellContent *book_shell_content;
-	EBookShellSidebar *book_shell_sidebar;
+	EShellContent *shell_content;
+	EShellSidebar *shell_sidebar;
 	EShellWindow *shell_window;
-	EAddressbookModel *model;
-	EAddressbookView *view;
-	ESelectionModel *selection_model;
-	ESourceSelector *selector;
-	ESource *source;
 	GtkAction *action;
 	const gchar *label;
-	gboolean editable;
 	gboolean sensitive;
-	gint n_contacts;
-	gint n_selected;
+	guint32 state;
+
+	/* Be descriptive. */
+	gboolean any_contacts_selected;
+	gboolean has_primary_source;
+	gboolean multiple_contacts_selected;
+	gboolean primary_source_is_system;
+	gboolean single_contact_selected;
+	gboolean selection_is_contact_list;
+	gboolean selection_has_email;
+	gboolean source_is_busy;
+	gboolean source_is_editable;
+	gboolean source_is_empty;
 
 	priv = E_BOOK_SHELL_VIEW_GET_PRIVATE (shell_view);
 
 	shell_window = e_shell_view_get_shell_window (shell_view);
 
-	book_shell_content = priv->book_shell_content;
-	view = e_book_shell_content_get_current_view (book_shell_content);
+	shell_content = e_shell_view_get_shell_content (shell_view);
+	state = e_shell_content_check_state (shell_content);
+
+	single_contact_selected =
+		(state & E_BOOK_SHELL_CONTENT_SELECTION_SINGLE);
+	multiple_contacts_selected =
+		(state & E_BOOK_SHELL_CONTENT_SELECTION_MULTIPLE);
+	selection_has_email =
+		(state & E_BOOK_SHELL_CONTENT_SELECTION_HAS_EMAIL);
+	selection_is_contact_list =
+		(state & E_BOOK_SHELL_CONTENT_SELECTION_IS_CONTACT_LIST);
+	source_is_busy =
+		(state & E_BOOK_SHELL_CONTENT_SOURCE_IS_BUSY);
+	source_is_editable =
+		(state & E_BOOK_SHELL_CONTENT_SOURCE_IS_EDITABLE);
+	source_is_empty =
+		(state & E_BOOK_SHELL_CONTENT_SOURCE_IS_EMPTY);
+
+	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+	state = e_shell_sidebar_check_state (shell_sidebar);
+
+	has_primary_source =
+		(state & E_BOOK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE);
+	primary_source_is_system =
+		(state & E_BOOK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM);
+
+	any_contacts_selected =
+		(single_contact_selected || multiple_contacts_selected);
+
+	action = ACTION (ADDRESS_BOOK_DELETE);
+	sensitive = has_primary_source && !primary_source_is_system;
+	gtk_action_set_sensitive (action, sensitive);
 
-	book_shell_sidebar = priv->book_shell_sidebar;
-	selector = e_book_shell_sidebar_get_selector (book_shell_sidebar);
-	source = e_source_selector_peek_primary_selection (selector);
-
-	model = e_addressbook_view_get_model (view);
-	editable = e_addressbook_model_get_editable (model);
-
-	selection_model = e_addressbook_view_get_selection_model (view);
-	n_contacts = (selection_model != NULL) ?
-		e_selection_model_row_count (selection_model) : 0;
-	n_selected = (selection_model != NULL) ?
-		e_selection_model_selected_count (selection_model) : 0;
+	action = ACTION (ADDRESS_BOOK_POPUP_DELETE);
+	sensitive = has_primary_source && !primary_source_is_system;
+	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (ADDRESS_BOOK_STOP);
-	sensitive = e_addressbook_model_can_stop (model);
+	sensitive = source_is_busy;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (CONTACT_CLIPBOARD_COPY);
-	sensitive = (n_selected > 0);
+	sensitive = any_contacts_selected;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (CONTACT_CLIPBOARD_CUT);
-	sensitive = editable && (n_selected > 0);
+	sensitive = source_is_editable && any_contacts_selected;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (CONTACT_CLIPBOARD_PASTE);
-	sensitive = editable;
+	sensitive = source_is_editable;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (CONTACT_COPY);
-	sensitive = (n_selected > 0);
+	sensitive = any_contacts_selected;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (CONTACT_DELETE);
-	sensitive = editable && (n_selected > 0);
+	sensitive = source_is_editable && any_contacts_selected;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (CONTACT_FORWARD);
-	sensitive = (n_selected > 0);
+	sensitive = any_contacts_selected;
 	gtk_action_set_sensitive (action, sensitive);
-	label = ngettext (
-		"_Forward Contact",
-		"_Forward Contacts", n_selected);
+	if (multiple_contacts_selected)
+		label = _("_Forward Contacts");
+	else
+		label = _("_Forward Contact");
 	g_object_set (action, "label", label, NULL);
 
 	action = ACTION (CONTACT_MOVE);
-	sensitive = editable && (n_selected > 0);
+	sensitive = source_is_editable && any_contacts_selected;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (CONTACT_OPEN);
-	sensitive = (n_selected > 0);
+	sensitive = any_contacts_selected;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (CONTACT_PRINT);
-	sensitive = (n_contacts > 0);
+	sensitive = any_contacts_selected;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (CONTACT_PRINT_PREVIEW);
-	sensitive = (n_contacts > 0);
+	sensitive = any_contacts_selected;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (CONTACT_SAVE_AS);
-	sensitive = (n_selected > 0);
+	sensitive = any_contacts_selected;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (CONTACT_SELECT_ALL);
-	sensitive = (n_contacts > 0);
+	sensitive = !(source_is_empty);
 	gtk_action_set_sensitive (action, sensitive);
 
-	/* FIXME Also check for email address. */
 	action = ACTION (CONTACT_SEND_MESSAGE);
-	sensitive = (n_selected > 0);
+	sensitive = any_contacts_selected && selection_has_email;
 	gtk_action_set_sensitive (action, sensitive);
-	label = ngettext (
-		"_Send Message to Contact",
-		"_Send Message to Contacts", n_selected);
+	if (multiple_contacts_selected)
+		label = _("_Send Message to Contacts");
+	else if (selection_is_contact_list)
+		label = _("_Send Message to List");
+	else
+		label = _("_Send Message to Contact");
 	g_object_set (action, "label", label, NULL);
-
-	/* TODO Add some context sensitivity to SEND_MESSAGE:
-	 *      Send Message to Contact  (n_selected == 1)
-	 *      Send Message to Contacts (n_selected > 1)
-	 *      Send Message to List     (n_selected == 1 && is_list)
-	 */
-
-	action = ACTION (ADDRESS_BOOK_DELETE);
-	if (source != NULL) {
-		const gchar *uri;
-
-		uri = e_source_peek_relative_uri (source);
-		sensitive = (uri == NULL || strcmp ("system", uri) != 0);
-	} else
-		sensitive = FALSE;
-	gtk_action_set_sensitive (action, sensitive);
 }
 
 static void

Modified: branches/kill-bonobo/calendar/gui/e-calendar-selector.c
==============================================================================
--- branches/kill-bonobo/calendar/gui/e-calendar-selector.c	(original)
+++ branches/kill-bonobo/calendar/gui/e-calendar-selector.c	Fri Oct 24 23:02:33 2008
@@ -231,7 +231,7 @@
 	const gchar *string;
 	gboolean remove_from_source;
 	gboolean success = FALSE;
-	gpointer object;
+	gpointer object = NULL;
 
 	tree_view = GTK_TREE_VIEW (widget);
 	model = gtk_tree_view_get_model (tree_view);

Modified: branches/kill-bonobo/calendar/modules/e-cal-shell-content.h
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-cal-shell-content.h	(original)
+++ branches/kill-bonobo/calendar/modules/e-cal-shell-content.h	Fri Oct 24 23:02:33 2008
@@ -54,6 +54,20 @@
 typedef struct _ECalShellContentClass ECalShellContentClass;
 typedef struct _ECalShellContentPrivate ECalShellContentPrivate;
 
+enum {
+	E_CAL_SHELL_CONTENT_SELECTION_SINGLE		= 1 << 0,
+	E_CAL_SHELL_CONTENT_SELECTION_MULTIPLE		= 1 << 1,
+	E_CAL_SHELL_CONTENT_SELECTION_IS_ASSIGNABLE	= 1 << 2,
+	E_CAL_SHELL_CONTENT_SELECTION_IS_COMPLETE	= 1 << 3,
+	E_CAL_SHELL_CONTENT_SELECTION_IS_EDITABLE	= 1 << 4,
+	E_CAL_SHELL_CONTENT_SELECTION_IS_MEETING	= 1 << 5,
+	E_CAL_SHELL_CONTENT_SELECTION_IS_ORGANIZER	= 1 << 6,
+	E_CAL_SHELL_CONTENT_SELECTION_IS_RECURRING	= 1 << 7,
+	E_CAL_SHELL_CONTENT_SELECTION_CAN_ACCEPT	= 1 << 8,
+	E_CAL_SHELL_CONTENT_SELECTION_CAN_DELEGATE	= 1 << 9,
+	E_CAL_SHELL_CONTENT_SELECTION_CAN_SAVE		= 1 << 10
+};
+
 struct _ECalShellContent {
 	EShellContent parent;
 	ECalShellContentPrivate *priv;

Modified: branches/kill-bonobo/calendar/modules/e-cal-shell-sidebar.h
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-cal-shell-sidebar.h	(original)
+++ branches/kill-bonobo/calendar/modules/e-cal-shell-sidebar.h	Fri Oct 24 23:02:33 2008
@@ -54,6 +54,13 @@
 typedef struct _ECalShellSidebarClass ECalShellSidebarClass;
 typedef struct _ECalShellSidebarPrivate ECalShellSidebarPrivate;
 
+enum {
+	E_CAL_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE		= 1 << 0,
+	E_CAL_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_EMPTY	= 1 << 1,
+	E_CAL_SHELL_SIDEBAR_SOURCE_CAN_GO_OFFLINE	= 1 << 2,
+	E_CAL_SHELL_SIDEBAR_SOURCE_CAN_DELETE		= 1 << 3
+};
+
 struct _ECalShellSidebar {
 	EShellSidebar parent;
 	ECalShellSidebarPrivate *priv;

Modified: branches/kill-bonobo/calendar/modules/e-memo-shell-content.c
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-memo-shell-content.c	(original)
+++ branches/kill-bonobo/calendar/modules/e-memo-shell-content.c	Fri Oct 24 23:02:33 2008
@@ -416,10 +416,56 @@
 	gconf_bridge_bind_property_delayed (bridge, key, object, "position");
 }
 
+static guint32
+memo_shell_content_check_state (EShellContent *shell_content)
+{
+	EMemoShellContent *memo_shell_content;
+	EMemoTable *memo_table;
+	ETable *table;
+	GSList *list, *iter;
+	gboolean editable = TRUE;
+	gboolean has_url = FALSE;
+	gint n_selected;
+	guint32 state = 0;
+
+	memo_shell_content = E_MEMO_SHELL_CONTENT (shell_content);
+	memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
+
+	table = e_memo_table_get_table (memo_table);
+	n_selected = e_table_selected_count (table);
+
+	list = e_memo_table_get_selected (memo_table);
+	for (iter = list; iter != NULL; iter = iter->next) {
+		ECalModelComponent *comp_data = iter->data;
+		icalproperty *prop;
+		gboolean read_only;
+
+		e_cal_is_read_only (comp_data->client, &read_only, NULL);
+		editable &= !read_only;
+
+		prop = icalcomponent_get_first_property (
+			comp_data->icalcomp, ICAL_URL_PROPERTY);
+		has_url |= (prop != NULL);
+	}
+	g_slist_free (list);
+
+	if (n_selected == 1)
+		state |= E_MEMO_SHELL_CONTENT_SELECTION_SINGLE;
+	if (n_selected > 1)
+		state |= E_MEMO_SHELL_CONTENT_SELECTION_MULTIPLE;
+	if (editable)
+		state |= E_MEMO_SHELL_CONTENT_SELECTION_CAN_EDIT;
+	if (has_url)
+		state |= E_MEMO_SHELL_CONTENT_SELECTION_HAS_URL;
+
+	return state;
+}
+
 static void
 memo_shell_content_class_init (EMemoShellContentClass *class)
 {
 	GObjectClass *object_class;
+	EShellContentClass *shell_content_class;
 
 	parent_class = g_type_class_peek_parent (class);
 	g_type_class_add_private (class, sizeof (EMemoShellContentPrivate));
@@ -431,6 +477,9 @@
 	object_class->finalize = memo_shell_content_finalize;
 	object_class->constructed = memo_shell_content_constructed;
 
+	shell_content_class = E_SHELL_CONTENT_CLASS (class);
+	shell_content_class->check_state = memo_shell_content_check_state;
+
 	g_object_class_install_property (
 		object_class,
 		PROP_PREVIEW_VISIBLE,

Modified: branches/kill-bonobo/calendar/modules/e-memo-shell-content.h
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-memo-shell-content.h	(original)
+++ branches/kill-bonobo/calendar/modules/e-memo-shell-content.h	Fri Oct 24 23:02:33 2008
@@ -55,6 +55,13 @@
 typedef struct _EMemoShellContentClass EMemoShellContentClass;
 typedef struct _EMemoShellContentPrivate EMemoShellContentPrivate;
 
+enum {
+	E_MEMO_SHELL_CONTENT_SELECTION_SINGLE		= 1 << 0,
+	E_MEMO_SHELL_CONTENT_SELECTION_MULTIPLE		= 1 << 1,
+	E_MEMO_SHELL_CONTENT_SELECTION_CAN_EDIT		= 1 << 2,
+	E_MEMO_SHELL_CONTENT_SELECTION_HAS_URL		= 1 << 3
+};
+
 struct _EMemoShellContent {
 	EShellContent parent;
 	EMemoShellContentPrivate *priv;

Modified: branches/kill-bonobo/calendar/modules/e-memo-shell-sidebar.c
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-memo-shell-sidebar.c	(original)
+++ branches/kill-bonobo/calendar/modules/e-memo-shell-sidebar.c	Fri Oct 24 23:02:33 2008
@@ -441,6 +441,34 @@
 		object);
 }
 
+static guint32
+memo_shell_sidebar_check_state (EShellSidebar *shell_sidebar)
+{
+	EMemoShellSidebar *memo_shell_sidebar;
+	ESourceSelector *selector;
+	ESource *source;
+	gboolean is_system = FALSE;
+	guint32 state = 0;
+
+	memo_shell_sidebar = E_MEMO_SHELL_SIDEBAR (shell_sidebar);
+	selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
+	source = e_source_selector_peek_primary_selection (selector);
+
+	if (source != NULL) {
+		const gchar *uri;
+
+		uri = e_source_peek_relative_uri (source);
+		is_system = (uri == NULL || strcmp (uri, "system") == 0);
+	}
+
+	if (source != NULL)
+		state = E_MEMO_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE;
+	if (is_system)
+		state = E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM;
+
+	return state;
+}
+
 static void
 memo_shell_sidebar_client_added (EMemoShellSidebar *memo_shell_sidebar,
                                  ECal *client)
@@ -477,6 +505,7 @@
 memo_shell_sidebar_class_init (EMemoShellSidebarClass *class)
 {
 	GObjectClass *object_class;
+	EShellSidebarClass *shell_sidebar_class;
 
 	parent_class = g_type_class_peek_parent (class);
 	g_type_class_add_private (class, sizeof (EMemoShellSidebarPrivate));
@@ -487,6 +516,9 @@
 	object_class->finalize = memo_shell_sidebar_finalize;
 	object_class->constructed = memo_shell_sidebar_constructed;
 
+	shell_sidebar_class = E_SHELL_SIDEBAR_CLASS (class);
+	shell_sidebar_class->check_state = memo_shell_sidebar_check_state;
+
 	class->client_added = memo_shell_sidebar_client_added;
 	class->client_removed = memo_shell_sidebar_client_removed;
 

Modified: branches/kill-bonobo/calendar/modules/e-memo-shell-sidebar.h
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-memo-shell-sidebar.h	(original)
+++ branches/kill-bonobo/calendar/modules/e-memo-shell-sidebar.h	Fri Oct 24 23:02:33 2008
@@ -53,6 +53,11 @@
 typedef struct _EMemoShellSidebarClass EMemoShellSidebarClass;
 typedef struct _EMemoShellSidebarPrivate EMemoShellSidebarPrivate;
 
+enum {
+	E_MEMO_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE		= 1 << 0,
+	E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM	= 1 << 1
+};
+
 struct _EMemoShellSidebar {
 	EShellSidebar parent;
 	EMemoShellSidebarPrivate *priv;

Modified: branches/kill-bonobo/calendar/modules/e-memo-shell-view.c
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-memo-shell-view.c	(original)
+++ branches/kill-bonobo/calendar/modules/e-memo-shell-view.c	Fri Oct 24 23:02:33 2008
@@ -77,104 +77,101 @@
 memo_shell_view_update_actions (EShellView *shell_view)
 {
 	EMemoShellViewPrivate *priv;
-	EMemoShellContent *memo_shell_content;
-	EMemoShellSidebar *memo_shell_sidebar;
+	EShellContent *shell_content;
+	EShellSidebar *shell_sidebar;
 	EShellWindow *shell_window;
-	ESourceSelector *selector;
-	EMemoTable *memo_table;
-	ETable *table;
-	ESource *source;
 	GtkAction *action;
-	GSList *list, *iter;
 	const gchar *label;
-	const gchar *uri = NULL;
-	gboolean user_created_source;
-	gboolean editable = TRUE;
-	gboolean has_url = FALSE;
 	gboolean sensitive;
-	gint n_selected;
+	guint32 state;
+
+	/* Be descriptive. */
+	gboolean any_memos_selected;
+	gboolean has_primary_source;
+	gboolean multiple_memos_selected;
+	gboolean primary_source_is_system;
+	gboolean selection_has_url;
+	gboolean single_memo_selected;
+	gboolean sources_are_editable;
 
 	priv = E_MEMO_SHELL_VIEW_GET_PRIVATE (shell_view);
 
 	shell_window = e_shell_view_get_shell_window (shell_view);
 
-	memo_shell_content = priv->memo_shell_content;
-	memo_table = e_memo_shell_content_get_memo_table (memo_shell_content);
-
-	memo_shell_sidebar = priv->memo_shell_sidebar;
-	selector = e_memo_shell_sidebar_get_selector (memo_shell_sidebar);
+	shell_content = e_shell_view_get_shell_content (shell_view);
+	state = e_shell_content_check_state (shell_content);
 
-	table = e_memo_table_get_table (memo_table);
-	n_selected = e_table_selected_count (table);
-
-	list = e_memo_table_get_selected (memo_table);
-	for (iter = list; iter != NULL; iter = iter->next) {
-		ECalModelComponent *comp_data = iter->data;
-		icalproperty *prop;
-		gboolean read_only;
-
-		e_cal_is_read_only (comp_data->client, &read_only, NULL);
-		editable &= !read_only;
-
-		prop = icalcomponent_get_first_property (
-			comp_data->icalcomp, ICAL_URL_PROPERTY);
-		has_url |= (prop != NULL);
-	}
-	g_slist_free (list);
+	single_memo_selected =
+		(state & E_MEMO_SHELL_CONTENT_SELECTION_SINGLE);
+	multiple_memos_selected =
+		(state & E_MEMO_SHELL_CONTENT_SELECTION_MULTIPLE);
+	sources_are_editable =
+		(state & E_MEMO_SHELL_CONTENT_SELECTION_CAN_EDIT);
+	selection_has_url =
+		(state & E_MEMO_SHELL_CONTENT_SELECTION_HAS_URL);
+
+	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+	state = e_shell_sidebar_check_state (shell_sidebar);
+
+	has_primary_source =
+		(state & E_MEMO_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE);
+	primary_source_is_system =
+		(state & E_MEMO_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM);
 
-	source = e_source_selector_peek_primary_selection (selector);
-	if (source != NULL)
-		uri = e_source_peek_relative_uri (source);
-	user_created_source = (uri != NULL && strcmp (uri, "system") != 0);
+	any_memos_selected =
+		(single_memo_selected || multiple_memos_selected);
 
 	action = ACTION (MEMO_CLIPBOARD_COPY);
-	sensitive = (n_selected > 0);
+	sensitive = any_memos_selected;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (MEMO_CLIPBOARD_CUT);
-	sensitive = (n_selected > 0) && editable;
+	sensitive = any_memos_selected && sources_are_editable;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (MEMO_CLIPBOARD_PASTE);
-	sensitive = editable;
+	sensitive = sources_are_editable;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (MEMO_DELETE);
-	sensitive = (n_selected > 0) && editable;
+	sensitive = any_memos_selected && sources_are_editable;
 	gtk_action_set_sensitive (action, sensitive);
-	label = ngettext ("Delete Memo", "Delete Memos", n_selected);
+	if (multiple_memos_selected)
+		label = _("Delete Memos");
+	else
+		label = _("Delete Memo");
 	g_object_set (action, "label", label, NULL);
 
 	action = ACTION (MEMO_FORWARD);
-	sensitive = (n_selected == 1);
+	sensitive = single_memo_selected;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (MEMO_LIST_COPY);
-	sensitive = (source != NULL);
+	sensitive = has_primary_source;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (MEMO_LIST_DELETE);
-	sensitive = user_created_source;
+	sensitive = has_primary_source && !primary_source_is_system;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (MEMO_LIST_PROPERTIES);
-	sensitive = (source != NULL);
+	sensitive = has_primary_source;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (MEMO_OPEN);
-	sensitive = (n_selected == 1);
+	sensitive = single_memo_selected;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (MEMO_OPEN_URL);
-	sensitive = (n_selected == 1) && has_url;
+	sensitive = single_memo_selected && selection_has_url;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (MEMO_PRINT);
-	sensitive = (n_selected == 1);
+	sensitive = single_memo_selected;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (MEMO_SAVE_AS);
-	sensitive = (n_selected == 1);
+	sensitive = single_memo_selected;
 	gtk_action_set_sensitive (action, sensitive);
 }
 

Modified: branches/kill-bonobo/calendar/modules/e-task-shell-content.c
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-task-shell-content.c	(original)
+++ branches/kill-bonobo/calendar/modules/e-task-shell-content.c	Fri Oct 24 23:02:33 2008
@@ -417,10 +417,81 @@
 	gconf_bridge_bind_property_delayed (bridge, key, object, "position");
 }
 
+static guint32
+task_shell_content_check_state (EShellContent *shell_content)
+{
+	ETaskShellContent *task_shell_content;
+	ECalendarTable *task_table;
+	ETable *table;
+	GSList *list, *iter;
+	gboolean assignable = TRUE;
+	gboolean editable = TRUE;
+	gboolean has_url = FALSE;
+	gint n_selected;
+	gint n_complete = 0;
+	gint n_incomplete = 0;
+	guint32 state = 0;
+
+	task_shell_content = E_TASK_SHELL_CONTENT (shell_content);
+	task_table = e_task_shell_content_get_task_table (task_shell_content);
+
+	table = e_calendar_table_get_table (task_table);
+	n_selected = e_table_selected_count (table);
+
+	list = e_calendar_table_get_selected (task_table);
+	for (iter = list; iter != NULL; iter = iter->next) {
+		ECalModelComponent *comp_data = iter->data;
+		icalproperty *prop;
+		const gchar *cap;
+		gboolean read_only;
+
+		e_cal_is_read_only (comp_data->client, &read_only, NULL);
+		editable &= !read_only;
+
+		cap = CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT;
+		if (e_cal_get_static_capability (comp_data->client, cap))
+			assignable = FALSE;
+
+		cap = CAL_STATIC_CAPABILITY_NO_CONV_TO_ASSIGN_TASK;
+		if (e_cal_get_static_capability (comp_data->client, cap))
+			assignable = FALSE;
+
+		prop = icalcomponent_get_first_property (
+			comp_data->icalcomp, ICAL_URL_PROPERTY);
+		has_url |= (prop != NULL);
+
+		prop = icalcomponent_get_first_property (
+			comp_data->icalcomp, ICAL_COMPLETED_PROPERTY);
+		if (prop != NULL)
+			n_complete++;
+		else
+			n_incomplete++;
+	}
+	g_slist_free (list);
+
+	if (n_selected == 1)
+		state |= E_TASK_SHELL_CONTENT_SELECTION_SINGLE;
+	if (n_selected > 1)
+		state |= E_TASK_SHELL_CONTENT_SELECTION_MULTIPLE;
+	if (assignable)
+		state |= E_TASK_SHELL_CONTENT_SELECTION_CAN_ASSIGN;
+	if (editable)
+		state |= E_TASK_SHELL_CONTENT_SELECTION_CAN_EDIT;
+	if (n_complete > 0)
+		state |= E_TASK_SHELL_CONTENT_SELECTION_HAS_COMPLETE;
+	if (n_incomplete > 0)
+		state |= E_TASK_SHELL_CONTENT_SELECTION_HAS_INCOMPLETE;
+	if (has_url)
+		state |= E_TASK_SHELL_CONTENT_SELECTION_HAS_URL;
+
+	return state;
+}
+
 static void
 task_shell_content_class_init (ETaskShellContentClass *class)
 {
 	GObjectClass *object_class;
+	EShellContentClass *shell_content_class;
 
 	parent_class = g_type_class_peek_parent (class);
 	g_type_class_add_private (class, sizeof (ETaskShellContentPrivate));
@@ -432,6 +503,9 @@
 	object_class->finalize = task_shell_content_finalize;
 	object_class->constructed = task_shell_content_constructed;
 
+	shell_content_class = E_SHELL_CONTENT_CLASS (class);
+	shell_content_class->check_state = task_shell_content_check_state;
+
 	g_object_class_install_property (
 		object_class,
 		PROP_PREVIEW_VISIBLE,

Modified: branches/kill-bonobo/calendar/modules/e-task-shell-content.h
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-task-shell-content.h	(original)
+++ branches/kill-bonobo/calendar/modules/e-task-shell-content.h	Fri Oct 24 23:02:33 2008
@@ -55,6 +55,16 @@
 typedef struct _ETaskShellContentClass ETaskShellContentClass;
 typedef struct _ETaskShellContentPrivate ETaskShellContentPrivate;
 
+enum {
+	E_TASK_SHELL_CONTENT_SELECTION_SINGLE		= 1 << 0,
+	E_TASK_SHELL_CONTENT_SELECTION_MULTIPLE		= 1 << 1,
+	E_TASK_SHELL_CONTENT_SELECTION_CAN_ASSIGN	= 1 << 2,
+	E_TASK_SHELL_CONTENT_SELECTION_CAN_EDIT		= 1 << 3,
+	E_TASK_SHELL_CONTENT_SELECTION_HAS_COMPLETE	= 1 << 4,
+	E_TASK_SHELL_CONTENT_SELECTION_HAS_INCOMPLETE	= 1 << 5,
+	E_TASK_SHELL_CONTENT_SELECTION_HAS_URL		= 1 << 6 
+};
+
 struct _ETaskShellContent {
 	EShellContent parent;
 	ETaskShellContentPrivate *priv;

Modified: branches/kill-bonobo/calendar/modules/e-task-shell-sidebar.c
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-task-shell-sidebar.c	(original)
+++ branches/kill-bonobo/calendar/modules/e-task-shell-sidebar.c	Fri Oct 24 23:02:33 2008
@@ -441,6 +441,34 @@
 		object);
 }
 
+static guint32
+task_shell_sidebar_check_state (EShellSidebar *shell_sidebar)
+{
+	ETaskShellSidebar *task_shell_sidebar;
+	ESourceSelector *selector;
+	ESource *source;
+	gboolean is_system = FALSE; 
+	guint32 state = 0;
+
+	task_shell_sidebar = E_TASK_SHELL_SIDEBAR (shell_sidebar);
+	selector = e_task_shell_sidebar_get_selector (task_shell_sidebar);
+	source = e_source_selector_peek_primary_selection (selector);
+
+	if (source != NULL) {
+		const gchar *uri;
+
+		uri = e_source_peek_relative_uri (source);
+		is_system = (uri == NULL || strcmp (uri, "system") == 0);
+	}
+
+	if (source != NULL)
+		state |= E_TASK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE;
+	if (is_system)
+		state |= E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM;
+
+	return state;
+}
+
 static void
 task_shell_sidebar_client_added (ETaskShellSidebar *task_shell_sidebar,
                                  ECal *client)
@@ -477,6 +505,7 @@
 task_shell_sidebar_class_init (ETaskShellSidebarClass *class)
 {
 	GObjectClass *object_class;
+	EShellSidebarClass *shell_sidebar_class;
 
 	parent_class = g_type_class_peek_parent (class);
 	g_type_class_add_private (class, sizeof (ETaskShellSidebarPrivate));
@@ -487,6 +516,9 @@
 	object_class->finalize = task_shell_sidebar_finalize;
 	object_class->constructed = task_shell_sidebar_constructed;
 
+	shell_sidebar_class = E_SHELL_SIDEBAR_CLASS (class);
+	shell_sidebar_class->check_state = task_shell_sidebar_check_state;
+
 	class->client_added = task_shell_sidebar_client_added;
 	class->client_removed = task_shell_sidebar_client_removed;
 

Modified: branches/kill-bonobo/calendar/modules/e-task-shell-sidebar.h
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-task-shell-sidebar.h	(original)
+++ branches/kill-bonobo/calendar/modules/e-task-shell-sidebar.h	Fri Oct 24 23:02:33 2008
@@ -53,6 +53,11 @@
 typedef struct _ETaskShellSidebarClass ETaskShellSidebarClass;
 typedef struct _ETaskShellSidebarPrivate ETaskShellSidebarPrivate;
 
+enum {
+	E_TASK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE		= 1 << 0,
+	E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM	= 1 << 1
+};
+
 struct _ETaskShellSidebar {
 	EShellSidebar parent;
 	ETaskShellSidebarPrivate *priv;

Modified: branches/kill-bonobo/calendar/modules/e-task-shell-view.c
==============================================================================
--- branches/kill-bonobo/calendar/modules/e-task-shell-view.c	(original)
+++ branches/kill-bonobo/calendar/modules/e-task-shell-view.c	Fri Oct 24 23:02:33 2008
@@ -77,139 +77,134 @@
 task_shell_view_update_actions (EShellView *shell_view)
 {
 	ETaskShellViewPrivate *priv;
-	ETaskShellContent *task_shell_content;
-	ETaskShellSidebar *task_shell_sidebar;
+	EShellContent *shell_content;
+	EShellSidebar *shell_sidebar;
 	EShellWindow *shell_window;
-	ESourceSelector *selector;
-	ETable *table;
-	ECalendarTable *task_table;
-	ESource *source;
 	GtkAction *action;
-	GSList *list, *iter;
 	const gchar *label;
-	const gchar *uri = NULL;
-	gboolean user_created_source;
-	gboolean assignable = TRUE;
-	gboolean editable = TRUE;
-	gboolean has_url = FALSE;
 	gboolean sensitive;
-	gint n_selected;
-	gint n_complete = 0;
-	gint n_incomplete = 0;
+	guint32 state;
+
+	/* Be descriptive. */
+	gboolean any_tasks_selected;
+	gboolean has_primary_source;
+	gboolean multiple_tasks_selected;
+	gboolean primary_source_is_system;
+	gboolean selection_has_url;
+	gboolean selection_is_assignable;
+	gboolean single_task_selected;
+	gboolean some_tasks_complete;
+	gboolean some_tasks_incomplete;
+	gboolean sources_are_editable;
 
 	priv = E_TASK_SHELL_VIEW_GET_PRIVATE (shell_view);
 
 	shell_window = e_shell_view_get_shell_window (shell_view);
 
-	task_shell_content = priv->task_shell_content;
-	task_table = e_task_shell_content_get_task_table (task_shell_content);
-
-	task_shell_sidebar = priv->task_shell_sidebar;
-	selector = e_task_shell_sidebar_get_selector (task_shell_sidebar);
+	shell_content = e_shell_view_get_shell_content (shell_view);
+	state = e_shell_content_check_state (shell_content);
 
-	table = e_calendar_table_get_table (task_table);
-	n_selected = e_table_selected_count (table);
-
-	list = e_calendar_table_get_selected (task_table);
-	for (iter = list; iter != NULL; iter = iter->next) {
-		ECalModelComponent *comp_data = iter->data;
-		icalproperty *prop;
-		const gchar *cap;
-		gboolean read_only;
-
-		e_cal_is_read_only (comp_data->client, &read_only, NULL);
-		editable &= !read_only;
-
-		cap = CAL_STATIC_CAPABILITY_NO_TASK_ASSIGNMENT;
-		if (e_cal_get_static_capability (comp_data->client, cap))
-			assignable = FALSE;
-
-		cap = CAL_STATIC_CAPABILITY_NO_CONV_TO_ASSIGN_TASK;
-		if (e_cal_get_static_capability (comp_data->client, cap))
-			assignable = FALSE;
-
-		prop = icalcomponent_get_first_property (
-			comp_data->icalcomp, ICAL_URL_PROPERTY);
-		has_url |= (prop != NULL);
-
-		prop = icalcomponent_get_first_property (
-			comp_data->icalcomp, ICAL_COMPLETED_PROPERTY);
-		if (prop != NULL)
-			n_complete++;
-		else
-			n_incomplete++;
-	}
-	g_slist_free (list);
+	single_task_selected =
+		(state & E_TASK_SHELL_CONTENT_SELECTION_SINGLE);
+	multiple_tasks_selected =
+		(state & E_TASK_SHELL_CONTENT_SELECTION_MULTIPLE);
+	selection_is_assignable =
+		(state & E_TASK_SHELL_CONTENT_SELECTION_CAN_ASSIGN);
+	sources_are_editable =
+		(state & E_TASK_SHELL_CONTENT_SELECTION_CAN_EDIT);
+	some_tasks_complete =
+		(state & E_TASK_SHELL_CONTENT_SELECTION_HAS_COMPLETE);
+	some_tasks_incomplete =
+		(state & E_TASK_SHELL_CONTENT_SELECTION_HAS_INCOMPLETE);
+	selection_has_url =
+		(state & E_TASK_SHELL_CONTENT_SELECTION_HAS_URL);
+
+	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
+	state = e_shell_sidebar_check_state (shell_sidebar);
+
+	has_primary_source =
+		(state & E_TASK_SHELL_SIDEBAR_HAS_PRIMARY_SOURCE);
+	primary_source_is_system =
+		(state & E_TASK_SHELL_SIDEBAR_PRIMARY_SOURCE_IS_SYSTEM);
 
-	source = e_source_selector_peek_primary_selection (selector);
-	if (source != NULL)
-		uri = e_source_peek_relative_uri (source);
-	user_created_source = (uri != NULL && strcmp (uri, "system") != 0);
+	any_tasks_selected =
+		(single_task_selected || multiple_tasks_selected);
 
 	action = ACTION (TASK_ASSIGN);
-	sensitive = (n_selected == 1) && editable && assignable;
+	sensitive =
+		single_task_selected && sources_are_editable &&
+		selection_is_assignable;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (TASK_CLIPBOARD_COPY);
-	sensitive = (n_selected > 0);
+	sensitive = any_tasks_selected;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (TASK_CLIPBOARD_CUT);
-	sensitive = (n_selected > 0) && editable;
+	sensitive = any_tasks_selected && sources_are_editable;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (TASK_CLIPBOARD_PASTE);
-	sensitive = editable;
+	sensitive = sources_are_editable;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (TASK_DELETE);
-	sensitive = (n_selected > 0) && editable;
+	sensitive = any_tasks_selected && sources_are_editable;
 	gtk_action_set_sensitive (action, sensitive);
-	label = ngettext ("Delete Task", "Delete Tasks", n_selected);
+	if (multiple_tasks_selected)
+		label = _("Delete Tasks");
+	else
+		label = _("Delete Task");
 	g_object_set (action, "label", label, NULL);
 
 	action = ACTION (TASK_FORWARD);
-	sensitive = (n_selected == 1);
+	sensitive = single_task_selected;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (TASK_LIST_COPY);
-	sensitive = (source != NULL);
+	sensitive = has_primary_source;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (TASK_LIST_DELETE);
-	sensitive = user_created_source;
+	sensitive = has_primary_source && !primary_source_is_system;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (TASK_LIST_PROPERTIES);
-	sensitive = (source != NULL);
+	sensitive = has_primary_source;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (TASK_MARK_COMPLETE);
-	sensitive = (n_selected > 0) && editable && (n_incomplete > 0);
+	sensitive =
+		any_tasks_selected &&
+		sources_are_editable &&
+		some_tasks_incomplete;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (TASK_MARK_INCOMPLETE);
-	sensitive = (n_selected > 0) && editable && (n_complete > 0);
+	sensitive =
+		any_tasks_selected &&
+		sources_are_editable &&
+		some_tasks_complete;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (TASK_OPEN);
-	sensitive = (n_selected == 1);
+	sensitive = single_task_selected;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (TASK_OPEN_URL);
-	sensitive = (n_selected == 1) && has_url;
+	sensitive = single_task_selected && selection_has_url;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (TASK_PRINT);
-	sensitive = (n_selected == 1);
+	sensitive = single_task_selected;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (TASK_PURGE);
-	sensitive = editable;
+	sensitive = sources_are_editable;
 	gtk_action_set_sensitive (action, sensitive);
 
 	action = ACTION (TASK_SAVE_AS);
-	sensitive = (n_selected == 1);
+	sensitive = single_task_selected;
 	gtk_action_set_sensitive (action, sensitive);
 }
 

Modified: branches/kill-bonobo/mail/e-mail-shell-content.c
==============================================================================
--- branches/kill-bonobo/mail/e-mail-shell-content.c	(original)
+++ branches/kill-bonobo/mail/e-mail-shell-content.c	Fri Oct 24 23:02:33 2008
@@ -184,6 +184,17 @@
 	gconf_bridge_bind_property_delayed (bridge, key, object, "position");
 }
 
+static guint32
+mail_shell_content_check_state (EShellContent *shell_content)
+{
+	EMailShellContent *mail_shell_content;
+	guint32 state = 0;
+
+	mail_shell_content = E_MAIL_SHELL_CONTENT (shell_content);
+
+	return state;
+}
+
 static void
 mail_shell_content_class_init (EMailShellContentClass *class)
 {
@@ -202,6 +213,7 @@
 
 	shell_content_class = E_SHELL_CONTENT_CLASS (class);
 	shell_content_class->new_search_context = em_search_context_new;
+	shell_content_class->check_state = mail_shell_content_check_state;
 
 	g_object_class_install_property (
 		object_class,

Modified: branches/kill-bonobo/mail/e-mail-shell-content.h
==============================================================================
--- branches/kill-bonobo/mail/e-mail-shell-content.h	(original)
+++ branches/kill-bonobo/mail/e-mail-shell-content.h	Fri Oct 24 23:02:33 2008
@@ -50,6 +50,28 @@
 typedef struct _EMailShellContentClass EMailShellContentClass;
 typedef struct _EMailShellContentPrivate EMailShellContentPrivate;
 
+enum {
+	E_MAIL_SHELL_CONTENT_SELECTION_SINGLE		= 1 << 0,
+	E_MAIL_SHELL_CONTENT_SELECTION_MULTIPLE		= 1 << 1,
+	E_MAIL_SHELL_CONTENT_SELECTION_CAN_ADD_SENDER	= 1 << 2,
+	E_MAIL_SHELL_CONTENT_SELECTION_CAN_DELETE	= 1 << 3,
+	E_MAIL_SHELL_CONTENT_SELECTION_CAN_EDIT		= 1 << 4,
+	E_MAIL_SHELL_CONTENT_SELECTION_CAN_UNDELETE	= 1 << 5,
+	E_MAIL_SHELL_CONTENT_SELECTION_FLAG_CLEAR	= 1 << 6,
+	E_MAIL_SHELL_CONTENT_SELECTION_FLAG_COMPLETED	= 1 << 7,
+	E_MAIL_SHELL_CONTENT_SELECTION_FLAG_FOLLOWUP	= 1 << 8,
+	E_MAIL_SHELL_CONTENT_SELECTION_HAS_IMPORTANT	= 1 << 9,
+	E_MAIL_SHELL_CONTENT_SELECTION_HAS_JUNK		= 1 << 10,
+	E_MAIL_SHELL_CONTENT_SELECTION_HAS_NOT_JUNK	= 1 << 11,
+	E_MAIL_SHELL_CONTENT_SELECTION_HAS_READ		= 1 << 12,
+	E_MAIL_SHELL_CONTENT_SELECTION_HAS_UNIMPORTANT	= 1 << 13,
+	E_MAIL_SHELL_CONTENT_SELECTION_HAS_UNREAD	= 1 << 14,
+	E_MAIL_SHELL_CONTENT_SELECTION_HAS_URI_CALLTO	= 1 << 15,
+	E_MAIL_SHELL_CONTENT_SELECTION_HAS_URI_HTTP	= 1 << 16,
+	E_MAIL_SHELL_CONTENT_SELECTION_HAS_URI_MAILTO	= 1 << 17,
+	E_MAIL_SHELL_CONTENT_SELECTION_IS_MAILING_LIST	= 1 << 18
+};
+
 struct _EMailShellContent {
 	EShellContent parent;
 	EMailShellContentPrivate *priv;

Modified: branches/kill-bonobo/mail/e-mail-shell-sidebar.c
==============================================================================
--- branches/kill-bonobo/mail/e-mail-shell-sidebar.c	(original)
+++ branches/kill-bonobo/mail/e-mail-shell-sidebar.c	Fri Oct 24 23:02:33 2008
@@ -21,8 +21,6 @@
 
 #include "e-mail-shell-sidebar.h"
 
-#include "mail/em-folder-tree.h"
-
 #define E_MAIL_SHELL_SIDEBAR_GET_PRIVATE(obj) \
 	(G_TYPE_INSTANCE_GET_PRIVATE \
 	((obj), E_TYPE_MAIL_SHELL_SIDEBAR, EMailShellSidebarPrivate))
@@ -32,7 +30,8 @@
 };
 
 enum {
-	PROP_0
+	PROP_0,
+	PROP_FOLDER_TREE
 };
 
 static gpointer parent_class;
@@ -43,6 +42,14 @@
                                  GValue *value,
                                  GParamSpec *pspec)
 {
+	switch (property_id) {
+		case PROP_FOLDER_TREE:
+			g_value_set_object (
+				value, e_mail_shell_sidebar_get_folder_tree (
+				E_MAIL_SHELL_SIDEBAR (object)));
+			return;
+	}
+
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 }
 
@@ -115,10 +122,75 @@
 	gtk_widget_show (widget);
 }
 
+static guint32
+mail_shell_sidebar_check_state (EShellSidebar *shell_sidebar)
+{
+	EMailShellSidebar *mail_shell_sidebar;
+	EShellModule *shell_module;
+	EShellView *shell_view;
+	EMFolderTree *folder_tree;
+	GtkTreeSelection *selection;
+	GtkTreeView *tree_view;
+	GtkTreeModel *model;
+	GtkTreeIter iter;
+	CamelFolder *folder;
+	CamelStore *local_store;
+	CamelStore *store;
+	gchar *full_name;
+	gchar *uri;
+	gboolean is_virtual = FALSE;
+	gboolean can_delete = TRUE;
+	gboolean is_outbox = FALSE;
+	gboolean is_store;
+	guint32 folder_flags = 0;
+	guint32 state = 0;
+
+	shell_view = e_shell_sidebar_get_shell_view (shell_sidebar);
+	shell_module = e_shell_view_get_shell_module (shell_view);
+	local_store = e_mail_shell_module_get_local_store (shell_module);
+
+	mail_shell_sidebar = E_MAIL_SHELL_SIDEBAR (shell_sidebar);
+	folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+	tree_view = GTK_TREE_VIEW (folder_tree);
+
+	selection = gtk_tree_view_get_selection (tree_view);
+	if (!emft_selection_get_selected (selection, &model, &iter))
+		return 0;
+
+	gtk_tree_model_get (
+		model, &iter,
+		COL_POINTER_CAMEL_STORE, &store,
+		COL_STRING_FULL_NAME, &full_name,
+		COL_BOOL_IS_STORE, &is_store,
+		COL_UINT_FLAGS, &folder_flags,
+		COL_STRING_URI, &uri, NULL);
+
+	if (!is_store) {
+		if (strcmp (full_name, CAMEL_VJUNK_NAME) == 0)
+			is_virtual = TRUE;
+
+		if (strcmp (full_name, CAMEL_VTRASH_NAME) == 0)
+			is_virtual = TRUE;
+
+		folder = em_folder_tree_get_selected_folder (folder_tree);
+		is_outbox = em_utils_folder_is_outbox (folder, NULL);
+	}
+
+	if (is_virtual)
+		state |= E_BOOK_SHELL_SIDEBAR_ALLOWS_CHILDREN;
+	if (is_outbox)
+		state |= E_BOOK_SHELL_SIDEBAR_FOLDER_IS_OUTBOX;
+	if (is_store)
+		state |= E_BOOK_SHELL_SIDEBAR_FOLDER_IS_STORE;
+
+	return state;
+}
+
 static void
 mail_shell_sidebar_class_init (EMailShellSidebarClass *class)
 {
 	GObjectClass *object_class;
+	EShellSidebarClass *shell_sidebar_class;
 
 	parent_class = g_type_class_peek_parent (class);
 	g_type_class_add_private (class, sizeof (EMailShellSidebarPrivate));
@@ -128,6 +200,19 @@
 	object_class->dispose = mail_shell_sidebar_dispose;
 	object_class->finalize = mail_shell_sidebar_finalize;
 	object_class->constructed = mail_shell_sidebar_constructed;
+
+	shell_sidebar_class = E_SHELL_SIDEBAR_CLASS (class);
+	shell_sidebar_class->check_state = mail_shell_sidebar_check_state;
+
+	g_object_class_install_property (
+		object_class,
+		PROP_FOLDER_TREE,
+		g_param_spec_object (
+			"folder-tree",
+			NULL,
+			NULL,
+			EM_TYPE_FOLDER_TREE,
+			G_PARAM_READABLE));
 }
 
 static void
@@ -175,3 +260,12 @@
 		E_TYPE_MAIL_SHELL_SIDEBAR,
 		"shell-view", shell_view, NULL);
 }
+
+EMFolderTree *
+e_mail_shell_sidebar_get_folder_tree (EMailShellSidebar *mail_shell_sidebar)
+{
+	g_return_val_if_fail (
+		E_IS_MAIL_SHELL_SIDEBAR (mail_shell_sidebar), NULL);
+
+	return mail_shell_sidebar->priv->folder_tree;
+}

Modified: branches/kill-bonobo/mail/e-mail-shell-sidebar.h
==============================================================================
--- branches/kill-bonobo/mail/e-mail-shell-sidebar.h	(original)
+++ branches/kill-bonobo/mail/e-mail-shell-sidebar.h	Fri Oct 24 23:02:33 2008
@@ -24,6 +24,7 @@
 
 #include <shell/e-shell-sidebar.h>
 #include <shell/e-shell-view.h>
+#include <mail/em-folder-tree.h>
 
 /* Standard GObject macros */
 #define E_TYPE_MAIL_SHELL_SIDEBAR \
@@ -50,6 +51,13 @@
 typedef struct _EMailShellSidebarClass EMailShellSidebarClass;
 typedef struct _EMailShellSidebarPrivate EMailShellSidebarPrivate;
 
+enum {
+	E_BOOK_SHELL_SIDEBAR_FOLDER_ALLOWS_CHILDREN	= 1 << 0,
+	E_BOOK_SHELL_SIDEBAR_FOLDER_CAN_DELETE		= 1 << 1,
+	E_BOOK_SHELL_SIDEBAR_FOLDER_IS_OUTBOX		= 1 << 2,
+	E_BOOK_SHELL_SIDEBAR_FOLDER_IS_STORE		= 1 << 3
+};
+
 struct _EMailShellSidebar {
 	EShellSidebar parent;
 	EMailShellSidebarPrivate *priv;
@@ -61,6 +69,8 @@
 
 GType		e_mail_shell_sidebar_get_type	(void);
 GtkWidget *	e_mail_shell_sidebar_new	(EShellView *shell_view);
+EMFolderTree *	e_mail_shell_sidebar_get_folder_tree
+						(EMailShellSidebar *mail_shell_sidebar);
 
 G_END_DECLS
 

Modified: branches/kill-bonobo/mail/e-mail-shell-view-actions.c
==============================================================================
--- branches/kill-bonobo/mail/e-mail-shell-view-actions.c	(original)
+++ branches/kill-bonobo/mail/e-mail-shell-view-actions.c	Fri Oct 24 23:02:33 2008
@@ -166,6 +166,14 @@
 }
 
 static void
+action_mail_flush_outbox_cb (GtkAction *action,
+                             EMailShellView *mail_shell_view)
+{
+	/* FIXME */
+	g_print ("Action: %s\n", gtk_action_get_name (GTK_ACTION (action)));
+}
+
+static void
 action_mail_folder_copy_cb (GtkAction *action,
                             EMailShellView *mail_shell_view)
 {
@@ -891,6 +899,13 @@
 	  N_("Flag the selected messages for follow-up"),
 	  G_CALLBACK (action_mail_flag_for_followup_cb) },
 
+	{ "mail-flush-outbox",
+	  "mail-send",
+	  N_("Fl_ush Outbox"),
+	  NULL,
+	  NULL,  /* XXX Add a tooltip! */
+	  G_CALLBACK (action_mail_flush_outbox_cb) },
+
 	{ "mail-folder-copy",
 	  "folder-copy",
 	  N_("_Copy Folder To..."),

Modified: branches/kill-bonobo/mail/e-mail-shell-view-private.c
==============================================================================
--- branches/kill-bonobo/mail/e-mail-shell-view-private.c	(original)
+++ branches/kill-bonobo/mail/e-mail-shell-view-private.c	Fri Oct 24 23:02:33 2008
@@ -24,6 +24,16 @@
 #include <widgets/menus/gal-view-factory-etable.h>
 
 static void
+mail_shell_view_folder_tree_popup_event_cb (EShellView *shell_view,
+                                            GdkEventButton *event)
+{
+	const gchar *widget_path;
+
+	widget_path = "/mail-folder-popup";
+	e_shell_view_show_popup_menu (shell_view, widget_path, event);
+}
+
+static void
 mail_shell_view_load_view_collection (EShellViewClass *shell_view_class)
 {
 	GalViewCollection *collection;
@@ -93,9 +103,11 @@
 e_mail_shell_view_private_constructed (EMailShellView *mail_shell_view)
 {
 	EMailShellViewPrivate *priv = mail_shell_view->priv;
+	EMailShellSidebar *mail_shell_sidebar;
 	EShellView *shell_view;
 	EShellContent *shell_content;
 	EShellSidebar *shell_sidebar;
+	EMFolderTree *folder_tree;
 
 	shell_view = E_SHELL_VIEW (mail_shell_view);
 	shell_content = e_shell_view_get_shell_content (shell_view);
@@ -105,6 +117,14 @@
 	priv->mail_shell_content = g_object_ref (shell_content);
 	priv->mail_shell_sidebar = g_object_ref (shell_content);
 
+	mail_shell_sidebar = E_MAIL_SHELL_SIDEBAR (shell_sidebar);
+	folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+
+	g_signal_connect_swapped (
+		folder_tree, "popup-event",
+		G_CALLBACK (mail_shell_view_folder_tree_popup_event_cb),
+		mail_shell_view);
+
 	e_mail_shell_view_actions_init (mail_shell_view);
 }
 

Modified: branches/kill-bonobo/mail/e-mail-shell-view.c
==============================================================================
--- branches/kill-bonobo/mail/e-mail-shell-view.c	(original)
+++ branches/kill-bonobo/mail/e-mail-shell-view.c	Fri Oct 24 23:02:33 2008
@@ -67,7 +67,64 @@
 static void
 mail_shell_view_update_actions (EShellView *shell_view)
 {
-	/* FIXME */
+	EMailShellViewPrivate *priv;
+	EMailShellSidebar *mail_shell_sidebar;
+	EShellWindow *shell_window;
+	EMFolderTree *folder_tree;
+	GtkAction *action;
+	CamelURL *camel_url;
+	gchar *uri;
+	gboolean sensitive;
+	gboolean visible;
+
+	priv = E_MAIL_SHELL_VIEW_GET_PRIVATE (shell_view);
+
+	shell_window = e_shell_view_get_shell_window (shell_view);
+
+	mail_shell_sidebar = priv->mail_shell_sidebar;
+	folder_tree = e_mail_shell_sidebar_get_folder_tree (mail_shell_sidebar);
+
+	uri = em_folder_tree_get_selected_uri (folder_tree);
+	camel_url = camel_url_new (uri, NULL);
+	g_free (uri);
+
+	action = ACTION (MAIL_EMPTY_TRASH);
+	visible = is_trash;
+	gtk_action_set_visible (action, visible);
+
+	action = ACTION (MAIL_FLUSH_OUTBOX);
+	visible = is_outbox;
+	gtk_action_set_visible (action, visible);
+
+	action = ACTION (MAIL_FOLDER_COPY);
+	sensitive = is_folder && is_selected;
+	gtk_action_set_sensitive (action, sensitive);
+
+	action = ACTION (MAIL_FOLDER_DELETE);
+	sensitive = is_folder && can_delete;
+	gtk_action_set_sensitive (action, sensitive);
+
+	action = ACTION (MAIL_FOLDER_MOVE);
+	sensitive = is_folder && can_delete;
+	gtk_action_set_sensitive (action, sensitive);
+
+	action = ACTION (MAIL_FOLDER_NEW);
+	sensitive = inferiors;
+	gtk_action_set_sensitive (action, sensitive);
+
+	action = ACTION (MAIL_FOLDER_PROPERTIES);
+	sensitive = is_folder && is_selected;
+	gtk_action_set_sensitive (action, sensitive);
+
+	action = ACTION (MAIL_FOLDER_REFRESH);
+	sensitive = is_folder && is_selected;
+	visible = nonstatic;
+	gtk_action_set_sensitive (action, sensitive);
+	gtk_action_set_visible (action, visible);
+
+	action = ACTION (MAIL_FOLDER_RENAME);
+	sensitive = is_folder && can_delete;
+	gtk_action_set_sensitive (action, sensitive);
 }
 
 static void

Modified: branches/kill-bonobo/mail/em-folder-selector.c
==============================================================================
--- branches/kill-bonobo/mail/em-folder-selector.c	(original)
+++ branches/kill-bonobo/mail/em-folder-selector.c	Fri Oct 24 23:02:33 2008
@@ -21,14 +21,8 @@
  *
  */
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
 #include <string.h>
-
 #include <glib/gi18n.h>
-
 #include <e-util/e-util.h>
 #include <misc/e-gui-utils.h>
 
@@ -42,87 +36,84 @@
 
 #define d(x)
 
-
 extern CamelSession *session;
+static gpointer parent_class;
 
+static void
+folder_selector_finalize (GObject *object)
+{
+	EMFolderSelector *emfs = EM_FOLDER_SELECTOR (object);
 
-static void em_folder_selector_class_init (EMFolderSelectorClass *klass);
-static void em_folder_selector_init (EMFolderSelector *emfs);
-static void em_folder_selector_destroy (GtkObject *obj);
-static void em_folder_selector_finalize (GObject *obj);
-
-
-static GtkDialogClass *parent_class = NULL;
+	g_free (emfs->selected_path);
+	g_free (emfs->selected_uri);
+	g_free (emfs->created_uri);
 
+	/* Chain up to parent's finalize() method. */
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
 
-GType
-em_folder_selector_get_type (void)
+static void
+folder_selector_destroy (GtkObject *object)
 {
-	static GType type = 0;
-
-	if (!type) {
-		static const GTypeInfo info = {
-			sizeof (EMFolderSelectorClass),
-			NULL, /* base_class_init */
-			NULL, /* base_class_finalize */
-			(GClassInitFunc) em_folder_selector_class_init,
-			NULL, /* class_finalize */
-			NULL, /* class_data */
-			sizeof (EMFolderSelector),
-			0,    /* n_preallocs */
-			(GInstanceInitFunc) em_folder_selector_init,
-		};
+	EMFolderSelector *emfs = EM_FOLDER_SELECTOR (object);
+	EMFolderTreeModel *model;
 
-		type = g_type_register_static (GTK_TYPE_DIALOG, "EMFolderSelector", &info, 0);
+	if (emfs->created_id != 0) {
+		model = em_folder_tree_get_model (emfs->emft);
+		g_signal_handler_disconnect (model, emfs->created_id);
+		emfs->created_id = 0;
 	}
 
-	return type;
+	/* Chain up to parent's destroy() method. */
+	GTK_OBJECT_CLASS (parent_class)->destroy (object);
 }
 
 static void
-em_folder_selector_class_init (EMFolderSelectorClass *klass)
+folder_selector_class_init (EMFolderSelectorClass *class)
 {
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
-	GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass);
+	GObjectClass *object_class;
+	GtkObjectClass *gtk_object_class;
 
-	parent_class = g_type_class_ref (GTK_TYPE_DIALOG);
+	parent_class = g_type_class_peek_parent (class);
 
-	object_class->finalize = em_folder_selector_finalize;
-	gtk_object_class->destroy = em_folder_selector_destroy;
+	object_class = G_OBJECT_CLASS (class);
+	object_class->finalize = folder_selector_finalize;
+
+	gtk_object_class = GTK_OBJECT_CLASS (class);
+	gtk_object_class->destroy = folder_selector_destroy;
 }
 
 static void
-em_folder_selector_init (EMFolderSelector *emfs)
+folder_selector_init (EMFolderSelector *emfs)
 {
 	emfs->selected_path = NULL;
 	emfs->selected_uri = NULL;
 }
 
-static void
-em_folder_selector_destroy (GtkObject *obj)
+GType
+em_folder_selector_get_type (void)
 {
-	EMFolderSelector *emfs = (EMFolderSelector *) obj;
-	EMFolderTreeModel *model;
-
-	if (emfs->created_id != 0) {
-		model = em_folder_tree_get_model (emfs->emft);
-		g_signal_handler_disconnect (model, emfs->created_id);
-		emfs->created_id = 0;
-	}
-
-	GTK_OBJECT_CLASS (parent_class)->destroy (obj);
-}
+	static GType type = 0;
 
-static void
-em_folder_selector_finalize (GObject *obj)
-{
-	EMFolderSelector *emfs = (EMFolderSelector *) obj;
+	if (G_UNLIKELY (type == 0)) {
+		static const GTypeInfo type_info = {
+			sizeof (EMFolderSelectorClass),
+			(GBaseInitFunc) NULL,
+			(GBaseFinalizeFunc) NULL,
+			(GClassInitFunc) folder_selector_class_init,
+			(GClassFinalizeFunc) NULL,
+			NULL,  /* class_data */
+			sizeof (EMFolderSelector),
+			0,     /* n_preallocs */
+			(GInstanceInitFunc) folder_selector_init,
+			NULL   /* value_table */
+		};
 
-	g_free (emfs->selected_path);
-	g_free (emfs->selected_uri);
-	g_free (emfs->created_uri);
+		type = g_type_register_static (
+			GTK_TYPE_DIALOG, "EMFolderSelector", &type_info, 0);
+	}
 
-	G_OBJECT_CLASS (parent_class)->finalize (obj);
+	return type;
 }
 
 static void
@@ -172,7 +163,7 @@
 void
 em_folder_selector_construct (EMFolderSelector *emfs, EMFolderTree *emft, guint32 flags, const char *title, const char *text, const char *oklabel)
 {
-	GtkWidget *label;
+	GtkWidget *widget;
 
 	gtk_window_set_modal (GTK_WINDOW (emfs), FALSE);
 	gtk_window_set_default_size (GTK_WINDOW (emfs), 350, 300);
@@ -194,19 +185,29 @@
 	gtk_dialog_set_response_sensitive (GTK_DIALOG (emfs), GTK_RESPONSE_OK, FALSE);
 	gtk_dialog_set_default_response (GTK_DIALOG (emfs), GTK_RESPONSE_OK);
 
+	widget = gtk_scrolled_window_new (NULL, NULL);
+	gtk_scrolled_window_set_policy (
+		GTK_SCROLLED_WINDOW (widget),
+		GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+	gtk_scrolled_window_set_shadow_type (
+		GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN);
+	gtk_box_pack_end (
+		GTK_BOX (GTK_DIALOG (emfs)->vbox), widget, TRUE, TRUE, 6);
+	gtk_widget_show (widget);
+
 	emfs->emft = emft;
-	gtk_widget_show ((GtkWidget *) emft);
+	gtk_container_add (GTK_CONTAINER (widget), GTK_WIDGET (emft));
+	gtk_widget_show (GTK_WIDGET (emft));
 
 	g_signal_connect (emfs->emft, "folder-selected", G_CALLBACK (folder_selected_cb), emfs);
 	g_signal_connect (emfs->emft, "folder-activated", G_CALLBACK (folder_activated_cb), emfs);
-	gtk_box_pack_end (GTK_BOX (GTK_DIALOG (emfs)->vbox), (GtkWidget *)emft, TRUE, TRUE, 6);
 
 	if (text != NULL) {
-		label = gtk_label_new (text);
-		gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
-		gtk_widget_show (label);
+		widget = gtk_label_new (text);
+		gtk_label_set_justify (GTK_LABEL (widget), GTK_JUSTIFY_LEFT);
+		gtk_widget_show (widget);
 
-		gtk_box_pack_end (GTK_BOX (GTK_DIALOG (emfs)->vbox), label, FALSE, TRUE, 6);
+		gtk_box_pack_end (GTK_BOX (GTK_DIALOG (emfs)->vbox), widget, FALSE, TRUE, 6);
 	}
 
 	gtk_widget_grab_focus ((GtkWidget *) emfs->emft);

Modified: branches/kill-bonobo/mail/em-folder-selector.h
==============================================================================
--- branches/kill-bonobo/mail/em-folder-selector.h	(original)
+++ branches/kill-bonobo/mail/em-folder-selector.h	Fri Oct 24 23:02:33 2008
@@ -26,20 +26,30 @@
 
 #include <gtk/gtk.h>
 
-#ifdef cplusplus
-extern "C" {
-#pragma }
-#endif /* cplusplus */
-
-#define EM_TYPE_FOLDER_SELECTOR			(em_folder_selector_get_type ())
-#define EM_FOLDER_SELECTOR(obj)			(G_TYPE_CHECK_INSTANCE_CAST ((obj), EM_TYPE_FOLDER_SELECTOR, EMFolderSelector))
-#define EM_FOLDER_SELECTOR_CLASS(klass)		(G_TYPE_CHECK_CLASS_CAST ((klass), EM_TYPE_FOLDER_SELECTOR, EMFolderSelectorClass))
-#define EM_IS_FOLDER_SELECTOR(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), EM_TYPE_FOLDER_SELECTOR))
-#define EM_IS_FOLDER_SELECTOR_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((obj), EM_TYPE_FOLDER_SELECTOR))
+/* Standard GObject macros */
+#define EM_TYPE_FOLDER_SELECTOR \
+	(em_folder_selector_get_type ())
+#define EM_FOLDER_SELECTOR(obj) \
+	(G_TYPE_CHECK_INSTANCE_CAST \
+	((obj), EM_TYPE_FOLDER_SELECTOR, EMFolderSelector))
+#define EM_FOLDER_SELECTOR_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_CAST \
+	((cls), EM_TYPE_FOLDER_SELECTOR, EMFolderSelectorClass))
+#define EM_IS_FOLDER_SELECTOR(obj) \
+	(G_TYPE_CHECK_INSTANCE_TYPE \
+	((obj), EM_TYPE_FOLDER_SELECTOR))
+#define EM_IS_FOLDER_SELECTOR_CLASS(cls) \
+	(G_TYPE_CHECK_CLASS_TYPE \
+	((cls), EM_TYPE_FOLDER_SELECTOR))
+#define EM_FOLDER_SELECTOR_GET_CLASS(obj) \
+	(G_TYPE_INSTANCE_GET_CLASS \
+	((obj), EM_TYPE_FOLDER_SELECTOR, EMFolderSelectorClass))
 
-typedef struct _EMFolderSelector        EMFolderSelector;
+G_BEGIN_DECLS
+
+typedef struct _EMFolderSelector EMFolderSelector;
+typedef struct _EMFolderSelectorClass EMFolderSelectorClass;
 typedef struct _EMFolderSelectorPrivate EMFolderSelectorPrivate;
-typedef struct _EMFolderSelectorClass   EMFolderSelectorClass;
 
 struct _EMFolderSelector {
 	GtkDialog parent;
@@ -87,8 +97,6 @@
 GList *em_folder_selector_get_selected_uris (EMFolderSelector *emfs);
 GList *em_folder_selector_get_selected_paths (EMFolderSelector *emfs);
 
-#ifdef cplusplus
-}
-#endif /* cplusplus */
+G_END_DECLS
 
 #endif /* EM_FOLDER_SELECTOR_H */

Modified: branches/kill-bonobo/mail/em-folder-tree.c
==============================================================================
--- branches/kill-bonobo/mail/em-folder-tree.c	(original)
+++ branches/kill-bonobo/mail/em-folder-tree.c	Fri Oct 24 23:02:33 2008
@@ -118,6 +118,7 @@
 enum {
 	FOLDER_ACTIVATED,  /* aka double-clicked or user hit enter */
 	FOLDER_SELECTED,
+	POPUP_EVENT,
 	LAST_SIGNAL
 };
 
@@ -177,6 +178,13 @@
 static gpointer parent_class = NULL;
 
 static void
+folder_tree_emit_popup_event (EMFolderTree *emft,
+                              GdkEvent *event)
+{
+	g_signal_emit (emft, signals[POPUP_EVENT], 0, event);
+}
+
+static void
 emft_free_select_uri (struct _selected_uri *u)
 {
 	g_free (u->uri);
@@ -284,6 +292,16 @@
 		G_TYPE_NONE, 2,
 		G_TYPE_STRING,
 		G_TYPE_STRING);
+
+	signals[POPUP_EVENT] = g_signal_new (
+		"popup-event",
+		G_OBJECT_CLASS_TYPE (object_class),
+		G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+		G_STRUCT_OFFSET (EMFolderTreeClass, popup_event),
+		NULL, NULL,
+		g_cclosure_marshal_VOID__BOXED,
+		G_TYPE_NONE, 1,
+		GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
 }
 
 static void
@@ -2229,6 +2247,9 @@
 			info_flags |= CAMEL_FOLDER_TYPE_OUTBOX;
 	}
 
+	folder_tree_emit_popup_event (emft, event);
+
+#if 0  /* KILL-BONOBO */
 	/** @HookPoint-EMPopup: Folder Tree Context Menu
 	 * @Id: org.gnome.evolution.mail.foldertree.popup
 	 * @Class: org.gnome.evolution.mail.popup:1.0
@@ -2257,6 +2278,7 @@
 	} else {
 		gtk_menu_popup (menu, NULL, NULL, NULL, NULL, event->button.button, event->button.time);
 	}
+#endif
 
 	g_free (full_name);
 	g_free (uri);

Modified: branches/kill-bonobo/mail/em-folder-tree.h
==============================================================================
--- branches/kill-bonobo/mail/em-folder-tree.h	(original)
+++ branches/kill-bonobo/mail/em-folder-tree.h	Fri Oct 24 23:02:33 2008
@@ -79,6 +79,7 @@
 						 const gchar *full_name,
 						 const gchar *uri,
 						 guint32 flags);
+	void		(*popup_event)		(EMFolderTree *emft);
 };
 
 GType em_folder_tree_get_type (void);

Modified: branches/kill-bonobo/mail/em-folder-utils.c
==============================================================================
--- branches/kill-bonobo/mail/em-folder-utils.c	(original)
+++ branches/kill-bonobo/mail/em-folder-utils.c	Fri Oct 24 23:02:33 2008
@@ -690,7 +690,7 @@
 	model = e_mail_shell_module_get_folder_tree_model (mail_shell_module);
 	folder_tree = (EMFolderTree *) em_folder_tree_new_with_model (model);
 
-	dialog = em_folder_selector_create_new (folder_tree, 0, _("Create folder"), _("Specify where to create the folder:"));
+	dialog = em_folder_selector_create_new (folder_tree, 0, _("Create Folder"), _("Specify where to create the folder:"));
 	if (folderinfo != NULL)
 		em_folder_selector_set_selected ((EMFolderSelector *) dialog, folderinfo->uri);
 	g_signal_connect (dialog, "response", G_CALLBACK (emfu_popup_new_folder_response), emft);

Modified: branches/kill-bonobo/shell/e-shell-content.c
==============================================================================
--- branches/kill-bonobo/shell/e-shell-content.c	(original)
+++ branches/kill-bonobo/shell/e-shell-content.c	Fri Oct 24 23:02:33 2008
@@ -910,6 +910,14 @@
 	return type;
 }
 
+/**
+ * e_shell_content_new:
+ * @shell_view: an #EShellView
+ *
+ * Creates a new #EShellContent instance belonging to @shell_view.
+ *
+ * Returns: a new #EShellContent instance
+ **/
 GtkWidget *
 e_shell_content_new (EShellView *shell_view)
 {
@@ -919,6 +927,40 @@
 		E_TYPE_SHELL_CONTENT, "shell-view", shell_view, NULL);
 }
 
+/**
+ * e_shell_content_check_state:
+ * @shell_content: an #EShellContent
+ *
+ * #EShellContent subclasses should implement the
+ * <structfield>check_state</structfield> method in #EShellContentClass
+ * to return a set of flags describing the current content selection.
+ * Subclasses are responsible for defining their own flags.  This is
+ * primarily used to assist shell views with updating actions (see
+ * e_shell_view_update_actions()).
+ *
+ * Returns: a set of flags describing the current @shell_content selection
+ **/
+guint32
+e_shell_content_check_state (EShellContent *shell_content)
+{
+	EShellContentClass *shell_content_class;
+
+	g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), 0);
+
+	shell_content_class = E_SHELL_CONTENT_GET_CLASS (shell_content);
+	g_return_val_if_fail (shell_content_class->check_state != NULL, 0);
+
+	return shell_content_class->check_state (shell_content);
+}
+
+/**
+ * e_shell_content_get_shell_view:
+ * @shell_content: an #EShellContent
+ *
+ * Returns the #EShellView that was passed to e_shell_content_new().
+ *
+ * Returns: the #EShellView to which @shell_content belongs
+ **/
 EShellView *
 e_shell_content_get_shell_view (EShellContent *shell_content)
 {

Modified: branches/kill-bonobo/shell/e-shell-content.h
==============================================================================
--- branches/kill-bonobo/shell/e-shell-content.h	(original)
+++ branches/kill-bonobo/shell/e-shell-content.h	Fri Oct 24 23:02:33 2008
@@ -76,10 +76,13 @@
 
 	/* Factory Methods */
 	RuleContext *	(*new_search_context)	(void);
+
+	guint32		(*check_state)		(EShellContent *shell_content);
 };
 
 GType		e_shell_content_get_type	(void);
 GtkWidget *	e_shell_content_new		(struct _EShellView *shell_view);
+guint32		e_shell_content_check_state	(EShellContent *shell_content);
 struct _EShellView *
 		e_shell_content_get_shell_view	(EShellContent *shell_content);
 RuleContext *	e_shell_content_get_context	(EShellContent *shell_content);

Modified: branches/kill-bonobo/shell/e-shell-sidebar.c
==============================================================================
--- branches/kill-bonobo/shell/e-shell-sidebar.c	(original)
+++ branches/kill-bonobo/shell/e-shell-sidebar.c	Fri Oct 24 23:02:33 2008
@@ -433,6 +433,8 @@
  * @shell_view: an #EShellView
  *
  * Creates a new #EShellSidebar instance belonging to @shell_view.
+ *
+ * Returns: a new #EShellSidebar instance
  **/
 GtkWidget *
 e_shell_sidebar_new (EShellView *shell_view)
@@ -445,6 +447,32 @@
 }
 
 /**
+ * e_shell_sidebar_check_state:
+ * @shell_sidebar an #EShellSidebar
+ *
+ * #EShellSidebar subclasses should implement the
+ * <structfield>check_state</structfield> method in #EShellSidebarClass
+ * to return a set of flags describing the current sidebar selection.
+ * Subclasses are responsible for defining their own flags.  This is
+ * primarily used to assist shell views with updating actions (see
+ * e_shell_view_update_actions()).
+ *
+ * Returns: a set of flags describing the current @shell_sidebar selection
+ **/
+guint32
+e_shell_sidebar_check_state (EShellSidebar *shell_sidebar)
+{
+	EShellSidebarClass *shell_sidebar_class;
+
+	g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), 0);
+
+	shell_sidebar_class = E_SHELL_SIDEBAR_GET_CLASS (shell_sidebar);
+	g_return_val_if_fail (shell_sidebar_class->check_state != NULL, 0);
+
+	return shell_sidebar_class->check_state (shell_sidebar);
+}
+
+/**
  * e_shell_sidebar_get_shell_view:
  * @shell_sidebar: an #EShellSidebar
  *

Modified: branches/kill-bonobo/shell/e-shell-sidebar.h
==============================================================================
--- branches/kill-bonobo/shell/e-shell-sidebar.h	(original)
+++ branches/kill-bonobo/shell/e-shell-sidebar.h	Fri Oct 24 23:02:33 2008
@@ -71,10 +71,13 @@
 
 struct _EShellSidebarClass {
 	GtkBinClass parent_class;
+
+	guint32		(*check_state)		(EShellSidebar *shell_sidebar);
 };
 
 GType		e_shell_sidebar_get_type	(void);
 GtkWidget *	e_shell_sidebar_new		(struct _EShellView *shell_view);
+guint32		e_shell_sidebar_check_state	(EShellSidebar *shell_sidebar);
 struct _EShellView *
 		e_shell_sidebar_get_shell_view	(EShellSidebar *shell_sidebar);
 const gchar *	e_shell_sidebar_get_primary_text(EShellSidebar *shell_sidebar);

Modified: branches/kill-bonobo/ui/evolution-mail.ui
==============================================================================
--- branches/kill-bonobo/ui/evolution-mail.ui	(original)
+++ branches/kill-bonobo/ui/evolution-mail.ui	Fri Oct 24 23:02:33 2008
@@ -160,13 +160,16 @@
     <toolitem action='mail-next'/>
   </toolbar>
   <popup name='mail-folder-popup'>
+    <menuitem action='mail-folder-new'/>
     <menuitem action='mail-folder-copy'/>
     <menuitem action='mail-folder-move'/>
     <separator/>
-    <menuitem action='mail-folder-new'/>
     <menuitem action='mail-folder-delete'/>
+    <separator/>
     <menuitem action='mail-folder-rename'/>
     <menuitem action='mail-folder-refresh'/>
+    <menuitem action='mail-flush-outbox'/>
+    <menuitem action='mail-empty-trash'/>
     <separator/>
     <menuitem action='mail-folder-properties'/>
   </popup>
@@ -193,7 +196,7 @@
     <menuitem action='mail-uri-call-to'/>
     <menuitem action='mail-uri-copy'/>
     <menuitem action='mail-uri-copy-address'/>
-    <menu action='mail-uri-to-search-folder-menu'/>
+    <menu action='mail-uri-to-search-folder-menu'>
       <menuitem action='mail-uri-to-search-folder-sender'/>
       <menuitem action='mail-uri-to-search-folder-recipient'/>
     </menu>



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