[gnome-control-center/wip/gbsneto/new-network-panel: 26/34] network: Add connections and devices to different stack



commit 2ce0493cc3cc658cdf9219d8f2d6defc0f9b89f2
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Sat Jul 15 21:24:07 2017 -0300

    network: Add connections and devices to different stack
    
    The current Network panel is composed of a single stack and
    a treeview to select the currently visible stack page. Each
    stack page represents a connection or device.
    
    The new Network panel, however, has none of the concept of
    selectable pages. In the new layout, all connections and
    devices appear all at once in a more compact and simpler
    fashion.
    
    This commit, then, starts moving towards a unified, pageless
    panel by adding all the connections and devices to different
    stacks. These different stacks are transient to the network
    object, and are added at appropriate boxes, giving the panel
    a unified layout.
    
    This has some serious implications in the design of the
    current code. Most of the code removals were related to the
    treeview and different pages handling. No more tree model
    madness is present, and the devices are now stored in a
    plain simple GPtrArray.
    
    After this patch, NetObject:add_to_stack isn't a good code
    design choice anymore. This will be addressed in a future
    patch.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=785581

 panels/network/cc-network-panel.c |  508 +++++++------------------------------
 panels/network/network.ui         |   94 +------
 2 files changed, 102 insertions(+), 500 deletions(-)
---
diff --git a/panels/network/cc-network-panel.c b/panels/network/cc-network-panel.c
index 53af4dc..9481c4c 100644
--- a/panels/network/cc-network-panel.c
+++ b/panels/network/cc-network-panel.c
@@ -54,15 +54,17 @@ struct _CcNetworkPanel
         CcPanel           parent;
 
         GCancellable     *cancellable;
-        GtkListStore     *liststore_devices;
+        GHashTable       *device_to_stack;
+        GPtrArray        *devices;
         NMClient         *client;
         MMManager        *modem_manager;
         GtkSizeGroup     *sizegroup;
         gboolean          updating_device;
 
         /* widgets */
-        GtkStack         *stack;
-        GtkWidget        *treeview;
+        GtkWidget        *box_proxy;
+        GtkWidget        *box_vpn;
+        GtkWidget        *box_wired;
 
         /* wireless dialog stuff */
         CmdlineOperation  arg_operation;
@@ -82,7 +84,7 @@ enum {
         PROP_PARAMETERS
 };
 
-static NetObject *find_in_model_by_id (CcNetworkPanel *panel, const gchar *id, GtkTreeIter *iter_out);
+static NetObject *find_net_object_by_id (CcNetworkPanel *panel, const gchar *id);
 static void handle_argv (CcNetworkPanel *panel);
 
 CC_PANEL_REGISTER (CcNetworkPanel, cc_network_panel)
@@ -210,6 +212,9 @@ cc_network_panel_dispose (GObject *object)
         g_clear_object (&self->client);
         g_clear_object (&self->modem_manager);
 
+        g_clear_pointer (&self->device_to_stack, g_hash_table_destroy);
+        g_clear_pointer (&self->devices, g_ptr_array_unref);
+
         G_OBJECT_CLASS (cc_network_panel_parent_class)->dispose (object);
 }
 
@@ -229,175 +234,37 @@ cc_network_panel_get_help_uri (CcPanel *panel)
        return "help:gnome-help/net";
 }
 
-static NetObject *
-get_selected_object (CcNetworkPanel *panel)
-{
-        GtkTreeSelection *selection;
-        GtkTreeModel *model;
-        GtkTreeIter iter;
-        NetObject *object = NULL;
-
-        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->treeview));
-        if (!gtk_tree_selection_get_selected (selection, &model, &iter)) {
-                return NULL;
-        }
-
-        gtk_tree_model_get (model, &iter,
-                            PANEL_DEVICES_COLUMN_OBJECT, &object,
-                            -1);
-
-        return object;
-}
-
-static void
-select_first_device (CcNetworkPanel *panel)
-{
-        GtkTreePath *path;
-        GtkTreeSelection *selection;
-
-        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->treeview));
-
-        /* select the first device */
-        path = gtk_tree_path_new_from_string ("0");
-        gtk_tree_selection_select_path (selection, path);
-        gtk_tree_path_free (path);
-}
-
-static void
-select_tree_iter (CcNetworkPanel *panel, GtkTreeIter *iter)
-{
-        GtkTreeSelection *selection;
-
-        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->treeview));
-
-        gtk_tree_selection_select_iter (selection, iter);
-}
-
 static void
 object_removed_cb (NetObject *object, CcNetworkPanel *panel)
 {
-        gboolean ret;
-        NetObject *object_tmp;
-        GtkTreeIter iter;
-        GtkTreeModel *model;
-        GtkTreeSelection *selection;
-
-        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->treeview));
+        GtkWidget *stack;
 
-        /* remove device from model */
-        model = GTK_TREE_MODEL (panel->liststore_devices);
-        ret = gtk_tree_model_get_iter_first (model, &iter);
-        if (!ret)
-                return;
-
-        /* get the other elements */
-        do {
-                gtk_tree_model_get (model, &iter,
-                                    PANEL_DEVICES_COLUMN_OBJECT, &object_tmp,
-                                    -1);
-                if (g_strcmp0 (net_object_get_id (object),
-                               net_object_get_id (object_tmp)) == 0) {
-                        g_object_unref (object_tmp);
-                        if (gtk_list_store_remove (GTK_LIST_STORE (model), &iter)) {
-                                if (gtk_tree_model_get_iter_first (model, &iter))
-                                        gtk_tree_selection_select_iter (selection, &iter);
-                        }
-                        break;
-                }
-                g_object_unref (object_tmp);
-        } while (gtk_tree_model_iter_next (model, &iter));
+        /* remove device */
+        stack = g_hash_table_lookup (panel->device_to_stack, object);
+        if (stack != NULL)
+                gtk_widget_destroy (stack);
 }
 
 GPtrArray *
 cc_network_panel_get_devices (CcNetworkPanel *panel)
 {
         GPtrArray *devices;
-        GtkTreeModel *model;
-        GtkTreeIter iter;
-        NetObject *object;
+        guint i;
 
-        devices = g_ptr_array_new_with_free_func (g_object_unref);
+        g_return_val_if_fail (CC_IS_NETWORK_PANEL (panel), NULL);
 
-        model = GTK_TREE_MODEL (panel->liststore_devices);
-        if (!gtk_tree_model_get_iter_first (model, &iter))
-                return devices;
+        devices = g_ptr_array_new_with_free_func (g_object_unref);
 
-        do {
-                gtk_tree_model_get (model, &iter,
-                                    PANEL_DEVICES_COLUMN_OBJECT, &object,
-                                    -1);
-                if (NET_IS_DEVICE (object))
-                        g_ptr_array_add (devices, object);
-                else
-                        g_object_unref (object);
-        } while (gtk_tree_model_iter_next (model, &iter));
+        for (i = 0; i < panel->devices->len; i++) {
+                NetObject *object = g_ptr_array_index (panel->devices, i);
 
-        return devices;
-}
+                if (!NET_IS_DEVICE (object))
+                        continue;
 
-static gint
-panel_net_object_get_sort_category (NetObject *net_object)
-{
-        if (NET_IS_DEVICE (net_object)) {
-                return panel_device_get_sort_category (net_device_get_nm_device (NET_DEVICE (net_object)));
-        } else if (NET_IS_PROXY (net_object)) {
-                return 9;
-        } else if (NET_IS_VPN (net_object)) {
-                return 5;
+                g_ptr_array_add (devices, g_object_ref (object));
         }
 
-        g_assert_not_reached ();
-}
-
-static gint
-panel_net_object_sort_func (GtkTreeModel *model, GtkTreeIter *a,
-                            GtkTreeIter *b, void *data)
-{
-        g_autoptr(NetObject) obj_a = NULL;
-        g_autoptr(NetObject) obj_b = NULL;
-        gint cat_a, cat_b;
-        const char *title_a, *title_b;
-
-        gtk_tree_model_get (model, a,
-                            PANEL_DEVICES_COLUMN_OBJECT, &obj_a,
-                            -1);
-        gtk_tree_model_get (model, b,
-                            PANEL_DEVICES_COLUMN_OBJECT, &obj_b,
-                            -1);
-
-        cat_a = panel_net_object_get_sort_category (obj_a);
-        cat_b = panel_net_object_get_sort_category (obj_b);
-
-        if (cat_a != cat_b)
-                return cat_a - cat_b;
-
-        title_a = net_object_get_title (obj_a);
-        title_b = net_object_get_title (obj_b);
-
-        if (title_a == title_b)
-                return 0;
-        if (title_a == NULL)
-                return -1;
-        if (title_b == NULL)
-                return 1;
-
-        return g_utf8_collate (title_a, title_b);
-}
-
-static void
-panel_net_object_notify_title_cb (NetObject *net_object, GParamSpec *pspec, CcNetworkPanel *panel)
-{
-        GtkTreeIter iter;
-
-        if (!find_in_model_by_id (panel, net_object_get_id (net_object), &iter))
-                return;
-
-        /* gtk_tree_model_row_changed would not cause the list store to resort.
-         * Instead set the object column to the current value.
-         * See https://bugzilla.gnome.org/show_bug.cgi?id=782737 */
-        gtk_list_store_set (panel->liststore_devices, &iter,
-                            PANEL_DEVICES_COLUMN_OBJECT, net_object,
-                           -1);
+        return devices;
 }
 
 static void
@@ -440,8 +307,7 @@ panel_refresh_device_titles (CcNetworkPanel *panel)
 
 static gboolean
 handle_argv_for_device (CcNetworkPanel *self,
-                       NMDevice       *device,
-                       GtkTreeIter    *iter)
+                       NMDevice       *device)
 {
         GtkWidget *toplevel = cc_shell_get_toplevel (cc_panel_get_shell (CC_PANEL (self)));
 
@@ -453,10 +319,8 @@ handle_argv_for_device (CcNetworkPanel *self,
                         cc_network_panel_connect_to_3g_network (toplevel, self->client, device);
 
                         reset_command_line_args (self); /* done */
-                        select_tree_iter (self, iter);
                         return TRUE;
                 } else if (self->arg_operation == OPERATION_SHOW_DEVICE) {
-                        select_tree_iter (self, iter);
                         reset_command_line_args (self); /* done */
                         return TRUE;
                 }
@@ -467,8 +331,7 @@ handle_argv_for_device (CcNetworkPanel *self,
 
 static gboolean
 handle_argv_for_connection (CcNetworkPanel *panel,
-                            NMConnection   *connection,
-                            GtkTreeIter    *iter)
+                            NMConnection   *connection)
 {
         if (panel->arg_operation == OPERATION_NULL)
                 return TRUE;
@@ -477,7 +340,6 @@ handle_argv_for_connection (CcNetworkPanel *panel,
 
         if (g_strcmp0 (nm_connection_get_path (connection), panel->arg_device) == 0) {
                 reset_command_line_args (panel);
-                select_tree_iter (panel, iter);
                 return TRUE;
         }
 
@@ -488,31 +350,26 @@ handle_argv_for_connection (CcNetworkPanel *panel,
 static void
 handle_argv (CcNetworkPanel *panel)
 {
-        GtkTreeModel *model;
-        GtkTreeIter iter;
-        gboolean ret;
+        gint i;
 
         if (panel->arg_operation == OPERATION_NULL)
                 return;
 
-        model = GTK_TREE_MODEL (panel->liststore_devices);
-        ret = gtk_tree_model_get_iter_first (model, &iter);
-        while (ret) {
+        for (i = 0; i < panel->devices->len; i++) {
                 GObject *object_tmp;
                 NMDevice *device;
                 NMConnection *connection;
                 gboolean done = FALSE;
 
-                gtk_tree_model_get (model, &iter,
-                                    PANEL_DEVICES_COLUMN_OBJECT, &object_tmp,
-                                    -1);
+                object_tmp = g_ptr_array_index (panel->devices, i);
+
                 if (NET_IS_DEVICE (object_tmp)) {
                         g_object_get (object_tmp, "nm-device", &device, NULL);
-                        done = handle_argv_for_device (panel, device, &iter);
+                        done = handle_argv_for_device (panel, device);
                         g_object_unref (device);
                 } else if (NET_IS_VPN (object_tmp)) {
                         g_object_get (object_tmp, "connection", &connection, NULL);
-                        done = handle_argv_for_connection (panel, connection, &iter);
+                        done = handle_argv_for_connection (panel, connection);
                         g_object_unref (connection);
                 }
 
@@ -520,47 +377,40 @@ handle_argv (CcNetworkPanel *panel)
 
                 if (done)
                         return;
-
-                ret = gtk_tree_model_iter_next (model, &iter);
         }
 
         g_debug ("Could not handle argv operation, no matching device yet?");
 }
 
-static void
-state_changed_cb (NMDevice *device,
-                  NMDeviceState new_state,
-                  NMDeviceState old_state,
-                  NMDeviceStateReason reason,
-                  CcNetworkPanel *panel)
+static GtkWidget *
+add_device_stack (CcNetworkPanel *self, NetObject *object)
 {
-        GtkTreeIter iter;
+        GtkWidget *stack;
 
-        if (!find_in_model_by_id (panel, nm_device_get_udi (device), &iter)) {
-                return;
-        }
+        stack = gtk_stack_new ();
+        gtk_widget_show (stack);
+        g_hash_table_insert (self->device_to_stack, object, stack);
+
+        net_object_add_to_stack (object, GTK_STACK (stack), self->sizegroup);
 
-        gtk_list_store_set (GTK_LIST_STORE (panel->liststore_devices), &iter,
-                            PANEL_DEVICES_COLUMN_ICON, panel_device_to_icon_name (device, TRUE),
-                           -1);
+        return stack;
 }
 
-static gboolean
+static void
 panel_add_device (CcNetworkPanel *panel, NMDevice *device)
 {
-        GtkTreeIter iter;
         NMDeviceType type;
         NetDevice *net_device;
         GType device_g_type;
         const char *udi;
 
         if (!nm_device_get_managed (device))
-                goto out;
+                return;
 
         /* do we have an existing object with this id? */
         udi = nm_device_get_udi (device);
-        if (find_in_model_by_id (panel, udi, NULL) != NULL)
-                goto out;
+        if (find_net_object_by_id (panel, udi) != NULL)
+                return;
 
         type = nm_device_get_device_type (device);
 
@@ -586,7 +436,7 @@ panel_add_device (CcNetworkPanel *panel, NMDevice *device)
         case NM_DEVICE_TYPE_BRIDGE:
         /* Don't add VPN devices */
         case NM_DEVICE_TYPE_TUN:
-                goto out;
+                return;
         default:
                 device_g_type = NET_TYPE_DEVICE_SIMPLE;
                 break;
@@ -609,7 +459,7 @@ panel_add_device (CcNetworkPanel *panel, NMDevice *device)
                 if (panel->modem_manager == NULL) {
                         g_warning ("Cannot grab information for modem at %s: No ModemManager support",
                                    nm_device_get_udi (device));
-                        goto out;
+                        return;
                 }
 
                 modem_object = g_dbus_object_manager_get_object (G_DBUS_OBJECT_MANAGER 
(panel->modem_manager),
@@ -617,7 +467,7 @@ panel_add_device (CcNetworkPanel *panel, NMDevice *device)
                 if (modem_object == NULL) {
                         g_warning ("Cannot grab information for modem at %s: Not found",
                                    nm_device_get_udi (device));
-                        goto out;
+                        return;
                 }
 
                 /* Set the modem object in the NetDeviceMobile */
@@ -628,164 +478,52 @@ panel_add_device (CcNetworkPanel *panel, NMDevice *device)
         }
 
         /* add as a panel */
-        if (device_g_type != NET_TYPE_DEVICE)
-                net_object_add_to_stack (NET_OBJECT (net_device), panel->stack, panel->sizegroup);
+        if (device_g_type != NET_TYPE_DEVICE) {
+                GtkWidget *stack;
+
+                stack = add_device_stack (panel, NET_OBJECT (net_device));
+                gtk_container_add (GTK_CONTAINER (panel->box_wired), stack);
+        }
+
+        /* Add to the devices array */
+        g_ptr_array_add (panel->devices, net_device);
 
         g_signal_connect_object (net_device, "removed",
                                  G_CALLBACK (object_removed_cb), panel, 0);
-        gtk_list_store_append (panel->liststore_devices, &iter);
-        gtk_list_store_set (panel->liststore_devices,
-                            &iter,
-                            PANEL_DEVICES_COLUMN_ICON, panel_device_to_icon_name (device, TRUE),
-                            PANEL_DEVICES_COLUMN_OBJECT, net_device,
-                            -1);
-        g_signal_connect (net_device, "notify::title",
-                          G_CALLBACK (panel_net_object_notify_title_cb), panel);
-
-        g_object_unref (net_device);
-        g_signal_connect (device, "state-changed",
-                          G_CALLBACK (state_changed_cb), panel);
-
-out:
-        return FALSE;
 }
 
 static void
 panel_remove_device (CcNetworkPanel *panel, NMDevice *device)
 {
-        gboolean ret;
-        NetObject *object_tmp;
-        GtkTreeIter iter;
-        GtkTreeModel *model;
-
-        /* remove device from model */
-        model = GTK_TREE_MODEL (panel->liststore_devices);
-        ret = gtk_tree_model_get_iter_first (model, &iter);
-        if (!ret)
-                return;
-
-        /* get the other elements */
-        do {
-                gtk_tree_model_get (model, &iter,
-                                    PANEL_DEVICES_COLUMN_OBJECT, &object_tmp,
-                                    -1);
-                if (g_strcmp0 (net_object_get_id (object_tmp),
-                               nm_device_get_udi (device)) == 0) {
-                        gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
-                        g_object_unref (object_tmp);
-                        break;
-                }
-                g_object_unref (object_tmp);
-        } while (gtk_tree_model_iter_next (model, &iter));
-}
-
-static void
-get_object_title (GtkTreeViewColumn *column,
-                  GtkCellRenderer   *cell,
-                  GtkTreeModel      *model,
-                  GtkTreeIter       *iter,
-                  gpointer           data)
-{
         NetObject *object;
 
-        gtk_tree_model_get (model, iter,
-                            PANEL_DEVICES_COLUMN_OBJECT, &object,
-                            -1);
-        if (!object)
-                return;
-
-        g_object_set (cell, "text", net_object_get_title (object), NULL);
-        g_object_unref (object);
-}
-
-static void
-panel_add_devices_columns (CcNetworkPanel *panel, GtkTreeView *treeview)
-{
-        GtkCellRenderer *renderer;
-        GtkTreeViewColumn *column;
-
-        /* image */
-        renderer = gtk_cell_renderer_pixbuf_new ();
-        g_object_set (renderer,
-                      "width", 32,
-                      "xalign", 1.0,
-                      "stock-size", GTK_ICON_SIZE_MENU,
-                      "follow-state", TRUE,
-                      NULL);
-        gtk_cell_renderer_set_padding (renderer, 4, 10);
-
-        column = gtk_tree_view_column_new_with_attributes ("icon", renderer,
-                                                           "icon-name", PANEL_DEVICES_COLUMN_ICON,
-                                                           NULL);
-        gtk_tree_view_append_column (treeview, column);
-
-        /* column for text */
-        renderer = gtk_cell_renderer_text_new ();
-        g_object_set (renderer,
-                      "wrap-mode", PANGO_WRAP_WORD,
-                      "ellipsize", PANGO_ELLIPSIZE_END,
-                      NULL);
-        column = gtk_tree_view_column_new_with_attributes ("title", renderer, NULL);
-        gtk_tree_view_column_set_cell_data_func (GTK_TREE_VIEW_COLUMN (column),
-                                                 renderer,
-                                                 get_object_title,
-                                                 NULL, NULL);
-        gtk_tree_view_column_set_sort_column_id (column, PANEL_DEVICES_COLUMN_OBJECT);
-        gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (panel->liststore_devices),
-                                         PANEL_DEVICES_COLUMN_OBJECT,
-                                         panel_net_object_sort_func, NULL, NULL);
-        gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (panel->liststore_devices),
-                                              PANEL_DEVICES_COLUMN_OBJECT,
-                                              GTK_SORT_ASCENDING);
-        gtk_tree_view_append_column (treeview, column);
-        gtk_tree_view_column_set_expand (column, TRUE);
-}
-
-static void
-nm_devices_treeview_clicked_cb (GtkTreeSelection *selection, CcNetworkPanel *panel)
-{
-        const gchar *needle;
-        GtkTreeIter iter;
-        GtkTreeModel *model;
-        NetObject *object = NULL;
+        /* remove device from array */
+        object = find_net_object_by_id (panel, nm_device_get_udi (device));
 
-        if (!gtk_tree_selection_get_selected (selection, &model, &iter)) {
-                g_debug ("no row selected");
+        if (object == NULL)
                 return;
-        }
-
-        /* find the widget in the stack that matches the object ID */
-        object = get_selected_object (panel);
-        needle = net_object_get_id (object);
 
-        gtk_stack_set_visible_child_name (panel->stack, needle);
-
-        g_object_unref (object);
+        g_ptr_array_remove (panel->devices, object);
 }
 
 static void
 panel_add_proxy_device (CcNetworkPanel *panel)
 {
-        GtkTreeIter iter;
+        GtkWidget *stack;
         NetProxy *proxy;
 
-        /* add proxy to stack */
         proxy = net_proxy_new ();
-        net_object_add_to_stack (NET_OBJECT (proxy), panel->stack, panel->sizegroup);
+
+        /* add proxy to stack */
+        stack = add_device_stack (panel, NET_OBJECT (proxy));
+        gtk_container_add (GTK_CONTAINER (panel->box_proxy), stack);
 
         /* add proxy to device list */
         net_object_set_title (NET_OBJECT (proxy), _("Network proxy"));
-        gtk_list_store_append (panel->liststore_devices, &iter);
-        gtk_list_store_set (panel->liststore_devices,
-                            &iter,
-                            PANEL_DEVICES_COLUMN_ICON, "preferences-system-network-symbolic",
-                            PANEL_DEVICES_COLUMN_OBJECT, proxy,
-                            -1);
 
         /* NOTE: No connect to notify::title here as it is guaranteed to not
          *       be changed by anyone.*/
-
-        g_object_unref (proxy);
+        g_ptr_array_add (panel->devices, proxy);
 }
 
 static void
@@ -844,13 +582,11 @@ manager_running (NMClient *client, GParamSpec *pspec, gpointer user_data)
         const GPtrArray *devices;
         int i;
         NMDevice *device_tmp;
-        gboolean selected = FALSE;
         CcNetworkPanel *panel = CC_NETWORK_PANEL (user_data);
 
         /* clear all devices we added */
         if (!nm_client_get_nm_running (client)) {
                 g_debug ("NM disappeared");
-                gtk_list_store_clear (panel->liststore_devices);
                 panel_add_proxy_device (panel);
                 goto out;
         }
@@ -863,14 +599,9 @@ manager_running (NMClient *client, GParamSpec *pspec, gpointer user_data)
         }
         for (i = 0; i < devices->len; i++) {
                 device_tmp = g_ptr_array_index (devices, i);
-                selected = panel_add_device (panel, device_tmp) || selected;
+                panel_add_device (panel, device_tmp);
         }
 out:
-        if (!selected) {
-                /* select the first device */
-                select_first_device (panel);
-        }
-
         panel_refresh_device_titles (panel);
 
         g_debug ("Calling handle_argv() after cold-plugging devices");
@@ -878,50 +609,35 @@ out:
 }
 
 static NetObject *
-find_in_model_by_id (CcNetworkPanel *panel, const gchar *id, GtkTreeIter *iter_out)
+find_net_object_by_id (CcNetworkPanel *panel, const gchar *id)
 {
-        gboolean ret;
         NetObject *object_tmp;
-        GtkTreeIter iter;
-        GtkTreeModel *model;
         NetObject *object = NULL;
+        guint i;
 
-        /* find in model */
-        model = GTK_TREE_MODEL (panel->liststore_devices);
-        ret = gtk_tree_model_get_iter_first (model, &iter);
-        if (!ret)
-                goto out;
+        for (i = 0; i < panel->devices->len; i++) {
+                object_tmp = g_ptr_array_index (panel->devices, i);
 
-        /* get the other elements */
-        ret = FALSE;
-        do {
-                gtk_tree_model_get (model, &iter,
-                                    PANEL_DEVICES_COLUMN_OBJECT, &object_tmp,
-                                    -1);
-                if (object_tmp != NULL) {
-                        g_debug ("got %s", net_object_get_id (object_tmp));
-                        if (g_strcmp0 (net_object_get_id (object_tmp), id) == 0)
-                                object = object_tmp;
-                        g_object_unref (object_tmp);
+                if (g_strcmp0 (net_object_get_id (object_tmp), id) == 0) {
+                        object = object_tmp;
+                        break;
                 }
-        } while (object == NULL && gtk_tree_model_iter_next (model, &iter));
-out:
-        if (iter_out)
-                *iter_out = iter;
+        }
+
         return object;
 }
 
 static void
 panel_add_vpn_device (CcNetworkPanel *panel, NMConnection *connection)
 {
+        GtkWidget *stack;
         gchar *title;
-        GtkTreeIter iter;
         NetVpn *net_vpn;
         const gchar *id;
 
         /* does already exist */
         id = nm_connection_get_path (connection);
-        if (find_in_model_by_id (panel, id, NULL) != NULL)
+        if (find_net_object_by_id (panel, id) != NULL)
                 return;
 
         /* add as a VPN object */
@@ -936,22 +652,17 @@ panel_add_vpn_device (CcNetworkPanel *panel, NMConnection *connection)
                                  G_CALLBACK (object_removed_cb), panel, 0);
 
         /* add as a panel */
-        net_object_add_to_stack (NET_OBJECT (net_vpn), panel->stack, panel->sizegroup);
+        stack = add_device_stack (panel, NET_OBJECT (net_vpn));
+        gtk_container_add (GTK_CONTAINER (panel->box_vpn), stack);
 
         title = g_strdup_printf (_("%s VPN"), nm_connection_get_id (connection));
 
         net_object_set_title (NET_OBJECT (net_vpn), title);
-        gtk_list_store_append (panel->liststore_devices, &iter);
-        gtk_list_store_set (panel->liststore_devices,
-                            &iter,
-                            PANEL_DEVICES_COLUMN_ICON, "network-vpn-symbolic",
-                            PANEL_DEVICES_COLUMN_OBJECT, net_vpn,
-                            -1);
-        g_signal_connect (net_vpn, "notify::title",
-                          G_CALLBACK (panel_net_object_notify_title_cb), panel);
+
+        /* store in the devices array */
+        g_ptr_array_add (panel->devices, net_vpn);
 
         g_free (title);
-        g_object_unref (net_vpn);
 }
 
 static void
@@ -1026,41 +737,6 @@ panel_check_network_manager_version (CcNetworkPanel *panel)
 }
 
 static void
-editor_done (NetConnectionEditor *editor,
-             gboolean             success,
-             gpointer             user_data)
-{
-        g_object_unref (editor);
-}
-
-static void
-add_connection_cb (GtkToolButton *button, CcNetworkPanel *panel)
-{
-        NetConnectionEditor *editor;
-        GtkWindow *toplevel;
-
-        toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (panel)));
-        editor = net_connection_editor_new (toplevel, NULL, NULL, NULL, panel->client);
-        g_signal_connect (editor, "done", G_CALLBACK (editor_done), panel);
-        net_connection_editor_run (editor);
-}
-
-static void
-remove_connection (GtkToolButton *button, CcNetworkPanel *panel)
-{
-        NetObject *object;
-
-        /* get current device */
-        object = get_selected_object (panel);
-        if (object == NULL)
-                return;
-
-        /* delete the object */
-        net_object_delete (object);
-        g_object_unref (object);
-}
-
-static void
 on_toplevel_map (GtkWidget      *widget,
                  CcNetworkPanel *panel)
 {
@@ -1088,20 +764,16 @@ cc_network_panel_class_init (CcNetworkPanelClass *klass)
 
         gtk_widget_class_set_template_from_resource (widget_class, 
"/org/gnome/control-center/network/network.ui");
 
-        gtk_widget_class_bind_template_child (widget_class, CcNetworkPanel, liststore_devices);
-        gtk_widget_class_bind_template_child (widget_class, CcNetworkPanel, stack);
+        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, sizegroup);
-        gtk_widget_class_bind_template_child (widget_class, CcNetworkPanel, treeview);
-
-        gtk_widget_class_bind_template_callback (widget_class, add_connection_cb);
-        gtk_widget_class_bind_template_callback (widget_class, remove_connection);
 }
 
 static void
 cc_network_panel_init (CcNetworkPanel *panel)
 {
         GError *error = NULL;
-        GtkTreeSelection *selection;
         GtkWidget *toplevel;
         GDBusConnection *system_bus;
         const GPtrArray *connections;
@@ -1112,12 +784,8 @@ cc_network_panel_init (CcNetworkPanel *panel)
         gtk_widget_init_template (GTK_WIDGET (panel));
 
         panel->cancellable = g_cancellable_new ();
-
-        panel_add_devices_columns (panel, GTK_TREE_VIEW (panel->treeview));
-        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (panel->treeview));
-        gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
-        g_signal_connect (selection, "changed",
-                          G_CALLBACK (nm_devices_treeview_clicked_cb), panel);
+        panel->devices = g_ptr_array_new_with_free_func (g_object_unref);
+        panel->device_to_stack = g_hash_table_new (g_direct_hash, g_direct_equal);
 
         /* add the virtual proxy device */
         panel_add_proxy_device (panel);
diff --git a/panels/network/network.ui b/panels/network/network.ui
index 36156b8..dfe099f 100644
--- a/panels/network/network.ui
+++ b/panels/network/network.ui
@@ -41,98 +41,32 @@
             <property name="can_focus">False</property>
             <property name="spacing">3</property>
             <property name="orientation">vertical</property>
+
+            <!-- Each GtkBox below will contain GtkStacks from the NetDevices -->
             <child>
               <object class="GtkBox">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
-                <property name="spacing">6</property>
+                <property name="orientation">vertical</property>
                 <child>
-                  <object class="GtkBox">
+                  <object class="GtkBox" id="box_wired">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="margin_start">12</property>
-                    <property name="margin_top">12</property>
-                    <property name="margin_bottom">12</property>
                     <property name="orientation">vertical</property>
-                    <child>
-                      <object class="GtkScrolledWindow" id="devices_scrolledwindow">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="hscrollbar_policy">never</property>
-                        <property name="shadow_type">in</property>
-                        <property name="expand">True</property>
-                        <property name="width_request">200</property>
-                        <child>
-                          <object class="GtkTreeView" id="treeview">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="model">liststore_devices</property>
-                            <property name="headers_visible">False</property>
-                            <property name="search_column">2</property>
-                            <property name="show_expanders">False</property>
-                            <child internal-child="selection">
-                              <object class="GtkTreeSelection" id="treeview-selection1"/>
-                            </child>
-                          </object>
-                        </child>
-                      </object>
-                    </child>
-                    <child>
-                      <object class="GtkToolbar" id="devices_toolbar">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="toolbar_style">icons</property>
-                        <property name="show_arrow">False</property>
-                        <property name="icon_size">1</property>
-                        <style>
-                          <class name="inline-toolbar"/>
-                        </style>
-                        <child>
-                          <object class="GtkToolButton" id="add_toolbutton">
-                            <property name="use_action_appearance">False</property>
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="use_action_appearance">False</property>
-                            <property name="label" translatable="yes">Add Device</property>
-                            <property name="use_underline">True</property>
-                            <property name="icon_name">list-add-symbolic</property>
-                            <signal name="clicked" handler="add_connection_cb" object="CcNetworkPanel" 
swapped="no" />
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="homogeneous">True</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <object class="GtkToolButton" id="remove_toolbutton">
-                            <property name="use_action_appearance">False</property>
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="use_action_appearance">False</property>
-                            <property name="label" translatable="yes">Remove Device</property>
-                            <property name="use_underline">True</property>
-                            <property name="icon_name">list-remove-symbolic</property>
-                            <signal name="clicked" handler="remove_connection" object="CcNetworkPanel" 
swapped="no" />
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="homogeneous">True</property>
-                          </packing>
-                        </child>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
                   </object>
                 </child>
                 <child>
-                  <object class="GtkStack" id="stack">
+                  <object class="GtkBox" id="box_vpn">
                     <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="transition_type">crossfade</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkBox" id="box_proxy">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
                   </object>
                 </child>
               </object>


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