[seahorse/wip/nielsdg/cleanup-empty-state: 3/3] KeyManager: add an empty state placeholder



commit 394e0020b7349d408c671c77cdfac4829eb2ac7e
Author: Niels De Graef <nielsdegraef gmail com>
Date:   Sun Jan 13 11:37:23 2019 +0100

    KeyManager: add an empty state placeholder
    
    See also the GNOME HIG about this topic:
    https://developer.gnome.org/hig/stable/empty-placeholder.html.en

 src/key-manager.vala        |  58 +++++++++++++++-
 src/seahorse-key-manager.ui | 160 +++++++++++++++++++++++++++++++++-----------
 2 files changed, 178 insertions(+), 40 deletions(-)
---
diff --git a/src/key-manager.vala b/src/key-manager.vala
index 90ea95fd..113c6370 100644
--- a/src/key-manager.vala
+++ b/src/key-manager.vala
@@ -31,14 +31,16 @@ public class Seahorse.KeyManager : Catalog {
     [GtkChild]
     private Gtk.ScrolledWindow sidebar_area;
     private Sidebar sidebar;
+    [GtkChild]
+    private Gtk.Stack content_stack;
+    [GtkChild]
+    private Gtk.TreeView key_list;
 
     [GtkChild]
     private Gtk.MenuButton new_item_button;
     [GtkChild]
     private Gtk.ToggleButton show_search_button;
 
-    [GtkChild]
-    private Gtk.TreeView key_list;
     private Gcr.Collection collection;
     private KeyManagerStore store;
 
@@ -77,6 +79,8 @@ public class Seahorse.KeyManager : Catalog {
 
         // Add new key store and associate it
         this.store = new KeyManagerStore(this.collection, this.key_list, this.settings);
+        this.store.row_inserted.connect(on_store_row_inserted);
+        this.store.row_deleted.connect(on_store_row_deleted);
 
         init_actions();
 
@@ -101,6 +105,9 @@ public class Seahorse.KeyManager : Catalog {
         targets.add_uri_targets(DndTarget.URIS);
         targets.add_text_targets(DndTarget.PLAIN);
         Gtk.drag_dest_set_target_list(this, targets);
+
+        // In the beginning, nothing's selected, so show empty state
+        check_empty_state();
     }
 
     private void init_actions() {
@@ -153,6 +160,34 @@ public class Seahorse.KeyManager : Catalog {
             show_properties(obj);
     }
 
+    private void on_store_row_inserted(Gtk.TreeModel store, Gtk.TreePath path, Gtk.TreeIter iter) {
+        check_empty_state();
+    }
+
+    private void on_store_row_deleted(Gtk.TreeModel store, Gtk.TreePath path) {
+        check_empty_state();
+    }
+
+    private void check_empty_state() {
+        bool empty = (store.iter_n_children(null) == 0);
+
+        this.show_search_button.sensitive = !empty;
+        if (!empty) {
+            this.content_stack.visible_child_name = "key_list_page";
+            return;
+        }
+
+        // We have an empty page, that might still have 2 reasons:
+        // - we really have no items in our collections
+        // - we're dealing with a locked keyring
+        Place? place = get_focused_place();
+        if (place != null && place is Lockable && ((Lockable) place).unlockable) {
+            this.content_stack.visible_child_name = "locked_keyring_page";
+            return;
+        }
+        this.content_stack.visible_child_name = "empty_state_page";
+    }
+
     [GtkCallback]
     private bool on_key_list_button_pressed(Gdk.EventButton event) {
         if (event.button == 3) {
@@ -358,6 +393,8 @@ public class Seahorse.KeyManager : Catalog {
     private Gcr.Collection setup_sidebar() {
         this.sidebar = new Sidebar();
         sidebar.hexpand = true;
+        /* Make sure we get */
+        this.sidebar.get_selection().changed.connect((sel) => check_empty_state());
 
         this.sidebar_panes.position = this.settings.get_int("sidebar-width");
         this.sidebar_panes.realize.connect(() =>   { this.sidebar_panes.position = 
this.settings.get_int("sidebar-width"); });
@@ -386,4 +423,21 @@ public class Seahorse.KeyManager : Catalog {
         if (!was_grabbed)
             widget.hide();
     }
+
+    [GtkCallback]
+    private void on_locked_keyring_unlock_button_clicked(Gtk.Button unlock_button) {
+        Lockable? place = get_focused_place() as Lockable;
+        return_if_fail(place != null && place.unlockable);
+
+        unlock_button.sensitive = false;
+        place.unlock.begin(null, null, (obj, res) => {
+            try {
+                unlock_button.sensitive = true;
+                place.unlock.end(res);
+            } catch (GLib.Error e) {
+                unlock_button.sensitive = true;
+                Util.show_error(this, _("Couldn't unlock keyring"), e.message);
+            }
+        });
+    }
 }
diff --git a/src/seahorse-key-manager.ui b/src/seahorse-key-manager.ui
index 9b84a07b..477681f4 100644
--- a/src/seahorse-key-manager.ui
+++ b/src/seahorse-key-manager.ui
@@ -364,62 +364,146 @@
               </object>
             </child>
             <child>
-              <object class="GtkScrolledWindow" id="key-list-scroll-area">
+              <object class="GtkStack" id="content_stack">
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="hscrollbar-policy">never</property>
+                <property name="homogeneous">True</property>
                 <child>
-                  <object class="GtkBox">
+                  <object class="GtkScrolledWindow">
                     <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="orientation">horizontal</property>
-                    <property name="margin-top">24</property>
-                    <property name="margin-bottom">24</property>
+                    <property name="can_focus">True</property>
+                    <property name="hscrollbar-policy">never</property>
                     <child>
                       <object class="GtkBox">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="hexpand">True</property>
+                        <property name="orientation">horizontal</property>
+                        <property name="margin-top">24</property>
+                        <property name="margin-bottom">24</property>
+                        <child>
+                          <object class="GtkBox">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="hexpand">True</property>
+                          </object>
+                        </child>
+                        <child>
+                          <object class="GtkBox">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="hexpand">True</property>
+                          </object>
+                          <packing>
+                            <property name="pack_type">end</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkFrame">
+                            <property name="visible">True</property>
+                            <property name="hexpand">True</property>
+                            <property name="margin-start">18</property>
+                            <property name="margin-end">18</property>
+                            <child>
+                              <object class="GtkTreeView" id="key_list">
+                                <property name="visible">True</property>
+                                <property name="enable-search">False</property>
+                                <property name="show-expanders">False</property>
+                                <property name="headers-visible">False</property>
+                                <property name="can_focus">True</property>
+                                <property name="enable-grid-lines">horizontal</property>
+                                <signal name="row-activated" handler="on_key_list_row_activated"/>
+                                <signal name="button-press-event" handler="on_key_list_button_pressed" />
+                                <signal name="popup-menu" handler="on_key_list_popup_menu" />
+                                <child internal-child="selection">
+                                  <object class="GtkTreeSelection" id="treeview-selection">
+                                    <property name="mode">multiple</property>
+                                    <signal name="changed" handler="on_view_selection_changed" />
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
+                          </object>
+                        </child>
                       </object>
                     </child>
+                  </object>
+                  <packing>
+                    <property name="name">key_list_page</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox">
+                    <property name="visible">True</property>
+                    <property name="orientation">vertical</property>
+                    <property name="halign">center</property>
+                    <property name="valign">center</property>
+                    <property name="spacing">24</property>
                     <child>
-                      <object class="GtkBox">
+                      <object class="GtkImage">
                         <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="hexpand">True</property>
+                        <property name="visible">True</property>
+                        <property name="pixel-size">100</property>
+                        <property name="icon-name">org.gnome.seahorse.Application-symbolic</property>
+                        <style>
+                          <class name="dim-label"/>
+                        </style>
                       </object>
-                      <packing>
-                        <property name="pack_type">end</property>
-                      </packing>
                     </child>
                     <child>
-                      <object class="GtkFrame">
+                      <object class="GtkLabel">
                         <property name="visible">True</property>
-                        <property name="hexpand">True</property>
-                        <property name="margin-start">18</property>
-                        <property name="margin-end">18</property>
-                        <child>
-                          <object class="GtkTreeView" id="key_list">
-                            <property name="visible">True</property>
-                            <property name="enable-search">False</property>
-                            <property name="show-expanders">False</property>
-                            <property name="headers-visible">False</property>
-                            <property name="can_focus">True</property>
-                            <property name="enable-grid-lines">horizontal</property>
-                            <signal name="row-activated" handler="on_key_list_row_activated"/>
-                            <signal name="button-press-event" handler="on_key_list_button_pressed" />
-                            <signal name="popup-menu" handler="on_key_list_popup_menu" />
-                            <child internal-child="selection">
-                              <object class="GtkTreeSelection" id="treeview-selection">
-                                <property name="mode">multiple</property>
-                                <signal name="changed" handler="on_view_selection_changed" />
-                              </object>
-                            </child>
-                          </object>
-                        </child>
+                        <property name="label" translatable="yes">This collection seems to be 
empty</property>
+                        <style>
+                          <class name="dim-label"/>
+                        </style>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="name">empty_state_page</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox">
+                    <property name="visible">True</property>
+                    <property name="orientation">vertical</property>
+                    <property name="halign">center</property>
+                    <property name="valign">center</property>
+                    <property name="spacing">24</property>
+                    <child>
+                      <object class="GtkImage">
+                        <property name="visible">True</property>
+                        <property name="visible">True</property>
+                        <property name="pixel-size">100</property>
+                        <property name="icon-name">org.gnome.seahorse.Application-symbolic</property>
+                        <style>
+                          <class name="dim-label"/>
+                        </style>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Keyring is locked</property>
+                        <attributes>
+                          <attribute name="scale" value="2"/>
+                        </attributes>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="locked_keyring_unlock_button">
+                        <property name="visible">True</property>
+                        <property name="halign">center</property>
+                        <property name="label" translatable="yes">Unlock</property>
+                        <signal name="clicked" handler="on_locked_keyring_unlock_button_clicked"/>
+                        <style>
+                          <class name="suggested-action"/>
+                        </style>
                       </object>
                     </child>
                   </object>
+                  <packing>
+                    <property name="name">locked_keyring_page</property>
+                  </packing>
                 </child>
               </object>
               <packing>


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