From 866a960fd9dba9c3c7162c61b1e12feca6d12668 Mon Sep 17 00:00:00 2001 From: Peter Williams Date: Tue, 14 Aug 2001 15:26:00 +0000 Subject: Fix bug #215... desensitize menu items based on the number of selected 2001-08-09 Peter Williams Fix bug #215... desensitize menu items based on the number of selected messages (and whether there's a message in the pane) * folder-browser-ui.c (folder_browser_ui_add_message): Sensitize the menu items appropriately based on the old state. (fbui_sensitize_items): New function. Set the sensitivity of a list of commands. (folder_browser_ui_set_selection_state): New function. Move the FB to a new state of selected-ness, and sensitize menu items appropriately. (folder_browser_ui_message_loaded): New function. When notified that a message has been loaded, sensitize some menu items. * folder-browser-ui.h: Prototype new functions. * folder-browser.h: New enumeration, FolderBrowserSelectionState, that records the previous state of the selection (_NONE, _SINGLE, _MULTIPLE). * folder-browser.c (got_folder): If the component is set, set our selection state to _NONE, because that's the default state of the ETree. (on_selection_changed): When the number of selected messages is updated, notify the FBUI code of our new state. (folder_browser_gui_init): Hook up to the selection_changed signal and default to the _NONE selection state. (done_message_selected): Notify when a message is loaded. 2001-08-08 Peter Williams * mail-folder-cache.c: Display how many messages are selected, too. (make_folder_status): If multiple messages are selected, add that to the string (the 0 and 1 cases are boring) (selection_changed): New function, update the selected count. (mail_folder_cache_note_fb): Connect to the selection_changed signal. svn path=/trunk/; revision=12012 --- mail/ChangeLog | 40 +++++++++++++++ mail/folder-browser-ui.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++- mail/folder-browser-ui.h | 4 ++ mail/folder-browser.c | 44 +++++++++++++++- mail/folder-browser.h | 9 ++++ mail/mail-folder-cache.c | 31 ++++++++++- 6 files changed, 254 insertions(+), 5 deletions(-) (limited to 'mail') diff --git a/mail/ChangeLog b/mail/ChangeLog index 28eb0e73da..0b33820aa6 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,43 @@ +2001-08-09 Peter Williams + + Fix bug #215... desensitize menu items based on the number of + selected messages (and whether there's a message in the pane) + + * folder-browser-ui.c (folder_browser_ui_add_message): Sensitize + the menu items appropriately based on the old state. + (fbui_sensitize_items): New function. Set the sensitivity of a + list of commands. + (folder_browser_ui_set_selection_state): New function. Move the FB + to a new state of selected-ness, and sensitize menu items + appropriately. + (folder_browser_ui_message_loaded): New function. When notified + that a message has been loaded, sensitize some menu items. + + * folder-browser-ui.h: Prototype new functions. + + * folder-browser.h: New enumeration, + FolderBrowserSelectionState, that records the previous state + of the selection (_NONE, _SINGLE, _MULTIPLE). + + * folder-browser.c (got_folder): If the component is set, + set our selection state to _NONE, because that's the default + state of the ETree. + (on_selection_changed): When the number of selected messages + is updated, notify the FBUI code of our new state. + (folder_browser_gui_init): Hook up to the selection_changed + signal and default to the _NONE selection state. + (done_message_selected): Notify when a message is loaded. + +2001-08-08 Peter Williams + + * mail-folder-cache.c: Display how many messages are selected, + too. + (make_folder_status): If multiple messages are selected, add that + to the string (the 0 and 1 cases are boring) + (selection_changed): New function, update the selected count. + (mail_folder_cache_note_fb): Connect to the selection_changed + signal. + 2001-08-14 Dan Winship * folder-browser.c (message_list_drag_data_get): Fix the fix for diff --git a/mail/folder-browser-ui.c b/mail/folder-browser-ui.c index 204630962d..3bd810a70d 100644 --- a/mail/folder-browser-ui.c +++ b/mail/folder-browser-ui.c @@ -278,7 +278,8 @@ folder_browser_ui_add_message (FolderBrowser *fb) { int state; BonoboUIComponent *uic = fb->uicomp; - + FolderBrowserSelectionState prev_state; + ui_add (fb, "message", message_verbs, message_pixcache); /* Display Style */ @@ -296,7 +297,13 @@ folder_browser_ui_add_message (FolderBrowser *fb) /* Resend Message */ if (fb->folder && !folder_browser_is_sent (fb)) - bonobo_ui_component_set_prop (uic, "/commands/MessageResend", "sensitive", "0", NULL); + bonobo_ui_component_set_prop (uic, "/commands/MessageResend", "sensitive", "0", NULL); + + /* sensitivity of message-specific commands */ + + prev_state = fb->selection_state; + fb->selection_state = FB_SELSTATE_UNDEFINED; + folder_browser_ui_set_selection_state (fb, prev_state); } /* @@ -387,3 +394,123 @@ folder_browser_ui_rm_all (FolderBrowser *fb) bonobo_ui_component_unset_container (uic); } +static void +fbui_sensitize_items (BonoboUIComponent *uic, const char **items, gboolean enable) +{ + int i; + char name_buf[256]; /* this should really be large enough */ + char *value; + + if (enable) + value = "1"; + else + value = "0"; + + for (i = 0; items[i]; i++) { + sprintf (name_buf, "/commands/%s", items[i]); + bonobo_ui_component_set_prop (uic, name_buf, "sensitive", value, NULL); + } +} + +static const char *message_pane_enables[] = { + /* these only work if there's a message in the message pane + * (preview pane). This state is independent of how many are + * selected. */ + "PrintMessage", "PrintPreviewMessage", + "ViewFullHeaders", "ViewLoadImages", "ViewNormal", "ViewSource", + + NULL +}; + +void +folder_browser_ui_set_selection_state (FolderBrowser *fb, FolderBrowserSelectionState state) +{ + BonoboUIComponent *uic = fb->uicomp; + + /* We'd like to keep the number of changes to be minimal cause + * this is a lot of corba traffic. So we break these sets of commands into bits: + * + * Also remember that everything defaults to sensitized + * + * Disable: + * NONE = none_disables + multiple_disables + * SINGLE = [nothing disabled] + * MULTIPLE = multiple_disables + * UNDEFINED = [nothing disabled] + */ + + static const char *none_disables[] = { + /* actions that work on > 0 messages */ + "MessageApplyFilters", + "MessageCopy", "MessageMove", + "MessageDelete", "MessageUndelete", + "MessageMarkAsRead", "MessageMarkAsUnRead", + "MessageMarkAsImportant", "MessageMarkAsUnimportant", + "MessageOpen", "MessageSaveAs", + "MessageForward", "MessageForwardAttached", + + "EditCut", "EditCopy", "EditPaste", "ViewHideSelected", + + NULL + }; + + static const char *multiple_disables[] = { + /* actions that work on exactly 1 message */ + "MessageReplyAll", "MessageReplyList", "MessageReplySender", "MessageResend", + "MessageForwardInline", "MessageForwardQuoted", + + "ToolsFilterMailingList", "ToolsFilterRecipient", "ToolsFilterSender", + "ToolsFilterSubject", "ToolsVFolderMailingList", "ToolsVFolderRecipient", + "ToolsVFolderSender", "ToolsVFolderSubject", + + /* moving around -- if we have more than one message selected, it + * doesn't behave very. If people complain, it isn't a problem + * to put these commands in none_disables tho. */ + "MailNext", "MailNextFlagged", "MailNextUnread", "MailNextThread", + "MailPrevious", "MailPreviousFlagged", "MailPreviousUnread", + + NULL + }; + + /* assumes that all the appropriate XML's have been loaded */ + + if (state == fb->selection_state) + return; + + switch (state) { + case FB_SELSTATE_NONE: + fbui_sensitize_items (uic, none_disables, FALSE); + if (fb->selection_state != FB_SELSTATE_MULTIPLE) + fbui_sensitize_items (uic, multiple_disables, FALSE); + break; + case FB_SELSTATE_SINGLE: + if (fb->selection_state != FB_SELSTATE_UNDEFINED) + fbui_sensitize_items (uic, multiple_disables, TRUE); + if (fb->selection_state == FB_SELSTATE_NONE) + fbui_sensitize_items (uic, none_disables, TRUE); + break; + case FB_SELSTATE_MULTIPLE: + if (fb->selection_state == FB_SELSTATE_NONE) + fbui_sensitize_items (uic, none_disables, TRUE); + else + fbui_sensitize_items (uic, multiple_disables, FALSE); + break; + case FB_SELSTATE_UNDEFINED: + printf ("changing to undefined selection state? hah!\n"); + return; + } + + if (fb->loaded_uid == NULL) + fbui_sensitize_items (uic, message_pane_enables, FALSE); + + fb->selection_state = state; +} + +void +folder_browser_ui_message_loaded (FolderBrowser *fb) +{ + BonoboUIComponent *uic = fb->uicomp; + + if (fb->loaded_uid == NULL) + fbui_sensitize_items (uic, message_pane_enables, TRUE); +} diff --git a/mail/folder-browser-ui.h b/mail/folder-browser-ui.h index 36e70e13e5..8bd0d13c1c 100644 --- a/mail/folder-browser-ui.h +++ b/mail/folder-browser-ui.h @@ -20,4 +20,8 @@ void folder_browser_ui_add_global (FolderBrowser *fb); void folder_browser_ui_rm_list (FolderBrowser *fb); void folder_browser_ui_rm_all (FolderBrowser *fb); +/* these affect the sensitivity of UI elements */ +void folder_browser_ui_set_selection_state (FolderBrowser *fb, FolderBrowserSelectionState state); +void folder_browser_ui_message_loaded (FolderBrowser *fb); + #endif /* _FOLDER_BROWSER_UI_H */ diff --git a/mail/folder-browser.c b/mail/folder-browser.c index 348d0aa8d0..269f59b9a6 100644 --- a/mail/folder-browser.c +++ b/mail/folder-browser.c @@ -47,6 +47,7 @@ #include "mail-autofilter.h" #include "mail-mt.h" #include "mail-folder-cache.h" +#include "folder-browser-ui.h" #include "mail-local.h" #include "mail-config.h" @@ -712,6 +713,11 @@ got_folder(char *uri, CamelFolder *folder, void *data) mail_folder_cache_note_folder (fb->uri, folder); mail_folder_cache_note_fb (fb->uri, fb); + /* when loading a new folder, nothing is selected initially */ + + if (fb->uicomp) + folder_browser_ui_set_selection_state (fb, FB_SELSTATE_NONE); + done: gtk_object_unref (GTK_OBJECT (fb)); @@ -1596,6 +1602,33 @@ on_double_click (ETree *tree, gint row, ETreePath path, gint col, GdkEvent *even open_msg (NULL, fb); } +static void +on_selection_changed (GtkObject *obj, gpointer user_data) +{ + FolderBrowser *fb = FOLDER_BROWSER (user_data); + FolderBrowserSelectionState state; + + /* we can get this signal at strange times... + * if no uicomp, don't even bother */ + + if (fb->uicomp == NULL) + return; + + switch (e_selection_model_selected_count (E_SELECTION_MODEL (obj))) { + case 0: + state = FB_SELSTATE_NONE; + break; + case 1: + state = FB_SELSTATE_SINGLE; + break; + default: + state = FB_SELSTATE_MULTIPLE; + break; + } + + folder_browser_ui_set_selection_state (fb, state); +} + static void fb_resize_cb (GtkWidget *w, GtkAllocation *a, FolderBrowser *fb) { @@ -1606,6 +1639,8 @@ fb_resize_cb (GtkWidget *w, GtkAllocation *a, FolderBrowser *fb) static void folder_browser_gui_init (FolderBrowser *fb) { + ESelectionModel *esm; + /* The panned container */ fb->vpaned = e_vpaned_new (); gtk_widget_show (fb->vpaned); @@ -1643,12 +1678,17 @@ folder_browser_gui_init (FolderBrowser *fb) gtk_signal_connect (GTK_OBJECT (fb->search), "menu_activated", GTK_SIGNAL_FUNC (folder_browser_search_menu_activated), fb); + gtk_table_attach (GTK_TABLE (fb), GTK_WIDGET (fb->search), 0, 1, 0, 1, GTK_FILL | GTK_EXPAND, 0, 0, 0); - + + esm = e_tree_get_selection_model (E_TREE (fb->message_list->tree)); + gtk_signal_connect (GTK_OBJECT (esm), "selection_changed", on_selection_changed, fb); + fb->selection_state = FB_SELSTATE_NONE; /* default to none */ + e_paned_add1 (E_PANED (fb->vpaned), GTK_WIDGET (fb->message_list)); gtk_widget_show (GTK_WIDGET (fb->message_list)); @@ -1687,6 +1727,8 @@ done_message_selected (CamelFolder *folder, char *uid, CamelMimeMessage *msg, vo return; mail_display_set_message (fb->mail_display, (CamelMedium *)msg); + folder_browser_ui_message_loaded (fb); + /* FIXME: should this signal be emitted here?? */ gtk_signal_emit (GTK_OBJECT (fb), folder_browser_signals [MESSAGE_LOADED], uid); diff --git a/mail/folder-browser.h b/mail/folder-browser.h index 332da56000..ea69c7579a 100644 --- a/mail/folder-browser.h +++ b/mail/folder-browser.h @@ -24,6 +24,13 @@ #define IS_FOLDER_BROWSER(o) (GTK_CHECK_TYPE ((o), FOLDER_BROWSER_TYPE)) #define IS_FOLDER_BROWSER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), FOLDER_BROWSER_TYPE)) +typedef enum _FolderBrowserSelectionState { + FB_SELSTATE_NONE, + FB_SELSTATE_SINGLE, + FB_SELSTATE_MULTIPLE, + FB_SELSTATE_UNDEFINED +} FolderBrowserSelectionState; + struct _FolderBrowser { GtkTable parent; @@ -63,6 +70,8 @@ struct _FolderBrowser { gboolean threaded; gboolean pref_master; + FolderBrowserSelectionState selection_state; + /* View collection and the menu handler object */ GalViewCollection *view_collection; GalViewMenus *view_menus; diff --git a/mail/mail-folder-cache.c b/mail/mail-folder-cache.c index 9e7d0f2e0f..46f595c6ed 100644 --- a/mail/mail-folder-cache.c +++ b/mail/mail-folder-cache.c @@ -50,7 +50,8 @@ typedef enum mail_folder_info_flags { MAIL_FIF_PATH_VALID = (1 << 5), MAIL_FIF_NAME_VALID = (1 << 6), MAIL_FIF_UPDATE_QUEUED = (1 << 7), - MAIL_FIF_FB_VALID = (1 << 8) + MAIL_FIF_FB_VALID = (1 << 8), + MAIL_FIF_SELECTED_VALID = (1 << 9) } mfif; typedef enum mail_folder_info_update_mode { @@ -73,7 +74,7 @@ typedef struct _mail_folder_info { gchar *name; guint flags; - guint unread, total, hidden; + guint unread, total, hidden, selected; FolderBrowser *fb; @@ -154,6 +155,13 @@ make_folder_status (mail_folder_info *mfi) set_one = TRUE; } + if (mfi->flags & MAIL_FIF_SELECTED_VALID && mfi->selected > 1) { + if (set_one) + work = g_string_append (work, _(", ")); + g_string_sprintfa (work, _("%d selected"), mfi->selected); + set_one = TRUE; + } + if (mfi->flags & MAIL_FIF_TOTAL_VALID) { if (set_one) work = g_string_append (work, _(", ")); @@ -423,6 +431,23 @@ message_list_built (MessageList *ml, gpointer user_data) maybe_update (mfi); } +static void +selection_changed (ESelectionModel *esm, gpointer user_data) +{ + mail_folder_info *mfi = user_data; + + d(g_message ("Selection model %p changed, checking selected", esm)); + + LOCK_FOLDERS (); + + mfi->selected = e_selection_model_selected_count (esm); + mfi->flags |= MAIL_FIF_SELECTED_VALID; + + UNLOCK_FOLDERS (); + + maybe_update (mfi); +} + static void check_for_fb_match (gpointer key, gpointer value, gpointer user_data) { @@ -652,6 +677,8 @@ mail_folder_cache_note_fb (const gchar *uri, FolderBrowser *fb) gtk_signal_connect (GTK_OBJECT (fb->message_list), "message_list_built", message_list_built, mfi); + gtk_signal_connect (GTK_OBJECT (e_tree_get_selection_model (fb->message_list->tree)), + "selection_changed", selection_changed, mfi); UNLOCK_FOLDERS (); -- cgit v1.2.3