[gnome-control-center/wip/gbsneto/new-network-panel: 18/19] network: Update VPN section



commit 1a486908198c4a213cb3258357ace1bbc8c908ff
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Fri Jul 21 14:39:27 2017 -0300

    network: Update VPN section
    
    The last remaining network device to be updated is
    the VPN device, and this patch is the result of this
    effort.
    
    The changes were mostly towards cleaning up and
    removing unecessary code. By removing the info labels,
    many getters were removed as well.
    
    In order to achieve a listbox-like UI, a couple of
    UI refactorings.

 panels/network/cc-network-panel.c |   30 +++
 panels/network/net-vpn.c          |  141 +-------------
 panels/network/net-vpn.h          |    2 +
 panels/network/network-vpn.ui     |  363 +++++--------------------------------
 panels/network/network.ui         |   43 +++++-
 5 files changed, 133 insertions(+), 446 deletions(-)
---
diff --git a/panels/network/cc-network-panel.c b/panels/network/cc-network-panel.c
index 072c619..ad019a3 100644
--- a/panels/network/cc-network-panel.c
+++ b/panels/network/cc-network-panel.c
@@ -65,6 +65,7 @@ struct _CcNetworkPanel
         GtkWidget        *box_proxy;
         GtkWidget        *box_vpn;
         GtkWidget        *box_wired;
+        GtkWidget        *empty_listbox;
 
         /* wireless dialog stuff */
         CmdlineOperation  arg_operation;
@@ -382,6 +383,28 @@ handle_argv (CcNetworkPanel *panel)
         g_debug ("Could not handle argv operation, no matching device yet?");
 }
 
+/* HACK: this function is basically a workaround. We don't have a single
+ * listbox in the VPN section, thus we need to track the separators and the
+ * stub row manually.
+ */
+static void
+update_vpn_section (CcNetworkPanel *self)
+{
+        guint i, n_vpns;
+
+        for (i = 0, n_vpns = 0; i < self->devices->len; i++) {
+                NetObject *net_object = g_ptr_array_index (self->devices, i);
+
+                if (!NET_IS_VPN (net_object))
+                        continue;
+
+                net_vpn_set_show_separator (NET_VPN (net_object), n_vpns > 0);
+                n_vpns++;
+        }
+
+        gtk_widget_set_visible (self->empty_listbox, n_vpns == 0);
+}
+
 static GtkWidget *
 add_device_stack (CcNetworkPanel *self, NetObject *object)
 {
@@ -504,6 +527,9 @@ panel_remove_device (CcNetworkPanel *panel, NMDevice *device)
                 return;
 
         g_ptr_array_remove (panel->devices, object);
+
+        /* update vpn widgets */
+        update_vpn_section (panel);
 }
 
 static void
@@ -663,6 +689,9 @@ panel_add_vpn_device (CcNetworkPanel *panel, NMConnection *connection)
         g_ptr_array_add (panel->devices, net_vpn);
 
         g_free (title);
+
+        /* update vpn widgets */
+        update_vpn_section (panel);
 }
 
 static void
@@ -788,6 +817,7 @@ cc_network_panel_class_init (CcNetworkPanelClass *klass)
         gtk_widget_class_bind_template_child (widget_class, CcNetworkPanel, box_proxy);
         gtk_widget_class_bind_template_child (widget_class, CcNetworkPanel, box_vpn);
         gtk_widget_class_bind_template_child (widget_class, CcNetworkPanel, box_wired);
+        gtk_widget_class_bind_template_child (widget_class, CcNetworkPanel, empty_listbox);
         gtk_widget_class_bind_template_child (widget_class, CcNetworkPanel, sizegroup);
 
         gtk_widget_class_bind_template_callback (widget_class, create_connection_cb);
diff --git a/panels/network/net-vpn.c b/panels/network/net-vpn.c
index a2e6905..47b7391 100644
--- a/panels/network/net-vpn.c
+++ b/panels/network/net-vpn.c
@@ -51,6 +51,16 @@ enum {
 
 G_DEFINE_TYPE (NetVpn, net_vpn, NET_TYPE_OBJECT)
 
+void
+net_vpn_set_show_separator (NetVpn   *self,
+                            gboolean  show_separator)
+{
+        GtkWidget *separator;
+
+        separator = GTK_WIDGET (gtk_builder_get_object (self->priv->builder, "separator"));
+        gtk_widget_set_visible (separator, show_separator);
+}
+
 static void
 connection_vpn_state_changed_cb (NMVpnConnection *connection,
                                  NMVpnConnectionState state,
@@ -136,98 +146,6 @@ net_vpn_get_state (NetVpn *vpn)
         return nm_vpn_connection_get_vpn_state (NM_VPN_CONNECTION (priv->connection));
 }
 
-/* VPN parameters can be found at:
- * http://git.gnome.org/browse/network-manager-openvpn/tree/src/nm-openvpn-service.h
- * http://git.gnome.org/browse/network-manager-vpnc/tree/src/nm-vpnc-service.h
- * http://git.gnome.org/browse/network-manager-pptp/tree/src/nm-pptp-service.h
- * http://git.gnome.org/browse/network-manager-openconnect/tree/src/nm-openconnect-service.h
- * http://git.gnome.org/browse/network-manager-openswan/tree/src/nm-openswan-service.h
- * See also 'properties' directory in these plugins.
- */
-static const gchar *
-get_vpn_key_gateway (const char *vpn_type)
-{
-        if (g_strcmp0 (vpn_type, "openvpn") == 0)     return "remote";
-        if (g_strcmp0 (vpn_type, "vpnc") == 0)        return "IPSec gateway";
-        if (g_strcmp0 (vpn_type, "pptp") == 0)        return "gateway";
-        if (g_strcmp0 (vpn_type, "openconnect") == 0) return "gateway";
-        if (g_strcmp0 (vpn_type, "openswan") == 0)    return "right";
-        return "";
-}
-
-static const gchar *
-get_vpn_key_group (const char *vpn_type)
-{
-        if (g_strcmp0 (vpn_type, "openvpn") == 0)     return "";
-        if (g_strcmp0 (vpn_type, "vpnc") == 0)        return "IPSec ID";
-        if (g_strcmp0 (vpn_type, "pptp") == 0)        return "";
-        if (g_strcmp0 (vpn_type, "openconnect") == 0) return "";
-        if (g_strcmp0 (vpn_type, "openswan") == 0)    return "";
-        return "";
-}
-
-static const gchar *
-get_vpn_key_username (const char *vpn_type)
-{
-        if (g_strcmp0 (vpn_type, "openvpn") == 0)     return "username";
-        if (g_strcmp0 (vpn_type, "vpnc") == 0)        return "Xauth username";
-        if (g_strcmp0 (vpn_type, "pptp") == 0)        return "user";
-        if (g_strcmp0 (vpn_type, "openconnect") == 0) return "username";
-        if (g_strcmp0 (vpn_type, "openswan") == 0)    return "leftxauthusername";
-        return "";
-}
-
-static const gchar *
-get_vpn_key_group_password (const char *vpn_type)
-{
-        if (g_strcmp0 (vpn_type, "openvpn") == 0)     return "";
-        if (g_strcmp0 (vpn_type, "vpnc") == 0)        return "Xauth password";
-        if (g_strcmp0 (vpn_type, "pptp") == 0)        return "";
-        if (g_strcmp0 (vpn_type, "openconnect") == 0) return "";
-        if (g_strcmp0 (vpn_type, "openswan") == 0)    return "";
-        return "";
-}
-
-static const gchar *
-net_vpn_get_gateway (NetVpn *vpn)
-{
-        NetVpnPrivate *priv = vpn->priv;
-        const gchar *key;
-
-        key = get_vpn_key_gateway (priv->service_type);
-        return nm_setting_vpn_get_data_item (nm_connection_get_setting_vpn (priv->connection), key);
-}
-
-static const gchar *
-net_vpn_get_id (NetVpn *vpn)
-{
-        NetVpnPrivate *priv = vpn->priv;
-        const gchar *key;
-
-        key = get_vpn_key_group (priv->service_type);
-        return nm_setting_vpn_get_data_item (nm_connection_get_setting_vpn (priv->connection), key);
-}
-
-static const gchar *
-net_vpn_get_username (NetVpn *vpn)
-{
-        NetVpnPrivate *priv = vpn->priv;
-        const gchar *key;
-
-        key = get_vpn_key_username (priv->service_type);
-        return nm_setting_vpn_get_data_item (nm_connection_get_setting_vpn (priv->connection), key);
-}
-
-static const gchar *
-net_vpn_get_password (NetVpn *vpn)
-{
-        NetVpnPrivate *priv = vpn->priv;
-        const gchar *key;
-
-        key = get_vpn_key_group_password (priv->service_type);
-        return nm_setting_vpn_get_data_item (nm_connection_get_setting_vpn (priv->connection), key);
-}
-
 static void
 vpn_proxy_delete (NetObject *object)
 {
@@ -246,10 +164,6 @@ vpn_proxy_add_to_stack (NetObject    *object,
 
         /* add widgets to size group */
         widget = GTK_WIDGET (gtk_builder_get_object (vpn->priv->builder,
-                                                     "heading_group_password"));
-        gtk_size_group_add_widget (heading_size_group, widget);
-
-        widget = GTK_WIDGET (gtk_builder_get_object (vpn->priv->builder,
                                                      "vbox9"));
         gtk_stack_add_named (stack, widget, net_object_get_id (object));
         return widget;
@@ -260,7 +174,6 @@ nm_device_refresh_vpn_ui (NetVpn *vpn)
 {
         GtkWidget *widget;
         GtkWidget *sw;
-        const gchar *status;
         NetVpnPrivate *priv = vpn->priv;
         const GPtrArray *acs;
         NMActiveConnection *a;
@@ -269,10 +182,6 @@ nm_device_refresh_vpn_ui (NetVpn *vpn)
         gchar *title;
         NMClient *client;
 
-        sw = GTK_WIDGET (gtk_builder_get_object (priv->builder,
-                                                 "device_off_switch"));
-        gtk_widget_set_visible (sw, TRUE);
-
         /* update title */
         widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
                                                      "label_device"));
@@ -318,40 +227,12 @@ nm_device_refresh_vpn_ui (NetVpn *vpn)
                 }
         }
 
-        widget = GTK_WIDGET (gtk_builder_get_object (priv->builder,
-                                                     "label_status"));
-        status = panel_vpn_state_to_localized_string (state);
-        gtk_label_set_label (GTK_LABEL (widget), status);
         priv->updating_device = TRUE;
+        sw = GTK_WIDGET (gtk_builder_get_object (priv->builder, "device_off_switch"));
         gtk_switch_set_active (GTK_SWITCH (sw),
                                state != NM_VPN_CONNECTION_STATE_FAILED &&
                                state != NM_VPN_CONNECTION_STATE_DISCONNECTED);
         priv->updating_device = FALSE;
-
-        /* service type */
-        panel_set_device_widget_details (vpn->priv->builder,
-                                         "service_type",
-                                         vpn->priv->service_type);
-
-        /* gateway */
-        panel_set_device_widget_details (vpn->priv->builder,
-                                         "gateway",
-                                         net_vpn_get_gateway (vpn));
-
-        /* groupname */
-        panel_set_device_widget_details (vpn->priv->builder,
-                                         "group_name",
-                                         net_vpn_get_id (vpn));
-
-        /* username */
-        panel_set_device_widget_details (vpn->priv->builder,
-                                         "username",
-                                         net_vpn_get_username (vpn));
-
-        /* password */
-        panel_set_device_widget_details (vpn->priv->builder,
-                                         "group_password",
-                                         net_vpn_get_password (vpn));
 }
 
 static void
diff --git a/panels/network/net-vpn.h b/panels/network/net-vpn.h
index 6ca1910..adcf8ad 100644
--- a/panels/network/net-vpn.h
+++ b/panels/network/net-vpn.h
@@ -52,6 +52,8 @@ struct _NetVpnClass
 };
 
 GType            net_vpn_get_type               (void);
+void             net_vpn_set_show_separator     (NetVpn   *self,
+                                                 gboolean  show_separator);
 
 G_END_DECLS
 
diff --git a/panels/network/network-vpn.ui b/panels/network/network-vpn.ui
index 7a3fab4..3fb080a 100644
--- a/panels/network/network-vpn.ui
+++ b/panels/network/network-vpn.ui
@@ -1,268 +1,46 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <!-- interface-requires gtk+ 3.0 -->
-      <object class="GtkVBox" id="vbox9">
-        <property name="visible">True</property>
+  <object class="GtkBox" id="vbox9">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="hexpand">True</property>
+    <property name="orientation">vertical</property>
+
+    <!-- HACK: a separator above the row, since we don't have a real listbox widget in the panel -->
+    <child>
+      <object class="GtkSeparator" id="separator">
         <property name="can_focus">False</property>
-        <property name="border_width">12</property>
-        <property name="spacing">6</property>
+        <property name="orientation">horizontal</property>
+      </object>
+    </child>
+
+    <!-- Main listbox -->
+    <child>
+      <object class="GtkListBox">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="selection_mode">none</property>
         <child>
-          <object class="GtkGrid" id="grid4">
+          <object class="GtkListBoxRow">
             <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="valign">start</property>
-            <property name="row_spacing">10</property>
-            <property name="column_spacing">6</property>
-            <child>
-              <object class="GtkLabel" id="heading_service_type">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="xalign">1</property>
-                <property name="label" translatable="yes">VPN Type</property>
-                <property name="mnemonic_widget">label_service_type</property>
-                <style>
-                  <class name="dim-label"/>
-                </style>
-              </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="GtkLabel" id="heading_gateway">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="xalign">1</property>
-                <property name="label" translatable="yes">Gateway</property>
-                <property name="mnemonic_widget">label_gateway</property>
-                <style>
-                  <class name="dim-label"/>
-                </style>
-              </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">2</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="heading_group_name">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="xalign">1</property>
-                <property name="label" translatable="yes">Group Name</property>
-                <property name="mnemonic_widget">label_group_name</property>
-                <style>
-                  <class name="dim-label"/>
-                </style>
-              </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">3</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="heading_group_password">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="xalign">1</property>
-                <property name="label" translatable="yes">Group Password</property>
-                <property name="mnemonic_widget">label_group_password</property>
-                <style>
-                  <class name="dim-label"/>
-                </style>
-              </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">4</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
+            <property name="can_focus">True</property>
+            <property name="activatable">False</property>
             <child>
-              <object class="GtkLabel" id="heading_username">
+              <object class="GtkBox">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="xalign">1</property>
-                <property name="label" translatable="yes">Username</property>
-                <property name="mnemonic_widget">label_username</property>
-                <style>
-                  <class name="dim-label"/>
-                </style>
-              </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">5</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="label_service_type">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="xalign">0</property>
-                <property name="label">openvpn</property>
-                <property name="selectable">True</property>
-              </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="top_attach">1</property>
-                <property name="width">2</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="label_gateway">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="xalign">0</property>
-                <property name="label">AA:BB:CC:DD:55:66:77:88</property>
-                <property name="ellipsize">end</property>
-                <property name="max-width-chars">24</property>
-                <property name="selectable">True</property>
-              </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="top_attach">2</property>
-                <property name="width">2</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="label_group_name">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="xalign">0</property>
-                <property name="label">SEKRIT</property>
-                <property name="selectable">True</property>
-              </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="top_attach">3</property>
-                <property name="width">2</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="label_group_password">
-                <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="top_attach">4</property>
-                <property name="width">2</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkLabel" id="label_username">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="xalign">0</property>
-                <property name="label">smithy</property>
-                <property name="selectable">True</property>
-              </object>
-              <packing>
-                <property name="left_attach">1</property>
-                <property name="top_attach">5</property>
-                <property name="width">2</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkAlignment" id="alignment_switch">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="halign">end</property>
                 <property name="valign">start</property>
+                <property name="margin">12</property>
+                <property name="spacing">12</property>
                 <child>
-                  <placeholder/>
-                </child>
-              </object>
-              <packing>
-                <property name="left_attach">2</property>
-                <property name="top_attach">0</property>
-                <property name="width">1</property>
-                <property name="height">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkBox" id="box1">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="hexpand">True</property>
-                <property name="spacing">6</property>
-                <child>
-                  <object class="GtkImage" id="image_device">
+                  <object class="GtkLabel" id="label_device">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="halign">end</property>
-                    <property name="valign">start</property>
-                    <property name="xalign">1</property>
-                    <property name="pixel_size">48</property>
-                    <property name="icon_name">network-vpn</property>
-                    <property name="icon-size">6</property>
-                  </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">0</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkVBox" id="vbox12">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="valign">start</property>
+                    <property name="xalign">0</property>
+                    <property name="ellipsize">end</property>
                     <property name="hexpand">True</property>
-                    <child>
-                      <object class="GtkLabel" id="label_device">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="xalign">0</property>
-                        <property name="label">VPN</property>
-                        <property name="ellipsize">end</property>
-                        <attributes>
-                          <attribute name="weight" value="bold"/>
-                          <attribute name="scale" value="1.2"/>
-                        </attributes>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">False</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
-                    <child>
-                      <object class="GtkLabel" id="label_status">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="xalign">0</property>
-                        <property name="label">Not connected</property>
-                      </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>
-                    <property name="fill">True</property>
-                    <property name="position">1</property>
-                  </packing>
                 </child>
                 <child>
                   <object class="GtkSwitch" id="device_off_switch">
@@ -276,80 +54,35 @@
                       </object>
                     </child>
                   </object>
-                  <packing>
-                    <property name="expand">False</property>
-                    <property name="fill">True</property>
-                    <property name="position">2</property>
-                  </packing>
                 </child>
-              </object>
-              <packing>
-                <property name="left_attach">0</property>
-                <property name="top_attach">0</property>
-                <property name="width">3</property>
-                <property name="height">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="GtkBox" id="box3">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <child>
-              <object class="GtkButton" id="button_options">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="halign">end</property>
-                <property name="valign">end</property>
-                <property name="hexpand">True</property>
-                <property name="vexpand">True</property>
-                <property name="use_underline">True</property>
-                <style>
-                  <class name="image-button"/>
-                </style>
                 <child>
-                  <object class="GtkImage" id="image1">
+                  <object class="GtkButton" id="button_options">
                     <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="icon_name">emblem-system-symbolic</property>
-                    <property name="icon_size">1</property>
-                  </object>
-                </child>
-                <child internal-child="accessible">
-                  <object class="AtkObject" id="button_options-accessible">
-                    <property name="accessible-name" translatable="yes">Options…</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="use_underline">True</property>
+                    <style>
+                      <class name="image-button"/>
+                    </style>
+                    <child>
+                      <object class="GtkImage">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="icon_name">emblem-system-symbolic</property>
+                      </object>
+                    </child>
+                    <child internal-child="accessible">
+                      <object class="AtkObject" id="button_options-accessible">
+                        <property name="accessible-name" translatable="yes">Options…</property>
+                      </object>
+                    </child>
                   </object>
                 </child>
               </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="pack_type">end</property>
-                <property name="position">0</property>
-              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
-            <property name="position">1</property>
-          </packing>
         </child>
       </object>
-  <object class="GtkSizeGroup" id="sizegroup1">
-    <widgets>
-      <widget name="heading_service_type"/>
-      <widget name="heading_gateway"/>
-      <widget name="heading_group_name"/>
-      <widget name="heading_group_password"/>
-      <widget name="heading_username"/>
-    </widgets>
+    </child>
   </object>
 </interface>
diff --git a/panels/network/network.ui b/panels/network/network.ui
index 52691fa..d287734 100644
--- a/panels/network/network.ui
+++ b/panels/network/network.ui
@@ -72,10 +72,11 @@
                           </object>
                         </child>
                         <child>
-                          <object class="GtkBox" id="box_vpn">
+                          <object class="GtkBox">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
                             <property name="orientation">vertical</property>
+                            <property name="spacing">6</property>
 
                             <!-- VPN header -->
                             <child>
@@ -111,6 +112,46 @@
                                 </child>
                               </object>
                             </child>
+                            <child>
+                              <object class="GtkFrame">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <child>
+                                  <object class="GtkBox" id="box_vpn">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="orientation">vertical</property>
+
+                                    <!-- "Not set up" row -->
+                                    <child>
+                                      <object class="GtkListBox" id="empty_listbox">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">True</property>
+                                        <property name="selection_mode">none</property>
+                                        <child>
+                                          <object class="GtkListBoxRow">
+                                            <property name="visible">True</property>
+                                            <property name="can_focus">True</property>
+                                            <property name="activatable">False</property>
+                                            <child>
+                                              <object class="GtkLabel">
+                                                <property name="visible">True</property>
+                                                <property name="can_focus">False</property>
+                                                <property name="hexpand">True</property>
+                                                <property name="margin">16</property>
+                                                <property name="xalign">0</property>
+                                                <property name="ellipsize">end</property>
+                                                <property name="label" translatable="yes">Not set 
up</property>
+                                              </object>
+                                            </child>
+                                          </object>
+                                        </child>
+                                      </object>
+                                    </child>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
                           </object>
                         </child>
                         <child>


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