aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog40
-rw-r--r--mail/folder-browser-ui.c131
-rw-r--r--mail/folder-browser-ui.h4
-rw-r--r--mail/folder-browser.c44
-rw-r--r--mail/folder-browser.h9
-rw-r--r--mail/mail-folder-cache.c31
6 files changed, 254 insertions, 5 deletions
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 <peterw@ximian.com>
+
+ 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 <peterw@ximian.com>
+
+ * 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 <danw@ximian.com>
* 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));
@@ -1597,6 +1603,33 @@ on_double_click (ETree *tree, gint row, ETreePath path, gint col, GdkEvent *even
}
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)
{
if (fb->preview_shown)
@@ -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, _(", "));
@@ -424,6 +432,23 @@ message_list_built (MessageList *ml, gpointer user_data)
}
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)
{
mail_folder_info *mfi = (mail_folder_info *) value;
@@ -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 ();