[geary] Provide custom close-and-save and close-and-discard buttons for composer



commit 36f316868a3c7d62f6cbe68f5ce8801c89187414
Author: Robert Schroll <rschroll gmail com>
Date:   Sat Feb 21 19:02:12 2015 -0500

    Provide custom close-and-save and close-and-discard buttons for composer
    
    This ensures that we only have a single close button for the main window
    at any time, and it always closes the whole application.  The composer
    gets a default close button only when detached.

 src/client/components/main-toolbar.vala     |    6 ++-
 src/client/composer/composer-headerbar.vala |   66 ++++++++++++++-------------
 src/client/composer/composer-widget.vala    |   15 ++++++
 ui/composer.glade                           |   16 +++++++
 4 files changed, 70 insertions(+), 33 deletions(-)
---
diff --git a/src/client/components/main-toolbar.vala b/src/client/components/main-toolbar.vala
index 79c5563..2585d9f 100644
--- a/src/client/components/main-toolbar.vala
+++ b/src/client/components/main-toolbar.vala
@@ -170,17 +170,19 @@ public class MainToolbar : Gtk.Box {
         search_entry.placeholder_text = placeholder;
     }
     
-    public void set_conversation_header(Gtk.Widget header) {
+    public void set_conversation_header(Gtk.HeaderBar header) {
         conversation_header.hide();
         header.get_style_context().add_class("titlebar");
         header.get_style_context().add_class("geary-titlebar-right");
+        header.show_close_button = show_close_button;
         pack_start(header, true, true);
     }
     
-    public void remove_conversation_header(Gtk.Widget header) {
+    public void remove_conversation_header(Gtk.HeaderBar header) {
         remove(header);
         header.get_style_context().remove_class("titlebar");
         header.get_style_context().remove_class("geary-titlebar-right");
+        header.show_close_button = false;
         conversation_header.show();
     }
     
diff --git a/src/client/composer/composer-headerbar.vala b/src/client/composer/composer-headerbar.vala
index ce8f7b8..e083c70 100644
--- a/src/client/composer/composer-headerbar.vala
+++ b/src/client/composer/composer-headerbar.vala
@@ -12,48 +12,50 @@ public class ComposerHeaderbar : PillHeaderbar {
     
     private Gtk.Button recipients;
     private Gtk.Label recipients_label;
-    private Gtk.Box win_buttons_start;
-    private Gtk.Box win_buttons_end;
+    private Gtk.Box detach_start;
+    private Gtk.Box detach_end;
     
     public ComposerHeaderbar(Gtk.ActionGroup action_group) {
         base(action_group);
         
         show_close_button = false;
         
-        Gtk.Button send_button = create_toolbar_button(null, ComposerWidget.ACTION_SEND, true);
-        send_button.get_style_context().add_class("suggested-action");
-        
         bool rtl = (get_direction() == Gtk.TextDirection.RTL);
         
-        win_buttons_start = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
+        // Toolbar setup.
+        Gee.List<Gtk.Button> insert = new Gee.ArrayList<Gtk.Button>();
+        
+        // Window management.
+        detach_start = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
         Gtk.Button detach_button = create_toolbar_button(null, ComposerWidget.ACTION_DETACH);
-        Gtk.Button close_button = create_toolbar_button(null, ComposerWidget.ACTION_CLOSE);
         detach_button.set_relief(Gtk.ReliefStyle.NONE);
-        close_button.set_relief(Gtk.ReliefStyle.NONE);
         if (rtl)
             detach_button.set_margin_left(6);
         else
             detach_button.set_margin_right(6);
-        win_buttons_start.pack_start(close_button);
-        win_buttons_start.pack_start(detach_button);
-        win_buttons_start.pack_start(new Gtk.Separator(Gtk.Orientation.VERTICAL));
+        detach_start.pack_start(detach_button);
+        detach_start.pack_start(new Gtk.Separator(Gtk.Orientation.VERTICAL));
         
-        win_buttons_end = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
+        detach_end = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
         detach_button = create_toolbar_button(null, ComposerWidget.ACTION_DETACH);
-        close_button = create_toolbar_button(null, ComposerWidget.ACTION_CLOSE);
         detach_button.set_relief(Gtk.ReliefStyle.NONE);
-        close_button.set_relief(Gtk.ReliefStyle.NONE);
         if (rtl)
             detach_button.set_margin_right(6);
         else
             detach_button.set_margin_left(6);
-        win_buttons_end.pack_end(close_button);
-        win_buttons_end.pack_end(detach_button);
-        win_buttons_end.pack_end(new Gtk.Separator(Gtk.Orientation.VERTICAL));
+        detach_end.pack_end(detach_button);
+        detach_end.pack_end(new Gtk.Separator(Gtk.Orientation.VERTICAL));
+        
+        insert.add(create_toolbar_button(null, ComposerWidget.ACTION_CLOSE_DISCARD));
+        insert.add(create_toolbar_button(null, ComposerWidget.ACTION_CLOSE_SAVE));
+        Gtk.Box close_buttons = create_pill_buttons(insert, false);
+        insert.clear();
+        
+        Gtk.Button send_button = create_toolbar_button(null, ComposerWidget.ACTION_SEND, true);
+        send_button.get_style_context().add_class("suggested-action");
         
         Gtk.Box attach_buttons = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
         Gtk.Button attach_only = create_toolbar_button(null, ComposerWidget.ACTION_ADD_ATTACHMENT);
-        Gee.List<Gtk.Button> insert = new Gee.ArrayList<Gtk.Button>();
         insert.add(create_toolbar_button(null, ComposerWidget.ACTION_ADD_ATTACHMENT));
         insert.add(create_toolbar_button(null, ComposerWidget.ACTION_ADD_ORIGINAL_ATTACHMENTS));
         Gtk.Box attach_pending = create_pill_buttons(insert, false);
@@ -67,12 +69,6 @@ public class ComposerHeaderbar : PillHeaderbar {
         recipients.add(recipients_label);
         recipients.clicked.connect(() => { state = ComposerWidget.ComposerState.INLINE; });
         
-        notify["state"].connect((s, p) => {
-            if (state == ComposerWidget.ComposerState.DETACHED) {
-                get_style_context().changed.disconnect(set_win_buttons_side);
-                win_buttons_start.visible = win_buttons_end.visible = false;
-            }
-        });
         bind_property("state", recipients, "visible", BindingFlags.SYNC_CREATE,
             (binding, source_value, ref target_value) => {
                 target_value = (state == ComposerWidget.ComposerState.INLINE_COMPACT);
@@ -84,18 +80,26 @@ public class ComposerHeaderbar : PillHeaderbar {
             BindingFlags.SYNC_CREATE);
         bind_property("send-enabled", send_button, "sensitive", BindingFlags.SYNC_CREATE);
         
-        add_start(win_buttons_start);
+        add_start(detach_start);
         add_start(attach_buttons);
         add_start(recipients);
 #if !GTK_3_12
         add_end(send_button);
+        add_end(close_buttons);
 #endif
-        add_end(win_buttons_end);
+        add_end(detach_end);
 #if GTK_3_12
+        add_end(close_buttons);
         add_end(send_button);
 #endif
-        get_style_context().changed.connect(set_win_buttons_side);
-        realize.connect(set_win_buttons_side);
+        get_style_context().changed.connect(set_detach_button_side);
+        realize.connect(set_detach_button_side);
+        notify["state"].connect((s, p) => {
+            if (state == ComposerWidget.ComposerState.DETACHED) {
+                get_style_context().changed.disconnect(set_detach_button_side);
+                detach_start.visible = detach_end.visible = false;
+            }
+        });
     }
     
     public void set_recipients(string label, string tooltip) {
@@ -103,7 +107,7 @@ public class ComposerHeaderbar : PillHeaderbar {
         recipients.tooltip_text = tooltip;
     }
     
-    private void set_win_buttons_side() {
+    private void set_detach_button_side() {
         string layout;
         bool at_end = false;
         get_toplevel().style_get("decoration-button-layout", out layout);
@@ -113,8 +117,8 @@ public class ComposerHeaderbar : PillHeaderbar {
             int colon_ind = layout.index_of(":");
             at_end = (colon_ind >= 0 && layout.index_of("close", colon_ind) >= 0);
         }
-        win_buttons_start.visible = !at_end;
-        win_buttons_end.visible = at_end;
+        detach_start.visible = !at_end;
+        detach_end.visible = at_end;
     }
 }
 
diff --git a/src/client/composer/composer-widget.vala b/src/client/composer/composer-widget.vala
index bceb6b4..98616a1 100644
--- a/src/client/composer/composer-widget.vala
+++ b/src/client/composer/composer-widget.vala
@@ -62,6 +62,8 @@ public class ComposerWidget : Gtk.EventBox {
     public const string ACTION_COMPOSE_AS_HTML = "compose as html";
     public const string ACTION_SHOW_EXTENDED = "show extended";
     public const string ACTION_CLOSE = "close";
+    public const string ACTION_CLOSE_SAVE = "close and save";
+    public const string ACTION_CLOSE_DISCARD = "close and discard";
     public const string ACTION_DETACH = "detach";
     public const string ACTION_SEND = "send";
     public const string ACTION_ADD_ATTACHMENT = "add attachment";
@@ -439,6 +441,8 @@ public class ComposerWidget : Gtk.EventBox {
         actions.get_action(ACTION_INSERT_LINK).activate.connect(on_insert_link);
         
         actions.get_action(ACTION_CLOSE).activate.connect(on_close);
+        actions.get_action(ACTION_CLOSE_SAVE).activate.connect(on_close_and_save);
+        actions.get_action(ACTION_CLOSE_DISCARD).activate.connect(on_close_and_discard);
         
         actions.get_action(ACTION_DETACH).activate.connect(on_detach);
         actions.get_action(ACTION_SEND).activate.connect(on_send);
@@ -1123,6 +1127,17 @@ public class ComposerWidget : Gtk.EventBox {
             container.close_container();
     }
     
+    private void on_close_and_save() {
+        if (can_save())
+            save_and_exit_async.begin();
+        else
+            container.close_container();
+    }
+    
+    private void on_close_and_discard() {
+        discard_and_exit_async.begin();
+    }
+    
     private void on_detach() {
         if (state == ComposerState.DETACHED)
             return;
diff --git a/ui/composer.glade b/ui/composer.glade
index dfa7d41..f3a23ba 100644
--- a/ui/composer.glade
+++ b/ui/composer.glade
@@ -152,6 +152,22 @@
       <accelerator key="w" modifiers="GDK_CONTROL_MASK"/>
     </child>
     <child>
+      <object class="GtkAction" id="close and save">
+        <property name="label" translatable="yes">Close and Save</property>
+        <property name="short_label" translatable="yes">Close and Save</property>
+        <property name="tooltip" translatable="yes">Close and Save</property>
+        <property name="icon_name">document-save-symbolic</property>
+      </object>
+    </child>
+    <child>
+      <object class="GtkAction" id="close and discard">
+        <property name="label" translatable="yes">Close and Discard</property>
+        <property name="short_label" translatable="yes">Close and Discard</property>
+        <property name="tooltip" translatable="yes">Close and Discard</property>
+        <property name="icon_name">user-trash-symbolic</property>
+      </object>
+    </child>
+    <child>
       <object class="GtkAction" id="font_large">
         <property name="label" translatable="yes">Lar_ge</property>
         <property name="short_label" translatable="yes">Large</property>


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