From 206f7e366cd08f13005037f618eb6a7cbb6e5264 Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Wed, 10 Jul 2002 23:28:11 +0000 Subject: Modified to use a single list of UI node elements with an enable-mask 2002-07-10 Jeffrey Stedfast * folder-browser-ui.c: Modified to use a single list of UI node elements with an enable-mask rather than split into groups. This allows much more control and easier modification to get the desired enable/disable effects. svn path=/trunk/; revision=17414 --- mail/ChangeLog | 5 + mail/folder-browser-ui.c | 422 ++++++++++++++++++++++------------------------- 2 files changed, 201 insertions(+), 226 deletions(-) diff --git a/mail/ChangeLog b/mail/ChangeLog index c2717da744..0acb6d21cc 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,5 +1,10 @@ 2002-07-10 Jeffrey Stedfast + * folder-browser-ui.c: Modified to use a single list of UI node + elements with an enable-mask rather than split into groups. This + allows much more control and easier modification to get the + desired enable/disable effects. + * mail-display.c (mail_display_set_message): If we unref'd a current_message, clear the datalist. Don't bother connecting to the message's finalise signal because something else may own a ref diff --git a/mail/folder-browser-ui.c b/mail/folder-browser-ui.c index 524af3c2ef..7ba0056980 100644 --- a/mail/folder-browser-ui.c +++ b/mail/folder-browser-ui.c @@ -168,10 +168,97 @@ static EPixmap global_pixcache [] = { E_PIXMAP_END }; -static void ui_add (FolderBrowser *fb, - const gchar *name, - BonoboUIVerb verb[], - EPixmap pixcache[]) + +enum { + IS_DRAFTS_FOLDER = (1 << 0), + IS_OUTBOX_FOLDER = (1 << 1), + IS_SENT_FOLDER = (1 << 2), + + IS_OUTGOING_FOLDER = (IS_DRAFTS_FOLDER | IS_OUTBOX_FOLDER | IS_SENT_FOLDER), + IS_INCOMING_FOLDER = (1 << 3), + + IS_ANY_FOLDER = (IS_OUTGOING_FOLDER | IS_INCOMING_FOLDER), + + SELECTION_NONE = (1 << 4), + SELECTION_SINGLE = (1 << 5), + SELECTION_MULTIPLE = (1 << 6), + + SELECTION_ANYTHING = (SELECTION_SINGLE | SELECTION_MULTIPLE), +}; + +struct _UINode { + const char *name; + guint32 enable_mask; +}; + +struct _UINode default_ui_nodes[] = { + { "ViewLoadImages", IS_ANY_FOLDER | SELECTION_SINGLE }, + { "ViewFullHeaders", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "ViewNormal", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "ViewSource", IS_ANY_FOLDER | SELECTION_ANYTHING }, + + { "AddSenderToAddressbook", IS_INCOMING_FOLDER | SELECTION_SINGLE }, + + { "MessageResend", IS_SENT_FOLDER | SELECTION_SINGLE }, + + /* actions that work on exactly 1 message */ + { "MessageReplyAll", IS_ANY_FOLDER | SELECTION_SINGLE }, + { "MessageReplyList", IS_ANY_FOLDER | SELECTION_SINGLE }, + { "MessageReplySender", IS_ANY_FOLDER | SELECTION_SINGLE }, + { "MessageForwardInline", IS_ANY_FOLDER | SELECTION_SINGLE }, + { "MessageForwardQuoted", IS_ANY_FOLDER | SELECTION_SINGLE }, + { "MessageRedirect", IS_ANY_FOLDER | SELECTION_SINGLE }, + { "MessageSearch", IS_ANY_FOLDER | SELECTION_SINGLE }, + + { "PrintMessage", IS_ANY_FOLDER | SELECTION_SINGLE }, + { "PrintPreviewMessage", IS_ANY_FOLDER | SELECTION_SINGLE }, + + { "ToolsFilterMailingList", IS_ANY_FOLDER | SELECTION_SINGLE }, + { "ToolsFilterRecipient", IS_ANY_FOLDER | SELECTION_SINGLE }, + { "ToolsFilterSender", IS_ANY_FOLDER | SELECTION_SINGLE }, + { "ToolsFilterSubject", IS_ANY_FOLDER | SELECTION_SINGLE }, + + { "ToolsVFolderMailingList", IS_ANY_FOLDER | SELECTION_SINGLE }, + { "ToolsVFolderRecipient", IS_ANY_FOLDER | SELECTION_SINGLE }, + { "ToolsVFolderSender", IS_ANY_FOLDER | SELECTION_SINGLE }, + { "ToolsVFolderSubject", IS_ANY_FOLDER | SELECTION_SINGLE }, + + /* actions that work on >= 1 message */ + { "MessageApplyFilters", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MessageCopy", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MessageMove", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MessageDelete", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MessageUndelete", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MessageMarkAsRead", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MessageMarkAsUnRead", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MessageMarkAsImportant", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MessageMarkAsUnimportant", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MessageFollowUpFlag", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MessageOpen", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MessageSaveAs", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MessageForward", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MessageForwardAttached", IS_ANY_FOLDER | SELECTION_ANYTHING }, + + { "EditCut", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "EditCopy", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "EditPaste", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "ViewHideSelected", IS_ANY_FOLDER | SELECTION_ANYTHING }, + + /* FIXME: should these be single-selection? */ + { "MailNext", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MailNextFlagged", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MailNextUnread", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MailNextThread", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MailPrevious", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MailPreviousFlagged", IS_ANY_FOLDER | SELECTION_ANYTHING }, + { "MailPreviousUnread", IS_ANY_FOLDER | SELECTION_ANYTHING }, +}; + +static int num_default_ui_nodes = sizeof (default_ui_nodes) / sizeof (default_ui_nodes[0]); + + +static void +ui_add (FolderBrowser *fb, const char *name, BonoboUIVerb verb[], EPixmap pixcache[]) { BonoboUIComponent *uic = fb->uicomp; char *file; @@ -192,13 +279,12 @@ static void ui_add (FolderBrowser *fb, /* more complex stuff */ static void -display_view(GalViewInstance *instance, - GalView *view, - gpointer data) +display_view (GalViewInstance *instance, GalView *view, gpointer data) { FolderBrowser *fb = data; - if (GAL_IS_VIEW_ETABLE(view)) { - gal_view_etable_attach_tree (GAL_VIEW_ETABLE(view), fb->message_list->tree); + + if (GAL_IS_VIEW_ETABLE (view)) { + gal_view_etable_attach_tree (GAL_VIEW_ETABLE (view), fb->message_list->tree); } } @@ -208,84 +294,83 @@ folder_browser_ui_setup_view_menus (FolderBrowser *fb) static GalViewCollection *collection = NULL; char *id; gboolean outgoing; - + if (fb->uicomp == NULL || fb->folder == NULL) return; - + g_assert (fb->view_instance == NULL); g_assert (fb->view_menus == NULL); - + outgoing = folder_browser_is_drafts (fb) || folder_browser_is_sent (fb) || folder_browser_is_outbox (fb); - + if (collection == NULL) { ETableSpecification *spec; char *local_dir; GalViewFactory *factory; - + collection = gal_view_collection_new(); - + gal_view_collection_set_title (collection, _("Mail")); - + local_dir = gnome_util_prepend_user_home ("/evolution/views/mail/"); gal_view_collection_set_storage_directories (collection, EVOLUTION_DATADIR "/evolution/views/mail/", local_dir); g_free (local_dir); - + spec = e_table_specification_new(); e_table_specification_load_from_file(spec, EVOLUTION_ETSPECDIR "/message-list.etspec"); - + factory = gal_view_factory_etable_new (spec); gtk_object_unref (GTK_OBJECT (spec)); gal_view_collection_add_factory (collection, factory); gtk_object_unref (GTK_OBJECT (factory)); - + gal_view_collection_load(collection); } - + id = mail_config_folder_to_safe_url(fb->folder); fb->view_instance = gal_view_instance_new (collection, id); g_free (id); - + if (outgoing) gal_view_instance_set_default_view (fb->view_instance, "As_Sent_Folder"); - + if (!gal_view_instance_exists (fb->view_instance)) { char *path; struct stat st; - + gal_view_instance_load (fb->view_instance); - + path = mail_config_folder_to_cachename (fb->folder, "et-header-"); if (path && stat (path, &st) == 0 && st.st_size > 0 && S_ISREG (st.st_mode)) { ETableSpecification *spec; ETableState *state; GalView *view; - + spec = e_table_specification_new(); e_table_specification_load_from_file(spec, EVOLUTION_ETSPECDIR "/message-list.etspec"); view = gal_view_etable_new(spec, ""); gtk_object_unref (GTK_OBJECT (spec)); - + state = e_table_state_new (); e_table_state_load_from_file (state, path); gal_view_etable_set_state (GAL_VIEW_ETABLE (view), state); gtk_object_unref (GTK_OBJECT (state)); - + gal_view_instance_set_custom_view (fb->view_instance, view); gtk_object_unref (GTK_OBJECT (view)); } g_free (path); } - - - fb->view_menus = gal_view_menus_new(fb->view_instance); - gal_view_menus_apply(fb->view_menus, fb->uicomp, NULL); - gtk_signal_connect(GTK_OBJECT(fb->view_instance), "display_view", - display_view, fb); + + fb->view_menus = gal_view_menus_new (fb->view_instance); + gal_view_menus_apply (fb->view_menus, fb->uicomp, NULL); + gtk_signal_connect (GTK_OBJECT (fb->view_instance), "display_view", + display_view, fb); display_view (fb->view_instance, gal_view_instance_get_current_view (fb->view_instance), fb); } @@ -295,10 +380,10 @@ folder_browser_ui_discard_view_menus (FolderBrowser *fb) { g_assert (fb->view_instance != NULL); g_assert (fb->view_menus != NULL); - + gtk_object_unref (GTK_OBJECT (fb->view_instance)); fb->view_instance = NULL; - + gtk_object_unref (GTK_OBJECT (fb->view_menus)); fb->view_menus = NULL; } @@ -326,34 +411,34 @@ folder_browser_ui_message_list_unfocus (FolderBrowser *fb) } static void -folder_browser_setup_property_menu (FolderBrowser *fb, - BonoboUIComponent *uic) +folder_browser_setup_property_menu (FolderBrowser *fb, BonoboUIComponent *uic) { char *name, *base = NULL; CamelURL *url; - - url = camel_url_new(fb->uri, NULL); + + url = camel_url_new (fb->uri, NULL); if (url) { if (url->fragment) - base = g_basename(url->fragment); + base = g_basename (url->fragment); else - base = g_basename(url->path); + base = g_basename (url->path); } - + if (base && base [0] != 0) name = g_strdup_printf (_("Properties for \"%s\""), base); else name = g_strdup (_("Properties")); - + bonobo_ui_component_set_prop ( uic, "/menu/File/Folder/ComponentPlaceholder/ChangeFolderProperties", "label", name, NULL); g_free (name); - + if (url) - camel_url_free(url); - - fbui_sensitise_item(fb, "ChangeFolderProperties", (strncmp(fb->uri, "vfolder:", 8) == 0 || strncmp(fb->uri, "file:", 5) == 0)); + camel_url_free (url); + + fbui_sensitise_item (fb, "ChangeFolderProperties", + (strncmp (fb->uri, "vfolder:", 8) == 0 || strncmp (fb->uri, "file:", 5) == 0)); } /* Must be in the same order as MailConfigDisplayStyle */ @@ -388,7 +473,7 @@ folder_browser_ui_add_message (FolderBrowser *fb) /* Resend Message */ if (fb->folder && !folder_browser_is_sent (fb)) - fbui_sensitise_item(fb, "MessageResend", FALSE); + fbui_sensitise_item (fb, "MessageResend", FALSE); /* sensitivity of message-specific commands */ prev_state = fb->selection_state; @@ -401,25 +486,17 @@ folder_browser_ui_add_message (FolderBrowser *fb) fb); } -/* -void -folder_browser_ui_rm_message (FolderBrowser *fb) -{ - ui_rm (fb, "message", message_verbs, message_pixcache); -} -*/ - void folder_browser_ui_add_list (FolderBrowser *fb) { - int state; BonoboUIComponent *uic = fb->uicomp; + int state; ui_add (fb, "list", list_verbs, list_pixcache); /* Hide Deleted */ if (fb->folder && (fb->folder->folder_flags & CAMEL_FOLDER_IS_TRASH)) { - fbui_sensitise_item(fb, "HideDeleted", FALSE); + fbui_sensitise_item (fb, "HideDeleted", FALSE); state = FALSE; } else { state = mail_config_get_hide_deleted (); @@ -459,11 +536,11 @@ folder_browser_ui_add_global (FolderBrowser *fb) { int state; BonoboUIComponent *uic = fb->uicomp; - + ui_add (fb, "global", global_verbs, global_pixcache); - + /* (Pre)view toggle */ - + state = mail_config_get_show_preview (FOLDER_BROWSER (fb)->uri); bonobo_ui_component_set_prop (uic, "/commands/ViewPreview", "state", state ? "1" : "0", NULL); bonobo_ui_component_add_listener (uic, "ViewPreview", folder_browser_toggle_preview, fb); @@ -475,207 +552,98 @@ folder_browser_ui_add_global (FolderBrowser *fb) bonobo_ui_component_set_prop(uic, "/commands/MailStop", "sensitive", "0", NULL); } -/* -void -folder_browser_ui_rm_global (FolderBrowser *fb) -{ -} -*/ - void folder_browser_ui_rm_all (FolderBrowser *fb) { BonoboUIComponent *uic = fb->uicomp; - + bonobo_ui_component_rm (uic, "/", NULL); bonobo_ui_component_unset_container (uic); - + if (fb->sensitise_state) { - g_hash_table_destroy(fb->sensitise_state); + g_hash_table_destroy (fb->sensitise_state); fb->sensitise_state = NULL; } } void -fbui_sensitise_item(FolderBrowser *fb, const char *item, int state) +fbui_sensitise_item (FolderBrowser *fb, const char *item, int state) { - char *name; + char *name, *key; int val; - char *key; - + /* If this whole caching idea doesn't work, remove it here */ if (fb->sensitise_state == NULL) - fb->sensitise_state = g_hash_table_new(g_str_hash, g_str_equal); - - if (g_hash_table_lookup_extended(fb->sensitise_state, item, (void **)&key, (void **)&val)) { + fb->sensitise_state = g_hash_table_new (g_str_hash, g_str_equal); + + if (g_hash_table_lookup_extended (fb->sensitise_state, item, (void **)&key, (void **)&val)) { if (val == state) return; } - - g_hash_table_insert(fb->sensitise_state, (char *)item, (void *)state); - + + g_hash_table_insert (fb->sensitise_state, (char *)item, (void *)state); + if (fb->uicomp) { - name = alloca(strlen(item) + strlen("/commands/") + 1); - sprintf(name, "/commands/%s", item); - bonobo_ui_component_set_prop(fb->uicomp, name, "sensitive", state?"1":"0", NULL); - } -} - -struct sensitize_data { - const char **items; - gboolean enable; -}; - -static gboolean -fbui_sensitize_timeout (gpointer data) -{ - FolderBrowser *fb = FOLDER_BROWSER (data); - GSList *iter, *list; - struct sensitize_data *sd; - int i; - - list = fb->sensitize_changes; - fb->sensitize_changes = NULL; - iter = list; - fb->sensitize_timeout_id = 0; - - gtk_object_ref((GtkObject *)fb); - - /*bonobo_ui_component_freeze (uic, NULL);*/ - - for (; iter; iter = iter->next) { - sd = (struct sensitize_data *) iter->data; - for (i=0;sd->items[i];i++) { - if (fb->uicomp) - fbui_sensitise_item(fb, sd->items[i], sd->enable); - } - g_free(sd); + name = alloca (strlen (item) + strlen ("/commands/") + 1); + sprintf (name, "/commands/%s", item); + bonobo_ui_component_set_prop (fb->uicomp, name, "sensitive", state ? "1" : "0", NULL); } - - g_slist_free (list); - gtk_object_unref((GtkObject *)fb); - - return FALSE; } static void -fbui_sensitize_items (FolderBrowser *fb, const char **items, gboolean enable) +fbui_sensitize_items (FolderBrowser *fb, guint32 enable_mask) { - struct sensitize_data *sd; - GSList *iter; - - /* If we're already updating these items, save an update by - * changing the item in the list. */ - - for (iter = fb->sensitize_changes; iter; iter = iter->next) { - sd = (struct sensitize_data *) iter->data; - - if (sd->items == items) - break; - } - - if (iter == NULL) { - sd = g_new (struct sensitize_data, 1); - sd->items = items; - sd->enable = enable; - - fb->sensitize_changes = g_slist_prepend (fb->sensitize_changes, sd); - } else { - /* Redundant, but shuts up the compiler. */ - sd = (struct sensitize_data *) iter->data; - sd->enable = enable; + gboolean enable; + int i; + + for (i = 0; i < num_default_ui_nodes; i++) { + enable = (default_ui_nodes[i].enable_mask & enable_mask) == enable_mask; + fbui_sensitise_item (fb, default_ui_nodes[i].name, enable); } - - if (fb->sensitize_timeout_id == 0) - fb->sensitize_timeout_id = g_timeout_add (110, fbui_sensitize_timeout, fb); } -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. */ - "ViewFullHeaders", "ViewLoadImages", "ViewNormal", "ViewSource", - "MessageSearch", "AddSenderToAddressbook", - NULL -}; - void folder_browser_ui_set_selection_state (FolderBrowser *fb, FolderBrowserSelectionState state) { - /* 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", - "MessageFollowUpFlag", "MessageOpen", "MessageSaveAs", - "MessageForward", "MessageForwardAttached", - "MessageRedirect", - - "EditCut", "EditCopy", "EditPaste", "ViewHideSelected", - - "MailNext", "MailNextFlagged", "MailNextUnread", "MailNextThread", - "MailPrevious", "MailPreviousFlagged", "MailPreviousUnread", - - NULL - }; - - static const char *multiple_disables[] = { - /* actions that work on exactly 1 message */ - "MessageReplyAll", "MessageReplyList", "MessageReplySender", "MessageResend", - "MessageForwardInline", "MessageForwardQuoted", "MessageRedirect", "MessageSearch", - - "PrintMessage", "PrintPreviewMessage", - - "ToolsFilterMailingList", "ToolsFilterRecipient", "ToolsFilterSender", - "ToolsFilterSubject", "ToolsVFolderMailingList", "ToolsVFolderRecipient", - "ToolsVFolderSender", "ToolsVFolderSubject", - - NULL - }; - - fbui_sensitize_items (fb, message_pane_enables, state != FB_SELSTATE_NONE && fb->loaded_uid && fb->preview_shown); - - /* assumes that all the appropriate XML's have been loaded */ - + gboolean outgoing = FALSE; + guint32 enable_mask = 0; + if (state == fb->selection_state) return; - + + if (folder_browser_is_drafts (fb)) { + enable_mask |= IS_DRAFTS_FOLDER; + outgoing = TRUE; + } + + if (folder_browser_is_outbox (fb)) { + enable_mask |= IS_OUTBOX_FOLDER; + outgoing = TRUE; + } + + if (folder_browser_is_sent (fb)) { + enable_mask |= IS_SENT_FOLDER; + outgoing = TRUE; + } + + if (outgoing == FALSE) + enable_mask |= IS_INCOMING_FOLDER; + switch (state) { - case FB_SELSTATE_NONE: - fbui_sensitize_items (fb, none_disables, FALSE); - if (fb->selection_state != FB_SELSTATE_MULTIPLE) - fbui_sensitize_items (fb, multiple_disables, FALSE); - break; case FB_SELSTATE_SINGLE: - if (fb->selection_state != FB_SELSTATE_UNDEFINED) - fbui_sensitize_items (fb, multiple_disables, TRUE); - if (fb->selection_state == FB_SELSTATE_NONE) - fbui_sensitize_items (fb, none_disables, TRUE); + enable_mask |= SELECTION_SINGLE; break; case FB_SELSTATE_MULTIPLE: - if (fb->selection_state == FB_SELSTATE_NONE) - fbui_sensitize_items (fb, none_disables, TRUE); - else - fbui_sensitize_items (fb, multiple_disables, FALSE); + enable_mask |= SELECTION_MULTIPLE; + break; + case FB_SELSTATE_NONE: + default: + enable_mask |= SELECTION_NONE; break; - case FB_SELSTATE_UNDEFINED: - printf ("changing to undefined selection state? hah!\n"); - return; } - + + fbui_sensitize_items (fb, enable_mask); + fb->selection_state = state; } @@ -683,7 +651,9 @@ void folder_browser_ui_message_loaded (FolderBrowser *fb) { BonoboUIComponent *uic = fb->uicomp; - - if (uic) - fbui_sensitize_items (fb, message_pane_enables, fb->loaded_uid && fb->preview_shown); + + if (uic) { + fb->selection_state = FB_SELSTATE_NONE; + folder_browser_ui_set_selection_state (fb, FB_SELSTATE_SINGLE); + } } -- cgit