[geary/wip/743960-split-header-2: 5/8] Move search entry out of header bar and into dedicated search bar



commit be224ac5610568da48bed4f981d3d2f3d67b90a6
Author: Robert Schroll <rschroll gmail com>
Date:   Sat Feb 21 21:27:59 2015 -0500

    Move search entry out of header bar and into dedicated search bar

 po/POTFILES.in                               |    1 +
 src/CMakeLists.txt                           |    1 +
 src/client/application/geary-controller.vala |   16 ++-
 src/client/components/main-toolbar.vala      |  130 ++-----------------------
 src/client/components/main-window.vala       |    8 +-
 src/client/components/search-bar.vala        |  131 ++++++++++++++++++++++++++
 6 files changed, 160 insertions(+), 127 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index ef6529f..434d83a 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -29,6 +29,7 @@ src/client/components/main-window.vala
 src/client/components/monitored-progress-bar.vala
 src/client/components/monitored-spinner.vala
 src/client/components/pill-toolbar.vala
+src/client/components/search-bar.vala
 src/client/components/status-bar.vala
 src/client/components/stock.vala
 src/client/components/stylish-webview.vala
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 78151fc..9d28574 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -335,6 +335,7 @@ client/components/main-window.vala
 client/components/monitored-progress-bar.vala
 client/components/monitored-spinner.vala
 client/components/pill-toolbar.vala
+client/components/search-bar.vala
 client/components/status-bar.vala
 client/components/stock.vala
 client/components/stylish-webview.vala
diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala
index 7a469c6..e49162e 100644
--- a/src/client/application/geary-controller.vala
+++ b/src/client/application/geary-controller.vala
@@ -52,6 +52,7 @@ public class GearyController : Geary.BaseObject {
     public const string ACTION_MOVE_MENU = "GearyMoveMenuButton";
     public const string ACTION_GEAR_MENU = "GearyGearMenuButton";
     public const string ACTION_SEARCH = "GearySearch";
+    public const string ACTION_TOGGLE_SEARCH = "GearyToggleSearch";
     
     public const string PROP_CURRENT_CONVERSATION ="current-conversations";
     
@@ -206,7 +207,7 @@ public class GearyController : Geary.BaseObject {
         main_window.folder_list.move_conversation.connect(on_move_conversation);
         main_window.main_toolbar.copy_folder_menu.folder_selected.connect(on_copy_conversation);
         main_window.main_toolbar.move_folder_menu.folder_selected.connect(on_move_conversation);
-        main_window.main_toolbar.search_text_changed.connect(on_search_text_changed);
+        main_window.search_bar.search_text_changed.connect(on_search_text_changed);
         main_window.conversation_viewer.link_selected.connect(on_link_selected);
         main_window.conversation_viewer.reply_to_message.connect(on_reply_to_message);
         main_window.conversation_viewer.reply_all_message.connect(on_reply_all_message);
@@ -479,6 +480,11 @@ public class GearyController : Geary.BaseObject {
         entries += search;
         add_accelerator("<Ctrl>S", ACTION_SEARCH);
         
+        // No callback is connected, since we bind the toggle button to the search bar visibility
+        Gtk.ActionEntry toggle_search = { ACTION_TOGGLE_SEARCH, null, null, null,
+            _("Toggle search bar"), null };
+        entries += toggle_search;
+        
         return entries;
     }
     
@@ -1161,7 +1167,7 @@ public class GearyController : Geary.BaseObject {
         cancel_inbox(account);
         
         previous_non_search_folder = null;
-        main_window.main_toolbar.set_search_text(""); // Reset search.
+        main_window.search_bar.set_search_text(""); // Reset search.
         if (current_account == account) {
             cancel_folder();
             switch_to_first_inbox(); // Switch folder.
@@ -2599,7 +2605,7 @@ public class GearyController : Geary.BaseObject {
     }
     
     private void on_search() {
-        main_window.main_toolbar.give_search_focus();
+        main_window.search_bar.give_search_focus();
     }
     
     private void on_sent(Geary.RFC822.Message rfc822) {
@@ -2761,7 +2767,7 @@ public class GearyController : Geary.BaseObject {
             cancellable_search);
         
         main_window.folder_list.set_search(folder);
-        search_text_changed(main_window.main_toolbar.search_text);
+        search_text_changed(main_window.search_bar.search_text);
     }
     
     private void on_search_text_changed(string search_text) {
@@ -2776,7 +2782,7 @@ public class GearyController : Geary.BaseObject {
     private bool on_search_timeout() {
         search_timeout_id = 0;
         
-        do_search(main_window.main_toolbar.search_text);
+        do_search(main_window.search_bar.search_text);
         
         return false;
     }
diff --git a/src/client/components/main-toolbar.vala b/src/client/components/main-toolbar.vala
index 2585d9f..42a5a1c 100644
--- a/src/client/components/main-toolbar.vala
+++ b/src/client/components/main-toolbar.vala
@@ -6,28 +6,17 @@
 
 // Draws the main toolbar.
 public class MainToolbar : Gtk.Box {
-    private const string ICON_CLEAR_NAME = "edit-clear-symbolic";
-    private const string ICON_CLEAR_RTL_NAME = "edit-clear-rtl-symbolic";
-    private const string DEFAULT_SEARCH_TEXT = _("Search");
-    
     public FolderMenu copy_folder_menu { get; private set; default = new FolderMenu(); }
     public FolderMenu move_folder_menu { get; private set; default = new FolderMenu(); }
-    public string search_text { get { return search_entry.text; } }
-    public bool search_entry_has_focus { get { return search_entry.has_focus; } }
     public string account { get; set; }
     public string folder { get; set; }
     public bool show_close_button { get; set; default = false; }
+    public bool search_open { get; set; default = false; }
     
     private PillHeaderbar folder_header;
     private PillHeaderbar conversation_header;
     private Gtk.Button archive_button;
     private Gtk.Button trash_delete_button;
-    private Gtk.SearchEntry search_entry = new Gtk.SearchEntry();
-    private Geary.ProgressMonitor? search_upgrade_progress_monitor = null;
-    private MonitoredProgressBar search_upgrade_progress_bar = new MonitoredProgressBar();
-    private Geary.Account? current_account = null;
-    
-    public signal void search_text_changed(string search_text);
     
     public MainToolbar() {
         Object(orientation: Gtk.Orientation.HORIZONTAL, spacing: 0);
@@ -46,8 +35,6 @@ public class MainToolbar : Gtk.Box {
         this.bind_property("show-close-button", conversation_header, "show-close-button",
             BindingFlags.SYNC_CREATE);
         
-        GearyApplication.instance.controller.account_selected.connect(on_account_changed);
-        
         bool rtl = get_direction() == Gtk.TextDirection.RTL;
         
         // Assemble mark menu.
@@ -68,6 +55,15 @@ public class MainToolbar : Gtk.Box {
             GearyController.ACTION_NEW_MESSAGE));
         folder_header.add_start(folder_header.create_pill_buttons(insert, false));
         
+        // Search
+        insert.clear();
+        Gtk.Button search = folder_header.create_toggle_button(
+            "preferences-system-search-symbolic", GearyController.ACTION_TOGGLE_SEARCH);
+        this.bind_property("search-open", search, "active",
+            BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
+        insert.add(search);
+        folder_header.add_end(folder_header.create_pill_buttons(insert, false));
+        
         // Reply buttons
         insert.clear();
         insert.add(conversation_header.create_toolbar_button(rtl ? "mail-reply-sender-rtl-symbolic"
@@ -105,25 +101,10 @@ public class MainToolbar : Gtk.Box {
             false));
         Gtk.Box undo = conversation_header.create_pill_buttons(insert);
         
-        // Search bar.
-        search_entry.width_chars = 28;
-        search_entry.tooltip_text = _("Search all mail in account for keywords (Ctrl+S)");
-        search_entry.changed.connect(on_search_entry_changed);
-        search_entry.key_press_event.connect(on_search_key_press);
-        on_search_entry_changed(); // set initial state
-        search_entry.has_focus = true;
-        
-        // Search upgrade progress bar.
-        search_upgrade_progress_bar.show_text = true;
-        search_upgrade_progress_bar.visible = false;
-        search_upgrade_progress_bar.no_show_all = true;
-        
         // pack_end() ordering is reversed in GtkHeaderBar in 3.12 and above
 #if !GTK_3_12
         conversation_header.add_end(archive_trash_delete);
         conversation_header.add_end(undo);
-        folder_header.add_end(search_upgrade_progress_bar);
-        folder_header.add_end(search_entry);
 #endif
         
         // Application button.  If we exported an app menu, we don't need this.
@@ -136,14 +117,10 @@ public class MainToolbar : Gtk.Box {
         
         // pack_end() ordering is reversed in GtkHeaderBar in 3.12 and above
 #if GTK_3_12
-        folder_header.add_end(search_entry);
-        folder_header.add_end(search_upgrade_progress_bar);
         conversation_header.add_end(undo);
         conversation_header.add_end(archive_trash_delete);
 #endif
         
-        set_search_placeholder_text(DEFAULT_SEARCH_TEXT);
-        
         pack_start(folder_header, false, false);
         pack_start(new Gtk.Separator(Gtk.Orientation.VERTICAL), false, false);
         pack_start(conversation_header, true, true);
@@ -158,18 +135,6 @@ public class MainToolbar : Gtk.Box {
         archive_button.visible = archive;
     }
     
-    public void set_search_text(string text) {
-        search_entry.text = text;
-    }
-    
-    public void give_search_focus() {
-        search_entry.grab_focus();
-    }
-    
-    public void set_search_placeholder_text(string placeholder) {
-        search_entry.placeholder_text = placeholder;
-    }
-    
     public void set_conversation_header(Gtk.HeaderBar header) {
         conversation_header.hide();
         header.get_style_context().add_class("titlebar");
@@ -185,80 +150,5 @@ public class MainToolbar : Gtk.Box {
         header.show_close_button = false;
         conversation_header.show();
     }
-    
-    private void on_search_entry_changed() {
-        search_text_changed(search_entry.text);
-        // Enable/disable clear button.
-        search_entry.secondary_icon_name = search_entry.text != "" ?
-            (get_direction() == Gtk.TextDirection.RTL ? ICON_CLEAR_RTL_NAME : ICON_CLEAR_NAME) : null;
-    }
-    
-    private bool on_search_key_press(Gdk.EventKey event) {
-        // Clear box if user hits escape.
-        if (Gdk.keyval_name(event.keyval) == "Escape")
-            search_entry.text = "";
-        
-        // Force search if user hits enter.
-        if (Gdk.keyval_name(event.keyval) == "Return")
-            on_search_entry_changed();
-        
-        return false;
-    }
-    
-    private void on_search_upgrade_start() {
-        // Set the progress bar's width to match the search entry's width.
-        int minimum_width = 0;
-        int natural_width = 0;
-        search_entry.get_preferred_width(out minimum_width, out natural_width);
-        search_upgrade_progress_bar.width_request = minimum_width;
-        
-        search_entry.hide();
-        search_upgrade_progress_bar.show();
-    }
-    
-    private void on_search_upgrade_finished() {
-        search_entry.show();
-        search_upgrade_progress_bar.hide();
-    }
-    
-    private void on_account_changed(Geary.Account? account) {
-        on_search_upgrade_finished(); // Reset search box.
-        
-        if (search_upgrade_progress_monitor != null) {
-            search_upgrade_progress_monitor.start.disconnect(on_search_upgrade_start);
-            search_upgrade_progress_monitor.finish.disconnect(on_search_upgrade_finished);
-            search_upgrade_progress_monitor = null;
-        }
-        
-        if (current_account != null) {
-            current_account.information.notify[Geary.AccountInformation.PROP_NICKNAME].disconnect(
-                on_nickname_changed);
-        }
-        
-        if (account != null) {
-            search_upgrade_progress_monitor = account.search_upgrade_monitor;
-            search_upgrade_progress_bar.set_progress_monitor(search_upgrade_progress_monitor);
-            
-            search_upgrade_progress_monitor.start.connect(on_search_upgrade_start);
-            search_upgrade_progress_monitor.finish.connect(on_search_upgrade_finished);
-            if (search_upgrade_progress_monitor.is_in_progress)
-                on_search_upgrade_start(); // Remove search box, we're already in progress.
-            
-            account.information.notify[Geary.AccountInformation.PROP_NICKNAME].connect(
-                on_nickname_changed);
-            
-            search_upgrade_progress_bar.text = _("Indexing %s account").printf(account.information.nickname);
-        }
-        
-        current_account = account;
-        
-        on_nickname_changed(); // Set new account name.
-    }
-    
-    private void on_nickname_changed() {
-        set_search_placeholder_text(current_account == null ||
-            GearyApplication.instance.controller.get_num_accounts() == 1 ? DEFAULT_SEARCH_TEXT :
-            _("Search %s account").printf(current_account.information.nickname));
-    }
 }
 
diff --git a/src/client/components/main-window.vala b/src/client/components/main-window.vala
index 38b9067..383f849 100644
--- a/src/client/components/main-window.vala
+++ b/src/client/components/main-window.vala
@@ -15,6 +15,7 @@ public class MainWindow : Gtk.ApplicationWindow {
     public FolderList.Tree folder_list { get; private set; default = new FolderList.Tree(); }
     public ConversationListStore conversation_list_store { get; private set; default = new 
ConversationListStore(); }
     public MainToolbar main_toolbar { get; private set; }
+    public SearchBar search_bar { get; private set; default = new SearchBar(); }
     public ConversationListView conversation_list_view  { get; private set; }
     public ConversationViewer conversation_viewer { get; private set; default = new ConversationViewer(); }
     public StatusBar status_bar { get; private set; default = new StatusBar(); }
@@ -85,6 +86,8 @@ public class MainWindow : Gtk.ApplicationWindow {
         
         // Toolbar.
         main_toolbar = new MainToolbar();
+        main_toolbar.bind_property("search-open", search_bar, "search-mode-enabled",
+            BindingFlags.SYNC_CREATE | BindingFlags.BIDIRECTIONAL);
         if (!GearyApplication.instance.is_running_unity) {
             main_toolbar.show_close_button = true;
             set_titlebar(main_toolbar);
@@ -247,6 +250,7 @@ public class MainWindow : Gtk.ApplicationWindow {
         folder_paned.pack2(conversation_frame, true, false);
         
         Gtk.Box status_bar_box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
+        status_bar_box.pack_start(search_bar, false, false, 0);
         status_bar_box.pack_start(folder_paned);
         status_bar_box.pack_start(status_bar, false, false, 0);
         status_bar_box.get_style_context().add_class(Gtk.STYLE_CLASS_SIDEBAR);
@@ -272,7 +276,7 @@ public class MainWindow : Gtk.ApplicationWindow {
     
     private bool on_key_press_event(Gdk.EventKey event) {
         if ((event.keyval == Gdk.Key.Shift_L || event.keyval == Gdk.Key.Shift_R)
-            && (event.state & Gdk.ModifierType.SHIFT_MASK) == 0 && !main_toolbar.search_entry_has_focus)
+            && (event.state & Gdk.ModifierType.SHIFT_MASK) == 0 && !search_bar.search_entry_has_focus)
             on_shift_key(true);
         
         // Check whether the focused widget wants to handle it, if not let the accelerators kick in
@@ -285,7 +289,7 @@ public class MainWindow : Gtk.ApplicationWindow {
         // the shift key to report as released when they release ALL of them.
         // There doesn't seem to be an easy way to do this in Gdk.
         if ((event.keyval == Gdk.Key.Shift_L || event.keyval == Gdk.Key.Shift_R)
-            && !main_toolbar.search_entry_has_focus)
+            && !search_bar.search_entry_has_focus)
             on_shift_key(false);
         
         return propagate_key_event(event);
diff --git a/src/client/components/search-bar.vala b/src/client/components/search-bar.vala
new file mode 100644
index 0000000..53a4942
--- /dev/null
+++ b/src/client/components/search-bar.vala
@@ -0,0 +1,131 @@
+/* Copyright 2015 Yorba Foundation
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later).  See the COPYING file in this distribution.
+ */
+
+public class SearchBar : Gtk.SearchBar {
+    private const string ICON_CLEAR_NAME = "edit-clear-symbolic";
+    private const string ICON_CLEAR_RTL_NAME = "edit-clear-rtl-symbolic";
+    private const string DEFAULT_SEARCH_TEXT = _("Search");
+    
+    public string search_text { get { return search_entry.text; } }
+    public bool search_entry_has_focus { get { return search_entry.has_focus; } }
+    
+    private Gtk.SearchEntry search_entry = new Gtk.SearchEntry();
+    private Geary.ProgressMonitor? search_upgrade_progress_monitor = null;
+    private MonitoredProgressBar search_upgrade_progress_bar = new MonitoredProgressBar();
+    private Geary.Account? current_account = null;
+    
+    public signal void search_text_changed(string search_text);
+    
+    public SearchBar() {
+        // Search entry.
+        search_entry.width_chars = 28;
+        search_entry.tooltip_text = _("Search all mail in account for keywords (Ctrl+S)");
+        search_entry.changed.connect(on_search_entry_changed);
+        search_entry.key_press_event.connect(on_search_key_press);
+        on_search_entry_changed(); // set initial state
+        search_entry.has_focus = true;
+        
+        // Search upgrade progress bar.
+        search_upgrade_progress_bar.show_text = true;
+        search_upgrade_progress_bar.visible = false;
+        search_upgrade_progress_bar.no_show_all = true;
+        
+        add(search_upgrade_progress_bar);
+        add(search_entry);
+        
+        set_search_placeholder_text(DEFAULT_SEARCH_TEXT);
+        
+        GearyApplication.instance.controller.account_selected.connect(on_account_changed);
+    }
+    
+    public void set_search_text(string text) {
+        search_entry.text = text;
+    }
+    
+    public void give_search_focus() {
+        set_search_mode(true);
+        search_entry.grab_focus();
+    }
+    
+    public void set_search_placeholder_text(string placeholder) {
+        search_entry.placeholder_text = placeholder;
+    }
+    
+    private void on_search_entry_changed() {
+        search_text_changed(search_entry.text);
+        // Enable/disable clear button.
+        search_entry.secondary_icon_name = search_entry.text != "" ?
+            (get_direction() == Gtk.TextDirection.RTL ? ICON_CLEAR_RTL_NAME : ICON_CLEAR_NAME) : null;
+    }
+    
+    private bool on_search_key_press(Gdk.EventKey event) {
+        // Clear box if user hits escape.
+        if (Gdk.keyval_name(event.keyval) == "Escape")
+            search_entry.text = "";
+        
+        // Force search if user hits enter.
+        if (Gdk.keyval_name(event.keyval) == "Return")
+            on_search_entry_changed();
+        
+        return false;
+    }
+    
+    private void on_search_upgrade_start() {
+        // Set the progress bar's width to match the search entry's width.
+        int minimum_width = 0;
+        int natural_width = 0;
+        search_entry.get_preferred_width(out minimum_width, out natural_width);
+        search_upgrade_progress_bar.width_request = minimum_width;
+        
+        search_entry.hide();
+        search_upgrade_progress_bar.show();
+    }
+    
+    private void on_search_upgrade_finished() {
+        search_entry.show();
+        search_upgrade_progress_bar.hide();
+    }
+    
+    private void on_account_changed(Geary.Account? account) {
+        on_search_upgrade_finished(); // Reset search box.
+        
+        if (search_upgrade_progress_monitor != null) {
+            search_upgrade_progress_monitor.start.disconnect(on_search_upgrade_start);
+            search_upgrade_progress_monitor.finish.disconnect(on_search_upgrade_finished);
+            search_upgrade_progress_monitor = null;
+        }
+        
+        if (current_account != null) {
+            current_account.information.notify[Geary.AccountInformation.PROP_NICKNAME].disconnect(
+                on_nickname_changed);
+        }
+        
+        if (account != null) {
+            search_upgrade_progress_monitor = account.search_upgrade_monitor;
+            search_upgrade_progress_bar.set_progress_monitor(search_upgrade_progress_monitor);
+            
+            search_upgrade_progress_monitor.start.connect(on_search_upgrade_start);
+            search_upgrade_progress_monitor.finish.connect(on_search_upgrade_finished);
+            if (search_upgrade_progress_monitor.is_in_progress)
+                on_search_upgrade_start(); // Remove search box, we're already in progress.
+            
+            account.information.notify[Geary.AccountInformation.PROP_NICKNAME].connect(
+                on_nickname_changed);
+            
+            search_upgrade_progress_bar.text = _("Indexing %s account").printf(account.information.nickname);
+        }
+        
+        current_account = account;
+        
+        on_nickname_changed(); // Set new account name.
+    }
+    
+    private void on_nickname_changed() {
+        set_search_placeholder_text(current_account == null ||
+            GearyApplication.instance.controller.get_num_accounts() == 1 ? DEFAULT_SEARCH_TEXT :
+            _("Search %s account").printf(current_account.information.nickname));
+    }
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]