Fix bug #215... desensitize menu items based on the number of selected

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.

svn path=/trunk/; revision=12012
This commit is contained in:
Peter Williams
2001-08-14 15:26:00 +00:00
committed by Peter Williams
parent 4b6f7546b8
commit 866a960fd9
6 changed files with 254 additions and 5 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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 */

View File

@ -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);

View File

@ -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;

View File

@ -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 ();