[network-manager-netbook] Implement "Advanced" expander.



commit e5634eb4cac66cd69858ef4236890bf0b0958044
Author: Tambet Ingo <tambet gmail com>
Date:   Wed Jun 10 10:12:25 2009 +0300

    Implement "Advanced" expander.
---
 TODO                         |    1 -
 src/Makefile.am              |    2 +
 src/nmn-connection-details.c |  340 ++++++++++++++++++++++++++++++++++++++++++
 src/nmn-connection-details.h |   36 +++++
 src/nmn-item.c               |   67 +++++++--
 src/nmn-item.h               |    1 +
 src/nmn-list.c               |    2 +-
 src/nmn-network-item.c       |   32 ++++
 8 files changed, 467 insertions(+), 14 deletions(-)

diff --git a/TODO b/TODO
index cc554ea..51662ac 100644
--- a/TODO
+++ b/TODO
@@ -1,2 +1 @@
-* "Advanced" button doesn't do anything, used for specifying static IP, manual DNS, etc.
 * Hidden APs are not supported at all.
diff --git a/src/Makefile.am b/src/Makefile.am
index 0ae5707..602765d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -21,6 +21,8 @@ network_manager_netbook_LDADD = \
 network_manager_netbook_SOURCES = \
 	nmn-applet.c \
 	nmn-applet.h \
+	nmn-connection-details.c \
+	nmn-connection-details.h \
 	nmn-device-handler.c \
 	nmn-device-handler.h \
 	nmn-ethernet-handler.c \
diff --git a/src/nmn-connection-details.c b/src/nmn-connection-details.c
new file mode 100644
index 0000000..3358a44
--- /dev/null
+++ b/src/nmn-connection-details.c
@@ -0,0 +1,340 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+#include <string.h>
+#include <arpa/inet.h>
+#include <nm-utils.h>
+#include "nmn-connection-details.h"
+
+G_DEFINE_TYPE (NmnConnectionDetails, nmn_connection_details, GTK_TYPE_TABLE)
+
+enum {
+    PROP_0,
+    PROP_EDITABLE,
+
+    LAST_PROP
+};
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NMN_TYPE_CONNECTION_DETAILS, NmnConnectionDetailsPrivate))
+
+typedef struct {
+    GtkComboBox *method_combo;
+    GtkWidget *address;
+    GtkWidget *netmask;
+    GtkWidget *gateway;
+    GtkWidget *dns;
+    gboolean editable;
+
+    gboolean disposed;
+} NmnConnectionDetailsPrivate;
+
+#define METHOD_AUTO       0
+#define METHOD_MANUAL     1
+#define METHOD_LINK_LOCAL 2
+
+GtkWidget *
+nmn_connection_details_new (gboolean editable)
+{
+    return GTK_WIDGET (g_object_new (NMN_TYPE_CONNECTION_DETAILS,
+                                     NMN_CONNECTION_DETAILS_EDITABLE, editable,
+                                     NULL));
+}
+
+void
+nmn_connection_details_set_setting (NmnConnectionDetails *self,
+                                    NMSettingIP4Config *setting)
+{
+    NmnConnectionDetailsPrivate *priv;
+    const char *method;
+    int active_method;
+
+    g_return_if_fail (NMN_IS_CONNECTION_DETAILS (self));
+    g_return_if_fail (NM_IS_SETTING_IP4_CONFIG (setting));
+
+    priv = GET_PRIVATE (self);
+
+    method = nm_setting_ip4_config_get_method (setting);
+    if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO))
+        active_method = METHOD_AUTO;
+    else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_MANUAL))
+        active_method = METHOD_MANUAL;
+    else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL))
+        active_method = METHOD_LINK_LOCAL;
+    else
+        active_method = -1;
+
+    gtk_combo_box_set_active (priv->method_combo, active_method);
+}
+
+static char *
+ip4_address_as_string (guint32 ip)
+{
+    char *ip_string;
+    struct in_addr tmp_addr;
+
+    tmp_addr.s_addr = ip;
+    ip_string = g_malloc0 (INET_ADDRSTRLEN + 1);
+    if (!inet_ntop (AF_INET, &tmp_addr, ip_string, INET_ADDRSTRLEN))
+        strcpy (ip_string, "(none)");
+
+    return ip_string;
+}
+
+static inline GtkWidget *
+aligned_label_new (const char *text)
+{
+    GtkWidget *w;
+
+    w = gtk_label_new (text);
+    g_object_set (w, "xalign", 0.0, NULL);
+
+    return w;
+}
+
+static GtkWidget *
+create_text_widget (GtkWidget *current_widget,
+                    GtkTable *table,
+                    int col,
+                    int row,
+                    gboolean editable)
+{
+    GtkWidget *w;
+    GType target_type;
+
+    target_type = editable ? GTK_TYPE_ENTRY : GTK_TYPE_LABEL;
+
+    if (current_widget && G_TYPE_CHECK_INSTANCE_TYPE (current_widget, target_type))
+        /* all well, nothing to do */
+        return current_widget;
+
+    if (current_widget)
+        gtk_widget_destroy (current_widget);
+
+    if (editable)
+        w = gtk_entry_new ();
+    else
+        w = aligned_label_new ("");
+
+    gtk_widget_show (w);
+    gtk_table_attach_defaults (table, w, col, col + 1, row, row + 1);
+
+    return w;
+}
+
+static void
+editable_changed (NmnConnectionDetails *self)
+{
+    NmnConnectionDetailsPrivate *priv = GET_PRIVATE (self);
+    GtkTable *table = GTK_TABLE (self);
+
+    priv->editable = gtk_combo_box_get_active (priv->method_combo) == METHOD_MANUAL;
+
+    priv->address = create_text_widget (priv->address, table, 1, 1, priv->editable);
+    priv->netmask = create_text_widget (priv->netmask, table, 1, 2, priv->editable);
+    priv->gateway = create_text_widget (priv->gateway, table, 1, 3, priv->editable);
+
+    gtk_text_view_set_editable (GTK_TEXT_VIEW (priv->dns), priv->editable);
+}
+
+static inline void
+widget_set_text (GtkWidget *w, char *str)
+{
+    if (GTK_IS_LABEL (w))
+        gtk_label_set_text (GTK_LABEL (w), str);
+    else if (GTK_IS_ENTRY (w))
+        gtk_entry_set_text (GTK_ENTRY (w), str);
+    else
+        g_warning ("Invalid widget type '%s'", G_OBJECT_TYPE_NAME (w));
+
+    g_free (str);
+}
+
+void
+nmn_connection_details_set_config (NmnConnectionDetails *self,
+                                   NMIP4Config *config)
+{
+    NmnConnectionDetailsPrivate *priv;
+    const GSList *list;
+    const GArray *array;
+    char *str;
+    GtkTextBuffer *buffer;
+
+    g_return_if_fail (NMN_IS_CONNECTION_DETAILS (self));
+    g_return_if_fail (NM_IS_IP4_CONFIG (config));
+
+    priv = GET_PRIVATE (self);
+
+    list = nm_ip4_config_get_addresses (config);
+    if (list) {
+        NMIP4Address *def_addr = (NMIP4Address *) list->data;
+        guint32 netmask;
+
+        str = ip4_address_as_string (nm_ip4_address_get_address (def_addr));
+        widget_set_text (priv->address, str);
+
+        netmask = nm_utils_ip4_prefix_to_netmask (nm_ip4_address_get_prefix (def_addr));
+        str = ip4_address_as_string (netmask);
+        widget_set_text (priv->netmask, str);
+
+        if (nm_ip4_address_get_gateway (def_addr)) {
+            str = ip4_address_as_string (nm_ip4_address_get_gateway (def_addr));
+            widget_set_text (priv->gateway, str);
+        }
+    }
+
+    array = nm_ip4_config_get_nameservers (config);
+	if (array) {
+        GString *string;
+        int i;
+
+        string = g_string_sized_new (50);
+        for (i = 0; i < array->len; i++) {
+            if (i > 0)
+                g_string_append_c (string, '\n');
+
+            str = ip4_address_as_string (g_array_index (array, guint32, i));
+            g_string_append (string, str);
+            g_free (str);
+        }
+
+        str = g_string_free (string, FALSE);
+	} else
+        str = NULL;
+
+    buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (priv->dns));
+    gtk_text_buffer_set_text (buffer, str, -1);
+    g_free (str);
+}
+
+static void
+nmn_connection_details_init (NmnConnectionDetails *details)
+{
+    NmnConnectionDetailsPrivate *priv = GET_PRIVATE (details);
+    GtkTable *table;
+    GtkWidget *w;
+
+    g_object_set (details,
+                  "n-rows", 5,
+                  "n-columns", 2,
+                  "homogeneous", FALSE,
+                  "row-spacing", 6,
+                  "column-spacing", 6,
+                  NULL);
+
+    table = GTK_TABLE (details);
+
+    w = aligned_label_new ("Connect by:");
+    gtk_table_attach_defaults (table, w, 0, 1, 0, 1);
+
+    w = aligned_label_new ("IP Address:");
+    gtk_table_attach_defaults (table, w, 0, 1, 1, 2);
+
+    w = aligned_label_new ("Subnet mask:");
+    gtk_table_attach_defaults (table, w, 0, 1, 2, 3);
+
+    w = aligned_label_new ("Router:");
+    gtk_table_attach_defaults (table, w, 0, 1, 3, 4);
+
+    w = aligned_label_new ("DNS:");
+    gtk_table_attach_defaults (table, w, 0, 1, 4, 5);
+
+    priv->dns = gtk_text_view_new ();
+    gtk_table_attach_defaults (table, priv->dns, 1, 2, 4, 5);
+
+    priv->method_combo = GTK_COMBO_BOX (gtk_combo_box_new_text ());
+    gtk_combo_box_append_text (priv->method_combo, "DHCP");
+    gtk_combo_box_append_text (priv->method_combo, "Manual");
+    gtk_combo_box_append_text (priv->method_combo, "Link Local");
+    gtk_table_attach_defaults (table, GTK_WIDGET (priv->method_combo), 1, 2, 0, 1);
+    g_signal_connect_swapped (priv->method_combo, "changed", G_CALLBACK (editable_changed), details);
+    gtk_combo_box_set_active (priv->method_combo, METHOD_AUTO);
+}
+
+static GObject*
+constructor (GType type,
+             guint n_construct_params,
+             GObjectConstructParam *construct_params)
+{
+    GObject *object;
+    NmnConnectionDetailsPrivate *priv;
+
+    object = G_OBJECT_CLASS (nmn_connection_details_parent_class)->constructor
+        (type, n_construct_params, construct_params);
+
+    if (!object)
+        return NULL;
+
+    priv = GET_PRIVATE (object);
+
+    gtk_widget_set_sensitive (GTK_WIDGET (priv->method_combo), priv->editable);
+    gtk_widget_show_all (GTK_WIDGET (object));
+
+    return object;
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+              const GValue *value, GParamSpec *pspec)
+{
+    NmnConnectionDetailsPrivate *priv = GET_PRIVATE (object);
+
+    switch (prop_id) {
+    case PROP_EDITABLE:
+        priv->editable = g_value_get_boolean (value);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+              GValue *value, GParamSpec *pspec)
+{
+    NmnConnectionDetailsPrivate *priv = GET_PRIVATE (object);
+
+    switch (prop_id) {
+    case PROP_EDITABLE:
+        g_value_set_boolean (value, priv->editable);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+dispose (GObject *object)
+{
+    NmnConnectionDetailsPrivate *priv = GET_PRIVATE (object);
+
+    if (priv->disposed)
+        return;
+
+    priv->disposed = TRUE;
+
+    G_OBJECT_CLASS (nmn_connection_details_parent_class)->dispose (object);
+}
+
+static void
+nmn_connection_details_class_init (NmnConnectionDetailsClass *class)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+    g_type_class_add_private (object_class, sizeof (NmnConnectionDetailsPrivate));
+
+    object_class->constructor = constructor;
+    object_class->set_property = set_property;
+    object_class->get_property = get_property;
+    object_class->dispose = dispose;
+
+    /* properties */
+    g_object_class_install_property
+        (object_class, PROP_EDITABLE,
+         g_param_spec_boolean (NMN_CONNECTION_DETAILS_EDITABLE,
+                               "Editable",
+                               "Editable",
+                               FALSE,
+                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+}
diff --git a/src/nmn-connection-details.h b/src/nmn-connection-details.h
new file mode 100644
index 0000000..bea4f4d
--- /dev/null
+++ b/src/nmn-connection-details.h
@@ -0,0 +1,36 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+#ifndef NMN_CONNECTION_DETAILS_H
+#define NMN_CONNECTION_DETAILS_H
+
+#include <gtk/gtk.h>
+#include <nm-setting-ip4-config.h>
+#include <nm-ip4-config.h>
+
+#define NMN_TYPE_CONNECTION_DETAILS            (nmn_connection_details_get_type ())
+#define NMN_CONNECTION_DETAILS(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMN_TYPE_CONNECTION_DETAILS, NmnConnectionDetails))
+#define NMN_CONNECTION_DETAILS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NMN_TYPE_CONNECTION_DETAILS, NmnConnectionDetailsClass))
+#define NMN_IS_CONNECTION_DETAILS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMN_TYPE_CONNECTION_DETAILS))
+#define NMN_IS_CONNECTION_DETAILS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NMN_TYPE_CONNECTION_DETAILS))
+#define NMN_CONNECTION_DETAILS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NMN_TYPE_CONNECTION_DETAILS, NmnConnectionDetailsClass))
+
+#define NMN_CONNECTION_DETAILS_EDITABLE "editable"
+
+typedef struct {
+    GtkTable parent;
+} NmnConnectionDetails;
+
+typedef struct {
+    GtkTableClass parent;
+} NmnConnectionDetailsClass;
+
+GType nmn_connection_details_get_type (void);
+
+GtkWidget *nmn_connection_details_new         (gboolean editable);
+void       nmn_connection_details_set_setting (NmnConnectionDetails *self,
+                                               NMSettingIP4Config *setting);
+
+void       nmn_connection_details_set_config  (NmnConnectionDetails *self,
+                                               NMIP4Config *config);
+
+#endif /* NMN_CONNECTION_DETAILS_H */
diff --git a/src/nmn-item.c b/src/nmn-item.c
index a32490b..88da11b 100644
--- a/src/nmn-item.c
+++ b/src/nmn-item.c
@@ -19,14 +19,15 @@ static guint signals[LAST_SIGNAL];
 #define NMN_ITEM_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NMN_TYPE_ITEM, NmnItemPrivate))
 
 typedef struct {
-    GtkBox *box;
+    GtkBox *vbox; /* child of self */
+    GtkBox *hbox; /* child of vbox */
 
     GtkWidget *icon;
     GtkLabel *name;
     GtkWidget *status_separator;
     GtkLabel *status_label;
     GtkLabel *security;
-    GtkLabel *advanced;
+    GtkWidget *advanced;
     GtkButton *connect;
     GtkWidget *remove;
     NmnItemStatus status;
@@ -163,13 +164,13 @@ nmn_item_set_delete_visible (NmnItem *item,
         gtk_container_add (GTK_CONTAINER (priv->remove),
                            gtk_image_new_from_stock (GTK_STOCK_DELETE, GTK_ICON_SIZE_BUTTON));
 
-        gtk_box_pack_end (priv->box, priv->remove, FALSE, FALSE, 0);
+        gtk_box_pack_end (priv->hbox, priv->remove, FALSE, FALSE, 0);
         gtk_widget_show_all (priv->remove);
         g_signal_connect_swapped (priv->remove, "clicked",
                                   G_CALLBACK (nmn_item_delete),
                                   item);
     } else if (!visible && priv->remove) {
-        gtk_container_remove (GTK_CONTAINER (priv->box), priv->remove);
+        gtk_container_remove (GTK_CONTAINER (priv->hbox), priv->remove);
         priv->remove = NULL;
     }
 }
@@ -220,6 +221,43 @@ nmn_item_priority_changed (NmnItem *self)
 }
 
 static void
+advanced_expanded (GtkExpander *expander,
+                   GParamSpec *param_spec,
+                   gpointer user_data)
+{
+    NmnItem *self = NMN_ITEM (user_data);
+    NmnItemPrivate *priv = NMN_ITEM_GET_PRIVATE (self);
+    GtkWidget *child;
+
+    if (gtk_expander_get_expanded (expander)) {
+        /* create widgets */
+
+        if (NMN_ITEM_GET_CLASS (self)->create_advanced_information)
+            child = NMN_ITEM_GET_CLASS (self)->create_advanced_information (self);
+        else
+            child = NULL;
+
+        if (child) {
+            GtkWidget *alignment;
+
+            alignment = gtk_alignment_new (0, 0, 0, 0);
+            gtk_container_add (GTK_CONTAINER (alignment), child);
+            gtk_widget_show (alignment);
+
+            gtk_box_pack_end (priv->vbox, alignment, FALSE, FALSE, 0);
+            g_object_set_data (G_OBJECT (priv->vbox), "expanded-child", alignment);
+        }
+    } else {
+        /* Hide or destroy widgets */
+        child = GTK_WIDGET (g_object_get_data (G_OBJECT (priv->vbox), "expanded-child"));
+        if (child) {
+            g_object_set_data (G_OBJECT (priv->vbox), "expanded-child", NULL);
+            gtk_container_remove (GTK_CONTAINER (priv->vbox), child);
+        }
+    }
+}
+
+static void
 nmn_item_connect (NmnItem *item)
 {
     g_warning ("Connect not overriden");
@@ -251,14 +289,19 @@ nmn_item_init (NmnItem *item)
     GtkWidget *hbox;
     GtkWidget *w;
 
-    priv->box = GTK_BOX (gtk_hbox_new (FALSE, 6));
-    gtk_container_set_border_width (GTK_CONTAINER (priv->box), 6);
+    priv->vbox = GTK_BOX (gtk_vbox_new (FALSE, 6));
+    gtk_container_set_border_width (GTK_CONTAINER (priv->vbox), 6);
+    gtk_container_add (GTK_CONTAINER (item), GTK_WIDGET (priv->vbox));
+
+    priv->hbox = GTK_BOX (gtk_hbox_new (FALSE, 6));
+    gtk_container_set_border_width (GTK_CONTAINER (priv->hbox), 6);
+    gtk_box_pack_start (priv->vbox, GTK_WIDGET (priv->hbox), TRUE, TRUE, 0);
 
     priv->icon = gtk_image_new ();
-    gtk_box_pack_start (priv->box, priv->icon, FALSE, FALSE, 0);
+    gtk_box_pack_start (priv->hbox, priv->icon, FALSE, FALSE, 0);
 
     vbox = gtk_vbox_new (FALSE, 0);
-    gtk_box_pack_start (priv->box, vbox, TRUE, TRUE, 0);
+    gtk_box_pack_start (priv->hbox, vbox, TRUE, TRUE, 0);
 
     hbox = gtk_hbox_new (FALSE, 12);
     gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
@@ -286,9 +329,10 @@ nmn_item_init (NmnItem *item)
     gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
     priv->security = GTK_LABEL (w);
 
-    w = gtk_label_new ("Advanced");
+    w = gtk_expander_new ("Advanced");
     gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
-    priv->advanced = GTK_LABEL (w);
+    priv->advanced = w;
+    g_signal_connect (w, "notify::expanded", G_CALLBACK (advanced_expanded), item);
 
     w = gtk_button_new_with_label ("Connect");
     gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
@@ -297,8 +341,7 @@ nmn_item_init (NmnItem *item)
 
     priv->remove = NULL;
 
-    gtk_container_add (GTK_CONTAINER (item), GTK_WIDGET (priv->box));
-    gtk_widget_show_all (GTK_WIDGET (priv->box));
+    gtk_widget_show_all (GTK_WIDGET (priv->vbox));
 }
 
 static void
diff --git a/src/nmn-item.h b/src/nmn-item.h
index a68a39d..e4334b7 100644
--- a/src/nmn-item.h
+++ b/src/nmn-item.h
@@ -23,6 +23,7 @@ typedef struct {
     void (*connect) (NmnItem *self);
     void (*disconnect) (NmnItem *self);
     guint (*get_priority) (NmnItem *self);
+    GtkWidget *(*create_advanced_information) (NmnItem *self);
 
     /* Signals */
     void (*connect_requested) (NmnItem *self);
diff --git a/src/nmn-list.c b/src/nmn-list.c
index d82c063..e2778de 100644
--- a/src/nmn-list.c
+++ b/src/nmn-list.c
@@ -299,7 +299,7 @@ nmn_list_init (NmnList *list)
                        G_N_ELEMENTS (nmn_list_targets),
                        GDK_ACTION_MOVE);
 
-    gtk_box_set_homogeneous (GTK_BOX (list), TRUE);
+    gtk_box_set_homogeneous (GTK_BOX (list), FALSE);
     gtk_box_set_spacing (GTK_BOX (list), 12);
 }
 
diff --git a/src/nmn-network-item.c b/src/nmn-network-item.c
index 9161f13..4c2e180 100644
--- a/src/nmn-network-item.c
+++ b/src/nmn-network-item.c
@@ -4,7 +4,9 @@
 #include <nm-device.h>
 #include <nm-connection.h>
 #include <nm-setting-connection.h>
+#include <nm-setting-ip4-config.h>
 #include "nmn-network-item.h"
+#include "nmn-connection-details.h"
 #include "nma-gconf-connection.h"
 
 #define DBUS_TYPE_G_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
@@ -298,6 +300,35 @@ get_priority (NmnItem *item)
     return priority;
 }
 
+static GtkWidget *
+create_advanced_information (NmnItem *item)
+{
+    NmnNetworkItemPrivate *priv = GET_PRIVATE (item);
+    GtkWidget *details;
+
+    details = nmn_connection_details_new (nmn_item_get_status (item) == NMN_ITEM_STATUS_DISCONNECTED);
+
+    if (priv->connection) {
+        NMConnection *connection;
+        NMSettingIP4Config *setting;
+
+        connection = nm_exported_connection_get_connection (priv->connection);
+        setting = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+        if (setting)
+            nmn_connection_details_set_setting (NMN_CONNECTION_DETAILS (details), setting);
+    }
+
+    if (nm_device_get_state (priv->device) == NM_DEVICE_STATE_ACTIVATED) {
+        NMIP4Config *config;
+
+        config = nm_device_get_ip4_config (priv->device);
+        if (config)
+            nmn_connection_details_set_config (NMN_CONNECTION_DETAILS (details), config);
+    }
+
+    return details;
+}
+
 static void
 nmn_network_item_init (NmnNetworkItem *item)
 {
@@ -423,6 +454,7 @@ nmn_network_item_class_init (NmnNetworkItemClass *class)
     item_class->disconnect = disconnect;
     item_class->delete = item_delete;
     item_class->get_priority = get_priority;
+    item_class->create_advanced_information = create_advanced_information;
 
     /* properties */
     g_object_class_install_property



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