[seahorse] Ssh: Use GtkTemplate for the UI instead of GtkBuilder.



commit 869234edc55969de4fd8ddb7350695008ff61ea7
Author: Niels De Graef <nielsdegraef gmail com>
Date:   Wed May 9 17:46:33 2018 +0200

    Ssh: Use GtkTemplate for the UI instead of GtkBuilder.
    
    This saves us quite a bit of lines, allows us to do more with Glade, and
    catches inconsistencies between the code and the UI at compile time.

 data/meson.build                   |    3 +-
 ssh/generate.vala                  |   42 +--
 ssh/key-properties.vala            |   59 +--
 ssh/meson.build                    |    5 +
 ssh/seahorse-ssh-generate.ui       |  439 +++++++++++-----------
 ssh/seahorse-ssh-key-properties.ui |  721 ++++++++++++++++++------------------
 ssh/seahorse-ssh-upload.ui         |  236 +++++++------
 ssh/upload.vala                    |   42 +--
 8 files changed, 764 insertions(+), 783 deletions(-)
---
diff --git a/data/meson.build b/data/meson.build
index ca88c02..611e457 100644
--- a/data/meson.build
+++ b/data/meson.build
@@ -11,8 +11,9 @@ install_data(gsettings_files,
 )
 
 # Resources
+resources_xml = join_paths(meson.source_root(), 'data', 'seahorse.gresource.xml')
 resources_src = gnome.compile_resources('seahorse-resources',
-  'seahorse.gresource.xml',
+  resources_xml,
 )
 
 # The appdata file
diff --git a/ssh/generate.vala b/ssh/generate.vala
index b5f2adb..a42978d 100644
--- a/ssh/generate.vala
+++ b/ssh/generate.vala
@@ -19,6 +19,7 @@
  * <http://www.gnu.org/licenses/>.
  */
 
+[GtkTemplate (ui = "/org/gnome/Seahorse/seahorse-ssh-generate.ui")]
 public class Seahorse.Ssh.Generate : Gtk.Dialog {
     public const int DEFAULT_DSA_SIZE = 1024;
     public const int DEFAULT_RSA_SIZE = 2048;
@@ -30,22 +31,24 @@ public class Seahorse.Ssh.Generate : Gtk.Dialog {
 
     private Source source;
 
+    [GtkChild]
     private Gtk.Grid details_grid;
     private KeyLengthChooser key_length_chooser;
+    [GtkChild]
     private Gtk.Entry email_entry;
+    [GtkChild]
     private Gtk.ComboBoxText algorithm_combo_box;
+    [GtkChild]
     private Gtk.Button create_with_setup_button;
+    [GtkChild]
     private Gtk.Button create_no_setup_button;
 
     public Generate(Source src, Gtk.Window parent) {
-        GLib.Object(border_width: 5,
-                    title: _("New Secure Shell Key"),
-                    resizable: false,
-                    modal: true,
-                    transient_for: parent);
+        this.transient_for = parent;
         this.source = src;
 
-        load_ui();
+        this.create_no_setup_button.clicked.connect((b) => create_key(false));
+        this.create_with_setup_button.clicked.connect((b) => create_key(true));
 
         this.key_length_chooser = new KeyLengthChooser();
         this.details_grid.attach(this.key_length_chooser, 1, 1);
@@ -70,32 +73,7 @@ public class Seahorse.Ssh.Generate : Gtk.Dialog {
         Seahorse.Registry.register_object(actions, "generator");
     }
 
-    // FIXME: normally we would do this using GtkTemplate, but this is quite hard with the current build 
setup
-    private void load_ui() {
-        Gtk.Builder builder = new Gtk.Builder();
-        try {
-            string path = "/org/gnome/Seahorse/seahorse-ssh-generate.ui";
-            builder.add_from_resource(path);
-        } catch (GLib.Error err) {
-            GLib.critical("%s", err.message);
-        }
-        Gtk.Container content = (Gtk.Container) builder.get_object("ssh-generate");
-        ((Gtk.Container)this.get_content_area()).add(content);
-        Gtk.Widget actions = (Gtk.Widget) builder.get_object("action_area");
-        ((Gtk.Container)this.get_action_area()).add(actions);
-
-        this.details_grid = (Gtk.Grid) builder.get_object("details_grid");
-        this.email_entry = (Gtk.Entry) builder.get_object("email-entry");
-        this.algorithm_combo_box = (Gtk.ComboBoxText) builder.get_object("algorithm-combo-box");
-        this.create_no_setup_button = (Gtk.Button) builder.get_object("create-no-setup");
-        this.create_with_setup_button = (Gtk.Button) builder.get_object("create-with-setup");
-
-        // Signals
-        this.algorithm_combo_box.changed.connect(on_algo_changed);
-        this.create_no_setup_button.clicked.connect((b) => create_key(false));
-        this.create_with_setup_button.clicked.connect((b) => create_key(true));
-    }
-
+    [GtkCallback]
     private void on_algo_changed(Gtk.ComboBox combo) {
         string t = algorithm_combo_box.get_active_text();
         this.key_length_chooser.algorithm = Algorithm.from_string(t);
diff --git a/ssh/key-properties.vala b/ssh/key-properties.vala
index 687775d..213d19f 100644
--- a/ssh/key-properties.vala
+++ b/ssh/key-properties.vala
@@ -19,6 +19,7 @@
  * <http://www.gnu.org/licenses/>.
  */
 
+[GtkTemplate (ui = "/org/gnome/Seahorse/seahorse-ssh-key-properties.ui")]
 public class Seahorse.Ssh.KeyProperties : Gtk.Dialog {
 
     private Key key;
@@ -26,71 +27,46 @@ public class Seahorse.Ssh.KeyProperties : Gtk.Dialog {
     // Used to make sure we don't start calling command unnecessarily
     private bool updating_ui = false;
 
+    [GtkChild]
     private Gtk.Image key_image;
+    [GtkChild]
     private Gtk.Entry comment_entry;
+    [GtkChild]
     private Gtk.Label id_label;
+    [GtkChild]
     private Gtk.Label trust_message;
+    [GtkChild]
     private Gtk.ToggleButton trust_check;
 
+    [GtkChild]
     private Gtk.Button passphrase_button;
+    [GtkChild]
     private Gtk.Button export_button;
 
+    [GtkChild]
     private Gtk.Label fingerprint_label;
+    [GtkChild]
     private Gtk.Label algo_label;
+    [GtkChild]
     private Gtk.Label location_label;
+    [GtkChild]
     private Gtk.Label key_length_label;
 
     public KeyProperties(Key key, Gtk.Window parent) {
-        GLib.Object(border_width: 5,
-                    title: _("Key Properties"),
-                    resizable: false,
-                    transient_for: parent);
+        this.transient_for = parent;
         this.key = key;
 
-        load_ui();
         update_ui();
 
         // A public key only
         if (key.usage != Seahorse.Usage.PRIVATE_KEY) {
-            passphrase_button.visible = false;
-            export_button.visible = false;
+            this.passphrase_button.visible = false;
+            this.export_button.visible = false;
         }
 
         this.key.notify.connect(() => update_ui());
     }
 
-    // FIXME: normally we would do this using GtkTemplate, but this is quite hard with the current build 
setup
-    private void load_ui() {
-        Gtk.Builder builder = new Gtk.Builder();
-        try {
-            string path = "/org/gnome/Seahorse/seahorse-ssh-key-properties.ui";
-            builder.add_from_resource(path);
-        } catch (GLib.Error err) {
-            GLib.critical("%s", err.message);
-        }
-        Gtk.Container content = (Gtk.Container) builder.get_object("ssh-key-properties");
-        ((Gtk.Container)this.get_content_area()).add(content);
-
-        this.key_image = (Gtk.Image) builder.get_object("key-image");
-        this.comment_entry = (Gtk.Entry) builder.get_object("comment-entry");
-        this.id_label = (Gtk.Label) builder.get_object("id-label");
-        this.trust_message = (Gtk.Label) builder.get_object("trust-message");
-        this.trust_check = (Gtk.ToggleButton) builder.get_object("trust-check");
-        this.passphrase_button = (Gtk.Button) builder.get_object("passphrase-button");
-        this.export_button = (Gtk.Button) builder.get_object("export-button");
-        this.fingerprint_label = (Gtk.Label) builder.get_object("fingerprint-label");
-        this.algo_label = (Gtk.Label) builder.get_object("algo-label");
-        this.location_label = (Gtk.Label) builder.get_object("location-label");
-        this.key_length_label = (Gtk.Label) builder.get_object("key-length-label");
-
-        // Signals
-        this.comment_entry.activate.connect(on_ssh_comment_activate);
-        this.comment_entry.focus_out_event.connect(on_ssh_comment_focus_out);
-        this.trust_check.toggled.connect(on_ssh_trust_toggled);
-        this.passphrase_button.clicked.connect(on_ssh_passphrase_button_clicked);
-        this.export_button.clicked.connect(on_ssh_export_button_clicked);
-    }
-
     private void update_ui() {
         this.updating_ui = true;
 
@@ -120,6 +96,7 @@ public class Seahorse.Ssh.KeyProperties : Gtk.Dialog {
         destroy();
     }
 
+    [GtkCallback]
     public void on_ssh_comment_activate(Gtk.Entry entry) {
         // Make sure not the same
         if (key.key_data.comment != null && entry.text == key.key_data.comment)
@@ -140,11 +117,13 @@ public class Seahorse.Ssh.KeyProperties : Gtk.Dialog {
         });
     }
 
+    [GtkCallback]
     private bool on_ssh_comment_focus_out(Gtk.Widget widget, Gdk.EventFocus event) {
         on_ssh_comment_activate((Gtk.Entry) widget);
         return false;
     }
 
+    [GtkCallback]
     private void on_ssh_trust_toggled(Gtk.ToggleButton button) {
         if (updating_ui)
             return;
@@ -163,6 +142,7 @@ public class Seahorse.Ssh.KeyProperties : Gtk.Dialog {
         });
     }
 
+    [GtkCallback]
     private void on_ssh_passphrase_button_clicked (Gtk.Button button) {
         button.sensitive = false;
 
@@ -178,6 +158,7 @@ public class Seahorse.Ssh.KeyProperties : Gtk.Dialog {
         });
     }
 
+    [GtkCallback]
     private void on_ssh_export_button_clicked (Gtk.Widget widget) {
         List<Exporter> exporters = new List<Exporter>();
         exporters.append(new Exporter(key, true));
diff --git a/ssh/meson.build b/ssh/meson.build
index 0a02160..18bfbe5 100644
--- a/ssh/meson.build
+++ b/ssh/meson.build
@@ -25,8 +25,13 @@ ssh_dependencies = [
   common_dep,
 ]
 
+ssh_vala_args = [
+  '--gresources', resources_xml,
+]
+
 ssh_lib = static_library('seahorse-ssh',
   ssh_sources,
+  vala_args: ssh_vala_args,
   dependencies: ssh_dependencies,
 )
 
diff --git a/ssh/seahorse-ssh-generate.ui b/ssh/seahorse-ssh-generate.ui
index 2230f0b..c0893bc 100644
--- a/ssh/seahorse-ssh-generate.ui
+++ b/ssh/seahorse-ssh-generate.ui
@@ -1,64 +1,109 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <requires lib="gtk+" version="3.0"/>
-  <object class="GtkBox" id="ssh-generate">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <property name="orientation">vertical</property>
-    <property name="spacing">2</property>
-    <child>
-      <object class="GtkBox" id="hbox4">
+  <requires lib="gtk+" version="3.22"/>
+  <template class="SeahorseSshGenerate" parent="GtkDialog">
+    <property name="modal">True</property>
+    <property name="resizable">False</property>
+    <property name="border_width">5</property>
+    <property name="title" translatable="yes">New Secure Shell Key</property>
+    <child internal-child="vbox">
+      <object class="GtkBox">
         <property name="visible">True</property>
-        <property name="orientation">horizontal</property>
         <property name="can_focus">False</property>
-        <property name="border_width">5</property>
-        <property name="spacing">12</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
         <child>
-          <object class="GtkAlignment" id="alignment9">
+          <object class="GtkBox" id="hbox4">
             <property name="visible">True</property>
+            <property name="orientation">horizontal</property>
             <property name="can_focus">False</property>
+            <property name="border_width">5</property>
+            <property name="spacing">12</property>
             <child>
-              <object class="GtkImage" id="ssh-image">
+              <object class="GtkAlignment" id="alignment9">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="yalign">0</property>
-                <property name="pixel_size">48</property>
-                <property name="icon_name">gcr-key-pair</property>
+                <child>
+                  <object class="GtkImage" id="ssh-image">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="yalign">0</property>
+                    <property name="pixel_size">48</property>
+                    <property name="icon_name">gcr-key-pair</property>
+                  </object>
+                </child>
               </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
             </child>
-          </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkBox" id="vbox5">
-            <property name="visible">True</property>
-            <property name="orientation">vertical</property>
-            <property name="can_focus">False</property>
-            <property name="spacing">12</property>
             <child>
-              <object class="GtkBox" id="vbox3">
+              <object class="GtkBox" id="vbox5">
                 <property name="visible">True</property>
                 <property name="orientation">vertical</property>
                 <property name="can_focus">False</property>
                 <property name="spacing">12</property>
                 <child>
-                  <object class="GtkBox" id="hbox41">
+                  <object class="GtkBox" id="vbox3">
                     <property name="visible">True</property>
-                    <property name="orientation">horizontal</property>
+                    <property name="orientation">vertical</property>
                     <property name="can_focus">False</property>
                     <property name="spacing">12</property>
                     <child>
-                      <object class="GtkLabel" id="label45">
+                      <object class="GtkBox" id="hbox41">
                         <property name="visible">True</property>
+                        <property name="orientation">horizontal</property>
                         <property name="can_focus">False</property>
-                        <property name="xalign">0</property>
-                        <property name="yalign">0</property>
-                        <property name="label" translatable="yes">A Secure Shell (SSH) key lets you connect 
securely to other computers.</property>
-                        <property name="wrap">True</property>
+                        <property name="spacing">12</property>
+                        <child>
+                          <object class="GtkLabel" id="label45">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">0</property>
+                            <property name="yalign">0</property>
+                            <property name="label" translatable="yes">A Secure Shell (SSH) key lets you 
connect securely to other computers.</property>
+                            <property name="wrap">True</property>
+                          </object>
+                          <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkAlignment" id="alignment8">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">0</property>
+                            <property name="yalign">0</property>
+                            <property name="xscale">0</property>
+                            <property name="yscale">0</property>
+                            <child>
+                              <object class="GtkButton" id="button3">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_action_appearance">False</property>
+                                <property name="relief">half</property>
+                                <signal name="clicked" handler="on_widget_help" swapped="no"/>
+                                <child>
+                                  <object class="GtkImage" id="image3">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="stock">gtk-help</property>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
                       </object>
                       <packing>
                         <property name="expand">True</property>
@@ -67,34 +112,77 @@
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkAlignment" id="alignment8">
+                      <object class="GtkAlignment" id="alignment7">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="xalign">0</property>
-                        <property name="yalign">0</property>
-                        <property name="xscale">0</property>
-                        <property name="yscale">0</property>
                         <child>
-                          <object class="GtkButton" id="button3">
+                          <object class="GtkGrid" id="grid1">
                             <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="receives_default">False</property>
-                            <property name="use_action_appearance">False</property>
-                            <property name="relief">half</property>
-                            <signal name="clicked" handler="on_widget_help" swapped="no"/>
+                            <property name="can_focus">False</property>
+                            <property name="row_spacing">6</property>
+                            <property name="column_spacing">12</property>
                             <child>
-                              <object class="GtkImage" id="image3">
+                              <object class="GtkLabel" id="label46">
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
-                                <property name="stock">gtk-help</property>
+                                <property name="xalign">1</property>
+                                <property name="yalign">0</property>
+                                <property name="label" translatable="yes">_Description:</property>
+                                <property name="use_markup">True</property>
+                                <property name="use_underline">True</property>
+                                <property name="mnemonic_widget">email_entry</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">0</property>
+                                <property name="top_attach">0</property>
+                                <property name="width">1</property>
+                                <property name="height">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkEntry" id="email_entry">
+                                <property name="width_request">180</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="invisible_char">●</property>
+                                <property name="activates_default">True</property>
+                                <property name="invisible_char_set">True</property>
                               </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="top_attach">0</property>
+                                <property name="width">1</property>
+                                <property name="height">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="label53">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="xalign">0</property>
+                                <property name="xpad">3</property>
+                                <property name="label" translatable="yes">Your email address, or a reminder 
of what this key is for.</property>
+                                <property name="wrap">True</property>
+                                <attributes>
+                                 <attribute name="style" value="italic"/>
+                                </attributes>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="top_attach">1</property>
+                                <property name="width">1</property>
+                                <property name="height">1</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <placeholder/>
                             </child>
                           </object>
                         </child>
                       </object>
                       <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
                         <property name="position">1</property>
                       </packing>
                     </child>
@@ -106,25 +194,24 @@
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkAlignment" id="alignment7">
+                  <object class="GtkExpander" id="expander1">
                     <property name="visible">True</property>
-                    <property name="can_focus">False</property>
+                    <property name="can_focus">True</property>
                     <child>
-                      <object class="GtkGrid" id="grid1">
+                      <object class="GtkGrid" id="details_grid">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
+                        <property name="margin_left">20</property>
                         <property name="row_spacing">6</property>
                         <property name="column_spacing">12</property>
                         <child>
-                          <object class="GtkLabel" id="label46">
+                          <object class="GtkLabel" id="label49">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="xalign">1</property>
-                            <property name="yalign">0</property>
-                            <property name="label" translatable="yes">_Description:</property>
-                            <property name="use_markup">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Encryption _Type:</property>
                             <property name="use_underline">True</property>
-                            <property name="mnemonic_widget">email-entry</property>
+                            <property name="mnemonic_widget">algorithm_combo_box</property>
                           </object>
                           <packing>
                             <property name="left_attach">0</property>
@@ -134,43 +221,61 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkEntry" id="email-entry">
-                            <property name="width_request">180</property>
+                          <object class="GtkLabel" id="label50">
                             <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="invisible_char">●</property>
-                            <property name="activates_default">True</property>
-                            <property name="invisible_char_set">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">Key _Strength (bits):</property>
+                            <property name="use_underline">True</property>
                           </object>
                           <packing>
-                            <property name="left_attach">1</property>
-                            <property name="top_attach">0</property>
+                            <property name="left_attach">0</property>
+                            <property name="top_attach">1</property>
                             <property name="width">1</property>
                             <property name="height">1</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkLabel" id="label53">
+                          <object class="GtkAlignment" id="alignment4">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
                             <property name="xalign">0</property>
-                            <property name="xpad">3</property>
-                            <property name="label" translatable="yes">Your email address, or a reminder of 
what this key is for.</property>
-                            <property name="wrap">True</property>
-                            <attributes>
-                             <attribute name="style" value="italic"/>
-                            </attributes>
+                            <property name="yalign">0</property>
+                            <property name="xscale">0</property>
+                            <child>
+                              <object class="GtkComboBoxText" id="algorithm_combo_box">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="entry_text_column">0</property>
+                                <property name="id_column">1</property>
+                                <items>
+                                  <item translatable="yes">RSA</item>
+                                  <item translatable="yes">DSA</item>
+                                  <item translatable="yes">ECDSA</item>
+                                  <item translatable="yes">ED25519</item>
+                                </items>
+                                <signal name="changed" handler="on_algo_changed"/>
+                              </object>
+                            </child>
                           </object>
                           <packing>
                             <property name="left_attach">1</property>
-                            <property name="top_attach">1</property>
+                            <property name="top_attach">0</property>
                             <property name="width">1</property>
                             <property name="height">1</property>
                           </packing>
                         </child>
-                        <child>
-                          <placeholder/>
-                        </child>
+                      </object>
+                    </child>
+                    <child type="label">
+                      <object class="GtkLabel" id="label48">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">_Advanced key options</property>
+                        <property name="use_underline">True</property>
+                        <attributes>
+                         <attribute name="weight" value="bold"/>
+                        </attributes>
                       </object>
                     </child>
                   </object>
@@ -180,96 +285,19 @@
                     <property name="position">1</property>
                   </packing>
                 </child>
-              </object>
-              <packing>
-                <property name="expand">True</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkExpander" id="expander1">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
                 <child>
-                  <object class="GtkGrid" id="details_grid">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="margin_left">20</property>
-                    <property name="row_spacing">6</property>
-                    <property name="column_spacing">12</property>
-                    <child>
-                      <object class="GtkLabel" id="label49">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">Encryption _Type:</property>
-                        <property name="use_underline">True</property>
-                        <property name="mnemonic_widget">algorithm-combo-box</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">0</property>
-                        <property name="width">1</property>
-                        <property name="height">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label50">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">Key _Strength (bits):</property>
-                        <property name="use_underline">True</property>
-                      </object>
-                      <packing>
-                        <property name="left_attach">0</property>
-                        <property name="top_attach">1</property>
-                        <property name="width">1</property>
-                        <property name="height">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkAlignment" id="alignment4">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="xalign">0</property>
-                        <property name="yalign">0</property>
-                        <property name="xscale">0</property>
-                        <child>
-                          <object class="GtkComboBoxText" id="algorithm-combo-box">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="entry_text_column">0</property>
-                            <property name="id_column">1</property>
-                            <items>
-                              <item translatable="yes">RSA</item>
-                              <item translatable="yes">DSA</item>
-                              <item translatable="yes">ECDSA</item>
-                              <item translatable="yes">ED25519</item>
-                            </items>
-                          </object>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="left_attach">1</property>
-                        <property name="top_attach">0</property>
-                        <property name="width">1</property>
-                        <property name="height">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                </child>
-                <child type="label">
-                  <object class="GtkLabel" id="label48">
+                  <object class="GtkLabel" id="label54">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">_Advanced key options</property>
-                    <property name="use_underline">True</property>
-                    <attributes>
-                     <attribute name="weight" value="bold"/>
-                    </attributes>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">If there is a computer you want to use this 
key with, you can set up that computer to recognize your new key.</property>
+                    <property name="wrap">True</property>
                   </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">2</property>
+                  </packing>
                 </child>
               </object>
               <packing>
@@ -278,63 +306,46 @@
                 <property name="position">1</property>
               </packing>
             </child>
-            <child>
-              <object class="GtkLabel" id="label54">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="xalign">0</property>
-                <property name="label" translatable="yes">If there is a computer you want to use this key 
with, you can set up that computer to recognize your new key.</property>
-                <property name="wrap">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">2</property>
-              </packing>
-            </child>
           </object>
           <packing>
-            <property name="expand">True</property>
+            <property name="expand">False</property>
             <property name="fill">True</property>
             <property name="position">1</property>
           </packing>
         </child>
       </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="fill">True</property>
-        <property name="position">1</property>
-      </packing>
-    </child>
-  </object>
-  <object class="GtkButtonBox" id="action_area">
-    <property name="visible">True</property>
-    <property name="can_focus">False</property>
-    <child>
-      <object class="GtkButton" id="create-no-setup">
-        <property name="label" translatable="yes">_Just Create Key</property>
-        <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="can_default">True</property>
-        <property name="receives_default">False</property>
-        <property name="use_underline">True</property>
-      </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="fill">False</property>
-      </packing>
     </child>
-    <child>
-      <object class="GtkButton" id="create-with-setup">
-        <property name="label" translatable="yes">_Create and Set Up</property>
+    <child internal-child="action_area">
+      <object class="GtkButtonBox" id="action_area">
         <property name="visible">True</property>
-        <property name="can_focus">True</property>
-        <property name="use_underline">True</property>
+        <property name="can_focus">False</property>
+        <child>
+          <object class="GtkButton" id="create_no_setup_button">
+            <property name="label" translatable="yes">_Just Create Key</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="can_default">True</property>
+            <property name="receives_default">False</property>
+            <property name="use_underline">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="create_with_setup_button">
+            <property name="label" translatable="yes">_Create and Set Up</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="use_underline">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+          </packing>
+        </child>
       </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="fill">False</property>
-      </packing>
     </child>
-  </object>
+  </template>
 </interface>
diff --git a/ssh/seahorse-ssh-key-properties.ui b/ssh/seahorse-ssh-key-properties.ui
index bacc182..8186a66 100644
--- a/ssh/seahorse-ssh-key-properties.ui
+++ b/ssh/seahorse-ssh-key-properties.ui
@@ -1,464 +1,473 @@
 <?xml version="1.0"?>
 <interface>
-  <requires lib="gtk+" version="3.0"/>
-  <!-- interface-naming-policy toplevel-contextual -->
+  <requires lib="gtk+" version="3.22"/>
   <object class="GtkImage" id="passphrase-image">
     <property name="stock">gtk-edit</property>
   </object>
   <object class="GtkImage" id="export-image">
     <property name="stock">gtk-save-as</property>
   </object>
-  <object class="GtkBox" id="ssh-key-properties">
-    <property name="visible">True</property>
-    <property name="orientation">vertical</property>
-    <property name="spacing">2</property>
-    <child>
-      <object class="GtkNotebook" id="notebook">
+
+  <template class="SeahorseSshKeyProperties" parent="GtkDialog">
+    <property name="resizable">False</property>
+    <child internal-child="vbox">
+      <object class="GtkBox">
         <property name="visible">True</property>
-        <property name="can_focus">True</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
         <property name="border_width">5</property>
         <child>
-          <object class="GtkBox" id="vbox7">
+          <object class="GtkNotebook" id="notebook">
             <property name="visible">True</property>
-            <property name="orientation">vertical</property>
-            <property name="border_width">12</property>
-            <property name="spacing">12</property>
+            <property name="can_focus">True</property>
+            <property name="border_width">5</property>
             <child>
-              <object class="GtkHBox" id="hbox61">
+              <object class="GtkBox" id="vbox7">
                 <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <property name="border_width">12</property>
+                <property name="spacing">12</property>
                 <child>
-                  <object class="GtkImage" id="key-image">
-                    <property name="visible">True</property>
-                    <property name="yalign">0</property>
-                    <property name="stock">gtk-missing-image</property>
-                    <property name="icon-size">6</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkGrid">
+                  <object class="GtkHBox" id="hbox61">
                     <property name="visible">True</property>
-                    <property name="column_spacing">12</property>
-                    <property name="row_spacing">3</property>
-                    <child>
-                      <object class="GtkLabel">
-                        <property name="visible">True</property>
-                        <property name="xalign">1</property>
-                        <property name="label" translatable="yes" context="name-of-ssh-key" comments="Name 
of key, often a persons name">Name:</property>
-                        <attributes>
-                         <attribute name="weight" value="bold"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="top_attach">0</property>
-                        <property name="left_attach">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkEntry" id="comment-entry">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="activates_default">True</property>
-                      </object>
-                      <packing>
-                        <property name="top_attach">0</property>
-                        <property name="left_attach">1</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel">
-                        <property name="visible">True</property>
-                        <property name="xalign">1</property>
-                        <property name="label" translatable="yes">Type:</property>
-                        <attributes>
-                         <attribute name="weight" value="bold"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="top_attach">1</property>
-                        <property name="left_attach">0</property>
-                      </packing>
-                    </child>
                     <child>
-                      <object class="GtkLabel" id="type-label">
+                      <object class="GtkImage" id="key_image">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">Secure Shell Key</property>
-                        <property name="selectable">True</property>
+                        <property name="yalign">0</property>
+                        <property name="stock">gtk-missing-image</property>
+                        <property name="icon-size">6</property>
                       </object>
                       <packing>
-                        <property name="top_attach">1</property>
-                        <property name="left_attach">1</property>
+                        <property name="expand">False</property>
+                        <property name="position">0</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkLabel">
-                        <property name="visible">True</property>
-                        <property name="halign">start</property>
-                        <property name="label" translatable="yes">Identifier:</property>
-                        <attributes>
-                         <attribute name="weight" value="bold"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="top_attach">2</property>
-                        <property name="left_attach">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="id-label">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="xalign">0</property>
-                        <property name="label"></property>
-                        <property name="selectable">True</property>
-                      </object>
-                      <packing>
-                        <property name="top_attach">2</property>
-                        <property name="left_attach">1</property>
-                      </packing>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkAlignment" id="alignment42">
-                <property name="visible">True</property>
-                <property name="xalign">1</property>
-                <property name="xscale">0</property>
-                <property name="yscale">0</property>
-                <child>
-                  <object class="GtkButton" id="passphrase-button">
-                    <property name="label" translatable="yes">Change _Passphrase</property>
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="image">passphrase-image</property>
-                    <property name="use_underline">True</property>
-                    <signal name="clicked" handler="on_ssh_passphrase_button_clicked"/>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkBox" id="vbox28">
-                <property name="visible">True</property>
-                <property name="orientation">vertical</property>
-                <property name="spacing">6</property>
-                <child>
-                  <object class="GtkLabel" id="label22226">
-                    <property name="visible">True</property>
-                    <property name="xalign">0</property>
-                    <property name="label" translatable="yes">Trust</property>
-                    <attributes>
-                     <attribute name="weight" value="bold"/>
-                    </attributes>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">False</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkAlignment" id="alignment46">
-                    <property name="visible">True</property>
-                    <property name="left_padding">12</property>
-                    <child>
-                      <object class="GtkBox" id="vbox29">
-                        <property name="visible">True</property>
-                        <property name="orientation">vertical</property>
-                        <property name="spacing">6</property>
-                        <child>
-                          <object class="GtkCheckButton" id="trust-check">
-                            <property name="label" translatable="yes">The owner of this key is _authorized 
to connect to this computer</property>
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="receives_default">False</property>
-                            <property name="use_underline">True</property>
-                            <property name="draw_indicator">True</property>
-                            <signal name="toggled" handler="on_ssh_trust_toggled"/>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                            <property name="position">0</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkLabel" id="trust-message">
-                            <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes">This only applies to the 
&lt;i&gt;%s&lt;/i&gt; account.</property>
-                            <property name="use_markup">True</property>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="fill">False</property>
-                            <property name="position">1</property>
-                          </packing>
-                        </child>
-                      </object>
-                    </child>
-                  </object>
-                  <packing>
-                    <property name="position">1</property>
-                  </packing>
-                </child>
-              </object>
-              <packing>
-                <property name="position">2</property>
-              </packing>
-            </child>
-          </object>
-          <packing>
-            <property name="tab_fill">False</property>
-          </packing>
-        </child>
-        <child type="tab">
-          <object class="GtkLabel" id="label1">
-            <property name="visible">True</property>
-            <property name="xpad">3</property>
-            <property name="label" translatable="yes">Key</property>
-          </object>
-          <packing>
-            <property name="tab_fill">False</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkBox" id="vbox8">
-            <property name="visible">True</property>
-            <property name="border_width">12</property>
-            <property name="orientation">vertical</property>
-            <property name="spacing">12</property>
-            <child>
-              <object class="GtkFrame" id="frame4">
-                <property name="visible">True</property>
-                <property name="label_xalign">0</property>
-                <property name="shadow_type">none</property>
-                <child>
-                  <object class="GtkAlignment" id="alignment29">
-                    <property name="visible">True</property>
-                    <property name="top_padding">6</property>
-                    <property name="left_padding">12</property>
-                    <child>
-                      <object class="GtkTable" id="table10">
+                      <object class="GtkGrid">
                         <property name="visible">True</property>
-                        <property name="n_rows">4</property>
-                        <property name="n_columns">2</property>
                         <property name="column_spacing">12</property>
-                        <property name="row_spacing">6</property>
+                        <property name="row_spacing">3</property>
                         <child>
-                          <object class="GtkLabel" id="label109">
+                          <object class="GtkLabel">
                             <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="yalign">0</property>
-                            <property name="label" translatable="yes">Algorithm:</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes" context="name-of-ssh-key" 
comments="Name of key, often a persons name">Name:</property>
                             <attributes>
                              <attribute name="weight" value="bold"/>
                             </attributes>
                           </object>
                           <packing>
-                            <property name="x_options">GTK_FILL</property>
-                            <property name="y_options"></property>
+                            <property name="top_attach">0</property>
+                            <property name="left_attach">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkLabel" id="label25">
+                          <object class="GtkEntry" id="comment_entry">
                             <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="yalign">0</property>
-                            <property name="label" translatable="yes">Key length:</property>
-                            <attributes>
-                             <attribute name="weight" value="bold"/>
-                            </attributes>
+                            <property name="can_focus">True</property>
+                            <property name="activates_default">True</property>
+                            <signal name="activate" handler="on_ssh_comment_activate"/>
+                            <signal name="focus_out_event" handler="on_ssh_comment_focus_out"/>
                           </object>
                           <packing>
-                            <property name="top_attach">1</property>
-                            <property name="bottom_attach">2</property>
-                            <property name="x_options">GTK_FILL</property>
-                            <property name="y_options"></property>
+                            <property name="top_attach">0</property>
+                            <property name="left_attach">1</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkLabel" id="algo-label">
+                          <object class="GtkLabel">
                             <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="xalign">0</property>
-                            <property name="label"></property>
-                            <property name="selectable">True</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">Type:</property>
+                            <attributes>
+                             <attribute name="weight" value="bold"/>
+                            </attributes>
                           </object>
                           <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                            <property name="x_options">GTK_FILL</property>
-                            <property name="y_options"></property>
+                            <property name="top_attach">1</property>
+                            <property name="left_attach">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkLabel" id="key-length-label">
+                          <object class="GtkLabel" id="type_label">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="xalign">0</property>
-                            <property name="label"></property>
+                            <property name="label" translatable="yes">Secure Shell Key</property>
                             <property name="selectable">True</property>
                           </object>
                           <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
                             <property name="top_attach">1</property>
-                            <property name="bottom_attach">2</property>
-                            <property name="x_options">GTK_FILL</property>
-                            <property name="y_options"></property>
+                            <property name="left_attach">1</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkLabel" id="label113">
+                          <object class="GtkLabel">
                             <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes">Location:</property>
+                            <property name="halign">start</property>
+                            <property name="label" translatable="yes">Identifier:</property>
                             <attributes>
                              <attribute name="weight" value="bold"/>
                             </attributes>
                           </object>
                           <packing>
                             <property name="top_attach">2</property>
-                            <property name="bottom_attach">3</property>
-                            <property name="x_options">GTK_FILL</property>
-                            <property name="y_options"></property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkLabel" id="label22231">
-                            <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes">Fingerprint:</property>
-                            <attributes>
-                             <attribute name="weight" value="bold"/>
-                            </attributes>
-                          </object>
-                          <packing>
-                            <property name="top_attach">3</property>
-                            <property name="bottom_attach">4</property>
-                            <property name="x_options">GTK_FILL</property>
-                            <property name="y_options"></property>
+                            <property name="left_attach">0</property>
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkLabel" id="fingerprint-label">
+                          <object class="GtkLabel" id="id_label">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="xalign">0</property>
-                            <property name="yalign">0</property>
                             <property name="label"></property>
                             <property name="selectable">True</property>
                           </object>
                           <packing>
+                            <property name="top_attach">2</property>
                             <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                            <property name="top_attach">3</property>
-                            <property name="bottom_attach">4</property>
-                            <property name="x_options">GTK_FILL</property>
-                            <property name="y_options"></property>
                           </packing>
                         </child>
+                      </object>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkAlignment" id="alignment42">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="xscale">0</property>
+                    <property name="yscale">0</property>
+                    <child>
+                      <object class="GtkButton" id="passphrase_button">
+                        <property name="label" translatable="yes">Change _Passphrase</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="image">passphrase-image</property>
+                        <property name="use_underline">True</property>
+                        <signal name="clicked" handler="on_ssh_passphrase_button_clicked"/>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox" id="vbox28">
+                    <property name="visible">True</property>
+                    <property name="orientation">vertical</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="label22226">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Trust</property>
+                        <attributes>
+                         <attribute name="weight" value="bold"/>
+                        </attributes>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkAlignment" id="alignment46">
+                        <property name="visible">True</property>
+                        <property name="left_padding">12</property>
                         <child>
-                          <object class="GtkLabel" id="location-label">
+                          <object class="GtkBox" id="vbox29">
                             <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="xalign">0</property>
-                            <property name="yalign">0</property>
-                            <property name="label"></property>
-                            <property name="use_markup">True</property>
-                            <property name="selectable">True</property>
-                            <property name="ellipsize">start</property>
+                            <property name="orientation">vertical</property>
+                            <property name="spacing">6</property>
+                            <child>
+                              <object class="GtkCheckButton" id="trust_check">
+                                <property name="label" translatable="yes">The owner of this key is 
_authorized to connect to this computer</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="use_underline">True</property>
+                                <property name="draw_indicator">True</property>
+                                <signal name="toggled" handler="on_ssh_trust_toggled"/>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="trust_message">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">This only applies to the 
&lt;i&gt;%s&lt;/i&gt; account.</property>
+                                <property name="use_markup">True</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">False</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
                           </object>
-                          <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                            <property name="top_attach">2</property>
-                            <property name="bottom_attach">3</property>
-                            <property name="y_options"></property>
-                          </packing>
                         </child>
                       </object>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
                     </child>
                   </object>
-                </child>
-                <child type="label">
-                  <object class="GtkLabel" id="label108">
-                    <property name="visible">True</property>
-                    <property name="label" translatable="yes">Technical Details:</property>
-                    <attributes>
-                     <attribute name="weight" value="bold"/>
-                    </attributes>
-                  </object>
+                  <packing>
+                    <property name="position">2</property>
+                  </packing>
                 </child>
               </object>
               <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
+            <child type="tab">
+              <object class="GtkLabel" id="label1">
+                <property name="visible">True</property>
+                <property name="xpad">3</property>
+                <property name="label" translatable="yes">Key</property>
+              </object>
+              <packing>
+                <property name="tab_fill">False</property>
               </packing>
             </child>
             <child>
-              <object class="GtkAlignment" id="alignment44">
+              <object class="GtkBox" id="vbox8">
                 <property name="visible">True</property>
-                <property name="xalign">1</property>
-                <property name="xscale">0</property>
-                <property name="yscale">0</property>
+                <property name="border_width">12</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">12</property>
+                <child>
+                  <object class="GtkFrame" id="frame4">
+                    <property name="visible">True</property>
+                    <property name="label_xalign">0</property>
+                    <property name="shadow_type">none</property>
+                    <child>
+                      <object class="GtkAlignment" id="alignment29">
+                        <property name="visible">True</property>
+                        <property name="top_padding">6</property>
+                        <property name="left_padding">12</property>
+                        <child>
+                          <object class="GtkTable" id="table10">
+                            <property name="visible">True</property>
+                            <property name="n_rows">4</property>
+                            <property name="n_columns">2</property>
+                            <property name="column_spacing">12</property>
+                            <property name="row_spacing">6</property>
+                            <child>
+                              <object class="GtkLabel" id="label109">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="yalign">0</property>
+                                <property name="label" translatable="yes">Algorithm:</property>
+                                <attributes>
+                                 <attribute name="weight" value="bold"/>
+                                </attributes>
+                              </object>
+                              <packing>
+                                <property name="x_options">GTK_FILL</property>
+                                <property name="y_options"></property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="label25">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="yalign">0</property>
+                                <property name="label" translatable="yes">Key length:</property>
+                                <attributes>
+                                 <attribute name="weight" value="bold"/>
+                                </attributes>
+                              </object>
+                              <packing>
+                                <property name="top_attach">1</property>
+                                <property name="bottom_attach">2</property>
+                                <property name="x_options">GTK_FILL</property>
+                                <property name="y_options"></property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="algo_label">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label"></property>
+                                <property name="selectable">True</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="x_options">GTK_FILL</property>
+                                <property name="y_options"></property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="key_length_label">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label"></property>
+                                <property name="selectable">True</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">1</property>
+                                <property name="bottom_attach">2</property>
+                                <property name="x_options">GTK_FILL</property>
+                                <property name="y_options"></property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="label113">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Location:</property>
+                                <attributes>
+                                 <attribute name="weight" value="bold"/>
+                                </attributes>
+                              </object>
+                              <packing>
+                                <property name="top_attach">2</property>
+                                <property name="bottom_attach">3</property>
+                                <property name="x_options">GTK_FILL</property>
+                                <property name="y_options"></property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="label22231">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Fingerprint:</property>
+                                <attributes>
+                                 <attribute name="weight" value="bold"/>
+                                </attributes>
+                              </object>
+                              <packing>
+                                <property name="top_attach">3</property>
+                                <property name="bottom_attach">4</property>
+                                <property name="x_options">GTK_FILL</property>
+                                <property name="y_options"></property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="fingerprint_label">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="xalign">0</property>
+                                <property name="yalign">0</property>
+                                <property name="label"></property>
+                                <property name="selectable">True</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">3</property>
+                                <property name="bottom_attach">4</property>
+                                <property name="x_options">GTK_FILL</property>
+                                <property name="y_options"></property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkLabel" id="location_label">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="xalign">0</property>
+                                <property name="yalign">0</property>
+                                <property name="label"></property>
+                                <property name="use_markup">True</property>
+                                <property name="selectable">True</property>
+                                <property name="ellipsize">start</property>
+                              </object>
+                              <packing>
+                                <property name="left_attach">1</property>
+                                <property name="right_attach">2</property>
+                                <property name="top_attach">2</property>
+                                <property name="bottom_attach">3</property>
+                                <property name="y_options"></property>
+                              </packing>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                    </child>
+                    <child type="label">
+                      <object class="GtkLabel" id="label108">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">Technical Details:</property>
+                        <attributes>
+                         <attribute name="weight" value="bold"/>
+                        </attributes>
+                      </object>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
                 <child>
-                  <object class="GtkButton" id="export-button">
-                    <property name="label" translatable="yes">E_xport Complete Key</property>
+                  <object class="GtkAlignment" id="alignment44">
                     <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="receives_default">False</property>
-                    <property name="image">export-image</property>
-                    <property name="use_underline">True</property>
+                    <property name="xalign">1</property>
+                    <property name="xscale">0</property>
+                    <property name="yscale">0</property>
+                    <child>
+                      <object class="GtkButton" id="export_button">
+                        <property name="label" translatable="yes">E_xport Complete Key</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">False</property>
+                        <property name="image">export-image</property>
+                        <property name="use_underline">True</property>
+                        <signal name="clicked" handler="on_ssh_export_button_clicked"/>
+                      </object>
+                    </child>
                   </object>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
                 </child>
               </object>
               <packing>
                 <property name="position">1</property>
               </packing>
             </child>
+            <child type="tab">
+              <object class="GtkLabel" id="label22222">
+                <property name="visible">True</property>
+                <property name="xpad">3</property>
+                <property name="label" translatable="yes">Details</property>
+              </object>
+              <packing>
+                <property name="position">1</property>
+                <property name="tab_fill">False</property>
+              </packing>
+            </child>
           </object>
           <packing>
             <property name="position">1</property>
           </packing>
         </child>
-        <child type="tab">
-          <object class="GtkLabel" id="label22222">
-            <property name="visible">True</property>
-            <property name="xpad">3</property>
-            <property name="label" translatable="yes">Details</property>
-          </object>
-          <packing>
-            <property name="position">1</property>
-            <property name="tab_fill">False</property>
-          </packing>
-        </child>
       </object>
-      <packing>
-        <property name="position">1</property>
-      </packing>
     </child>
-  </object>
+  </template>
 </interface>
diff --git a/ssh/seahorse-ssh-upload.ui b/ssh/seahorse-ssh-upload.ui
index 41e8442..3f53c66 100644
--- a/ssh/seahorse-ssh-upload.ui
+++ b/ssh/seahorse-ssh-upload.ui
@@ -1,147 +1,169 @@
 <?xml version="1.0"?>
 <interface>
-  <requires lib="gtk+" version="2.16"/>
-  <!-- interface-naming-policy toplevel-contextual -->
-  <object class="GtkBox" id="ssh-upload">
-    <property name="visible">True</property>
-    <property name="orientation">vertical</property>
-    <property name="spacing">2</property>
-    <child>
-      <object class="GtkBox" id="vbox1">
+  <requires lib="gtk+" version="3.22"/>
+  <template class="SeahorseSshUpload" parent="GtkDialog">
+    <property name="title" translatable="yes">Set Up Computer for SSH Connection</property>
+    <property name="resizable">False</property>
+    <property name="default_width">400</property>
+    <property name="border_width">5</property>
+    <property name="modal">True</property>
+    <property name="skip_taskbar_hint">True</property>
+    <property name="skip_pager_hint">True</property>
+    <property name="window_position">center-on-parent</property>
+    <child internal-child="vbox">
+      <object class="GtkBox">
         <property name="visible">True</property>
         <property name="orientation">vertical</property>
-        <property name="border_width">5</property>
-        <property name="spacing">12</property>
+        <property name="spacing">2</property>
         <child>
-          <object class="GtkBox" id="vbox2">
+          <object class="GtkBox" id="vbox1">
             <property name="visible">True</property>
             <property name="orientation">vertical</property>
+            <property name="border_width">5</property>
             <property name="spacing">12</property>
             <child>
-              <object class="GtkLabel" id="label5">
-                <property name="width_request">380</property>
+              <object class="GtkBox" id="vbox2">
                 <property name="visible">True</property>
-                <property name="label" translatable="yes">To use your Secure Shell key with another computer 
that uses SSH, you must already have a login account on that computer.</property>
-                <property name="wrap">True</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">False</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkTable" id="table1">
-                <property name="visible">True</property>
-                <property name="n_rows">2</property>
-                <property name="n_columns">2</property>
-                <property name="column_spacing">12</property>
-                <property name="row_spacing">6</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">12</property>
                 <child>
-                  <object class="GtkBox" id="vbox3">
+                  <object class="GtkLabel" id="label5">
+                    <property name="width_request">380</property>
                     <property name="visible">True</property>
-                    <property name="orientation">vertical</property>
-                    <property name="spacing">3</property>
+                    <property name="label" translatable="yes">To use your Secure Shell key with another 
computer that uses SSH, you must already have a login account on that computer.</property>
+                    <property name="wrap">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkTable" id="table1">
+                    <property name="visible">True</property>
+                    <property name="n_rows">2</property>
+                    <property name="n_columns">2</property>
+                    <property name="column_spacing">12</property>
+                    <property name="row_spacing">6</property>
                     <child>
-                      <object class="GtkEntry" id="host-entry">
+                      <object class="GtkBox" id="vbox3">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="has_focus">True</property>
-                        <property name="tooltip_text" translatable="yes">The host name or address of the 
server.</property>
-                        <property name="invisible_char">&#x25CF;</property>
-                        <property name="activates_default">True</property>
+                        <property name="orientation">vertical</property>
+                        <property name="spacing">3</property>
+                        <child>
+                          <object class="GtkEntry" id="host_entry">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="has_focus">True</property>
+                            <property name="tooltip_text" translatable="yes">The host name or address of the 
server.</property>
+                            <property name="invisible_char">&#x25CF;</property>
+                            <property name="activates_default">True</property>
+                            <signal name="changed" handler="on_upload_input_changed"/>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkLabel" id="label7">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">eg: 
fileserver.example.com:port</property>
+                            <attributes>
+                             <attribute name="style" value="italic"/>
+                            </attributes>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
                       </object>
                       <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options">GTK_FILL</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkLabel" id="label7">
+                      <object class="GtkLabel" id="label3">
                         <property name="visible">True</property>
-                        <property name="xalign">0</property>
-                        <property name="label" translatable="yes">eg: fileserver.example.com:port</property>
-                        <attributes>
-                         <attribute name="style" value="italic"/>
-                        </attributes>
+                        <property name="xalign">1</property>
+                        <property name="yalign">0</property>
+                        <property name="ypad">4</property>
+                        <property name="label" translatable="yes">_Server address:</property>
+                        <property name="use_underline">True</property>
                       </object>
                       <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">1</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options">GTK_FILL</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label2">
+                        <property name="visible">True</property>
+                        <property name="xalign">1</property>
+                        <property name="label" translatable="yes">_Login name:</property>
+                        <property name="use_underline">True</property>
+                        <property name="mnemonic_widget">user_entry</property>
+                      </object>
+                      <packing>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="x_options">GTK_FILL</property>
+                        <property name="y_options"></property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkEntry" id="user_entry">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="has_focus">True</property>
+                        <property name="tooltip_text" translatable="yes">The host name or address of the 
server.</property>
+                        <property name="invisible_char">&#x25CF;</property>
+                        <property name="activates_default">True</property>
+                        <signal name="changed" handler="on_upload_input_changed"/>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="right_attach">2</property>
+                        <property name="top_attach">1</property>
+                        <property name="bottom_attach">2</property>
+                        <property name="y_options"></property>
                       </packing>
                     </child>
                   </object>
                   <packing>
-                    <property name="left_attach">1</property>
-                    <property name="right_attach">2</property>
-                    <property name="x_options">GTK_FILL</property>
-                    <property name="y_options">GTK_FILL</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="label3">
-                    <property name="visible">True</property>
-                    <property name="xalign">1</property>
-                    <property name="yalign">0</property>
-                    <property name="ypad">4</property>
-                    <property name="label" translatable="yes">_Server address:</property>
-                    <property name="use_underline">True</property>
-                  </object>
-                  <packing>
-                    <property name="x_options">GTK_FILL</property>
-                    <property name="y_options">GTK_FILL</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkLabel" id="label2">
-                    <property name="visible">True</property>
-                    <property name="xalign">1</property>
-                    <property name="label" translatable="yes">_Login name:</property>
-                    <property name="use_underline">True</property>
-                    <property name="mnemonic_widget">user-entry</property>
-                  </object>
-                  <packing>
-                    <property name="top_attach">1</property>
-                    <property name="bottom_attach">2</property>
-                    <property name="x_options">GTK_FILL</property>
-                    <property name="y_options"></property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkEntry" id="user-entry">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="has_focus">True</property>
-                    <property name="tooltip_text" translatable="yes">The host name or address of the 
server.</property>
-                    <property name="invisible_char">&#x25CF;</property>
-                    <property name="activates_default">True</property>
-                  </object>
-                  <packing>
-                    <property name="left_attach">1</property>
-                    <property name="right_attach">2</property>
-                    <property name="top_attach">1</property>
-                    <property name="bottom_attach">2</property>
-                    <property name="y_options"></property>
+                    <property name="position">1</property>
                   </packing>
                 </child>
               </object>
               <packing>
-                <property name="position">1</property>
+                <property name="expand">False</property>
+                <property name="position">0</property>
               </packing>
             </child>
           </object>
           <packing>
             <property name="expand">False</property>
-            <property name="position">0</property>
+            <property name="position">1</property>
           </packing>
         </child>
       </object>
-      <packing>
-        <property name="expand">False</property>
-        <property name="position">1</property>
-      </packing>
     </child>
-  </object>
+    <child type="action">
+      <object class="GtkButton" id="setup_button">
+        <property name="visible">True</property>
+        <property name="label" translatable="yes">Set Up</property>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="ok">setup_button</action-widget>
+    </action-widgets>
+  </template>
 </interface>
diff --git a/ssh/upload.vala b/ssh/upload.vala
index 75d6611..8faf9b4 100644
--- a/ssh/upload.vala
+++ b/ssh/upload.vala
@@ -19,29 +19,22 @@
  * <http://www.gnu.org/licenses/>.
  */
 
+[GtkTemplate (ui = "/org/gnome/Seahorse/seahorse-ssh-upload.ui")]
 public class Seahorse.Ssh.Upload : Gtk.Dialog {
 
     private unowned List<Key> keys;
 
+    [GtkChild]
     private Gtk.Entry user_entry;
+    [GtkChild]
     private Gtk.Entry host_entry;
-    private Gtk.Button ok_button;
+    [GtkChild]
+    private Gtk.Button setup_button;
 
     public Upload(List<Key> keys, Gtk.Window? parent) {
-        GLib.Object(border_width: 5,
-                    title: _("Set Up Computer for SSH Connection"),
-                    resizable: false,
-                    default_width: 400,
-                    skip_taskbar_hint: true,
-                    skip_pager_hint: true,
-                    window_position: Gtk.WindowPosition.CENTER_ON_PARENT,
-                    modal: true,
-                    transient_for: parent);
-
+        this.transient_for = parent;
         this.keys = keys;
 
-        load_ui();
-
         // Default to the users current name
         this.user_entry.text = Environment.get_user_name();
         // Focus the host
@@ -50,26 +43,6 @@ public class Seahorse.Ssh.Upload : Gtk.Dialog {
         on_upload_input_changed();
     }
 
-    // FIXME: normally we would do this using GtkTemplate, but this is quite hard with the current build 
setup
-    private void load_ui() {
-        Gtk.Builder builder = new Gtk.Builder();
-        try {
-            string path = "/org/gnome/Seahorse/seahorse-ssh-upload.ui";
-            builder.add_from_resource(path);
-        } catch (GLib.Error err) {
-            GLib.critical("%s", err.message);
-        }
-        Gtk.Container content = (Gtk.Container) builder.get_object("ssh-upload");
-        ((Gtk.Container)this.get_content_area()).add(content);
-
-        this.host_entry = (Gtk.Entry) builder.get_object("host-entry");
-        this.host_entry.changed.connect(on_upload_input_changed);
-        this.user_entry = (Gtk.Entry) builder.get_object("user-entry");
-        this.user_entry.changed.connect(on_upload_input_changed);
-
-        this.ok_button = (Gtk.Button) add_button(_("Set Up"), Gtk.ResponseType.OK);
-    }
-
     private void upload_keys() {
         string user = this.user_entry.text.strip();
         string host_port = this.host_entry.text.strip();
@@ -97,6 +70,7 @@ public class Seahorse.Ssh.Upload : Gtk.Dialog {
         Seahorse.Progress.show(cancellable, _("Configuring Secure Shell Keys…"), false);
     }
 
+    [GtkCallback]
     private void on_upload_input_changed () {
         string user = this.user_entry.text;
         string host = this.host_entry.text;
@@ -110,7 +84,7 @@ public class Seahorse.Ssh.Upload : Gtk.Dialog {
             host = host.substring(0, port_pos);
         }
 
-        this.ok_button.sensitive = (host.strip() != "") && (user.strip() != "");
+        this.setup_button.sensitive = (host.strip() != "") && (user.strip() != "");
     }
 
     /**


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