From f7547cc6ac347ea5e9dd92034264a23e6fd48ac4 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 26 Mar 2010 18:33:00 -0400 Subject: Simplify the search UI for express mode. For express mode: - Move the search bar up to the toolbar. - Hide the "filter" combo box and lock down the first item. - Hide the "scope" combo box and lock down the first item. (This is the combo box with "Current Folder" only in the mailer.) - EShellView owns the search bar widget now instead of EShellContent. - Insert several nasty hacks that will likely come back to bite me. --- shell/e-shell-content.c | 156 +++++++++++++---------------------------- shell/e-shell-content.h | 8 +-- shell/e-shell-searchbar.c | 106 +++++++++++++++++++++++----- shell/e-shell-searchbar.h | 11 ++- shell/e-shell-view.c | 134 ++++++++++++++++++++++++++++++++++- shell/e-shell-view.h | 6 ++ shell/e-shell-window-private.c | 1 - shell/e-shell-window.c | 25 +++++-- 8 files changed, 302 insertions(+), 145 deletions(-) (limited to 'shell') diff --git a/shell/e-shell-content.c b/shell/e-shell-content.c index 4c17131d52..5d5857cfc2 100644 --- a/shell/e-shell-content.c +++ b/shell/e-shell-content.c @@ -48,9 +48,9 @@ struct _EShellContentPrivate { - gpointer shell_view; /* weak pointer */ + gpointer shell_view; /* weak pointer */ - GtkWidget *searchbar; + GtkWidget *searchbar; /* not referenced */ /* Custom search rules. */ gchar *user_filename; @@ -146,11 +146,9 @@ shell_content_dispose (GObject *object) static void shell_content_constructed (GObject *object) { - EShellContentClass *class; EShellContent *shell_content; EShellBackend *shell_backend; EShellView *shell_view; - GtkWidget *widget; const gchar *data_dir; shell_content = E_SHELL_CONTENT (object); @@ -165,41 +163,9 @@ shell_content_constructed (GObject *object) shell_content->priv->user_filename = g_build_filename (data_dir, "searches.xml", NULL); - class = E_SHELL_CONTENT_GET_CLASS (shell_content); - if (class->construct_searchbar != NULL) - widget = class->construct_searchbar (shell_content); - else - widget = NULL; - if (widget != NULL) { - gtk_widget_set_parent (widget, GTK_WIDGET (shell_content)); - shell_content->priv->searchbar = g_object_ref (widget); - gtk_widget_show (widget); - } - e_extensible_load_extensions (E_EXTENSIBLE (object)); } -static void -shell_content_destroy (GtkObject *gtk_object) -{ - EShellContentPrivate *priv; - - priv = E_SHELL_CONTENT_GET_PRIVATE (gtk_object); - - /* Unparent the widget before destroying it to avoid - * writing a custom GtkContainer::remove() method. */ - - if (priv->searchbar != NULL) { - gtk_widget_unparent (priv->searchbar); - gtk_widget_destroy (priv->searchbar); - g_object_unref (priv->searchbar); - priv->searchbar = NULL; - } - - /* Chain up to parent's destroy() method. */ - GTK_OBJECT_CLASS (e_shell_content_parent_class)->destroy (gtk_object); -} - static void shell_content_size_request (GtkWidget *widget, GtkRequisition *requisition) @@ -261,6 +227,26 @@ shell_content_size_allocate (GtkWidget *widget, gtk_widget_size_allocate (child, &child_allocation); } +static void +shell_content_remove (GtkContainer *container, + GtkWidget *widget) +{ + GtkContainerClass *container_class; + EShellContentPrivate *priv; + + priv = E_SHELL_CONTENT_GET_PRIVATE (container); + + if (widget == priv->searchbar) { + gtk_widget_unparent (priv->searchbar); + priv->searchbar = NULL; + return; + } + + /* Chain up to parent's remove() method. */ + container_class = GTK_CONTAINER_CLASS (e_shell_content_parent_class); + container_class->remove (container, widget); +} + static void shell_content_forall (GtkContainer *container, gboolean include_internals, @@ -280,43 +266,10 @@ shell_content_forall (GtkContainer *container, container, include_internals, callback, callback_data); } -static gchar * -shell_content_get_search_name (EShellContent *shell_content) -{ - EShellSearchbar *searchbar; - EShellView *shell_view; - EFilterRule *rule; - const gchar *search_text; - - shell_view = e_shell_content_get_shell_view (shell_content); - - rule = e_shell_view_get_search_rule (shell_view); - g_return_val_if_fail (E_IS_FILTER_RULE (rule), NULL); - - searchbar = E_SHELL_SEARCHBAR (shell_content->priv->searchbar); - search_text = e_shell_searchbar_get_search_text (searchbar); - - if (search_text == NULL || *search_text == '\0') - search_text = "''"; - - return g_strdup_printf ("%s %s", rule->name, search_text); -} - -static GtkWidget * -shell_content_construct_searchbar (EShellContent *shell_content) -{ - EShellView *shell_view; - - shell_view = e_shell_content_get_shell_view (shell_content); - - return e_shell_searchbar_new (shell_view); -} - static void e_shell_content_class_init (EShellContentClass *class) { GObjectClass *object_class; - GtkObjectClass *gtk_object_class; GtkWidgetClass *widget_class; GtkContainerClass *container_class; @@ -328,19 +281,14 @@ e_shell_content_class_init (EShellContentClass *class) object_class->dispose = shell_content_dispose; object_class->constructed = shell_content_constructed; - gtk_object_class = GTK_OBJECT_CLASS (class); - gtk_object_class->destroy = shell_content_destroy; - widget_class = GTK_WIDGET_CLASS (class); widget_class->size_request = shell_content_size_request; widget_class->size_allocate = shell_content_size_allocate; container_class = GTK_CONTAINER_CLASS (class); + container_class->remove = shell_content_remove; container_class->forall = shell_content_forall; - class->get_search_name = shell_content_get_search_name; - class->construct_searchbar = shell_content_construct_searchbar; - /** * EShellContent:shell-view * @@ -384,21 +332,34 @@ e_shell_content_new (EShellView *shell_view) } /** - * e_shell_content_get_searchbar: + * e_shell_content_set_searchbar: * @shell_content: an #EShellContent + * @searchbar: a #GtkWidget, or %NULL * - * Returns the search bar widget returned by the - * construct_searchbar method in - * #EShellContentClass. - * - * Returns: the search bar widget + * Packs @searchbar at the top of @shell_content. **/ -GtkWidget * -e_shell_content_get_searchbar (EShellContent *shell_content) +void +e_shell_content_set_searchbar (EShellContent *shell_content, + GtkWidget *searchbar) { - g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL); + g_return_if_fail (E_IS_SHELL_CONTENT (shell_content)); + + if (searchbar != NULL) { + g_return_if_fail (GTK_IS_WIDGET (searchbar)); + g_object_ref_sink (searchbar); + } + + if (shell_content->priv->searchbar != NULL) + gtk_container_remove ( + GTK_CONTAINER (shell_content), + shell_content->priv->searchbar); + + shell_content->priv->searchbar = searchbar; - return shell_content->priv->searchbar; + if (searchbar != NULL) + gtk_widget_set_parent (searchbar, GTK_WIDGET (shell_content)); + + gtk_widget_queue_resize (GTK_WIDGET (shell_content)); } /** @@ -443,29 +404,6 @@ e_shell_content_get_shell_view (EShellContent *shell_content) return E_SHELL_VIEW (shell_content->priv->shell_view); } -/** - * e_shell_content_get_search_name: - * @shell_content: an #EShellContent - * - * Returns a newly-allocated string containing a suitable name for the - * current search criteria. This is used as the suggested name in the - * Save Search dialog. Free the returned string with g_free(). - * - * Returns: a name for the current search criteria - **/ -gchar * -e_shell_content_get_search_name (EShellContent *shell_content) -{ - EShellContentClass *class; - - g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL); - - class = E_SHELL_CONTENT_GET_CLASS (shell_content); - g_return_val_if_fail (class->get_search_name != NULL, NULL); - - return class->get_search_name (shell_content); -} - void e_shell_content_run_advanced_search_dialog (EShellContent *shell_content) { @@ -591,7 +529,7 @@ e_shell_content_run_save_search_dialog (EShellContent *shell_content) g_return_if_fail (E_IS_FILTER_RULE (rule)); rule = e_filter_rule_clone (rule); - search_name = e_shell_content_get_search_name (shell_content); + search_name = e_shell_view_get_search_name (shell_view); e_filter_rule_set_name (rule, search_name); g_free (search_name); diff --git a/shell/e-shell-content.h b/shell/e-shell-content.h index 7a852145e4..e6a11291a7 100644 --- a/shell/e-shell-content.h +++ b/shell/e-shell-content.h @@ -68,22 +68,18 @@ struct _EShellContentClass { /* Methods */ guint32 (*check_state) (EShellContent *shell_content); - gchar * (*get_search_name) (EShellContent *shell_content); - - /* This is a protected method. Not for public use. */ - GtkWidget * (*construct_searchbar) (EShellContent *shell_content); }; GType e_shell_content_get_type (void); GtkWidget * e_shell_content_new (struct _EShellView *shell_view); -GtkWidget * e_shell_content_get_searchbar (EShellContent *shell_content); +void e_shell_content_set_searchbar (EShellContent *shell_content, + GtkWidget *searchbar); guint32 e_shell_content_check_state (EShellContent *shell_content); struct _EShellView * e_shell_content_get_shell_view (EShellContent *shell_content); const gchar * e_shell_content_get_view_id (EShellContent *shell_content); void e_shell_content_set_view_id (EShellContent *shell_content, const gchar *view_id); -gchar * e_shell_content_get_search_name (EShellContent *shell_content); void e_shell_content_run_advanced_search_dialog (EShellContent *shell_content); void e_shell_content_run_edit_searches_dialog diff --git a/shell/e-shell-searchbar.c b/shell/e-shell-searchbar.c index 0cfe16ca64..940bd9fd6b 100644 --- a/shell/e-shell-searchbar.c +++ b/shell/e-shell-searchbar.c @@ -67,8 +67,9 @@ struct _EShellSearchbarPrivate { /* State Key File */ gchar *state_group; + guint express_mode : 1; guint filter_visible : 1; - guint label_visible : 1; + guint labels_visible : 1; guint search_visible : 1; guint scope_visible : 1; guint state_dirty : 1; @@ -76,9 +77,10 @@ struct _EShellSearchbarPrivate { enum { PROP_0, + PROP_EXPRESS_MODE, PROP_FILTER_COMBO_BOX, PROP_FILTER_VISIBLE, - PROP_LABEL_VISIBLE, + PROP_LABELS_VISIBLE, PROP_SEARCH_HINT, PROP_SEARCH_OPTION, PROP_SEARCH_TEXT, @@ -472,14 +474,20 @@ shell_searchbar_set_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_EXPRESS_MODE: + e_shell_searchbar_set_express_mode ( + E_SHELL_SEARCHBAR (object), + g_value_get_boolean (value)); + return; + case PROP_FILTER_VISIBLE: e_shell_searchbar_set_filter_visible ( E_SHELL_SEARCHBAR (object), g_value_get_boolean (value)); return; - case PROP_LABEL_VISIBLE: - e_shell_searchbar_set_label_visible ( + case PROP_LABELS_VISIBLE: + e_shell_searchbar_set_labels_visible ( E_SHELL_SEARCHBAR (object), g_value_get_boolean (value)); return; @@ -537,15 +545,21 @@ shell_searchbar_get_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_EXPRESS_MODE: + g_value_set_boolean ( + value, e_shell_searchbar_get_express_mode ( + E_SHELL_SEARCHBAR (object))); + return; + case PROP_FILTER_COMBO_BOX: g_value_set_object ( value, e_shell_searchbar_get_filter_combo_box ( E_SHELL_SEARCHBAR (object))); return; - case PROP_LABEL_VISIBLE: + case PROP_LABELS_VISIBLE: g_value_set_boolean ( - value, e_shell_searchbar_get_label_visible ( + value, e_shell_searchbar_get_labels_visible ( E_SHELL_SEARCHBAR (object))); return; @@ -735,6 +749,17 @@ e_shell_searchbar_class_init (EShellSearchbarClass *class) widget_class = GTK_WIDGET_CLASS (class); widget_class->map = shell_searchbar_map; + g_object_class_install_property ( + object_class, + PROP_EXPRESS_MODE, + g_param_spec_boolean ( + "express-mode", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + g_object_class_install_property ( object_class, PROP_FILTER_COMBO_BOX, @@ -747,9 +772,9 @@ e_shell_searchbar_class_init (EShellSearchbarClass *class) g_object_class_install_property ( object_class, - PROP_LABEL_VISIBLE, + PROP_LABELS_VISIBLE, g_param_spec_boolean ( - "label-visible", + "labels-visible", NULL, NULL, TRUE, @@ -894,6 +919,10 @@ e_shell_searchbar_init (EShellSearchbar *searchbar) gtk_box_pack_start (box, widget, FALSE, FALSE, 0); gtk_widget_show (widget); + e_binding_new ( + searchbar, "labels-visible", + widget, "visible"); + label = GTK_LABEL (widget); widget = e_action_combo_box_new (); @@ -921,11 +950,12 @@ e_shell_searchbar_init (EShellSearchbar *searchbar) gtk_box_pack_start (box, widget, FALSE, FALSE, 0); gtk_widget_show (widget); - label = GTK_LABEL (widget); e_binding_new ( - searchbar, "label-visible", + searchbar, "labels-visible", widget, "visible"); + label = GTK_LABEL (widget); + widget = e_hinted_entry_new (); gtk_label_set_mnemonic_widget (label, widget); gtk_box_pack_start (box, widget, TRUE, TRUE, 0); @@ -1032,6 +1062,31 @@ e_shell_searchbar_get_shell_view (EShellSearchbar *searchbar) return E_SHELL_VIEW (searchbar->priv->shell_view); } +gboolean +e_shell_searchbar_get_express_mode (EShellSearchbar *searchbar) +{ + g_return_val_if_fail (E_IS_SHELL_SEARCHBAR (searchbar), FALSE); + + return searchbar->priv->express_mode; +} + +void +e_shell_searchbar_set_express_mode (EShellSearchbar *searchbar, + gboolean express_mode) +{ + g_return_if_fail (E_IS_SHELL_SEARCHBAR (searchbar)); + + searchbar->priv->express_mode = express_mode; + + /* Emit "notify" on all the properties we override. */ + g_object_freeze_notify (G_OBJECT (searchbar)); + g_object_notify (G_OBJECT (searchbar), "express-mode"); + g_object_notify (G_OBJECT (searchbar), "labels-visible"); + g_object_notify (G_OBJECT (searchbar), "filter-visible"); + g_object_notify (G_OBJECT (searchbar), "scope-visible"); + g_object_thaw_notify (G_OBJECT (searchbar)); +} + EActionComboBox * e_shell_searchbar_get_filter_combo_box (EShellSearchbar *searchbar) { @@ -1041,22 +1096,26 @@ e_shell_searchbar_get_filter_combo_box (EShellSearchbar *searchbar) } gboolean -e_shell_searchbar_get_label_visible (EShellSearchbar *searchbar) +e_shell_searchbar_get_labels_visible (EShellSearchbar *searchbar) { g_return_val_if_fail (E_IS_SHELL_SEARCHBAR (searchbar), FALSE); - return searchbar->priv->label_visible; + /* Express mode overrides this. */ + if (e_shell_searchbar_get_express_mode (searchbar)) + return FALSE; + + return searchbar->priv->labels_visible; } void -e_shell_searchbar_set_label_visible (EShellSearchbar *searchbar, - gboolean label_visible) +e_shell_searchbar_set_labels_visible (EShellSearchbar *searchbar, + gboolean labels_visible) { g_return_if_fail (E_IS_SHELL_SEARCHBAR (searchbar)); - searchbar->priv->label_visible = label_visible; + searchbar->priv->labels_visible = labels_visible; - g_object_notify (G_OBJECT (searchbar), "label-visible"); + g_object_notify (G_OBJECT (searchbar), "labels-visible"); } gboolean @@ -1064,6 +1123,10 @@ e_shell_searchbar_get_filter_visible (EShellSearchbar *searchbar) { g_return_val_if_fail (E_IS_SHELL_SEARCHBAR (searchbar), FALSE); + /* Express mode overrides this. */ + if (e_shell_searchbar_get_express_mode (searchbar)) + return FALSE; + return searchbar->priv->filter_visible; } @@ -1204,6 +1267,10 @@ e_shell_searchbar_get_scope_visible (EShellSearchbar *searchbar) { g_return_val_if_fail (E_IS_SHELL_SEARCHBAR (searchbar), FALSE); + /* Express mode overrides this. */ + if (e_shell_searchbar_get_express_mode (searchbar)) + return FALSE; + return searchbar->priv->scope_visible; } @@ -1257,6 +1324,7 @@ e_shell_searchbar_load_state (EShellSearchbar *searchbar) GKeyFile *key_file; GtkAction *action; GtkWidget *widget; + gboolean express_mode; const gchar *search_text; const gchar *state_group; const gchar *key; @@ -1272,6 +1340,8 @@ e_shell_searchbar_load_state (EShellSearchbar *searchbar) key_file = e_shell_view_get_state_key_file (shell_view); shell_window = e_shell_view_get_shell_window (shell_view); + express_mode = e_shell_searchbar_get_express_mode (searchbar); + /* Changing the combo boxes triggers searches, so block * the search action until the state is fully restored. */ action = E_SHELL_WINDOW_ACTION_SEARCH_QUICK (shell_window); @@ -1283,7 +1353,7 @@ e_shell_searchbar_load_state (EShellSearchbar *searchbar) key = STATE_KEY_SEARCH_FILTER; string = g_key_file_get_string (key_file, state_group, key, NULL); - if (string != NULL && *string != '\0') + if (string != NULL && *string != '\0' && !express_mode) action = e_shell_window_get_action (shell_window, string); else action = NULL; @@ -1328,7 +1398,7 @@ e_shell_searchbar_load_state (EShellSearchbar *searchbar) key = STATE_KEY_SEARCH_SCOPE; string = g_key_file_get_string (key_file, state_group, key, NULL); - if (string != NULL && *string != '\0') + if (string != NULL && *string != '\0' && !express_mode) action = e_shell_window_get_action (shell_window, string); else action = NULL; diff --git a/shell/e-shell-searchbar.h b/shell/e-shell-searchbar.h index 77860cdfdb..84049e99e0 100644 --- a/shell/e-shell-searchbar.h +++ b/shell/e-shell-searchbar.h @@ -69,6 +69,11 @@ struct _EShellSearchbarClass { GType e_shell_searchbar_get_type (void); GtkWidget * e_shell_searchbar_new (EShellView *shell_view); EShellView * e_shell_searchbar_get_shell_view(EShellSearchbar *searchbar); +gboolean e_shell_searchbar_get_express_mode + (EShellSearchbar *searchbar); +void e_shell_searchbar_set_express_mode + (EShellSearchbar *searchbar, + gboolean express_mode); EActionComboBox * e_shell_searchbar_get_filter_combo_box (EShellSearchbar *searchbar); @@ -77,11 +82,11 @@ gboolean e_shell_searchbar_get_filter_visible void e_shell_searchbar_set_filter_visible (EShellSearchbar *searchbar, gboolean filter_visible); -gboolean e_shell_searchbar_get_label_visible +gboolean e_shell_searchbar_get_labels_visible (EShellSearchbar *searchbar); -void e_shell_searchbar_set_label_visible +void e_shell_searchbar_set_labels_visible (EShellSearchbar *searchbar, - gboolean label_visible); + gboolean labels_visible); const gchar * e_shell_searchbar_get_search_hint (EShellSearchbar *searchbar); void e_shell_searchbar_set_search_hint diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c index 6463e847d4..51ad7dd2d0 100644 --- a/shell/e-shell-view.c +++ b/shell/e-shell-view.c @@ -30,6 +30,7 @@ #include #include +#include "e-util/e-binding.h" #include "e-util/e-extensible.h" #include "e-util/e-file-utils.h" #include "e-util/e-plugin-ui.h" @@ -38,12 +39,14 @@ #include "e-util/e-util.h" #include "filter/e-rule-context.h" +#include "e-shell-searchbar.h" #include "e-shell-window-actions.h" #define E_SHELL_VIEW_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_SHELL_VIEW, EShellViewPrivate)) +#define SIMPLE_SEARCHBAR_WIDTH 300 #define STATE_SAVE_TIMEOUT_SECONDS 3 struct _EShellViewPrivate { @@ -64,6 +67,7 @@ struct _EShellViewPrivate { GtkWidget *shell_content; GtkWidget *shell_sidebar; GtkWidget *shell_taskbar; + GtkWidget *searchbar; EFilterRule *search_rule; guint execute_search_blocked; @@ -73,6 +77,7 @@ enum { PROP_0, PROP_ACTION, PROP_PAGE_NUM, + PROP_SEARCHBAR, PROP_SEARCH_RULE, PROP_SHELL_BACKEND, PROP_SHELL_CONTENT, @@ -349,8 +354,9 @@ shell_view_set_action (EShellView *shell_view, static void shell_view_set_shell_window (EShellView *shell_view, - GtkWidget *shell_window) + EShellWindow *shell_window) { + g_return_if_fail (E_IS_SHELL_WINDOW (shell_window)); g_return_if_fail (shell_view->priv->shell_window == NULL); shell_view->priv->shell_window = shell_window; @@ -426,6 +432,12 @@ shell_view_get_property (GObject *object, E_SHELL_VIEW (object))); return; + case PROP_SEARCHBAR: + g_value_set_object ( + value, e_shell_view_get_searchbar ( + E_SHELL_VIEW (object))); + return; + case PROP_SEARCH_RULE: g_value_set_object ( value, e_shell_view_get_search_rule ( @@ -526,6 +538,11 @@ shell_view_dispose (GObject *object) priv->shell_taskbar = NULL; } + if (priv->searchbar != NULL) { + g_object_unref (priv->searchbar); + priv->searchbar = NULL; + } + if (priv->search_rule != NULL) { g_object_unref (priv->search_rule); priv->search_rule = NULL; @@ -579,6 +596,11 @@ shell_view_constructed (GObject *object) shell_view->priv->shell_sidebar = g_object_ref_sink (widget); gtk_widget_show (widget); + if (shell_view_class->construct_searchbar != NULL) { + widget = shell_view_class->construct_searchbar (shell_view); + shell_view->priv->searchbar = g_object_ref_sink (widget); + } + /* Size group should be safe to unreference now. */ g_object_unref (shell_view->priv->size_group); shell_view->priv->size_group = NULL; @@ -586,6 +608,76 @@ shell_view_constructed (GObject *object) e_extensible_load_extensions (E_EXTENSIBLE (object)); } +static GtkWidget * +shell_view_construct_searchbar (EShellView *shell_view) +{ + EShell *shell; + EShellWindow *shell_window; + EShellContent *shell_content; + EShellSearchbar *shell_searchbar; + GtkToolItem *item; + GtkAction *action; + GtkWidget *main_toolbar; + GtkWidget *widget; + + shell_content = e_shell_view_get_shell_content (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); + shell = e_shell_window_get_shell (shell_window); + + widget = e_shell_searchbar_new (shell_view); + + /* In normal mode, we hand the searchbar off to EShellContent. */ + if (!e_shell_get_express_mode (shell)) { + e_shell_content_set_searchbar (shell_content, widget); + gtk_widget_show (widget); + return widget; + } + + /* Express mode is more complicated. We append a heavily simplified + * version of it to the main toolbar, but only show it when this shell + * view is active. So each view still gets its own searchbar. */ + + shell_searchbar = E_SHELL_SEARCHBAR (widget); + e_shell_searchbar_set_express_mode (shell_searchbar, TRUE); + + /* XXX Hardcoded sizes are evil, but what should the width be + * relative to. Window width? The other toolbar width? */ + gtk_widget_set_size_request (widget, SIMPLE_SEARCHBAR_WIDTH, -1); + + main_toolbar = e_shell_window_get_managed_widget ( + shell_window, "/search-toolbar"); + + item = gtk_tool_item_new (); + gtk_container_add (GTK_CONTAINER (item), widget); + gtk_widget_show (GTK_WIDGET (item)); + + action = e_shell_view_get_action (shell_view); + e_binding_new (action, "active", widget, "visible"); + + gtk_toolbar_insert (GTK_TOOLBAR (main_toolbar), item, -1); + + return widget; +} + +static gchar * +shell_view_get_search_name (EShellView *shell_view) +{ + EShellSearchbar *searchbar; + EFilterRule *rule; + const gchar *search_text; + + rule = e_shell_view_get_search_rule (shell_view); + g_return_val_if_fail (E_IS_FILTER_RULE (rule), NULL); + + searchbar = E_SHELL_SEARCHBAR (shell_view->priv->searchbar); + search_text = e_shell_searchbar_get_search_text (searchbar); + + if (search_text == NULL || *search_text == '\0') + search_text = "''"; + + return g_strdup_printf ("%s %s", rule->name, search_text); +} + static void shell_view_toggled (EShellView *shell_view) { @@ -666,6 +758,9 @@ shell_view_class_init (EShellViewClass *class) class->new_shell_sidebar = e_shell_sidebar_new; class->new_shell_taskbar = e_shell_taskbar_new; + class->construct_searchbar = shell_view_construct_searchbar; + class->get_search_name = shell_view_get_search_name; + class->toggled = shell_view_toggled; class->clear_search = shell_view_clear_search; class->custom_search = shell_view_custom_search; @@ -1212,6 +1307,29 @@ e_shell_view_set_page_num (EShellView *shell_view, g_object_notify (G_OBJECT (shell_view), "page-num"); } +/** + * e_shell_view_get_search_name: + * @shell_view: an #EShellView + * + * Returns a newly-allocated string containing a suitable name for the + * current search criteria. This is used as the suggested name in the + * Save Search dialog. Free the returned string with g_free(). + * + * Returns: a name for the current search criteria + **/ +gchar * +e_shell_view_get_search_name (EShellView *shell_view) +{ + EShellViewClass *class; + + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + class = E_SHELL_VIEW_GET_CLASS (shell_view); + g_return_val_if_fail (class->get_search_name != NULL, NULL); + + return class->get_search_name (shell_view); +} + /** * e_shell_view_get_search_rule: * @shell_view: an #EShellView @@ -1228,6 +1346,20 @@ e_shell_view_get_search_rule (EShellView *shell_view) return shell_view->priv->search_rule; } +/** + * e_shell_view_get_searchbar: + * @shell_view: an #EShellView + * + * Returns the searchbar widget for @shell_view. + **/ +GtkWidget * +e_shell_view_get_searchbar (EShellView *shell_view) +{ + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + return shell_view->priv->searchbar; +} + /** * e_shell_view_set_search_rule: * @shell_view: an #EShellView diff --git a/shell/e-shell-view.h b/shell/e-shell-view.h index 1c24556b8f..2cf2136693 100644 --- a/shell/e-shell-view.h +++ b/shell/e-shell-view.h @@ -166,6 +166,10 @@ struct _EShellViewClass { GtkWidget * (*new_shell_sidebar) (EShellView *shell_view); GtkWidget * (*new_shell_taskbar) (EShellView *shell_view); + /* Create, configure and pack a search bar widget. */ + GtkWidget * (*construct_searchbar) (EShellView *shell_view); + gchar * (*get_search_name) (EShellView *shell_view); + /* Signals */ void (*toggled) (EShellView *shell_view); void (*clear_search) (EShellView *shell_view); @@ -188,6 +192,8 @@ gboolean e_shell_view_is_active (EShellView *shell_view); gint e_shell_view_get_page_num (EShellView *shell_view); void e_shell_view_set_page_num (EShellView *shell_view, gint page_num); +GtkWidget * e_shell_view_get_searchbar (EShellView *shell_view); +gchar * e_shell_view_get_search_name (EShellView *shell_view); EFilterRule * e_shell_view_get_search_rule (EShellView *shell_view); void e_shell_view_set_search_rule (EShellView *shell_view, EFilterRule *search_rule); diff --git a/shell/e-shell-window-private.c b/shell/e-shell-window-private.c index faccac8052..47706637ab 100644 --- a/shell/e-shell-window-private.c +++ b/shell/e-shell-window-private.c @@ -300,7 +300,6 @@ e_shell_window_private_constructed (EShellWindow *shell_window) merge_id = gtk_ui_manager_new_merge_id (ui_manager); priv->gal_view_merge_id = merge_id; - /* Construct window widgets. */ widget = gtk_vbox_new (FALSE, 0); diff --git a/shell/e-shell-window.c b/shell/e-shell-window.c index d09926b355..f6176c1a35 100644 --- a/shell/e-shell-window.c +++ b/shell/e-shell-window.c @@ -349,17 +349,21 @@ static GtkWidget * shell_window_construct_toolbar (EShellWindow *shell_window) { GtkUIManager *ui_manager; - GtkWidget *main_toolbar; + GtkWidget *toolbar; + GtkWidget *box; GtkToolItem *item; ui_manager = e_shell_window_get_ui_manager (shell_window); - main_toolbar = e_shell_window_get_managed_widget ( - shell_window, "/main-toolbar"); + box = gtk_hbox_new (FALSE, 0); + gtk_widget_show (box); e_binding_new ( shell_window, "toolbar-visible", - main_toolbar, "visible"); + box, "visible"); + + toolbar = e_shell_window_get_managed_widget ( + shell_window, "/main-toolbar"); /* XXX Having this separator in the UI definition doesn't work * because GtkUIManager is unaware of the "New" button, so @@ -372,7 +376,7 @@ shell_window_construct_toolbar (EShellWindow *shell_window) * convinced having it proxy some new type of GtkAction * is worth the extra effort. */ item = gtk_separator_tool_item_new (); - gtk_toolbar_insert (GTK_TOOLBAR (main_toolbar), item, 0); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, 0); gtk_widget_show (GTK_WIDGET (item)); item = e_menu_tool_button_new (_("New")); @@ -381,7 +385,7 @@ shell_window_construct_toolbar (EShellWindow *shell_window) GTK_WIDGET (item), "clicked", gtk_ui_manager_get_accel_group (ui_manager), GDK_N, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE); - gtk_toolbar_insert (GTK_TOOLBAR (main_toolbar), item, 0); + gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, 0); gtk_widget_show (GTK_WIDGET (item)); g_signal_connect ( @@ -389,7 +393,14 @@ shell_window_construct_toolbar (EShellWindow *shell_window) G_CALLBACK (shell_window_toolbar_update_new_menu), GTK_MENU_TOOL_BUTTON (item)); - return main_toolbar; + gtk_box_pack_start (GTK_BOX (box), toolbar, TRUE, TRUE, 0); + + toolbar = e_shell_window_get_managed_widget ( + shell_window, "/search-toolbar"); + gtk_toolbar_set_show_arrow (GTK_TOOLBAR (toolbar), FALSE); + gtk_box_pack_start (GTK_BOX (box), toolbar, FALSE, FALSE, 0); + + return box; } static GtkWidget * -- cgit v1.2.3