[geary/wip/trash-714212] Swap trash for delete with shift key



commit 2b5c457a1f7c62b4df4b09afb74fbed4e2cfc50c
Author: Charles Lindsay <chaz yorba org>
Date:   Thu Dec 19 18:23:33 2013 -0800

    Swap trash for delete with shift key

 src/client/application/geary-controller.vala |   13 +++++++++----
 src/client/components/main-toolbar.vala      |   10 +++++++---
 src/client/components/main-window.vala       |   26 +++++++++++++++++++++++---
 3 files changed, 39 insertions(+), 10 deletions(-)
---
diff --git a/src/client/application/geary-controller.vala b/src/client/application/geary-controller.vala
index 57ab2c9..b3cecd6 100644
--- a/src/client/application/geary-controller.vala
+++ b/src/client/application/geary-controller.vala
@@ -42,7 +42,7 @@ public class GearyController : Geary.BaseObject {
     public const int MIN_CONVERSATION_COUNT = 50;
     
     private const string DELETE_MESSAGE_LABEL = _("_Delete");
-    private const string DELETE_MESSAGE_TOOLTIP_SINGLE = _("Delete conversation (Shitf+Delete)");
+    private const string DELETE_MESSAGE_TOOLTIP_SINGLE = _("Delete conversation (Shift+Delete)");
     private const string DELETE_MESSAGE_TOOLTIP_MULTIPLE = _("Delete conversations (Shift+Delete)");
     private const string DELETE_MESSAGE_ICON_NAME = "edit-delete-symbolic";
     
@@ -163,6 +163,7 @@ public class GearyController : Geary.BaseObject {
         
         // Create the main window (must be done after creating actions.)
         main_window = new MainWindow(GearyApplication.instance);
+        main_window.on_shift_key.connect(on_shift_key);
         main_window.notify["has-toplevel-focus"].connect(on_has_toplevel_focus);
         
         enable_message_buttons(false);
@@ -927,9 +928,8 @@ public class GearyController : Geary.BaseObject {
     // by other utility methods
     private void update_ui() {
         update_tooltips();
-        // TODO: also replace it with delete when shift is held down
-        main_window.main_toolbar.replace_trash_with_delete(!current_folder_supports_trash());
-        main_window.main_toolbar.show_archive_button(current_account.can_support_archive());
+        main_window.main_toolbar.update_trash_buttons(current_folder_supports_trash(),
+            current_account.can_support_archive());
     }
     
     private void on_folder_selected(Geary.Folder? folder) {
@@ -1303,6 +1303,11 @@ public class GearyController : Geary.BaseObject {
         }
     }
     
+    private void on_shift_key(bool pressed) {
+        main_window.main_toolbar.update_trash_buttons(!pressed && current_folder_supports_trash(),
+            current_account.can_support_archive());
+    }
+    
     // this signal does not necessarily indicate that the application previously didn't have
     // focus and now it does
     private void on_has_toplevel_focus() {
diff --git a/src/client/components/main-toolbar.vala b/src/client/components/main-toolbar.vala
index 53ec620..eb08326 100644
--- a/src/client/components/main-toolbar.vala
+++ b/src/client/components/main-toolbar.vala
@@ -114,7 +114,7 @@ public class MainToolbar : PillToolbar {
         set_search_placeholder_text(DEFAULT_SEARCH_TEXT);
     }
     
-    public void show_archive_button(bool show) {
+    private void show_archive_button(bool show) {
         if (show) {
             archive_button.show();
             trash_buttons[0].show();
@@ -126,10 +126,14 @@ public class MainToolbar : PillToolbar {
         }
     }
     
-    public void replace_trash_with_delete(bool replace) {
-        string action_name = (replace ? GearyController.ACTION_DELETE_MESSAGE : 
GearyController.ACTION_TRASH_MESSAGE);
+    /// Updates the trash button as trash or delete, and shows or hides the archive button.
+    public void update_trash_buttons(bool trash, bool archive) {
+        string action_name = (trash ? GearyController.ACTION_TRASH_MESSAGE
+            : GearyController.ACTION_DELETE_MESSAGE);
         foreach (Gtk.Button b in trash_buttons)
             setup_button(b, null, action_name, true);
+        
+        show_archive_button(archive);
     }
     
     public void set_search_text(string text) {
diff --git a/src/client/components/main-window.vala b/src/client/components/main-window.vala
index e400e1d..49111e6 100644
--- a/src/client/components/main-window.vala
+++ b/src/client/components/main-window.vala
@@ -9,6 +9,9 @@ public class MainWindow : Gtk.ApplicationWindow {
     private const int FOLDER_LIST_WIDTH = 100;
     private const int STATUS_BAR_HEIGHT = 18;
     
+    /// Fired when the shift key is pressed or released.
+    public signal void on_shift_key(bool pressed);
+    
     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; }
@@ -35,6 +38,8 @@ public class MainWindow : Gtk.ApplicationWindow {
         
         conversation_list_view = new ConversationListView(conversation_list_store);
         
+        add_events(Gdk.EventMask.KEY_PRESS_MASK | Gdk.EventMask.KEY_RELEASE_MASK);
+        
         // This code both loads AND saves the pane positions with live
         // updating. This is more resilient against crashes because
         // the value in dconf changes *immediately*, and stays saved
@@ -57,6 +62,7 @@ public class MainWindow : Gtk.ApplicationWindow {
         
         delete_event.connect(on_delete_event);
         key_press_event.connect(on_key_press_event);
+        key_release_event.connect(on_key_release_event);
         GearyApplication.instance.controller.notify[GearyController.PROP_CURRENT_CONVERSATION].
             connect(on_conversation_monitor_changed);
         Geary.Engine.instance.account_available.connect(on_account_available);
@@ -73,7 +79,8 @@ public class MainWindow : Gtk.ApplicationWindow {
         
         base.show_all();
         
-        main_toolbar.show_archive_button(true);
+        // Some buttons need to be hidden, so we have to do this after we show everything.
+        main_toolbar.update_trash_buttons(true, true);
     }
     
     private bool on_delete_event() {
@@ -150,8 +157,6 @@ public class MainWindow : Gtk.ApplicationWindow {
         main_layout.pack_end(folder_paned, true, true, 0);
         
         add(main_layout);
-        
-        this.key_press_event.connect(on_key_press_event);
     }
     
     // Returns true when there's a conversation list scrollbar visible, i.e. the list is tall
@@ -162,11 +167,26 @@ public class MainWindow : Gtk.ApplicationWindow {
     }
     
     private bool on_key_press_event(Gdk.EventKey event) {
+        // TODO: suppress sending shift signal when focus is in search box
+        if ((event.keyval == Gdk.Key.Shift_L || event.keyval == Gdk.Key.Shift_R)
+            && (event.state & Gdk.ModifierType.SHIFT_MASK) == 0)
+            on_shift_key(true);
+        
         // Check whether the focused widget wants to handle it, if not let the accelerators kick in
         // via the default handling
         return propagate_key_event(event);
     }
     
+    private bool on_key_release_event(Gdk.EventKey event) {
+        // FIXME: it's possible the user will press two shift keys.  We want
+        // 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)
+            on_shift_key(false);
+        
+        return propagate_key_event(event);
+    }
+    
     private void on_conversation_monitor_changed() {
         Geary.App.ConversationMonitor? conversation_monitor =
             GearyApplication.instance.controller.current_conversations;


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