diff options
-rw-r--r-- | doc/reference/evolution-shell/evolution-shell-sections.txt | 2 | ||||
-rw-r--r-- | shell/e-shell-searchbar.c | 318 | ||||
-rw-r--r-- | shell/e-shell-searchbar.h | 9 | ||||
-rw-r--r-- | shell/e-shell-window-private.h | 1 | ||||
-rw-r--r-- | shell/e-shell-window.c | 57 |
5 files changed, 150 insertions, 237 deletions
diff --git a/doc/reference/evolution-shell/evolution-shell-sections.txt b/doc/reference/evolution-shell/evolution-shell-sections.txt index 80d7752f14..0fbe973792 100644 --- a/doc/reference/evolution-shell/evolution-shell-sections.txt +++ b/doc/reference/evolution-shell/evolution-shell-sections.txt @@ -105,6 +105,8 @@ EShellSearchbar e_shell_searchbar_new e_shell_searchbar_get_shell_view e_shell_searchbar_get_filter_combo_box +e_shell_searchbar_get_filter_visible +e_shell_searchbar_set_filter_visible e_shell_searchbar_get_search_hint e_shell_searchbar_set_search_hint e_shell_searchbar_get_search_option diff --git a/shell/e-shell-searchbar.c b/shell/e-shell-searchbar.c index cb04b56e92..9f6adebbcf 100644 --- a/shell/e-shell-searchbar.c +++ b/shell/e-shell-searchbar.c @@ -40,9 +40,6 @@ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_SHELL_SEARCHBAR, EShellSearchbarPrivate)) -/* spacing between "groups" on the search bar */ -#define COLUMN_SPACING 24 - #define SEARCH_OPTION_ADVANCED (-1) /* Default "state key file" group: [Search Bar] */ @@ -68,11 +65,11 @@ struct _EShellSearchbarPrivate { /* Child widget containers (referenced) */ GQueue child_containers; - guint resize_idle_id; /* State Key File */ gchar *state_group; + gboolean filter_visible; gboolean scope_visible; gboolean state_dirty; }; @@ -80,6 +77,7 @@ struct _EShellSearchbarPrivate { enum { PROP_0, PROP_FILTER_COMBO_BOX, + PROP_FILTER_VISIBLE, PROP_SEARCH_HINT, PROP_SEARCH_OPTION, PROP_SEARCH_TEXT, @@ -92,7 +90,7 @@ enum { G_DEFINE_TYPE_WITH_CODE ( EShellSearchbar, e_shell_searchbar, - GTK_TYPE_GRID, + GTK_TYPE_BOX, G_IMPLEMENT_INTERFACE ( E_TYPE_EXTENSIBLE, NULL)) @@ -491,125 +489,6 @@ shell_searchbar_option_changed_cb (GtkRadioAction *action, } static gboolean -shell_searchbar_resize_idle_cb (gpointer user_data) -{ - GtkWidget *widget; - EShellSearchbar *searchbar; - GQueue *child_containers; - GList *head, *link; - GArray *widths; - gint row = 0; - gint column = 0; - gint roww = 0; - gint maxw = 0; - gint child_left; - gint child_top; - gint allocated_width; - gboolean needs_reposition = FALSE; - - widget = GTK_WIDGET (user_data); - allocated_width = gtk_widget_get_allocated_width (widget); - - searchbar = E_SHELL_SEARCHBAR (widget); - child_containers = &searchbar->priv->child_containers; - head = g_queue_peek_head_link (child_containers); - - widths = g_array_new (FALSE, FALSE, sizeof (gint)); - - for (link = head; link != NULL; link = g_list_next (link)) { - GtkWidget *child = GTK_WIDGET (link->data); - gint minw = -1; - - if (!gtk_widget_get_visible (child)) - minw = 0; - else - gtk_widget_get_preferred_width (child, &minw, NULL); - - g_array_append_val (widths, minw); - - if (roww && minw) { - roww += COLUMN_SPACING; - column++; - } - - roww += minw; - - if (minw > maxw) - maxw = minw; - - if (roww > allocated_width) { - row++; - roww = minw; - column = 0; - } - - gtk_container_child_get ( - GTK_CONTAINER (widget), child, - "left-attach", &child_left, - "top-attach", &child_top, - NULL); - - needs_reposition |= - (child_left != column) || - (child_top != row); - - if (column == 0 && row > 0 && roww < maxw) { - /* Columns have the same width, so use - * the wider widget for calculations. */ - roww = maxw; - } - } - - if (needs_reposition) { - guint ii = 0; - - row = 0; - column = 0; - roww = 0; - - g_warn_if_fail (child_containers->length == widths->len); - - for (link = head; link != NULL; link = g_list_next (link)) - gtk_container_remove ( - GTK_CONTAINER (widget), - GTK_WIDGET (link->data)); - - for (link = head; link != NULL; link = g_list_next (link)) { - GtkWidget *child; - gint w; - - child = GTK_WIDGET (link->data); - w = g_array_index (widths, gint, ii++); - - if (roww && w) { - roww += COLUMN_SPACING; - column++; - } - - roww += w; - - if (roww > allocated_width) { - row++; - roww = w; - column = 0; - } - - gtk_grid_attach ( - GTK_GRID (widget), child, column, row, 1, 1); - - if (column == 0 && row > 0 && roww < maxw) - roww = maxw; - } - } - - g_array_free (widths, TRUE); - - searchbar->priv->resize_idle_id = 0; - - return FALSE; -} - -static gboolean shell_searchbar_entry_focus_in_cb (GtkWidget *entry, GdkEvent *event, EShellSearchbar *searchbar) @@ -650,6 +529,12 @@ shell_searchbar_set_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_FILTER_VISIBLE: + e_shell_searchbar_set_filter_visible ( + E_SHELL_SEARCHBAR (object), + g_value_get_boolean (value)); + return; + case PROP_SEARCH_HINT: e_shell_searchbar_set_search_hint ( E_SHELL_SEARCHBAR (object), @@ -703,6 +588,12 @@ shell_searchbar_get_property (GObject *object, E_SHELL_SEARCHBAR (object))); return; + case PROP_FILTER_VISIBLE: + g_value_set_boolean ( + value, e_shell_searchbar_get_filter_visible ( + E_SHELL_SEARCHBAR (object))); + return; + case PROP_SEARCH_HINT: g_value_set_string ( value, e_shell_searchbar_get_search_hint ( @@ -756,11 +647,6 @@ shell_searchbar_dispose (GObject *object) priv = E_SHELL_SEARCHBAR_GET_PRIVATE (object); - if (priv->resize_idle_id > 0) { - g_source_remove (priv->resize_idle_id); - priv->resize_idle_id = 0; - } - if (priv->shell_view != NULL) { g_object_remove_weak_pointer ( G_OBJECT (priv->shell_view), &priv->shell_view); @@ -776,9 +662,6 @@ shell_searchbar_dispose (GObject *object) g_clear_object (&priv->css_provider); - while (!g_queue_is_empty (&priv->child_containers)) - g_object_unref (g_queue_pop_head (&priv->child_containers)); - /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (e_shell_searchbar_parent_class)->dispose (object); } @@ -895,51 +778,6 @@ shell_searchbar_map (GtkWidget *widget) } static void -shell_searchbar_size_allocate (GtkWidget *widget, - GdkRectangle *allocation) -{ - EShellSearchbarPrivate *priv; - - priv = E_SHELL_SEARCHBAR_GET_PRIVATE (widget); - - /* Chain up to parent's size_allocate() method. */ - GTK_WIDGET_CLASS (e_shell_searchbar_parent_class)-> - size_allocate (widget, allocation); - - if (priv->resize_idle_id == 0) - priv->resize_idle_id = g_idle_add ( - shell_searchbar_resize_idle_cb, widget); -} - -static void -shell_searchbar_get_preferred_width (GtkWidget *widget, - gint *minimum_width, - gint *natural_width) -{ - GList *children, *iter; - gint max_minimum = 0, max_natural = 0; - - children = gtk_container_get_children (GTK_CONTAINER (widget)); - for (iter = children; iter != NULL; iter = iter->next) { - GtkWidget *child = iter->data; - gint minimum = 0, natural = 0; - - if (gtk_widget_get_visible (child)) { - gtk_widget_get_preferred_width (child, &minimum, &natural); - if (minimum > max_minimum) - max_minimum = minimum; - if (natural > max_natural) - max_natural = natural; - } - } - - g_list_free (children); - - *minimum_width = max_minimum + COLUMN_SPACING; - *natural_width = max_natural + COLUMN_SPACING; -} - -static void e_shell_searchbar_class_init (EShellSearchbarClass *class) { GObjectClass *object_class; @@ -956,8 +794,6 @@ e_shell_searchbar_class_init (EShellSearchbarClass *class) widget_class = GTK_WIDGET_CLASS (class); widget_class->map = shell_searchbar_map; - widget_class->size_allocate = shell_searchbar_size_allocate; - widget_class->get_preferred_width = shell_searchbar_get_preferred_width; g_object_class_install_property ( object_class, @@ -972,6 +808,18 @@ e_shell_searchbar_class_init (EShellSearchbarClass *class) g_object_class_install_property ( object_class, + PROP_FILTER_VISIBLE, + g_param_spec_boolean ( + "filter-visible", + NULL, + NULL, + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property ( + object_class, PROP_SEARCH_HINT, g_param_spec_string ( "search-hint", @@ -1064,89 +912,66 @@ e_shell_searchbar_class_init (EShellSearchbarClass *class) static void e_shell_searchbar_init (EShellSearchbar *searchbar) { - GtkGrid *grid; + GtkBox *box; GtkLabel *label; GtkWidget *widget; - GQueue *child_containers; searchbar->priv = E_SHELL_SEARCHBAR_GET_PRIVATE (searchbar); - child_containers = &searchbar->priv->child_containers; - - gtk_grid_set_column_spacing (GTK_GRID (searchbar), COLUMN_SPACING); - gtk_grid_set_row_spacing (GTK_GRID (searchbar), 4); + gtk_box_set_spacing (GTK_BOX (searchbar), 6); /* Filter Combo Widgets */ - grid = GTK_GRID (searchbar); + box = GTK_BOX (searchbar); - widget = gtk_grid_new (); - g_object_set ( - G_OBJECT (widget), - "orientation", GTK_ORIENTATION_HORIZONTAL, - "border-width", 3, - "column-spacing", 3, - "valign", GTK_ALIGN_CENTER, - NULL); - gtk_grid_attach (grid, widget, 0, 0, 1, 1); - gtk_widget_show (widget); + widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); - g_queue_push_tail (child_containers, g_object_ref (widget)); + g_object_bind_property ( + searchbar, "filter-visible", + widget, "visible", + G_BINDING_SYNC_CREATE); - grid = GTK_GRID (widget); + box = GTK_BOX (widget); /* Translators: The "Show:" label precedes a combo box that * allows the user to filter the current view. Examples of * items that appear in the combo box are "Unread Messages", * "Important Messages", or "Active Appointments". */ widget = gtk_label_new_with_mnemonic (_("Sho_w:")); - gtk_grid_attach (grid, widget, 0, 0, 1, 1); + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); gtk_widget_show (widget); label = GTK_LABEL (widget); widget = e_action_combo_box_new (); gtk_label_set_mnemonic_widget (label, widget); - gtk_grid_attach (grid, widget, 1, 0, 1, 1); + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); searchbar->priv->filter_combo_box = widget; gtk_widget_show (widget); /* Search Entry Widgets */ - grid = GTK_GRID (searchbar); + box = GTK_BOX (searchbar); - widget = gtk_grid_new (); - g_object_set ( - G_OBJECT (widget), - "orientation", GTK_ORIENTATION_HORIZONTAL, - "column-spacing", 3, - "valign", GTK_ALIGN_CENTER, - "halign", GTK_ALIGN_FILL, - "hexpand", TRUE, - NULL); - gtk_grid_attach (grid, widget, 1, 0, 1, 1); + widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); + gtk_widget_set_margin_left (widget, 12); + gtk_box_pack_start (box, widget, TRUE, TRUE, 0); gtk_widget_show (widget); - g_queue_push_tail (child_containers, g_object_ref (widget)); - - grid = GTK_GRID (widget); + box = GTK_BOX (widget); /* Translators: This is part of the quick search interface. * example: Search: [_______________] in [ Current Folder ] */ widget = gtk_label_new_with_mnemonic (_("Sear_ch:")); - gtk_grid_attach (grid, widget, 0, 0, 1, 1); + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); gtk_widget_show (widget); label = GTK_LABEL (widget); widget = gtk_entry_new (); gtk_label_set_mnemonic_widget (label, widget); - g_object_set ( - G_OBJECT (widget), - "halign", GTK_ALIGN_FILL, - "hexpand", TRUE, - NULL); - gtk_grid_attach (grid, widget, 1, 0, 1, 1); + gtk_box_pack_start (box, widget, TRUE, TRUE, 0); searchbar->priv->search_entry = widget; gtk_widget_show (widget); @@ -1192,37 +1017,29 @@ e_shell_searchbar_init (EShellSearchbar *searchbar) /* Scope Combo Widgets */ - grid = GTK_GRID (searchbar); - - widget = gtk_grid_new (); - g_object_set ( - G_OBJECT (widget), - "orientation", GTK_ORIENTATION_HORIZONTAL, - "column-spacing", 3, - "valign", GTK_ALIGN_CENTER, - NULL); - gtk_grid_attach (grid, widget, 2, 0, 1, 1); + box = GTK_BOX (searchbar); - g_queue_push_tail (child_containers, g_object_ref (widget)); + widget = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3); + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); g_object_bind_property ( searchbar, "scope-visible", widget, "visible", G_BINDING_SYNC_CREATE); - grid = GTK_GRID (widget); + box = GTK_BOX (widget); /* Translators: This is part of the quick search interface. * example: Search: [_______________] in [ Current Folder ] */ widget = gtk_label_new_with_mnemonic (_("i_n")); - gtk_grid_attach (grid, widget, 0, 0, 1, 1); + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); gtk_widget_show (widget); label = GTK_LABEL (widget); widget = e_action_combo_box_new (); gtk_label_set_mnemonic_widget (label, widget); - gtk_grid_attach (grid, widget, 1, 0, 1, 1); + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); searchbar->priv->scope_combo_box = widget; gtk_widget_show (widget); @@ -1280,6 +1097,37 @@ e_shell_searchbar_get_filter_combo_box (EShellSearchbar *searchbar) return E_ACTION_COMBO_BOX (searchbar->priv->filter_combo_box); } +gboolean +e_shell_searchbar_get_filter_visible (EShellSearchbar *searchbar) +{ + g_return_val_if_fail (E_IS_SHELL_SEARCHBAR (searchbar), FALSE); + + return searchbar->priv->filter_visible; +} + +void +e_shell_searchbar_set_filter_visible (EShellSearchbar *searchbar, + gboolean filter_visible) +{ + g_return_if_fail (E_IS_SHELL_SEARCHBAR (searchbar)); + + if (searchbar->priv->filter_visible == filter_visible) + return; + + searchbar->priv->filter_visible = filter_visible; + + /* If we're hiding the filter combo box, reset it to its + * first item so that no content gets permanently hidden. */ + if (!filter_visible) { + EActionComboBox *combo_box; + + combo_box = e_shell_searchbar_get_filter_combo_box (searchbar); + gtk_combo_box_set_active (GTK_COMBO_BOX (combo_box), 0); + } + + g_object_notify (G_OBJECT (searchbar), "filter-visible"); +} + const gchar * e_shell_searchbar_get_search_hint (EShellSearchbar *searchbar) { diff --git a/shell/e-shell-searchbar.h b/shell/e-shell-searchbar.h index f8b34c2f9c..2d4ada5397 100644 --- a/shell/e-shell-searchbar.h +++ b/shell/e-shell-searchbar.h @@ -57,12 +57,12 @@ typedef struct _EShellSearchbarPrivate EShellSearchbarPrivate; * functions below. **/ struct _EShellSearchbar { - GtkGrid parent; + GtkBox parent; EShellSearchbarPrivate *priv; }; struct _EShellSearchbarClass { - GtkGridClass parent_class; + GtkBoxClass parent_class; }; GType e_shell_searchbar_get_type (void); @@ -72,6 +72,11 @@ EShellView * e_shell_searchbar_get_shell_view EActionComboBox * e_shell_searchbar_get_filter_combo_box (EShellSearchbar *searchbar); +gboolean e_shell_searchbar_get_filter_visible + (EShellSearchbar *searchbar); +void e_shell_searchbar_set_filter_visible + (EShellSearchbar *searchbar, + gboolean filter_visible); const gchar * e_shell_searchbar_get_search_hint (EShellSearchbar *searchbar); void e_shell_searchbar_set_search_hint diff --git a/shell/e-shell-window-private.h b/shell/e-shell-window-private.h index 3572bf5000..31d9b77af0 100644 --- a/shell/e-shell-window-private.h +++ b/shell/e-shell-window-private.h @@ -32,6 +32,7 @@ #include <e-shell.h> #include <e-shell-content.h> #include <e-shell-view.h> +#include <e-shell-searchbar.h> #include <e-shell-switcher.h> #include <e-shell-window-actions.h> #include <e-shell-utils.h> diff --git a/shell/e-shell-window.c b/shell/e-shell-window.c index f19af058cf..20af727664 100644 --- a/shell/e-shell-window.c +++ b/shell/e-shell-window.c @@ -172,6 +172,21 @@ shell_window_update_close_action_cb (EShellWindow *shell_window) } static void +shell_window_tweak_for_small_screen (EShellWindow *shell_window) +{ + EShellView *shell_view; + GtkWidget *shell_searchbar; + const gchar *active_view; + + active_view = e_shell_window_get_active_view (shell_window); + shell_view = e_shell_window_get_shell_view (shell_window, active_view); + shell_searchbar = e_shell_view_get_searchbar (shell_view); + + e_shell_searchbar_set_filter_visible ( + E_SHELL_SEARCHBAR (shell_searchbar), FALSE); +} + +static void shell_window_set_geometry (EShellWindow *shell_window, const gchar *geometry) { @@ -377,6 +392,40 @@ shell_window_constructed (GObject *object) } static void +shell_window_get_preferred_width (GtkWidget *widget, + gint *out_minimum_width, + gint *out_natural_width) +{ + GdkScreen *screen; + gint screen_width; + gint minimum_width = 0; + gint natural_width = 0; + gboolean tweaked = FALSE; + + screen = gtk_widget_get_screen (widget); + screen_width = gdk_screen_get_width (screen); + +try_again: + /* Chain up to parent's get_preferred_width() method. */ + GTK_WIDGET_CLASS (e_shell_window_parent_class)-> + get_preferred_width (widget, &minimum_width, &natural_width); + + if (!tweaked && minimum_width > screen_width) { + EShellWindow *shell_window; + + shell_window = E_SHELL_WINDOW (widget); + shell_window_tweak_for_small_screen (shell_window); + + tweaked = TRUE; /* prevents looping */ + + goto try_again; + } + + *out_minimum_width = minimum_width; + *out_natural_width = natural_width; +} + +static void shell_window_close_alert (EShellWindow *shell_window) { EShellView *shell_view; @@ -746,6 +795,7 @@ static void e_shell_window_class_init (EShellWindowClass *class) { GObjectClass *object_class; + GtkWidgetClass *widget_class; GtkBindingSet *binding_set; g_type_class_add_private (class, sizeof (EShellWindowPrivate)); @@ -757,6 +807,9 @@ e_shell_window_class_init (EShellWindowClass *class) object_class->finalize = shell_window_finalize; object_class->constructed = shell_window_constructed; + widget_class = GTK_WIDGET_CLASS (class); + widget_class->get_preferred_width = shell_window_get_preferred_width; + class->close_alert = shell_window_close_alert; class->construct_menubar = shell_window_construct_menubar; class->construct_toolbar = shell_window_construct_toolbar; @@ -1330,6 +1383,10 @@ e_shell_window_set_active_view (EShellWindow *shell_window, action = e_shell_view_get_action (shell_view); gtk_action_activate (action); + + /* Renegotiate the shell window size in case a newly-created + * shell view needs tweaked to accommodate a smaller screen. */ + gtk_widget_queue_resize (GTK_WIDGET (shell_window)); } /** |