[network-manager-netbook] Split up NmnItemRenderer to that and NmnNetworkRenderer



commit 7536168dcdfc219a7678ef34fd3f72a37d5df025
Author: Tambet Ingo <tambet gmail com>
Date:   Tue Mar 2 13:23:06 2010 -0400

    Split up NmnItemRenderer to that and NmnNetworkRenderer
    
    In preparation to have a GSM PIN unlock renderer which looks nothing like
    network items, but still needs prelight handling etc.

 src/Makefile.am            |    2 +
 src/nmn-item-renderer.c    |  416 +++++-----------------------------------
 src/nmn-item-renderer.h    |    9 +-
 src/nmn-list.c             |    4 +-
 src/nmn-network-renderer.c |  455 ++++++++++++++++++++++++++++++++++++++++++++
 src/nmn-network-renderer.h |   45 +++++
 6 files changed, 558 insertions(+), 373 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index d89f636..52caac7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -31,6 +31,8 @@ network_manager_netbook_SOURCES = \
 	nmn-list.h \
 	nmn-model.c \
 	nmn-model.h \
+	nmn-network-renderer.c \
+	nmn-network-renderer.h \
 	nmn-new-connection.c \
 	nmn-new-connection.h \
 	nmn-panel-client.c \
diff --git a/src/nmn-item-renderer.c b/src/nmn-item-renderer.c
index 85c6062..cd8673f 100644
--- a/src/nmn-item-renderer.c
+++ b/src/nmn-item-renderer.c
@@ -36,48 +36,25 @@ enum {
     LAST_PROP
 };
 
+enum {
+    BACKGROUND_UPDATED,
+    ITEM_CHANGED,
+
+    LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
 #define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NMN_TYPE_ITEM_RENDERER, NmnItemRendererPrivate))
 
 typedef struct {
     NMListItem *item;
 
-    GtkBox *vbox; /* child of self */
-    GtkBox *hbox; /* child of vbox */
-
-    GtkImage *icon;
-    GtkLabel *name_and_status;
-    GtkLabel *security_label;
-    GtkWidget *expander;
-    NmnConnectionDetails *details;
-    GtkWidget *connect_button;
-    GtkWidget *remove_button;
-
     gboolean prelight;
     GdkColor prelight_color;
     GdkColor connection_item_color;
-
-    gulong item_changed_id;
-
-    gboolean disposed;
 } NmnItemRendererPrivate;
 
-static NmnConnectionDetails *get_details (NmnItemRenderer *self);
-
-
-GtkWidget *
-nmn_item_renderer_new (void)
-{
-    return (GtkWidget *) g_object_new (NMN_TYPE_ITEM_RENDERER, NULL);
-}
-
-NMListItem *
-nmn_item_renderer_get_item (NmnItemRenderer *self)
-{
-    g_return_val_if_fail (NMN_IS_ITEM_RENDERER (self), NULL);
-
-    return GET_PRIVATE (self)->item;
-}
-
 static void
 update_background (NmnItemRenderer *self)
 {
@@ -94,338 +71,15 @@ update_background (NmnItemRenderer *self)
     }
 
     gtk_widget_modify_bg (GTK_WIDGET (self), GTK_STATE_NORMAL, color);
-    g_object_set (priv->connect_button, "visible", priv->prelight, NULL);
-    g_object_set (priv->remove_button, "visible", priv->prelight && nm_list_item_get_show_delete (priv->item), NULL);
-    g_object_set (priv->expander, "visible", priv->prelight, NULL);
-}
-
-static void
-update_details (NmnItemRenderer *self)
-{
-    NmnItemRendererPrivate *priv = GET_PRIVATE (self);
-    NMConnection *connection;
-    const char *hw_address;
-    NMSettingIP4Config *setting = NULL;
-    NMIP4Config *config = NULL;
-
-    if (!priv->details)
-        return;
-
-    connection = (NMConnection *) nm_connection_item_get_connection (NM_CONNECTION_ITEM (priv->item));
-    if (connection) {
-        NMDevice *device;
-
-        device = nm_device_item_get_device (NM_DEVICE_ITEM (priv->item));
-        setting = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
-    
-        if (device && nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED)
-            config = nm_device_get_ip4_config (device);
-    }
-
-    hw_address = nm_device_item_get_hw_address (NM_DEVICE_ITEM (priv->item));
-    nmn_connection_details_set_data (priv->details, setting, config, hw_address);
-}
-
-static void
-item_changed (NMListItem *item,
-              GParamSpec *spec,
-              gpointer user_data)
-{
-    NmnItemRenderer *self = NMN_ITEM_RENDERER (user_data);
-    NmnItemRendererPrivate *priv = GET_PRIVATE (self);
-    const char *property = spec ? spec->name : NULL;
-    char *str;
-
-    if (!property || !strcmp (property, NM_LIST_ITEM_NAME) ||
-        !strcmp (property, NM_LIST_ITEM_STATUS) || !strcmp (property, NM_CONNECTION_ITEM_CONNECTION)) {
-        const char *status_str;
-        const char *button_label;
-        NMListItemStatus status;
-
-        status = nm_list_item_get_status (priv->item);
-        switch (status) {
-        case NM_LIST_ITEM_STATUS_CONNECTED:
-            status_str = _("Connected");
-            button_label = _("Disconnect");
-            break;
-        case NM_LIST_ITEM_STATUS_CONNECTING:
-            status_str = _("Connecting");
-            button_label = _("Cancel");
-            break;
-        default:
-            status_str = _("Disconnected");
-            button_label = _("Connect");
-            break;
-        }
-
-        if (NM_IS_CONNECTION_ITEM (item) && nm_connection_item_get_connection (NM_CONNECTION_ITEM (item)))
-            str = g_strdup_printf ("<big><b>%s - %s</b></big>", nm_list_item_get_name (item), status_str);
-        else {
-            const char *available_str = _("Available");
-
-            str = g_strdup_printf ("<big><b>%s - %s</b></big>",
-                                   nm_list_item_get_name (item),
-                                   available_str);
-        }
-
-        gtk_label_set_markup (priv->name_and_status, str);
-        g_free (str);
-
-        gtk_button_set_label (GTK_BUTTON (priv->connect_button), button_label);
-        update_details (self);
-        update_background (self);
-    }
-
-    if (!property || !strcmp (property, NM_LIST_ITEM_ICON))
-        gtk_image_set_from_pixbuf (priv->icon, nm_icon_cache_get (nm_list_item_get_icon (item)));
-
-    if (!property || !strcmp (property, NM_LIST_ITEM_SECURITY))
-        gtk_label_set_text (priv->security_label, nm_list_item_get_security (item));
-}
-
-static void
-update_connection_cb (NMSettingsConnectionInterface *connection,
-                      GError *error,
-                      gpointer user_data)
-{
-    NmnItemRenderer *self = NMN_ITEM_RENDERER (user_data);
-    NmnItemRendererPrivate *priv = GET_PRIVATE (self);
-
-    if (error)
-        g_warning ("Couldn't update connection: %s", error->message);
-    else
-        nm_list_item_connect (nmn_item_renderer_get_item (self));
+    g_signal_emit (self, signals[BACKGROUND_UPDATED], 0, priv->prelight);
 }
 
-static void
-connect_with_updated_details (NmnItemRenderer *self,
-                              NMConnection *connection,
-                              gboolean new_connection)
-{
-    NmnConnectionDetails *details;
-    gboolean changed = FALSE;
-
-    details = GET_PRIVATE (self)->details;
-    if (details) {
-        NMSetting *current_config;
-        NMSetting *new_config;
-
-        current_config = nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
-        new_config = NM_SETTING (nmn_connection_details_get_data (NMN_CONNECTION_DETAILS (details)));
-
-        if (current_config == NULL || nm_setting_compare (current_config, new_config, 0) == FALSE) {
-            nm_connection_add_setting (connection, new_config);
-            changed = TRUE;
-        }
-    }
-
-    if (new_connection) {
-        NMConnectionItem *connection_item = NM_CONNECTION_ITEM (nmn_item_renderer_get_item (self));
-
-        nm_connection_item_new_connection (connection_item, connection, TRUE);
-        g_object_unref (connection);
-    } else if (changed)
-        nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (connection),
-                                                 update_connection_cb, self);
-    else
-        nm_list_item_connect (nmn_item_renderer_get_item (self));
-}
-
-static void
-connection_created_cb (GObject *object,
-                       GAsyncResult *result,
-                       gpointer user_data)
-{
-    NMConnection *connection;
-    GError *error = NULL;
-
-    connection = nm_connection_item_create_connection_finish (NM_CONNECTION_ITEM (object), result, &error);
-    if (connection)
-        connect_with_updated_details (NMN_ITEM_RENDERER (user_data), connection, TRUE);
-}
-
-static void
-connect_button_clicked (GtkButton *button, gpointer user_data)
-{
-    NmnItemRenderer *self = NMN_ITEM_RENDERER (user_data);
-    NMListItem *item;
-
-    item = nmn_item_renderer_get_item (self);
-    if (nm_list_item_get_status (item) == NM_LIST_ITEM_STATUS_DISCONNECTED) {
-        NMConnectionItem *connection_item;
-        NMConnection *connection;
-
-        connection_item = NM_CONNECTION_ITEM (nmn_item_renderer_get_item (self));
-        connection = (NMConnection *) nm_connection_item_get_connection (connection_item);
-        if (connection)
-            connect_with_updated_details (self, connection, FALSE);
-        else
-            /* We don't have a connection yet, so create one */
-            nm_connection_item_create_connection (connection_item, connection_created_cb, self);
-    } else
-        nm_list_item_disconnect (item);
-}
-
-static void
-details_changed (NmnConnectionDetails *details,
-                 gboolean complete,
-                 gpointer user_data)
-{
-    NmnItemRendererPrivate *priv = GET_PRIVATE (user_data);
-
-    gtk_widget_set_sensitive (GTK_WIDGET (priv->connect_button), complete);
-}
-
-static NmnConnectionDetails *
-get_details (NmnItemRenderer *self)
-{
-    NmnItemRendererPrivate *priv = GET_PRIVATE (self);
-    GtkWidget *alignment;
-
-    if (priv->details)
-        return priv->details;
-
-    if (!NM_IS_DEVICE_ITEM (priv->item) || !nm_device_item_get_device (NM_DEVICE_ITEM (priv->item)))
-        return NULL;
-
-    priv->details = nmn_connection_details_new ();
-    update_details (self);
-
-    alignment = gtk_alignment_new (0, 0, 0, 0);
-    gtk_container_add (GTK_CONTAINER (alignment), GTK_WIDGET (priv->details));
-    gtk_widget_show (alignment);
-    gtk_box_pack_end (priv->vbox, alignment, FALSE, FALSE, 0);
-
-    g_signal_connect (priv->details, "changed", G_CALLBACK (details_changed), self);
-    details_changed (priv->details, nmn_connection_details_verify (priv->details), self);
-
-    return priv->details;
-}
-
-static void
-advanced_expanded (GtkExpander *expander,
-                   GParamSpec *param_spec,
-                   gpointer user_data)
-{
-    NmnConnectionDetails *details;
-
-    details = get_details (NMN_ITEM_RENDERER (user_data));
-    if (details)
-        g_object_set (details, "visible", gtk_expander_get_expanded (expander), NULL);
-}
-
-static void
-remove_button_clicked (GtkButton *button, gpointer user_data)
+NMListItem *
+nmn_item_renderer_get_item (NmnItemRenderer *self)
 {
-    NmnItemRenderer *self = NMN_ITEM_RENDERER (user_data);
-    GtkDialog *dialog;
-    GtkWidget *label;
-    const char *name;
-    char *label_text;
-    NMListItem *item;
-
-    item = nmn_item_renderer_get_item (self);
-
-    dialog = GTK_DIALOG (gtk_dialog_new_with_buttons (_("Really remove?"),
-                                                      NULL,
-                                                      GTK_DIALOG_MODAL |
-                                                      GTK_DIALOG_DESTROY_WITH_PARENT,
-                                                      _("No, save"),
-                                                      GTK_RESPONSE_REJECT,
-                                                      _("Yes, delete"),
-                                                      GTK_RESPONSE_ACCEPT,
-                                                      NULL));
-
-    gtk_dialog_set_has_separator (dialog, FALSE);
-    gtk_dialog_set_default_response (dialog, GTK_RESPONSE_ACCEPT);
-    gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
-    gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_DELETE);
-
-    name = nm_list_item_get_name (item);
-    label_text = g_strdup_printf (_("Do you want to remove the '%s' %s network? "
-                                    "This\nwill forget the password and you will"
-                                    " no longer be\nautomatically connected to "
-                                    "'%s'."),
-                                  name,
-                                  nm_list_item_get_type_name (item),
-                                  name);
-
-    label = gtk_label_new (label_text);
-    g_free (label_text);
-
-    gtk_box_set_spacing (GTK_BOX (dialog->vbox), 12);
-    gtk_box_pack_start (GTK_BOX (dialog->vbox), label, TRUE, TRUE, 6);
-    gtk_widget_show_all (GTK_WIDGET (dialog));
-
-    if (gtk_dialog_run (dialog) == GTK_RESPONSE_ACCEPT)
-        nm_list_item_delete (item);
-
-    gtk_widget_destroy (GTK_WIDGET (dialog));
-    nm_utils_dialog_done ();
-}
+    g_return_val_if_fail (NMN_IS_ITEM_RENDERER (self), NULL);
 
-static void
-init_widgets (NmnItemRenderer *self)
-{
-    NmnItemRendererPrivate *priv = GET_PRIVATE (self);
-    GtkWidget *vbox;
-    GtkWidget *hbox;
-    GtkWidget *w;
-
-    priv->vbox = GTK_BOX (gtk_vbox_new (FALSE, 6));
-    gtk_container_set_border_width (GTK_CONTAINER (priv->vbox), 6);
-    gtk_container_add (GTK_CONTAINER (self), 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), FALSE, FALSE, 0);
-
-    priv->icon = GTK_IMAGE (gtk_image_new ());
-    gtk_box_pack_start (priv->hbox, GTK_WIDGET (priv->icon), FALSE, FALSE, 0);
-
-    vbox = gtk_vbox_new (FALSE, 0);
-    gtk_box_pack_start (priv->hbox, vbox, FALSE, FALSE, 0);
-
-    w = gtk_label_new ("");
-    gtk_label_set_use_markup (GTK_LABEL (w), TRUE);
-    gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5);
-    gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
-    priv->name_and_status = GTK_LABEL (w);
-
-    hbox = gtk_hbox_new (FALSE, 12);
-    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
-    w = gtk_label_new ("");
-    gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
-    priv->security_label = GTK_LABEL (w);
-
-    /* FIXME: this should be visibile only for NMDeviceItems */
-    w = gtk_expander_new ("Advanced");
-    gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
-    priv->expander = w;
-    g_signal_connect (w, "notify::expanded", G_CALLBACK (advanced_expanded), self);
-
-    w = gtk_button_new_with_label ("Connect");
-    gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
-    priv->connect_button = w;
-    g_signal_connect (w, "clicked", G_CALLBACK (connect_button_clicked), self);
-
-    /* Remove button */
-    vbox = gtk_vbox_new (FALSE, 0);
-    gtk_box_pack_end (priv->hbox, vbox, FALSE, FALSE, 0);
-
-    w = gtk_button_new ();
-    gtk_button_set_image (GTK_BUTTON (w),
-                          gtk_image_new_from_icon_name ("edit-clear", GTK_ICON_SIZE_MENU));
-
-    gtk_button_set_relief (GTK_BUTTON (w), GTK_RELIEF_NONE);
-    gtk_button_set_image_position (GTK_BUTTON (w), GTK_POS_RIGHT);
-    gtk_widget_set_tooltip_text (w, "Remove connection");
-    gtk_box_pack_start (GTK_BOX (vbox), w, TRUE, FALSE, 0);
-    priv->remove_button = w;
-    g_signal_connect (w, "clicked", G_CALLBACK (remove_button_clicked), self);
-
-    gtk_widget_show_all (GTK_WIDGET (priv->vbox));
+    return GET_PRIVATE (self)->item;
 }
 
 void
@@ -440,10 +94,16 @@ nmn_item_renderer_set_item (NmnItemRenderer *self,
     priv = GET_PRIVATE (self);
     g_return_if_fail (priv->item == NULL);
 
-    init_widgets (self);
     priv->item = g_object_ref (item);
-    priv->item_changed_id = g_signal_connect (priv->item, "notify", G_CALLBACK (item_changed), self);
-    item_changed (priv->item, NULL, self);
+    g_signal_emit (self, signals[ITEM_CHANGED], 0);
+}
+
+gboolean
+nmn_item_renderer_is_prelight (NmnItemRenderer *self)
+{
+    g_return_val_if_fail (NMN_IS_ITEM_RENDERER (self), FALSE);
+
+    return GET_PRIVATE (self)->prelight;
 }
 
 static gboolean
@@ -486,13 +146,9 @@ dispose (GObject *object)
 {
     NmnItemRendererPrivate *priv = GET_PRIVATE (object);
 
-    if (!priv->disposed) {
-        if (priv->item) {
-            g_signal_handler_disconnect (priv->item, priv->item_changed_id);
-            g_object_unref (priv->item);
-        }
-
-        priv->disposed = TRUE;
+    if (priv->item) {
+        g_object_unref (priv->item);
+        priv->item = NULL;
     }
 
     G_OBJECT_CLASS (nmn_item_renderer_parent_class)->dispose (object);
@@ -510,4 +166,24 @@ nmn_item_renderer_class_init (NmnItemRendererClass *class)
 
     widget_class->enter_notify_event = enter_notify_event;
     widget_class->leave_notify_event = leave_notify_event;
+
+    /* signals */
+    signals[BACKGROUND_UPDATED] = g_signal_new
+        ("background-updated",
+         G_OBJECT_CLASS_TYPE (class),
+         G_SIGNAL_RUN_LAST,
+         G_STRUCT_OFFSET (NmnItemRendererClass, background_updated),
+         NULL, NULL,
+         g_cclosure_marshal_VOID__BOOLEAN,
+         G_TYPE_NONE, 1,
+         G_TYPE_BOOLEAN);
+
+    signals[ITEM_CHANGED] = g_signal_new
+        ("item-changed",
+         G_OBJECT_CLASS_TYPE (class),
+         G_SIGNAL_RUN_LAST,
+         G_STRUCT_OFFSET (NmnItemRendererClass, item_changed),
+         NULL, NULL,
+         g_cclosure_marshal_VOID__VOID,
+         G_TYPE_NONE, 0);
 }
diff --git a/src/nmn-item-renderer.h b/src/nmn-item-renderer.h
index a43337e..6278155 100644
--- a/src/nmn-item-renderer.h
+++ b/src/nmn-item-renderer.h
@@ -39,13 +39,20 @@ typedef struct {
 
 typedef struct {
     GtkEventBoxClass parent;
+
+    /* Signals */
+    void (*background_updated) (NmnItemRenderer *self,
+                                gboolean prelight);
+
+    void (*item_changed)       (NmnItemRenderer *self);
 } NmnItemRendererClass;
 
 GType nmn_item_renderer_get_type (void);
 
-GtkWidget  *nmn_item_renderer_new      (void);
 NMListItem *nmn_item_renderer_get_item (NmnItemRenderer *self);
 void        nmn_item_renderer_set_item (NmnItemRenderer *self,
                                         NMListItem *item);
 
+gboolean    nmn_item_renderer_is_prelight (NmnItemRenderer *self);
+
 #endif /* NMN_ITEM_RENDERER_H */
diff --git a/src/nmn-list.c b/src/nmn-list.c
index 08a241c..c192413 100644
--- a/src/nmn-list.c
+++ b/src/nmn-list.c
@@ -23,7 +23,7 @@
 #include <nm-list-item.h>
 #include "nmn-list.h"
 #include "nmn-model.h"
-#include "nmn-item-renderer.h"
+#include "nmn-network-renderer.h"
 
 G_DEFINE_TYPE (NmnList, nmn_list, GTK_TYPE_VBOX)
 
@@ -267,7 +267,7 @@ model_row_inserted (GtkTreeModel *model,
 
     index = gtk_tree_path_get_indices (path)[0];
 
-    renderer = (NmnItemRenderer *) nmn_item_renderer_new ();
+    renderer = (NmnItemRenderer *) nmn_network_renderer_new ();
     renderer->index = index;
 
     if (gtk_tree_model_get_flags (model) & GTK_TREE_MODEL_ITERS_PERSIST)
diff --git a/src/nmn-network-renderer.c b/src/nmn-network-renderer.c
new file mode 100644
index 0000000..92f182b
--- /dev/null
+++ b/src/nmn-network-renderer.c
@@ -0,0 +1,455 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2009 Novell, Inc.
+ */
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include "nmn-network-renderer.h"
+#include "nm-list-item.h"
+#include "nm-icon-cache.h"
+#include "nm-connection-item.h"
+#include "nm-device-item.h"
+#include "nmn-connection-details.h"
+#include "utils.h"
+
+G_DEFINE_TYPE (NmnNetworkRenderer, nmn_network_renderer, NMN_TYPE_ITEM_RENDERER)
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NMN_TYPE_NETWORK_RENDERER, NmnNetworkRendererPrivate))
+
+typedef struct {
+    GtkBox *vbox; /* child of self */
+    GtkBox *hbox; /* child of vbox */
+
+    GtkImage *icon;
+    GtkLabel *name_and_status;
+    GtkLabel *security_label;
+    GtkWidget *expander;
+    NmnConnectionDetails *details;
+    GtkWidget *connect_button;
+    GtkWidget *remove_button;
+
+    gulong item_changed_id;
+} NmnNetworkRendererPrivate;
+
+static NmnConnectionDetails *get_details (NmnNetworkRenderer *self);
+static void renderer_background_updated (NmnItemRenderer *item_renderer, gboolean prelight);
+
+GtkWidget *
+nmn_network_renderer_new (void)
+{
+    return (GtkWidget *) g_object_new (NMN_TYPE_NETWORK_RENDERER, NULL);
+}
+
+static void
+update_details (NmnNetworkRenderer *self)
+{
+    NmnNetworkRendererPrivate *priv = GET_PRIVATE (self);
+    NMConnection *connection;
+    const char *hw_address;
+    NMSettingIP4Config *setting = NULL;
+    NMIP4Config *config = NULL;
+    NMListItem *item;
+
+    if (!priv->details)
+        return;
+
+    item = nmn_item_renderer_get_item (NMN_ITEM_RENDERER (self));
+    connection = (NMConnection *) nm_connection_item_get_connection (NM_CONNECTION_ITEM (item));
+    if (connection) {
+        NMDevice *device;
+
+        device = nm_device_item_get_device (NM_DEVICE_ITEM (item));
+        setting = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+    
+        if (device && nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED)
+            config = nm_device_get_ip4_config (device);
+    }
+
+    hw_address = nm_device_item_get_hw_address (NM_DEVICE_ITEM (item));
+    nmn_connection_details_set_data (priv->details, setting, config, hw_address);
+}
+
+static void
+item_changed (NMListItem *item,
+              GParamSpec *spec,
+              gpointer user_data)
+{
+    NmnNetworkRenderer *self = NMN_NETWORK_RENDERER (user_data);
+    NmnNetworkRendererPrivate *priv = GET_PRIVATE (self);
+    const char *property = spec ? spec->name : NULL;
+    char *str;
+
+    if (!property || !strcmp (property, NM_LIST_ITEM_NAME) ||
+        !strcmp (property, NM_LIST_ITEM_STATUS) || !strcmp (property, NM_CONNECTION_ITEM_CONNECTION)) {
+        const char *status_str;
+        const char *button_label;
+        NMListItemStatus status;
+
+        status = nm_list_item_get_status (item);
+        switch (status) {
+        case NM_LIST_ITEM_STATUS_CONNECTED:
+            status_str = _("Connected");
+            button_label = _("Disconnect");
+            break;
+        case NM_LIST_ITEM_STATUS_CONNECTING:
+            status_str = _("Connecting");
+            button_label = _("Cancel");
+            break;
+        default:
+            status_str = _("Disconnected");
+            button_label = _("Connect");
+            break;
+        }
+
+        if (NM_IS_CONNECTION_ITEM (item) && nm_connection_item_get_connection (NM_CONNECTION_ITEM (item)))
+            str = g_strdup_printf ("<big><b>%s - %s</b></big>", nm_list_item_get_name (item), status_str);
+        else {
+            const char *available_str = _("Available");
+
+            str = g_strdup_printf ("<big><b>%s - %s</b></big>",
+                                   nm_list_item_get_name (item),
+                                   available_str);
+        }
+
+        gtk_label_set_markup (priv->name_and_status, str);
+        g_free (str);
+
+        gtk_button_set_label (GTK_BUTTON (priv->connect_button), button_label);
+        update_details (self);
+        renderer_background_updated (NMN_ITEM_RENDERER (self),
+                                     nmn_item_renderer_is_prelight (NMN_ITEM_RENDERER (self)));
+    }
+
+    if (!property || !strcmp (property, NM_LIST_ITEM_ICON))
+        gtk_image_set_from_pixbuf (priv->icon, nm_icon_cache_get (nm_list_item_get_icon (item)));
+
+    if (!property || !strcmp (property, NM_LIST_ITEM_SECURITY))
+        gtk_label_set_text (priv->security_label, nm_list_item_get_security (item));
+}
+
+static void
+update_connection_cb (NMSettingsConnectionInterface *connection,
+                      GError *error,
+                      gpointer user_data)
+{
+    if (error)
+        g_warning ("Couldn't update connection: %s", error->message);
+    else
+        nm_list_item_connect (nmn_item_renderer_get_item (NMN_ITEM_RENDERER (user_data)));
+}
+
+static void
+connect_with_updated_details (NmnItemRenderer *self,
+                              NMConnection *connection,
+                              gboolean new_connection)
+{
+    NmnConnectionDetails *details;
+    gboolean changed = FALSE;
+
+    details = GET_PRIVATE (self)->details;
+    if (details) {
+        NMSetting *current_config;
+        NMSetting *new_config;
+
+        current_config = nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
+        new_config = NM_SETTING (nmn_connection_details_get_data (NMN_CONNECTION_DETAILS (details)));
+
+        if (current_config == NULL || nm_setting_compare (current_config, new_config, 0) == FALSE) {
+            nm_connection_add_setting (connection, new_config);
+            changed = TRUE;
+        }
+    }
+
+    if (new_connection) {
+        NMConnectionItem *connection_item = NM_CONNECTION_ITEM (nmn_item_renderer_get_item (self));
+
+        nm_connection_item_new_connection (connection_item, connection, TRUE);
+        g_object_unref (connection);
+    } else if (changed)
+        nm_settings_connection_interface_update (NM_SETTINGS_CONNECTION_INTERFACE (connection),
+                                                 update_connection_cb, self);
+    else
+        nm_list_item_connect (nmn_item_renderer_get_item (self));
+}
+
+static void
+connection_created_cb (GObject *object,
+                       GAsyncResult *result,
+                       gpointer user_data)
+{
+    NMConnection *connection;
+    GError *error = NULL;
+
+    connection = nm_connection_item_create_connection_finish (NM_CONNECTION_ITEM (object), result, &error);
+    if (connection)
+        connect_with_updated_details (NMN_ITEM_RENDERER (user_data), connection, TRUE);
+}
+
+static void
+connect_button_clicked (GtkButton *button, gpointer user_data)
+{
+    NmnItemRenderer *self = NMN_ITEM_RENDERER (user_data);
+    NMListItem *item;
+
+    item = nmn_item_renderer_get_item (self);
+    if (nm_list_item_get_status (item) == NM_LIST_ITEM_STATUS_DISCONNECTED) {
+        NMConnectionItem *connection_item;
+        NMConnection *connection;
+
+        connection_item = NM_CONNECTION_ITEM (nmn_item_renderer_get_item (self));
+        connection = (NMConnection *) nm_connection_item_get_connection (connection_item);
+        if (connection)
+            connect_with_updated_details (self, connection, FALSE);
+        else
+            /* We don't have a connection yet, so create one */
+            nm_connection_item_create_connection (connection_item, connection_created_cb, self);
+    } else
+        nm_list_item_disconnect (item);
+}
+
+static void
+details_changed (NmnConnectionDetails *details,
+                 gboolean complete,
+                 gpointer user_data)
+{
+    NmnNetworkRendererPrivate *priv = GET_PRIVATE (user_data);
+
+    gtk_widget_set_sensitive (GTK_WIDGET (priv->connect_button), complete);
+}
+
+static NmnConnectionDetails *
+get_details (NmnNetworkRenderer *self)
+{
+    NmnNetworkRendererPrivate *priv = GET_PRIVATE (self);
+    GtkWidget *alignment;
+    NMListItem *item;
+
+    if (priv->details)
+        return priv->details;
+
+    item = nmn_item_renderer_get_item (NMN_ITEM_RENDERER (self));
+    if (!NM_IS_DEVICE_ITEM (item) || !nm_device_item_get_device (NM_DEVICE_ITEM (item)))
+        return NULL;
+
+    priv->details = nmn_connection_details_new ();
+    update_details (self);
+
+    alignment = gtk_alignment_new (0, 0, 0, 0);
+    gtk_container_add (GTK_CONTAINER (alignment), GTK_WIDGET (priv->details));
+    gtk_widget_show (alignment);
+    gtk_box_pack_end (priv->vbox, alignment, FALSE, FALSE, 0);
+
+    g_signal_connect (priv->details, "changed", G_CALLBACK (details_changed), self);
+    details_changed (priv->details, nmn_connection_details_verify (priv->details), self);
+
+    return priv->details;
+}
+
+static void
+advanced_expanded (GtkExpander *expander,
+                   GParamSpec *param_spec,
+                   gpointer user_data)
+{
+    NmnConnectionDetails *details;
+
+    details = get_details (NMN_NETWORK_RENDERER (user_data));
+    if (details)
+        g_object_set (details, "visible", gtk_expander_get_expanded (expander), NULL);
+}
+
+static void
+remove_button_clicked (GtkButton *button, gpointer user_data)
+{
+    GtkDialog *dialog;
+    GtkWidget *label;
+    const char *name;
+    char *label_text;
+    NMListItem *item;
+
+    item = nmn_item_renderer_get_item (NMN_ITEM_RENDERER (user_data));
+    dialog = GTK_DIALOG (gtk_dialog_new_with_buttons (_("Really remove?"),
+                                                      NULL,
+                                                      GTK_DIALOG_MODAL |
+                                                      GTK_DIALOG_DESTROY_WITH_PARENT,
+                                                      _("No, save"),
+                                                      GTK_RESPONSE_REJECT,
+                                                      _("Yes, delete"),
+                                                      GTK_RESPONSE_ACCEPT,
+                                                      NULL));
+
+    gtk_dialog_set_has_separator (dialog, FALSE);
+    gtk_dialog_set_default_response (dialog, GTK_RESPONSE_ACCEPT);
+    gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+    gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_DELETE);
+
+    name = nm_list_item_get_name (item);
+    label_text = g_strdup_printf (_("Do you want to remove the '%s' %s network? "
+                                    "This\nwill forget the password and you will"
+                                    " no longer be\nautomatically connected to "
+                                    "'%s'."),
+                                  name,
+                                  nm_list_item_get_type_name (item),
+                                  name);
+
+    label = gtk_label_new (label_text);
+    g_free (label_text);
+
+    gtk_box_set_spacing (GTK_BOX (dialog->vbox), 12);
+    gtk_box_pack_start (GTK_BOX (dialog->vbox), label, TRUE, TRUE, 6);
+    gtk_widget_show_all (GTK_WIDGET (dialog));
+
+    if (gtk_dialog_run (dialog) == GTK_RESPONSE_ACCEPT)
+        nm_list_item_delete (item);
+
+    gtk_widget_destroy (GTK_WIDGET (dialog));
+    nm_utils_dialog_done ();
+}
+
+static void
+init_widgets (NmnNetworkRenderer *self)
+{
+    NmnNetworkRendererPrivate *priv = GET_PRIVATE (self);
+    GtkWidget *vbox;
+    GtkWidget *hbox;
+    GtkWidget *w;
+
+    priv->vbox = GTK_BOX (gtk_vbox_new (FALSE, 6));
+    gtk_container_set_border_width (GTK_CONTAINER (priv->vbox), 6);
+    gtk_container_add (GTK_CONTAINER (self), 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), FALSE, FALSE, 0);
+
+    priv->icon = GTK_IMAGE (gtk_image_new ());
+    gtk_box_pack_start (priv->hbox, GTK_WIDGET (priv->icon), FALSE, FALSE, 0);
+
+    vbox = gtk_vbox_new (FALSE, 0);
+    gtk_box_pack_start (priv->hbox, vbox, FALSE, FALSE, 0);
+
+    w = gtk_label_new ("");
+    gtk_label_set_use_markup (GTK_LABEL (w), TRUE);
+    gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5);
+    gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
+    priv->name_and_status = GTK_LABEL (w);
+
+    hbox = gtk_hbox_new (FALSE, 12);
+    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+
+    w = gtk_label_new ("");
+    gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
+    priv->security_label = GTK_LABEL (w);
+
+    /* FIXME: this should be visibile only for NMDeviceItems */
+    w = gtk_expander_new ("Advanced");
+    gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
+    priv->expander = w;
+    g_signal_connect (w, "notify::expanded", G_CALLBACK (advanced_expanded), self);
+
+    w = gtk_button_new_with_label ("Connect");
+    gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
+    priv->connect_button = w;
+    g_signal_connect (w, "clicked", G_CALLBACK (connect_button_clicked), self);
+
+    /* Remove button */
+    vbox = gtk_vbox_new (FALSE, 0);
+    gtk_box_pack_end (priv->hbox, vbox, FALSE, FALSE, 0);
+
+    w = gtk_button_new ();
+    gtk_button_set_image (GTK_BUTTON (w),
+                          gtk_image_new_from_icon_name ("edit-clear", GTK_ICON_SIZE_MENU));
+
+    gtk_button_set_relief (GTK_BUTTON (w), GTK_RELIEF_NONE);
+    gtk_button_set_image_position (GTK_BUTTON (w), GTK_POS_RIGHT);
+    gtk_widget_set_tooltip_text (w, "Remove connection");
+    gtk_box_pack_start (GTK_BOX (vbox), w, TRUE, FALSE, 0);
+    priv->remove_button = w;
+    g_signal_connect (w, "clicked", G_CALLBACK (remove_button_clicked), self);
+
+    gtk_widget_show_all (GTK_WIDGET (priv->vbox));
+}
+
+static void
+renderer_background_updated (NmnItemRenderer *item_renderer,
+                             gboolean prelight)
+{
+    NmnNetworkRendererPrivate *priv = GET_PRIVATE (item_renderer);
+    NMListItem *item;
+    gboolean show_delete;
+
+    item = nmn_item_renderer_get_item (item_renderer);
+    if (prelight && item && nm_list_item_get_show_delete (item))
+        show_delete = TRUE;
+    else
+        show_delete = FALSE;
+
+    g_object_set (priv->connect_button, "visible", prelight, NULL);
+    g_object_set (priv->remove_button, "visible", show_delete, NULL);
+    g_object_set (priv->expander, "visible", prelight, NULL);
+}
+
+static void
+renderer_item_changed (NmnItemRenderer *item_renderer)
+{
+    NmnNetworkRendererPrivate *priv = GET_PRIVATE (item_renderer);
+    NMListItem *item;
+
+    init_widgets (NMN_NETWORK_RENDERER (item_renderer));
+
+    item = nmn_item_renderer_get_item (item_renderer);
+    if (item) {
+        priv->item_changed_id = g_signal_connect (item, "notify", G_CALLBACK (item_changed), item_renderer);
+        item_changed (item, NULL, item_renderer);
+    }
+    /* FIXME: disconnect previous handlers */
+}
+
+static void
+nmn_network_renderer_init (NmnNetworkRenderer *item)
+{
+}
+
+static void
+dispose (GObject *object)
+{
+    NmnNetworkRendererPrivate *priv = GET_PRIVATE (object);
+
+    if (priv->item_changed_id) {
+        NMListItem *item;
+
+        item = nmn_item_renderer_get_item (NMN_ITEM_RENDERER (object));
+        g_signal_handler_disconnect (item, priv->item_changed_id);
+        priv->item_changed_id = 0;
+    }
+
+    G_OBJECT_CLASS (nmn_network_renderer_parent_class)->dispose (object);
+}
+
+static void
+nmn_network_renderer_class_init (NmnNetworkRendererClass *class)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (class);
+    NmnItemRendererClass *renderer_class = NMN_ITEM_RENDERER_CLASS (class);
+
+    g_type_class_add_private (object_class, sizeof (NmnNetworkRendererPrivate));
+
+    object_class->dispose = dispose;
+
+    renderer_class->background_updated = renderer_background_updated;
+    renderer_class->item_changed = renderer_item_changed;
+}
diff --git a/src/nmn-network-renderer.h b/src/nmn-network-renderer.h
new file mode 100644
index 0000000..cd11da3
--- /dev/null
+++ b/src/nmn-network-renderer.h
@@ -0,0 +1,45 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2009 Novell, Inc.
+ */
+
+#ifndef NMN_NETWORK_RENDERER_H
+#define NMN_NETWORK_RENDERER_H
+
+#include <gtk/gtk.h>
+#include "nmn-item-renderer.h"
+
+#define NMN_TYPE_NETWORK_RENDERER            (nmn_network_renderer_get_type ())
+#define NMN_NETWORK_RENDERER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMN_TYPE_NETWORK_RENDERER, NmnNetworkRenderer))
+#define NMN_NETWORK_RENDERER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NMN_TYPE_NETWORK_RENDERER, NmnNetworkRendererClass))
+#define NMN_IS_NETWORK_RENDERER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMN_TYPE_NETWORK_RENDERER))
+#define NMN_IS_NETWORK_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NMN_TYPE_NETWORK_RENDERER))
+#define NMN_NETWORK_RENDERER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NMN_TYPE_NETWORK_RENDERER, NmnNetworkRendererClass))
+
+typedef struct {
+    NmnItemRenderer parent;
+} NmnNetworkRenderer;
+
+typedef struct {
+    NmnItemRendererClass parent;
+} NmnNetworkRendererClass;
+
+GType nmn_network_renderer_get_type (void);
+
+GtkWidget  *nmn_network_renderer_new (void);
+
+#endif /* NMN_NETWORK_RENDERER_H */



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