[network-manager-netbook/MplPanelClient] The great rewrite.
- From: Tambet Ingo <tambeti src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [network-manager-netbook/MplPanelClient] The great rewrite.
- Date: Fri, 27 Nov 2009 14:11:29 +0000 (UTC)
commit f8df6c92a2e17931d3d6b9bfe5713231e292c94b
Author: Tambet Ingo <tambet gmail com>
Date: Fri Nov 27 16:02:04 2009 +0200
The great rewrite.
Rewrite most of the code to:
* Use model-view design for lists, it was getting out of hand.
* Split out libnm-gtk which could be shared with nm-applet.
* Show all available APs in the main list (with different background).
.gitignore | 6 -
Makefile.am | 2 +-
configure.in | 8 +-
libnm-gtk/.gitignore | 1 +
libnm-gtk/Makefile.am | 95 ++
{src/gconf-helpers => libnm-gtk}/gconf-helpers.c | 43 +-
{src/gconf-helpers => libnm-gtk}/gconf-helpers.h | 2 +-
{src/gconf-helpers => libnm-gtk}/gconf-upgrade.c | 0
{src/gconf-helpers => libnm-gtk}/gconf-upgrade.h | 0
libnm-gtk/nm-cdma-item.c | 76 ++
libnm-gtk/nm-cdma-item.h | 52 +
libnm-gtk/nm-cdma-provider.c | 71 ++
libnm-gtk/nm-cdma-provider.h | 51 +
libnm-gtk/nm-connection-item.c | 371 +++++++
libnm-gtk/nm-connection-item.h | 61 ++
libnm-gtk/nm-connection-list.c | 276 ++++++
libnm-gtk/nm-connection-list.h | 54 +
libnm-gtk/nm-connection-model.c | 203 ++++
libnm-gtk/nm-connection-model.h | 60 ++
libnm-gtk/nm-device-handler.c | 263 +++++
libnm-gtk/nm-device-handler.h | 60 ++
libnm-gtk/nm-device-item.c | 176 ++++
libnm-gtk/nm-device-item.h | 55 ++
libnm-gtk/nm-device-model.c | 266 +++++
libnm-gtk/nm-device-model.h | 61 ++
libnm-gtk/nm-device-provider.c | 154 +++
libnm-gtk/nm-device-provider.h | 59 ++
libnm-gtk/nm-ethernet-item.c | 116 +++
libnm-gtk/nm-ethernet-item.h | 52 +
libnm-gtk/nm-ethernet-provider.c | 71 ++
libnm-gtk/nm-ethernet-provider.h | 51 +
.../nm-gconf-connection.c | 150 ++--
libnm-gtk/nm-gconf-connection.h | 78 ++
.../nm-gconf-settings.c | 154 ++--
.../nm-gconf-settings.h | 38 +-
libnm-gtk/nm-gsm-item.c | 76 ++
libnm-gtk/nm-gsm-item.h | 52 +
libnm-gtk/nm-gsm-provider.c | 71 ++
libnm-gtk/nm-gsm-provider.h | 51 +
src/nmn-icon-cache.c => libnm-gtk/nm-icon-cache.c | 37 +-
src/nmn-icon-cache.h => libnm-gtk/nm-icon-cache.h | 10 +-
libnm-gtk/nm-item-provider.c | 308 ++++++
libnm-gtk/nm-item-provider.h | 79 ++
libnm-gtk/nm-list-item.c | 343 +++++++
libnm-gtk/nm-list-item.h | 93 ++
libnm-gtk/nm-list-model.c | 314 ++++++
libnm-gtk/nm-list-model.h | 67 ++
libnm-gtk/nm-status-icon.c | 244 +++++
libnm-gtk/nm-status-icon.h | 51 +
libnm-gtk/nm-status-model.c | 126 +++
libnm-gtk/nm-status-model.h | 55 ++
libnm-gtk/nm-wifi-item.c | 592 +++++++++++
libnm-gtk/nm-wifi-item.h | 63 ++
libnm-gtk/nm-wifi-provider.c | 229 +++++
libnm-gtk/nm-wifi-provider.h | 51 +
libnm-gtk/test.c | 224 +++++
libnm-gtk/utils.c | 856 ++++++++++++++++
libnm-gtk/utils.h | 57 ++
{src => libnm-gtk}/wireless-dialog.c | 2 -
{src => libnm-gtk}/wireless-dialog.h | 0
{src => libnm-gtk}/wireless-helper.h | 0
{src => libnm-gtk}/wireless-security.ui | 0
{src => libnm-gtk}/wireless-security/Makefile.am | 5 +-
.../wireless-security/ca-nag-dialog.ui | 0
.../wireless-security/dynamic-wep.ui | 0
{src => libnm-gtk}/wireless-security/eap-leap.ui | 0
.../wireless-security/eap-method-leap.c | 0
.../wireless-security/eap-method-leap.h | 0
.../wireless-security/eap-method-peap.c | 0
.../wireless-security/eap-method-peap.h | 0
.../wireless-security/eap-method-simple.c | 0
.../wireless-security/eap-method-simple.h | 0
.../wireless-security/eap-method-tls.c | 0
.../wireless-security/eap-method-tls.h | 0
.../wireless-security/eap-method-ttls.c | 0
.../wireless-security/eap-method-ttls.h | 0
{src => libnm-gtk}/wireless-security/eap-method.c | 0
{src => libnm-gtk}/wireless-security/eap-method.h | 0
{src => libnm-gtk}/wireless-security/eap-peap.ui | 0
{src => libnm-gtk}/wireless-security/eap-simple.ui | 0
{src => libnm-gtk}/wireless-security/eap-tls.ui | 0
{src => libnm-gtk}/wireless-security/eap-ttls.ui | 0
{src => libnm-gtk}/wireless-security/helpers.c | 0
{src => libnm-gtk}/wireless-security/helpers.h | 0
{src => libnm-gtk}/wireless-security/leap.ui | 0
{src => libnm-gtk}/wireless-security/wep-key.ui | 0
.../wireless-security/wireless-security.c | 0
.../wireless-security/wireless-security.h | 0
{src => libnm-gtk}/wireless-security/wpa-eap.ui | 0
{src => libnm-gtk}/wireless-security/wpa-psk.ui | 0
.../wireless-security/ws-dynamic-wep.c | 0
.../wireless-security/ws-dynamic-wep.h | 0
{src => libnm-gtk}/wireless-security/ws-leap.c | 1 -
{src => libnm-gtk}/wireless-security/ws-leap.h | 0
{src => libnm-gtk}/wireless-security/ws-wep-key.c | 2 -
{src => libnm-gtk}/wireless-security/ws-wep-key.h | 0
{src => libnm-gtk}/wireless-security/ws-wpa-eap.c | 0
{src => libnm-gtk}/wireless-security/ws-wpa-eap.h | 0
{src => libnm-gtk}/wireless-security/ws-wpa-psk.c | 1 -
{src => libnm-gtk}/wireless-security/ws-wpa-psk.h | 0
marshallers/.gitignore | 2 +
{src/marshallers => marshallers}/Makefile.am | 0
.../marshallers => marshallers}/nma-marshal-main.c | 0
{src/marshallers => marshallers}/nma-marshal.list | 0
po/.gitignore | 2 +
po/POTFILES.in | 53 +-
src/.gitignore | 1 +
src/Makefile.am | 60 +-
src/gconf-helpers/Makefile.am | 21 -
src/gconf-helpers/nma-gconf-connection.h | 78 --
src/main.c | 79 +-
src/nmn-applet.c | 294 ++-----
src/nmn-applet.h | 19 +-
src/nmn-device-handler.c | 379 --------
src/nmn-device-handler.h | 73 --
src/nmn-ethernet-handler.c | 188 ----
src/nmn-ethernet-handler.h | 47 -
src/nmn-ethernet-item.c | 133 ---
src/nmn-ethernet-item.h | 47 -
src/nmn-item-renderer.c | 445 +++++++++
src/nmn-item-renderer.h | 51 +
src/nmn-item.c | 151 ---
src/nmn-item.h | 62 --
src/nmn-list.c | 552 ++++++-----
src/nmn-list.h | 10 +-
src/nmn-model.c | 433 +++++++++
src/nmn-model.h | 80 ++
src/nmn-network-item.c | 1025 --------------------
src/nmn-network-item.h | 105 --
src/nmn-networks.c | 471 ---------
src/nmn-networks.h | 48 -
src/nmn-new-connection.c | 111 ++-
src/nmn-new-connection.h | 6 +-
src/nmn-nm-data.c | 327 -------
src/nmn-nm-data.h | 79 --
src/nmn-panel-client.c | 388 ++++++++
src/nmn-panel-client.h | 52 +
src/nmn-serial-handler.c | 134 ---
src/nmn-serial-handler.h | 47 -
src/nmn-serial-item.c | 157 ---
src/nmn-serial-item.h | 47 -
src/nmn-status-icon.c | 632 ------------
src/nmn-status-icon.h | 55 --
src/nmn-text-item.c | 102 --
src/nmn-text-item.h | 44 -
src/nmn-wifi-handler.c | 375 -------
src/nmn-wifi-handler.h | 47 -
src/nmn-wifi-item.c | 743 --------------
src/nmn-wifi-item.h | 60 --
src/nmn-wifi-list.c | 428 --------
src/nmn-wifi-list.h | 50 -
src/utils.c | 825 ----------------
src/utils.h | 56 +-
153 files changed, 9115 insertions(+), 7855 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 70fcfb3..7259568 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,11 +23,5 @@ ltmain.sh
missing
network-manager-netbook.css
org.moblin.UX.Shell.Panels.network.service
-POTFILES
-po/*.gmo
-shave
-shave-libtool
-src/marshallers/nma-marshal.[ch]
-src/network-manager-netbook
stamp-*
TAGS
diff --git a/Makefile.am b/Makefile.am
index 909e9ad..521009a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = icons src po
+SUBDIRS = icons marshallers libnm-gtk src po
autostartdir = $(sysconfdir)/xdg/autostart
autostart_DATA = network-manager-netbook.desktop
diff --git a/configure.in b/configure.in
index 9d42df8..d7b5abd 100644
--- a/configure.in
+++ b/configure.in
@@ -24,6 +24,8 @@ AM_GLIB_GNU_GETTEXT
NM_REQUIRED=0.7.996
+PKG_CHECK_MODULES(LIBNM_GTK, gtk+-2.0 gconf-2.0 gnome-keyring-1 libnm-util >= $NM_REQUIRED libnm-glib >= $NM_REQUIRED)
+
PKG_CHECK_MODULES(NMN, dbus-glib-1 >= 0.75 gtk+-2.0 gconf-2.0 gnome-keyring-1 libnotify libnm-util >= $NM_REQUIRED libnm-glib >= $NM_REQUIRED mobile-broadband-provider-info moblin-panel nbtk-gtk-1.2)
GLIB_GENMARSHAL=`pkg-config --variable=glib_genmarshal glib-2.0`
@@ -35,10 +37,10 @@ icons/Makefile
icons/22/Makefile
icons/32/Makefile
icons/48/Makefile
+libnm-gtk/Makefile
+libnm-gtk/wireless-security/Makefile
po/Makefile.in
-src/marshallers/Makefile
-src/gconf-helpers/Makefile
-src/wireless-security/Makefile
+marshallers/Makefile
src/Makefile
])
AC_OUTPUT
diff --git a/libnm-gtk/.gitignore b/libnm-gtk/.gitignore
new file mode 100644
index 0000000..9d0f16a
--- /dev/null
+++ b/libnm-gtk/.gitignore
@@ -0,0 +1 @@
+libnm-gtk-test
diff --git a/libnm-gtk/Makefile.am b/libnm-gtk/Makefile.am
new file mode 100644
index 0000000..2b5ca7e
--- /dev/null
+++ b/libnm-gtk/Makefile.am
@@ -0,0 +1,95 @@
+SUBDIRS = wireless-security
+
+NULL=
+
+noinst_LTLIBRARIES = libnm-gtk.la
+
+libnm_gtk_la_CPPFLAGS = \
+ -DUIDIR=\""$(uidir)"\" \
+ -DICONDIR=\""$(pkgdatadir)/icons"\" \
+ $(LIBNM_GTK_CFLAGS) \
+ -I${top_builddir}/marshallers \
+ -I${top_srcdir}/libnm-gtk/wireless-security \
+ $(NULL)
+
+libnm_gtk_la_LIBADD = \
+ $(LIBNM_GTK_LIBS) \
+ ${top_builddir}/marshallers/libmarshallers.la \
+ ${top_builddir}/libnm-gtk/wireless-security/libwireless-security.la \
+ $(NULL)
+
+libnmincludedir = $(includedir)/libnm-gtk
+
+libnminclude_HEADERS = \
+ nm-cdma-item.h \
+ nm-cdma-provider.h \
+ nm-connection-item.h \
+ nm-connection-list.h \
+ nm-connection-model.h \
+ nm-device-handler.h \
+ nm-device-item.h \
+ nm-device-model.h \
+ nm-device-provider.h \
+ nm-ethernet-item.h \
+ nm-ethernet-provider.h \
+ nm-gconf-connection.h \
+ nm-gconf-settings.h \
+ nm-gsm-item.h \
+ nm-gsm-provider.h \
+ nm-item-provider.h \
+ nm-list-item.h \
+ nm-list-model.h \
+ nm-status-icon.h \
+ nm-status-model.h \
+ nm-wifi-item.h \
+ nm-wifi-provider.h \
+ $(NULL)
+
+libnm_gtk_la_SOURCES = \
+ gconf-helpers.c \
+ gconf-helpers.h \
+ gconf-upgrade.c \
+ gconf-upgrade.h \
+ nm-cdma-item.c \
+ nm-cdma-provider.c \
+ nm-connection-item.c \
+ nm-connection-list.c \
+ nm-connection-model.c \
+ nm-device-handler.c \
+ nm-device-item.c \
+ nm-device-model.c \
+ nm-device-provider.c \
+ nm-ethernet-item.c \
+ nm-ethernet-provider.c \
+ nm-gconf-connection.c \
+ nm-gconf-settings.c \
+ nm-gsm-item.c \
+ nm-gsm-provider.c \
+ nm-icon-cache.c \
+ nm-icon-cache.h \
+ nm-item-provider.c \
+ nm-list-item.c \
+ nm-list-model.c \
+ nm-status-icon.c \
+ nm-status-model.c \
+ nm-wifi-item.c \
+ nm-wifi-provider.c \
+ utils.c \
+ utils.h \
+ wireless-dialog.c \
+ wireless-dialog.h \
+ wireless-helper.h \
+ $(NULL)
+
+noinst_PROGRAMS = libnm-gtk-test
+
+libnm_gtk_test_SOURCES = test.c
+libnm_gtk_test_CFLAGS = $(LIBNM_GTK_CFLAGS)
+libnm_gtk_test_LDADD = libnm-gtk.la $(LIBNM_GTK_LIBS)
+
+uidir = $(datadir)/network-manager-netbook
+ui_DATA = wireless-security.ui
+
+EXTRA_DIST = \
+ $(ui_DATA) \
+ $(NULL)
diff --git a/src/gconf-helpers/gconf-helpers.c b/libnm-gtk/gconf-helpers.c
similarity index 98%
rename from src/gconf-helpers/gconf-helpers.c
rename to libnm-gtk/gconf-helpers.c
index 06b2a55..bc2700d 100644
--- a/src/gconf-helpers/gconf-helpers.c
+++ b/libnm-gtk/gconf-helpers.c
@@ -21,6 +21,7 @@
*/
#include <string.h>
+#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <net/ethernet.h>
@@ -50,7 +51,8 @@
#include "gconf-helpers.h"
#include "gconf-upgrade.h"
#include "utils.h"
-#include "nmn-applet.h"
+
+#define APPLET_PREFS_PATH "/apps/nm-applet"
#define DBUS_TYPE_G_ARRAY_OF_OBJECT_PATH (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH))
#define DBUS_TYPE_G_ARRAY_OF_STRING (dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING))
@@ -2466,8 +2468,8 @@ remove_leftovers (CopyOneSettingValueInfo *info)
g_slist_free (dirs);
}
-void
-nm_gconf_write_connection (NMConnection *connection,
+static void
+write_connection_internal (NMConnection *connection,
GConfClient *client,
const char *dir)
{
@@ -2506,6 +2508,41 @@ nm_gconf_write_connection (NMConnection *connection,
nm_gconf_set_ignore_ca_cert (info.connection_uuid, TRUE, ignore);
}
+void
+nm_gconf_write_connection (NMConnection *connection,
+ GConfClient *client,
+ const char *dir)
+{
+ GConfClient *my_client;
+ char *my_dir;
+
+ g_return_if_fail (NM_IS_CONNECTION (connection));
+
+ my_client = client ? g_object_ref (client) : gconf_client_get_default ();
+
+ if (dir)
+ my_dir = g_strdup (dir);
+ else {
+ int i;
+
+ /* Find free GConf directory */
+ while (i++ < G_MAXUINT32) {
+ char buf[255];
+
+ snprintf (&buf[0], 255, GCONF_PATH_CONNECTIONS"/%d", i);
+ if (!gconf_client_dir_exists (my_client, buf, NULL)) {
+ my_dir = g_strdup (buf);
+ break;
+ }
+ }
+ }
+
+ write_connection_internal (connection, my_client, my_dir);
+ gconf_client_suggest_sync (my_client, NULL);
+ g_object_unref (my_client);
+ g_free (my_dir);
+}
+
static char *
get_ignore_path (const char *uuid, gboolean phase2)
{
diff --git a/src/gconf-helpers/gconf-helpers.h b/libnm-gtk/gconf-helpers.h
similarity index 99%
rename from src/gconf-helpers/gconf-helpers.h
rename to libnm-gtk/gconf-helpers.h
index 17d1ce8..87889f9 100644
--- a/src/gconf-helpers/gconf-helpers.h
+++ b/libnm-gtk/gconf-helpers.h
@@ -27,7 +27,7 @@
#include <glib.h>
#include <nm-connection.h>
-#include "nma-gconf-connection.h"
+#include "nm-gconf-connection.h"
#define GCONF_PATH_CONNECTIONS "/system/networking/connections"
diff --git a/src/gconf-helpers/gconf-upgrade.c b/libnm-gtk/gconf-upgrade.c
similarity index 100%
rename from src/gconf-helpers/gconf-upgrade.c
rename to libnm-gtk/gconf-upgrade.c
diff --git a/src/gconf-helpers/gconf-upgrade.h b/libnm-gtk/gconf-upgrade.h
similarity index 100%
rename from src/gconf-helpers/gconf-upgrade.h
rename to libnm-gtk/gconf-upgrade.h
diff --git a/libnm-gtk/nm-cdma-item.c b/libnm-gtk/nm-cdma-item.c
new file mode 100644
index 0000000..8e479a5
--- /dev/null
+++ b/libnm-gtk/nm-cdma-item.c
@@ -0,0 +1,76 @@
+/* -*- 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 <glib/gi18n.h>
+#include <nm-setting-8021x.h>
+#include "nm-cdma-item.h"
+
+G_DEFINE_TYPE (NMCdmaItem, nm_cdma_item, NM_TYPE_DEVICE_ITEM)
+
+NMListItem *
+nm_cdma_item_new (NMClient *client,
+ NMCdmaDevice *device,
+ NMSettingsConnectionInterface *connection)
+{
+ g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (NM_IS_CDMA_DEVICE (device), NULL);
+ g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection), NULL);
+
+ return (NMListItem *) g_object_new (NM_TYPE_CDMA_ITEM,
+ NM_LIST_ITEM_TYPE_NAME, _("3G"),
+ NM_CONNECTION_ITEM_CLIENT, client,
+ NM_CONNECTION_ITEM_CONNECTION, connection,
+ NM_DEVICE_ITEM_DEVICE, device,
+ NULL);
+}
+
+static int
+priority (NMListItem *item)
+{
+ return NM_LIST_ITEM_PRIORITY_DEV_CDMA + NM_LIST_ITEM_CLASS (nm_cdma_item_parent_class)->priority (item);
+}
+
+/*****************************************************************************/
+
+static void
+notify (GObject *object, GParamSpec *spec)
+{
+ /* If the connection is removed from the item, request deletion */
+ if (spec && !g_strcmp0 (spec->name, NM_CONNECTION_ITEM_CONNECTION) &&
+ !nm_connection_item_get_connection (NM_CONNECTION_ITEM (object)))
+
+ nm_list_item_request_remove (NM_LIST_ITEM (object));
+}
+
+static void
+nm_cdma_item_init (NMCdmaItem *self)
+{
+ g_object_set (self, NM_LIST_ITEM_ICON, "nm-device-wwan", NULL);
+}
+
+static void
+nm_cdma_item_class_init (NMCdmaItemClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMListItemClass *list_class = NM_LIST_ITEM_CLASS (klass);
+
+ object_class->notify = notify;
+
+ list_class->priority = priority;
+}
diff --git a/libnm-gtk/nm-cdma-item.h b/libnm-gtk/nm-cdma-item.h
new file mode 100644
index 0000000..f58ed70
--- /dev/null
+++ b/libnm-gtk/nm-cdma-item.h
@@ -0,0 +1,52 @@
+/* -*- 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 NM_CDMA_ITEM_H
+#define NM_CDMA_ITEM_H
+
+#include <glib-object.h>
+#include <nm-cdma-device.h>
+#include <nm-device-item.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_CDMA_ITEM (nm_cdma_item_get_type ())
+#define NM_CDMA_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CDMA_ITEM, NMCdmaItem))
+#define NM_CDMA_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CDMA_ITEM, NMCdmaItemClass))
+#define NM_IS_CDMA_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CDMA_ITEM))
+#define NM_IS_CDMA_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_CDMA_ITEM))
+#define NM_CDMA_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CDMA_ITEM, NMCdmaItemClass))
+
+typedef struct {
+ NMDeviceItem parent;
+} NMCdmaItem;
+
+typedef struct {
+ NMDeviceItemClass parent_class;
+} NMCdmaItemClass;
+
+GType nm_cdma_item_get_type (void);
+
+NMListItem *nm_cdma_item_new (NMClient *client,
+ NMCdmaDevice *device,
+ NMSettingsConnectionInterface *connection);
+
+G_END_DECLS
+
+#endif /* NM_CDMA_ITEM_H */
diff --git a/libnm-gtk/nm-cdma-provider.c b/libnm-gtk/nm-cdma-provider.c
new file mode 100644
index 0000000..f3bc4d8
--- /dev/null
+++ b/libnm-gtk/nm-cdma-provider.c
@@ -0,0 +1,71 @@
+/* -*- 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 "nm-cdma-provider.h"
+#include "nm-cdma-item.h"
+#include "utils.h"
+
+G_DEFINE_TYPE (NMCdmaProvider, nm_cdma_provider, NM_TYPE_DEVICE_PROVIDER)
+
+NMItemProvider *
+nm_cdma_provider_new (NMClient *client,
+ NMCdmaDevice *device)
+{
+ g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (NM_IS_CDMA_DEVICE (device), NULL);
+
+ return (NMItemProvider *) g_object_new (NM_TYPE_CDMA_PROVIDER,
+ NM_ITEM_PROVIDER_CLIENT, client,
+ NM_DEVICE_PROVIDER_DEVICE, device,
+ NULL);
+}
+
+static void
+cdma_added (NMItemProvider *provider,
+ NMSettingsConnectionInterface *connection)
+{
+ NMDeviceProvider *device_provider = NM_DEVICE_PROVIDER (provider);
+ NMDevice *device;
+
+ if (!nm_device_provider_ready (device_provider))
+ return;
+
+ device = nm_device_provider_get_device (device_provider);
+ if (utils_connection_valid_for_device (NM_CONNECTION (connection), device, NULL)) {
+ NMListItem *item;
+
+ item = nm_cdma_item_new (nm_item_provider_get_client (provider), NM_CDMA_DEVICE (device), connection);
+ nm_item_provider_item_added (provider, item);
+ }
+}
+
+/*****************************************************************************/
+
+static void
+nm_cdma_provider_init (NMCdmaProvider *self)
+{
+}
+
+static void
+nm_cdma_provider_class_init (NMCdmaProviderClass *klass)
+{
+ NMItemProviderClass *item_class = NM_ITEM_PROVIDER_CLASS (klass);
+
+ item_class->connection_added = cdma_added;
+}
diff --git a/libnm-gtk/nm-cdma-provider.h b/libnm-gtk/nm-cdma-provider.h
new file mode 100644
index 0000000..57f9d81
--- /dev/null
+++ b/libnm-gtk/nm-cdma-provider.h
@@ -0,0 +1,51 @@
+/* -*- 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 NM_CDMA_PROVIDER_H
+#define NM_CDMA_PROVIDER_H
+
+#include <glib-object.h>
+#include <nm-cdma-device.h>
+#include <nm-device-provider.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_CDMA_PROVIDER (nm_cdma_provider_get_type ())
+#define NM_CDMA_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CDMA_PROVIDER, NMCdmaProvider))
+#define NM_CDMA_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CDMA_PROVIDER, NMCdmaProviderClass))
+#define NM_IS_CDMA_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CDMA_PROVIDER))
+#define NM_IS_CDMA_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_CDMA_PROVIDER))
+#define NM_CDMA_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CDMA_PROVIDER, NMCdmaProviderClass))
+
+typedef struct {
+ NMDeviceProvider parent;
+} NMCdmaProvider;
+
+typedef struct {
+ NMDeviceProviderClass parent_class;
+} NMCdmaProviderClass;
+
+GType nm_cdma_provider_get_type (void);
+
+NMItemProvider *nm_cdma_provider_new (NMClient *client,
+ NMCdmaDevice *device);
+
+G_END_DECLS
+
+#endif /* NM_CDMA_PROVIDER_H */
diff --git a/libnm-gtk/nm-connection-item.c b/libnm-gtk/nm-connection-item.c
new file mode 100644
index 0000000..8b55e19
--- /dev/null
+++ b/libnm-gtk/nm-connection-item.c
@@ -0,0 +1,371 @@
+/* -*- 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 <nm-setting-connection.h>
+#include <nm-settings-connection-interface.h>
+#include <nm-active-connection.h>
+#include "nm-connection-item.h"
+#include "gconf-helpers.h"
+
+G_DEFINE_TYPE (NMConnectionItem, nm_connection_item, NM_TYPE_LIST_ITEM)
+
+enum {
+ PROP_0,
+ PROP_CLIENT,
+ PROP_CONNECTION,
+
+ LAST_PROP
+};
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NM_TYPE_CONNECTION_ITEM, NMConnectionItemPrivate))
+
+typedef struct {
+ NMClient *client;
+ NMSettingsConnectionInterface *connection;
+ NMActiveConnection *ac;
+ gboolean connect_pending;
+
+ gulong removed_id;
+ gulong updated_id;
+ gulong acs_changed_id;
+ gulong ac_state_changed_id;
+
+ gboolean disposed;
+} NMConnectionItemPrivate;
+
+NMClient *
+nm_connection_item_get_client (NMConnectionItem *self)
+{
+ g_return_val_if_fail (NM_IS_CONNECTION_ITEM (self), NULL);
+
+ return GET_PRIVATE (self)->client;
+}
+
+NMSettingsConnectionInterface *
+nm_connection_item_get_connection (NMConnectionItem *self)
+{
+ g_return_val_if_fail (NM_IS_CONNECTION_ITEM (self), NULL);
+
+ return GET_PRIVATE (self)->connection;
+}
+
+static void
+connection_removed (NMSettingsConnectionInterface *connection,
+ gpointer data)
+{
+ g_debug ("Connection %p removed", connection);
+ nm_connection_item_set_connection (NM_CONNECTION_ITEM (data), NULL);
+}
+
+static void
+connection_updated (NMSettingsConnectionInterface *connection,
+ GHashTable *new_settings,
+ gpointer data)
+{
+ NMConnectionItem *self = NM_CONNECTION_ITEM (data);
+ NMSettingConnection *s_con;
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION);
+ g_object_set (self, NM_LIST_ITEM_NAME, nm_setting_connection_get_id (s_con), NULL);
+}
+
+static void
+ac_state_changed (NMActiveConnection *ac,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ NMListItem *item = NM_LIST_ITEM (user_data);
+ NMListItemStatus status;
+
+ if (ac) {
+ switch (nm_active_connection_get_state (ac)) {
+ case NM_ACTIVE_CONNECTION_STATE_ACTIVATED:
+ status = NM_LIST_ITEM_STATUS_CONNECTED;
+ break;
+ case NM_ACTIVE_CONNECTION_STATE_ACTIVATING:
+ status = NM_LIST_ITEM_STATUS_CONNECTING;
+ break;
+ default:
+ status = NM_LIST_ITEM_STATUS_DISCONNECTED;
+ break;
+ }
+ } else
+ status = NM_LIST_ITEM_STATUS_DISCONNECTED;
+
+ if (status != nm_list_item_get_status (item))
+ g_object_set (G_OBJECT (item), NM_LIST_ITEM_STATUS, status, NULL);
+}
+
+static void
+set_active_connection (NMConnectionItem *self,
+ NMActiveConnection *ac)
+{
+ NMConnectionItemPrivate *priv = GET_PRIVATE (self);
+
+ if (priv->ac) {
+ g_signal_handler_disconnect (priv->ac, priv->ac_state_changed_id);
+ g_object_unref (priv->ac);
+ }
+
+ if (ac) {
+ priv->ac = g_object_ref (ac);
+ priv->ac_state_changed_id = g_signal_connect (priv->ac, "notify::" NM_ACTIVE_CONNECTION_STATE,
+ G_CALLBACK (ac_state_changed), self);
+ } else {
+ priv->ac_state_changed_id = 0;
+ priv->ac = NULL;
+ }
+
+ ac_state_changed (ac, NULL, self);
+}
+
+static void
+active_connections_changed (NMClient *client,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ NMConnectionItem *self = NM_CONNECTION_ITEM (user_data);
+ NMConnectionItemPrivate *priv = GET_PRIVATE (self);
+ NMConnection *connection;
+ const GPtrArray *acs;
+ const char *path;
+ NMActiveConnection *ac = NULL;
+ NMConnectionScope scope;
+ int i;
+
+ if (!priv->connection)
+ return;
+
+ connection = NM_CONNECTION (nm_connection_item_get_connection (self));
+ path = nm_connection_get_path (connection);
+ scope = nm_connection_get_scope (connection);
+
+ acs = nm_client_get_active_connections (client);
+ for (i = 0; acs && i < acs->len; i++) {
+ ac = g_ptr_array_index (acs, i);
+
+ if (scope == nm_active_connection_get_scope (ac) && !strcmp (path, nm_active_connection_get_connection (ac)))
+ break;
+
+ ac = NULL;
+ }
+
+ set_active_connection (self, ac);
+}
+
+static gboolean
+idle_connect (gpointer data)
+{
+ nm_list_item_connect (NM_LIST_ITEM (data));
+
+ return FALSE;
+}
+
+void
+nm_connection_item_set_connection (NMConnectionItem *self,
+ NMSettingsConnectionInterface *connection)
+{
+ NMConnectionItemPrivate *priv;
+
+ g_return_if_fail (NM_IS_CONNECTION_ITEM (self));
+
+ priv = GET_PRIVATE (self);
+
+ if (priv->connection) {
+ set_active_connection (self, NULL);
+ g_signal_handler_disconnect (priv->connection, priv->removed_id);
+ g_signal_handler_disconnect (priv->connection, priv->updated_id);
+ g_signal_handler_disconnect (priv->client, priv->acs_changed_id);
+ g_object_unref (priv->connection);
+ }
+
+ if (connection) {
+ priv->connection = g_object_ref (connection);
+
+ priv->removed_id = g_signal_connect (connection, "removed", G_CALLBACK (connection_removed), self);
+ priv->updated_id = g_signal_connect (connection, "updated", G_CALLBACK (connection_updated), self);
+ connection_updated (connection, NULL, self);
+
+ priv->acs_changed_id = g_signal_connect (priv->client, "notify::" NM_CLIENT_ACTIVE_CONNECTIONS,
+ G_CALLBACK (active_connections_changed), self);
+ active_connections_changed (priv->client, NULL, self);
+ } else {
+ priv->updated_id = 0;
+ priv->acs_changed_id = 0;
+ priv->connection = NULL;
+ }
+
+ g_object_notify (G_OBJECT (self), NM_CONNECTION_ITEM_CONNECTION);
+ g_object_set (G_OBJECT (self), NM_LIST_ITEM_SHOW_DELETE, connection != NULL, NULL);
+
+ if (priv->connect_pending) {
+ priv->connect_pending = FALSE;
+
+ if (connection)
+ idle_connect (self);
+ }
+}
+
+void
+nm_connection_item_new_connection (NMConnectionItem *self,
+ NMConnection *connection,
+ gboolean connect)
+{
+ g_return_if_fail (NM_IS_CONNECTION_ITEM (self));
+ g_return_if_fail (NM_IS_CONNECTION (connection));
+
+ if (connect)
+ GET_PRIVATE (self)->connect_pending = TRUE;
+
+ nm_gconf_write_connection (connection, NULL, NULL);
+}
+
+static void
+delete_cb (NMSettingsConnectionInterface *connection,
+ GError *error,
+ gpointer user_data)
+{
+ if (error)
+ g_warning ("Could not delete connection: %s", error->message);
+}
+
+static void
+do_delete (NMListItem *item)
+{
+ NMConnectionItemPrivate *priv = GET_PRIVATE (item);
+
+ if (priv->connection)
+ nm_settings_connection_interface_delete (priv->connection, delete_cb, item);
+}
+
+static int
+priority (NMListItem *item)
+{
+ NMConnectionItemPrivate *priv = GET_PRIVATE (item);
+ int priority = 0;
+
+ if (priv->ac && nm_active_connection_get_state (priv->ac) == NM_ACTIVE_CONNECTION_STATE_ACTIVATED) {
+ if (nm_active_connection_get_default (priv->ac))
+ priority += NM_LIST_ITEM_PRIORITY_DEFAULT_ROUTE;
+
+ priority += NM_LIST_ITEM_PRIORITY_ACTIVATED;
+ }
+
+ if (priv->connection)
+ priority += NM_LIST_ITEM_PRIORITY_CONFIGURED;
+
+ priority += NM_LIST_ITEM_CLASS (nm_connection_item_parent_class)->priority (item);
+
+ return priority;
+}
+
+/*****************************************************************************/
+
+static void
+nm_connection_item_init (NMConnectionItem *self)
+{
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMConnectionItemPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_CLIENT:
+ /* Construct only */
+ priv->client = g_value_dup_object (value);
+ break;
+ case PROP_CONNECTION:
+ nm_connection_item_set_connection (NM_CONNECTION_ITEM (object), g_value_get_object (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)
+{
+ NMConnectionItem *self = NM_CONNECTION_ITEM (object);
+
+ switch (prop_id) {
+ case PROP_CLIENT:
+ g_value_set_object (value, GET_PRIVATE (self)->client);
+ break;
+ case PROP_CONNECTION:
+ g_value_set_object (value, nm_connection_item_get_connection (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ NMConnectionItem *self = NM_CONNECTION_ITEM (object);
+ NMConnectionItemPrivate *priv = GET_PRIVATE (self);
+
+ if (!priv->disposed) {
+ nm_connection_item_set_connection (self, NULL);
+ g_object_unref (priv->client);
+ priv->disposed = TRUE;
+ }
+
+ G_OBJECT_CLASS (nm_connection_item_parent_class)->dispose (object);
+}
+
+static void
+nm_connection_item_class_init (NMConnectionItemClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMListItemClass *list_class = NM_LIST_ITEM_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (NMConnectionItemPrivate));
+
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+
+ list_class->delete = do_delete;
+ list_class->priority = priority;
+
+ /* Properties */
+ g_object_class_install_property
+ (object_class, PROP_CLIENT,
+ g_param_spec_object (NM_CONNECTION_ITEM_CLIENT,
+ "NMClient",
+ "NMClient",
+ NM_TYPE_CLIENT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property
+ (object_class, PROP_CONNECTION,
+ g_param_spec_object (NM_CONNECTION_ITEM_CONNECTION,
+ "Connection",
+ "Connection",
+ NM_TYPE_SETTINGS_CONNECTION_INTERFACE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
diff --git a/libnm-gtk/nm-connection-item.h b/libnm-gtk/nm-connection-item.h
new file mode 100644
index 0000000..d9fc599
--- /dev/null
+++ b/libnm-gtk/nm-connection-item.h
@@ -0,0 +1,61 @@
+/* -*- 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 NM_CONNECTION_ITEM_H
+#define NM_CONNECTION_ITEM_H
+
+#include <glib-object.h>
+#include <nm-client.h>
+#include <nm-settings-connection-interface.h>
+#include <nm-list-item.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_CONNECTION_ITEM (nm_connection_item_get_type ())
+#define NM_CONNECTION_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONNECTION_ITEM, NMConnectionItem))
+#define NM_CONNECTION_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CONNECTION_ITEM, NMConnectionItemClass))
+#define NM_IS_CONNECTION_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CONNECTION_ITEM))
+#define NM_IS_CONNECTION_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_CONNECTION_ITEM))
+#define NM_CONNECTION_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CONNECTION_ITEM, NMConnectionItemClass))
+
+#define NM_CONNECTION_ITEM_CLIENT "client"
+#define NM_CONNECTION_ITEM_CONNECTION "connection"
+
+typedef struct {
+ NMListItem parent;
+} NMConnectionItem;
+
+typedef struct {
+ NMListItemClass parent_class;
+} NMConnectionItemClass;
+
+GType nm_connection_item_get_type (void);
+
+NMClient *nm_connection_item_get_client (NMConnectionItem *self);
+NMSettingsConnectionInterface *nm_connection_item_get_connection (NMConnectionItem *self);
+void nm_connection_item_set_connection (NMConnectionItem *self,
+ NMSettingsConnectionInterface *connection);
+
+void nm_connection_item_new_connection (NMConnectionItem *self,
+ NMConnection *connection,
+ gboolean connect);
+
+G_END_DECLS
+
+#endif /* NM_CONNECTION_ITEM_H */
diff --git a/libnm-gtk/nm-connection-list.c b/libnm-gtk/nm-connection-list.c
new file mode 100644
index 0000000..29065d1
--- /dev/null
+++ b/libnm-gtk/nm-connection-list.c
@@ -0,0 +1,276 @@
+/* -*- 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 "nm-connection-list.h"
+
+G_DEFINE_TYPE (NMConnectionList, nm_connection_list, GTK_TYPE_LIST_STORE)
+
+enum {
+ PROP_0,
+ PROP_CLIENT,
+
+ LAST_PROP
+};
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NM_TYPE_CONNECTION_LIST, NMConnectionListPrivate))
+
+typedef struct {
+ NMClient *client;
+ GSList *settings;
+
+ gboolean disposed;
+} NMConnectionListPrivate;
+
+GtkTreeModel *
+nm_connection_list_new (NMClient *client)
+{
+ g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
+
+ return (GtkTreeModel *) g_object_new (NM_TYPE_CONNECTION_LIST,
+ NM_CONNECTION_LIST_CLIENT, client,
+ NULL);
+}
+
+/* Connection handling */
+
+static void
+connection_updated (NMSettingsConnectionInterface *connection,
+ GHashTable *new_settings,
+ gpointer data)
+{
+ g_debug ("Connection %p updated", connection);
+}
+
+static void
+connection_removed (NMSettingsConnectionInterface *connection,
+ gpointer data)
+{
+ g_debug ("Connection %p removed", connection);
+ g_signal_handlers_disconnect_matched (connection, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, data);
+}
+
+static void
+connection_added (NMSettingsInterface *settings,
+ NMSettingsConnectionInterface *connection,
+ gpointer data)
+{
+ g_debug ("Connection %p added", connection);
+
+ g_signal_connect (connection, "updated", G_CALLBACK (connection_updated), data);
+ g_signal_connect (connection, "removed", G_CALLBACK (connection_removed), data);
+}
+
+static void
+connection_handling_cleanup (NMConnectionList *self)
+{
+ NMConnectionListPrivate *priv = GET_PRIVATE (self);
+ GSList *iter;
+
+ g_debug ("Cleaning up settings");
+
+ for (iter = priv->settings; iter; iter = iter->next) {
+ NMSettingsInterface *settings = NM_SETTINGS_INTERFACE (iter->data);
+ GSList *connections;
+ GSList *connection_iter;
+
+ connections = nm_settings_interface_list_connections (settings);
+ for (connection_iter = connections; connection_iter; connection_iter = connection_iter->next)
+ connection_removed (NM_SETTINGS_CONNECTION_INTERFACE (connection_iter->data), self);
+
+ g_slist_free (connections);
+
+ g_signal_handlers_disconnect_matched (settings, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, self);
+ g_object_unref (settings);
+ }
+
+ g_slist_free (priv->settings);
+}
+
+/* Device handling */
+
+static void
+device_state_changed (NMDevice *device,
+ NMDeviceState new_state,
+ NMDeviceState old_state,
+ NMDeviceStateReason reason)
+{
+ g_debug ("device state %s changed (%d)", nm_device_get_iface (device), new_state);
+}
+
+static void
+device_added (NMClient *client,
+ NMDevice *device,
+ gpointer user_data)
+{
+ g_debug ("device %s added", nm_device_get_iface (device));
+
+ g_signal_connect (device, "state-changed", G_CALLBACK (device_state_changed), user_data);
+}
+
+static void
+device_removed (NMClient *client,
+ NMDevice *device,
+ gpointer user_data)
+{
+ g_debug ("device %s removed", nm_device_get_iface (device));
+
+ g_signal_handlers_disconnect_matched (device, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, user_data);
+}
+
+static void
+device_handling_setup (NMConnectionList *self)
+{
+ NMConnectionListPrivate *priv = GET_PRIVATE (self);
+ const GPtrArray *devices;
+ int i;
+
+ g_signal_connect (priv->client, "device-added", G_CALLBACK (device_added), self);
+ g_signal_connect (priv->client, "device-removed", G_CALLBACK (device_removed), self);
+
+ devices = nm_client_get_devices (priv->client);
+ for (i = 0; devices && devices->len > i; i++)
+ device_added (priv->client, NM_DEVICE (g_ptr_array_index (devices, i)), self);
+}
+
+static void
+device_handling_cleanup (NMConnectionList *self)
+{
+ NMConnectionListPrivate *priv = GET_PRIVATE (self);
+ const GPtrArray *devices;
+ int i;
+
+ g_debug ("Cleaning up devices");
+
+ g_signal_handlers_disconnect_matched (priv->client, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, self);
+
+ devices = nm_client_get_devices (priv->client);
+ for (i = 0; devices && devices->len > i; i++)
+ device_removed (priv->client, NM_DEVICE (g_ptr_array_index (devices, i)), self);
+}
+
+void
+nm_connection_list_add_settings (NMConnectionList *self,
+ NMSettingsInterface *settings)
+{
+ NMConnectionListPrivate *priv;
+ GSList *connections;
+ GSList *iter;
+
+ g_return_if_fail (NM_IS_CONNECTION_LIST (self));
+ g_return_if_fail (NM_IS_SETTINGS_INTERFACE (settings));
+
+ priv = GET_PRIVATE (self);
+
+ if (priv->settings == NULL)
+ /* First setting, set up device handling */
+ device_handling_setup (self);
+
+ priv->settings = g_slist_prepend (priv->settings, g_object_ref (settings));
+ g_signal_connect (settings, "new-connection", G_CALLBACK (connection_added), self);
+
+ connections = nm_settings_interface_list_connections (settings);
+ for (iter = connections; iter; iter = iter->next)
+ connection_added (settings, NM_SETTINGS_CONNECTION_INTERFACE (iter->data), self);
+
+ g_slist_free (connections);
+}
+
+/*****************************************************************************/
+
+static void
+nm_connection_list_init (NMConnectionList *self)
+{
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMConnectionListPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_CLIENT:
+ /* Construct only */
+ priv->client = g_value_dup_object (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)
+{
+ NMConnectionListPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_CLIENT:
+ g_value_set_object (value, priv->client);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ NMConnectionList *self = NM_CONNECTION_LIST (object);
+ NMConnectionListPrivate *priv = GET_PRIVATE (self);
+
+ if (!priv->disposed) {
+ connection_handling_cleanup (self);
+ device_handling_cleanup (self);
+
+ if (priv->client)
+ g_object_unref (priv->client);
+
+ priv->disposed = TRUE;
+ }
+
+ G_OBJECT_CLASS (nm_connection_list_parent_class)->dispose (object);
+}
+
+static void
+nm_connection_list_class_init (NMConnectionListClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (NMConnectionListPrivate));
+
+ 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_CLIENT,
+ g_param_spec_object (NM_CONNECTION_LIST_CLIENT,
+ "NMClient",
+ "NMClient",
+ NM_TYPE_CLIENT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
diff --git a/libnm-gtk/nm-connection-list.h b/libnm-gtk/nm-connection-list.h
new file mode 100644
index 0000000..175d6d8
--- /dev/null
+++ b/libnm-gtk/nm-connection-list.h
@@ -0,0 +1,54 @@
+/* -*- 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 NM_CONNECTION_LIST_H
+#define NM_CONNECTION_LIST_H
+
+#include <gtk/gtk.h>
+#include <nm-client.h>
+#include <nm-settings-interface.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_CONNECTION_LIST (nm_connection_list_get_type ())
+#define NM_CONNECTION_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONNECTION_LIST, NMConnectionList))
+#define NM_CONNECTION_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CONNECTION_LIST, NMConnectionListClass))
+#define NM_IS_CONNECTION_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CONNECTION_LIST))
+#define NM_IS_CONNECTION_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_CONNECTION_LIST))
+#define NM_CONNECTION_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CONNECTION_LIST, NMConnectionListClass))
+
+#define NM_CONNECTION_LIST_CLIENT "client"
+
+typedef struct {
+ GtkListStore parent;
+} NMConnectionList;
+
+typedef struct {
+ GtkListStoreClass parent_class;
+} NMConnectionListClass;
+
+GType nm_connection_list_get_type (void);
+
+GtkTreeModel *nm_connection_list_new (NMClient *client);
+void nm_connection_list_add_settings (NMConnectionList *self,
+ NMSettingsInterface *settings);
+
+G_END_DECLS
+
+#endif /* NM_CONNECTION_LIST_H */
diff --git a/libnm-gtk/nm-connection-model.c b/libnm-gtk/nm-connection-model.c
new file mode 100644
index 0000000..e84e17c
--- /dev/null
+++ b/libnm-gtk/nm-connection-model.c
@@ -0,0 +1,203 @@
+/* -*- 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 <nm-setting-connection.h>
+#include "nm-connection-model.h"
+
+G_DEFINE_TYPE (NMConnectionModel, nm_connection_model, GTK_TYPE_LIST_STORE)
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NM_TYPE_CONNECTION_MODEL, NMConnectionModelPrivate))
+
+typedef struct {
+ GSList *settings;
+
+ gboolean disposed;
+} NMConnectionModelPrivate;
+
+static GQuark quark_item_iter = 0;
+
+GtkTreeModel *
+nm_connection_model_new (void)
+{
+ return (GtkTreeModel *) g_object_new (NM_TYPE_CONNECTION_MODEL, NULL);
+}
+
+static void
+update_iter (GtkListStore *store,
+ GtkTreeIter *iter,
+ NMSettingsConnectionInterface *connection)
+{
+ NMSettingConnection *s_con;
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection),
+ NM_TYPE_SETTING_CONNECTION);
+ g_return_if_fail (s_con != NULL);
+
+ gtk_list_store_set (store, iter,
+ NM_CONNECTION_MODEL_COL_CONNECTION, connection,
+ NM_CONNECTION_MODEL_COL_NAME, nm_setting_connection_get_id (s_con),
+ NM_CONNECTION_MODEL_COL_TYPE, nm_setting_connection_get_connection_type (s_con),
+ -1);
+}
+
+static void
+connection_updated (NMSettingsConnectionInterface *connection,
+ GHashTable *new_settings,
+ gpointer user_data)
+{
+ GtkTreeIter *iter;
+
+ iter = (GtkTreeIter *) g_object_get_qdata (G_OBJECT (connection), quark_item_iter);
+ if (iter)
+ update_iter (GTK_LIST_STORE (user_data), iter, connection);
+}
+
+static void
+connection_removed (NMSettingsConnectionInterface *connection,
+ gpointer user_data)
+{
+ GtkListStore *store = GTK_LIST_STORE (user_data);
+ GtkTreeIter *iter;
+
+ g_signal_handlers_disconnect_by_func (connection, connection_updated, user_data);
+ g_signal_handlers_disconnect_by_func (connection, connection_removed, user_data);
+
+ iter = (GtkTreeIter *) g_object_get_qdata (G_OBJECT (connection), quark_item_iter);
+ if (iter) {
+ gtk_list_store_remove (store, iter);
+ g_object_set_qdata (G_OBJECT (connection), quark_item_iter, NULL);
+ }
+}
+
+static void
+connection_added (NMSettingsInterface *settings,
+ NMSettingsConnectionInterface *connection,
+ gpointer user_data)
+{
+ GtkListStore *store = GTK_LIST_STORE (user_data);
+ GtkTreeIter *iter;
+
+ iter = g_slice_new0 (GtkTreeIter);
+
+ gtk_list_store_append (store, iter);
+ update_iter (store, iter, connection);
+
+ g_object_set_qdata_full (G_OBJECT (connection), quark_item_iter, iter, (GDestroyNotify) gtk_tree_iter_free);
+ g_signal_connect (connection, "updated", G_CALLBACK (connection_updated), user_data);
+ g_signal_connect (connection, "removed", G_CALLBACK (connection_removed), user_data);
+}
+
+void
+nm_connection_model_add_settings (NMConnectionModel *self,
+ NMSettingsInterface *settings)
+{
+ NMConnectionModelPrivate *priv;
+ GSList *items;
+ GSList *iter;
+
+ g_return_if_fail (NM_IS_CONNECTION_MODEL (self));
+ g_return_if_fail (NM_IS_SETTINGS_INTERFACE (settings));
+
+ priv = GET_PRIVATE (self);
+ priv->settings = g_slist_append (priv->settings, g_object_ref (settings));
+ g_signal_connect (settings, "new-connection", G_CALLBACK (connection_added), self);
+
+ items = nm_settings_interface_list_connections (settings);
+ for (iter = items; iter; iter = iter->next)
+ connection_added (settings, NM_SETTINGS_CONNECTION_INTERFACE (iter->data), self);
+
+ g_slist_free (items);
+}
+
+#if 0
+static int
+sort_callback (GtkTreeModel *model,
+ GtkTreeIter *a,
+ GtkTreeIter *b,
+ gpointer user_data)
+{
+ GValue value_a = {0, };
+ GValue value_b = {0, };
+ int result;
+
+ gtk_tree_model_get_value (model, a, NM_CONNECTION_MODEL_COL_ITEM, &value_a);
+ gtk_tree_model_get_value (model, b, NM_CONNECTION_MODEL_COL_ITEM, &value_b);
+
+ result = nm_list_item_compare (NM_LIST_ITEM (g_value_get_object (&value_a)),
+ NM_LIST_ITEM (g_value_get_object (&value_b)));
+
+ g_value_unset (&value_a);
+ g_value_unset (&value_b);
+
+ return result;
+}
+#endif
+
+/*****************************************************************************/
+
+static void
+nm_connection_model_init (NMConnectionModel *self)
+{
+ GType types[NM_CONNECTION_MODEL_N_COLUMNS];
+
+ types[NM_CONNECTION_MODEL_COL_CONNECTION] = NM_TYPE_SETTINGS_CONNECTION_INTERFACE;
+ types[NM_CONNECTION_MODEL_COL_NAME] = G_TYPE_STRING;
+ types[NM_CONNECTION_MODEL_COL_TYPE] = G_TYPE_STRING;
+
+ gtk_list_store_set_column_types (GTK_LIST_STORE (self), NM_CONNECTION_MODEL_N_COLUMNS, types);
+
+#if 0
+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (self),
+ NM_CONNECTION_MODEL_COL_ITEM,
+ sort_callback,
+ NULL,
+ NULL);
+
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (self), NM_CONNECTION_MODEL_COL_ITEM, GTK_SORT_ASCENDING);
+#endif
+}
+
+static void
+dispose (GObject *object)
+{
+ NMConnectionModelPrivate *priv = GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ if (priv->settings) {
+ g_slist_foreach (priv->settings, (GFunc) g_object_unref, NULL);
+ g_slist_free (priv->settings);
+ }
+
+ priv->disposed = TRUE;
+ }
+
+ G_OBJECT_CLASS (nm_connection_model_parent_class)->dispose (object);
+}
+
+static void
+nm_connection_model_class_init (NMConnectionModelClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ quark_item_iter = g_quark_from_static_string ("NMConnectionModel-item-iter");
+
+ g_type_class_add_private (object_class, sizeof (NMConnectionModelPrivate));
+
+ object_class->dispose = dispose;
+}
diff --git a/libnm-gtk/nm-connection-model.h b/libnm-gtk/nm-connection-model.h
new file mode 100644
index 0000000..5d3b7a8
--- /dev/null
+++ b/libnm-gtk/nm-connection-model.h
@@ -0,0 +1,60 @@
+/* -*- 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 NM_CONNECTION_MODEL_H
+#define NM_CONNECTION_MODEL_H
+
+#include <gtk/gtk.h>
+#include <nm-settings-interface.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_CONNECTION_MODEL (nm_connection_model_get_type ())
+#define NM_CONNECTION_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CONNECTION_MODEL, NMConnectionModel))
+#define NM_CONNECTION_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_CONNECTION_MODEL, NMConnectionModelClass))
+#define NM_IS_CONNECTION_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_CONNECTION_MODEL))
+#define NM_IS_CONNECTION_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_CONNECTION_MODEL))
+#define NM_CONNECTION_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_CONNECTION_MODEL, NMConnectionModelClass))
+
+enum {
+ NM_CONNECTION_MODEL_COL_CONNECTION,
+ NM_CONNECTION_MODEL_COL_NAME,
+ NM_CONNECTION_MODEL_COL_TYPE,
+
+ NM_CONNECTION_MODEL_N_COLUMNS
+};
+
+typedef struct {
+ GtkListStore parent;
+} NMConnectionModel;
+
+typedef struct {
+ GtkListStoreClass parent_class;
+} NMConnectionModelClass;
+
+GType nm_connection_model_get_type (void);
+
+GtkTreeModel *nm_connection_model_new (void);
+void nm_connection_model_add_settings (NMConnectionModel *self,
+ NMSettingsInterface *settings);
+
+
+G_END_DECLS
+
+#endif /* NM_CONNECTION_MODEL_H */
diff --git a/libnm-gtk/nm-device-handler.c b/libnm-gtk/nm-device-handler.c
new file mode 100644
index 0000000..167b9fc
--- /dev/null
+++ b/libnm-gtk/nm-device-handler.c
@@ -0,0 +1,263 @@
+/* -*- 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 <nm-device-ethernet.h>
+#include <nm-device-wifi.h>
+#include <nm-gsm-device.h>
+#include <nm-cdma-device.h>
+
+#include "nm-device-handler.h"
+#include "nm-ethernet-provider.h"
+#include "nm-wifi-provider.h"
+#include "nm-gsm-provider.h"
+#include "nm-cdma-provider.h"
+
+G_DEFINE_TYPE (NMDeviceHandler, nm_device_handler, G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_CLIENT,
+
+ LAST_PROP
+};
+
+enum {
+ PROVIDER_ADDED,
+ PROVIDER_REMOVED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NM_TYPE_DEVICE_HANDLER, NMDeviceHandlerPrivate))
+
+typedef struct {
+ NMClient *client;
+ GSList *providers;
+
+ gboolean disposed;
+} NMDeviceHandlerPrivate;
+
+
+NMDeviceHandler *
+nm_device_handler_new (NMClient *client)
+{
+ g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
+
+ return (NMDeviceHandler *) g_object_new (NM_TYPE_DEVICE_HANDLER,
+ NM_DEVICE_HANDLER_CLIENT, client,
+ NULL);
+}
+
+GSList *
+nm_device_handler_get_providers (NMDeviceHandler *self)
+{
+ g_return_val_if_fail (NM_IS_DEVICE_HANDLER (self), NULL);
+
+ return GET_PRIVATE (self)->providers;
+}
+
+static NMItemProvider *
+create_provider (NMDeviceHandler *self, NMDevice *device)
+{
+ NMDeviceHandlerPrivate *priv = GET_PRIVATE (self);
+ NMItemProvider *provider;
+ GType type;
+
+ type = G_OBJECT_TYPE (device);
+
+ if (type == NM_TYPE_DEVICE_ETHERNET)
+ provider = nm_ethernet_provider_new (priv->client, NM_DEVICE_ETHERNET (device));
+ else if (type == NM_TYPE_DEVICE_WIFI)
+ provider = nm_wifi_provider_new (priv->client, NM_DEVICE_WIFI (device));
+ else if (type == NM_TYPE_GSM_DEVICE)
+ provider = nm_gsm_provider_new (priv->client, NM_GSM_DEVICE (device));
+ else if (type == NM_TYPE_CDMA_DEVICE)
+ provider = nm_cdma_provider_new (priv->client, NM_CDMA_DEVICE (device));
+ else {
+ g_warning ("Unknown device type %s", G_OBJECT_TYPE_NAME (device));
+ provider = NULL;
+ }
+
+ return provider;
+}
+
+static void
+device_added (NMClient *client,
+ NMDevice *device,
+ gpointer user_data)
+{
+ NMDeviceHandler *self = NM_DEVICE_HANDLER (user_data);
+ NMDeviceHandlerPrivate *priv = GET_PRIVATE (self);
+ NMItemProvider *provider;
+
+ g_debug ("device %s added", nm_device_get_iface (device));
+
+ provider = create_provider (self, device);
+ if (provider) {
+ priv->providers = g_slist_prepend (priv->providers, provider);
+ g_signal_emit (self, signals[PROVIDER_ADDED], 0, provider);
+ }
+}
+
+static void
+device_removed (NMClient *client,
+ NMDevice *device,
+ gpointer user_data)
+{
+ NMDeviceHandler *self = NM_DEVICE_HANDLER (user_data);
+ NMDeviceHandlerPrivate *priv = GET_PRIVATE (self);
+ GSList *iter;
+
+ g_debug ("device %s removed", nm_device_get_iface (device));
+
+ for (iter = priv->providers; iter; iter = iter->next) {
+ NMDeviceProvider *provider = (NMDeviceProvider *) iter->data;
+
+ if (nm_device_provider_get_device (provider) == device) {
+ priv->providers = g_slist_delete_link (priv->providers, iter);
+ g_signal_emit (self, signals[PROVIDER_REMOVED], 0, provider);
+ g_object_unref (provider);
+ break;
+ }
+ }
+}
+
+/*****************************************************************************/
+
+static void
+nm_device_handler_init (NMDeviceHandler *self)
+{
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMDeviceHandlerPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_CLIENT:
+ /* Construct only */
+ priv->client = g_value_dup_object (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)
+{
+ NMDeviceHandlerPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_CLIENT:
+ g_value_set_object (value, priv->client);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+constructed (GObject *object)
+{
+ NMDeviceHandlerPrivate *priv = GET_PRIVATE (object);
+ const GPtrArray *devices;
+ int i;
+
+ if (G_OBJECT_CLASS (nm_device_handler_parent_class)->constructed)
+ G_OBJECT_CLASS (nm_device_handler_parent_class)->constructed (object);
+
+ g_signal_connect (priv->client, "device-added", G_CALLBACK (device_added), object);
+ g_signal_connect (priv->client, "device-removed", G_CALLBACK (device_removed), object);
+
+ devices = nm_client_get_devices (priv->client);
+ for (i = 0; devices && devices->len > i; i++)
+ device_added (priv->client, NM_DEVICE (g_ptr_array_index (devices, i)), object);
+}
+
+static void
+dispose (GObject *object)
+{
+ NMDeviceHandlerPrivate *priv = GET_PRIVATE (object);
+ const GPtrArray *devices;
+ int i;
+
+ if (!priv->disposed) {
+ g_signal_handlers_disconnect_matched (priv->client, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
+
+ devices = nm_client_get_devices (priv->client);
+ for (i = 0; devices && devices->len > i; i++)
+ device_removed (priv->client, NM_DEVICE (g_ptr_array_index (devices, i)), object);
+
+ priv->disposed = TRUE;
+ }
+
+ G_OBJECT_CLASS (nm_device_handler_parent_class)->dispose (object);
+}
+
+static void
+nm_device_handler_class_init (NMDeviceHandlerClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (NMDeviceHandlerPrivate));
+
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->constructed = constructed;
+ object_class->dispose = dispose;
+
+ /* Properties */
+ g_object_class_install_property
+ (object_class, PROP_CLIENT,
+ g_param_spec_object (NM_DEVICE_HANDLER_CLIENT,
+ "NMClient",
+ "NMClient",
+ NM_TYPE_CLIENT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ /* Signals */
+ signals[PROVIDER_ADDED] =
+ g_signal_new ("provider-added",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMDeviceHandlerClass, provider_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ NM_TYPE_ITEM_PROVIDER);
+
+ signals[PROVIDER_REMOVED] =
+ g_signal_new ("provider-removed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMDeviceHandlerClass, provider_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ NM_TYPE_ITEM_PROVIDER);
+}
diff --git a/libnm-gtk/nm-device-handler.h b/libnm-gtk/nm-device-handler.h
new file mode 100644
index 0000000..e33a98d
--- /dev/null
+++ b/libnm-gtk/nm-device-handler.h
@@ -0,0 +1,60 @@
+/* -*- 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 NM_DEVICE_HANDLER_H
+#define NM_DEVICE_HANDLER_H
+
+#include <glib-object.h>
+#include <nm-client.h>
+#include <nm-item-provider.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_DEVICE_HANDLER (nm_device_handler_get_type ())
+#define NM_DEVICE_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_HANDLER, NMDeviceHandler))
+#define NM_DEVICE_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_HANDLER, NMDeviceHandlerClass))
+#define NM_IS_DEVICE_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_HANDLER))
+#define NM_IS_DEVICE_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DEVICE_HANDLER))
+#define NM_DEVICE_HANDLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_HANDLER, NMDeviceHandlerClass))
+
+#define NM_DEVICE_HANDLER_CLIENT "client"
+
+typedef struct {
+ GObject parent;
+} NMDeviceHandler;
+
+typedef struct {
+ GObjectClass parent_class;
+
+ /* Signals */
+ void (*provider_added) (NMDeviceHandler *self,
+ NMItemProvider *provider);
+
+ void (*provider_removed) (NMDeviceHandler *self,
+ NMItemProvider *provider);
+} NMDeviceHandlerClass;
+
+GType nm_device_handler_get_type (void);
+
+NMDeviceHandler *nm_device_handler_new (NMClient *client);
+GSList *nm_device_handler_get_providers (NMDeviceHandler *self);
+
+G_END_DECLS
+
+#endif /* NM_DEVICE_HANDLER_H */
diff --git a/libnm-gtk/nm-device-item.c b/libnm-gtk/nm-device-item.c
new file mode 100644
index 0000000..dc134bb
--- /dev/null
+++ b/libnm-gtk/nm-device-item.c
@@ -0,0 +1,176 @@
+/* -*- 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 "nm-device-item.h"
+
+G_DEFINE_ABSTRACT_TYPE (NMDeviceItem, nm_device_item, NM_TYPE_CONNECTION_ITEM)
+
+enum {
+ PROP_0,
+ PROP_DEVICE,
+
+ LAST_PROP
+};
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NM_TYPE_DEVICE_ITEM, NMDeviceItemPrivate))
+
+typedef struct {
+ NMDevice *device;
+
+ gboolean disposed;
+} NMDeviceItemPrivate;
+
+NMDevice *
+nm_device_item_get_device (NMDeviceItem *self)
+{
+ g_return_val_if_fail (NM_IS_DEVICE_ITEM (self), NULL);
+
+ return GET_PRIVATE (self)->device;
+}
+
+static void
+connect_cb (gpointer user_data, const char *object_path, GError *error)
+{
+ if (error)
+ g_warning ("Could not activate device: %s", error->message);
+}
+
+static void
+connect (NMListItem *item)
+{
+ NMDeviceItem *self = NM_DEVICE_ITEM (item);
+ NMConnectionItem *connection_item = NM_CONNECTION_ITEM (self);
+ NMConnection *connection;
+ const char *path;
+ const char *service_name;
+ char *specific_object;
+ NMConnectionScope scope;
+
+ connection = NM_CONNECTION (nm_connection_item_get_connection (connection_item));
+ path = nm_connection_get_path (connection);
+
+ scope = nm_connection_get_scope (connection);
+ service_name = (scope == NM_CONNECTION_SCOPE_USER) ?
+ NM_DBUS_SERVICE_USER_SETTINGS : NM_DBUS_SERVICE_SYSTEM_SETTINGS;
+
+ if (NM_DEVICE_ITEM_GET_CLASS (item)->get_specific_object)
+ specific_object = NM_DEVICE_ITEM_GET_CLASS (item)->get_specific_object (self);
+ else
+ specific_object = g_strdup ("/");
+
+ nm_client_activate_connection (nm_connection_item_get_client (connection_item),
+ service_name, path,
+ nm_device_item_get_device (self),
+ specific_object,
+ connect_cb,
+ item);
+
+ g_free (specific_object);
+}
+
+static void
+disconnect_cb (NMDevice *device, GError *error, gpointer user_data)
+{
+ if (error)
+ g_warning ("Could not deactivate device: %s", error->message);
+}
+
+static void
+disconnect (NMListItem *item)
+{
+ nm_device_disconnect (nm_device_item_get_device (NM_DEVICE_ITEM (item)), disconnect_cb, item);
+}
+
+/*****************************************************************************/
+
+static void
+nm_device_item_init (NMDeviceItem *self)
+{
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMDeviceItemPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_DEVICE:
+ /* Construct only */
+ priv->device = g_value_dup_object (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)
+{
+ NMDeviceItemPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_DEVICE:
+ g_value_set_object (value, priv->device);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ NMDeviceItemPrivate *priv = GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ g_object_unref (priv->device);
+ priv->disposed = TRUE;
+ }
+
+ G_OBJECT_CLASS (nm_device_item_parent_class)->dispose (object);
+}
+
+static void
+nm_device_item_class_init (NMDeviceItemClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMListItemClass *list_class = NM_LIST_ITEM_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (NMDeviceItemPrivate));
+
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+
+ list_class->connect = connect;
+ list_class->disconnect = disconnect;
+
+ /* Properties */
+ g_object_class_install_property
+ (object_class, PROP_DEVICE,
+ g_param_spec_object (NM_DEVICE_ITEM_DEVICE,
+ "Device",
+ "Device",
+ NM_TYPE_DEVICE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
diff --git a/libnm-gtk/nm-device-item.h b/libnm-gtk/nm-device-item.h
new file mode 100644
index 0000000..be94b94
--- /dev/null
+++ b/libnm-gtk/nm-device-item.h
@@ -0,0 +1,55 @@
+/* -*- 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 NM_DEVICE_ITEM_H
+#define NM_DEVICE_ITEM_H
+
+#include <glib-object.h>
+#include <nm-device.h>
+#include <nm-connection-item.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_DEVICE_ITEM (nm_device_item_get_type ())
+#define NM_DEVICE_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_ITEM, NMDeviceItem))
+#define NM_DEVICE_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_ITEM, NMDeviceItemClass))
+#define NM_IS_DEVICE_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_ITEM))
+#define NM_IS_DEVICE_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DEVICE_ITEM))
+#define NM_DEVICE_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_ITEM, NMDeviceItemClass))
+
+#define NM_DEVICE_ITEM_DEVICE "device"
+
+typedef struct {
+ NMConnectionItem parent;
+} NMDeviceItem;
+
+typedef struct {
+ NMConnectionItemClass parent_class;
+
+ /* Methods */
+ char *(*get_specific_object) (NMDeviceItem *self);
+} NMDeviceItemClass;
+
+GType nm_device_item_get_type (void);
+
+NMDevice *nm_device_item_get_device (NMDeviceItem *self);
+
+G_END_DECLS
+
+#endif /* NM_DEVICE_ITEM_H */
diff --git a/libnm-gtk/nm-device-model.c b/libnm-gtk/nm-device-model.c
new file mode 100644
index 0000000..359e0ba
--- /dev/null
+++ b/libnm-gtk/nm-device-model.c
@@ -0,0 +1,266 @@
+/* -*- 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 <nm-device.h>
+#include <nm-device-ethernet.h>
+#include <nm-device-wifi.h>
+#include <nm-serial-device.h>
+
+#include "nm-device-model.h"
+#include "nm-icon-cache.h"
+#include "utils.h"
+
+G_DEFINE_TYPE (NMDeviceModel, nm_device_model, GTK_TYPE_LIST_STORE)
+
+enum {
+ PROP_0,
+ PROP_CLIENT,
+
+ LAST_PROP
+};
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NM_TYPE_DEVICE_MODEL, NMDeviceModelPrivate))
+
+typedef struct {
+ NMClient *client;
+ gulong device_added_id;
+ gulong device_removed_id;
+
+ gboolean disposed;
+} NMDeviceModelPrivate;
+
+static GQuark quark_device_iter = 0;
+
+NMDeviceModel *
+nm_device_model_new (NMClient *client)
+{
+ g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
+
+ return (NMDeviceModel *) g_object_new (NM_TYPE_DEVICE_MODEL,
+ NM_DEVICE_MODEL_CLIENT, client,
+ NULL);
+}
+
+static void
+device_state_changed (NMDevice *device,
+ NMDeviceState new_state,
+ NMDeviceState old_state,
+ NMDeviceStateReason reason,
+ gpointer user_data)
+{
+ GtkListStore *store = GTK_LIST_STORE (user_data);
+ GtkTreeIter *iter;
+
+ iter = (GtkTreeIter *) g_object_get_qdata (G_OBJECT (device), quark_device_iter);
+ if (iter)
+ gtk_list_store_set (store, iter, NM_DEVICE_MODEL_COL_STATE, new_state, -1);
+}
+
+static void
+device_added (NMClient *client,
+ NMDevice *device,
+ gpointer user_data)
+{
+ GtkListStore *store = GTK_LIST_STORE (user_data);
+ GtkTreeIter *iter;
+ GdkPixbuf *pixbuf;
+
+ iter = g_slice_new0 (GtkTreeIter);
+
+ if (NM_IS_DEVICE_ETHERNET (device))
+ pixbuf = nm_icon_cache_get ("nm-device-wired");
+ else if (NM_IS_DEVICE_WIFI (device))
+ pixbuf = nm_icon_cache_get ("nm-device-wireless");
+ else if (NM_IS_SERIAL_DEVICE (device))
+ pixbuf = nm_icon_cache_get ("nm-device-wwan");
+ else {
+ g_warning ("Unhandled device type (%s)", G_OBJECT_TYPE_NAME (device));
+ pixbuf = NULL;
+ }
+
+ gtk_list_store_append (store, iter);
+ gtk_list_store_set (store, iter,
+ NM_DEVICE_MODEL_COL_DEVICE, device,
+ NM_DEVICE_MODEL_COL_IFACE, nm_device_get_iface (device),
+ NM_DEVICE_MODEL_COL_DESCRIPTION, utils_get_device_description (device),
+ NM_DEVICE_MODEL_COL_ICON, pixbuf,
+ NM_DEVICE_MODEL_COL_STATE, nm_device_get_state (device),
+ -1);
+
+ g_object_set_qdata_full (G_OBJECT (device), quark_device_iter, iter, (GDestroyNotify) gtk_tree_iter_free);
+ g_signal_connect (device, "state-changed", G_CALLBACK (device_state_changed), user_data);
+}
+
+static void
+device_removed (NMClient *client,
+ NMDevice *device,
+ gpointer user_data)
+{
+ GtkListStore *store = GTK_LIST_STORE (user_data);
+ GtkTreeIter *iter;
+
+ iter = (GtkTreeIter *) g_object_get_qdata (G_OBJECT (device), quark_device_iter);
+ if (iter) {
+ g_signal_handlers_disconnect_by_func (device, device_state_changed, user_data);
+ gtk_list_store_remove (store, iter);
+ g_object_set_qdata (G_OBJECT (device), quark_device_iter, NULL);
+ }
+}
+
+#if 0
+static int
+sort_callback (GtkTreeModel *model,
+ GtkTreeIter *a,
+ GtkTreeIter *b,
+ gpointer user_data)
+{
+ GValue value_a = {0, };
+ GValue value_b = {0, };
+ int result;
+
+ gtk_tree_model_get_value (model, a, NM_DEVICE_MODEL_COL_ITEM, &value_a);
+ gtk_tree_model_get_value (model, b, NM_DEVICE_MODEL_COL_ITEM, &value_b);
+
+ result = nm_device_item_compare (NM_DEVICE_ITEM (g_value_get_object (&value_a)),
+ NM_DEVICE_ITEM (g_value_get_object (&value_b)));
+
+ g_value_unset (&value_a);
+ g_value_unset (&value_b);
+
+ return result;
+}
+#endif
+
+/*****************************************************************************/
+
+static void
+nm_device_model_init (NMDeviceModel *self)
+{
+ GType types[NM_DEVICE_MODEL_N_COLUMNS];
+
+ types[NM_DEVICE_MODEL_COL_DEVICE] = NM_TYPE_DEVICE;
+ types[NM_DEVICE_MODEL_COL_IFACE] = G_TYPE_STRING;
+ types[NM_DEVICE_MODEL_COL_DESCRIPTION] = G_TYPE_STRING;
+ types[NM_DEVICE_MODEL_COL_ICON] = GDK_TYPE_PIXBUF;
+ types[NM_DEVICE_MODEL_COL_STATE] = G_TYPE_INT;
+
+ gtk_list_store_set_column_types (GTK_LIST_STORE (self), NM_DEVICE_MODEL_N_COLUMNS, types);
+#if 0
+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (self),
+ NM_DEVICE_MODEL_COL_ITEM,
+ sort_callback,
+ NULL,
+ NULL);
+
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (self), NM_DEVICE_MODEL_COL_DEVICE, GTK_SORT_ASCENDING);
+#endif
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMDeviceModelPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_CLIENT:
+ /* Construct only */
+ priv->client = g_value_dup_object (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)
+{
+ NMDeviceModelPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_CLIENT:
+ g_value_set_object (value, priv->client);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+constructed (GObject *object)
+{
+ NMDeviceModelPrivate *priv = GET_PRIVATE (object);
+ const GPtrArray *devices;
+ int i;
+
+ if (G_OBJECT_CLASS (nm_device_model_parent_class)->constructed)
+ G_OBJECT_CLASS (nm_device_model_parent_class)->constructed (object);
+
+ priv->device_added_id = g_signal_connect (priv->client, "device-added", G_CALLBACK (device_added), object);
+ priv->device_removed_id = g_signal_connect (priv->client, "device-removed", G_CALLBACK (device_removed), object);
+
+ devices = nm_client_get_devices (priv->client);
+ for (i = 0; devices && devices->len > i; i++)
+ device_added (priv->client, NM_DEVICE (g_ptr_array_index (devices, i)), object);
+}
+
+static void
+dispose (GObject *object)
+{
+ NMDeviceModelPrivate *priv = GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ g_signal_handler_disconnect (priv->client, priv->device_added_id);
+ g_signal_handler_disconnect (priv->client, priv->device_removed_id);
+
+ if (priv->client)
+ g_object_unref (priv->client);
+
+ priv->disposed = TRUE;
+ }
+
+ G_OBJECT_CLASS (nm_device_model_parent_class)->dispose (object);
+}
+
+static void
+nm_device_model_class_init (NMDeviceModelClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ quark_device_iter = g_quark_from_static_string ("NMDeviceModel-device-iter");
+
+ g_type_class_add_private (object_class, sizeof (NMDeviceModelPrivate));
+
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->constructed = constructed;
+ object_class->dispose = dispose;
+
+ /* Properties */
+ g_object_class_install_property
+ (object_class, PROP_CLIENT,
+ g_param_spec_object (NM_DEVICE_MODEL_CLIENT,
+ "NMClient",
+ "NMClient",
+ NM_TYPE_CLIENT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
diff --git a/libnm-gtk/nm-device-model.h b/libnm-gtk/nm-device-model.h
new file mode 100644
index 0000000..e7ff8f6
--- /dev/null
+++ b/libnm-gtk/nm-device-model.h
@@ -0,0 +1,61 @@
+/* -*- 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 NM_DEVICE_MODEL_H
+#define NM_DEVICE_MODEL_H
+
+#include <gtk/gtk.h>
+#include <nm-client.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_DEVICE_MODEL (nm_device_model_get_type ())
+#define NM_DEVICE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_MODEL, NMDeviceModel))
+#define NM_DEVICE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_MODEL, NMDeviceModelClass))
+#define NM_IS_DEVICE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_MODEL))
+#define NM_IS_DEVICE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DEVICE_MODEL))
+#define NM_DEVICE_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_MODEL, NMDeviceModelClass))
+
+#define NM_DEVICE_MODEL_CLIENT "client"
+
+enum {
+ NM_DEVICE_MODEL_COL_DEVICE,
+ NM_DEVICE_MODEL_COL_IFACE,
+ NM_DEVICE_MODEL_COL_DESCRIPTION,
+ NM_DEVICE_MODEL_COL_ICON,
+ NM_DEVICE_MODEL_COL_STATE,
+
+ NM_DEVICE_MODEL_N_COLUMNS
+};
+
+typedef struct {
+ GtkListStore parent;
+} NMDeviceModel;
+
+typedef struct {
+ GtkListStoreClass parent_class;
+} NMDeviceModelClass;
+
+GType nm_device_model_get_type (void);
+
+NMDeviceModel *nm_device_model_new (NMClient *client);
+
+G_END_DECLS
+
+#endif /* NM_DEVICE_MODEL_H */
diff --git a/libnm-gtk/nm-device-provider.c b/libnm-gtk/nm-device-provider.c
new file mode 100644
index 0000000..54eb31e
--- /dev/null
+++ b/libnm-gtk/nm-device-provider.c
@@ -0,0 +1,154 @@
+/* -*- 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 "nm-device-provider.h"
+
+G_DEFINE_ABSTRACT_TYPE (NMDeviceProvider, nm_device_provider, NM_TYPE_ITEM_PROVIDER)
+
+enum {
+ PROP_0,
+ PROP_DEVICE,
+
+ LAST_PROP
+};
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NM_TYPE_DEVICE_PROVIDER, NMDeviceProviderPrivate))
+
+typedef struct {
+ NMDevice *device;
+ gulong state_changed_id;
+
+ gboolean disposed;
+} NMDeviceProviderPrivate;
+
+NMDevice *
+nm_device_provider_get_device (NMDeviceProvider *self)
+{
+ g_return_val_if_fail (NM_IS_DEVICE_PROVIDER (self), NULL);
+
+ return GET_PRIVATE (self)->device;
+}
+
+gboolean
+nm_device_provider_ready (NMDeviceProvider *self)
+{
+ g_return_val_if_fail (NM_IS_DEVICE_PROVIDER (self), FALSE);
+
+ return nm_device_get_state (nm_device_provider_get_device (self)) >= NM_DEVICE_STATE_DISCONNECTED;
+}
+
+static void
+device_state_changed (NMDevice *device,
+ NMDeviceState new_state,
+ NMDeviceState old_state,
+ NMDeviceStateReason reason,
+ gpointer user_data)
+{
+ NMDeviceProvider *self = NM_DEVICE_PROVIDER (user_data);
+
+ g_debug ("device state %s changed (%d)", nm_device_get_iface (device), new_state);
+
+ if (old_state < NM_DEVICE_STATE_DISCONNECTED && new_state >= NM_DEVICE_STATE_DISCONNECTED)
+ /* Device became usable */
+ nm_item_provider_reset (NM_ITEM_PROVIDER (self));
+ else if (old_state >= NM_DEVICE_STATE_DISCONNECTED && new_state < NM_DEVICE_STATE_DISCONNECTED)
+ /* Device became unusable */
+ nm_item_provider_clear (NM_ITEM_PROVIDER (self));
+
+ if (NM_DEVICE_PROVIDER_GET_CLASS (self)->state_changed)
+ NM_DEVICE_PROVIDER_GET_CLASS (self)->state_changed (self, new_state, old_state, reason);
+}
+
+/*****************************************************************************/
+
+static void
+nm_device_provider_init (NMDeviceProvider *self)
+{
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMDeviceProviderPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_DEVICE:
+ /* Construct only */
+ priv->device = g_value_dup_object (value);
+ priv->state_changed_id = g_signal_connect (priv->device, "state-changed",
+ G_CALLBACK (device_state_changed), object);
+ 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)
+{
+ NMDeviceProviderPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_DEVICE:
+ g_value_set_object (value, priv->device);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ NMDeviceProviderPrivate *priv = GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ g_signal_handler_disconnect (priv->device, priv->state_changed_id);
+ g_object_unref (priv->device);
+
+ priv->disposed = TRUE;
+ }
+
+ G_OBJECT_CLASS (nm_device_provider_parent_class)->dispose (object);
+}
+
+static void
+nm_device_provider_class_init (NMDeviceProviderClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (NMDeviceProviderPrivate));
+
+ 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_DEVICE,
+ g_param_spec_object (NM_DEVICE_PROVIDER_DEVICE,
+ "NMDevice",
+ "NMDevice",
+ NM_TYPE_DEVICE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
diff --git a/libnm-gtk/nm-device-provider.h b/libnm-gtk/nm-device-provider.h
new file mode 100644
index 0000000..70695d7
--- /dev/null
+++ b/libnm-gtk/nm-device-provider.h
@@ -0,0 +1,59 @@
+/* -*- 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 NM_DEVICE_PROVIDER_H
+#define NM_DEVICE_PROVIDER_H
+
+#include <glib-object.h>
+#include <nm-device.h>
+#include <nm-item-provider.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_DEVICE_PROVIDER (nm_device_provider_get_type ())
+#define NM_DEVICE_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE_PROVIDER, NMDeviceProvider))
+#define NM_DEVICE_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_DEVICE_PROVIDER, NMDeviceProviderClass))
+#define NM_IS_DEVICE_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_DEVICE_PROVIDER))
+#define NM_IS_DEVICE_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_DEVICE_PROVIDER))
+#define NM_DEVICE_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_DEVICE_PROVIDER, NMDeviceProviderClass))
+
+#define NM_DEVICE_PROVIDER_DEVICE "device"
+
+typedef struct {
+ NMItemProvider parent;
+} NMDeviceProvider;
+
+typedef struct {
+ NMItemProviderClass parent_class;
+
+ /* Methods */
+ void (*state_changed) (NMDeviceProvider *self,
+ NMDeviceState new_state,
+ NMDeviceState old_state,
+ NMDeviceStateReason reason);
+} NMDeviceProviderClass;
+
+GType nm_device_provider_get_type (void);
+
+NMDevice *nm_device_provider_get_device (NMDeviceProvider *self);
+gboolean nm_device_provider_ready (NMDeviceProvider *self);
+
+G_END_DECLS
+
+#endif /* NM_DEVICE_PROVIDER_H */
diff --git a/libnm-gtk/nm-ethernet-item.c b/libnm-gtk/nm-ethernet-item.c
new file mode 100644
index 0000000..1e9a277
--- /dev/null
+++ b/libnm-gtk/nm-ethernet-item.c
@@ -0,0 +1,116 @@
+/* -*- 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 <nm-setting-8021x.h>
+#include "nm-ethernet-item.h"
+#include "nm-icon-cache.h"
+
+G_DEFINE_TYPE (NMEthernetItem, nm_ethernet_item, NM_TYPE_DEVICE_ITEM)
+
+NMListItem *
+nm_ethernet_item_new (NMClient *client,
+ NMDeviceEthernet *device,
+ NMSettingsConnectionInterface *connection)
+{
+ g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (NM_IS_DEVICE_ETHERNET (device), NULL);
+ g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection), NULL);
+
+ return (NMListItem *) g_object_new (NM_TYPE_ETHERNET_ITEM,
+ NM_LIST_ITEM_TYPE_NAME, _("wired"),
+ NM_CONNECTION_ITEM_CLIENT, client,
+ NM_CONNECTION_ITEM_CONNECTION, connection,
+ NM_DEVICE_ITEM_DEVICE, device,
+ NULL);
+}
+
+static void
+update_icon (NMEthernetItem *self)
+{
+ const char *icon;
+ NMListItemStatus status;
+
+ status = nm_list_item_get_status (NM_LIST_ITEM (self));
+ if (status == NM_LIST_ITEM_STATUS_CONNECTED)
+ icon = "nm-device-wired";
+ else
+ icon = "nm-no-connection";
+
+ if (icon)
+ g_object_set (self, NM_LIST_ITEM_ICON, icon, NULL);
+}
+
+static int
+priority (NMListItem *item)
+{
+ return NM_LIST_ITEM_PRIORITY_DEV_ETHERNET + NM_LIST_ITEM_CLASS (nm_ethernet_item_parent_class)->priority (item);
+}
+
+/*****************************************************************************/
+
+static void
+nm_ethernet_item_init (NMEthernetItem *self)
+{
+ update_icon (self);
+}
+
+static void
+constructed (GObject *object)
+{
+ NMConnection *connection;
+ NMSetting *setting;
+
+ if (G_OBJECT_CLASS (nm_ethernet_item_parent_class)->constructed)
+ G_OBJECT_CLASS (nm_ethernet_item_parent_class)->constructed (object);
+
+ connection = NM_CONNECTION (nm_connection_item_get_connection (NM_CONNECTION_ITEM (object)));
+ setting = nm_connection_get_setting (connection, NM_TYPE_SETTING_802_1X);
+
+ if (setting)
+ g_object_set (object, NM_LIST_ITEM_SECURITY, _("802.1x"), NULL);
+}
+
+static void
+notify (GObject *object,
+ GParamSpec *pspec)
+{
+ if (!pspec || !pspec->name)
+ return;
+
+ if (!strcmp (pspec->name, NM_LIST_ITEM_STATUS))
+ update_icon (NM_ETHERNET_ITEM (object));
+ else if (!strcmp (pspec->name, NM_CONNECTION_ITEM_CONNECTION) &&
+ !nm_connection_item_get_connection (NM_CONNECTION_ITEM (object)))
+ /* If the connection is removed from the item, request deletion */
+ nm_list_item_request_remove (NM_LIST_ITEM (object));
+}
+
+static void
+nm_ethernet_item_class_init (NMEthernetItemClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMListItemClass *list_class = NM_LIST_ITEM_CLASS (klass);
+
+ object_class->constructed = constructed;
+ object_class->notify = notify;
+
+ list_class->priority = priority;
+}
diff --git a/libnm-gtk/nm-ethernet-item.h b/libnm-gtk/nm-ethernet-item.h
new file mode 100644
index 0000000..9662742
--- /dev/null
+++ b/libnm-gtk/nm-ethernet-item.h
@@ -0,0 +1,52 @@
+/* -*- 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 NM_ETHERNET_ITEM_H
+#define NM_ETHERNET_ITEM_H
+
+#include <glib-object.h>
+#include <nm-device-ethernet.h>
+#include <nm-device-item.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_ETHERNET_ITEM (nm_ethernet_item_get_type ())
+#define NM_ETHERNET_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ETHERNET_ITEM, NMEthernetItem))
+#define NM_ETHERNET_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_ETHERNET_ITEM, NMEthernetItemClass))
+#define NM_IS_ETHERNET_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_ETHERNET_ITEM))
+#define NM_IS_ETHERNET_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_ETHERNET_ITEM))
+#define NM_ETHERNET_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ETHERNET_ITEM, NMEthernetItemClass))
+
+typedef struct {
+ NMDeviceItem parent;
+} NMEthernetItem;
+
+typedef struct {
+ NMDeviceItemClass parent_class;
+} NMEthernetItemClass;
+
+GType nm_ethernet_item_get_type (void);
+
+NMListItem *nm_ethernet_item_new (NMClient *client,
+ NMDeviceEthernet *device,
+ NMSettingsConnectionInterface *connection);
+
+G_END_DECLS
+
+#endif /* NM_ETHERNET_ITEM_H */
diff --git a/libnm-gtk/nm-ethernet-provider.c b/libnm-gtk/nm-ethernet-provider.c
new file mode 100644
index 0000000..6305edc
--- /dev/null
+++ b/libnm-gtk/nm-ethernet-provider.c
@@ -0,0 +1,71 @@
+/* -*- 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 "nm-ethernet-provider.h"
+#include "nm-ethernet-item.h"
+#include "utils.h"
+
+G_DEFINE_TYPE (NMEthernetProvider, nm_ethernet_provider, NM_TYPE_DEVICE_PROVIDER)
+
+NMItemProvider *
+nm_ethernet_provider_new (NMClient *client,
+ NMDeviceEthernet *device)
+{
+ g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (NM_IS_DEVICE_ETHERNET (device), NULL);
+
+ return (NMItemProvider *) g_object_new (NM_TYPE_ETHERNET_PROVIDER,
+ NM_ITEM_PROVIDER_CLIENT, client,
+ NM_DEVICE_PROVIDER_DEVICE, device,
+ NULL);
+}
+
+static void
+ethernet_added (NMItemProvider *provider,
+ NMSettingsConnectionInterface *connection)
+{
+ NMDeviceProvider *device_provider = NM_DEVICE_PROVIDER (provider);
+ NMDevice *device;
+
+ if (!nm_device_provider_ready (device_provider))
+ return;
+
+ device = nm_device_provider_get_device (device_provider);
+ if (utils_connection_valid_for_device (NM_CONNECTION (connection), device, NULL)) {
+ NMListItem *item;
+
+ item = nm_ethernet_item_new (nm_item_provider_get_client (provider), NM_DEVICE_ETHERNET (device), connection);
+ nm_item_provider_item_added (provider, item);
+ }
+}
+
+/*****************************************************************************/
+
+static void
+nm_ethernet_provider_init (NMEthernetProvider *self)
+{
+}
+
+static void
+nm_ethernet_provider_class_init (NMEthernetProviderClass *klass)
+{
+ NMItemProviderClass *item_class = NM_ITEM_PROVIDER_CLASS (klass);
+
+ item_class->connection_added = ethernet_added;
+}
diff --git a/libnm-gtk/nm-ethernet-provider.h b/libnm-gtk/nm-ethernet-provider.h
new file mode 100644
index 0000000..20f8c95
--- /dev/null
+++ b/libnm-gtk/nm-ethernet-provider.h
@@ -0,0 +1,51 @@
+/* -*- 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 NM_ETHERNET_PROVIDER_H
+#define NM_ETHERNET_PROVIDER_H
+
+#include <glib-object.h>
+#include <nm-device-ethernet.h>
+#include <nm-device-provider.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_ETHERNET_PROVIDER (nm_ethernet_provider_get_type ())
+#define NM_ETHERNET_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ETHERNET_PROVIDER, NMEthernetProvider))
+#define NM_ETHERNET_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_ETHERNET_PROVIDER, NMEthernetProviderClass))
+#define NM_IS_ETHERNET_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_ETHERNET_PROVIDER))
+#define NM_IS_ETHERNET_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_ETHERNET_PROVIDER))
+#define NM_ETHERNET_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ETHERNET_PROVIDER, NMEthernetProviderClass))
+
+typedef struct {
+ NMDeviceProvider parent;
+} NMEthernetProvider;
+
+typedef struct {
+ NMDeviceProviderClass parent_class;
+} NMEthernetProviderClass;
+
+GType nm_ethernet_provider_get_type (void);
+
+NMItemProvider *nm_ethernet_provider_new (NMClient *client,
+ NMDeviceEthernet *device);
+
+G_END_DECLS
+
+#endif /* NM_ETHERNET_PROVIDER_H */
diff --git a/src/gconf-helpers/nma-gconf-connection.c b/libnm-gtk/nm-gconf-connection.c
similarity index 86%
rename from src/gconf-helpers/nma-gconf-connection.c
rename to libnm-gtk/nm-gconf-connection.c
index 51fe667..0117e84 100644
--- a/src/gconf-helpers/nma-gconf-connection.c
+++ b/libnm-gtk/nm-gconf-connection.c
@@ -31,7 +31,7 @@
#include <nm-setting-vpn.h>
#include <nm-setting-8021x.h>
-#include "nma-gconf-connection.h"
+#include "nm-gconf-connection.h"
#include "gconf-helpers.h"
#include "nm-utils.h"
#include "utils.h"
@@ -42,18 +42,18 @@ static NMSettingsConnectionInterface *parent_settings_connection_iface;
static void settings_connection_interface_init (NMSettingsConnectionInterface *class);
-G_DEFINE_TYPE_EXTENDED (NMAGConfConnection, nma_gconf_connection, NM_TYPE_EXPORTED_CONNECTION, 0,
+G_DEFINE_TYPE_EXTENDED (NMGConfConnection, nm_gconf_connection, NM_TYPE_EXPORTED_CONNECTION, 0,
G_IMPLEMENT_INTERFACE (NM_TYPE_SETTINGS_CONNECTION_INTERFACE,
settings_connection_interface_init))
-#define NMA_GCONF_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMA_TYPE_GCONF_CONNECTION, NMAGConfConnectionPrivate))
+#define NM_GCONF_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_GCONF_CONNECTION, NMGConfConnectionPrivate))
typedef struct {
GConfClient *client;
char *dir;
gboolean disposed;
-} NMAGConfConnectionPrivate;
+} NMGConfConnectionPrivate;
enum {
PROP_0,
@@ -71,11 +71,11 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
-NMAGConfConnection *
-nma_gconf_connection_new (GConfClient *client, const char *conf_dir)
+NMGConfConnection *
+nm_gconf_connection_new (GConfClient *client, const char *conf_dir)
{
NMConnection *connection;
- NMAGConfConnection *gconf_connection;
+ NMGConfConnection *gconf_connection;
g_return_val_if_fail (GCONF_IS_CLIENT (client), NULL);
g_return_val_if_fail (conf_dir != NULL, NULL);
@@ -83,7 +83,7 @@ nma_gconf_connection_new (GConfClient *client, const char *conf_dir)
/* retrieve GConf data */
connection = nm_gconf_read_connection (client, conf_dir);
if (connection) {
- gconf_connection = nma_gconf_connection_new_from_connection (client, conf_dir, connection);
+ gconf_connection = nm_gconf_connection_new_from_connection (client, conf_dir, connection);
g_object_unref (connection);
} else {
nm_warning ("No connection read from GConf at %s.", conf_dir);
@@ -93,13 +93,13 @@ nma_gconf_connection_new (GConfClient *client, const char *conf_dir)
return gconf_connection;
}
-NMAGConfConnection *
-nma_gconf_connection_new_from_connection (GConfClient *client,
- const char *conf_dir,
- NMConnection *connection)
+NMGConfConnection *
+nm_gconf_connection_new_from_connection (GConfClient *client,
+ const char *conf_dir,
+ NMConnection *connection)
{
GObject *object;
- NMAGConfConnection *self;
+ NMGConfConnection *self;
GError *error = NULL;
gboolean success;
GHashTable *settings;
@@ -120,15 +120,15 @@ nma_gconf_connection_new_from_connection (GConfClient *client,
return NULL;
}
- object = g_object_new (NMA_TYPE_GCONF_CONNECTION,
- NMA_GCONF_CONNECTION_CLIENT, client,
- NMA_GCONF_CONNECTION_DIR, conf_dir,
+ object = g_object_new (NM_TYPE_GCONF_CONNECTION,
+ NM_GCONF_CONNECTION_CLIENT, client,
+ NM_GCONF_CONNECTION_DIR, conf_dir,
NM_CONNECTION_SCOPE, NM_CONNECTION_SCOPE_USER,
NULL);
if (!object)
return NULL;
- self = NMA_GCONF_CONNECTION (object);
+ self = NM_GCONF_CONNECTION (object);
/* Fill certs so that the nm_connection_replace_settings verification works */
settings = nm_connection_to_hash (connection);
@@ -142,17 +142,17 @@ nma_gconf_connection_new_from_connection (GConfClient *client,
}
const char *
-nma_gconf_connection_get_gconf_path (NMAGConfConnection *self)
+nm_gconf_connection_get_gconf_path (NMGConfConnection *self)
{
- g_return_val_if_fail (NMA_IS_GCONF_CONNECTION (self), NULL);
+ g_return_val_if_fail (NM_IS_GCONF_CONNECTION (self), NULL);
- return NMA_GCONF_CONNECTION_GET_PRIVATE (self)->dir;
+ return NM_GCONF_CONNECTION_GET_PRIVATE (self)->dir;
}
gboolean
-nma_gconf_connection_gconf_changed (NMAGConfConnection *self)
+nm_gconf_connection_gconf_changed (NMGConfConnection *self)
{
- NMAGConfConnectionPrivate *priv = NMA_GCONF_CONNECTION_GET_PRIVATE (self);
+ NMGConfConnectionPrivate *priv = NM_GCONF_CONNECTION_GET_PRIVATE (self);
NMConnection *new;
GHashTable *new_settings;
GError *error = NULL;
@@ -197,7 +197,7 @@ nma_gconf_connection_gconf_changed (NMAGConfConnection *self)
nm_settings_connection_interface_emit_updated (NM_SETTINGS_CONNECTION_INTERFACE (self));
return TRUE;
-invalid:
+ invalid:
g_clear_error (&error);
g_signal_emit_by_name (self, NM_SETTINGS_CONNECTION_INTERFACE_REMOVED);
return FALSE;
@@ -246,11 +246,11 @@ destroy_gvalue (gpointer data)
}
static GHashTable *
-nma_gconf_connection_get_keyring_items (NMAGConfConnection *self,
- const char *setting_name,
- GError **error)
+nm_gconf_connection_get_keyring_items (NMGConfConnection *self,
+ const char *setting_name,
+ GError **error)
{
- NMAGConfConnectionPrivate *priv;
+ NMGConfConnectionPrivate *priv;
NMSettingConnection *s_con;
GHashTable *secrets;
GList *found_list = NULL;
@@ -264,7 +264,7 @@ nma_gconf_connection_get_keyring_items (NMAGConfConnection *self,
g_return_val_if_fail (error != NULL, NULL);
g_return_val_if_fail (*error == NULL, NULL);
- priv = NMA_GCONF_CONNECTION_GET_PRIVATE (self);
+ priv = NM_GCONF_CONNECTION_GET_PRIVATE (self);
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (NM_CONNECTION (self), NM_TYPE_SETTING_CONNECTION));
g_assert (s_con);
@@ -298,7 +298,7 @@ nma_gconf_connection_get_keyring_items (NMAGConfConnection *self,
attr = &(gnome_keyring_attribute_list_index (found->attributes, i));
if ( (strcmp (attr->name, KEYRING_SK_TAG) == 0)
- && (attr->type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING)) {
+ && (attr->type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING)) {
key_name = attr->value.string;
break;
}
@@ -368,7 +368,7 @@ delete_done (GnomeKeyringResult result, gpointer user_data)
}
static void
-clear_keyring_items (NMAGConfConnection *self)
+clear_keyring_items (NMGConfConnection *self)
{
NMSettingConnection *s_con;
const char *uuid;
@@ -413,7 +413,7 @@ update (NMSettingsConnectionInterface *connection,
NMSettingsConnectionInterfaceUpdateFunc callback,
gpointer user_data)
{
- NMAGConfConnectionPrivate *priv = NMA_GCONF_CONNECTION_GET_PRIVATE (connection);
+ NMGConfConnectionPrivate *priv = NM_GCONF_CONNECTION_GET_PRIVATE (connection);
nm_gconf_write_connection (NM_CONNECTION (connection),
priv->client,
@@ -429,12 +429,12 @@ do_delete (NMSettingsConnectionInterface *connection,
NMSettingsConnectionInterfaceDeleteFunc callback,
gpointer user_data)
{
- NMAGConfConnectionPrivate *priv = NMA_GCONF_CONNECTION_GET_PRIVATE (connection);
+ NMGConfConnectionPrivate *priv = NM_GCONF_CONNECTION_GET_PRIVATE (connection);
gboolean success;
GError *error = NULL;
/* Clean up keyring keys */
- clear_keyring_items (NMA_GCONF_CONNECTION (connection));
+ clear_keyring_items (NM_GCONF_CONNECTION (connection));
success = gconf_client_recursive_unset (priv->client, priv->dir, 0, &error);
if (!success) {
@@ -453,11 +453,11 @@ internal_get_secrets (NMSettingsConnectionInterface *connection,
const char **hints,
gboolean request_new,
gboolean local,
- NMANewSecretsRequestedFunc callback,
+ NMNewSecretsRequestedFunc callback,
gpointer callback_data,
GError **error)
{
- NMAGConfConnection *self = NMA_GCONF_CONNECTION (connection);
+ NMGConfConnection *self = NM_GCONF_CONNECTION (connection);
GHashTable *settings = NULL;
GHashTable *secrets = NULL;
NMSettingConnection *s_con;
@@ -493,7 +493,7 @@ internal_get_secrets (NMSettingsConnectionInterface *connection,
/* Only try to get new secrets for D-Bus requests */
if (local) {
- secrets = nma_gconf_connection_get_keyring_items (self, setting_name, error);
+ secrets = nm_gconf_connection_get_keyring_items (self, setting_name, error);
if (!secrets && error && *error)
return FALSE;
} else {
@@ -508,7 +508,7 @@ internal_get_secrets (NMSettingsConnectionInterface *connection,
goto get_secrets;
}
- secrets = nma_gconf_connection_get_keyring_items (self, setting_name, error);
+ secrets = nm_gconf_connection_get_keyring_items (self, setting_name, error);
if (!secrets) {
if (error && *error)
return FALSE;
@@ -521,7 +521,7 @@ internal_get_secrets (NMSettingsConnectionInterface *connection,
if (g_hash_table_size (secrets) == 0) {
g_hash_table_destroy (secrets);
nm_warning ("%s.%d - Secrets were found for setting '%s' but none"
- " were valid.", __FILE__, __LINE__, setting_name);
+ " were valid.", __FILE__, __LINE__, setting_name);
goto get_secrets;
}
@@ -565,7 +565,7 @@ internal_get_secrets (NMSettingsConnectionInterface *connection,
g_hash_table_destroy (settings);
return TRUE;
-get_secrets:
+ get_secrets:
g_signal_emit (self,
signals[NEW_SECRETS_REQUESTED],
0,
@@ -675,7 +675,7 @@ is_dbus_request_authorized (DBusGMethodInvocation *context,
/* And finally, the actual UID check */
if ( (allow_user && (sender_uid == geteuid()))
- || (sender_uid == 0))
+ || (sender_uid == 0))
success = TRUE;
else {
g_set_error (error, NM_SETTINGS_INTERFACE_ERROR,
@@ -683,7 +683,7 @@ is_dbus_request_authorized (DBusGMethodInvocation *context,
"%s", "Requestor UID does not match the UID of the user settings service");
}
-out:
+ out:
if (bus)
dbus_g_connection_unref (bus);
g_free (sender);
@@ -708,7 +708,7 @@ dbus_update (NMExportedConnection *exported,
GHashTable *new_settings,
DBusGMethodInvocation *context)
{
- NMAGConfConnection *self = NMA_GCONF_CONNECTION (exported);
+ NMGConfConnection *self = NM_GCONF_CONNECTION (exported);
NMConnection *new;
gboolean success = FALSE;
GError *error = NULL;
@@ -754,7 +754,7 @@ static void
dbus_delete (NMExportedConnection *exported,
DBusGMethodInvocation *context)
{
- NMAGConfConnection *self = NMA_GCONF_CONNECTION (exported);
+ NMGConfConnection *self = NM_GCONF_CONNECTION (exported);
GError *error = NULL;
/* Restrict Update to execution by the current user and root for DBus invocation */
@@ -832,7 +832,7 @@ dbus_get_settings (NMExportedConnection *connection, GError **error)
added = TRUE;
}
- settings = NM_EXPORTED_CONNECTION_CLASS (nma_gconf_connection_parent_class)->get_settings (connection, error);
+ settings = NM_EXPORTED_CONNECTION_CLASS (nm_gconf_connection_parent_class)->get_settings (connection, error);
if (added)
g_object_set (s_vpn, NM_SETTING_VPN_USER_NAME, NULL, NULL);
@@ -853,7 +853,7 @@ settings_connection_interface_init (NMSettingsConnectionInterface *iface)
}
static void
-nma_gconf_connection_init (NMAGConfConnection *connection)
+nm_gconf_connection_init (NMGConfConnection *connection)
{
}
@@ -863,14 +863,14 @@ constructor (GType type,
GObjectConstructParam *construct_params)
{
GObject *object;
- NMAGConfConnectionPrivate *priv;
+ NMGConfConnectionPrivate *priv;
- object = G_OBJECT_CLASS (nma_gconf_connection_parent_class)->constructor (type, n_construct_params, construct_params);
+ object = G_OBJECT_CLASS (nm_gconf_connection_parent_class)->constructor (type, n_construct_params, construct_params);
if (!object)
return NULL;
- priv = NMA_GCONF_CONNECTION_GET_PRIVATE (object);
+ priv = NM_GCONF_CONNECTION_GET_PRIVATE (object);
if (!priv->client) {
nm_warning ("GConfClient not provided.");
@@ -890,7 +890,7 @@ constructor (GType type,
static void
dispose (GObject *object)
{
- NMAGConfConnectionPrivate *priv = NMA_GCONF_CONNECTION_GET_PRIVATE (object);
+ NMGConfConnectionPrivate *priv = NM_GCONF_CONNECTION_GET_PRIVATE (object);
if (priv->disposed)
return;
@@ -898,24 +898,24 @@ dispose (GObject *object)
g_object_unref (priv->client);
- G_OBJECT_CLASS (nma_gconf_connection_parent_class)->dispose (object);
+ G_OBJECT_CLASS (nm_gconf_connection_parent_class)->dispose (object);
}
static void
finalize (GObject *object)
{
- NMAGConfConnectionPrivate *priv = NMA_GCONF_CONNECTION_GET_PRIVATE (object);
+ NMGConfConnectionPrivate *priv = NM_GCONF_CONNECTION_GET_PRIVATE (object);
g_free (priv->dir);
- G_OBJECT_CLASS (nma_gconf_connection_parent_class)->finalize (object);
+ G_OBJECT_CLASS (nm_gconf_connection_parent_class)->finalize (object);
}
static void
set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
+ const GValue *value, GParamSpec *pspec)
{
- NMAGConfConnectionPrivate *priv = NMA_GCONF_CONNECTION_GET_PRIVATE (object);
+ NMGConfConnectionPrivate *priv = NM_GCONF_CONNECTION_GET_PRIVATE (object);
switch (prop_id) {
case PROP_CLIENT:
@@ -934,9 +934,9 @@ set_property (GObject *object, guint prop_id,
static void
get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
+ GValue *value, GParamSpec *pspec)
{
- NMAGConfConnectionPrivate *priv = NMA_GCONF_CONNECTION_GET_PRIVATE (object);
+ NMGConfConnectionPrivate *priv = NM_GCONF_CONNECTION_GET_PRIVATE (object);
switch (prop_id) {
case PROP_CLIENT:
@@ -952,12 +952,12 @@ get_property (GObject *object, guint prop_id,
}
static void
-nma_gconf_connection_class_init (NMAGConfConnectionClass *class)
+nm_gconf_connection_class_init (NMGConfConnectionClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
NMExportedConnectionClass *ec_class = NM_EXPORTED_CONNECTION_CLASS (class);
- g_type_class_add_private (class, sizeof (NMAGConfConnectionPrivate));
+ g_type_class_add_private (class, sizeof (NMGConfConnectionPrivate));
/* Virtual methods */
object_class->constructor = constructor;
@@ -974,28 +974,28 @@ nma_gconf_connection_class_init (NMAGConfConnectionClass *class)
/* Properties */
g_object_class_install_property
(object_class, PROP_CLIENT,
- g_param_spec_object (NMA_GCONF_CONNECTION_CLIENT,
- "GConfClient",
- "GConfClient",
- GCONF_TYPE_CLIENT,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ g_param_spec_object (NM_GCONF_CONNECTION_CLIENT,
+ "GConfClient",
+ "GConfClient",
+ GCONF_TYPE_CLIENT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property
(object_class, PROP_DIR,
- g_param_spec_string (NMA_GCONF_CONNECTION_DIR,
- "GConf directory",
- "GConf directory",
- NULL,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ g_param_spec_string (NM_GCONF_CONNECTION_DIR,
+ "GConf directory",
+ "GConf directory",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
/* Signals */
signals[NEW_SECRETS_REQUESTED] =
g_signal_new ("new-secrets-requested",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMAGConfConnectionClass, new_secrets_requested),
- NULL, NULL,
- nma_marshal_VOID__STRING_POINTER_BOOLEAN_POINTER_POINTER,
- G_TYPE_NONE, 5,
- G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN, G_TYPE_POINTER, G_TYPE_POINTER);
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMGConfConnectionClass, new_secrets_requested),
+ NULL, NULL,
+ nma_marshal_VOID__STRING_POINTER_BOOLEAN_POINTER_POINTER,
+ G_TYPE_NONE, 5,
+ G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN, G_TYPE_POINTER, G_TYPE_POINTER);
}
diff --git a/libnm-gtk/nm-gconf-connection.h b/libnm-gtk/nm-gconf-connection.h
new file mode 100644
index 0000000..00a3883
--- /dev/null
+++ b/libnm-gtk/nm-gconf-connection.h
@@ -0,0 +1,78 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
+ *
+ * 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 2008 Novell, Inc.
+ * (C) Copyright 2008 Red Hat, Inc.
+ */
+
+#ifndef NM_GCONF_CONNECTION_H
+#define NM_GCONF_CONNECTION_H
+
+#include <gconf/gconf-client.h>
+#include <dbus/dbus-glib.h>
+#include <nm-connection.h>
+#include <nm-exported-connection.h>
+#include <nm-settings-connection-interface.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_GCONF_CONNECTION (nm_gconf_connection_get_type ())
+#define NM_GCONF_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_GCONF_CONNECTION, NMGConfConnection))
+#define NM_GCONF_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_GCONF_CONNECTION, NMGConfConnectionClass))
+#define NM_IS_GCONF_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_GCONF_CONNECTION))
+#define NM_IS_GCONF_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_GCONF_CONNECTION))
+#define NM_GCONF_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_GCONF_CONNECTION, NMGConfConnectionClass))
+
+#define NM_GCONF_CONNECTION_CLIENT "client"
+#define NM_GCONF_CONNECTION_DIR "dir"
+
+typedef struct {
+ NMExportedConnection parent;
+} NMGConfConnection;
+
+typedef void (*NMNewSecretsRequestedFunc) (NMSettingsConnectionInterface *connection,
+ GHashTable *settings,
+ GError *error,
+ gpointer user_data);
+
+typedef struct {
+ NMExportedConnectionClass parent;
+
+ /* Signals */
+ void (*new_secrets_requested) (NMGConfConnection *self,
+ const char *setting_name,
+ const char **hints,
+ gboolean ask_user,
+ DBusGMethodInvocation *context);
+} NMGConfConnectionClass;
+
+GType nm_gconf_connection_get_type (void);
+
+NMGConfConnection *nm_gconf_connection_new (GConfClient *client,
+ const char *conf_dir);
+
+NMGConfConnection *nm_gconf_connection_new_from_connection (GConfClient *client,
+ const char *conf_dir,
+ NMConnection *connection);
+
+gboolean nm_gconf_connection_gconf_changed (NMGConfConnection *self);
+
+const char *nm_gconf_connection_get_gconf_path (NMGConfConnection *self);
+
+G_END_DECLS
+
+#endif /* NM_GCONF_CONNECTION_H */
diff --git a/src/gconf-helpers/nma-gconf-settings.c b/libnm-gtk/nm-gconf-settings.c
similarity index 68%
rename from src/gconf-helpers/nma-gconf-settings.c
rename to libnm-gtk/nm-gconf-settings.c
index 986d947..e9b0b21 100644
--- a/src/gconf-helpers/nma-gconf-settings.c
+++ b/libnm-gtk/nm-gconf-settings.c
@@ -21,14 +21,14 @@
#include <string.h>
#include <stdio.h>
-#include "nma-gconf-settings.h"
+#include "nm-gconf-settings.h"
#include "gconf-helpers.h"
#include "nma-marshal.h"
#include "nm-utils.h"
-G_DEFINE_TYPE (NMAGConfSettings, nma_gconf_settings, NM_TYPE_SETTINGS_SERVICE)
+G_DEFINE_TYPE (NMGConfSettings, nm_gconf_settings, NM_TYPE_SETTINGS_SERVICE)
-#define NMA_GCONF_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NMA_TYPE_GCONF_SETTINGS, NMAGConfSettingsPrivate))
+#define NM_GCONF_SETTINGS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_GCONF_SETTINGS, NMGConfSettingsPrivate))
typedef struct {
GConfClient *client;
@@ -36,9 +36,10 @@ typedef struct {
GSList *connections;
guint read_connections_id;
GHashTable *pending_changes;
+ gboolean reading_connections;
gboolean disposed;
-} NMAGConfSettingsPrivate;
+} NMGConfSettingsPrivate;
enum {
NEW_SECRETS_REQUESTED,
@@ -49,25 +50,25 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
-NMAGConfSettings *
-nma_gconf_settings_new (DBusGConnection *bus)
+NMGConfSettings *
+nm_gconf_settings_new (DBusGConnection *bus)
{
- return (NMAGConfSettings *) g_object_new (NMA_TYPE_GCONF_SETTINGS,
- NM_SETTINGS_SERVICE_SCOPE, NM_CONNECTION_SCOPE_USER,
- NM_SETTINGS_SERVICE_BUS, bus,
- NULL);
+ return (NMGConfSettings *) g_object_new (NM_TYPE_GCONF_SETTINGS,
+ NM_SETTINGS_SERVICE_SCOPE, NM_CONNECTION_SCOPE_USER,
+ NM_SETTINGS_SERVICE_BUS, bus,
+ NULL);
}
static void
-connection_new_secrets_requested_cb (NMAGConfConnection *connection,
+connection_new_secrets_requested_cb (NMGConfConnection *connection,
const char *setting_name,
const char **hints,
gboolean ask_user,
- NMANewSecretsRequestedFunc callback,
+ NMNewSecretsRequestedFunc callback,
gpointer callback_data,
gpointer user_data)
{
- NMAGConfSettings *self = NMA_GCONF_SETTINGS (user_data);
+ NMGConfSettings *self = NM_GCONF_SETTINGS (user_data);
/* Re-emit the signal to listeners so they don't have to know about
* every single connection
@@ -86,20 +87,20 @@ connection_new_secrets_requested_cb (NMAGConfConnection *connection,
static void
connection_removed (NMExportedConnection *connection, gpointer user_data)
{
- NMAGConfSettingsPrivate *priv = NMA_GCONF_SETTINGS_GET_PRIVATE (user_data);
+ NMGConfSettingsPrivate *priv = NM_GCONF_SETTINGS_GET_PRIVATE (user_data);
priv->connections = g_slist_remove (priv->connections, connection);
g_object_unref (connection);
}
static void
-internal_add_connection (NMAGConfSettings *self, NMAGConfConnection *connection)
+internal_add_connection (NMGConfSettings *self, NMGConfConnection *connection)
{
- NMAGConfSettingsPrivate *priv = NMA_GCONF_SETTINGS_GET_PRIVATE (self);
+ NMGConfSettingsPrivate *priv = NM_GCONF_SETTINGS_GET_PRIVATE (self);
DBusGConnection *bus = NULL;
g_return_if_fail (connection != NULL);
- g_return_if_fail (NMA_IS_GCONF_CONNECTION (connection));
+ g_return_if_fail (NM_IS_GCONF_CONNECTION (connection));
priv->connections = g_slist_prepend (priv->connections, connection);
g_signal_connect (connection, "new-secrets-requested",
@@ -115,8 +116,11 @@ internal_add_connection (NMAGConfSettings *self, NMAGConfConnection *connection)
dbus_g_connection_unref (bus);
}
- g_signal_emit_by_name (self, NM_SETTINGS_INTERFACE_NEW_CONNECTION, NM_CONNECTION (connection));
- g_return_if_fail (NMA_IS_GCONF_CONNECTION (priv->connections->data));
+ if (!priv->reading_connections)
+ /* Don't emit the signal when doing the initial population */
+ g_signal_emit_by_name (self, NM_SETTINGS_INTERFACE_NEW_CONNECTION, NM_CONNECTION (connection));
+
+ g_return_if_fail (NM_IS_GCONF_CONNECTION (priv->connections->data));
}
static void
@@ -127,24 +131,24 @@ update_cb (NMSettingsConnectionInterface *connection,
if (error) {
g_warning ("%s: %s:%d error updating connection %s: (%d) %s",
__func__, __FILE__, __LINE__,
- nma_gconf_connection_get_gconf_path (NMA_GCONF_CONNECTION (connection)),
+ nm_gconf_connection_get_gconf_path (NM_GCONF_CONNECTION (connection)),
error ? error->code : -1,
(error && error->message) ? error->message : "(unknown)");
}
}
-NMAGConfConnection *
-nma_gconf_settings_add_connection (NMAGConfSettings *self, NMConnection *connection)
+NMGConfConnection *
+nm_gconf_settings_add_connection (NMGConfSettings *self, NMConnection *connection)
{
- NMAGConfSettingsPrivate *priv;
- NMAGConfConnection *exported;
+ NMGConfSettingsPrivate *priv;
+ NMGConfConnection *exported;
guint32 i = 0;
char *path = NULL;
- g_return_val_if_fail (NMA_IS_GCONF_SETTINGS (self), NULL);
+ g_return_val_if_fail (NM_IS_GCONF_SETTINGS (self), NULL);
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
- priv = NMA_GCONF_SETTINGS_GET_PRIVATE (self);
+ priv = NM_GCONF_SETTINGS_GET_PRIVATE (self);
/* Find free GConf directory */
while (i++ < G_MAXUINT32) {
@@ -162,7 +166,7 @@ nma_gconf_settings_add_connection (NMAGConfSettings *self, NMConnection *connect
return NULL;
}
- exported = nma_gconf_connection_new_from_connection (priv->client, path, connection);
+ exported = nm_gconf_connection_new_from_connection (priv->client, path, connection);
g_free (path);
if (exported) {
internal_add_connection (self, exported);
@@ -183,7 +187,7 @@ add_connection (NMSettingsService *settings,
NMSettingsAddConnectionFunc callback,
gpointer user_data)
{
- NMAGConfSettings *self = NMA_GCONF_SETTINGS (settings);
+ NMGConfSettings *self = NM_GCONF_SETTINGS (settings);
/* For now, we don't support additions via D-Bus until we figure out
* the security implications.
@@ -197,25 +201,25 @@ add_connection (NMSettingsService *settings,
return;
}
- nma_gconf_settings_add_connection (self, connection);
+ nm_gconf_settings_add_connection (self, connection);
callback (NM_SETTINGS_INTERFACE (settings), NULL, user_data);
}
-static NMAGConfConnection *
-get_connection_by_gconf_path (NMAGConfSettings *self, const char *path)
+static NMGConfConnection *
+get_connection_by_gconf_path (NMGConfSettings *self, const char *path)
{
- NMAGConfSettingsPrivate *priv;
+ NMGConfSettingsPrivate *priv;
GSList *iter;
- g_return_val_if_fail (NMA_IS_GCONF_SETTINGS (self), NULL);
+ g_return_val_if_fail (NM_IS_GCONF_SETTINGS (self), NULL);
g_return_val_if_fail (path != NULL, NULL);
- priv = NMA_GCONF_SETTINGS_GET_PRIVATE (self);
+ priv = NM_GCONF_SETTINGS_GET_PRIVATE (self);
for (iter = priv->connections; iter; iter = iter->next) {
- NMAGConfConnection *connection = NMA_GCONF_CONNECTION (iter->data);
+ NMGConfConnection *connection = NM_GCONF_CONNECTION (iter->data);
const char *gconf_path;
- gconf_path = nma_gconf_connection_get_gconf_path (connection);
+ gconf_path = nm_gconf_connection_get_gconf_path (connection);
if (gconf_path && !strcmp (gconf_path, path))
return connection;
}
@@ -224,9 +228,9 @@ get_connection_by_gconf_path (NMAGConfSettings *self, const char *path)
}
static void
-read_connections (NMAGConfSettings *settings)
+read_connections (NMGConfSettings *settings)
{
- NMAGConfSettingsPrivate *priv = NMA_GCONF_SETTINGS_GET_PRIVATE (settings);
+ NMGConfSettingsPrivate *priv = NM_GCONF_SETTINGS_GET_PRIVATE (settings);
GSList *dir_list;
GSList *iter;
@@ -234,16 +238,20 @@ read_connections (NMAGConfSettings *settings)
if (!dir_list)
return;
+ priv->reading_connections = TRUE;
+
for (iter = dir_list; iter; iter = iter->next) {
char *dir = (char *) iter->data;
- NMAGConfConnection *connection;
+ NMGConfConnection *connection;
- connection = nma_gconf_connection_new (priv->client, dir);
+ connection = nm_gconf_connection_new (priv->client, dir);
if (connection)
internal_add_connection (settings, connection);
g_free (dir);
}
+ priv->reading_connections = FALSE;
+
g_slist_free (dir_list);
priv->connections = g_slist_reverse (priv->connections);
}
@@ -251,8 +259,8 @@ read_connections (NMAGConfSettings *settings)
static gboolean
read_connections_cb (gpointer data)
{
- NMA_GCONF_SETTINGS_GET_PRIVATE (data)->read_connections_id = 0;
- read_connections (NMA_GCONF_SETTINGS (data));
+ NM_GCONF_SETTINGS_GET_PRIVATE (data)->read_connections_id = 0;
+ read_connections (NM_GCONF_SETTINGS (data));
return FALSE;
}
@@ -260,20 +268,20 @@ read_connections_cb (gpointer data)
static GSList *
list_connections (NMSettingsService *settings)
{
- NMAGConfSettingsPrivate *priv = NMA_GCONF_SETTINGS_GET_PRIVATE (settings);
+ NMGConfSettingsPrivate *priv = NM_GCONF_SETTINGS_GET_PRIVATE (settings);
if (priv->read_connections_id) {
g_source_remove (priv->read_connections_id);
priv->read_connections_id = 0;
- read_connections (NMA_GCONF_SETTINGS (settings));
+ read_connections (NM_GCONF_SETTINGS (settings));
}
return g_slist_copy (priv->connections);
}
typedef struct {
- NMAGConfSettings *settings;
+ NMGConfSettings *settings;
char *path;
} ConnectionChangedInfo;
@@ -290,19 +298,19 @@ static gboolean
connection_changes_done (gpointer data)
{
ConnectionChangedInfo *info = (ConnectionChangedInfo *) data;
- NMAGConfSettingsPrivate *priv = NMA_GCONF_SETTINGS_GET_PRIVATE (info->settings);
- NMAGConfConnection *connection;
+ NMGConfSettingsPrivate *priv = NM_GCONF_SETTINGS_GET_PRIVATE (info->settings);
+ NMGConfConnection *connection;
connection = get_connection_by_gconf_path (info->settings, info->path);
if (!connection) {
/* New connection */
- connection = nma_gconf_connection_new (priv->client, info->path);
+ connection = nm_gconf_connection_new (priv->client, info->path);
if (connection)
internal_add_connection (info->settings, connection);
} else {
if (gconf_client_dir_exists (priv->client, info->path, NULL)) {
/* Updated connection */
- if (!nma_gconf_connection_gconf_changed (connection))
+ if (!nm_gconf_connection_gconf_changed (connection))
priv->connections = g_slist_remove (priv->connections, connection);
}
}
@@ -318,8 +326,8 @@ connections_changed_cb (GConfClient *conf_client,
GConfEntry *entry,
gpointer user_data)
{
- NMAGConfSettings *self = NMA_GCONF_SETTINGS (user_data);
- NMAGConfSettingsPrivate *priv = NMA_GCONF_SETTINGS_GET_PRIVATE (self);
+ NMGConfSettings *self = NM_GCONF_SETTINGS (user_data);
+ NMGConfSettingsPrivate *priv = NM_GCONF_SETTINGS_GET_PRIVATE (self);
char **dirs = NULL;
guint len;
char *path = NULL;
@@ -330,9 +338,9 @@ connections_changed_cb (GConfClient *conf_client,
goto out;
if ( strcmp (dirs[0], "")
- || strcmp (dirs[1], "system")
- || strcmp (dirs[2], "networking")
- || strcmp (dirs[3], "connections"))
+ || strcmp (dirs[1], "system")
+ || strcmp (dirs[2], "networking")
+ || strcmp (dirs[3], "connections"))
goto out;
path = g_strconcat ("/", dirs[1], "/", dirs[2], "/", dirs[3], "/", dirs[4], NULL);
@@ -347,11 +355,11 @@ connections_changed_cb (GConfClient *conf_client,
path = NULL;
id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, connection_changes_done,
- info, connection_changed_info_destroy);
+ info, connection_changed_info_destroy);
g_hash_table_insert (priv->pending_changes, info->path, GUINT_TO_POINTER (id));
}
-out:
+ out:
g_free (path);
g_strfreev (dirs);
}
@@ -365,9 +373,9 @@ remove_pending_change (gpointer data)
/************************************************************/
static void
-nma_gconf_settings_init (NMAGConfSettings *self)
+nm_gconf_settings_init (NMGConfSettings *self)
{
- NMAGConfSettingsPrivate *priv = NMA_GCONF_SETTINGS_GET_PRIVATE (self);
+ NMGConfSettingsPrivate *priv = NM_GCONF_SETTINGS_GET_PRIVATE (self);
priv->client = gconf_client_get_default ();
priv->pending_changes = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, remove_pending_change);
@@ -386,21 +394,21 @@ nma_gconf_settings_init (NMAGConfSettings *self)
static GObject *
constructor (GType type,
- guint n_construct_params,
- GObjectConstructParam *construct_params)
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
{
GObject *object;
- object = G_OBJECT_CLASS (nma_gconf_settings_parent_class)->constructor (type, n_construct_params, construct_params);
+ object = G_OBJECT_CLASS (nm_gconf_settings_parent_class)->constructor (type, n_construct_params, construct_params);
if (object)
- NMA_GCONF_SETTINGS_GET_PRIVATE (object)->read_connections_id = g_idle_add (read_connections_cb, object);
+ NM_GCONF_SETTINGS_GET_PRIVATE (object)->read_connections_id = g_idle_add (read_connections_cb, object);
return object;
}
static void
dispose (GObject *object)
{
- NMAGConfSettingsPrivate *priv = NMA_GCONF_SETTINGS_GET_PRIVATE (object);
+ NMGConfSettingsPrivate *priv = NM_GCONF_SETTINGS_GET_PRIVATE (object);
if (priv->disposed)
return;
@@ -422,16 +430,16 @@ dispose (GObject *object)
g_object_unref (priv->client);
- G_OBJECT_CLASS (nma_gconf_settings_parent_class)->dispose (object);
+ G_OBJECT_CLASS (nm_gconf_settings_parent_class)->dispose (object);
}
static void
-nma_gconf_settings_class_init (NMAGConfSettingsClass *class)
+nm_gconf_settings_class_init (NMGConfSettingsClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
NMSettingsServiceClass *settings_class = NM_SETTINGS_SERVICE_CLASS (class);
- g_type_class_add_private (class, sizeof (NMAGConfSettingsPrivate));
+ g_type_class_add_private (class, sizeof (NMGConfSettingsPrivate));
/* Virtual methods */
object_class->constructor = constructor;
@@ -443,11 +451,11 @@ nma_gconf_settings_class_init (NMAGConfSettingsClass *class)
/* Signals */
signals[NEW_SECRETS_REQUESTED] =
g_signal_new ("new-secrets-requested",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMAGConfSettingsClass, new_secrets_requested),
- NULL, NULL,
- nma_marshal_VOID__OBJECT_STRING_POINTER_BOOLEAN_POINTER_POINTER,
- G_TYPE_NONE, 6,
- G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN, G_TYPE_POINTER, G_TYPE_POINTER);
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMGConfSettingsClass, new_secrets_requested),
+ NULL, NULL,
+ nma_marshal_VOID__OBJECT_STRING_POINTER_BOOLEAN_POINTER_POINTER,
+ G_TYPE_NONE, 6,
+ G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN, G_TYPE_POINTER, G_TYPE_POINTER);
}
diff --git a/src/gconf-helpers/nma-gconf-settings.h b/libnm-gtk/nm-gconf-settings.h
similarity index 51%
rename from src/gconf-helpers/nma-gconf-settings.h
rename to libnm-gtk/nm-gconf-settings.h
index d197a35..f1e6497 100644
--- a/src/gconf-helpers/nma-gconf-settings.h
+++ b/libnm-gtk/nm-gconf-settings.h
@@ -18,47 +18,47 @@
* (C) Copyright 2008 Novell, Inc.
*/
-#ifndef NMA_GCONF_SETTINGS_H
-#define NMA_GCONF_SETTINGS_H
+#ifndef NM_GCONF_SETTINGS_H
+#define NM_GCONF_SETTINGS_H
#include <nm-connection.h>
#include <nm-settings-service.h>
-#include "nma-gconf-connection.h"
+#include "nm-gconf-connection.h"
G_BEGIN_DECLS
-#define NMA_TYPE_GCONF_SETTINGS (nma_gconf_settings_get_type ())
-#define NMA_GCONF_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMA_TYPE_GCONF_SETTINGS, NMAGConfSettings))
-#define NMA_GCONF_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMA_TYPE_GCONF_SETTINGS, NMAGConfSettingsClass))
-#define NMA_IS_GCONF_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMA_TYPE_GCONF_SETTINGS))
-#define NMA_IS_GCONF_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NMA_TYPE_GCONF_SETTINGS))
-#define NMA_GCONF_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMA_TYPE_GCONF_SETTINGS, NMAGConfSettingsClass))
+#define NM_TYPE_GCONF_SETTINGS (nm_gconf_settings_get_type ())
+#define NM_GCONF_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_GCONF_SETTINGS, NMGConfSettings))
+#define NM_GCONF_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_GCONF_SETTINGS, NMGConfSettingsClass))
+#define NM_IS_GCONF_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_GCONF_SETTINGS))
+#define NM_IS_GCONF_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_GCONF_SETTINGS))
+#define NM_GCONF_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_GCONF_SETTINGS, NMGConfSettingsClass))
typedef struct {
NMSettingsService parent;
-} NMAGConfSettings;
+} NMGConfSettings;
typedef struct {
NMSettingsServiceClass parent;
/* Signals */
- void (*new_secrets_requested) (NMAGConfSettings *self,
- NMAGConfConnection *exported,
+ void (*new_secrets_requested) (NMGConfSettings *self,
+ NMGConfConnection *exported,
const char *setting_name,
const char **hints,
gboolean ask_user,
- NMANewSecretsRequestedFunc callback,
+ NMNewSecretsRequestedFunc callback,
gpointer callback_data);
-} NMAGConfSettingsClass;
+} NMGConfSettingsClass;
-GType nma_gconf_settings_get_type (void);
+GType nm_gconf_settings_get_type (void);
-NMAGConfSettings *nma_gconf_settings_new (DBusGConnection *bus);
+NMGConfSettings *nm_gconf_settings_new (DBusGConnection *bus);
-NMAGConfConnection *nma_gconf_settings_add_connection (NMAGConfSettings *self,
- NMConnection *connection);
+NMGConfConnection *nm_gconf_settings_add_connection (NMGConfSettings *self,
+ NMConnection *connection);
G_END_DECLS
-#endif /* NMA_GCONF_SETTINGS_H */
+#endif /* NM_GCONF_SETTINGS_H */
diff --git a/libnm-gtk/nm-gsm-item.c b/libnm-gtk/nm-gsm-item.c
new file mode 100644
index 0000000..e3cffc9
--- /dev/null
+++ b/libnm-gtk/nm-gsm-item.c
@@ -0,0 +1,76 @@
+/* -*- 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 <glib/gi18n.h>
+#include <nm-setting-8021x.h>
+#include "nm-gsm-item.h"
+
+G_DEFINE_TYPE (NMGsmItem, nm_gsm_item, NM_TYPE_DEVICE_ITEM)
+
+NMListItem *
+nm_gsm_item_new (NMClient *client,
+ NMGsmDevice *device,
+ NMSettingsConnectionInterface *connection)
+{
+ g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (NM_IS_GSM_DEVICE (device), NULL);
+ g_return_val_if_fail (NM_IS_SETTINGS_CONNECTION_INTERFACE (connection), NULL);
+
+ return (NMListItem *) g_object_new (NM_TYPE_GSM_ITEM,
+ NM_LIST_ITEM_TYPE_NAME, _("3G"),
+ NM_CONNECTION_ITEM_CLIENT, client,
+ NM_CONNECTION_ITEM_CONNECTION, connection,
+ NM_DEVICE_ITEM_DEVICE, device,
+ NULL);
+}
+
+static int
+priority (NMListItem *item)
+{
+ return NM_LIST_ITEM_PRIORITY_DEV_GSM + NM_LIST_ITEM_CLASS (nm_gsm_item_parent_class)->priority (item);
+}
+
+/*****************************************************************************/
+
+static void
+notify (GObject *object, GParamSpec *spec)
+{
+ /* If the connection is removed from the item, request deletion */
+ if (spec && !g_strcmp0 (spec->name, NM_CONNECTION_ITEM_CONNECTION) &&
+ !nm_connection_item_get_connection (NM_CONNECTION_ITEM (object)))
+
+ nm_list_item_request_remove (NM_LIST_ITEM (object));
+}
+
+static void
+nm_gsm_item_init (NMGsmItem *self)
+{
+ g_object_set (self, NM_LIST_ITEM_ICON, "nm-device-wwan", NULL);
+}
+
+static void
+nm_gsm_item_class_init (NMGsmItemClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMListItemClass *list_class = NM_LIST_ITEM_CLASS (klass);
+
+ object_class->notify = notify;
+
+ list_class->priority = priority;
+}
diff --git a/libnm-gtk/nm-gsm-item.h b/libnm-gtk/nm-gsm-item.h
new file mode 100644
index 0000000..5ea92c7
--- /dev/null
+++ b/libnm-gtk/nm-gsm-item.h
@@ -0,0 +1,52 @@
+/* -*- 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 NM_GSM_ITEM_H
+#define NM_GSM_ITEM_H
+
+#include <glib-object.h>
+#include <nm-gsm-device.h>
+#include <nm-device-item.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_GSM_ITEM (nm_gsm_item_get_type ())
+#define NM_GSM_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_GSM_ITEM, NMGsmItem))
+#define NM_GSM_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_GSM_ITEM, NMGsmItemClass))
+#define NM_IS_GSM_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_GSM_ITEM))
+#define NM_IS_GSM_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_GSM_ITEM))
+#define NM_GSM_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_GSM_ITEM, NMGsmItemClass))
+
+typedef struct {
+ NMDeviceItem parent;
+} NMGsmItem;
+
+typedef struct {
+ NMDeviceItemClass parent_class;
+} NMGsmItemClass;
+
+GType nm_gsm_item_get_type (void);
+
+NMListItem *nm_gsm_item_new (NMClient *client,
+ NMGsmDevice *device,
+ NMSettingsConnectionInterface *connection);
+
+G_END_DECLS
+
+#endif /* NM_GSM_ITEM_H */
diff --git a/libnm-gtk/nm-gsm-provider.c b/libnm-gtk/nm-gsm-provider.c
new file mode 100644
index 0000000..859c488
--- /dev/null
+++ b/libnm-gtk/nm-gsm-provider.c
@@ -0,0 +1,71 @@
+/* -*- 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 "nm-gsm-provider.h"
+#include "nm-gsm-item.h"
+#include "utils.h"
+
+G_DEFINE_TYPE (NMGsmProvider, nm_gsm_provider, NM_TYPE_DEVICE_PROVIDER)
+
+NMItemProvider *
+nm_gsm_provider_new (NMClient *client,
+ NMGsmDevice *device)
+{
+ g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (NM_IS_GSM_DEVICE (device), NULL);
+
+ return (NMItemProvider *) g_object_new (NM_TYPE_GSM_PROVIDER,
+ NM_ITEM_PROVIDER_CLIENT, client,
+ NM_DEVICE_PROVIDER_DEVICE, device,
+ NULL);
+}
+
+static void
+gsm_added (NMItemProvider *provider,
+ NMSettingsConnectionInterface *connection)
+{
+ NMDeviceProvider *device_provider = NM_DEVICE_PROVIDER (provider);
+ NMDevice *device;
+
+ if (!nm_device_provider_ready (device_provider))
+ return;
+
+ device = nm_device_provider_get_device (device_provider);
+ if (utils_connection_valid_for_device (NM_CONNECTION (connection), device, NULL)) {
+ NMListItem *item;
+
+ item = nm_gsm_item_new (nm_item_provider_get_client (provider), NM_GSM_DEVICE (device), connection);
+ nm_item_provider_item_added (provider, item);
+ }
+}
+
+/*****************************************************************************/
+
+static void
+nm_gsm_provider_init (NMGsmProvider *self)
+{
+}
+
+static void
+nm_gsm_provider_class_init (NMGsmProviderClass *klass)
+{
+ NMItemProviderClass *item_class = NM_ITEM_PROVIDER_CLASS (klass);
+
+ item_class->connection_added = gsm_added;
+}
diff --git a/libnm-gtk/nm-gsm-provider.h b/libnm-gtk/nm-gsm-provider.h
new file mode 100644
index 0000000..c497b10
--- /dev/null
+++ b/libnm-gtk/nm-gsm-provider.h
@@ -0,0 +1,51 @@
+/* -*- 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 NM_GSM_PROVIDER_H
+#define NM_GSM_PROVIDER_H
+
+#include <glib-object.h>
+#include <nm-gsm-device.h>
+#include <nm-device-provider.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_GSM_PROVIDER (nm_gsm_provider_get_type ())
+#define NM_GSM_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_GSM_PROVIDER, NMGsmProvider))
+#define NM_GSM_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_GSM_PROVIDER, NMGsmProviderClass))
+#define NM_IS_GSM_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_GSM_PROVIDER))
+#define NM_IS_GSM_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_GSM_PROVIDER))
+#define NM_GSM_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_GSM_PROVIDER, NMGsmProviderClass))
+
+typedef struct {
+ NMDeviceProvider parent;
+} NMGsmProvider;
+
+typedef struct {
+ NMDeviceProviderClass parent_class;
+} NMGsmProviderClass;
+
+GType nm_gsm_provider_get_type (void);
+
+NMItemProvider *nm_gsm_provider_new (NMClient *client,
+ NMGsmDevice *device);
+
+G_END_DECLS
+
+#endif /* NM_GSM_PROVIDER_H */
diff --git a/src/nmn-icon-cache.c b/libnm-gtk/nm-icon-cache.c
similarity index 73%
rename from src/nmn-icon-cache.c
rename to libnm-gtk/nm-icon-cache.c
index 9aacbd2..d0a3427 100644
--- a/src/nmn-icon-cache.c
+++ b/libnm-gtk/nm-icon-cache.c
@@ -18,13 +18,13 @@
*/
#include <gtk/gtk.h>
-#include "nmn-icon-cache.h"
+#include "nm-icon-cache.h"
static GtkIconTheme *icon_theme = NULL;
static GHashTable *cache = NULL;
void
-nmn_icon_cache_invalidate (void)
+nm_icon_cache_invalidate (void)
{
if (cache) {
g_hash_table_destroy (cache);
@@ -35,18 +35,38 @@ nmn_icon_cache_invalidate (void)
icon_theme = NULL;
}
+static void
+init_icon_theme (void)
+{
+ char **path = NULL;
+ int n_path;
+ int i;
+
+ icon_theme = gtk_icon_theme_get_default ();
+ g_signal_connect (icon_theme, "changed", G_CALLBACK (nm_icon_cache_invalidate), NULL);
+
+ gtk_icon_theme_get_search_path (icon_theme, &path, &n_path);
+ for (i = n_path - 1; i >= 0; i--) {
+ if (g_strcmp0 (ICONDIR, path[i]) == 0)
+ break;
+ }
+
+ if (i < 0)
+ gtk_icon_theme_append_search_path (icon_theme, ICONDIR);
+
+ g_strfreev (path);
+}
+
GdkPixbuf *
-nmn_icon_cache_get (const char *icon_name)
+nm_icon_cache_get (const char *icon_name)
{
GdkPixbuf *pixbuf;
GError *error = NULL;
g_return_val_if_fail (icon_name != NULL, NULL);
- if (G_UNLIKELY (icon_theme == NULL)) {
- icon_theme = gtk_icon_theme_get_for_screen (gdk_screen_get_default ());
- g_signal_connect (icon_theme, "changed", G_CALLBACK (nmn_icon_cache_invalidate), NULL);
- }
+ if (G_UNLIKELY (icon_theme == NULL))
+ init_icon_theme ();
if (G_UNLIKELY (cache == NULL)) {
cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
@@ -55,14 +75,13 @@ nmn_icon_cache_get (const char *icon_name)
pixbuf = (GdkPixbuf *) g_hash_table_lookup (cache, icon_name);
if (!pixbuf) {
- /* Prefer theme icons */
pixbuf = gtk_icon_theme_load_icon (icon_theme, icon_name, 48, 0, &error);
if (!pixbuf) {
/* Try harder, using our own icons if theme doesn't provide something */
char *path;
- path = g_strconcat (ICON_PATH, icon_name, ".png", NULL);
+ path = g_strconcat (ICONDIR, icon_name, ".png", NULL);
pixbuf = gdk_pixbuf_new_from_file (path, NULL);
g_free (path);
}
diff --git a/src/nmn-icon-cache.h b/libnm-gtk/nm-icon-cache.h
similarity index 82%
rename from src/nmn-icon-cache.h
rename to libnm-gtk/nm-icon-cache.h
index ddf6818..92f6354 100644
--- a/src/nmn-icon-cache.h
+++ b/libnm-gtk/nm-icon-cache.h
@@ -17,12 +17,12 @@
* (C) Copyright 2009 Novell, Inc.
*/
-#ifndef NMN_ICON_CACHE_H
-#define NMN_ICON_CACHE_H
+#ifndef NM_ICON_CACHE_H
+#define NM_ICON_CACHE_H
#include <gdk-pixbuf/gdk-pixbuf.h>
-GdkPixbuf *nmn_icon_cache_get (const char *icon_name);
-void nmn_icon_cache_invalidate (void);
+GdkPixbuf *nm_icon_cache_get (const char *icon_name);
+void nm_icon_cache_invalidate (void);
-#endif /* NMN_ICON_CACHE_H */
+#endif /* NM_ICON_CACHE_H */
diff --git a/libnm-gtk/nm-item-provider.c b/libnm-gtk/nm-item-provider.c
new file mode 100644
index 0000000..80bb2e4
--- /dev/null
+++ b/libnm-gtk/nm-item-provider.c
@@ -0,0 +1,308 @@
+/* -*- 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 <nm-setting-connection.h>
+#include "nm-item-provider.h"
+
+G_DEFINE_ABSTRACT_TYPE (NMItemProvider, nm_item_provider, G_TYPE_OBJECT)
+
+enum {
+ PROP_0,
+ PROP_CLIENT,
+
+ LAST_PROP
+};
+
+enum {
+ ITEM_ADDED,
+ ITEM_CHANGED,
+ ITEM_REMOVED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NM_TYPE_ITEM_PROVIDER, NMItemProviderPrivate))
+
+typedef struct {
+ NMClient *client;
+ GSList *settings;
+
+ GSList *items;
+
+ gboolean disposed;
+} NMItemProviderPrivate;
+
+static void
+item_changed (NMListItem *item,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ g_signal_emit (user_data, signals[ITEM_CHANGED], 0, item);
+}
+
+static void
+remove_item (NMListItem *item,
+ gpointer user_data)
+{
+ NMItemProvider *self = NM_ITEM_PROVIDER (user_data);
+ NMItemProviderPrivate *priv = GET_PRIVATE (self);
+ GSList *link;
+
+ link = g_slist_find (priv->items, item);
+ if (link) {
+ g_signal_handlers_disconnect_matched (item, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, user_data);
+
+ priv->items = g_slist_delete_link (priv->items, link);
+ g_signal_emit (self, signals[ITEM_REMOVED], 0, item);
+ g_object_unref (item);
+ }
+}
+
+void
+nm_item_provider_item_added (NMItemProvider *provider,
+ NMListItem *item)
+{
+ NMItemProviderPrivate *priv;
+
+ g_return_if_fail (NM_IS_ITEM_PROVIDER (provider));
+ g_return_if_fail (NM_IS_LIST_ITEM (item));
+
+ priv = GET_PRIVATE (provider);
+ priv->items = g_slist_prepend (priv->items, g_object_ref_sink (item));
+ g_signal_connect (item, "request-remove", G_CALLBACK (remove_item), provider);
+ g_signal_connect (item, "notify", G_CALLBACK (item_changed), provider);
+
+ g_signal_emit (provider, signals[ITEM_ADDED], 0, item);
+}
+
+static void
+connection_added (NMSettingsInterface *settings,
+ NMSettingsConnectionInterface *connection,
+ gpointer data)
+{
+ NMItemProvider *self = NM_ITEM_PROVIDER (data);
+ NMSettingConnection *s_con;
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (NM_CONNECTION (connection), NM_TYPE_SETTING_CONNECTION);
+ g_debug ("Connection '%s' (%d) added", nm_setting_connection_get_id (s_con),
+ nm_connection_get_scope (NM_CONNECTION (connection)));
+
+ if (NM_ITEM_PROVIDER_GET_CLASS (self)->connection_added)
+ NM_ITEM_PROVIDER_GET_CLASS (self)->connection_added (self, connection);
+}
+
+static void
+add_settings_connections (NMSettingsInterface *settings,
+ NMItemProvider *self)
+{
+ GSList *items;
+ GSList *iter;
+
+ items = nm_settings_interface_list_connections (settings);
+ for (iter = items; iter; iter = iter->next)
+ connection_added (settings, NM_SETTINGS_CONNECTION_INTERFACE (iter->data), self);
+
+ g_slist_free (items);
+}
+
+void
+nm_item_provider_add_settings (NMItemProvider *self,
+ NMSettingsInterface *settings)
+{
+ NMItemProviderPrivate *priv;
+
+ g_return_if_fail (NM_IS_ITEM_PROVIDER (self));
+ g_return_if_fail (NM_IS_SETTINGS_INTERFACE (settings));
+
+ priv = GET_PRIVATE (self);
+
+ priv->settings = g_slist_prepend (priv->settings, g_object_ref (settings));
+ g_signal_connect (settings, "new-connection", G_CALLBACK (connection_added), self);
+ add_settings_connections (settings, self);
+}
+
+NMClient *
+nm_item_provider_get_client (NMItemProvider *self)
+{
+ g_return_val_if_fail (NM_IS_ITEM_PROVIDER (self), NULL);
+
+ return GET_PRIVATE (self)->client;
+}
+
+GSList *
+nm_item_provider_get_connections (NMItemProvider *self)
+{
+ NMItemProviderPrivate *priv;
+ GSList *iter;
+ GSList *list = NULL;
+
+ g_return_val_if_fail (NM_IS_ITEM_PROVIDER (self), NULL);
+
+ priv = GET_PRIVATE (self);
+ for (iter = priv->settings; iter; iter = iter->next)
+ list = g_slist_concat (list, nm_settings_interface_list_connections (NM_SETTINGS_INTERFACE (iter->data)));
+
+ return list;
+}
+
+GSList *
+nm_item_provider_get_items (NMItemProvider *self)
+{
+ g_return_val_if_fail (NM_IS_ITEM_PROVIDER (self), NULL);
+
+ return GET_PRIVATE (self)->items;
+}
+
+void
+nm_item_provider_clear (NMItemProvider *self)
+{
+ NMItemProviderPrivate *priv;
+
+ g_return_if_fail (NM_IS_ITEM_PROVIDER (self));
+
+ priv = GET_PRIVATE (self);
+ g_slist_foreach (priv->items, (GFunc) remove_item, self);
+}
+
+void
+nm_item_provider_reset (NMItemProvider *self)
+{
+ NMItemProviderPrivate *priv;
+
+ g_return_if_fail (NM_IS_ITEM_PROVIDER (self));
+
+ priv = GET_PRIVATE (self);
+ g_slist_foreach (priv->settings, (GFunc) add_settings_connections, self);
+}
+
+/*****************************************************************************/
+
+static void
+nm_item_provider_init (NMItemProvider *self)
+{
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMItemProviderPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_CLIENT:
+ /* Construct only */
+ priv->client = g_value_dup_object (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)
+{
+ NMItemProviderPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_CLIENT:
+ g_value_set_object (value, priv->client);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ NMItemProviderPrivate *priv = GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ nm_item_provider_clear (NM_ITEM_PROVIDER (object));
+
+ g_slist_foreach (priv->settings, (GFunc) g_object_unref, NULL);
+ g_slist_free (priv->settings);
+
+ if (priv->client)
+ g_object_unref (priv->client);
+
+ priv->disposed = TRUE;
+ }
+
+ G_OBJECT_CLASS (nm_item_provider_parent_class)->dispose (object);
+}
+
+static void
+nm_item_provider_class_init (NMItemProviderClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (NMItemProviderPrivate));
+
+ 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_CLIENT,
+ g_param_spec_object (NM_ITEM_PROVIDER_CLIENT,
+ "NMClient",
+ "NMClient",
+ NM_TYPE_CLIENT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ signals[ITEM_ADDED] =
+ g_signal_new ("item-added",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMItemProviderClass, item_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ NM_TYPE_LIST_ITEM);
+
+ /* Signals */
+ signals[ITEM_CHANGED] =
+ g_signal_new ("item-changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMItemProviderClass, item_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ NM_TYPE_LIST_ITEM);
+
+ signals[ITEM_REMOVED] =
+ g_signal_new ("item-removed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMItemProviderClass, item_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ NM_TYPE_LIST_ITEM);
+}
diff --git a/libnm-gtk/nm-item-provider.h b/libnm-gtk/nm-item-provider.h
new file mode 100644
index 0000000..6376375
--- /dev/null
+++ b/libnm-gtk/nm-item-provider.h
@@ -0,0 +1,79 @@
+/* -*- 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 NM_ITEM_PROVIDER_H
+#define NM_ITEM_PROVIDER_H
+
+#include <glib-object.h>
+#include <nm-client.h>
+#include <nm-settings-interface.h>
+#include <nm-list-item.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_ITEM_PROVIDER (nm_item_provider_get_type ())
+#define NM_ITEM_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ITEM_PROVIDER, NMItemProvider))
+#define NM_ITEM_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_ITEM_PROVIDER, NMItemProviderClass))
+#define NM_IS_ITEM_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_ITEM_PROVIDER))
+#define NM_IS_ITEM_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_ITEM_PROVIDER))
+#define NM_ITEM_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ITEM_PROVIDER, NMItemProviderClass))
+
+#define NM_ITEM_PROVIDER_CLIENT "client"
+
+typedef struct {
+ GObject parent;
+} NMItemProvider;
+
+typedef struct {
+ GObjectClass parent_class;
+
+ /* Methods */
+ void (*connection_added) (NMItemProvider *self,
+ NMSettingsConnectionInterface *connection);
+
+ /* Signals */
+ void (*item_added) (NMItemProvider *self,
+ NMListItem *item);
+
+ void (*item_changed) (NMItemProvider *self,
+ NMListItem *item);
+
+ void (*item_removed) (NMItemProvider *self,
+ NMListItem *item);
+} NMItemProviderClass;
+
+GType nm_item_provider_get_type (void);
+
+void nm_item_provider_add_settings (NMItemProvider *self,
+ NMSettingsInterface *settings);
+
+NMClient *nm_item_provider_get_client (NMItemProvider *self);
+GSList *nm_item_provider_get_connections (NMItemProvider *self);
+
+GSList *nm_item_provider_get_items (NMItemProvider *self);
+
+void nm_item_provider_item_added (NMItemProvider *provider,
+ NMListItem *item);
+
+void nm_item_provider_clear (NMItemProvider *self);
+void nm_item_provider_reset (NMItemProvider *self);
+
+G_END_DECLS
+
+#endif /* NM_ITEM_PROVIDER_H */
diff --git a/libnm-gtk/nm-list-item.c b/libnm-gtk/nm-list-item.c
new file mode 100644
index 0000000..d29da51
--- /dev/null
+++ b/libnm-gtk/nm-list-item.c
@@ -0,0 +1,343 @@
+/* -*- 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 "nm-list-item.h"
+
+G_DEFINE_TYPE (NMListItem, nm_list_item, G_TYPE_INITIALLY_UNOWNED)
+
+enum {
+ PROP_0,
+ PROP_NAME,
+ PROP_TYPE_NAME,
+ PROP_ICON,
+ PROP_SECURITY,
+ PROP_STATUS,
+ PROP_SHOW_DELETE,
+
+ LAST_PROP
+};
+
+enum {
+ REQUEST_REMOVE,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NM_TYPE_LIST_ITEM, NMListItemPrivate))
+
+typedef struct {
+ char *name;
+ char *type_name;
+ char *security;
+ char *icon;
+ NMListItemStatus status;
+ gboolean show_delete;
+
+ gboolean disposed;
+} NMListItemPrivate;
+
+const char *
+nm_list_item_get_name (NMListItem *self)
+{
+ g_return_val_if_fail (NM_IS_LIST_ITEM (self), NULL);
+
+ return GET_PRIVATE (self)->name;
+}
+
+const char *
+nm_list_item_get_type_name (NMListItem *self)
+{
+ g_return_val_if_fail (NM_IS_LIST_ITEM (self), NULL);
+
+ return GET_PRIVATE (self)->type_name;
+}
+
+const char *
+nm_list_item_get_icon (NMListItem *self)
+{
+ g_return_val_if_fail (NM_IS_LIST_ITEM (self), NULL);
+
+ return GET_PRIVATE (self)->icon;
+}
+
+const char *
+nm_list_item_get_security (NMListItem *self)
+{
+ g_return_val_if_fail (NM_IS_LIST_ITEM (self), NULL);
+
+ return GET_PRIVATE (self)->security;
+}
+
+NMListItemStatus
+nm_list_item_get_status (NMListItem *self)
+{
+ g_return_val_if_fail (NM_IS_LIST_ITEM (self), NM_LIST_ITEM_STATUS_DISCONNECTED);
+
+ return GET_PRIVATE (self)->status;
+}
+
+gboolean
+nm_list_item_get_show_delete (NMListItem *self)
+{
+ g_return_val_if_fail (NM_IS_LIST_ITEM (self), FALSE);
+
+ return GET_PRIVATE (self)->show_delete;
+}
+
+void
+nm_list_item_request_remove (NMListItem *self)
+{
+ g_return_if_fail (NM_IS_LIST_ITEM (self));
+
+ g_signal_emit (self, signals[REQUEST_REMOVE], 0);
+}
+
+void
+nm_list_item_connect (NMListItem *self)
+{
+ g_return_if_fail (NM_IS_LIST_ITEM (self));
+
+ if (NM_LIST_ITEM_GET_CLASS (self)->connect)
+ NM_LIST_ITEM_GET_CLASS (self)->connect (self);
+}
+
+void
+nm_list_item_disconnect (NMListItem *self)
+{
+ g_return_if_fail (NM_IS_LIST_ITEM (self));
+
+ if (NM_LIST_ITEM_GET_CLASS (self)->disconnect)
+ NM_LIST_ITEM_GET_CLASS (self)->disconnect (self);
+}
+
+void
+nm_list_item_delete (NMListItem *self)
+{
+ g_return_if_fail (NM_IS_LIST_ITEM (self));
+
+ if (NM_LIST_ITEM_GET_CLASS (self)->delete)
+ NM_LIST_ITEM_GET_CLASS (self)->delete (self);
+}
+
+static int
+priority (NMListItem *self)
+{
+ return 0;
+}
+
+static int
+nm_list_item_get_priority (NMListItem *item)
+{
+ return NM_LIST_ITEM_GET_CLASS (item)->priority (item);
+}
+
+int
+nm_list_item_compare (NMListItem *self,
+ NMListItem *other)
+{
+ int priority;
+ int other_priority;
+
+ g_return_val_if_fail (NM_IS_LIST_ITEM (self), 1);
+ g_return_val_if_fail (NM_IS_LIST_ITEM (other), 1);
+
+ priority = nm_list_item_get_priority (self);
+ other_priority = nm_list_item_get_priority (other);
+
+ if (priority > other_priority)
+ return -1;
+ else if (priority < other_priority)
+ return 1;
+
+ return g_strcmp0 (nm_list_item_get_name (self), nm_list_item_get_name (other));
+}
+
+/*****************************************************************************/
+
+static void
+nm_list_item_init (NMListItem *self)
+{
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMListItemPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_NAME:
+ g_free (priv->name);
+ priv->name = g_value_dup_string (value);
+ g_object_notify (object, NM_LIST_ITEM_NAME);
+ break;
+ case PROP_TYPE_NAME:
+ g_free (priv->type_name);
+ priv->type_name = g_value_dup_string (value);
+ g_object_notify (object, NM_LIST_ITEM_TYPE_NAME);
+ break;
+ case PROP_ICON:
+ g_free (priv->icon);
+ priv->icon = g_value_dup_string (value);
+ g_object_notify (object, NM_LIST_ITEM_ICON);
+ break;
+ case PROP_SECURITY:
+ g_free (priv->security);
+ priv->security = g_value_dup_string (value);
+ g_object_notify (object, NM_LIST_ITEM_SECURITY);
+ break;
+ case PROP_STATUS:
+ priv->status = g_value_get_int (value);
+ g_object_notify (object, NM_LIST_ITEM_STATUS);
+ break;
+ case PROP_SHOW_DELETE:
+ priv->show_delete = g_value_get_boolean (value);
+ g_object_notify (object, NM_LIST_ITEM_SHOW_DELETE);
+ 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)
+{
+ NMListItem *self = NM_LIST_ITEM (object);
+
+ switch (prop_id) {
+ case PROP_NAME:
+ g_value_set_string (value, nm_list_item_get_name (self));
+ break;
+ case PROP_TYPE_NAME:
+ g_value_set_string (value, nm_list_item_get_type_name (self));
+ break;
+ case PROP_ICON:
+ g_value_set_string (value, nm_list_item_get_icon (self));
+ break;
+ case PROP_SECURITY:
+ g_value_set_string (value, nm_list_item_get_security (self));
+ break;
+ case PROP_STATUS:
+ g_value_set_int (value, nm_list_item_get_status (self));
+ break;
+ case PROP_SHOW_DELETE:
+ g_value_set_boolean (value, nm_list_item_get_show_delete (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ NMListItemPrivate *priv = GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ g_free (priv->name);
+ g_free (priv->type_name);
+ g_free (priv->icon);
+ g_free (priv->security);
+
+ priv->disposed = TRUE;
+ }
+
+ G_OBJECT_CLASS (nm_list_item_parent_class)->dispose (object);
+}
+
+static void
+nm_list_item_class_init (NMListItemClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (NMListItemPrivate));
+
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+
+ klass->priority = priority;
+
+ /* Properties */
+ g_object_class_install_property
+ (object_class, PROP_NAME,
+ g_param_spec_string (NM_LIST_ITEM_NAME,
+ "Name",
+ "Name",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property
+ (object_class, PROP_TYPE_NAME,
+ g_param_spec_string (NM_LIST_ITEM_TYPE_NAME,
+ "TypeName",
+ "TypeName",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property
+ (object_class, PROP_ICON,
+ g_param_spec_string (NM_LIST_ITEM_ICON,
+ "Icon",
+ "Icon",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property
+ (object_class, PROP_SECURITY,
+ g_param_spec_string (NM_LIST_ITEM_SECURITY,
+ "Security",
+ "Security",
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property
+ (object_class, PROP_STATUS,
+ g_param_spec_int (NM_LIST_ITEM_STATUS,
+ "Status",
+ "Status",
+ NM_LIST_ITEM_STATUS_DISCONNECTED,
+ NM_LIST_ITEM_STATUS_CONNECTED,
+ NM_LIST_ITEM_STATUS_DISCONNECTED,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property
+ (object_class, PROP_SHOW_DELETE,
+ g_param_spec_boolean (NM_LIST_ITEM_SHOW_DELETE,
+ "Show delete",
+ "Show delete button",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ /* Signals */
+ signals[REQUEST_REMOVE] =
+ g_signal_new ("request-remove",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMListItemClass, request_remove),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+}
diff --git a/libnm-gtk/nm-list-item.h b/libnm-gtk/nm-list-item.h
new file mode 100644
index 0000000..15988d9
--- /dev/null
+++ b/libnm-gtk/nm-list-item.h
@@ -0,0 +1,93 @@
+/* -*- 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 NM_LIST_ITEM_H
+#define NM_LIST_ITEM_H
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_LIST_ITEM (nm_list_item_get_type ())
+#define NM_LIST_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_LIST_ITEM, NMListItem))
+#define NM_LIST_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_LIST_ITEM, NMListItemClass))
+#define NM_IS_LIST_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_LIST_ITEM))
+#define NM_IS_LIST_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_LIST_ITEM))
+#define NM_LIST_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_LIST_ITEM, NMListItemClass))
+
+typedef enum {
+ NM_LIST_ITEM_STATUS_DISCONNECTED,
+ NM_LIST_ITEM_STATUS_CONNECTING,
+ NM_LIST_ITEM_STATUS_CONNECTED
+} NMListItemStatus;
+
+#define NM_LIST_ITEM_NAME "name"
+#define NM_LIST_ITEM_TYPE_NAME "type-name"
+#define NM_LIST_ITEM_ICON "icon"
+#define NM_LIST_ITEM_SECURITY "security"
+#define NM_LIST_ITEM_STATUS "status"
+#define NM_LIST_ITEM_SHOW_DELETE "show-delete"
+
+/* Sorting priorities. These are summed and the items are sorted
+ in ascending numeric order (higher first) */
+#define NM_LIST_ITEM_PRIORITY_DEFAULT_ROUTE 1000
+#define NM_LIST_ITEM_PRIORITY_ACTIVATED 200
+#define NM_LIST_ITEM_PRIORITY_CONFIGURED 100
+#define NM_LIST_ITEM_PRIORITY_DEV_ETHERNET 99
+#define NM_LIST_ITEM_PRIORITY_DEV_WIFI 98
+#define NM_LIST_ITEM_PRIORITY_DEV_GSM 97
+#define NM_LIST_ITEM_PRIORITY_DEV_CDMA 96
+
+typedef struct {
+ GInitiallyUnowned parent;
+} NMListItem;
+
+typedef struct {
+ GInitiallyUnownedClass parent_class;
+
+ /* Methods */
+ void (*connect) (NMListItem *self);
+ void (*disconnect) (NMListItem *self);
+ void (*delete) (NMListItem *self);
+ int (*priority) (NMListItem *self);
+
+ /* Signals */
+ void (*request_remove) (NMListItem *self);
+} NMListItemClass;
+
+GType nm_list_item_get_type (void);
+
+const char *nm_list_item_get_name (NMListItem *self);
+const char *nm_list_item_get_type_name (NMListItem *self);
+const char *nm_list_item_get_icon (NMListItem *self);
+const char *nm_list_item_get_security (NMListItem *self);
+NMListItemStatus nm_list_item_get_status (NMListItem *self);
+gboolean nm_list_item_get_show_delete (NMListItem *self);
+
+void nm_list_item_request_remove (NMListItem *self);
+
+void nm_list_item_connect (NMListItem *self);
+void nm_list_item_disconnect (NMListItem *self);
+void nm_list_item_delete (NMListItem *self);
+int nm_list_item_compare (NMListItem *self,
+ NMListItem *other);
+
+G_END_DECLS
+
+#endif /* NM_LIST_ITEM_H */
diff --git a/libnm-gtk/nm-list-model.c b/libnm-gtk/nm-list-model.c
new file mode 100644
index 0000000..e257392
--- /dev/null
+++ b/libnm-gtk/nm-list-model.c
@@ -0,0 +1,314 @@
+/* -*- 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 "nm-list-model.h"
+#include "nm-list-item.h"
+#include "nm-device-handler.h"
+
+G_DEFINE_TYPE (NMListModel, nm_list_model, GTK_TYPE_LIST_STORE)
+
+enum {
+ PROP_0,
+ PROP_CLIENT,
+
+ LAST_PROP
+};
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NM_TYPE_LIST_MODEL, NMListModelPrivate))
+
+typedef struct {
+ NMClient *client;
+ GSList *settings;
+ NMDeviceHandler *device_handler;
+
+ gboolean disposed;
+} NMListModelPrivate;
+
+static GQuark quark_item_iter = 0;
+
+NMListModel *
+nm_list_model_new (NMClient *client)
+{
+ g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
+
+ return (NMListModel *) g_object_new (NM_TYPE_LIST_MODEL,
+ NM_LIST_MODEL_CLIENT, client,
+ NULL);
+}
+
+void
+nm_list_model_add_settings (NMListModel *self,
+ NMSettingsInterface *settings)
+{
+ NMListModelPrivate *priv;
+
+ g_return_if_fail (NM_IS_LIST_MODEL (self));
+ g_return_if_fail (NM_IS_SETTINGS_INTERFACE (settings));
+
+ priv = GET_PRIVATE (self);
+ priv->settings = g_slist_append (priv->settings, g_object_ref (settings));
+
+ g_slist_foreach (nm_device_handler_get_providers (priv->device_handler),
+ (GFunc) nm_item_provider_add_settings, settings);
+}
+
+NMClient *
+nm_list_model_get_client (NMListModel *self)
+{
+ g_return_val_if_fail (NM_IS_LIST_MODEL (self), NULL);
+
+ return GET_PRIVATE (self)->client;
+}
+
+static void
+item_added (NMItemProvider *provider,
+ NMListItem *item,
+ gpointer user_data)
+{
+ GtkListStore *store = GTK_LIST_STORE (user_data);
+ GtkTreeIter *iter;
+
+ iter = g_slice_new0 (GtkTreeIter);
+ gtk_list_store_insert_with_values (store, iter, G_MAXINT,
+ NM_LIST_MODEL_COL_ITEM, item,
+ NM_LIST_MODEL_COL_NAME, nm_list_item_get_name (item),
+ NM_LIST_MODEL_COL_ICON, nm_list_item_get_icon (item),
+ NM_LIST_MODEL_COL_SECURITY, nm_list_item_get_security (item),
+ NM_LIST_MODEL_COL_STATUS, nm_list_item_get_status (item),
+ NM_LIST_MODEL_COL_SHOW_DELETE, nm_list_item_get_show_delete (item),
+ -1);
+
+ g_object_set_qdata_full (G_OBJECT (item), quark_item_iter, iter, (GDestroyNotify) gtk_tree_iter_free);
+}
+
+static void
+item_changed (NMItemProvider *provider,
+ NMListItem *item,
+ gpointer user_data)
+{
+ GtkListStore *store = GTK_LIST_STORE (user_data);
+ GtkTreeIter *iter;
+
+ iter = (GtkTreeIter *) g_object_get_qdata (G_OBJECT (item), quark_item_iter);
+ if (iter)
+ gtk_list_store_set (store, iter,
+ NM_LIST_MODEL_COL_ITEM, item,
+ NM_LIST_MODEL_COL_NAME, nm_list_item_get_name (item),
+ NM_LIST_MODEL_COL_ICON, nm_list_item_get_icon (item),
+ NM_LIST_MODEL_COL_SECURITY, nm_list_item_get_security (item),
+ NM_LIST_MODEL_COL_STATUS, nm_list_item_get_status (item),
+ NM_LIST_MODEL_COL_SHOW_DELETE, nm_list_item_get_show_delete (item),
+ -1);
+}
+
+static void
+item_removed (NMItemProvider *provider,
+ NMListItem *item,
+ gpointer user_data)
+{
+ GtkListStore *store = GTK_LIST_STORE (user_data);
+ GtkTreeIter *iter;
+
+ iter = (GtkTreeIter *) g_object_get_qdata (G_OBJECT (item), quark_item_iter);
+ if (iter) {
+ gtk_list_store_remove (store, iter);
+ g_object_set_qdata (G_OBJECT (item), quark_item_iter, NULL);
+ }
+}
+
+static void
+device_provider_added (NMDeviceHandler *handler,
+ NMItemProvider *provider,
+ gpointer user_data)
+{
+ NMListModelPrivate *priv = GET_PRIVATE (user_data);
+ GSList *list;
+ GSList *iter;
+
+ g_signal_connect (provider, "item-added", G_CALLBACK (item_added), user_data);
+ g_signal_connect (provider, "item-changed", G_CALLBACK (item_changed), user_data);
+ g_signal_connect (provider, "item-removed", G_CALLBACK (item_removed), user_data);
+
+ list = nm_item_provider_get_items (provider);
+ for (iter = list; iter; iter = iter->next)
+ item_added (provider, (NMListItem *) iter->data, user_data);
+
+ for (iter = priv->settings; iter; iter = iter->next)
+ nm_item_provider_add_settings (provider, (NMSettingsInterface *) iter->data);
+}
+
+static void
+device_provider_removed (NMDeviceHandler *handler,
+ NMItemProvider *provider,
+ gpointer user_data)
+{
+ g_signal_handlers_disconnect_matched (provider, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, user_data);
+}
+
+static int
+sort_callback (GtkTreeModel *model,
+ GtkTreeIter *a,
+ GtkTreeIter *b,
+ gpointer user_data)
+{
+ NMListItem *item_a;
+ NMListItem *item_b;
+ int result;
+
+ gtk_tree_model_get (model, a, NM_LIST_MODEL_COL_ITEM, &item_a, -1);
+ gtk_tree_model_get (model, b, NM_LIST_MODEL_COL_ITEM, &item_b, -1);
+
+ result = nm_list_item_compare (item_a, item_b);
+
+ if (item_a)
+ g_object_unref (item_a);
+
+ if (item_b)
+ g_object_unref (item_b);
+
+ return result;
+}
+
+/*****************************************************************************/
+
+static void
+nm_list_model_init (NMListModel *self)
+{
+ GType types[NM_LIST_MODEL_N_COLUMNS];
+
+ types[NM_LIST_MODEL_COL_ITEM] = NM_TYPE_LIST_ITEM;
+ types[NM_LIST_MODEL_COL_NAME] = G_TYPE_STRING;
+ types[NM_LIST_MODEL_COL_ICON] = G_TYPE_STRING;
+ types[NM_LIST_MODEL_COL_SECURITY] = G_TYPE_STRING;
+ types[NM_LIST_MODEL_COL_STATUS] = G_TYPE_INT;
+ types[NM_LIST_MODEL_COL_SHOW_DELETE] = G_TYPE_BOOLEAN;
+
+ gtk_list_store_set_column_types (GTK_LIST_STORE (self), NM_LIST_MODEL_N_COLUMNS, types);
+
+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (self),
+ NM_LIST_MODEL_COL_ITEM,
+ sort_callback,
+ NULL,
+ NULL);
+
+ gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (self), NM_LIST_MODEL_COL_ITEM, GTK_SORT_ASCENDING);
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMListModelPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_CLIENT:
+ /* Construct only */
+ priv->client = g_value_dup_object (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)
+{
+ NMListModelPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_CLIENT:
+ g_value_set_object (value, priv->client);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+constructed (GObject *object)
+{
+ NMListModelPrivate *priv = GET_PRIVATE (object);
+ GSList *list;
+ GSList *iter;
+
+ if (G_OBJECT_CLASS (nm_list_model_parent_class)->constructed)
+ G_OBJECT_CLASS (nm_list_model_parent_class)->constructed (object);
+
+ priv->device_handler = nm_device_handler_new (priv->client);
+ g_signal_connect (priv->device_handler, "provider-added", G_CALLBACK (device_provider_added), object);
+ g_signal_connect (priv->device_handler, "provider-removed", G_CALLBACK (device_provider_removed), object);
+
+ list = nm_device_handler_get_providers (priv->device_handler);
+ for (iter = list; iter; iter = iter->next)
+ device_provider_added (priv->device_handler, NM_ITEM_PROVIDER (iter->data), object);
+
+ /* FIXME: create VPNProvider */
+}
+
+static void
+dispose (GObject *object)
+{
+ NMListModelPrivate *priv = GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ if (priv->device_handler)
+ g_object_unref (priv->device_handler);
+
+ if (priv->settings) {
+ g_slist_foreach (priv->settings, (GFunc) g_object_unref, NULL);
+ g_slist_free (priv->settings);
+ priv->settings = NULL;
+ }
+
+ if (priv->client)
+ g_object_unref (priv->client);
+
+ priv->disposed = TRUE;
+ }
+
+ G_OBJECT_CLASS (nm_list_model_parent_class)->dispose (object);
+}
+
+static void
+nm_list_model_class_init (NMListModelClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ quark_item_iter = g_quark_from_static_string ("NMListModel-item-iter");
+
+ g_type_class_add_private (object_class, sizeof (NMListModelPrivate));
+
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->constructed = constructed;
+ object_class->dispose = dispose;
+
+ /* Properties */
+ g_object_class_install_property
+ (object_class, PROP_CLIENT,
+ g_param_spec_object (NM_LIST_MODEL_CLIENT,
+ "NMClient",
+ "NMClient",
+ NM_TYPE_CLIENT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
diff --git a/libnm-gtk/nm-list-model.h b/libnm-gtk/nm-list-model.h
new file mode 100644
index 0000000..22f4683
--- /dev/null
+++ b/libnm-gtk/nm-list-model.h
@@ -0,0 +1,67 @@
+/* -*- 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 NM_LIST_MODEL_H
+#define NM_LIST_MODEL_H
+
+#include <gtk/gtk.h>
+#include <nm-client.h>
+#include <nm-settings-interface.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_LIST_MODEL (nm_list_model_get_type ())
+#define NM_LIST_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_LIST_MODEL, NMListModel))
+#define NM_LIST_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_LIST_MODEL, NMListModelClass))
+#define NM_IS_LIST_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_LIST_MODEL))
+#define NM_IS_LIST_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_LIST_MODEL))
+#define NM_LIST_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_LIST_MODEL, NMListModelClass))
+
+#define NM_LIST_MODEL_CLIENT "client"
+
+enum {
+ NM_LIST_MODEL_COL_ITEM,
+ NM_LIST_MODEL_COL_NAME,
+ NM_LIST_MODEL_COL_ICON,
+ NM_LIST_MODEL_COL_SECURITY,
+ NM_LIST_MODEL_COL_STATUS,
+ NM_LIST_MODEL_COL_SHOW_DELETE,
+
+ NM_LIST_MODEL_N_COLUMNS
+};
+
+typedef struct {
+ GtkListStore parent;
+} NMListModel;
+
+typedef struct {
+ GtkListStoreClass parent_class;
+} NMListModelClass;
+
+GType nm_list_model_get_type (void);
+
+NMListModel *nm_list_model_new (NMClient *client);
+void nm_list_model_add_settings (NMListModel *self,
+ NMSettingsInterface *settings);
+
+NMClient *nm_list_model_get_client (NMListModel *self);
+
+G_END_DECLS
+
+#endif /* NM_LIST_MODEL_H */
diff --git a/libnm-gtk/nm-status-icon.c b/libnm-gtk/nm-status-icon.c
new file mode 100644
index 0000000..3385624
--- /dev/null
+++ b/libnm-gtk/nm-status-icon.c
@@ -0,0 +1,244 @@
+/* -*- 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 "nm-status-icon.h"
+#include "nm-list-item.h"
+#include "nm-device-item.h"
+#include "nm-icon-cache.h"
+
+#define ACTIVATION_STEPS 6
+
+G_DEFINE_TYPE (NMStatusIcon, nm_status_icon, GTK_TYPE_STATUS_ICON)
+
+enum {
+ PROP_0,
+ PROP_MODEL,
+
+ LAST_PROP
+};
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NM_TYPE_STATUS_ICON, NMStatusIconPrivate))
+
+typedef struct {
+ NMStatusModel *model;
+ NMListItem *item;
+
+ guint animation_id;
+ guint animation_step;
+
+ gboolean disposed;
+} NMStatusIconPrivate;
+
+GtkStatusIcon *
+nm_status_icon_new (NMStatusModel *model)
+{
+ g_return_val_if_fail (NM_IS_STATUS_MODEL (model), NULL);
+
+ return (GtkStatusIcon *) g_object_new (NM_TYPE_STATUS_ICON,
+ NM_STATUS_ICON_MODEL, model,
+ NULL);
+}
+
+static gboolean
+activation_animation (gpointer data)
+{
+ NMStatusIconPrivate *priv = GET_PRIVATE (data);
+ char *image;
+ GdkPixbuf *pixbuf;
+ int stage;
+
+ if (++priv->animation_step > ACTIVATION_STEPS)
+ priv->animation_step = 1;
+
+ if (NM_IS_DEVICE_ITEM (priv->item)) {
+ NMDeviceState state;
+
+ state = nm_device_get_state (nm_device_item_get_device (NM_DEVICE_ITEM (priv->item)));
+ switch (state) {
+ case NM_DEVICE_STATE_PREPARE:
+ stage = 1;
+ break;
+ case NM_DEVICE_STATE_CONFIG:
+ case NM_DEVICE_STATE_NEED_AUTH:
+ stage = 2;
+ break;
+ case NM_DEVICE_STATE_IP_CONFIG:
+ stage = 3;
+ break;
+ default:
+ stage = 1;
+ break;
+ }
+ } else
+ stage = 1;
+
+ image = g_strdup_printf ("nm-stage%02d-connecting%04d", stage, priv->animation_step);
+ pixbuf = nm_icon_cache_get (image);
+ g_free (image);
+
+ if (pixbuf)
+ gtk_status_icon_set_from_pixbuf (GTK_STATUS_ICON (data), pixbuf);
+
+ return TRUE;
+}
+
+static void
+item_status_changed (NMListItem *item,
+ GParamSpec *spec,
+ gpointer user_data)
+{
+ NMStatusIconPrivate *priv = GET_PRIVATE (user_data);
+ GdkPixbuf *pixbuf;
+
+ if (priv->animation_id) {
+ g_source_remove (priv->animation_id);
+ priv->animation_id = 0;
+ }
+
+ switch (nm_list_item_get_status (item)) {
+ case NM_LIST_ITEM_STATUS_CONNECTING:
+ priv->animation_id = g_timeout_add (200, activation_animation, user_data);
+ activation_animation (user_data);
+ pixbuf = NULL;
+ break;
+ default:
+ pixbuf = nm_icon_cache_get (nm_list_item_get_icon (item));
+ }
+
+ if (pixbuf)
+ gtk_status_icon_set_from_pixbuf (GTK_STATUS_ICON (user_data), pixbuf);
+}
+
+static void
+model_changed (NMStatusModel *model,
+ NMListItem *active_item,
+ gpointer user_data)
+{
+ NMStatusIcon *self = NM_STATUS_ICON (user_data);
+ NMStatusIconPrivate *priv = GET_PRIVATE (self);
+
+ if (active_item == priv->item)
+ return;
+
+ g_signal_handlers_disconnect_by_func (priv->item, item_status_changed, self);
+ priv->item = active_item;
+
+ if (active_item) {
+ g_signal_connect (active_item, "notify::" NM_LIST_ITEM_STATUS, G_CALLBACK (item_status_changed), self);
+ g_signal_connect (active_item, "notify::" NM_LIST_ITEM_ICON, G_CALLBACK (item_status_changed), self);
+ item_status_changed (active_item, NULL, self);
+ } else {
+ GdkPixbuf *pixbuf;
+
+ pixbuf = nm_icon_cache_get ("nm-no-connection");
+ if (pixbuf)
+ gtk_status_icon_set_from_pixbuf (GTK_STATUS_ICON (self), pixbuf);
+ }
+}
+
+/*****************************************************************************/
+
+static void
+nm_status_icon_init (NMStatusIcon *self)
+{
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMStatusIconPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_MODEL:
+ /* Construct only */
+ priv->model = g_value_dup_object (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)
+{
+ NMStatusIconPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_MODEL:
+ g_value_set_object (value, priv->model);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+constructed (GObject *object)
+{
+ NMStatusIconPrivate *priv = GET_PRIVATE (object);
+
+ if (G_OBJECT_CLASS (nm_status_icon_parent_class)->constructed)
+ G_OBJECT_CLASS (nm_status_icon_parent_class)->constructed (object);
+
+ g_signal_connect (priv->model, "changed", G_CALLBACK (model_changed), object);
+}
+
+static void
+dispose (GObject *object)
+{
+ NMStatusIconPrivate *priv = GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ if (priv->animation_id)
+ g_source_remove (priv->animation_id);
+
+ if (priv->model)
+ g_object_unref (priv->model);
+
+ priv->disposed = TRUE;
+ }
+
+ G_OBJECT_CLASS (nm_status_icon_parent_class)->dispose (object);
+}
+
+static void
+nm_status_icon_class_init (NMStatusIconClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (NMStatusIconPrivate));
+
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->constructed = constructed;
+ object_class->dispose = dispose;
+
+ /* Properties */
+ g_object_class_install_property
+ (object_class, PROP_MODEL,
+ g_param_spec_object (NM_STATUS_ICON_MODEL,
+ "NMStatusModel",
+ "NMStatusModel",
+ NM_TYPE_STATUS_MODEL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
diff --git a/libnm-gtk/nm-status-icon.h b/libnm-gtk/nm-status-icon.h
new file mode 100644
index 0000000..7dbc123
--- /dev/null
+++ b/libnm-gtk/nm-status-icon.h
@@ -0,0 +1,51 @@
+/* -*- 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 NM_STATUS_ICON_H
+#define NM_STATUS_ICON_H
+
+#include <gtk/gtk.h>
+#include <nm-status-model.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_STATUS_ICON (nm_status_icon_get_type ())
+#define NM_STATUS_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_STATUS_ICON, NMStatusIcon))
+#define NM_STATUS_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_STATUS_ICON, NMStatusIconClass))
+#define NM_IS_STATUS_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_STATUS_ICON))
+#define NM_IS_STATUS_ICON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_STATUS_ICON))
+#define NM_STATUS_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_STATUS_ICON, NMStatusIconClass))
+
+#define NM_STATUS_ICON_MODEL "model"
+
+typedef struct {
+ GtkStatusIcon parent;
+} NMStatusIcon;
+
+typedef struct {
+ GtkStatusIconClass parent;
+} NMStatusIconClass;
+
+GType nm_status_icon_get_type (void);
+
+GtkStatusIcon *nm_status_icon_new (NMStatusModel *model);
+
+G_END_DECLS
+
+#endif /* NM_STATUS_ICON_H */
diff --git a/libnm-gtk/nm-status-model.c b/libnm-gtk/nm-status-model.c
new file mode 100644
index 0000000..a0f482f
--- /dev/null
+++ b/libnm-gtk/nm-status-model.c
@@ -0,0 +1,126 @@
+/* -*- 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 "nm-status-model.h"
+
+G_DEFINE_TYPE (NMStatusModel, nm_status_model, GTK_TYPE_TREE_MODEL_FILTER)
+
+enum {
+ CHANGED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+GtkTreeModel *
+nm_status_model_new (GtkTreeModel *list_model)
+{
+ g_return_val_if_fail (GTK_IS_TREE_MODEL (list_model), NULL);
+
+ return (GtkTreeModel *) g_object_new (NM_TYPE_STATUS_MODEL,
+ "child-model", list_model,
+ NULL);
+}
+
+NMListItem *
+nm_status_model_get_active_item (NMStatusModel *self)
+{
+ NMListItem *item = NULL;
+ GtkTreeIter iter;
+
+ g_return_val_if_fail (NM_IS_STATUS_MODEL (self), NULL);
+
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (self), &iter))
+ gtk_tree_model_get (GTK_TREE_MODEL (self), &iter, NM_LIST_MODEL_COL_ITEM, &item, -1);
+
+ return item;
+}
+
+static void
+model_changed (NMStatusModel *self)
+{
+ NMListItem *item;
+
+ item = nm_status_model_get_active_item (self);
+ g_signal_emit (self, signals[CHANGED], 0, item);
+ g_object_unref (item);
+}
+
+static gboolean
+row_visible_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ NMListItem *item = NULL;
+ gboolean visible = FALSE;
+
+ gtk_tree_model_get (model, iter, NM_LIST_MODEL_COL_ITEM, &item, -1);
+ if (item) {
+ NMListItemStatus status;
+
+ status = nm_list_item_get_status (item);
+ g_object_unref (item);
+
+ if (status == NM_LIST_ITEM_STATUS_CONNECTED || status == NM_LIST_ITEM_STATUS_CONNECTING)
+ visible = TRUE;
+ }
+
+ return visible;
+}
+
+/*****************************************************************************/
+
+static void
+nm_status_model_init (NMStatusModel *self)
+{
+ gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (self),
+ row_visible_func, NULL, NULL);
+
+ g_signal_connect_swapped (self, "row-deleted", G_CALLBACK (model_changed), self);
+ g_signal_connect_swapped (self, "row-inserted", G_CALLBACK (model_changed), self);
+ g_signal_connect_swapped (self, "rows-reordered", G_CALLBACK (model_changed), self);
+}
+
+static void
+finalize (GObject *object)
+{
+ g_signal_handlers_disconnect_by_func (object, model_changed, object);
+
+ G_OBJECT_CLASS (nm_status_model_parent_class)->finalize (object);
+}
+
+static void
+nm_status_model_class_init (NMStatusModelClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = finalize;
+
+ /* Signals */
+ signals[CHANGED] =
+ g_signal_new ("changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMStatusModelClass, changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ NM_TYPE_LIST_ITEM);
+}
diff --git a/libnm-gtk/nm-status-model.h b/libnm-gtk/nm-status-model.h
new file mode 100644
index 0000000..38aed54
--- /dev/null
+++ b/libnm-gtk/nm-status-model.h
@@ -0,0 +1,55 @@
+/* -*- 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 NM_STATUS_MODEL_H
+#define NM_STATUS_MODEL_H
+
+#include <gtk/gtk.h>
+#include <nm-list-model.h>
+#include <nm-list-item.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_STATUS_MODEL (nm_status_model_get_type ())
+#define NM_STATUS_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_STATUS_MODEL, NMStatusModel))
+#define NM_STATUS_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_STATUS_MODEL, NMStatusModelClass))
+#define NM_IS_STATUS_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_STATUS_MODEL))
+#define NM_IS_STATUS_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_STATUS_MODEL))
+#define NM_STATUS_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_STATUS_MODEL, NMStatusModelClass))
+
+typedef struct {
+ GtkTreeModelFilter parent;
+} NMStatusModel;
+
+typedef struct {
+ GtkTreeModelFilterClass parent_class;
+
+ /* Signals */
+ void (*changed) (NMStatusModel *self,
+ NMListItem *active_item);
+} NMStatusModelClass;
+
+GType nm_status_model_get_type (void);
+
+GtkTreeModel *nm_status_model_new (GtkTreeModel *list_model);
+NMListItem *nm_status_model_get_active_item (NMStatusModel *self);
+
+G_END_DECLS
+
+#endif /* NM_STATUS_MODEL_H */
diff --git a/libnm-gtk/nm-wifi-item.c b/libnm-gtk/nm-wifi-item.c
new file mode 100644
index 0000000..1d6a780
--- /dev/null
+++ b/libnm-gtk/nm-wifi-item.c
@@ -0,0 +1,592 @@
+/* -*- 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 <glib/gi18n.h>
+#include <nm-setting-connection.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-wireless-security.h>
+#include <nm-setting-8021x.h>
+#include <nm-utils.h>
+#include "nm-wifi-item.h"
+#include "wireless-dialog.h"
+#include "nm-icon-cache.h"
+#include "utils.h"
+
+G_DEFINE_TYPE (NMWifiItem, nm_wifi_item, NM_TYPE_DEVICE_ITEM)
+
+enum {
+ PROP_0,
+ PROP_AP,
+
+ LAST_PROP
+};
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NM_TYPE_WIFI_ITEM, NMWifiItemPrivate))
+
+typedef struct {
+ GSList *ap_list;
+ NMAccessPoint *current_ap;
+
+ gboolean disposed;
+} NMWifiItemPrivate;
+
+NMListItem *
+nm_wifi_item_new (NMClient *client,
+ NMDeviceWifi *device,
+ NMAccessPoint *ap,
+ NMSettingsConnectionInterface *connection)
+{
+ g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL);
+ g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), NULL);
+
+ return (NMListItem *) g_object_new (NM_TYPE_WIFI_ITEM,
+ NM_LIST_ITEM_TYPE_NAME, _("WiFi"),
+ NM_CONNECTION_ITEM_CLIENT, client,
+ NM_CONNECTION_ITEM_CONNECTION, connection,
+ NM_DEVICE_ITEM_DEVICE, device,
+ NM_WIFI_ITEM_AP, ap,
+ NULL);
+}
+
+NMAccessPoint *
+nm_wifi_item_get_ap (NMWifiItem *self)
+{
+ g_return_val_if_fail (NM_IS_WIFI_ITEM (self), NULL);
+
+ return GET_PRIVATE (self)->current_ap;
+}
+
+static void
+update_icon (NMWifiItem *self)
+{
+ NMWifiItemPrivate *priv = GET_PRIVATE (self);
+ const char *icon;
+ guint strength;
+
+ strength = CLAMP (nm_access_point_get_strength (priv->current_ap), 0, 100);
+ if (strength > 80)
+ icon = "nm-signal-100-active";
+ else if (strength > 55)
+ icon = "nm-signal-75-active";
+ else if (strength > 30)
+ icon = "nm-signal-50-active";
+ else if (strength > 5)
+ icon = "nm-signal-25-active";
+ else
+ icon = "nm-signal-00-active";
+
+ if (icon)
+ g_object_set (self, NM_LIST_ITEM_ICON, icon, NULL);
+}
+
+static void
+update_current_ap (NMWifiItem *self)
+{
+ NMWifiItemPrivate *priv = GET_PRIVATE (self);
+ GSList *iter;
+
+ /* FIXME: If device is activated, use activation AP only */
+
+ for (iter = priv->ap_list; iter; iter = iter->next) {
+ NMAccessPoint *ap = (NMAccessPoint *) iter->data;
+
+ if (!priv->current_ap || nm_access_point_get_strength (priv->current_ap) < nm_access_point_get_strength (ap))
+ priv->current_ap = ap;
+ }
+
+ update_icon (self);
+}
+
+gboolean
+nm_wifi_item_add_ap (NMWifiItem *self,
+ NMAccessPoint *ap)
+{
+ NMWifiItemPrivate *priv;
+
+ g_return_val_if_fail (NM_IS_WIFI_ITEM (self), FALSE);
+ g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), FALSE);
+
+ priv = GET_PRIVATE (self);
+ if (priv->current_ap && !utils_access_point_is_compatible (priv->current_ap, ap))
+ return FALSE;
+
+ priv->ap_list = g_slist_prepend (priv->ap_list, g_object_ref (ap));
+ update_current_ap (self);
+
+ g_signal_connect_swapped (ap, "notify::" NM_ACCESS_POINT_STRENGTH, G_CALLBACK (update_current_ap), self);
+
+ return TRUE;
+}
+
+void
+nm_wifi_item_remove_ap (NMWifiItem *self,
+ NMAccessPoint *ap)
+{
+ NMWifiItemPrivate *priv;
+ GSList *iter;
+
+ g_return_if_fail (NM_IS_WIFI_ITEM (self));
+ g_return_if_fail (NM_IS_ACCESS_POINT (ap));
+
+ priv = GET_PRIVATE (self);
+ for (iter = priv->ap_list; iter; iter = iter->next) {
+ if (ap != iter->data)
+ continue;
+
+ g_signal_handlers_disconnect_matched (ap,
+ G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, update_current_ap, self);
+
+ priv->ap_list = g_slist_delete_link (priv->ap_list, iter);
+ g_object_unref (ap);
+
+ if (priv->ap_list)
+ update_current_ap (self);
+ else
+ /* No APs left, die */
+ nm_list_item_request_remove (NM_LIST_ITEM (self));
+
+ break;
+ }
+}
+
+static char *
+wifi_get_specific_object (NMDeviceItem *item)
+{
+ NMAccessPoint *ap;
+
+ ap = GET_PRIVATE (item)->current_ap;
+
+ return g_strdup (nm_object_get_path (NM_OBJECT (ap)));
+}
+
+static int
+priority (NMListItem *item)
+{
+ return NM_LIST_ITEM_PRIORITY_DEV_WIFI + NM_LIST_ITEM_CLASS (nm_wifi_item_parent_class)->priority (item);
+}
+
+static const char * default_ssid_list[] = {
+ "linksys",
+ "linksys-a",
+ "linksys-g",
+ "default",
+ "belkin54g",
+ "NETGEAR",
+ NULL
+};
+
+static gboolean
+is_manufacturer_default_ssid (const GByteArray *ssid)
+{
+ const char **default_ssid = default_ssid_list;
+
+ while (*default_ssid) {
+ if (ssid->len == strlen (*default_ssid)) {
+ if (!memcmp (*default_ssid, ssid->data, ssid->len))
+ return TRUE;
+ }
+ default_ssid++;
+ }
+ return FALSE;
+}
+
+static void
+add_ciphers_from_flags (NMSettingWirelessSecurity *sec,
+ guint32 flags,
+ gboolean pairwise)
+{
+ if (pairwise) {
+ if (flags & NM_802_11_AP_SEC_PAIR_TKIP)
+ nm_setting_wireless_security_add_pairwise (sec, "tkip");
+ if (flags & NM_802_11_AP_SEC_PAIR_CCMP)
+ nm_setting_wireless_security_add_pairwise (sec, "ccmp");
+ } else {
+ if (flags & NM_802_11_AP_SEC_GROUP_WEP40)
+ nm_setting_wireless_security_add_group (sec, "wep40");
+ if (flags & NM_802_11_AP_SEC_GROUP_WEP104)
+ nm_setting_wireless_security_add_group (sec, "wep104");
+ if (flags & NM_802_11_AP_SEC_GROUP_TKIP)
+ nm_setting_wireless_security_add_group (sec, "tkip");
+ if (flags & NM_802_11_AP_SEC_GROUP_CCMP)
+ nm_setting_wireless_security_add_group (sec, "ccmp");
+ }
+}
+
+static NMSettingWirelessSecurity *
+get_security_for_ap (NMAccessPoint *ap,
+ guint32 dev_caps,
+ gboolean *supported,
+ NMSetting8021x **s_8021x)
+{
+ NMSettingWirelessSecurity *sec;
+ NM80211Mode mode;
+ guint32 flags;
+ guint32 wpa_flags;
+ guint32 rsn_flags;
+
+ g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), NULL);
+ g_return_val_if_fail (supported != NULL, NULL);
+ g_return_val_if_fail (*supported == TRUE, NULL);
+ g_return_val_if_fail (s_8021x != NULL, NULL);
+ g_return_val_if_fail (*s_8021x == NULL, NULL);
+
+ sec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new ();
+
+ mode = nm_access_point_get_mode (ap);
+ flags = nm_access_point_get_flags (ap);
+ wpa_flags = nm_access_point_get_wpa_flags (ap);
+ rsn_flags = nm_access_point_get_rsn_flags (ap);
+
+ /* No security */
+ if ( !(flags & NM_802_11_AP_FLAGS_PRIVACY)
+ && (wpa_flags == NM_802_11_AP_SEC_NONE)
+ && (rsn_flags == NM_802_11_AP_SEC_NONE))
+ goto none;
+
+ /* Static WEP, Dynamic WEP, or LEAP */
+ if (flags & NM_802_11_AP_FLAGS_PRIVACY) {
+ if ((dev_caps & NM_WIFI_DEVICE_CAP_RSN) || (dev_caps & NM_WIFI_DEVICE_CAP_WPA)) {
+ /* If the device can do WPA/RSN but the AP has no WPA/RSN informatoin
+ * elements, it must be LEAP or static/dynamic WEP.
+ */
+ if ((wpa_flags == NM_802_11_AP_SEC_NONE) && (rsn_flags == NM_802_11_AP_SEC_NONE)) {
+ g_object_set (sec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none",
+ NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 0,
+ NULL);
+ return sec;
+ }
+ /* Otherwise, the AP supports WPA or RSN, which is preferred */
+ } else {
+ /* Device can't do WPA/RSN, but can at least pass through the
+ * WPA/RSN information elements from a scan. Since Privacy was
+ * advertised, LEAP or static/dynamic WEP must be in use.
+ */
+ g_object_set (sec,
+ NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "none",
+ NM_SETTING_WIRELESS_SECURITY_WEP_TX_KEYIDX, 0,
+ NULL);
+ return sec;
+ }
+ }
+
+ /* Stuff after this point requires infrastructure */
+ if (mode != NM_802_11_MODE_INFRA) {
+ *supported = FALSE;
+ goto none;
+ }
+
+ /* WPA2 PSK first */
+ if ( (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)
+ && (dev_caps & NM_WIFI_DEVICE_CAP_RSN)) {
+ g_object_set (sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", NULL);
+ nm_setting_wireless_security_add_proto (sec, "rsn");
+ add_ciphers_from_flags (sec, rsn_flags, TRUE);
+ add_ciphers_from_flags (sec, rsn_flags, FALSE);
+ return sec;
+ }
+
+ /* WPA PSK */
+ if ( (wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK)
+ && (dev_caps & NM_WIFI_DEVICE_CAP_WPA)) {
+ g_object_set (sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-psk", NULL);
+ nm_setting_wireless_security_add_proto (sec, "wpa");
+ add_ciphers_from_flags (sec, wpa_flags, TRUE);
+ add_ciphers_from_flags (sec, wpa_flags, FALSE);
+ return sec;
+ }
+
+ /* WPA2 Enterprise */
+ if ( (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
+ && (dev_caps & NM_WIFI_DEVICE_CAP_RSN)) {
+ g_object_set (sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", NULL);
+ nm_setting_wireless_security_add_proto (sec, "rsn");
+ add_ciphers_from_flags (sec, rsn_flags, TRUE);
+ add_ciphers_from_flags (sec, rsn_flags, FALSE);
+
+ *s_8021x = NM_SETTING_802_1X (nm_setting_802_1x_new ());
+ nm_setting_802_1x_add_eap_method (*s_8021x, "ttls");
+ g_object_set (*s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", NULL);
+ return sec;
+ }
+
+ /* WPA Enterprise */
+ if ( (wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
+ && (dev_caps & NM_WIFI_DEVICE_CAP_WPA)) {
+ g_object_set (sec, NM_SETTING_WIRELESS_SECURITY_KEY_MGMT, "wpa-eap", NULL);
+ nm_setting_wireless_security_add_proto (sec, "wpa");
+ add_ciphers_from_flags (sec, wpa_flags, TRUE);
+ add_ciphers_from_flags (sec, wpa_flags, FALSE);
+
+ *s_8021x = NM_SETTING_802_1X (nm_setting_802_1x_new ());
+ nm_setting_802_1x_add_eap_method (*s_8021x, "ttls");
+ g_object_set (*s_8021x, NM_SETTING_802_1X_PHASE2_AUTH, "mschapv2", NULL);
+ return sec;
+ }
+
+ *supported = FALSE;
+
+ none:
+ g_object_unref (sec);
+ return NULL;
+}
+
+static NMConnection *
+create_new_connection (NMDeviceWifi *device, NMAccessPoint *ap)
+{
+ NMConnection *connection;
+ NMSettingConnection *s_con;
+ NMSettingWireless *s_wireless;
+ NMSettingWirelessSecurity *s_wireless_sec;
+ NMSetting8021x *s_8021x = NULL;
+ const GByteArray *ap_ssid;
+ char *id;
+ char buf[33];
+ int buf_len;
+ NM80211Mode mode;
+ guint32 dev_caps;
+ gboolean supported = TRUE;
+
+ dev_caps = nm_device_wifi_get_capabilities (device);
+ s_wireless_sec = get_security_for_ap (ap, dev_caps, &supported, &s_8021x);
+ if (!supported)
+ return NULL;
+
+ s_wireless = NM_SETTING_WIRELESS (nm_setting_wireless_new ());
+ ap_ssid = nm_access_point_get_ssid (ap);
+ g_object_set (s_wireless, NM_SETTING_WIRELESS_SSID, ap_ssid, NULL);
+
+ mode = nm_access_point_get_mode (ap);
+ if (mode == NM_802_11_MODE_ADHOC)
+ g_object_set (s_wireless, NM_SETTING_WIRELESS_MODE, "adhoc", NULL);
+ else if (mode == NM_802_11_MODE_INFRA)
+ g_object_set (s_wireless, NM_SETTING_WIRELESS_MODE, "infrastructure", NULL);
+ else
+ g_assert_not_reached ();
+
+ connection = nm_connection_new ();
+ nm_connection_add_setting (connection, NM_SETTING (s_wireless));
+ if (s_wireless_sec) {
+ g_object_set (s_wireless, NM_SETTING_WIRELESS_SEC, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME, NULL);
+ nm_connection_add_setting (connection, NM_SETTING (s_wireless_sec));
+ }
+ if (s_8021x)
+ nm_connection_add_setting (connection, NM_SETTING (s_8021x));
+
+ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
+ g_object_set (s_con,
+ NM_SETTING_CONNECTION_TYPE, nm_setting_get_name (NM_SETTING (s_wireless)),
+ NM_SETTING_CONNECTION_AUTOCONNECT, !is_manufacturer_default_ssid (ap_ssid),
+ NULL);
+
+ memset (buf, 0, sizeof (buf));
+ buf_len = MIN (ap_ssid->len, sizeof (buf) - 1);
+ memcpy (buf, ap_ssid->data, buf_len);
+ id = nm_utils_ssid_to_utf8 (buf, buf_len);
+ g_object_set (s_con, NM_SETTING_CONNECTION_ID, id, NULL);
+ g_free (id);
+
+ id = nm_utils_uuid_generate ();
+ g_object_set (s_con, NM_SETTING_CONNECTION_UUID, id, NULL);
+ g_free (id);
+
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+
+ return connection;
+}
+
+static void
+wireless_dialog_response_cb (NMAWirelessDialog *dialog,
+ gint response,
+ gpointer user_data)
+{
+ gtk_widget_hide (GTK_WIDGET (dialog));
+
+ if (response == GTK_RESPONSE_OK)
+ nm_connection_item_new_connection (NM_CONNECTION_ITEM (user_data),
+ nma_wireless_dialog_get_connection (dialog),
+ TRUE);
+
+ gtk_widget_destroy (GTK_WIDGET (dialog));
+}
+
+static void
+connect (NMListItem *item)
+{
+ NMConnection *connection;
+ NMDeviceWifi *device;
+ NMAccessPoint *ap;
+
+ connection = (NMConnection *) nm_connection_item_get_connection (NM_CONNECTION_ITEM (item));
+ if (connection) {
+ NM_LIST_ITEM_CLASS (nm_wifi_item_parent_class)->connect (item);
+ return;
+ }
+
+ /* We don't have a connection yet, so create one */
+
+ device = NM_DEVICE_WIFI (nm_device_item_get_device (NM_DEVICE_ITEM (item)));
+ ap = nm_wifi_item_get_ap (NM_WIFI_ITEM (item));
+
+ connection = create_new_connection (device, ap);
+ if (!connection)
+ return;
+
+ if (nm_connection_need_secrets (connection, NULL)) {
+ GtkWidget *dialog;
+
+ dialog = nma_wireless_dialog_new (nm_connection_item_get_client (NM_CONNECTION_ITEM (item)),
+ connection, NM_DEVICE (device), ap);
+ g_signal_connect (dialog, "done", G_CALLBACK (wireless_dialog_response_cb), item);
+ nma_wireless_dialog_show (NMA_WIRELESS_DIALOG (dialog));
+ } else
+ nm_connection_item_new_connection (NM_CONNECTION_ITEM (item), connection, TRUE);
+
+ g_object_unref (connection);
+}
+
+/*****************************************************************************/
+
+static void
+nm_wifi_item_init (NMWifiItem *self)
+{
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMWifiItem *self = NM_WIFI_ITEM (object);
+
+ switch (prop_id) {
+ case PROP_AP:
+ /* Construct only */
+ nm_wifi_item_add_ap (self, NM_ACCESS_POINT (g_value_dup_object (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)
+{
+ NMWifiItemPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_AP:
+ g_value_set_object (value, priv->current_ap);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+constructed (GObject *object)
+{
+ NMWifiItemPrivate *priv = GET_PRIVATE (object);
+ const GByteArray *ssid;
+ char *str;
+ guint32 flags;
+ guint32 wpa_flags;
+ guint32 rsn_flags;
+
+ if (G_OBJECT_CLASS (nm_wifi_item_parent_class)->constructed)
+ G_OBJECT_CLASS (nm_wifi_item_parent_class)->constructed (object);
+
+ ssid = nm_access_point_get_ssid (priv->current_ap);
+ str = nm_utils_ssid_to_utf8 ((char *) ssid->data, ssid->len);
+ g_object_set (object, NM_LIST_ITEM_NAME, str, NULL);
+ g_free (str);
+
+ flags = nm_access_point_get_flags (priv->current_ap);
+ wpa_flags = nm_access_point_get_wpa_flags (priv->current_ap);
+ rsn_flags = nm_access_point_get_rsn_flags (priv->current_ap);
+
+ if (rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK ||
+ wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_PSK ||
+ rsn_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X ||
+ wpa_flags & NM_802_11_AP_SEC_KEY_MGMT_802_1X)
+ str = "WPA encrypted";
+ else if (flags & NM_802_11_AP_FLAGS_PRIVACY)
+ str = "WEP encrypted";
+ else
+ str = NULL;
+
+ if (str)
+ g_object_set (object, NM_LIST_ITEM_SECURITY, str, NULL);
+}
+
+static void
+dispose (GObject *object)
+{
+ NMWifiItemPrivate *priv = GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ while (priv->ap_list) {
+ NMAccessPoint *ap = (NMAccessPoint *) priv->ap_list->data;
+
+ g_signal_handlers_disconnect_matched (ap,
+ G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, update_current_ap, object);
+ g_object_unref (ap);
+ priv->ap_list = g_slist_delete_link (priv->ap_list, priv->ap_list);
+ }
+
+ priv->disposed = TRUE;
+ }
+
+ G_OBJECT_CLASS (nm_wifi_item_parent_class)->dispose (object);
+}
+
+
+static void
+nm_wifi_item_class_init (NMWifiItemClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMListItemClass *list_class = NM_LIST_ITEM_CLASS (klass);
+ NMDeviceItemClass *device_class = NM_DEVICE_ITEM_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (NMWifiItemPrivate));
+
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->constructed = constructed;
+ object_class->dispose = dispose;
+
+ list_class->priority = priority;
+ list_class->connect = connect;
+
+ device_class->get_specific_object = wifi_get_specific_object;
+
+ /* Properties */
+ g_object_class_install_property
+ (object_class, PROP_AP,
+ g_param_spec_object (NM_WIFI_ITEM_AP,
+ "NMAccessPoint",
+ "NMAccessPoint",
+ NM_TYPE_ACCESS_POINT,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
diff --git a/libnm-gtk/nm-wifi-item.h b/libnm-gtk/nm-wifi-item.h
new file mode 100644
index 0000000..d9c0745
--- /dev/null
+++ b/libnm-gtk/nm-wifi-item.h
@@ -0,0 +1,63 @@
+/* -*- 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 NM_WIFI_ITEM_H
+#define NM_WIFI_ITEM_H
+
+#include <glib-object.h>
+#include <nm-device-wifi.h>
+#include <nm-device-item.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_WIFI_ITEM (nm_wifi_item_get_type ())
+#define NM_WIFI_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIFI_ITEM, NMWifiItem))
+#define NM_WIFI_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIFI_ITEM, NMWifiItemClass))
+#define NM_IS_WIFI_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIFI_ITEM))
+#define NM_IS_WIFI_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_WIFI_ITEM))
+#define NM_WIFI_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIFI_ITEM, NMWifiItemClass))
+
+#define NM_WIFI_ITEM_AP "ap"
+
+typedef struct {
+ NMDeviceItem parent;
+} NMWifiItem;
+
+typedef struct {
+ NMDeviceItemClass parent_class;
+} NMWifiItemClass;
+
+GType nm_wifi_item_get_type (void);
+
+NMListItem *nm_wifi_item_new (NMClient *client,
+ NMDeviceWifi *device,
+ NMAccessPoint *ap,
+ NMSettingsConnectionInterface *connection);
+
+NMAccessPoint *nm_wifi_item_get_ap (NMWifiItem *self);
+
+gboolean nm_wifi_item_add_ap (NMWifiItem *self,
+ NMAccessPoint *ap);
+
+void nm_wifi_item_remove_ap (NMWifiItem *self,
+ NMAccessPoint *ap);
+
+G_END_DECLS
+
+#endif /* NM_WIFI_ITEM_H */
diff --git a/libnm-gtk/nm-wifi-provider.c b/libnm-gtk/nm-wifi-provider.c
new file mode 100644
index 0000000..6a60704
--- /dev/null
+++ b/libnm-gtk/nm-wifi-provider.c
@@ -0,0 +1,229 @@
+/* -*- 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 <nm-utils.h>
+#include "nm-wifi-provider.h"
+#include "nm-wifi-item.h"
+#include "utils.h"
+
+G_DEFINE_TYPE (NMWifiProvider, nm_wifi_provider, NM_TYPE_DEVICE_PROVIDER)
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NM_TYPE_WIFI_PROVIDER, NMWifiProviderPrivate))
+
+typedef struct {
+ gulong ap_added_id;
+ gulong ap_removed_id;
+
+ gboolean disposed;
+} NMWifiProviderPrivate;
+
+NMItemProvider *
+nm_wifi_provider_new (NMClient *client,
+ NMDeviceWifi *device)
+{
+ g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
+ g_return_val_if_fail (NM_IS_DEVICE_WIFI (device), NULL);
+
+ return (NMItemProvider *) g_object_new (NM_TYPE_WIFI_PROVIDER,
+ NM_ITEM_PROVIDER_CLIENT, client,
+ NM_DEVICE_PROVIDER_DEVICE, device,
+ NULL);
+}
+
+static void
+wifi_added (NMItemProvider *provider,
+ NMSettingsConnectionInterface *connection)
+{
+ NMDeviceProvider *device_provider = NM_DEVICE_PROVIDER (provider);
+ NMDeviceWifi *device;
+ GSList *list;
+ GSList *iter;
+ const GPtrArray *ap_list;
+ int i;
+
+ if (!nm_device_provider_ready (device_provider))
+ return;
+
+ device = NM_DEVICE_WIFI (nm_device_provider_get_device (device_provider));
+
+ /* First, see if we have an AP item already which has
+ no connection and is compatible with this connection */
+ list = nm_item_provider_get_items (provider);
+ for (iter = list; iter; iter = iter->next) {
+ NMListItem *item = (NMListItem *) iter->data;
+ NMSettingsConnectionInterface *item_connection;
+ NMAccessPoint *ap;
+
+ item_connection = nm_connection_item_get_connection (NM_CONNECTION_ITEM (item));
+ if (item_connection == connection) {
+ /* Already have this same connection why do we get called??? */
+ g_warning ("Connection already in the list, something is broken");
+ return;
+ }
+
+ if (item_connection)
+ continue;
+
+ ap = nm_wifi_item_get_ap (NM_WIFI_ITEM (item));
+ if (utils_connection_valid_for_device (NM_CONNECTION (connection), NM_DEVICE (device), ap)) {
+ g_debug ("Found connection for item %s", nm_list_item_get_name (item));
+ g_object_set (item, NM_CONNECTION_ITEM_CONNECTION, connection, NULL);
+ return;
+ }
+ }
+
+ /* That didn't work. let's see if we have a compatible AP so we can still
+ show this connection. This happens when there's multiple connections which
+ match an AP and we want to have an item for each connection */
+
+ ap_list = nm_device_wifi_get_access_points (device);
+ for (i = 0; ap_list && ap_list->len > i; i++) {
+ NMAccessPoint *ap = (NMAccessPoint *) g_ptr_array_index (ap_list, i);
+
+ if (utils_connection_valid_for_device (NM_CONNECTION (connection), NM_DEVICE (device), ap)) {
+ NMListItem *item;
+
+ g_debug ("Created new item for connection");
+ item = nm_wifi_item_new (nm_item_provider_get_client (provider), device, ap, connection);
+ nm_item_provider_item_added (provider, item);
+ break;
+ }
+ }
+}
+
+static void
+ap_added (NMDeviceWifi *device,
+ NMAccessPoint *ap,
+ gpointer user_data)
+{
+ NMItemProvider *provider = NM_ITEM_PROVIDER (user_data);
+ const GByteArray *ssid;
+ GSList *list;
+ GSList *iter;
+ NMListItem *item;
+ gboolean added = FALSE;
+
+ /* Don't add BSSs that hide their SSID */
+ ssid = nm_access_point_get_ssid (ap);
+ if (!ssid || nm_utils_is_empty_ssid (ssid->data, ssid->len))
+ return;
+
+ /* First, check if any existing item already has a compatible AP */
+ list = nm_item_provider_get_items (provider);
+ for (iter = list; iter; iter = iter->next) {
+ NMWifiItem *wifi_item = (NMWifiItem *) iter->data;
+
+ if (nm_wifi_item_add_ap (wifi_item, ap))
+ added = TRUE;
+ }
+
+ if (added)
+ return;
+
+ /* It was not compatible with any existing item, see if we
+ * have a connection for this AP */
+ list = nm_item_provider_get_connections (provider);
+ for (iter = list; iter; iter = iter->next) {
+ NMSettingsConnectionInterface *connection = (NMSettingsConnectionInterface *) iter->data;
+
+ if (!utils_connection_valid_for_device (NM_CONNECTION (connection), NM_DEVICE (device), ap))
+ continue;
+
+ item = nm_wifi_item_new (nm_item_provider_get_client (provider), device, ap, connection);
+ nm_item_provider_item_added (provider, item);
+ added = TRUE;
+ }
+
+ g_slist_free (list);
+
+ if (added)
+ return;
+
+ /* There's no connection for this AP. Create a connectionless item */
+ item = nm_wifi_item_new (nm_item_provider_get_client (provider), device, ap, NULL);
+ nm_item_provider_item_added (provider, item);
+}
+
+static void
+ap_removed (NMDeviceWifi *device,
+ NMAccessPoint *ap,
+ gpointer user_data)
+{
+ g_slist_foreach (nm_item_provider_get_items (NM_ITEM_PROVIDER (user_data)),
+ (GFunc) nm_wifi_item_remove_ap, ap);
+}
+
+/*****************************************************************************/
+
+static void
+nm_wifi_provider_init (NMWifiProvider *self)
+{
+}
+
+static void
+constructed (GObject *object)
+{
+ NMWifiProviderPrivate *priv = GET_PRIVATE (object);
+ NMDeviceWifi *device;
+ const GPtrArray *ap_list;
+ int i;
+
+ if (G_OBJECT_CLASS (nm_wifi_provider_parent_class)->constructed)
+ G_OBJECT_CLASS (nm_wifi_provider_parent_class)->constructed (object);
+
+ device = NM_DEVICE_WIFI (nm_device_provider_get_device (NM_DEVICE_PROVIDER (object)));
+ priv->ap_added_id = g_signal_connect (device, "access-point-added", G_CALLBACK (ap_added), object);
+ priv->ap_removed_id = g_signal_connect (device, "access-point-removed", G_CALLBACK (ap_removed), object);
+
+ ap_list = nm_device_wifi_get_access_points (device);
+ for (i = 0; ap_list && ap_list->len > i; i++)
+ ap_added (device, (NMAccessPoint *) g_ptr_array_index (ap_list, i), object);
+}
+
+static void
+dispose (GObject *object)
+{
+ NMWifiProviderPrivate *priv = GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ NMDevice *device;
+
+ device = nm_device_provider_get_device (NM_DEVICE_PROVIDER (object));
+ g_signal_handler_disconnect (device, priv->ap_added_id);
+ g_signal_handler_disconnect (device, priv->ap_removed_id);
+
+ priv->disposed = TRUE;
+ }
+
+ G_OBJECT_CLASS (nm_wifi_provider_parent_class)->dispose (object);
+}
+
+static void
+nm_wifi_provider_class_init (NMWifiProviderClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ NMItemProviderClass *item_class = NM_ITEM_PROVIDER_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (NMWifiProviderPrivate));
+
+ object_class->constructed = constructed;
+ object_class->dispose = dispose;
+
+ item_class->connection_added = wifi_added;
+}
diff --git a/libnm-gtk/nm-wifi-provider.h b/libnm-gtk/nm-wifi-provider.h
new file mode 100644
index 0000000..78d6890
--- /dev/null
+++ b/libnm-gtk/nm-wifi-provider.h
@@ -0,0 +1,51 @@
+/* -*- 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 NM_WIFI_PROVIDER_H
+#define NM_WIFI_PROVIDER_H
+
+#include <glib-object.h>
+#include <nm-device-wifi.h>
+#include <nm-device-provider.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_WIFI_PROVIDER (nm_wifi_provider_get_type ())
+#define NM_WIFI_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIFI_PROVIDER, NMWifiProvider))
+#define NM_WIFI_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIFI_PROVIDER, NMWifiProviderClass))
+#define NM_IS_WIFI_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIFI_PROVIDER))
+#define NM_IS_WIFI_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_WIFI_PROVIDER))
+#define NM_WIFI_PROVIDER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIFI_PROVIDER, NMWifiProviderClass))
+
+typedef struct {
+ NMDeviceProvider parent;
+} NMWifiProvider;
+
+typedef struct {
+ NMDeviceProviderClass parent_class;
+} NMWifiProviderClass;
+
+GType nm_wifi_provider_get_type (void);
+
+NMItemProvider *nm_wifi_provider_new (NMClient *client,
+ NMDeviceWifi *device);
+
+G_END_DECLS
+
+#endif /* NM_WIFI_PROVIDER_H */
diff --git a/libnm-gtk/test.c b/libnm-gtk/test.c
new file mode 100644
index 0000000..1e7de4c
--- /dev/null
+++ b/libnm-gtk/test.c
@@ -0,0 +1,224 @@
+/* -*- 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 <gtk/gtk.h>
+#include <nm-client.h>
+#include <nm-remote-settings-system.h>
+#include "nm-list-model.h"
+#include "nm-device-model.h"
+#include "nm-status-icon.h"
+#include "nm-connection-model.h"
+#include "nm-gconf-settings.h"
+
+static void
+setup_status_icon (NMListModel *model)
+{
+ NMStatusModel *status_model;
+ GtkStatusIcon *status_icon;
+
+ status_model = NM_STATUS_MODEL (nm_status_model_new (GTK_TREE_MODEL (model)));
+ status_icon = nm_status_icon_new (status_model);
+ g_object_unref (status_model);
+}
+
+static GtkWidget *
+create_device_combo (void)
+{
+ GtkWidget *combo;
+ GtkCellRenderer *renderer;
+
+ combo = gtk_combo_box_new ();
+
+ gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo));
+
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer,
+ "pixbuf", NM_DEVICE_MODEL_COL_ICON);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer,
+ "text", NM_DEVICE_MODEL_COL_IFACE);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
+ gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer,
+ "text", NM_DEVICE_MODEL_COL_DESCRIPTION);
+
+ return combo;
+}
+
+static GtkWidget *
+create_connection_tree (void)
+{
+ GtkWidget *tree;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ tree = gtk_tree_view_new ();
+
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes ("Name",
+ renderer,
+ "text", NM_CONNECTION_MODEL_COL_NAME,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
+
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes ("Type",
+ renderer,
+ "text", NM_CONNECTION_MODEL_COL_TYPE,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
+
+ return tree;
+}
+
+static GtkWidget *
+create_list_tree (void)
+{
+ GtkWidget *tree;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ tree = gtk_tree_view_new ();
+
+ renderer = gtk_cell_renderer_pixbuf_new ();
+ column = gtk_tree_view_column_new_with_attributes ("Icon",
+ renderer,
+ "icon-name", NM_LIST_MODEL_COL_ICON,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
+
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes ("Name",
+ renderer,
+ "text", NM_LIST_MODEL_COL_NAME,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
+
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes ("Security",
+ renderer,
+ "text", NM_LIST_MODEL_COL_SECURITY,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
+
+ renderer = gtk_cell_renderer_text_new ();
+ column = gtk_tree_view_column_new_with_attributes ("Status",
+ renderer,
+ "text", NM_LIST_MODEL_COL_STATUS,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
+
+ renderer = gtk_cell_renderer_toggle_new ();
+ column = gtk_tree_view_column_new_with_attributes ("Show delete",
+ renderer,
+ "active", NM_LIST_MODEL_COL_SHOW_DELETE,
+ NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (tree), column);
+
+ return tree;
+}
+
+static void
+do_stuff (void)
+{
+ NMClient *client;
+ DBusGConnection *bus;
+ NMSettingsInterface *user_settings;
+ NMSettingsInterface *system_settings;
+ GtkTreeModel *model;
+ GtkWidget *tree;
+ GtkWidget *scrolled;
+ GtkWidget *window;
+ GtkWidget *box;
+
+ /* Window setup */
+ window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_default_size (GTK_WINDOW (window), 400, 400);
+ g_signal_connect (window, "delete-event", G_CALLBACK (gtk_main_quit), NULL);
+ box = gtk_vbox_new (FALSE, 6);
+ gtk_container_add (GTK_CONTAINER (window), box);
+
+ client = nm_client_new ();
+ bus = nm_object_get_connection (NM_OBJECT (client));
+ system_settings = (NMSettingsInterface *) nm_remote_settings_system_new (bus);
+ user_settings = (NMSettingsInterface *) nm_gconf_settings_new (bus);
+
+ /* Device model/tree */
+ model = GTK_TREE_MODEL (nm_device_model_new (client));
+ tree = create_device_combo ();
+ gtk_combo_box_set_model (GTK_COMBO_BOX (tree), model);
+ g_object_unref (model);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (tree), 0);
+ gtk_box_pack_start (GTK_BOX (box), tree, FALSE, TRUE, 0);
+
+ /* Connection model/tree */
+ model = nm_connection_model_new ();
+ nm_connection_model_add_settings (NM_CONNECTION_MODEL (model), user_settings);
+ nm_connection_model_add_settings (NM_CONNECTION_MODEL (model), system_settings);
+
+ tree = create_connection_tree ();
+ gtk_tree_view_set_model (GTK_TREE_VIEW (tree), model);
+ g_object_unref (model);
+ scrolled = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ gtk_container_add (GTK_CONTAINER (scrolled), tree);
+ gtk_box_pack_start (GTK_BOX (box), scrolled, TRUE, TRUE, 0);
+
+ /* List model/tree */
+ model = GTK_TREE_MODEL (nm_list_model_new (client));
+ nm_list_model_add_settings (NM_LIST_MODEL (model), user_settings);
+ nm_list_model_add_settings (NM_LIST_MODEL (model), system_settings);
+
+ tree = create_list_tree ();
+ gtk_tree_view_set_model (GTK_TREE_VIEW (tree), model);
+ setup_status_icon (NM_LIST_MODEL (model));
+ g_object_unref (model);
+
+ scrolled = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+ gtk_container_add (GTK_CONTAINER (scrolled), tree);
+ gtk_box_pack_start (GTK_BOX (box), scrolled, TRUE, TRUE, 0);
+
+ gtk_widget_show_all (window);
+
+ g_object_unref (user_settings);
+ g_object_unref (system_settings);
+ g_object_unref (client);
+}
+
+int
+main (int argc, char *argv[])
+{
+ gtk_init (&argc, &argv);
+
+ do_stuff ();
+ gtk_main ();
+
+ return 0;
+}
diff --git a/libnm-gtk/utils.c b/libnm-gtk/utils.c
new file mode 100644
index 0000000..80fd194
--- /dev/null
+++ b/libnm-gtk/utils.c
@@ -0,0 +1,856 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
+ *
+ * Dan Williams <dcbw redhat com>
+ *
+ * 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 2007 Red Hat, Inc.
+ */
+
+#include <string.h>
+#include <netinet/ether.h>
+#include <glib.h>
+#include <nm-device-ethernet.h>
+#include <nm-device-wifi.h>
+#include <nm-device-bt.h>
+#include <nm-gsm-device.h>
+#include <nm-cdma-device.h>
+#include <nm-access-point.h>
+
+#include <nm-setting-connection.h>
+#include <nm-setting-wired.h>
+#include <nm-setting-wireless.h>
+#include <nm-setting-wireless-security.h>
+#include <nm-setting-8021x.h>
+#include <nm-setting-gsm.h>
+#include <nm-setting-cdma.h>
+#include <nm-setting-pppoe.h>
+#include <nm-setting-bluetooth.h>
+#include <nm-utils.h>
+
+#include "utils.h"
+
+/*
+ * utils_bin2hexstr
+ *
+ * Convert a byte-array into a hexadecimal string.
+ *
+ * Code originally by Alex Larsson <alexl redhat com> and
+ * copyright Red Hat, Inc. under terms of the LGPL.
+ *
+ */
+char *
+utils_bin2hexstr (const char *bytes, int len, int final_len)
+{
+ static char hex_digits[] = "0123456789abcdef";
+ char * result;
+ int i;
+
+ g_return_val_if_fail (bytes != NULL, NULL);
+ g_return_val_if_fail (len > 0, NULL);
+ g_return_val_if_fail (len < 256, NULL); /* Arbitrary limit */
+
+ result = g_malloc0 (len * 2 + 1);
+ for (i = 0; i < len; i++)
+ {
+ result[2*i] = hex_digits[(bytes[i] >> 4) & 0xf];
+ result[2*i+1] = hex_digits[bytes[i] & 0xf];
+ }
+ /* Cut converted key off at the correct length for this cipher type */
+ if (final_len > -1)
+ result[final_len] = '\0';
+
+ return result;
+}
+
+static char *ignored_words[] = {
+ "Semiconductor",
+ "Components",
+ "Corporation",
+ "Communications",
+ "Company",
+ "Corp.",
+ "Corp",
+ "Co.",
+ "Inc.",
+ "Inc",
+ "Ltd.",
+ "Limited.",
+ "Intel?",
+ "chipset",
+ "adapter",
+ "[hex]",
+ "NDIS",
+ "Module",
+ NULL
+};
+
+static char *ignored_phrases[] = {
+ "Multiprotocol MAC/baseband processor",
+ "Wireless LAN Controller",
+ "Wireless LAN Adapter",
+ "Wireless Adapter",
+ "Network Connection",
+ "Wireless Cardbus Adapter",
+ "Wireless CardBus Adapter",
+ "54 Mbps Wireless PC Card",
+ "Wireless PC Card",
+ "Wireless PC",
+ "PC Card with XJACK(r) Antenna",
+ "Wireless cardbus",
+ "Wireless LAN PC Card",
+ "Technology Group Ltd.",
+ "Communication S.p.A.",
+ "Business Mobile Networks BV",
+ "Mobile Broadband Minicard Composite Device",
+ "Mobile Communications AB",
+ NULL
+};
+
+static char *
+fixup_desc_string (const char *desc)
+{
+ char *p, *temp;
+ char **words, **item;
+ GString *str;
+
+ p = temp = g_strdup (desc);
+ while (*p) {
+ if (*p == '_' || *p == ',')
+ *p = ' ';
+ p++;
+ }
+
+ /* Attempt to shorten ID by ignoring certain phrases */
+ for (item = ignored_phrases; *item; item++) {
+ guint32 ignored_len = strlen (*item);
+
+ p = strstr (temp, *item);
+ if (p)
+ memmove (p, p + ignored_len, strlen (p + ignored_len) + 1); /* +1 for the \0 */
+ }
+
+ /* Attmept to shorten ID by ignoring certain individual words */
+ words = g_strsplit (temp, " ", 0);
+ str = g_string_new_len (NULL, strlen (temp));
+ g_free (temp);
+
+ for (item = words; *item; item++) {
+ int i = 0;
+ gboolean ignore = FALSE;
+
+ if (g_ascii_isspace (**item) || (**item == '\0'))
+ continue;
+
+ while (ignored_words[i] && !ignore) {
+ if (!strcmp (*item, ignored_words[i]))
+ ignore = TRUE;
+ i++;
+ }
+
+ if (!ignore) {
+ if (str->len)
+ g_string_append_c (str, ' ');
+ g_string_append (str, *item);
+ }
+ }
+ g_strfreev (words);
+
+ temp = str->str;
+ g_string_free (str, FALSE);
+
+ return temp;
+}
+
+#define DESC_TAG "description"
+
+const char *
+utils_get_device_description (NMDevice *device)
+{
+ char *description = NULL;
+ const char *dev_product;
+ const char *dev_vendor;
+ char *product = NULL;
+ char *vendor = NULL;
+ GString *str;
+
+ g_return_val_if_fail (device != NULL, NULL);
+
+ description = g_object_get_data (G_OBJECT (device), DESC_TAG);
+ if (description)
+ return description;
+
+ dev_product = nm_device_get_product (device);
+ dev_vendor = nm_device_get_vendor (device);
+ if (!dev_product || !dev_vendor)
+ return NULL;
+
+ product = fixup_desc_string (dev_product);
+ vendor = fixup_desc_string (dev_vendor);
+
+ str = g_string_new_len (NULL, strlen (vendor) + strlen (product) + 1);
+
+ g_string_append (str, vendor);
+ g_free (vendor);
+
+ g_string_append_c (str, ' ');
+ g_string_append (str, product);
+ g_free (product);
+
+ description = str->str;
+ g_string_free (str, FALSE);
+
+ g_object_set_data_full (G_OBJECT (device),
+ "description", description,
+ (GDestroyNotify) g_free);
+
+ return description;
+}
+
+struct cf_pair {
+ guint32 chan;
+ guint32 freq;
+};
+
+static struct cf_pair a_table[] = {
+ /* A band */
+ { 7, 5035 },
+ { 8, 5040 },
+ { 9, 5045 },
+ { 11, 5055 },
+ { 12, 5060 },
+ { 16, 5080 },
+ { 34, 5170 },
+ { 36, 5180 },
+ { 38, 5190 },
+ { 40, 5200 },
+ { 42, 5210 },
+ { 44, 5220 },
+ { 46, 5230 },
+ { 48, 5240 },
+ { 50, 5250 },
+ { 52, 5260 },
+ { 56, 5280 },
+ { 58, 5290 },
+ { 60, 5300 },
+ { 64, 5320 },
+ { 100, 5500 },
+ { 104, 5520 },
+ { 108, 5540 },
+ { 112, 5560 },
+ { 116, 5580 },
+ { 120, 5600 },
+ { 124, 5620 },
+ { 128, 5640 },
+ { 132, 5660 },
+ { 136, 5680 },
+ { 140, 5700 },
+ { 149, 5745 },
+ { 152, 5760 },
+ { 153, 5765 },
+ { 157, 5785 },
+ { 160, 5800 },
+ { 161, 5805 },
+ { 165, 5825 },
+ { 183, 4915 },
+ { 184, 4920 },
+ { 185, 4925 },
+ { 187, 4935 },
+ { 188, 4945 },
+ { 192, 4960 },
+ { 196, 4980 },
+ { 0, -1 }
+};
+
+static struct cf_pair bg_table[] = {
+ /* B/G band */
+ { 1, 2412 },
+ { 2, 2417 },
+ { 3, 2422 },
+ { 4, 2427 },
+ { 5, 2432 },
+ { 6, 2437 },
+ { 7, 2442 },
+ { 8, 2447 },
+ { 9, 2452 },
+ { 10, 2457 },
+ { 11, 2462 },
+ { 12, 2467 },
+ { 13, 2472 },
+ { 14, 2484 },
+ { 0, -1 }
+};
+
+guint32
+utils_freq_to_channel (guint32 freq)
+{
+ int i = 0;
+
+ while (a_table[i].chan && (a_table[i].freq != freq))
+ i++;
+ if (a_table[i].chan)
+ return a_table[i].chan;
+
+ i = 0;
+ while (bg_table[i].chan && (bg_table[i].freq != freq))
+ i++;
+ return bg_table[i].chan;
+}
+
+guint32
+utils_channel_to_freq (guint32 channel, char *band)
+{
+ int i = 0;
+
+ if (!strcmp (band, "a")) {
+ while (a_table[i].chan && (a_table[i].chan != channel))
+ i++;
+ return a_table[i].freq;
+ } else if (!strcmp (band, "bg")) {
+ while (bg_table[i].chan && (bg_table[i].chan != channel))
+ i++;
+ return bg_table[i].freq;
+ }
+
+ return 0;
+}
+
+guint32
+utils_find_next_channel (guint32 channel, int direction, char *band)
+{
+ size_t a_size = sizeof (a_table) / sizeof (struct cf_pair);
+ size_t bg_size = sizeof (bg_table) / sizeof (struct cf_pair);
+ struct cf_pair *pair = NULL;
+
+ if (!strcmp (band, "a")) {
+ if (channel < a_table[0].chan)
+ return a_table[0].chan;
+ if (channel > a_table[a_size - 2].chan)
+ return a_table[a_size - 2].chan;
+ pair = &a_table[0];
+ } else if (!strcmp (band, "bg")) {
+ if (channel < bg_table[0].chan)
+ return bg_table[0].chan;
+ if (channel > bg_table[bg_size - 2].chan)
+ return bg_table[bg_size - 2].chan;
+ pair = &bg_table[0];
+ } else {
+ g_assert_not_reached ();
+ return 0;
+ }
+
+ while (pair->chan) {
+ if (channel == pair->chan)
+ return channel;
+ if ((channel < (pair+1)->chan) && (channel > pair->chan)) {
+ if (direction > 0)
+ return (pair+1)->chan;
+ else
+ return pair->chan;
+ }
+ pair++;
+ }
+ return 0;
+}
+
+/*
+ * utils_ether_addr_valid
+ *
+ * Compares an Ethernet address against known invalid addresses.
+ *
+ */
+gboolean
+utils_ether_addr_valid (const struct ether_addr *test_addr)
+{
+ guint8 invalid_addr1[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+ guint8 invalid_addr2[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ guint8 invalid_addr3[ETH_ALEN] = {0x44, 0x44, 0x44, 0x44, 0x44, 0x44};
+ guint8 invalid_addr4[ETH_ALEN] = {0x00, 0x30, 0xb4, 0x00, 0x00, 0x00}; /* prism54 dummy MAC */
+
+ g_return_val_if_fail (test_addr != NULL, FALSE);
+
+ /* Compare the AP address the card has with invalid ethernet MAC addresses. */
+ if (!memcmp (test_addr->ether_addr_octet, &invalid_addr1, ETH_ALEN))
+ return FALSE;
+
+ if (!memcmp (test_addr->ether_addr_octet, &invalid_addr2, ETH_ALEN))
+ return FALSE;
+
+ if (!memcmp (test_addr->ether_addr_octet, &invalid_addr3, ETH_ALEN))
+ return FALSE;
+
+ if (!memcmp (test_addr->ether_addr_octet, &invalid_addr4, ETH_ALEN))
+ return FALSE;
+
+ if (test_addr->ether_addr_octet[0] & 1) /* Multicast addresses */
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+utils_check_ap_compatible (NMAccessPoint *ap,
+ NMConnection *connection)
+{
+ NMSettingWireless *s_wireless;
+ NMSettingWirelessSecurity *s_wireless_sec;
+ const GByteArray *setting_bssid;
+ const char *setting_mode;
+ const char *setting_band;
+ NM80211Mode ap_mode;
+ guint32 freq;
+
+ g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), FALSE);
+ g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ if (s_wireless == NULL)
+ return FALSE;
+
+ if (!nm_utils_same_ssid (nm_setting_wireless_get_ssid (s_wireless), nm_access_point_get_ssid (ap), TRUE))
+ return FALSE;
+
+ setting_bssid = nm_setting_wireless_get_bssid (s_wireless);
+ if (setting_bssid) {
+ struct ether_addr ap_addr;
+
+ if (ether_aton_r (nm_access_point_get_hw_address (ap), &ap_addr)) {
+ if (memcmp (setting_bssid->data, &ap_addr, ETH_ALEN))
+ return FALSE;
+ }
+ }
+
+ ap_mode = nm_access_point_get_mode (ap);
+ setting_mode = nm_setting_wireless_get_mode (s_wireless);
+ if (setting_mode) {
+ if ( !strcmp (setting_mode, "infrastructure")
+ && (ap_mode != NM_802_11_MODE_INFRA))
+ return FALSE;
+ if ( !strcmp (setting_mode, "adhoc")
+ && (ap_mode != NM_802_11_MODE_ADHOC))
+ return FALSE;
+ }
+
+ freq = nm_access_point_get_frequency (ap);
+ setting_band = nm_setting_wireless_get_band (s_wireless);
+ if (setting_band) {
+ if (!strcmp (setting_band, "a")) {
+ if (freq < 5170 || freq > 5825)
+ return FALSE;
+ } else if (!strcmp (setting_band, "bg")) {
+ if (freq < 2412 || freq > 2472)
+ return FALSE;
+ }
+ }
+
+ // FIXME: channel check
+
+ s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection,
+ NM_TYPE_SETTING_WIRELESS_SECURITY);
+
+ return nm_setting_wireless_ap_security_compatible (s_wireless,
+ s_wireless_sec,
+ nm_access_point_get_flags (ap),
+ nm_access_point_get_wpa_flags (ap),
+ nm_access_point_get_rsn_flags (ap),
+ nm_access_point_get_mode (ap));
+}
+
+static gboolean
+connection_valid_for_wired (NMConnection *connection,
+ NMSettingConnection *s_con,
+ NMDevice *device,
+ gpointer specific_object)
+{
+ NMDeviceEthernet *ethdev = NM_DEVICE_ETHERNET (device);
+ NMSettingWired *s_wired;
+ const char *str_mac;
+ struct ether_addr *bin_mac;
+ const char *connection_type;
+ const GByteArray *setting_mac;
+ gboolean is_pppoe = FALSE;
+
+ connection_type = nm_setting_connection_get_connection_type (s_con);
+ if (!strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME))
+ is_pppoe = TRUE;
+
+ if (!is_pppoe && strcmp (connection_type, NM_SETTING_WIRED_SETTING_NAME))
+ return FALSE;
+
+ s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
+ if (!is_pppoe && !s_wired)
+ return FALSE;
+
+ if (s_wired) {
+ /* Match MAC address */
+ setting_mac = nm_setting_wired_get_mac_address (s_wired);
+ if (!setting_mac)
+ return TRUE;
+
+ str_mac = nm_device_ethernet_get_hw_address (ethdev);
+ g_return_val_if_fail (str_mac != NULL, FALSE);
+
+ bin_mac = ether_aton (str_mac);
+ g_return_val_if_fail (bin_mac != NULL, FALSE);
+
+ if (memcmp (bin_mac->ether_addr_octet, setting_mac->data, ETH_ALEN))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+connection_valid_for_wireless (NMConnection *connection,
+ NMSettingConnection *s_con,
+ NMDevice *device,
+ gpointer specific_object)
+{
+ NMDeviceWifi *wdev = NM_DEVICE_WIFI (device);
+ NMSettingWireless *s_wireless;
+ NMSettingWirelessSecurity *s_wireless_sec;
+ const GByteArray *setting_mac;
+ const char *setting_security, *key_mgmt;
+ guint32 wcaps;
+ NMAccessPoint *ap;
+
+ if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_WIRELESS_SETTING_NAME))
+ return FALSE;
+
+ s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
+ g_return_val_if_fail (s_wireless != NULL, FALSE);
+
+ /* Match MAC address */
+ setting_mac = nm_setting_wireless_get_mac_address (s_wireless);
+ if (setting_mac) {
+ const char *str_mac;
+ struct ether_addr *bin_mac;
+
+ str_mac = nm_device_wifi_get_hw_address (wdev);
+ g_return_val_if_fail (str_mac != NULL, FALSE);
+
+ bin_mac = ether_aton (str_mac);
+ g_return_val_if_fail (bin_mac != NULL, FALSE);
+
+ if (memcmp (bin_mac->ether_addr_octet, setting_mac->data, ETH_ALEN))
+ return FALSE;
+ }
+
+ /* If an AP was given make sure that's compatible with the connection first */
+ if (specific_object) {
+ ap = NM_ACCESS_POINT (specific_object);
+ g_assert (ap);
+
+ if (!utils_check_ap_compatible (ap, connection))
+ return FALSE;
+ }
+
+ setting_security = nm_setting_wireless_get_security (s_wireless);
+ if (!setting_security || strcmp (setting_security, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME))
+ return TRUE; /* all devices can do unencrypted networks */
+
+ s_wireless_sec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
+ if (!s_wireless_sec)
+ return TRUE; /* all devices can do unencrypted networks */
+
+ key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wireless_sec);
+
+ /* All devices should support static WEP */
+ if (!strcmp (key_mgmt, "none"))
+ return TRUE;
+
+ /* All devices should support legacy LEAP and Dynamic WEP */
+ if (!strcmp (key_mgmt, "ieee8021x"))
+ return TRUE;
+
+ /* Match security with device capabilities */
+ wcaps = nm_device_wifi_get_capabilities (wdev);
+
+ /* At this point, the device better have basic WPA support. */
+ if ( !(wcaps & NM_WIFI_DEVICE_CAP_WPA)
+ || !(wcaps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP))
+ return FALSE;
+
+ /* Check for only RSN */
+ if ( (nm_setting_wireless_security_get_num_protos (s_wireless_sec) == 1)
+ && !strcmp (nm_setting_wireless_security_get_proto (s_wireless_sec, 0), "rsn")
+ && !(wcaps & NM_WIFI_DEVICE_CAP_RSN))
+ return FALSE;
+
+ /* Check for only pairwise CCMP */
+ if ( (nm_setting_wireless_security_get_num_pairwise (s_wireless_sec) == 1)
+ && !strcmp (nm_setting_wireless_security_get_pairwise (s_wireless_sec, 0), "ccmp")
+ && !(wcaps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP))
+ return FALSE;
+
+ /* Check for only group CCMP */
+ if ( (nm_setting_wireless_security_get_num_groups (s_wireless_sec) == 1)
+ && !strcmp (nm_setting_wireless_security_get_group (s_wireless_sec, 0), "ccmp")
+ && !(wcaps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP))
+ return FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+connection_valid_for_gsm (NMConnection *connection,
+ NMSettingConnection *s_con,
+ NMDevice *device,
+ gpointer specific_object)
+{
+ NMSettingGsm *s_gsm;
+
+ if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_GSM_SETTING_NAME))
+ return FALSE;
+
+ s_gsm = NM_SETTING_GSM (nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM));
+ g_return_val_if_fail (s_gsm != NULL, FALSE);
+
+ return TRUE;
+}
+
+static gboolean
+connection_valid_for_cdma (NMConnection *connection,
+ NMSettingConnection *s_con,
+ NMDevice *device,
+ gpointer specific_object)
+{
+ NMSettingCdma *s_cdma;
+
+ if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_CDMA_SETTING_NAME))
+ return FALSE;
+
+ s_cdma = NM_SETTING_CDMA (nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA));
+ g_return_val_if_fail (s_cdma != NULL, FALSE);
+
+ return TRUE;
+}
+
+static guint32
+get_connection_bt_type (NMConnection *connection)
+{
+ NMSettingBluetooth *s_bt;
+ const char *bt_type;
+
+ s_bt = (NMSettingBluetooth *) nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH);
+ if (!s_bt)
+ return NM_BT_CAPABILITY_NONE;
+
+ bt_type = nm_setting_bluetooth_get_connection_type (s_bt);
+ g_assert (bt_type);
+
+ if (!strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN))
+ return NM_BT_CAPABILITY_DUN;
+ else if (!strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU))
+ return NM_BT_CAPABILITY_NAP;
+
+ return NM_BT_CAPABILITY_NONE;
+}
+
+static gboolean
+connection_valid_for_bt (NMConnection *connection,
+ NMSettingConnection *s_con,
+ NMDevice *device,
+ gpointer specific_object)
+{
+ NMSettingBluetooth *s_bt;
+ const GByteArray *array;
+ char *str;
+ const char *hw_addr;
+ int addr_match = FALSE;
+ guint32 bt_type;
+
+ if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_BLUETOOTH_SETTING_NAME))
+ return FALSE;
+
+ s_bt = NM_SETTING_BLUETOOTH (nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH));
+ if (!s_bt)
+ return FALSE;
+
+ array = nm_setting_bluetooth_get_bdaddr (s_bt);
+ if (!array || (array->len != ETH_ALEN))
+ return FALSE;
+
+ bt_type = get_connection_bt_type (connection);
+ if (!(bt_type & nm_device_bt_get_capabilities (NM_DEVICE_BT (device))))
+ return FALSE;
+
+ str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+ array->data[0], array->data[1], array->data[2],
+ array->data[3], array->data[4], array->data[5]);
+ hw_addr = nm_device_bt_get_hw_address (NM_DEVICE_BT (device));
+ if (hw_addr)
+ addr_match = !g_ascii_strcasecmp (hw_addr, str);
+ g_free (str);
+
+ return addr_match;
+}
+
+gboolean
+utils_connection_valid_for_device (NMConnection *connection,
+ NMDevice *device,
+ gpointer specific_object)
+{
+ NMSettingConnection *s_con;
+
+ g_return_val_if_fail (connection != NULL, FALSE);
+ g_return_val_if_fail (device != NULL, FALSE);
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
+ g_return_val_if_fail (s_con != NULL, FALSE);
+ g_return_val_if_fail (nm_setting_connection_get_connection_type (s_con) != NULL, FALSE);
+
+ if (NM_IS_DEVICE_ETHERNET (device))
+ return connection_valid_for_wired (connection, s_con, device, specific_object);
+ else if (NM_IS_DEVICE_WIFI (device))
+ return connection_valid_for_wireless (connection, s_con, device, specific_object);
+ else if (NM_IS_GSM_DEVICE (device))
+ return connection_valid_for_gsm (connection, s_con, device, specific_object);
+ else if (NM_IS_CDMA_DEVICE (device))
+ return connection_valid_for_cdma (connection, s_con, device, specific_object);
+ else if (NM_IS_DEVICE_BT (device))
+ return connection_valid_for_bt (connection, s_con, device, specific_object);
+ else
+ g_warning ("Unknown device type '%s'", g_type_name (G_OBJECT_TYPE(device)));
+
+ return FALSE;
+}
+
+gboolean
+utils_access_point_is_compatible (NMAccessPoint *ap1,
+ NMAccessPoint *ap2)
+{
+ const GByteArray *ssid1;
+ const GByteArray *ssid2;
+
+ if (!ap1 || !ap2)
+ return FALSE;
+
+ ssid1 = nm_access_point_get_ssid (ap1);
+ ssid2 = nm_access_point_get_ssid (ap2);
+
+ if (!ssid1 || !ssid2)
+ return FALSE;
+
+ if (ssid1->len != ssid2->len || memcmp (ssid1->data, ssid2->data, ssid1->len))
+ return FALSE;
+
+ if (nm_access_point_get_mode (ap1) != nm_access_point_get_mode (ap2) ||
+ nm_access_point_get_flags (ap1) != nm_access_point_get_flags (ap2) ||
+ nm_access_point_get_wpa_flags (ap1) != nm_access_point_get_wpa_flags (ap2) ||
+ nm_access_point_get_rsn_flags (ap1) != nm_access_point_get_rsn_flags (ap2))
+ return FALSE;
+
+ return TRUE;
+}
+
+GSList *
+utils_filter_connections_for_device (NMDevice *device, GSList *connections)
+{
+ GSList *iter;
+ GSList *filtered = NULL;
+
+ for (iter = connections; iter; iter = g_slist_next (iter)) {
+ NMConnection *connection = NM_CONNECTION (iter->data);
+
+ if (utils_connection_valid_for_device (connection, device, NULL))
+ filtered = g_slist_append (filtered, connection);
+ }
+
+ return filtered;
+}
+
+gboolean
+utils_mac_valid (const struct ether_addr *addr)
+{
+ guint8 invalid1[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+ guint8 invalid2[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ guint8 invalid3[ETH_ALEN] = {0x44, 0x44, 0x44, 0x44, 0x44, 0x44};
+ guint8 invalid4[ETH_ALEN] = {0x00, 0x30, 0xb4, 0x00, 0x00, 0x00}; /* prism54 dummy MAC */
+
+ g_return_val_if_fail (addr != NULL, FALSE);
+
+ /* Compare the AP address the card has with invalid ethernet MAC addresses. */
+ if (!memcmp (addr->ether_addr_octet, &invalid1, ETH_ALEN))
+ return FALSE;
+
+ if (!memcmp (addr->ether_addr_octet, &invalid2, ETH_ALEN))
+ return FALSE;
+
+ if (!memcmp (addr->ether_addr_octet, &invalid3, ETH_ALEN))
+ return FALSE;
+
+ if (!memcmp (addr->ether_addr_octet, &invalid4, ETH_ALEN))
+ return FALSE;
+
+ if (addr->ether_addr_octet[0] & 1) /* Multicast addresses */
+ return FALSE;
+
+ return TRUE;
+}
+
+char *
+utils_ether_ntop (const struct ether_addr *mac)
+{
+ /* we like leading zeros and all-caps, instead
+ * of what glibc's ether_ntop() gives us
+ */
+ return g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
+ mac->ether_addr_octet[0], mac->ether_addr_octet[1],
+ mac->ether_addr_octet[2], mac->ether_addr_octet[3],
+ mac->ether_addr_octet[4], mac->ether_addr_octet[5]);
+}
+
+
+char *
+utils_next_available_name (GSList *connections, const char *format)
+{
+ GSList *names = NULL, *iter;
+ char *cname = NULL;
+ int i = 0;
+
+ for (iter = connections; iter; iter = g_slist_next (iter)) {
+ NMConnection *candidate = NM_CONNECTION (iter->data);
+ NMSettingConnection *s_con;
+ const char *id;
+
+ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (candidate, NM_TYPE_SETTING_CONNECTION));
+ id = nm_setting_connection_get_id (s_con);
+ g_assert (id);
+ names = g_slist_append (names, (gpointer) id);
+ }
+
+ /* Find the next available unique connection name */
+ while (!cname && (i++ < 10000)) {
+ char *temp;
+ gboolean found = FALSE;
+
+ temp = g_strdup_printf (format, i);
+ for (iter = names; iter; iter = g_slist_next (iter)) {
+ if (!strcmp (iter->data, temp)) {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found)
+ cname = temp;
+ else
+ g_free (temp);
+ }
+
+ g_slist_free (names);
+ return cname;
+}
diff --git a/libnm-gtk/utils.h b/libnm-gtk/utils.h
new file mode 100644
index 0000000..54a39f7
--- /dev/null
+++ b/libnm-gtk/utils.h
@@ -0,0 +1,57 @@
+/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
+ *
+ * Dan Williams <dcbw redhat com>
+ *
+ * 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 2007 Red Hat, Inc.
+ */
+
+#ifndef UTILS_H
+#define UTILS_H
+
+#include <glib.h>
+#include <nm-connection.h>
+#include <nm-device.h>
+#include <net/ethernet.h>
+#include <nm-access-point.h>
+
+char * utils_bin2hexstr (const char *bytes, int len, int final_len);
+
+const char *utils_get_device_description (NMDevice *device);
+
+guint32 utils_freq_to_channel (guint32 freq);
+guint32 utils_channel_to_freq (guint32 channel, char *band);
+guint32 utils_find_next_channel (guint32 channel, int direction, char *band);
+
+gboolean utils_ether_addr_valid (const struct ether_addr *test_addr);
+
+gboolean utils_connection_valid_for_device (NMConnection *connection,
+ NMDevice *device,
+ gpointer specific_object);
+
+gboolean utils_access_point_is_compatible (NMAccessPoint *ap1,
+ NMAccessPoint *ap2);
+
+GSList *utils_filter_connections_for_device (NMDevice *device, GSList *connections);
+
+char *utils_ether_ntop (const struct ether_addr *mac);
+
+gboolean utils_mac_valid (const struct ether_addr *addr);
+
+char *utils_next_available_name (GSList *connections, const char *format);
+
+#endif /* UTILS_H */
+
diff --git a/src/wireless-dialog.c b/libnm-gtk/wireless-dialog.c
similarity index 99%
rename from src/wireless-dialog.c
rename to libnm-gtk/wireless-dialog.c
index b4e0963..6b0e96f 100644
--- a/src/wireless-dialog.c
+++ b/libnm-gtk/wireless-dialog.c
@@ -1006,8 +1006,6 @@ nma_wireless_dialog_show (NMAWirelessDialog *dialog)
g_return_if_fail (NMA_IS_WIRELESS_DIALOG (dialog));
- utils_hide_main_widget ();
-
widget = GTK_WIDGET (dialog);
/* Prevent focus stealing */
diff --git a/src/wireless-dialog.h b/libnm-gtk/wireless-dialog.h
similarity index 100%
rename from src/wireless-dialog.h
rename to libnm-gtk/wireless-dialog.h
diff --git a/src/wireless-helper.h b/libnm-gtk/wireless-helper.h
similarity index 100%
rename from src/wireless-helper.h
rename to libnm-gtk/wireless-helper.h
diff --git a/src/wireless-security.ui b/libnm-gtk/wireless-security.ui
similarity index 100%
rename from src/wireless-security.ui
rename to libnm-gtk/wireless-security.ui
diff --git a/src/wireless-security/Makefile.am b/libnm-gtk/wireless-security/Makefile.am
similarity index 89%
rename from src/wireless-security/Makefile.am
rename to libnm-gtk/wireless-security/Makefile.am
index 9c49a32..117d32f 100644
--- a/src/wireless-security/Makefile.am
+++ b/libnm-gtk/wireless-security/Makefile.am
@@ -30,13 +30,12 @@ libwireless_security_la_SOURCES = \
libwireless_security_la_CPPFLAGS = \
$(NMN_CFLAGS) \
- -I${top_srcdir}/src/gconf-helpers \
+ -I${top_srcdir}/libnm-gtk \
-I${top_srcdir}/src/ \
-DUIDIR=\""$(uidir)"\"
libwireless_security_la_LIBADD = \
- $(NMN_LIBS) \
- ${top_builddir}/src/gconf-helpers/libgconf-helpers.la
+ $(NMN_LIBS)
uidir = $(datadir)/network-manager-netbook
ui_DATA = \
diff --git a/src/wireless-security/ca-nag-dialog.ui b/libnm-gtk/wireless-security/ca-nag-dialog.ui
similarity index 100%
rename from src/wireless-security/ca-nag-dialog.ui
rename to libnm-gtk/wireless-security/ca-nag-dialog.ui
diff --git a/src/wireless-security/dynamic-wep.ui b/libnm-gtk/wireless-security/dynamic-wep.ui
similarity index 100%
rename from src/wireless-security/dynamic-wep.ui
rename to libnm-gtk/wireless-security/dynamic-wep.ui
diff --git a/src/wireless-security/eap-leap.ui b/libnm-gtk/wireless-security/eap-leap.ui
similarity index 100%
rename from src/wireless-security/eap-leap.ui
rename to libnm-gtk/wireless-security/eap-leap.ui
diff --git a/src/wireless-security/eap-method-leap.c b/libnm-gtk/wireless-security/eap-method-leap.c
similarity index 100%
rename from src/wireless-security/eap-method-leap.c
rename to libnm-gtk/wireless-security/eap-method-leap.c
diff --git a/src/wireless-security/eap-method-leap.h b/libnm-gtk/wireless-security/eap-method-leap.h
similarity index 100%
rename from src/wireless-security/eap-method-leap.h
rename to libnm-gtk/wireless-security/eap-method-leap.h
diff --git a/src/wireless-security/eap-method-peap.c b/libnm-gtk/wireless-security/eap-method-peap.c
similarity index 100%
rename from src/wireless-security/eap-method-peap.c
rename to libnm-gtk/wireless-security/eap-method-peap.c
diff --git a/src/wireless-security/eap-method-peap.h b/libnm-gtk/wireless-security/eap-method-peap.h
similarity index 100%
rename from src/wireless-security/eap-method-peap.h
rename to libnm-gtk/wireless-security/eap-method-peap.h
diff --git a/src/wireless-security/eap-method-simple.c b/libnm-gtk/wireless-security/eap-method-simple.c
similarity index 100%
rename from src/wireless-security/eap-method-simple.c
rename to libnm-gtk/wireless-security/eap-method-simple.c
diff --git a/src/wireless-security/eap-method-simple.h b/libnm-gtk/wireless-security/eap-method-simple.h
similarity index 100%
rename from src/wireless-security/eap-method-simple.h
rename to libnm-gtk/wireless-security/eap-method-simple.h
diff --git a/src/wireless-security/eap-method-tls.c b/libnm-gtk/wireless-security/eap-method-tls.c
similarity index 100%
rename from src/wireless-security/eap-method-tls.c
rename to libnm-gtk/wireless-security/eap-method-tls.c
diff --git a/src/wireless-security/eap-method-tls.h b/libnm-gtk/wireless-security/eap-method-tls.h
similarity index 100%
rename from src/wireless-security/eap-method-tls.h
rename to libnm-gtk/wireless-security/eap-method-tls.h
diff --git a/src/wireless-security/eap-method-ttls.c b/libnm-gtk/wireless-security/eap-method-ttls.c
similarity index 100%
rename from src/wireless-security/eap-method-ttls.c
rename to libnm-gtk/wireless-security/eap-method-ttls.c
diff --git a/src/wireless-security/eap-method-ttls.h b/libnm-gtk/wireless-security/eap-method-ttls.h
similarity index 100%
rename from src/wireless-security/eap-method-ttls.h
rename to libnm-gtk/wireless-security/eap-method-ttls.h
diff --git a/src/wireless-security/eap-method.c b/libnm-gtk/wireless-security/eap-method.c
similarity index 100%
rename from src/wireless-security/eap-method.c
rename to libnm-gtk/wireless-security/eap-method.c
diff --git a/src/wireless-security/eap-method.h b/libnm-gtk/wireless-security/eap-method.h
similarity index 100%
rename from src/wireless-security/eap-method.h
rename to libnm-gtk/wireless-security/eap-method.h
diff --git a/src/wireless-security/eap-peap.ui b/libnm-gtk/wireless-security/eap-peap.ui
similarity index 100%
rename from src/wireless-security/eap-peap.ui
rename to libnm-gtk/wireless-security/eap-peap.ui
diff --git a/src/wireless-security/eap-simple.ui b/libnm-gtk/wireless-security/eap-simple.ui
similarity index 100%
rename from src/wireless-security/eap-simple.ui
rename to libnm-gtk/wireless-security/eap-simple.ui
diff --git a/src/wireless-security/eap-tls.ui b/libnm-gtk/wireless-security/eap-tls.ui
similarity index 100%
rename from src/wireless-security/eap-tls.ui
rename to libnm-gtk/wireless-security/eap-tls.ui
diff --git a/src/wireless-security/eap-ttls.ui b/libnm-gtk/wireless-security/eap-ttls.ui
similarity index 100%
rename from src/wireless-security/eap-ttls.ui
rename to libnm-gtk/wireless-security/eap-ttls.ui
diff --git a/src/wireless-security/helpers.c b/libnm-gtk/wireless-security/helpers.c
similarity index 100%
rename from src/wireless-security/helpers.c
rename to libnm-gtk/wireless-security/helpers.c
diff --git a/src/wireless-security/helpers.h b/libnm-gtk/wireless-security/helpers.h
similarity index 100%
rename from src/wireless-security/helpers.h
rename to libnm-gtk/wireless-security/helpers.h
diff --git a/src/wireless-security/leap.ui b/libnm-gtk/wireless-security/leap.ui
similarity index 100%
rename from src/wireless-security/leap.ui
rename to libnm-gtk/wireless-security/leap.ui
diff --git a/src/wireless-security/wep-key.ui b/libnm-gtk/wireless-security/wep-key.ui
similarity index 100%
rename from src/wireless-security/wep-key.ui
rename to libnm-gtk/wireless-security/wep-key.ui
diff --git a/src/wireless-security/wireless-security.c b/libnm-gtk/wireless-security/wireless-security.c
similarity index 100%
rename from src/wireless-security/wireless-security.c
rename to libnm-gtk/wireless-security/wireless-security.c
diff --git a/src/wireless-security/wireless-security.h b/libnm-gtk/wireless-security/wireless-security.h
similarity index 100%
rename from src/wireless-security/wireless-security.h
rename to libnm-gtk/wireless-security/wireless-security.h
diff --git a/src/wireless-security/wpa-eap.ui b/libnm-gtk/wireless-security/wpa-eap.ui
similarity index 100%
rename from src/wireless-security/wpa-eap.ui
rename to libnm-gtk/wireless-security/wpa-eap.ui
diff --git a/src/wireless-security/wpa-psk.ui b/libnm-gtk/wireless-security/wpa-psk.ui
similarity index 100%
rename from src/wireless-security/wpa-psk.ui
rename to libnm-gtk/wireless-security/wpa-psk.ui
diff --git a/src/wireless-security/ws-dynamic-wep.c b/libnm-gtk/wireless-security/ws-dynamic-wep.c
similarity index 100%
rename from src/wireless-security/ws-dynamic-wep.c
rename to libnm-gtk/wireless-security/ws-dynamic-wep.c
diff --git a/src/wireless-security/ws-dynamic-wep.h b/libnm-gtk/wireless-security/ws-dynamic-wep.h
similarity index 100%
rename from src/wireless-security/ws-dynamic-wep.h
rename to libnm-gtk/wireless-security/ws-dynamic-wep.h
diff --git a/src/wireless-security/ws-leap.c b/libnm-gtk/wireless-security/ws-leap.c
similarity index 99%
rename from src/wireless-security/ws-leap.c
rename to libnm-gtk/wireless-security/ws-leap.c
index d2d18bb..92efffb 100644
--- a/src/wireless-security/ws-leap.c
+++ b/libnm-gtk/wireless-security/ws-leap.c
@@ -24,7 +24,6 @@
#include "wireless-security.h"
#include "utils.h"
-#include "gconf-helpers.h"
#include "helpers.h"
diff --git a/src/wireless-security/ws-leap.h b/libnm-gtk/wireless-security/ws-leap.h
similarity index 100%
rename from src/wireless-security/ws-leap.h
rename to libnm-gtk/wireless-security/ws-leap.h
diff --git a/src/wireless-security/ws-wep-key.c b/libnm-gtk/wireless-security/ws-wep-key.c
similarity index 99%
rename from src/wireless-security/ws-wep-key.c
rename to libnm-gtk/wireless-security/ws-wep-key.c
index 21fac42..19c95cc 100644
--- a/src/wireless-security/ws-wep-key.c
+++ b/libnm-gtk/wireless-security/ws-wep-key.c
@@ -27,8 +27,6 @@
#include "wireless-security.h"
#include "utils.h"
-#include "gconf-helpers.h"
-
static void
show_toggled_cb (GtkCheckButton *button, WirelessSecurity *sec)
diff --git a/src/wireless-security/ws-wep-key.h b/libnm-gtk/wireless-security/ws-wep-key.h
similarity index 100%
rename from src/wireless-security/ws-wep-key.h
rename to libnm-gtk/wireless-security/ws-wep-key.h
diff --git a/src/wireless-security/ws-wpa-eap.c b/libnm-gtk/wireless-security/ws-wpa-eap.c
similarity index 100%
rename from src/wireless-security/ws-wpa-eap.c
rename to libnm-gtk/wireless-security/ws-wpa-eap.c
diff --git a/src/wireless-security/ws-wpa-eap.h b/libnm-gtk/wireless-security/ws-wpa-eap.h
similarity index 100%
rename from src/wireless-security/ws-wpa-eap.h
rename to libnm-gtk/wireless-security/ws-wpa-eap.h
diff --git a/src/wireless-security/ws-wpa-psk.c b/libnm-gtk/wireless-security/ws-wpa-psk.c
similarity index 99%
rename from src/wireless-security/ws-wpa-psk.c
rename to libnm-gtk/wireless-security/ws-wpa-psk.c
index 93aab61..eaa555c 100644
--- a/src/wireless-security/ws-wpa-psk.c
+++ b/libnm-gtk/wireless-security/ws-wpa-psk.c
@@ -25,7 +25,6 @@
#include "wireless-security.h"
#include "utils.h"
-#include "gconf-helpers.h"
#include "helpers.h"
#define WPA_PMK_LEN 32
diff --git a/src/wireless-security/ws-wpa-psk.h b/libnm-gtk/wireless-security/ws-wpa-psk.h
similarity index 100%
rename from src/wireless-security/ws-wpa-psk.h
rename to libnm-gtk/wireless-security/ws-wpa-psk.h
diff --git a/marshallers/.gitignore b/marshallers/.gitignore
new file mode 100644
index 0000000..5ed6c5c
--- /dev/null
+++ b/marshallers/.gitignore
@@ -0,0 +1,2 @@
+nma-marshal.[ch]
+
diff --git a/src/marshallers/Makefile.am b/marshallers/Makefile.am
similarity index 100%
rename from src/marshallers/Makefile.am
rename to marshallers/Makefile.am
diff --git a/src/marshallers/nma-marshal-main.c b/marshallers/nma-marshal-main.c
similarity index 100%
rename from src/marshallers/nma-marshal-main.c
rename to marshallers/nma-marshal-main.c
diff --git a/src/marshallers/nma-marshal.list b/marshallers/nma-marshal.list
similarity index 100%
rename from src/marshallers/nma-marshal.list
rename to marshallers/nma-marshal.list
diff --git a/po/.gitignore b/po/.gitignore
new file mode 100644
index 0000000..746eeb4
--- /dev/null
+++ b/po/.gitignore
@@ -0,0 +1,2 @@
+*.gmo
+POTFILES
diff --git a/po/POTFILES.in b/po/POTFILES.in
index b0b63d3..ad5126d 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,29 +1,30 @@
-src/main.c
+libnm-gtk/nm-ethernet-item.c
+libnm-gtk/nm-wifi-item.c
+libnm-gtk/nm-gsm-item.c
+libnm-gtk/nm-cdma-item.c
+libnm-gtk/wireless-dialog.c
+[type: gettext/glade]libnm-gtk/wireless-security.ui
+[type: gettext/glade]libnm-gtk/wireless-security/ca-nag-dialog.ui
+[type: gettext/glade]libnm-gtk/wireless-security/dynamic-wep.ui
+[type: gettext/glade]libnm-gtk/wireless-security/eap-leap.ui
+[type: gettext/glade]libnm-gtk/wireless-security/eap-peap.ui
+[type: gettext/glade]libnm-gtk/wireless-security/eap-simple.ui
+[type: gettext/glade]libnm-gtk/wireless-security/eap-tls.ui
+[type: gettext/glade]libnm-gtk/wireless-security/eap-ttls.ui
+[type: gettext/glade]libnm-gtk/wireless-security/leap.ui
+[type: gettext/glade]libnm-gtk/wireless-security/wep-key.ui
+[type: gettext/glade]libnm-gtk/wireless-security/wpa-eap.ui
+[type: gettext/glade]libnm-gtk/wireless-security/wpa-psk.ui
+libnm-gtk/wireless-security/eap-method-peap.c
+libnm-gtk/wireless-security/eap-method-tls.c
+libnm-gtk/wireless-security/eap-method-ttls.c
+libnm-gtk/wireless-security/eap-method.c
+libnm-gtk/wireless-security/wireless-security.c
+src/nmn-list.c
src/nmn-applet.c
+src/main.c
+src/nmn-panel-client.c
+src/nmn-item-renderer.c
src/nmn-connection-details.c
-src/nmn-ethernet-item.c
-src/nmn-network-item.c
-src/nmn-networks.c
-src/nmn-mobile-providers.c
src/nmn-new-connection.c
-src/nmn-serial-item.c
-src/nmn-status-icon.c
-src/nmn-wifi-item.c
-src/wireless-dialog.c
-[type: gettext/glade]src/wireless-security.ui
-[type: gettext/glade]src/wireless-security/ca-nag-dialog.ui
-[type: gettext/glade]src/wireless-security/dynamic-wep.ui
-[type: gettext/glade]src/wireless-security/eap-leap.ui
-[type: gettext/glade]src/wireless-security/eap-peap.ui
-[type: gettext/glade]src/wireless-security/eap-simple.ui
-[type: gettext/glade]src/wireless-security/eap-tls.ui
-[type: gettext/glade]src/wireless-security/eap-ttls.ui
-[type: gettext/glade]src/wireless-security/leap.ui
-[type: gettext/glade]src/wireless-security/wep-key.ui
-[type: gettext/glade]src/wireless-security/wpa-eap.ui
-[type: gettext/glade]src/wireless-security/wpa-psk.ui
-src/wireless-security/eap-method-peap.c
-src/wireless-security/eap-method-tls.c
-src/wireless-security/eap-method-ttls.c
-src/wireless-security/eap-method.c
-src/wireless-security/wireless-security.c
+src/nmn-mobile-providers.c
diff --git a/src/.gitignore b/src/.gitignore
new file mode 100644
index 0000000..2d10d4b
--- /dev/null
+++ b/src/.gitignore
@@ -0,0 +1 @@
+network-manager-netbook
diff --git a/src/Makefile.am b/src/Makefile.am
index 25f4425..87b2edf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,13 +1,12 @@
-SUBDIRS = marshallers gconf-helpers wireless-security
-
NULL=
libexec_PROGRAMS = network-manager-netbook
network_manager_netbook_CPPFLAGS = \
$(NMN_CFLAGS) \
- -I${top_srcdir}/src/gconf-helpers \
- -I${top_srcdir}/src/wireless-security \
+ -I${top_builddir}/marshallers \
+ -I${top_srcdir}/libnm-gtk \
+ -I${top_srcdir}/libnm-gtk/wireless-security \
-DUIDIR=\""$(uidir)"\" \
-DICON_PATH=\""$(pkgdatadir)/icons/"\" \
-DNMNLOCALEDIR=\"$(datadir)/locale\" \
@@ -16,8 +15,9 @@ network_manager_netbook_CPPFLAGS = \
network_manager_netbook_LDADD = \
$(NMN_LIBS) \
- ${top_builddir}/src/gconf-helpers/libgconf-helpers.la \
- ${top_builddir}/src/wireless-security/libwireless-security.la \
+ ${top_builddir}/marshallers/libmarshallers.la \
+ ${top_builddir}/libnm-gtk/libnm-gtk.la \
+ ${top_builddir}/libnm-gtk/wireless-security/libwireless-security.la \
$(NULL)
network_manager_netbook_SOURCES = \
@@ -25,53 +25,17 @@ network_manager_netbook_SOURCES = \
nmn-applet.h \
nmn-connection-details.c \
nmn-connection-details.h \
- nmn-device-handler.c \
- nmn-device-handler.h \
- nmn-ethernet-handler.c \
- nmn-ethernet-handler.h \
- nmn-ethernet-item.c \
- nmn-ethernet-item.h \
- nmn-icon-cache.c \
- nmn-icon-cache.h \
- nmn-item.c \
- nmn-item.h \
+ nmn-item-renderer.c \
+ nmn-item-renderer.h \
nmn-list.c \
nmn-list.h \
nmn-mobile-providers.c \
nmn-mobile-providers.h \
- nmn-network-item.c \
- nmn-network-item.h \
- nmn-networks.c \
- nmn-networks.h \
+ nmn-model.c \
+ nmn-model.h \
nmn-new-connection.c \
nmn-new-connection.h \
- nmn-nm-data.c \
- nmn-nm-data.h \
- nmn-serial-handler.c \
- nmn-serial-handler.h \
- nmn-serial-item.c \
- nmn-serial-item.h \
- nmn-status-icon.c \
- nmn-status-icon.h \
- nmn-text-item.c \
- nmn-text-item.h \
- nmn-wifi-handler.c \
- nmn-wifi-handler.h \
- nmn-wifi-item.c \
- nmn-wifi-item.h \
- nmn-wifi-list.c \
- nmn-wifi-list.h \
+ nmn-panel-client.c \
+ nmn-panel-client.h \
main.c \
- utils.c \
- utils.h \
- wireless-dialog.c \
- wireless-dialog.h \
- wireless-helper.h \
- $(NULL)
-
-uidir = $(datadir)/network-manager-netbook
-ui_DATA = wireless-security.ui
-
-EXTRA_DIST = \
- $(ui_DATA) \
$(NULL)
diff --git a/src/main.c b/src/main.c
index 5234a3a..67669b3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -23,17 +23,31 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
-#include <moblin-panel/mpl-panel-common.h>
-#include <moblin-panel/mpl-panel-gtk.h>
#include "nmn-applet.h"
-#include "nmn-icon-cache.h"
-#include "utils.h"
+#include "nm-status-model.h"
+#include "nm-icon-cache.h"
+#include "nmn-panel-client.h"
+
+static void
+panel_client_show (MplPanelClient *panel_client,
+ gpointer user_data)
+{
+ nmn_applet_show (NMN_APPLET (user_data));
+}
+
+static void
+panel_client_hide (MplPanelClient *panel_client,
+ gpointer user_data)
+{
+ nmn_applet_hide (NMN_APPLET (user_data));
+}
int
main (int argc, char *argv[])
{
- MplPanelClient *panel_client;
+ NmnModel *model;
NmnApplet *applet;
+ GtkWidget *container;
gboolean standalone = FALSE;
GError *error = NULL;
GOptionEntry entries[] = {
@@ -46,12 +60,12 @@ main (int argc, char *argv[])
g_set_application_name (_("NetworkManager Netbook"));
gtk_init_with_args (&argc, &argv, _("- NetworkManager Netbook"),
- entries, GETTEXT_PACKAGE, &error);
+ entries, GETTEXT_PACKAGE, &error);
if (error) {
- g_printerr ("%s\n", error->message);
- g_error_free (error);
- return 1;
+ g_printerr ("%s\n", error->message);
+ g_error_free (error);
+ return 1;
}
/* Force to the moblin theme */
@@ -60,31 +74,38 @@ main (int argc, char *argv[])
"Moblin-Netbook",
NULL);
+ model = nmn_model_new ();
+ applet = nmn_applet_new (model);
+
if (standalone) {
- GtkWidget *window;
- window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- g_signal_connect (window, "delete-event", (GCallback) gtk_main_quit,
- NULL);
- applet = nmn_applet_new_standalone (GTK_WINDOW (window));
- gtk_widget_set_size_request (window, 1000, -1);
- utils_set_main_widget (G_OBJECT (window));
- gtk_widget_show (window);
+ container = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+ g_signal_connect (container, "delete-event", (GCallback) gtk_main_quit, NULL);
+ gtk_widget_set_size_request (container, 1000, -1);
} else {
- panel_client = mpl_panel_gtk_new (MPL_PANEL_NETWORK,
- _("network"),
- THEME_PATH "/network-manager-netbook.css",
- "unknown",
- TRUE);
-
- mpl_panel_client_set_height_request (panel_client, 499);
- applet = nmn_applet_new (panel_client);
- utils_set_main_widget (G_OBJECT (panel_client));
+ NMStatusModel *status_model;
+ NmnPanelClient *panel_client;
+
+ status_model = NM_STATUS_MODEL (nm_status_model_new (GTK_TREE_MODEL (model)));
+ panel_client = nmn_panel_client_new (status_model);
+ g_object_unref (status_model);
+
+ if (!panel_client)
+ g_error ("Moblin panel client intialization failed.");
+
+ g_signal_connect (panel_client, "show-begin", G_CALLBACK (panel_client_show), applet);
+ g_signal_connect (panel_client, "show-end", G_CALLBACK (panel_client_hide), applet);
+
+ container = mpl_panel_gtk_get_window (MPL_PANEL_GTK (panel_client));
}
- gtk_main ();
+ gtk_widget_show (GTK_WIDGET (applet));
+ gtk_container_add (GTK_CONTAINER (container), GTK_WIDGET (applet));
+ gtk_widget_modify_bg (container, GTK_STATE_NORMAL, >k_widget_get_style (container)->white);
+ gtk_widget_show (container);
- g_object_unref (applet);
- nmn_icon_cache_invalidate ();
+ gtk_main ();
+ g_object_unref (model);
+ nm_icon_cache_invalidate ();
return 0;
}
diff --git a/src/nmn-applet.c b/src/nmn-applet.c
index 1c5df3b..f57af91 100644
--- a/src/nmn-applet.c
+++ b/src/nmn-applet.c
@@ -19,20 +19,18 @@
#include <glib/gi18n.h>
#include <dbus/dbus-glib-lowlevel.h>
-#include <moblin-panel/mpl-panel-gtk.h>
#include <nbtk/nbtk-gtk.h>
#include "nmn-applet.h"
-#include "nmn-nm-data.h"
-#include "nmn-status-icon.h"
-#include "nmn-networks.h"
#include "nmn-new-connection.h"
-G_DEFINE_TYPE (NmnApplet, nmn_applet, G_TYPE_OBJECT)
+#include "nmn-model.h"
+#include "nmn-list.h"
+
+G_DEFINE_TYPE (NmnApplet, nmn_applet, GTK_TYPE_VBOX)
enum {
PROP_0,
- PROP_PANEL_CLIENT,
- PROP_WINDOW,
+ PROP_MODEL,
LAST_PROP
};
@@ -40,10 +38,7 @@ enum {
#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NMN_TYPE_APPLET, NmnAppletPrivate))
typedef struct {
- NmnNMData *nm_data;
- MplPanelClient *panel_client;
- GtkWindow *window;
- NmnStatusIcon *status_icon;
+ NmnModel *model;
GtkWidget *pane;
GtkWidget *list;
@@ -62,24 +57,27 @@ typedef struct {
gboolean disposed;
} NmnAppletPrivate;
+static void add_new_connection_hide (GtkWidget *widget, gpointer user_data);
+
NmnApplet *
-nmn_applet_new (MplPanelClient *panel_client)
+nmn_applet_new (NmnModel *model)
{
- g_return_val_if_fail (MPL_IS_PANEL_CLIENT (panel_client), NULL);
+ g_return_val_if_fail (NMN_IS_MODEL (model), NULL);
return NMN_APPLET (g_object_new (NMN_TYPE_APPLET,
- NMN_APPLET_PANEL_CLIENT, panel_client,
+ NMN_APPLET_MODEL, model,
NULL));
}
-NmnApplet *
-nmn_applet_new_standalone (GtkWindow *window)
+void
+nmn_applet_show (NmnApplet *applet)
{
- g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
+}
- return NMN_APPLET (g_object_new (NMN_TYPE_APPLET,
- NMN_APPLET_WINDOW, window,
- NULL));
+void
+nmn_applet_hide (NmnApplet *applet)
+{
+ add_new_connection_hide (NULL, applet);
}
/* enable/disable wifi button */
@@ -91,32 +89,32 @@ enable_wifi_toggled (NbtkGtkLightSwitch *w,
{
NmnAppletPrivate *priv = GET_PRIVATE (user_data);
- nmn_nm_data_wifi_toggled (priv->nm_data, active);
+ nmn_model_wifi_toggled (priv->model, active);
}
static void
-wifi_toggle_set_sensitive (NmnNMData *nm_data,
+wifi_toggle_set_sensitive (NmnModel *model,
GtkWidget *widget,
gboolean suggested)
{
- if (suggested == FALSE || nmn_nm_data_wifi_can_change (nm_data) == FALSE)
+ if (suggested == FALSE || nmn_model_wifi_can_change (model) == FALSE)
gtk_widget_set_sensitive (widget, FALSE);
else
gtk_widget_set_sensitive (widget, TRUE);
}
static void
-wifi_toggled (NmnNMData *nm_data,
+wifi_toggled (NmnModel *model,
gboolean active,
gpointer user_data)
{
NmnAppletPrivate *priv = GET_PRIVATE (user_data);
- g_signal_handlers_block_by_func (priv->nm_data, enable_wifi_toggled, user_data);
+ g_signal_handlers_block_by_func (priv->model, enable_wifi_toggled, user_data);
nbtk_gtk_light_switch_set_active (NBTK_GTK_LIGHT_SWITCH (priv->enable_wifi), active);
- g_signal_handlers_unblock_by_func (priv->nm_data, enable_wifi_toggled, user_data);
+ g_signal_handlers_unblock_by_func (priv->model, enable_wifi_toggled, user_data);
- wifi_toggle_set_sensitive (priv->nm_data, priv->enable_wifi, TRUE);
+ wifi_toggle_set_sensitive (priv->model, priv->enable_wifi, TRUE);
}
static void
@@ -127,8 +125,8 @@ enable_wifi_setup (NmnApplet *applet)
g_signal_connect (priv->enable_wifi, "switch-flipped", G_CALLBACK (enable_wifi_toggled), applet);
gtk_widget_show (priv->enable_wifi);
- g_signal_connect (priv->nm_data, "wifi-toggled", G_CALLBACK (wifi_toggled), applet);
- wifi_toggled (priv->nm_data, nmn_nm_data_wifi_get_active (priv->nm_data), applet);
+ g_signal_connect (priv->model, "wifi-toggled", G_CALLBACK (wifi_toggled), applet);
+ wifi_toggled (priv->model, nmn_model_wifi_get_active (priv->model), applet);
}
/* enable/disable ethernet button */
@@ -140,19 +138,19 @@ enable_ethernet_toggled (NbtkGtkLightSwitch *w,
{
NmnAppletPrivate *priv = GET_PRIVATE (user_data);
- nmn_nm_data_ethernet_toggled (priv->nm_data, active);
+ nmn_model_ethernet_toggled (priv->model, active);
}
static void
-ethernet_toggled (NmnNMData *nm_data,
+ethernet_toggled (NmnModel *model,
gboolean active,
gpointer user_data)
{
NmnAppletPrivate *priv = GET_PRIVATE (user_data);
- g_signal_handlers_block_by_func (priv->nm_data, enable_ethernet_toggled, user_data);
+ g_signal_handlers_block_by_func (priv->model, enable_ethernet_toggled, user_data);
nbtk_gtk_light_switch_set_active (NBTK_GTK_LIGHT_SWITCH (priv->enable_ethernet), active);
- g_signal_handlers_unblock_by_func (priv->nm_data, enable_ethernet_toggled, user_data);
+ g_signal_handlers_unblock_by_func (priv->model, enable_ethernet_toggled, user_data);
}
static void
@@ -163,8 +161,8 @@ enable_ethernet_setup (NmnApplet *applet)
g_signal_connect (priv->enable_ethernet, "switch-flipped", G_CALLBACK (enable_ethernet_toggled), applet);
gtk_widget_show (priv->enable_ethernet);
- g_signal_connect (priv->nm_data, "ethernet-toggled", G_CALLBACK (ethernet_toggled), applet);
- ethernet_toggled (priv->nm_data, nmn_nm_data_ethernet_get_active (priv->nm_data), applet);
+ g_signal_connect (priv->model, "ethernet-toggled", G_CALLBACK (ethernet_toggled), applet);
+ ethernet_toggled (priv->model, nmn_model_ethernet_get_active (priv->model), applet);
}
/* enable/disable 3G button */
@@ -176,19 +174,19 @@ enable_3g_toggled (NbtkGtkLightSwitch *w,
{
NmnAppletPrivate *priv = GET_PRIVATE (user_data);
- nmn_nm_data_modems_toggled (priv->nm_data, active);
+ nmn_model_modems_toggled (priv->model, active);
}
static void
-modems_toggled (NmnNMData *nm_data,
+modems_toggled (NmnModel *model,
gboolean active,
gpointer user_data)
{
NmnAppletPrivate *priv = GET_PRIVATE (user_data);
- g_signal_handlers_block_by_func (priv->nm_data, enable_3g_toggled, user_data);
+ g_signal_handlers_block_by_func (priv->model, enable_3g_toggled, user_data);
nbtk_gtk_light_switch_set_active (NBTK_GTK_LIGHT_SWITCH (priv->enable_3g), active);
- g_signal_handlers_unblock_by_func (priv->nm_data, enable_3g_toggled, user_data);
+ g_signal_handlers_unblock_by_func (priv->model, enable_3g_toggled, user_data);
}
static void
@@ -199,8 +197,8 @@ enable_3g_setup (NmnApplet *applet)
g_signal_connect (priv->enable_3g, "switch-flipped", G_CALLBACK (enable_3g_toggled), applet);
gtk_widget_show (priv->enable_3g);
- g_signal_connect (priv->nm_data, "modems-toggled", G_CALLBACK (modems_toggled), applet);
- modems_toggled (priv->nm_data, nmn_nm_data_modems_get_active (priv->nm_data), applet);
+ g_signal_connect (priv->model, "modems-toggled", G_CALLBACK (modems_toggled), applet);
+ modems_toggled (priv->model, nmn_model_modems_get_active (priv->model), applet);
}
/* enable/disable Offline mode button */
@@ -214,25 +212,25 @@ enable_network_toggled (NbtkGtkLightSwitch *w,
gtk_widget_set_sensitive (priv->enable_ethernet, !active);
gtk_widget_set_sensitive (priv->enable_3g, !active);
- wifi_toggle_set_sensitive (priv->nm_data, priv->enable_wifi, !active);
+ wifi_toggle_set_sensitive (priv->model, priv->enable_wifi, !active);
- nmn_nm_data_offline_mode_toggled (priv->nm_data, active);
+ nmn_model_offline_mode_toggled (priv->model, active);
}
static void
-offline_toggled (NmnNMData *nm_data,
+offline_toggled (NmnModel *model,
gboolean active,
gpointer user_data)
{
NmnAppletPrivate *priv = GET_PRIVATE (user_data);
- g_signal_handlers_block_by_func (priv->nm_data, enable_network_toggled, user_data);
+ g_signal_handlers_block_by_func (priv->model, enable_network_toggled, user_data);
nbtk_gtk_light_switch_set_active (NBTK_GTK_LIGHT_SWITCH (priv->enable_network), active);
- g_signal_handlers_unblock_by_func (priv->nm_data, enable_network_toggled, user_data);
+ g_signal_handlers_unblock_by_func (priv->model, enable_network_toggled, user_data);
gtk_widget_set_sensitive (priv->enable_3g, !active);
gtk_widget_set_sensitive (priv->enable_ethernet, !active);
- wifi_toggle_set_sensitive (priv->nm_data, priv->enable_wifi, !active);
+ wifi_toggle_set_sensitive (priv->model, priv->enable_wifi, !active);
}
static void
@@ -243,8 +241,8 @@ enable_network_setup (NmnApplet *applet)
g_signal_connect (priv->enable_network, "switch-flipped", G_CALLBACK (enable_network_toggled), applet);
gtk_widget_show (priv->enable_network);
- g_signal_connect (priv->nm_data, "offline-mode-toggled", G_CALLBACK (offline_toggled), applet);
- offline_toggled (priv->nm_data, nmn_nm_data_offline_mode_get_active (priv->nm_data), applet);
+ g_signal_connect (priv->model, "offline-mode-toggled", G_CALLBACK (offline_toggled), applet);
+ offline_toggled (priv->model, nmn_model_offline_mode_get_active (priv->model), applet);
}
/* add new connection button */
@@ -274,8 +272,8 @@ add_new_connection_setup (NmnApplet *applet)
{
NmnAppletPrivate *priv = GET_PRIVATE (applet);
- priv->new_dialog = nmn_new_connection_create (priv->nm_data);
- g_object_ref_sink (priv->new_dialog);
+ priv->new_dialog = nmn_new_connection_create (priv->model);
+ gtk_box_pack_end (GTK_BOX (applet), priv->new_dialog, TRUE, TRUE, 0);
gtk_widget_modify_bg (priv->new_dialog, GTK_STATE_NORMAL, >k_widget_get_style (priv->new_dialog)->white);
g_signal_connect (priv->new_dialog, "hide", G_CALLBACK (add_new_connection_hide), applet);
@@ -283,104 +281,18 @@ add_new_connection_setup (NmnApplet *applet)
}
static void
-show_begin_cb (MplPanelClient *panel_client,
- gpointer user_data)
-{
- NmnAppletPrivate *priv = GET_PRIVATE (user_data);
-
- if (!priv->network_list_populated) {
- nmn_networks_populate (NMN_NETWORKS (priv->list));
- priv->network_list_populated = TRUE;
- }
-}
-
-static void
-hide_end_cb (MplPanelClient *panel_client,
- gpointer user_data)
-{
- add_new_connection_hide (NULL, user_data);
-}
-
-static DBusGConnection *
-init_dbus (void)
-{
- DBusGConnection *bus;
- DBusGProxy *proxy;
- GError *error = NULL;
- int request_name_result;
-
- dbus_connection_set_change_sigpipe (TRUE);
-
- bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error);
- if (!bus) {
- g_warning ("Could not get the system bus. Make sure "
- "the message bus daemon is running! Message: %s",
- error->message);
- g_error_free (error);
- return NULL;
- }
-
- dbus_connection_set_exit_on_disconnect (dbus_g_connection_get_connection (bus), FALSE);
-
- proxy = dbus_g_proxy_new_for_name (bus,
- "org.freedesktop.DBus",
- "/org/freedesktop/DBus",
- "org.freedesktop.DBus");
-
- if (!dbus_g_proxy_call (proxy, "RequestName", &error,
- G_TYPE_STRING, NM_DBUS_SERVICE_USER_SETTINGS,
- G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
- G_TYPE_INVALID,
- G_TYPE_UINT, &request_name_result,
- G_TYPE_INVALID)) {
- g_warning ("Could not acquire the NetworkManagerUserSettings service.\n"
- " Message: '%s'", error->message);
- g_error_free (error);
- goto err;
- }
-
- if (request_name_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
- g_warning ("Could not acquire the NetworkManagerUserSettings service "
- "as it is already taken. Return: %d",
- request_name_result);
- goto err;
- }
-
- return bus;
-
- err:
- dbus_g_connection_unref (bus);
- return NULL;
-}
-
-static void
nmn_applet_init (NmnApplet *applet)
{
NmnAppletPrivate *priv = GET_PRIVATE (applet);
- DBusGConnection *bus;
GtkWidget *w;
GtkWidget *vbox;
GtkWidget *frame;
GtkWidget *table;
char *label;
- bus = init_dbus ();
- /* FIXME: Do something nicer here */
- g_assert (bus);
-
- priv->nm_data = nmn_nm_data_new (bus);
- dbus_g_connection_unref (bus);
-
- priv->status_icon = nmn_status_icon_new ();
-
- dbus_g_connection_register_g_object (nm_object_get_connection (NM_OBJECT (priv->nm_data)),
- NM_DBUS_PATH_SETTINGS,
- G_OBJECT (nmn_nm_data_get_user_settings (priv->nm_data)));
-
- nmn_status_icon_set_nm_client (priv->status_icon, NM_CLIENT (priv->nm_data));
-
priv->pane = gtk_hbox_new (FALSE, 6);
gtk_container_set_border_width (GTK_CONTAINER (priv->pane), 6);
+ gtk_box_pack_start (GTK_BOX (applet), priv->pane, TRUE, TRUE, 0);
/* left side (Networks list, add new connection button) */
vbox = gtk_vbox_new (FALSE, 6);
@@ -404,7 +316,7 @@ nmn_applet_init (NmnApplet *applet)
w = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (w), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- priv->list = nmn_networks_new (priv->nm_data);
+ priv->list = nmn_list_new ();
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (w), priv->list);
gtk_widget_show (priv->list);
gtk_box_pack_start (GTK_BOX (vbox), w, TRUE, TRUE, 0);
@@ -471,13 +383,6 @@ nmn_applet_init (NmnApplet *applet)
gtk_table_attach_defaults (GTK_TABLE (table), w, 0, 2, 1, 2);
gtk_widget_show_all (priv->pane);
-
-
- enable_wifi_setup (applet);
- enable_ethernet_setup (applet);
- enable_3g_setup (applet);
- enable_network_setup (applet);
- add_new_connection_setup (applet);
}
static GObject*
@@ -486,9 +391,8 @@ constructor (GType type,
GObjectConstructParam *construct_params)
{
GObject *object;
+ NmnApplet *applet;
NmnAppletPrivate *priv;
- GtkWidget *box;
- GtkWidget *window;
object = G_OBJECT_CLASS (nmn_applet_parent_class)->constructor
(type, n_construct_params, construct_params);
@@ -496,41 +400,22 @@ constructor (GType type,
if (!object)
return NULL;
- priv = GET_PRIVATE (object);
+ applet = NMN_APPLET (object);
+ priv = GET_PRIVATE (applet);
- if (!priv->panel_client && !priv->window) {
+ if (!priv->model) {
g_warning ("Missing constructor arguments");
g_object_unref (object);
return NULL;
}
- if (priv->panel_client && priv->window) {
- g_warning ("You can only use a PanelClient if you don't pass a window");
- g_object_unref (object);
- return NULL;
- }
-
- box = gtk_vbox_new (FALSE, 0);
- gtk_widget_show (priv->pane);
- gtk_box_pack_start (GTK_BOX (box), priv->pane, TRUE, TRUE, 0);
-
- gtk_widget_hide (priv->new_dialog);
- gtk_box_pack_end (GTK_BOX (box), priv->new_dialog, TRUE, TRUE, 0);
- gtk_widget_show (box);
- if (priv->panel_client)
- window = mpl_panel_gtk_get_window (MPL_PANEL_GTK (priv->panel_client));
- else
- window = GTK_WIDGET (priv->window);
- gtk_container_add (GTK_CONTAINER (window), box);
- gtk_widget_modify_bg (window, GTK_STATE_NORMAL, >k_widget_get_style (window)->white);
- gtk_widget_show (GTK_WIDGET (window));
-
- if (priv->panel_client) {
- g_signal_connect (priv->panel_client, "show-begin", G_CALLBACK (show_begin_cb), object);
- g_signal_connect (priv->panel_client, "hide-end", G_CALLBACK (hide_end_cb), object);
- } else {
- show_begin_cb (NULL, object);
- }
+ nmn_list_set_model (NMN_LIST (priv->list), GTK_TREE_MODEL (priv->model));
+ enable_wifi_setup (applet);
+ enable_ethernet_setup (applet);
+ enable_3g_setup (applet);
+ enable_network_setup (applet);
+ add_new_connection_setup (applet);
+ add_new_connection_hide (NULL, applet);
return object;
}
@@ -542,20 +427,9 @@ set_property (GObject *object, guint prop_id,
NmnAppletPrivate *priv = GET_PRIVATE (object);
switch (prop_id) {
- case PROP_PANEL_CLIENT:
+ case PROP_MODEL:
/* Construct only */
- priv->panel_client = g_value_dup_object (value);
- if (priv->panel_client)
- nmn_status_icon_set_panel_client (priv->status_icon, priv->panel_client);
- break;
- case PROP_WINDOW:
- /* Construct only */
- priv->window = g_value_dup_object (value);
- //FIXME we'd like to show a status icon somewhere though
-#if 0
- if (priv->window)
- nmn_status_icon_set_panel_client (priv->status_icon, priv->panel_client);
-#endif
+ priv->model = g_value_dup_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -570,8 +444,8 @@ get_property (GObject *object, guint prop_id,
NmnAppletPrivate *priv = GET_PRIVATE (object);
switch (prop_id) {
- case PROP_PANEL_CLIENT:
- g_value_set_object (value, priv->panel_client);
+ case PROP_MODEL:
+ g_value_set_object (value, priv->model);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -589,23 +463,8 @@ dispose (GObject *object)
priv->disposed = TRUE;
- if (priv->new_dialog)
- gtk_widget_destroy (priv->new_dialog);
-
- if (priv->pane)
- g_object_unref (priv->pane);
-
- if (priv->status_icon)
- g_object_unref (priv->status_icon);
-
- if (priv->nm_data)
- g_object_unref (priv->nm_data);
-
- if (priv->panel_client)
- g_object_unref (priv->panel_client);
-
- if (priv->window)
- g_object_unref (priv->window);
+ if (priv->model)
+ g_object_unref (priv->model);
G_OBJECT_CLASS (nmn_applet_parent_class)->dispose (object);
}
@@ -624,17 +483,10 @@ nmn_applet_class_init (NmnAppletClass *class)
/* properties */
g_object_class_install_property
- (object_class, PROP_PANEL_CLIENT,
- g_param_spec_object (NMN_APPLET_PANEL_CLIENT,
- "MplPanelClient",
- "Panel client",
- MPL_TYPE_PANEL_CLIENT,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
- g_object_class_install_property
- (object_class, PROP_WINDOW,
- g_param_spec_object (NMN_APPLET_WINDOW,
- "GtkWindow",
- "Top-level window",
- GTK_TYPE_WINDOW,
+ (object_class, PROP_MODEL,
+ g_param_spec_object (NMN_APPLET_MODEL,
+ "NmnModel",
+ "NmnModel",
+ NMN_TYPE_MODEL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}
diff --git a/src/nmn-applet.h b/src/nmn-applet.h
index d5a47ce..f03cc15 100644
--- a/src/nmn-applet.h
+++ b/src/nmn-applet.h
@@ -20,16 +20,11 @@
#ifndef NMN_APPLET_H
#define NMN_APPLET_H
-#include <glib-object.h>
#include <gtk/gtk.h>
-#include <moblin-panel/mpl-panel-client.h>
+#include "nmn-model.h"
G_BEGIN_DECLS
-#define APPLET_PREFS_PATH "/apps/nm-applet"
-#define PREF_DISABLE_CONNECTED_NOTIFICATIONS APPLET_PREFS_PATH "/disable-connected-notifications"
-#define PREF_DISABLE_DISCONNECTED_NOTIFICATIONS APPLET_PREFS_PATH "/disable-disconnected-notifications"
-
#define NMN_TYPE_APPLET (nmn_applet_get_type ())
#define NMN_APPLET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMN_TYPE_APPLET, NmnApplet))
#define NMN_APPLET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMN_TYPE_APPLET, NmnAppletClass))
@@ -37,21 +32,21 @@ G_BEGIN_DECLS
#define NMN_IS_APPLET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NMN_TYPE_APPLET))
#define NMN_APPLET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMN_TYPE_APPLET, NmnAppletClass))
-#define NMN_APPLET_PANEL_CLIENT "panel-client"
-#define NMN_APPLET_WINDOW "window"
+#define NMN_APPLET_MODEL "model"
typedef struct {
- GObject parent;
+ GtkVBox parent;
} NmnApplet;
typedef struct {
- GObjectClass parent;
+ GtkVBoxClass parent;
} NmnAppletClass;
GType nmn_applet_get_type (void);
-NmnApplet *nmn_applet_new (MplPanelClient *panel_client);
-NmnApplet *nmn_applet_new_standalone (GtkWindow *window);
+NmnApplet *nmn_applet_new (NmnModel *model);
+void nmn_applet_show (NmnApplet *applet);
+void nmn_applet_hide (NmnApplet *applet);
G_END_DECLS
diff --git a/src/nmn-item-renderer.c b/src/nmn-item-renderer.c
new file mode 100644
index 0000000..828c121
--- /dev/null
+++ b/src/nmn-item-renderer.c
@@ -0,0 +1,445 @@
+/* -*- 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-item-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"
+
+G_DEFINE_TYPE (NmnItemRenderer, nmn_item_renderer, GTK_TYPE_EVENT_BOX)
+
+enum {
+ PROP_0,
+ PROP_ITEM,
+
+ LAST_PROP
+};
+
+#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;
+
+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)
+{
+ NmnItemRendererPrivate *priv = GET_PRIVATE (self);
+ GdkColor *color;
+
+ if (priv->prelight) {
+ color = &priv->prelight_color;
+ } else {
+ if (NM_IS_CONNECTION_ITEM (priv->item) && nm_connection_item_get_connection (NM_CONNECTION_ITEM (priv->item)))
+ color = &priv->connection_item_color;
+ else
+ color = NULL;
+ }
+
+ gtk_widget_modify_bg (GTK_WIDGET (self), GTK_STATE_NORMAL, color);
+}
+
+static void
+update_details (NmnItemRenderer *self)
+{
+ NmnItemRendererPrivate *priv = GET_PRIVATE (self);
+ NMConnection *connection;
+ NMDevice *device;
+ NMSettingIP4Config *setting;
+ NMIP4Config *config;
+
+ if (!priv->details)
+ return;
+
+ connection = (NMConnection *) nm_connection_item_get_connection (NM_CONNECTION_ITEM (priv->item));
+ if (!connection)
+ return;
+
+ 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);
+ else
+ config = NULL;
+
+ nmn_connection_details_set_data (priv->details, setting, config);
+}
+
+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)) {
+ 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 = _("Disconnect");
+ 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
+ str = g_strdup_printf ("<big><b>%s</b></big>", nm_list_item_get_name (item));
+
+ 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);
+ }
+
+ 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));
+
+ if (!property || !strcmp (property, NM_LIST_ITEM_SHOW_DELETE)) {
+ if (nm_list_item_get_show_delete (item))
+ gtk_widget_show (priv->remove_button);
+ else
+ gtk_widget_hide (priv->remove_button);
+ }
+
+ if (!property || !strcmp (property, NM_CONNECTION_ITEM_CONNECTION)) {
+ update_background (self);
+
+ if (property && NM_IS_CONNECTION_ITEM (item) &&
+ !nm_connection_item_get_connection (NM_CONNECTION_ITEM (item))) {
+ str = g_strdup_printf ("<big><b>%s</b></big>", nm_list_item_get_name (item));
+ gtk_label_set_markup (priv->name_and_status, str);
+ g_free (str);
+ }
+ }
+}
+
+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)
+ nm_list_item_connect (item);
+ 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);
+}
+
+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)
+{
+ 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,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_REJECT,
+ GTK_STOCK_OK,
+ 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);
+
+ 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));
+}
+
+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));
+}
+
+void
+nmn_item_renderer_set_item (NmnItemRenderer *self,
+ NMListItem *item)
+{
+ NmnItemRendererPrivate *priv;
+
+ g_return_if_fail (NMN_IS_ITEM_RENDERER (self));
+ g_return_if_fail (NM_IS_LIST_ITEM (item));
+
+ 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);
+}
+
+static gboolean
+enter_notify_event (GtkWidget *widget,
+ GdkEventCrossing *event)
+{
+ NmnItemRendererPrivate *priv = GET_PRIVATE (widget);
+
+ priv->prelight = TRUE;
+ update_background (NMN_ITEM_RENDERER (widget));
+
+ return TRUE;
+}
+
+static gboolean
+leave_notify_event (GtkWidget *widget,
+ GdkEventCrossing *event)
+{
+ NmnItemRendererPrivate *priv = GET_PRIVATE (widget);
+
+ if (event->detail != GDK_NOTIFY_INFERIOR) {
+ priv->prelight = FALSE;
+ update_background (NMN_ITEM_RENDERER (widget));
+ }
+
+ return TRUE;
+}
+
+static void
+nmn_item_renderer_init (NmnItemRenderer *item)
+{
+ NmnItemRendererPrivate *priv = GET_PRIVATE (item);
+
+ gdk_color_parse ("#cbcbcb", &priv->prelight_color);
+ gdk_color_parse ("#e8e8e8", &priv->connection_item_color);
+}
+
+static void
+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;
+ }
+
+ G_OBJECT_CLASS (nmn_item_renderer_parent_class)->dispose (object);
+}
+
+static void
+nmn_item_renderer_class_init (NmnItemRendererClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+ g_type_class_add_private (object_class, sizeof (NmnItemRendererPrivate));
+
+ object_class->dispose = dispose;
+
+ widget_class->enter_notify_event = enter_notify_event;
+ widget_class->leave_notify_event = leave_notify_event;
+}
diff --git a/src/nmn-item-renderer.h b/src/nmn-item-renderer.h
new file mode 100644
index 0000000..a43337e
--- /dev/null
+++ b/src/nmn-item-renderer.h
@@ -0,0 +1,51 @@
+/* -*- 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_ITEM_RENDERER_H
+#define NMN_ITEM_RENDERER_H
+
+#include <gtk/gtk.h>
+#include <nm-list-item.h>
+
+#define NMN_TYPE_ITEM_RENDERER (nmn_item_renderer_get_type ())
+#define NMN_ITEM_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMN_TYPE_ITEM_RENDERER, NmnItemRenderer))
+#define NMN_ITEM_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMN_TYPE_ITEM_RENDERER, NmnItemRendererClass))
+#define NMN_IS_ITEM_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMN_TYPE_ITEM_RENDERER))
+#define NMN_IS_ITEM_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NMN_TYPE_ITEM_RENDERER))
+#define NMN_ITEM_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMN_TYPE_ITEM_RENDERER, NmnItemRendererClass))
+
+typedef struct {
+ GtkEventBox parent;
+
+ GtkTreeIter iter;
+ int index;
+} NmnItemRenderer;
+
+typedef struct {
+ GtkEventBoxClass parent;
+} 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);
+
+#endif /* NMN_ITEM_RENDERER_H */
diff --git a/src/nmn-list.c b/src/nmn-list.c
index b712981..fc6a70c 100644
--- a/src/nmn-list.c
+++ b/src/nmn-list.c
@@ -18,19 +18,27 @@
*/
#include <string.h>
+#include <glib/gi18n.h>
+#include <nm-list-model.h>
+#include <nm-list-item.h>
#include "nmn-list.h"
-
-#define NMN_DRAG_TARGET "NMN_DRAG_TARGET"
-static const GtkTargetEntry nmn_list_targets [] = {
- { NMN_DRAG_TARGET, GTK_TARGET_SAME_APP, 0 },
-};
+#include "nmn-model.h"
+#include "nmn-item-renderer.h"
G_DEFINE_TYPE (NmnList, nmn_list, GTK_TYPE_VBOX)
-#define NMN_LIST_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NMN_TYPE_LIST, NmnListPrivate))
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NMN_TYPE_LIST, NmnListPrivate))
typedef struct {
- GtkWidget *dnd_window;
+ GtkTreeModel *model;
+ GSList *rows;
+
+ gulong row_deleted_id;
+ gulong row_inserted_id;
+ gulong rows_reordered_id;
+ guint layout_idle_id;
+
+ gboolean disposed;
} NmnListPrivate;
GtkWidget *
@@ -39,319 +47,381 @@ nmn_list_new (void)
return GTK_WIDGET (g_object_new (NMN_TYPE_LIST, NULL));
}
-typedef struct {
- GtkWidget *needle;
- int counter;
- int found;
-} ContainerPosInfo;
-
-static void
-get_position_cb (GtkWidget *widget, gpointer data)
+GtkWidget *
+nmn_list_new_with_model (GtkTreeModel *model)
{
- ContainerPosInfo *info = (ContainerPosInfo *) data;
+ GtkWidget *list;
+
+ list = nmn_list_new ();
+ if (list)
+ nmn_list_set_model (NMN_LIST (list), model);
+
+ return list;
+}
- if (widget == info->needle)
- info->found = info->counter;
+static const char *
+get_punctuation (guint items_left)
+{
+ if (items_left > 1)
+ return ", ";
+ if (items_left == 1)
+ return _(" and ");
- info->counter++;
+ /* items_left == 0 */
+ return ".";
}
-static int
-container_get_position (GtkContainer *container, GtkWidget *child)
+static char *
+get_empty_text (NmnModel *model)
{
- ContainerPosInfo info;
+ GString *string;
- info.counter = 0;
- info.found = -1;
- info.needle = child;
+ string = g_string_new (_("Sorry, we can't find any networks."));
- gtk_container_foreach (container, get_position_cb, &info);
+ if (nmn_model_offline_mode_get_active (model)) {
+ g_string_append (string, _(" You could try disabling Offline mode."));
+ } else {
+ gboolean wifi_enabled;
+ gboolean ethernet_enabled;
+ gboolean modem_enabled;
+ guint disabled_count = 0;
+
+ wifi_enabled = nmn_model_wifi_get_active (model);
+ if (!wifi_enabled)
+ disabled_count++;
+
+ ethernet_enabled = nmn_model_ethernet_get_active (model);
+ if (!ethernet_enabled)
+ disabled_count++;
+
+ modem_enabled = nmn_model_modems_get_active (model);
+ if (!modem_enabled)
+ disabled_count++;
+
+ if (disabled_count > 0) {
+ g_string_append (string, _(" You could try turning on "));
+
+ if (!wifi_enabled) {
+ g_string_append (string, _("WiFi"));
+ g_string_append (string, get_punctuation (--disabled_count));
+ }
+
+ if (!ethernet_enabled) {
+ g_string_append (string, _("Wired"));
+ g_string_append (string, get_punctuation (--disabled_count));
+ }
+
+ if (!modem_enabled) {
+ g_string_append (string, _("3G"));
+ g_string_append (string, get_punctuation (--disabled_count));
+ }
+ }
+ }
- return info.found;
+ return g_string_free (string, FALSE);
}
static void
-drag_begin (GtkWidget *widget, GdkDragContext *drag_context, gpointer user_data)
+nmn_list_clear (NmnList *self)
{
- NmnListPrivate *priv = NMN_LIST_GET_PRIVATE (user_data);
-
- g_object_set_data (G_OBJECT (widget), "original-location",
- GINT_TO_POINTER (container_get_position (GTK_CONTAINER (user_data), widget)));
-
- g_object_ref (widget);
- gtk_container_remove (GTK_CONTAINER (user_data), widget);
+ GtkContainer *container = GTK_CONTAINER (self);
+ GList *list;
+ GList *iter;
- priv->dnd_window = gtk_window_new (GTK_WINDOW_POPUP);
- gtk_container_add (GTK_CONTAINER (priv->dnd_window), widget);
- g_object_unref (widget);
+ list = gtk_container_get_children (container);
+ for (iter = list; iter; iter = iter->next)
+ gtk_container_remove (container, GTK_WIDGET (iter->data));
- gtk_drag_set_icon_widget (drag_context, priv->dnd_window, -2, -2);
+ g_list_free (list);
}
static void
-drag_data_get (GtkWidget *widget,
- GdkDragContext *context,
- GtkSelectionData *data,
- guint info,
- guint time)
+switches_flipped (NmnList *self)
{
- if (data->target == gdk_atom_intern_static_string (NMN_DRAG_TARGET)) {
- gtk_selection_data_set (data,
- data->target,
- 8,
- (void*) &widget,
- sizeof (gpointer));
- }
+ NmnListPrivate *priv = GET_PRIVATE (self);
+ char *txt, *s;
+ GtkWidget *w;
+
+ if (priv->rows || !NMN_IS_MODEL (priv->model))
+ return;
+
+ nmn_list_clear (self);
+
+ txt = get_empty_text (NMN_MODEL (priv->model));
+ s = g_strdup_printf ("<big><b>%s</b></big>", txt);
+ g_free (txt);
+
+ w = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5);
+ gtk_label_set_markup (GTK_LABEL (w), s);
+ g_free (s);
+
+ gtk_box_pack_start (GTK_BOX (self), w, FALSE, FALSE, 0);
+ gtk_widget_show (w);
}
-static gboolean
-drag_failed (GtkWidget *widget,
- GdkDragContext *drag_context,
- GtkDragResult result,
- gpointer user_data)
+static void
+nmn_list_layout (NmnList *self)
{
- if (result != GTK_DRAG_RESULT_SUCCESS) {
- NmnListPrivate *priv = NMN_LIST_GET_PRIVATE (user_data);
+ NmnListPrivate *priv = GET_PRIVATE (self);
+ GSList *iter;
- g_debug ("drag failed");
- g_object_ref (widget);
- gtk_container_remove (GTK_CONTAINER (priv->dnd_window), widget);
- gtk_box_pack_start (GTK_BOX (user_data), widget, FALSE, FALSE, 0);
- gtk_box_reorder_child (GTK_BOX (user_data), widget,
- GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "original-location")));
+ if (priv->layout_idle_id) {
+ g_source_remove (priv->layout_idle_id);
+ priv->layout_idle_id = 0;
+ }
- g_object_unref (widget);
+ /* FIXME: This could probably be much more efficient, especially for cases where
+ a single item is added to the end of the list or a single item changes it's location */
- return TRUE;
+ nmn_list_clear (self);
+ switches_flipped (self);
+
+ for (iter = priv->rows; iter; iter = iter->next) {
+ NmnItemRenderer *renderer = iter->data;
+ NMListItem *item;
+
+ item = nmn_item_renderer_get_item (renderer);
+ if (!item) {
+ GtkTreeIter iter;
+
+ if (gtk_tree_model_get_flags (priv->model) & GTK_TREE_MODEL_ITERS_PERSIST)
+ iter = renderer->iter;
+ else {
+ GtkTreePath *path;
+
+ path = gtk_tree_path_new_from_indices (renderer->index, -1);
+ gtk_tree_model_get_iter (priv->model, &iter, path);
+ gtk_tree_path_free (path);
+ }
+
+ gtk_tree_model_get (priv->model, &iter, NM_LIST_MODEL_COL_ITEM, &item, -1);
+ if (item)
+ nmn_item_renderer_set_item (renderer, item);
+ }
+
+ if (item) {
+ gtk_box_pack_start (GTK_BOX (self), GTK_WIDGET (renderer), FALSE, FALSE, 0);
+ gtk_widget_show (GTK_WIDGET (renderer));
+ }
}
+}
+
+static gboolean
+queue_layout_cb (gpointer data)
+{
+ NmnListPrivate *priv = GET_PRIVATE (data);
+
+ priv->layout_idle_id = 0;
+ nmn_list_layout (NMN_LIST (data));
return FALSE;
}
static void
-drag_end (GtkWidget *widget, GdkDragContext *drag_context, gpointer user_data)
+queue_layout (NmnList *self)
{
- NmnListPrivate *priv = NMN_LIST_GET_PRIVATE (user_data);
+ NmnListPrivate *priv = GET_PRIVATE (self);
- g_debug ("drag end");
- GTK_BIN (priv->dnd_window)->child = NULL;
- gtk_widget_destroy (priv->dnd_window);
+ if (!priv->layout_idle_id)
+ priv->layout_idle_id = g_idle_add (queue_layout_cb, self);
}
-static gint
-compare_items (gconstpointer a,
- gconstpointer b)
+static void
+model_row_deleted (GtkTreeModel *model,
+ GtkTreePath *path,
+ gpointer user_data)
{
- NmnItem *a_item = NMN_ITEM (a);
- NmnItem *b_item = NMN_ITEM (b);
- char *a_label;
- char *b_label;
- guint a_priority;
- guint b_priority;
- gint result;
-
- a_priority = nmn_item_get_priority (a_item);
- b_priority = nmn_item_get_priority (b_item);
-
- if (a_priority < b_priority)
- return 1;
-
- if (a_priority > b_priority)
- return -1;
-
- a_label = nmn_item_get_name (a_item);
- b_label = nmn_item_get_name (b_item);
-
- if (a_label) {
- if (b_label)
- result = strcmp (a_label, b_label);
- else
- result = 1;
- } else
- result = -1;
-
- g_free (a_label);
- g_free (b_label);
-
- return result;
+ NmnList *self = NMN_LIST (user_data);
+ NmnListPrivate *priv = GET_PRIVATE (self);
+ GSList *list;
+ GSList *next;
+ NmnItemRenderer *renderer;
+ int index;
+
+ index = gtk_tree_path_get_indices(path)[0];
+ list = g_slist_nth (priv->rows, index);
+ renderer = list->data;
+ g_object_unref (renderer);
+
+ for (next = list->next; next; next = next->next) {
+ renderer = next->data;
+ renderer->index--;
+ }
+
+ priv->rows = g_slist_delete_link (priv->rows, list);
+ queue_layout (self);
}
static void
-nmn_list_sort (NmnList *list)
+model_row_inserted (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data)
{
- GList *items;
- GList *iter;
- int i;
-
- items = gtk_container_get_children (GTK_CONTAINER (list));
- items = g_list_sort (items, compare_items);
- i = 0;
+ NmnList *self = NMN_LIST (user_data);
+ NmnListPrivate *priv = GET_PRIVATE (self);
+ NmnItemRenderer *renderer;
+ GSList *list;
+ int index;
+
+ index = gtk_tree_path_get_indices (path)[0];
+
+ renderer = (NmnItemRenderer *) nmn_item_renderer_new ();
+ renderer->index = index;
+
+ if (gtk_tree_model_get_flags (model) & GTK_TREE_MODEL_ITERS_PERSIST)
+ renderer->iter = *iter;
+
+ priv->rows = g_slist_insert (priv->rows, g_object_ref_sink (renderer), index);
+
+ list = g_slist_nth (priv->rows, index + 1);
+ for (; list; list = list->next) {
+ renderer = list->data;
+ renderer->index++;
+ }
- for (iter = items; iter; iter = iter->next)
- gtk_box_reorder_child (GTK_BOX (list), GTK_WIDGET (iter->data), i++);
+ queue_layout (self);
}
-void
-nmn_list_add_item (NmnList *list,
- NmnItem *item)
+static void
+model_rows_reordered (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gint *new_order,
+ gpointer user_data)
{
- g_return_if_fail (NMN_IS_LIST (list));
- g_return_if_fail (NMN_IS_ITEM (item));
-
- /* FIXME: See http://bugzilla.moblin.org/show_bug.cgi?id=5499
- and https://bugzilla.novell.com/show_bug.cgi?id=528715 */
-#if 0
- gtk_drag_source_set (GTK_WIDGET (item), GDK_BUTTON1_MASK,
- nmn_list_targets, G_N_ELEMENTS (nmn_list_targets),
- GDK_ACTION_MOVE);
-#endif
-
- g_signal_connect (item, "drag-begin",
- G_CALLBACK (drag_begin),
- list);
-
- g_signal_connect (item, "drag-data-get",
- G_CALLBACK (drag_data_get),
- list);
-
- g_signal_connect (item, "drag-failed",
- G_CALLBACK (drag_failed),
- list);
-
- g_signal_connect (item, "drag-end",
- G_CALLBACK (drag_end),
- list);
-
- g_signal_connect_swapped (item, "notify",
- G_CALLBACK (nmn_list_sort),
- list);
-
- gtk_box_pack_start (GTK_BOX (list), GTK_WIDGET (item), FALSE, FALSE, 0);
- nmn_list_sort (list);
- gtk_widget_show (GTK_WIDGET (item));
-}
+ NmnList *self = NMN_LIST (user_data);
+ NmnListPrivate *priv = GET_PRIVATE (self);
+ GSList *list;
+ NmnItemRenderer **renderer_array;
+ GSList *rows = NULL;
+ gint *order;
+ int length;
+ int i;
+ length = gtk_tree_model_iter_n_children (model, NULL);
-typedef struct {
- GtkWidget *match;
- gint match_position;
- gint y;
- gint counter;
-} FindActiveInfo;
+ order = g_new (int, length);
+ for (i = 0; i < length; i++)
+ order[new_order[i]] = i;
-static void
-find_active_item_cb (GtkWidget *widget, gpointer data)
-{
- FindActiveInfo *info = (FindActiveInfo *) data;
+ renderer_array = g_new (NmnItemRenderer *, length);
+ for (i = 0, list = priv->rows; list != NULL; list = list->next, i++)
+ renderer_array[order[i]] = list->data;
+ g_free (order);
- if (widget->allocation.y <= info->y && widget->allocation.y + widget->allocation.height > info->y) {
- info->match = widget;
- info->match_position = info->counter;
+ for (i = length - 1; i >= 0; i--) {
+ renderer_array[i]->index = i;
+ rows = g_slist_prepend (rows, renderer_array[i]);
}
+
+ g_free (renderer_array);
+ g_slist_free (priv->rows);
+ priv->rows = rows;
- info->counter++;
+ queue_layout (self);
}
static gboolean
-find_active_item (GtkContainer *container, gint y, GtkWidget **active_widget, gint *active_position)
+model_foreach_cb (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data)
{
- FindActiveInfo info;
-
- info.match = NULL;
- info.match_position = 0;
- info.counter = 0;
- info.y = y;
- gtk_container_foreach (container, find_active_item_cb, &info);
+ model_row_inserted (model, path, iter, user_data);
- if (info.match) {
- *active_widget = info.match;
- *active_position = info.match_position;
- }
-
- return info.match != NULL;
+ return FALSE;
}
-static gboolean
-nmn_list_drag_drop (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- guint time)
+void
+nmn_list_set_model (NmnList *list,
+ GtkTreeModel *model)
{
- GdkAtom target, item_target;
+ NmnListPrivate *priv;
+
+ g_return_if_fail (NMN_IS_LIST (list));
+
+ priv = GET_PRIVATE (list);
- g_debug ("drag_drop1");
- target = gtk_drag_dest_find_target (widget, context, NULL);
- item_target = gdk_atom_intern_static_string (NMN_DRAG_TARGET);
+ if (model == priv->model)
+ return;
- if (target == item_target) {
- gtk_drag_get_data (widget, context, target, time);
- g_debug ("drag_drop2");
- return TRUE;
+ if (priv->model) {
+ if (NMN_IS_MODEL (priv->model))
+ g_signal_handlers_disconnect_by_func (priv->model, switches_flipped, list);
+
+ g_signal_handler_disconnect (priv->model, priv->row_deleted_id);
+ g_signal_handler_disconnect (priv->model, priv->row_inserted_id);
+ g_signal_handler_disconnect (priv->model, priv->rows_reordered_id);
+
+ g_object_unref (priv->model);
}
- g_debug ("drag_drop3");
- return FALSE;
+ priv->model = model;
+
+ if (priv->model) {
+ g_object_ref (priv->model);
+
+ priv->row_deleted_id = g_signal_connect (model, "row-deleted", G_CALLBACK (model_row_deleted), list);
+ priv->row_inserted_id = g_signal_connect (model, "row-inserted", G_CALLBACK (model_row_inserted), list);
+ priv->rows_reordered_id = g_signal_connect (model, "rows-reordered", G_CALLBACK (model_rows_reordered), list);
+
+ gtk_tree_model_foreach (model, model_foreach_cb, list);
+
+ if (NMN_IS_MODEL (model)) {
+ g_signal_connect_swapped (model, "ethernet-toggled", G_CALLBACK (switches_flipped), list);
+ g_signal_connect_swapped (model, "wifi-toggled", G_CALLBACK (switches_flipped), list);
+ g_signal_connect_swapped (model, "modems-toggled", G_CALLBACK (switches_flipped), list);
+ g_signal_connect_swapped (model, "offline-mode-toggled", G_CALLBACK (switches_flipped), list);
+ }
+ }
}
-static void
-nmn_list_drag_data_received (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- GtkSelectionData *data,
- guint info,
- guint time)
+GtkTreeModel *
+nmn_list_get_model (NmnList *list)
{
- GtkWidget *source_widget;
- NmnListPrivate *priv = NMN_LIST_GET_PRIVATE (widget);
-
- g_debug ("data_received1");
- source_widget = gtk_drag_get_source_widget (context);
- if (source_widget && data->target == gdk_atom_intern_static_string (NMN_DRAG_TARGET)) {
- GtkWidget *active_widget;
- gint active_position = -1;
-
- g_debug ("data_received2");
- find_active_item (GTK_CONTAINER (widget), y, &active_widget, &active_position);
-
- g_object_ref (source_widget);
- g_print ("child %p, source_widget: %p target: %p\n", GTK_BIN (priv->dnd_window)->child, source_widget, (void*) data->data);
- gtk_container_remove (GTK_CONTAINER (priv->dnd_window), source_widget);
- gtk_box_pack_start (GTK_BOX (widget), source_widget, FALSE, FALSE, 0);
- gtk_box_reorder_child (GTK_BOX (widget), source_widget, active_position);
- g_object_unref (source_widget);
-
- gtk_drag_finish (context, TRUE, FALSE, time);
- } else {
- g_debug ("data_received3");
- gtk_drag_finish (context, FALSE, FALSE, time);
- }
+ g_return_val_if_fail (NMN_IS_LIST (list), NULL);
- g_debug ("data_received4");
+ return GET_PRIVATE (list)->model;
}
+/*****************************************************************************/
+
static void
nmn_list_init (NmnList *list)
{
- gtk_drag_dest_set (GTK_WIDGET (list),
- GTK_DEST_DEFAULT_ALL,
- nmn_list_targets,
- G_N_ELEMENTS (nmn_list_targets),
- GDK_ACTION_MOVE);
-
gtk_box_set_homogeneous (GTK_BOX (list), FALSE);
- gtk_box_set_spacing (GTK_BOX (list), 12);
+ gtk_box_set_spacing (GTK_BOX (list), 6);
+ gtk_container_set_border_width (GTK_CONTAINER (list), 6);
+}
+
+static void
+dispose (GObject *object)
+{
+ NmnListPrivate *priv = GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ if (priv->layout_idle_id)
+ g_source_remove (priv->layout_idle_id);
+
+ g_slist_foreach (priv->rows, (GFunc) g_object_unref, NULL);
+ g_slist_free (priv->rows);
+
+ nmn_list_set_model (NMN_LIST (object), NULL);
+
+ priv->disposed = TRUE;
+ }
+
+ G_OBJECT_CLASS (nmn_list_parent_class)->dispose (object);
}
static void
nmn_list_class_init (NmnListClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
g_type_class_add_private (object_class, sizeof (NmnListPrivate));
- widget_class->drag_drop = nmn_list_drag_drop;
- widget_class->drag_data_received = nmn_list_drag_data_received;
+ object_class->dispose = dispose;
}
diff --git a/src/nmn-list.h b/src/nmn-list.h
index f1d62f3..8d6a4b4 100644
--- a/src/nmn-list.h
+++ b/src/nmn-list.h
@@ -21,7 +21,6 @@
#define NMN_LIST_H
#include <gtk/gtk.h>
-#include <nmn-item.h>
#define NMN_TYPE_LIST (nmn_list_get_type ())
#define NMN_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMN_TYPE_LIST, NmnList))
@@ -40,8 +39,11 @@ typedef struct {
GType nmn_list_get_type (void);
-GtkWidget *nmn_list_new (void);
-void nmn_list_add_item (NmnList *list,
- NmnItem *item);
+GtkWidget *nmn_list_new (void);
+GtkWidget *nmn_list_new_with_model (GtkTreeModel *model);
+void nmn_list_set_model (NmnList *list,
+ GtkTreeModel *model);
+
+GtkTreeModel *nmn_list_get_model (NmnList *list);
#endif /* NMN_LIST_H */
diff --git a/src/nmn-model.c b/src/nmn-model.c
new file mode 100644
index 0000000..0e14490
--- /dev/null
+++ b/src/nmn-model.c
@@ -0,0 +1,433 @@
+/* -*- 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 <nm-remote-settings-system.h>
+#include "nmn-model.h"
+#include "nm-list-model.h"
+#include "nm-gconf-settings.h"
+#include "nm-list-item.h"
+#include "nm-ethernet-item.h"
+#include "nm-wifi-item.h"
+#include "nm-gsm-item.h"
+#include "nm-cdma-item.h"
+
+G_DEFINE_TYPE (NmnModel, nmn_model, GTK_TYPE_TREE_MODEL_FILTER)
+
+enum {
+ ETHERNET_TOGGLED,
+ WIFI_TOGGLED,
+ MODEMS_TOGGLED,
+ OFFLINE_MODE_TOGGLED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NMN_TYPE_MODEL, NmnModelPrivate))
+
+typedef struct {
+ NMClient *client;
+ NMSettingsInterface *user_settings;
+ NMSettingsInterface *system_settings;
+
+ gboolean ethernet_active;
+ gboolean wifi_active;
+ gboolean modems_active;
+ gboolean offline_mode_active;
+
+ gboolean disposed;
+} NmnModelPrivate;
+
+NmnModel *
+nmn_model_new (void)
+{
+ NmnModel *model;
+ NMClient *client;
+ NMListModel *child_model;
+
+ client = nm_client_new ();
+ child_model = nm_list_model_new (client);
+ g_object_unref (client);
+
+ model = (NmnModel *) g_object_new (NMN_TYPE_MODEL,
+ "child-model", child_model,
+ NULL);
+
+ g_object_unref (child_model);
+
+ return model;
+}
+
+NMClient *
+nmn_model_get_client (NmnModel *self)
+{
+ g_return_val_if_fail (NMN_IS_MODEL (self), NULL);
+
+ return GET_PRIVATE (self)->client;
+}
+
+NMSettingsInterface *
+nmn_model_get_user_settings (NmnModel *self)
+{
+ g_return_val_if_fail (NMN_IS_MODEL (self), NULL);
+
+ return GET_PRIVATE (self)->user_settings;
+}
+
+NMSettingsInterface *
+nmn_model_get_system_settings (NmnModel *self)
+{
+ g_return_val_if_fail (NMN_IS_MODEL (self), NULL);
+
+ return GET_PRIVATE (self)->system_settings;
+}
+
+gboolean
+nmn_model_ethernet_get_active (NmnModel *self)
+{
+ g_return_val_if_fail (NMN_IS_MODEL (self), FALSE);
+
+ return GET_PRIVATE (self)->ethernet_active;
+}
+
+void
+nmn_model_ethernet_toggled (NmnModel *self,
+ gboolean active)
+{
+ NmnModelPrivate *priv;
+
+ g_return_if_fail (NMN_IS_MODEL (self));
+
+ priv = GET_PRIVATE (self);
+ if (priv->ethernet_active != active) {
+ /* FIXME: Save in gconf? */
+ priv->ethernet_active = active;
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (self));
+
+ g_signal_emit (self, signals[ETHERNET_TOGGLED], 0, active);
+ }
+}
+
+gboolean
+nmn_model_wifi_can_change (NmnModel *self)
+{
+ g_return_val_if_fail (NMN_IS_MODEL (self), FALSE);
+
+ return nm_client_wireless_hardware_get_enabled (nmn_model_get_client (self));
+}
+
+gboolean
+nmn_model_wifi_get_active (NmnModel *self)
+{
+ g_return_val_if_fail (NMN_IS_MODEL (self), FALSE);
+
+ return GET_PRIVATE (self)->wifi_active;
+}
+
+static void
+wifi_toggled_internal (NmnModel *self, gboolean active)
+{
+ NmnModelPrivate *priv = GET_PRIVATE (self);
+
+ if (priv->wifi_active != active) {
+ /* FIXME: Save in gconf? */
+ priv->wifi_active = active;
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (self));
+
+ g_signal_emit (self, signals[WIFI_TOGGLED], 0, active);
+ }
+}
+
+void
+nmn_model_wifi_toggled (NmnModel *self,
+ gboolean active)
+{
+ g_return_if_fail (NMN_IS_MODEL (self));
+
+ wifi_toggled_internal (self, active);
+ nm_client_wireless_set_enabled (nmn_model_get_client (self), active);
+}
+
+gboolean
+nmn_model_modems_get_active (NmnModel *self)
+{
+ g_return_val_if_fail (NMN_IS_MODEL (self), FALSE);
+
+ return GET_PRIVATE (self)->modems_active;
+}
+
+void
+nmn_model_modems_toggled (NmnModel *self,
+ gboolean active)
+{
+ NmnModelPrivate *priv;
+
+ g_return_if_fail (NMN_IS_MODEL (self));
+
+ priv = GET_PRIVATE (self);
+ if (priv->modems_active != active) {
+ /* FIXME: Save in gconf? */
+ priv->modems_active = active;
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (self));
+
+ g_signal_emit (self, signals[MODEMS_TOGGLED], 0, active);
+ }
+}
+
+gboolean
+nmn_model_offline_mode_get_active (NmnModel *self)
+{
+ g_return_val_if_fail (NMN_IS_MODEL (self), FALSE);
+
+ return GET_PRIVATE (self)->offline_mode_active;
+}
+
+static void
+offline_mode_toggled_internal (NmnModel *self, gboolean active)
+{
+ NmnModelPrivate *priv = GET_PRIVATE (self);
+
+ if (priv->offline_mode_active != active) {
+ /* FIXME: Save in gconf? */
+ priv->offline_mode_active = active;
+ gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (self));
+
+ g_signal_emit (self, signals[OFFLINE_MODE_TOGGLED], 0, active);
+ }
+}
+
+void
+nmn_model_offline_mode_toggled (NmnModel *self,
+ gboolean active)
+{
+ g_return_if_fail (NMN_IS_MODEL (self));
+
+ offline_mode_toggled_internal (self, active);
+ nm_client_sleep (nmn_model_get_client (self), active);
+}
+
+static void
+nm_client_state_changed (NMClient *client,
+ GParamSpec *gobject,
+ gpointer user_data)
+{
+ offline_mode_toggled_internal (NMN_MODEL (user_data), nm_client_get_state (client) == NM_STATE_ASLEEP);
+}
+
+static void
+nm_wireless_state_changed (NMClient *client,
+ GParamSpec *gobject,
+ gpointer user_data)
+{
+ wifi_toggled_internal (NMN_MODEL (user_data), nm_client_wireless_get_enabled (client));
+}
+
+static gboolean
+model_row_visible_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ NMListItem *item = NULL;
+ gboolean visible = FALSE;
+
+ gtk_tree_model_get (model, iter, NM_LIST_MODEL_COL_ITEM, &item, -1);
+ if (item) {
+ NmnModelPrivate *priv = GET_PRIVATE (data);
+
+ if (priv->offline_mode_active)
+ visible = FALSE;
+ else if (NM_IS_WIFI_ITEM (item))
+ visible = priv->wifi_active;
+ else if (NM_IS_ETHERNET_ITEM (item))
+ visible = priv->ethernet_active;
+ else if (NM_IS_GSM_ITEM (item))
+ visible = priv->modems_active;
+ else if (NM_IS_CDMA_ITEM (item))
+ visible = priv->modems_active;
+
+ g_object_unref (item);
+ }
+
+ return visible;
+}
+
+static gboolean
+request_dbus_name (DBusGConnection *bus)
+{
+ DBusGProxy *proxy;
+ GError *error = NULL;
+ int request_name_result;
+
+ dbus_connection_set_change_sigpipe (TRUE);
+ dbus_connection_set_exit_on_disconnect (dbus_g_connection_get_connection (bus), FALSE);
+
+ proxy = dbus_g_proxy_new_for_name (bus,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus");
+
+ if (!dbus_g_proxy_call (proxy, "RequestName", &error,
+ G_TYPE_STRING, NM_DBUS_SERVICE_USER_SETTINGS,
+ G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &request_name_result,
+ G_TYPE_INVALID)) {
+ g_warning ("Could not acquire the NetworkManagerUserSettings service.\n"
+ " Message: '%s'", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ if (request_name_result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+ g_warning ("Could not acquire the NetworkManagerUserSettings service "
+ "as it is already taken. Return: %d",
+ request_name_result);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+nmn_model_init (NmnModel *model)
+{
+ NmnModelPrivate *priv = GET_PRIVATE (model);
+
+ gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (model),
+ model_row_visible_func, model, NULL);
+
+ /* FIXME: Load from gconf? */
+ priv->ethernet_active = TRUE;
+ priv->wifi_active = TRUE;
+ priv->modems_active = TRUE;
+ priv->offline_mode_active = FALSE;
+}
+
+static void
+constructed (GObject *object)
+{
+ NmnModelPrivate *priv = GET_PRIVATE (object);
+ NMListModel *child_model;
+ DBusGConnection *bus;
+
+ if (G_OBJECT_CLASS (nmn_model_parent_class)->constructed)
+ G_OBJECT_CLASS (nmn_model_parent_class)->constructed (object);
+
+ child_model = NM_LIST_MODEL (gtk_tree_model_filter_get_model (GTK_TREE_MODEL_FILTER (object)));
+
+ priv->client = nm_list_model_get_client (child_model);
+ bus = nm_object_get_connection (NM_OBJECT (priv->client));
+
+ priv->user_settings = NM_SETTINGS_INTERFACE (nm_gconf_settings_new (bus));
+ priv->system_settings = NM_SETTINGS_INTERFACE (nm_remote_settings_system_new (bus));
+
+ nm_list_model_add_settings (child_model, priv->user_settings);
+ nm_list_model_add_settings (child_model, priv->system_settings);
+
+ g_signal_connect (priv->client,
+ "notify::" NM_CLIENT_STATE,
+ G_CALLBACK (nm_client_state_changed),
+ object);
+
+ g_signal_connect (priv->client,
+ "notify::" NM_CLIENT_WIRELESS_ENABLED,
+ G_CALLBACK (nm_wireless_state_changed),
+ object);
+
+ g_signal_connect (priv->client,
+ "notify::" NM_CLIENT_WIRELESS_HARDWARE_ENABLED,
+ G_CALLBACK (nm_wireless_state_changed),
+ object);
+
+ nm_wireless_state_changed (priv->client, NULL, object);
+ nm_client_state_changed (priv->client, NULL, object);
+
+ if (request_dbus_name (bus))
+ dbus_g_connection_register_g_object (bus, NM_DBUS_PATH_SETTINGS, G_OBJECT (priv->user_settings));
+}
+
+static void
+dispose (GObject *object)
+{
+ NmnModelPrivate *priv = GET_PRIVATE (object);
+
+ if (!priv->disposed) {
+ g_signal_handlers_disconnect_by_func (priv->client, gtk_tree_model_filter_refilter, object);
+
+ g_object_unref (priv->user_settings);
+ g_object_unref (priv->system_settings);
+
+ priv->disposed = TRUE;
+ }
+
+ G_OBJECT_CLASS (nmn_model_parent_class)->dispose (object);
+}
+
+static void
+nmn_model_class_init (NmnModelClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ g_type_class_add_private (object_class, sizeof (NmnModelPrivate));
+
+ object_class->constructed = constructed;
+ object_class->dispose = dispose;
+
+ /* signals */
+ signals[ETHERNET_TOGGLED] = g_signal_new
+ ("ethernet-toggled",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NmnModelClass, ethernet_toggled),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1,
+ G_TYPE_BOOLEAN);
+
+ signals[WIFI_TOGGLED] = g_signal_new
+ ("wifi-toggled",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NmnModelClass, wifi_toggled),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1,
+ G_TYPE_BOOLEAN);
+
+ signals[MODEMS_TOGGLED] = g_signal_new
+ ("modems-toggled",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NmnModelClass, modems_toggled),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1,
+ G_TYPE_BOOLEAN);
+
+ signals[OFFLINE_MODE_TOGGLED] = g_signal_new
+ ("offline-mode-toggled",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (NmnModelClass, offline_mode_toggled),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1,
+ G_TYPE_BOOLEAN);
+}
diff --git a/src/nmn-model.h b/src/nmn-model.h
new file mode 100644
index 0000000..a74e3e4
--- /dev/null
+++ b/src/nmn-model.h
@@ -0,0 +1,80 @@
+/* -*- 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_MODEL_H
+#define NMN_MODEL_H
+
+#include <gtk/gtk.h>
+#include <nm-client.h>
+#include <nm-settings-interface.h>
+
+#define NMN_TYPE_MODEL (nmn_model_get_type ())
+#define NMN_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMN_TYPE_MODEL, NmnModel))
+#define NMN_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMN_TYPE_MODEL, NmnModelClass))
+#define NMN_IS_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMN_TYPE_MODEL))
+#define NMN_IS_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NMN_TYPE_MODEL))
+#define NMN_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMN_TYPE_MODEL, NmnModelClass))
+
+typedef struct {
+ GtkTreeModelFilter parent;
+} NmnModel;
+
+typedef struct {
+ GtkTreeModelFilterClass parent;
+
+ /* Signals */
+ void (*ethernet_toggled) (NmnModel *self,
+ gboolean active);
+
+ void (*wifi_toggled) (NmnModel *self,
+ gboolean active);
+
+ void (*modems_toggled) (NmnModel *self,
+ gboolean active);
+
+ void (*offline_mode_toggled) (NmnModel *self,
+ gboolean active);
+} NmnModelClass;
+
+GType nmn_model_get_type (void);
+
+NmnModel *nmn_model_new (void);
+NMClient *nmn_model_get_client (NmnModel *self);
+
+NMSettingsInterface *nmn_model_get_user_settings (NmnModel *self);
+NMSettingsInterface *nmn_model_get_system_settings (NmnModel *self);
+
+gboolean nmn_model_ethernet_get_active (NmnModel *self);
+void nmn_model_ethernet_toggled (NmnModel *self,
+ gboolean active);
+
+gboolean nmn_model_wifi_can_change (NmnModel *self);
+gboolean nmn_model_wifi_get_active (NmnModel *self);
+void nmn_model_wifi_toggled (NmnModel *self,
+ gboolean active);
+
+gboolean nmn_model_modems_get_active (NmnModel *self);
+void nmn_model_modems_toggled (NmnModel *self,
+ gboolean active);
+
+gboolean nmn_model_offline_mode_get_active (NmnModel *self);
+void nmn_model_offline_mode_toggled (NmnModel *self,
+ gboolean active);
+
+#endif /* NMN_MODEL_H */
diff --git a/src/nmn-new-connection.c b/src/nmn-new-connection.c
index 4f97615..917833c 100644
--- a/src/nmn-new-connection.c
+++ b/src/nmn-new-connection.c
@@ -32,8 +32,10 @@
#include <nm-setting-ip4-config.h>
#include <nm-utils.h>
#include "nmn-new-connection.h"
-#include "nma-gconf-settings.h"
-#include "nmn-wifi-list.h"
+#include "nm-list-model.h"
+#include "nm-wifi-item.h"
+#include "nm-gconf-settings.h"
+#include "nmn-list.h"
#include "nmn-mobile-providers.h"
#include "wireless-dialog.h"
@@ -41,7 +43,7 @@ G_DEFINE_TYPE (NmnNewConnection, nmn_new_connection, GTK_TYPE_VBOX)
enum {
PROP_0,
- PROP_NM_DATA,
+ PROP_MODEL,
LAST_PROP
};
@@ -49,7 +51,7 @@ enum {
#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NMN_TYPE_NEW_CONNECTION, NmnNewConnectionPrivate))
typedef struct {
- NmnNMData *nm_data;
+ NmnModel *model;
/* WiFi widgets */
GtkWidget *wifi_list_container;
@@ -66,12 +68,12 @@ typedef struct {
} NmnNewConnectionPrivate;
GtkWidget *
-nmn_new_connection_create (NmnNMData *nm_data)
+nmn_new_connection_create (NmnModel *model)
{
- g_return_val_if_fail (NMN_IS_NM_DATA (nm_data), NULL);
+ g_return_val_if_fail (NMN_IS_MODEL (model), NULL);
return GTK_WIDGET (g_object_new (NMN_TYPE_NEW_CONNECTION,
- NMN_NEW_CONNECTION_NM_DATA, nm_data,
+ NMN_NEW_CONNECTION_MODEL, model,
NULL));
}
@@ -105,16 +107,16 @@ save_timestamp_cb (NMSettingsConnectionInterface *connection,
}
static gboolean
-save_connection (NmnNMData *data, NMConnection *connection)
+save_connection (NmnModel *model, NMConnection *connection)
{
NMSettingConnection *s_con;
NMSettingsConnectionInterface *gconf_connection;
- NMAGConfSettings *settings;
+ NMGConfSettings *settings;
- settings = NMA_GCONF_SETTINGS (nmn_nm_data_get_user_settings (data));
+ settings = NM_GCONF_SETTINGS (nmn_model_get_user_settings (model));
gconf_connection = nm_settings_interface_get_connection_by_path (NM_SETTINGS_INTERFACE (settings),
- nm_connection_get_path (connection));
+ nm_connection_get_path (connection));
if (!gconf_connection)
return FALSE;
s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
@@ -136,9 +138,9 @@ wifi_dialog_done (NMAWirelessDialog *dialog,
goto done;
connection = nma_wireless_dialog_get_connection (dialog);
- save_connection (priv->nm_data, connection);
+ save_connection (priv->model, connection);
- nm_client_activate_connection (NM_CLIENT (priv->nm_data),
+ nm_client_activate_connection (nmn_model_get_client (priv->model),
NM_DBUS_SERVICE_USER_SETTINGS,
nm_connection_get_path (connection),
nma_wireless_dialog_get_device (dialog),
@@ -157,18 +159,44 @@ wifi_search (GtkButton *button, gpointer user_data)
NmnNewConnectionPrivate *priv = GET_PRIVATE (user_data);
GtkWidget *dialog;
- dialog = nma_wireless_dialog_hidden_new (NM_CLIENT (priv->nm_data));
+ dialog = nma_wireless_dialog_hidden_new (nmn_model_get_client (priv->model));
g_signal_connect (dialog, "done", G_CALLBACK (wifi_dialog_done), user_data);
nma_wireless_dialog_show (NMA_WIRELESS_DIALOG (dialog));
}
+static gboolean
+wifi_model_visible_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ NMListItem *item = NULL;
+ gboolean visible = FALSE;
+
+ gtk_tree_model_get (model, iter, NM_LIST_MODEL_COL_ITEM, &item, -1);
+ if (item) {
+ /* Show unconfigured WiFi items */
+ if (NM_IS_WIFI_ITEM (item) && !nm_connection_item_get_connection (NM_CONNECTION_ITEM (item)))
+ visible = TRUE;
+
+ g_object_unref (item);
+ }
+
+ return visible;
+}
+
static void
wifi_page_init (NmnNewConnection *connection)
{
NmnNewConnectionPrivate *priv = GET_PRIVATE (connection);
+ GtkTreeModel *wifi_model;
+
+ wifi_model = gtk_tree_model_filter_new (GTK_TREE_MODEL (priv->model), NULL);
+ gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (wifi_model),
+ wifi_model_visible_func, NULL, NULL);
- priv->wifi_list = nmn_wifi_list_new (priv->nm_data);
- g_signal_connect (priv->wifi_list, "connect-requested", G_CALLBACK (connect_requested), connection);
+ priv->wifi_list = nmn_list_new_with_model (wifi_model);
+ g_object_unref (wifi_model);
+ //g_signal_connect (priv->wifi_list, "connect-requested", G_CALLBACK (connect_requested), connection);
gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (priv->wifi_list_container), priv->wifi_list);
gtk_widget_show_all (priv->wifi_list);
}
@@ -183,11 +211,13 @@ static gboolean
mobile_have_device (NmnNewConnection *connection, NmnMobileProviderType *type)
{
NmnNewConnectionPrivate *priv = GET_PRIVATE (connection);
+ NMClient *client;
const GPtrArray *devices;
int i;
gboolean found = FALSE;
- devices = nm_client_get_devices (NM_CLIENT (priv->nm_data));
+ client = nmn_model_get_client (priv->model);
+ devices = nm_client_get_devices (client);
for (i = 0; !found && devices && i < devices->len; i++) {
NMDevice *device = NM_DEVICE (g_ptr_array_index (devices, i));
@@ -212,7 +242,7 @@ mobile_status_update (NmnNewConnection *connection)
NmnMobileProviderType type;
gboolean found;
- if (!nmn_nm_data_modems_get_active (priv->nm_data)) {
+ if (!nmn_model_modems_get_active (priv->model)) {
found = FALSE;
gtk_label_set_text (GTK_LABEL (priv->mobile_label), _("3G disabled"));
} else {
@@ -394,6 +424,8 @@ mobile_tree_selection_changed (GtkTreeSelection *selection,
gtk_tree_model_get (model, &iter, MOBILE_COL_METHOD, &method, -1);
gtk_widget_set_sensitive (priv->mobile_save, method != NULL);
+ if (method)
+ nmn_mobile_access_method_unref (method);
}
static NMConnection *
@@ -517,13 +549,19 @@ mobile_save_clicked (GtkButton *button, gpointer user_data)
nmn_mobile_provider_unref (provider);
if (connection) {
- nma_gconf_settings_add_connection (NMA_GCONF_SETTINGS (nmn_nm_data_get_user_settings (priv->nm_data)),
- connection);
+ nm_gconf_settings_add_connection (NM_GCONF_SETTINGS (nmn_model_get_user_settings (priv->model)),
+ connection);
g_object_unref (connection);
}
gtk_widget_hide (GTK_WIDGET (self));
}
+
+ if (provider)
+ nmn_mobile_provider_unref (provider);
+
+ if (method)
+ nmn_mobile_access_method_unref (method);
}
static void
@@ -543,12 +581,13 @@ static void
mobile_page_init (NmnNewConnection *connection)
{
NmnNewConnectionPrivate *priv = GET_PRIVATE (connection);
+ NMClient *client = nmn_model_get_client (priv->model);
g_signal_connect (connection, "realize", G_CALLBACK (mobile_list_populate), NULL);
- g_signal_connect (priv->nm_data, "device-added", G_CALLBACK (mobile_device_added), connection);
- g_signal_connect_swapped (priv->nm_data, "device-removed", G_CALLBACK (mobile_status_update), connection);
+ g_signal_connect (client, "device-added", G_CALLBACK (mobile_device_added), connection);
+ g_signal_connect_swapped (client, "device-removed", G_CALLBACK (mobile_status_update), connection);
- priv->mobile_toggled_id = g_signal_connect_swapped (priv->nm_data, "modems-toggled",
+ priv->mobile_toggled_id = g_signal_connect_swapped (priv->model, "modems-toggled",
G_CALLBACK (mobile_status_update),
connection);
@@ -647,7 +686,7 @@ constructor (GType type,
priv = GET_PRIVATE (object);
- if (!priv->nm_data) {
+ if (!priv->model) {
g_warning ("Missing constructor arguments");
g_object_unref (object);
return NULL;
@@ -666,9 +705,9 @@ set_property (GObject *object, guint prop_id,
NmnNewConnectionPrivate *priv = GET_PRIVATE (object);
switch (prop_id) {
- case PROP_NM_DATA:
+ case PROP_MODEL:
/* Construct only */
- priv->nm_data = g_value_dup_object (value);
+ priv->model = g_value_dup_object (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -683,8 +722,8 @@ get_property (GObject *object, guint prop_id,
NmnNewConnectionPrivate *priv = GET_PRIVATE (object);
switch (prop_id) {
- case PROP_NM_DATA:
- g_value_set_object (value, priv->nm_data);
+ case PROP_MODEL:
+ g_value_set_object (value, priv->model);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -702,10 +741,10 @@ dispose (GObject *object)
priv->disposed = TRUE;
- g_signal_handler_disconnect (priv->nm_data, priv->mobile_toggled_id);
+ g_signal_handler_disconnect (priv->model, priv->mobile_toggled_id);
- if (priv->nm_data)
- g_object_unref (priv->nm_data);
+ if (priv->model)
+ g_object_unref (priv->model);
G_OBJECT_CLASS (nmn_new_connection_parent_class)->dispose (object);
}
@@ -725,10 +764,10 @@ nmn_new_connection_class_init (NmnNewConnectionClass *class)
/* properties */
g_object_class_install_property
- (object_class, PROP_NM_DATA,
- g_param_spec_object (NMN_NEW_CONNECTION_NM_DATA,
- "NmnNMData",
- "NmnNMData",
- NMN_TYPE_NM_DATA,
+ (object_class, PROP_MODEL,
+ g_param_spec_object (NMN_NEW_CONNECTION_MODEL,
+ "NmnModel",
+ "NmnModel",
+ NMN_TYPE_MODEL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}
diff --git a/src/nmn-new-connection.h b/src/nmn-new-connection.h
index c0af684..886b531 100644
--- a/src/nmn-new-connection.h
+++ b/src/nmn-new-connection.h
@@ -21,7 +21,7 @@
#define NMN_NEW_CONNECTION_H
#include <gtk/gtk.h>
-#include "nmn-nm-data.h"
+#include "nmn-model.h"
#define NMN_TYPE_NEW_CONNECTION (nmn_new_connection_get_type ())
#define NMN_NEW_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMN_TYPE_NEW_CONNECTION, NmnNewConnection))
@@ -30,7 +30,7 @@
#define NMN_IS_NEW_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NMN_TYPE_NEW_CONNECTION))
#define NMN_NEW_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMN_TYPE_NEW_CONNECTION, NmnNewConnectionClass))
-#define NMN_NEW_CONNECTION_NM_DATA "nm-data"
+#define NMN_NEW_CONNECTION_MODEL "model"
typedef struct {
GtkVBox parent;
@@ -42,6 +42,6 @@ typedef struct {
GType nmn_new_connection_get_type (void);
-GtkWidget *nmn_new_connection_create (NmnNMData *nm_data);
+GtkWidget *nmn_new_connection_create (NmnModel *model);
#endif /* NMN_NEW_CONNECTION_H */
diff --git a/src/nmn-panel-client.c b/src/nmn-panel-client.c
new file mode 100644
index 0000000..138b66f
--- /dev/null
+++ b/src/nmn-panel-client.c
@@ -0,0 +1,388 @@
+/* -*- 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 <gdk/gdk.h>
+#include <gtk/gtk.h>
+#include <libnotify/notify.h>
+#include <moblin-panel/mpl-panel-common.h>
+#include <nm-device-ethernet.h>
+#include <nm-device-wifi.h>
+#include <nm-gsm-device.h>
+#include <nm-cdma-device.h>
+#include <nm-utils.h>
+
+#include "nmn-panel-client.h"
+
+#define ACTIVATION_STEPS 6
+
+G_DEFINE_TYPE (NmnPanelClient, nmn_panel_client, MPL_TYPE_PANEL_GTK)
+
+enum {
+ PROP_0,
+ PROP_MODEL,
+
+ LAST_PROP
+};
+
+#define GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NMN_TYPE_PANEL_CLIENT, NmnPanelClientPrivate))
+
+typedef struct {
+ NMStatusModel *model;
+
+ NMListItem *item;
+ guint animation_id;
+ guint animation_step;
+
+ /* Saved from previous item */
+ NMListItemStatus status;
+ char *connection_type;
+ char *connection_name;
+} NmnPanelClientPrivate;
+
+NmnPanelClient *
+nmn_panel_client_new (NMStatusModel *model)
+{
+ g_return_val_if_fail (NM_IS_STATUS_MODEL (model), NULL);
+
+ return (NmnPanelClient *) g_object_new (NMN_TYPE_PANEL_CLIENT,
+ "name", MPL_PANEL_NETWORK,
+ "tooltip", _("network"),
+ "stylesheet", THEME_PATH "/network-manager-netbook.css",
+ "button-style", "unknown",
+ "toolbar-service", TRUE,
+ NMN_PANEL_CLIENT_MODEL, model,
+ NULL);
+
+}
+
+static void
+stop_activation_animation (NmnPanelClient *self)
+{
+ NmnPanelClientPrivate *priv = GET_PRIVATE (self);
+
+ if (priv->animation_id) {
+ g_source_remove (priv->animation_id);
+ priv->animation_id = 0;
+ priv->animation_step = 0;
+ }
+}
+
+static gboolean
+activation_animation (gpointer data)
+{
+ NmnPanelClient *self = NMN_PANEL_CLIENT (data);
+ NmnPanelClientPrivate *priv = GET_PRIVATE (self);
+ char *image;
+
+ if (++priv->animation_step > ACTIVATION_STEPS)
+ priv->animation_step = 1;
+
+ image = g_strdup_printf ("progress-%02d", priv->animation_step);
+ mpl_panel_client_request_button_style (MPL_PANEL_CLIENT (self), image);
+ g_free (image);
+
+ return TRUE;
+}
+
+/* FIXME: This is all pretty gross */
+static const char *
+massage_icon (const char *original)
+{
+ static char *icon = NULL;
+
+ if (icon) {
+ g_free (icon);
+ icon = NULL;
+ }
+
+ if (!original)
+ return NULL;
+
+ if (g_str_has_prefix (original, "nm-"))
+ icon = g_strdup (original + 3);
+ else
+ icon = g_strdup (original);
+
+ if (g_str_has_suffix (icon, "-active") || g_str_has_suffix (icon, "-normal"))
+ icon[strlen(icon) - 7] = '\0';
+
+ return icon;
+}
+
+static void
+update_icon (NmnPanelClient *self)
+{
+ NmnPanelClientPrivate *priv = GET_PRIVATE (self);
+ NMListItemStatus status;
+
+ status = priv->item ? nm_list_item_get_status (priv->item) : NM_LIST_ITEM_STATUS_DISCONNECTED;
+ switch (status) {
+ case NM_LIST_ITEM_STATUS_CONNECTING:
+ if (priv->animation_id == 0) {
+ priv->animation_id = g_timeout_add (200, activation_animation, self);
+ activation_animation (self);
+ }
+ break;
+ case NM_LIST_ITEM_STATUS_DISCONNECTED:
+ stop_activation_animation (self);
+ mpl_panel_client_request_button_style (MPL_PANEL_CLIENT (self), "no-network");
+ break;
+ case NM_LIST_ITEM_STATUS_CONNECTED:
+ stop_activation_animation (self);
+ mpl_panel_client_request_button_style (MPL_PANEL_CLIENT (self),
+ massage_icon (nm_list_item_get_icon (priv->item)));
+
+ break;
+ }
+}
+
+static void
+update_notification (NmnPanelClient *self)
+{
+ NmnPanelClientPrivate *priv = GET_PRIVATE (self);
+ const char *title;
+ char *msg;
+ const char *connection_type;
+ const char *connection_name;
+ const char *icon;
+ NMListItemStatus status;
+
+ if (priv->item) {
+ status = nm_list_item_get_status (priv->item);
+ connection_type = nm_list_item_get_type_name (priv->item);
+ connection_name = nm_list_item_get_name (priv->item);
+ icon = nm_list_item_get_icon (priv->item);
+ } else {
+ status = NM_LIST_ITEM_STATUS_DISCONNECTED;
+ connection_type = NULL;
+ connection_name = NULL;
+ icon = NULL;
+ }
+
+ if (priv->status == NM_LIST_ITEM_STATUS_DISCONNECTED && status == NM_LIST_ITEM_STATUS_CONNECTED) {
+ title = _("Network connected");
+
+ if (connection_type) {
+ if (connection_name)
+ msg = g_strdup_printf (_("You're now connected to %s, a %s network"),
+ connection_name, connection_type);
+ else
+ msg = g_strdup_printf (_("You're now connected to %s network"), connection_type);
+ } else
+ msg = g_strdup (_("You're now connected to network"));
+ } else if (priv->status == NM_LIST_ITEM_STATUS_CONNECTED && status == NM_LIST_ITEM_STATUS_DISCONNECTED) {
+ title = _("Network lost");
+
+ if (priv->connection_type) {
+ if (priv->connection_name)
+ msg = g_strdup_printf (_("Sorry, we've lost your %s connection to %s"),
+ priv->connection_type, priv->connection_name);
+ else
+ msg = g_strdup_printf (_("Sorry, we've lost your %s connection"), priv->connection_type);
+ } else
+ msg = g_strdup (_("Sorry, we've lost your connection"));
+ } else {
+ title = NULL;
+ msg = NULL;
+ }
+
+ if (title && msg) {
+ NotifyNotification *note;
+
+ note = notify_notification_new (title, msg, icon, NULL);
+ notify_notification_set_timeout (note, 10000);
+ notify_notification_show (note, NULL);
+ g_object_unref (note);
+ g_free (msg);
+
+ priv->status = status;
+ g_free (priv->connection_type);
+ priv->connection_type = connection_type ? g_strdup (connection_type) : NULL;
+ g_free (priv->connection_name);
+ priv->connection_name = connection_name ? g_strdup (connection_name) : NULL;
+ }
+}
+
+static void
+update_tooltip (NmnPanelClient *self)
+{
+ NmnPanelClientPrivate *priv = GET_PRIVATE (self);
+ char *tip;
+ const char *connection_type;
+ const char *connection_name;
+ NMListItemStatus status;
+
+ status = priv->item ? nm_list_item_get_status (priv->item) : NM_LIST_ITEM_STATUS_DISCONNECTED;
+ switch (status) {
+ case NM_LIST_ITEM_STATUS_DISCONNECTED:
+ tip = g_strdup_printf (_("networks - not connected"));
+ break;
+ case NM_LIST_ITEM_STATUS_CONNECTING:
+ tip = g_strdup_printf (_("networks - connecting"));
+ break;
+ case NM_LIST_ITEM_STATUS_CONNECTED:
+ connection_type = nm_list_item_get_type_name (priv->item);
+ connection_name = nm_list_item_get_name (priv->item);
+
+ if (connection_type) {
+ if (connection_name)
+ tip = g_strdup_printf (_("networks - %s - %s"), connection_name, connection_type);
+ else
+ tip = g_strdup_printf (_("networks - %s"), connection_type);
+ } else
+ tip = g_strdup (_("networks - connected"));
+
+ break;
+ }
+
+ mpl_panel_client_request_tooltip (MPL_PANEL_CLIENT (self), tip);
+ g_free (tip);
+}
+
+static void
+item_status_changed (NMListItem *item,
+ GParamSpec *spec,
+ gpointer user_data)
+{
+ NmnPanelClient *self = NMN_PANEL_CLIENT (user_data);
+
+ update_notification (self);
+ update_tooltip (self);
+ update_icon (self);
+}
+
+static void
+model_changed (NMStatusModel *model,
+ NMListItem *active_item,
+ gpointer user_data)
+{
+ NmnPanelClient *self = NMN_PANEL_CLIENT (user_data);
+ NmnPanelClientPrivate *priv = GET_PRIVATE (self);
+
+ if (active_item == priv->item)
+ return;
+
+ if (priv->item)
+ g_signal_handlers_disconnect_by_func (priv->item, item_status_changed, self);
+
+ priv->item = active_item;
+
+ if (active_item) {
+ g_signal_connect (active_item, "notify::" NM_LIST_ITEM_STATUS, G_CALLBACK (item_status_changed), self);
+ g_signal_connect (active_item, "notify::" NM_LIST_ITEM_ICON, G_CALLBACK (item_status_changed), self);
+ }
+
+ item_status_changed (active_item, NULL, self);
+}
+
+/*****************************************************************************/
+
+static void
+nmn_panel_client_init (NmnPanelClient *self)
+{
+ notify_init ("network-manager-netbook");
+ mpl_panel_client_set_height_request (MPL_PANEL_CLIENT (self), 499);
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NmnPanelClientPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_MODEL:
+ /* Construct only */
+ priv->model = g_value_dup_object (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)
+{
+ NmnPanelClientPrivate *priv = GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_MODEL:
+ g_value_set_object (value, priv->model);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+constructed (GObject *object)
+{
+ NmnPanelClientPrivate *priv = GET_PRIVATE (object);
+
+ if (G_OBJECT_CLASS (nmn_panel_client_parent_class)->constructed)
+ G_OBJECT_CLASS (nmn_panel_client_parent_class)->constructed (object);
+
+ g_signal_connect (priv->model, "changed", G_CALLBACK (model_changed), object);
+ item_status_changed (NULL, NULL, object);
+}
+
+static void
+finalize (GObject *object)
+{
+ NmnPanelClientPrivate *priv = GET_PRIVATE (object);
+
+ stop_activation_animation (NMN_PANEL_CLIENT (object));
+
+ g_free (priv->connection_type);
+ g_free (priv->connection_name);
+
+ if (priv->model)
+ g_object_unref (priv->model);
+
+ notify_uninit ();
+
+ G_OBJECT_CLASS (nmn_panel_client_parent_class)->finalize (object);
+}
+
+static void
+nmn_panel_client_class_init (NmnPanelClientClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (object_class, sizeof (NmnPanelClientPrivate));
+
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->constructed = constructed;
+ object_class->finalize = finalize;
+
+ /* Properties */
+ g_object_class_install_property
+ (object_class, PROP_MODEL,
+ g_param_spec_object (NMN_PANEL_CLIENT_MODEL,
+ "NMStatusModel",
+ "NMStatusModel",
+ NM_TYPE_STATUS_MODEL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
diff --git a/src/nmn-panel-client.h b/src/nmn-panel-client.h
new file mode 100644
index 0000000..875f73d
--- /dev/null
+++ b/src/nmn-panel-client.h
@@ -0,0 +1,52 @@
+/* -*- 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_PANEL_CLIENT_H
+#define NMN_PANEL_CLIENT_H
+
+#include <glib-object.h>
+#include <moblin-panel/mpl-panel-gtk.h>
+#include <nm-status-model.h>
+
+G_BEGIN_DECLS
+
+#define NMN_TYPE_PANEL_CLIENT (nmn_panel_client_get_type ())
+#define NMN_PANEL_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMN_TYPE_PANEL_CLIENT, NmnPanelClient))
+#define NMN_PANEL_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NMN_TYPE_PANEL_CLIENT, NmnPanelClientClass))
+#define NMN_IS_PANEL_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMN_TYPE_PANEL_CLIENT))
+#define NMN_IS_PANEL_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NMN_TYPE_PANEL_CLIENT))
+#define NMN_PANEL_CLIENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NMN_TYPE_PANEL_CLIENT, NmnPanelClientClass))
+
+#define NMN_PANEL_CLIENT_MODEL "model"
+
+typedef struct {
+ MplPanelGtk parent;
+} NmnPanelClient;
+
+typedef struct {
+ MplPanelGtkClass parent;
+} NmnPanelClientClass;
+
+GType nmn_panel_client_get_type (void);
+
+NmnPanelClient *nmn_panel_client_new (NMStatusModel *model);
+
+G_END_DECLS
+
+#endif /* NMN_PANEL_CLIENT_H */
diff --git a/src/utils.c b/src/utils.c
index 575f94b..22bed05 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -1,832 +1,7 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
- *
- * Dan Williams <dcbw redhat com>
- *
- * 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 2007 Red Hat, Inc.
- */
-
-#include <string.h>
-#include <netinet/ether.h>
-#include <glib.h>
#include <moblin-panel/mpl-panel-client.h>
-#include <nm-device-ethernet.h>
-#include <nm-device-wifi.h>
-#include <nm-device-bt.h>
-#include <nm-gsm-device.h>
-#include <nm-cdma-device.h>
-#include <nm-access-point.h>
-#include <nm-setting-connection.h>
-#include <nm-setting-wired.h>
-#include <nm-setting-wireless.h>
-#include <nm-setting-wireless-security.h>
-#include <nm-setting-8021x.h>
-#include <nm-setting-gsm.h>
-#include <nm-setting-cdma.h>
-#include <nm-setting-pppoe.h>
-#include <nm-setting-bluetooth.h>
-#include <nm-utils.h>
-
#include "utils.h"
-#include "gconf-helpers.h"
-
-/*
- * utils_bin2hexstr
- *
- * Convert a byte-array into a hexadecimal string.
- *
- * Code originally by Alex Larsson <alexl redhat com> and
- * copyright Red Hat, Inc. under terms of the LGPL.
- *
- */
-char *
-utils_bin2hexstr (const char *bytes, int len, int final_len)
-{
- static char hex_digits[] = "0123456789abcdef";
- char * result;
- int i;
-
- g_return_val_if_fail (bytes != NULL, NULL);
- g_return_val_if_fail (len > 0, NULL);
- g_return_val_if_fail (len < 256, NULL); /* Arbitrary limit */
-
- result = g_malloc0 (len * 2 + 1);
- for (i = 0; i < len; i++)
- {
- result[2*i] = hex_digits[(bytes[i] >> 4) & 0xf];
- result[2*i+1] = hex_digits[bytes[i] & 0xf];
- }
- /* Cut converted key off at the correct length for this cipher type */
- if (final_len > -1)
- result[final_len] = '\0';
-
- return result;
-}
-
-static char *ignored_words[] = {
- "Semiconductor",
- "Components",
- "Corporation",
- "Communications",
- "Company",
- "Corp.",
- "Corp",
- "Co.",
- "Inc.",
- "Inc",
- "Ltd.",
- "Limited.",
- "Intel?",
- "chipset",
- "adapter",
- "[hex]",
- "NDIS",
- "Module",
- NULL
-};
-
-static char *ignored_phrases[] = {
- "Multiprotocol MAC/baseband processor",
- "Wireless LAN Controller",
- "Wireless LAN Adapter",
- "Wireless Adapter",
- "Network Connection",
- "Wireless Cardbus Adapter",
- "Wireless CardBus Adapter",
- "54 Mbps Wireless PC Card",
- "Wireless PC Card",
- "Wireless PC",
- "PC Card with XJACK(r) Antenna",
- "Wireless cardbus",
- "Wireless LAN PC Card",
- "Technology Group Ltd.",
- "Communication S.p.A.",
- "Business Mobile Networks BV",
- "Mobile Broadband Minicard Composite Device",
- "Mobile Communications AB",
- NULL
-};
-
-static char *
-fixup_desc_string (const char *desc)
-{
- char *p, *temp;
- char **words, **item;
- GString *str;
-
- p = temp = g_strdup (desc);
- while (*p) {
- if (*p == '_' || *p == ',')
- *p = ' ';
- p++;
- }
-
- /* Attempt to shorten ID by ignoring certain phrases */
- for (item = ignored_phrases; *item; item++) {
- guint32 ignored_len = strlen (*item);
-
- p = strstr (temp, *item);
- if (p)
- memmove (p, p + ignored_len, strlen (p + ignored_len) + 1); /* +1 for the \0 */
- }
-
- /* Attmept to shorten ID by ignoring certain individual words */
- words = g_strsplit (temp, " ", 0);
- str = g_string_new_len (NULL, strlen (temp));
- g_free (temp);
-
- for (item = words; *item; item++) {
- int i = 0;
- gboolean ignore = FALSE;
-
- if (g_ascii_isspace (**item) || (**item == '\0'))
- continue;
-
- while (ignored_words[i] && !ignore) {
- if (!strcmp (*item, ignored_words[i]))
- ignore = TRUE;
- i++;
- }
-
- if (!ignore) {
- if (str->len)
- g_string_append_c (str, ' ');
- g_string_append (str, *item);
- }
- }
- g_strfreev (words);
-
- temp = str->str;
- g_string_free (str, FALSE);
-
- return temp;
-}
-
-#define DESC_TAG "description"
-
-const char *
-utils_get_device_description (NMDevice *device)
-{
- char *description = NULL;
- const char *dev_product;
- const char *dev_vendor;
- char *product = NULL;
- char *vendor = NULL;
- GString *str;
-
- g_return_val_if_fail (device != NULL, NULL);
-
- description = g_object_get_data (G_OBJECT (device), DESC_TAG);
- if (description)
- return description;
-
- dev_product = nm_device_get_product (device);
- dev_vendor = nm_device_get_vendor (device);
- if (!dev_product || !dev_vendor)
- return NULL;
-
- product = fixup_desc_string (dev_product);
- vendor = fixup_desc_string (dev_vendor);
-
- str = g_string_new_len (NULL, strlen (vendor) + strlen (product) + 1);
-
- g_string_append (str, vendor);
- g_free (vendor);
-
- g_string_append_c (str, ' ');
- g_string_append (str, product);
- g_free (product);
-
- description = str->str;
- g_string_free (str, FALSE);
-
- g_object_set_data_full (G_OBJECT (device),
- "description", description,
- (GDestroyNotify) g_free);
-
- return description;
-}
-
-struct cf_pair {
- guint32 chan;
- guint32 freq;
-};
-
-static struct cf_pair a_table[] = {
- /* A band */
- { 7, 5035 },
- { 8, 5040 },
- { 9, 5045 },
- { 11, 5055 },
- { 12, 5060 },
- { 16, 5080 },
- { 34, 5170 },
- { 36, 5180 },
- { 38, 5190 },
- { 40, 5200 },
- { 42, 5210 },
- { 44, 5220 },
- { 46, 5230 },
- { 48, 5240 },
- { 50, 5250 },
- { 52, 5260 },
- { 56, 5280 },
- { 58, 5290 },
- { 60, 5300 },
- { 64, 5320 },
- { 100, 5500 },
- { 104, 5520 },
- { 108, 5540 },
- { 112, 5560 },
- { 116, 5580 },
- { 120, 5600 },
- { 124, 5620 },
- { 128, 5640 },
- { 132, 5660 },
- { 136, 5680 },
- { 140, 5700 },
- { 149, 5745 },
- { 152, 5760 },
- { 153, 5765 },
- { 157, 5785 },
- { 160, 5800 },
- { 161, 5805 },
- { 165, 5825 },
- { 183, 4915 },
- { 184, 4920 },
- { 185, 4925 },
- { 187, 4935 },
- { 188, 4945 },
- { 192, 4960 },
- { 196, 4980 },
- { 0, -1 }
-};
-
-static struct cf_pair bg_table[] = {
- /* B/G band */
- { 1, 2412 },
- { 2, 2417 },
- { 3, 2422 },
- { 4, 2427 },
- { 5, 2432 },
- { 6, 2437 },
- { 7, 2442 },
- { 8, 2447 },
- { 9, 2452 },
- { 10, 2457 },
- { 11, 2462 },
- { 12, 2467 },
- { 13, 2472 },
- { 14, 2484 },
- { 0, -1 }
-};
-
-guint32
-utils_freq_to_channel (guint32 freq)
-{
- int i = 0;
-
- while (a_table[i].chan && (a_table[i].freq != freq))
- i++;
- if (a_table[i].chan)
- return a_table[i].chan;
-
- i = 0;
- while (bg_table[i].chan && (bg_table[i].freq != freq))
- i++;
- return bg_table[i].chan;
-}
-
-guint32
-utils_channel_to_freq (guint32 channel, char *band)
-{
- int i = 0;
-
- if (!strcmp (band, "a")) {
- while (a_table[i].chan && (a_table[i].chan != channel))
- i++;
- return a_table[i].freq;
- } else if (!strcmp (band, "bg")) {
- while (bg_table[i].chan && (bg_table[i].chan != channel))
- i++;
- return bg_table[i].freq;
- }
-
- return 0;
-}
-
-guint32
-utils_find_next_channel (guint32 channel, int direction, char *band)
-{
- size_t a_size = sizeof (a_table) / sizeof (struct cf_pair);
- size_t bg_size = sizeof (bg_table) / sizeof (struct cf_pair);
- struct cf_pair *pair = NULL;
-
- if (!strcmp (band, "a")) {
- if (channel < a_table[0].chan)
- return a_table[0].chan;
- if (channel > a_table[a_size - 2].chan)
- return a_table[a_size - 2].chan;
- pair = &a_table[0];
- } else if (!strcmp (band, "bg")) {
- if (channel < bg_table[0].chan)
- return bg_table[0].chan;
- if (channel > bg_table[bg_size - 2].chan)
- return bg_table[bg_size - 2].chan;
- pair = &bg_table[0];
- } else {
- g_assert_not_reached ();
- return 0;
- }
-
- while (pair->chan) {
- if (channel == pair->chan)
- return channel;
- if ((channel < (pair+1)->chan) && (channel > pair->chan)) {
- if (direction > 0)
- return (pair+1)->chan;
- else
- return pair->chan;
- }
- pair++;
- }
- return 0;
-}
-
-/*
- * utils_ether_addr_valid
- *
- * Compares an Ethernet address against known invalid addresses.
- *
- */
-gboolean
-utils_ether_addr_valid (const struct ether_addr *test_addr)
-{
- guint8 invalid_addr1[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
- guint8 invalid_addr2[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- guint8 invalid_addr3[ETH_ALEN] = {0x44, 0x44, 0x44, 0x44, 0x44, 0x44};
- guint8 invalid_addr4[ETH_ALEN] = {0x00, 0x30, 0xb4, 0x00, 0x00, 0x00}; /* prism54 dummy MAC */
-
- g_return_val_if_fail (test_addr != NULL, FALSE);
-
- /* Compare the AP address the card has with invalid ethernet MAC addresses. */
- if (!memcmp (test_addr->ether_addr_octet, &invalid_addr1, ETH_ALEN))
- return FALSE;
-
- if (!memcmp (test_addr->ether_addr_octet, &invalid_addr2, ETH_ALEN))
- return FALSE;
-
- if (!memcmp (test_addr->ether_addr_octet, &invalid_addr3, ETH_ALEN))
- return FALSE;
-
- if (!memcmp (test_addr->ether_addr_octet, &invalid_addr4, ETH_ALEN))
- return FALSE;
-
- if (test_addr->ether_addr_octet[0] & 1) /* Multicast addresses */
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-utils_check_ap_compatible (NMAccessPoint *ap,
- NMConnection *connection)
-{
- NMSettingWireless *s_wireless;
- NMSettingWirelessSecurity *s_wireless_sec;
- const GByteArray *setting_bssid;
- const char *setting_mode;
- const char *setting_band;
- NM80211Mode ap_mode;
- guint32 freq;
-
- g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), FALSE);
- g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE);
-
- s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
- if (s_wireless == NULL)
- return FALSE;
-
- if (!nm_utils_same_ssid (nm_setting_wireless_get_ssid (s_wireless), nm_access_point_get_ssid (ap), TRUE))
- return FALSE;
-
- setting_bssid = nm_setting_wireless_get_bssid (s_wireless);
- if (setting_bssid) {
- struct ether_addr ap_addr;
-
- if (ether_aton_r (nm_access_point_get_hw_address (ap), &ap_addr)) {
- if (memcmp (setting_bssid->data, &ap_addr, ETH_ALEN))
- return FALSE;
- }
- }
-
- ap_mode = nm_access_point_get_mode (ap);
- setting_mode = nm_setting_wireless_get_mode (s_wireless);
- if (setting_mode) {
- if ( !strcmp (setting_mode, "infrastructure")
- && (ap_mode != NM_802_11_MODE_INFRA))
- return FALSE;
- if ( !strcmp (setting_mode, "adhoc")
- && (ap_mode != NM_802_11_MODE_ADHOC))
- return FALSE;
- }
-
- freq = nm_access_point_get_frequency (ap);
- setting_band = nm_setting_wireless_get_band (s_wireless);
- if (setting_band) {
- if (!strcmp (setting_band, "a")) {
- if (freq < 5170 || freq > 5825)
- return FALSE;
- } else if (!strcmp (setting_band, "bg")) {
- if (freq < 2412 || freq > 2472)
- return FALSE;
- }
- }
-
- // FIXME: channel check
-
- s_wireless_sec = (NMSettingWirelessSecurity *) nm_connection_get_setting (connection,
- NM_TYPE_SETTING_WIRELESS_SECURITY);
-
- return nm_setting_wireless_ap_security_compatible (s_wireless,
- s_wireless_sec,
- nm_access_point_get_flags (ap),
- nm_access_point_get_wpa_flags (ap),
- nm_access_point_get_rsn_flags (ap),
- nm_access_point_get_mode (ap));
-}
-
-static gboolean
-connection_valid_for_wired (NMConnection *connection,
- NMSettingConnection *s_con,
- NMDevice *device,
- gpointer specific_object)
-{
- NMDeviceEthernet *ethdev = NM_DEVICE_ETHERNET (device);
- NMSettingWired *s_wired;
- const char *str_mac;
- struct ether_addr *bin_mac;
- const char *connection_type;
- const GByteArray *setting_mac;
- gboolean is_pppoe = FALSE;
-
- connection_type = nm_setting_connection_get_connection_type (s_con);
- if (!strcmp (connection_type, NM_SETTING_PPPOE_SETTING_NAME))
- is_pppoe = TRUE;
-
- if (!is_pppoe && strcmp (connection_type, NM_SETTING_WIRED_SETTING_NAME))
- return FALSE;
-
- s_wired = NM_SETTING_WIRED (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRED));
- if (!is_pppoe && !s_wired)
- return FALSE;
-
- if (s_wired) {
- /* Match MAC address */
- setting_mac = nm_setting_wired_get_mac_address (s_wired);
- if (!setting_mac)
- return TRUE;
-
- str_mac = nm_device_ethernet_get_hw_address (ethdev);
- g_return_val_if_fail (str_mac != NULL, FALSE);
-
- bin_mac = ether_aton (str_mac);
- g_return_val_if_fail (bin_mac != NULL, FALSE);
-
- if (memcmp (bin_mac->ether_addr_octet, setting_mac->data, ETH_ALEN))
- return FALSE;
- }
-
- return TRUE;
-}
-
-static gboolean
-connection_valid_for_wireless (NMConnection *connection,
- NMSettingConnection *s_con,
- NMDevice *device,
- gpointer specific_object)
-{
- NMDeviceWifi *wdev = NM_DEVICE_WIFI (device);
- NMSettingWireless *s_wireless;
- NMSettingWirelessSecurity *s_wireless_sec;
- const GByteArray *setting_mac;
- const char *setting_security, *key_mgmt;
- guint32 wcaps;
- NMAccessPoint *ap;
-
- if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_WIRELESS_SETTING_NAME))
- return FALSE;
-
- s_wireless = NM_SETTING_WIRELESS (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS));
- g_return_val_if_fail (s_wireless != NULL, FALSE);
-
- /* Match MAC address */
- setting_mac = nm_setting_wireless_get_mac_address (s_wireless);
- if (setting_mac) {
- const char *str_mac;
- struct ether_addr *bin_mac;
-
- str_mac = nm_device_wifi_get_hw_address (wdev);
- g_return_val_if_fail (str_mac != NULL, FALSE);
-
- bin_mac = ether_aton (str_mac);
- g_return_val_if_fail (bin_mac != NULL, FALSE);
-
- if (memcmp (bin_mac->ether_addr_octet, setting_mac->data, ETH_ALEN))
- return FALSE;
- }
-
- /* If an AP was given make sure that's compatible with the connection first */
- if (specific_object) {
- ap = NM_ACCESS_POINT (specific_object);
- g_assert (ap);
-
- if (!utils_check_ap_compatible (ap, connection))
- return FALSE;
- }
-
- setting_security = nm_setting_wireless_get_security (s_wireless);
- if (!setting_security || strcmp (setting_security, NM_SETTING_WIRELESS_SECURITY_SETTING_NAME))
- return TRUE; /* all devices can do unencrypted networks */
-
- s_wireless_sec = NM_SETTING_WIRELESS_SECURITY (nm_connection_get_setting (connection, NM_TYPE_SETTING_WIRELESS_SECURITY));
- if (!s_wireless_sec)
- return TRUE; /* all devices can do unencrypted networks */
-
- key_mgmt = nm_setting_wireless_security_get_key_mgmt (s_wireless_sec);
-
- /* All devices should support static WEP */
- if (!strcmp (key_mgmt, "none"))
- return TRUE;
-
- /* All devices should support legacy LEAP and Dynamic WEP */
- if (!strcmp (key_mgmt, "ieee8021x"))
- return TRUE;
-
- /* Match security with device capabilities */
- wcaps = nm_device_wifi_get_capabilities (wdev);
-
- /* At this point, the device better have basic WPA support. */
- if ( !(wcaps & NM_WIFI_DEVICE_CAP_WPA)
- || !(wcaps & NM_WIFI_DEVICE_CAP_CIPHER_TKIP))
- return FALSE;
-
- /* Check for only RSN */
- if ( (nm_setting_wireless_security_get_num_protos (s_wireless_sec) == 1)
- && !strcmp (nm_setting_wireless_security_get_proto (s_wireless_sec, 0), "rsn")
- && !(wcaps & NM_WIFI_DEVICE_CAP_RSN))
- return FALSE;
-
- /* Check for only pairwise CCMP */
- if ( (nm_setting_wireless_security_get_num_pairwise (s_wireless_sec) == 1)
- && !strcmp (nm_setting_wireless_security_get_pairwise (s_wireless_sec, 0), "ccmp")
- && !(wcaps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP))
- return FALSE;
-
- /* Check for only group CCMP */
- if ( (nm_setting_wireless_security_get_num_groups (s_wireless_sec) == 1)
- && !strcmp (nm_setting_wireless_security_get_group (s_wireless_sec, 0), "ccmp")
- && !(wcaps & NM_WIFI_DEVICE_CAP_CIPHER_CCMP))
- return FALSE;
-
- return TRUE;
-}
-
-static gboolean
-connection_valid_for_gsm (NMConnection *connection,
- NMSettingConnection *s_con,
- NMDevice *device,
- gpointer specific_object)
-{
- NMSettingGsm *s_gsm;
-
- if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_GSM_SETTING_NAME))
- return FALSE;
-
- s_gsm = NM_SETTING_GSM (nm_connection_get_setting (connection, NM_TYPE_SETTING_GSM));
- g_return_val_if_fail (s_gsm != NULL, FALSE);
-
- return TRUE;
-}
-
-static gboolean
-connection_valid_for_cdma (NMConnection *connection,
- NMSettingConnection *s_con,
- NMDevice *device,
- gpointer specific_object)
-{
- NMSettingCdma *s_cdma;
-
- if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_CDMA_SETTING_NAME))
- return FALSE;
-
- s_cdma = NM_SETTING_CDMA (nm_connection_get_setting (connection, NM_TYPE_SETTING_CDMA));
- g_return_val_if_fail (s_cdma != NULL, FALSE);
-
- return TRUE;
-}
-
-static guint32
-get_connection_bt_type (NMConnection *connection)
-{
- NMSettingBluetooth *s_bt;
- const char *bt_type;
-
- s_bt = (NMSettingBluetooth *) nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH);
- if (!s_bt)
- return NM_BT_CAPABILITY_NONE;
-
- bt_type = nm_setting_bluetooth_get_connection_type (s_bt);
- g_assert (bt_type);
-
- if (!strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_DUN))
- return NM_BT_CAPABILITY_DUN;
- else if (!strcmp (bt_type, NM_SETTING_BLUETOOTH_TYPE_PANU))
- return NM_BT_CAPABILITY_NAP;
-
- return NM_BT_CAPABILITY_NONE;
-}
-
-static gboolean
-connection_valid_for_bt (NMConnection *connection,
- NMSettingConnection *s_con,
- NMDevice *device,
- gpointer specific_object)
-{
- NMSettingBluetooth *s_bt;
- const GByteArray *array;
- char *str;
- const char *hw_addr;
- int addr_match = FALSE;
- guint32 bt_type;
-
- if (strcmp (nm_setting_connection_get_connection_type (s_con), NM_SETTING_BLUETOOTH_SETTING_NAME))
- return FALSE;
-
- s_bt = NM_SETTING_BLUETOOTH (nm_connection_get_setting (connection, NM_TYPE_SETTING_BLUETOOTH));
- if (!s_bt)
- return FALSE;
-
- array = nm_setting_bluetooth_get_bdaddr (s_bt);
- if (!array || (array->len != ETH_ALEN))
- return FALSE;
-
- bt_type = get_connection_bt_type (connection);
- if (!(bt_type & nm_device_bt_get_capabilities (NM_DEVICE_BT (device))))
- return FALSE;
-
- str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
- array->data[0], array->data[1], array->data[2],
- array->data[3], array->data[4], array->data[5]);
- hw_addr = nm_device_bt_get_hw_address (NM_DEVICE_BT (device));
- if (hw_addr)
- addr_match = !g_ascii_strcasecmp (hw_addr, str);
- g_free (str);
-
- return addr_match;
-}
-
-gboolean
-utils_connection_valid_for_device (NMConnection *connection,
- NMDevice *device,
- gpointer specific_object)
-{
- NMSettingConnection *s_con;
-
- g_return_val_if_fail (connection != NULL, FALSE);
- g_return_val_if_fail (device != NULL, FALSE);
-
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
- g_return_val_if_fail (s_con != NULL, FALSE);
- g_return_val_if_fail (nm_setting_connection_get_connection_type (s_con) != NULL, FALSE);
-
- if (NM_IS_DEVICE_ETHERNET (device))
- return connection_valid_for_wired (connection, s_con, device, specific_object);
- else if (NM_IS_DEVICE_WIFI (device))
- return connection_valid_for_wireless (connection, s_con, device, specific_object);
- else if (NM_IS_GSM_DEVICE (device))
- return connection_valid_for_gsm (connection, s_con, device, specific_object);
- else if (NM_IS_CDMA_DEVICE (device))
- return connection_valid_for_cdma (connection, s_con, device, specific_object);
- else if (NM_IS_DEVICE_BT (device))
- return connection_valid_for_bt (connection, s_con, device, specific_object);
- else
- g_warning ("Unknown device type '%s'", g_type_name (G_OBJECT_TYPE(device)));
-
- return FALSE;
-}
-
-GSList *
-utils_filter_connections_for_device (NMDevice *device, GSList *connections)
-{
- GSList *iter;
- GSList *filtered = NULL;
-
- for (iter = connections; iter; iter = g_slist_next (iter)) {
- NMConnection *connection = NM_CONNECTION (iter->data);
-
- if (utils_connection_valid_for_device (connection, device, NULL))
- filtered = g_slist_append (filtered, connection);
- }
-
- return filtered;
-}
-
-gboolean
-utils_mac_valid (const struct ether_addr *addr)
-{
- guint8 invalid1[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
- guint8 invalid2[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- guint8 invalid3[ETH_ALEN] = {0x44, 0x44, 0x44, 0x44, 0x44, 0x44};
- guint8 invalid4[ETH_ALEN] = {0x00, 0x30, 0xb4, 0x00, 0x00, 0x00}; /* prism54 dummy MAC */
-
- g_return_val_if_fail (addr != NULL, FALSE);
-
- /* Compare the AP address the card has with invalid ethernet MAC addresses. */
- if (!memcmp (addr->ether_addr_octet, &invalid1, ETH_ALEN))
- return FALSE;
-
- if (!memcmp (addr->ether_addr_octet, &invalid2, ETH_ALEN))
- return FALSE;
-
- if (!memcmp (addr->ether_addr_octet, &invalid3, ETH_ALEN))
- return FALSE;
-
- if (!memcmp (addr->ether_addr_octet, &invalid4, ETH_ALEN))
- return FALSE;
-
- if (addr->ether_addr_octet[0] & 1) /* Multicast addresses */
- return FALSE;
-
- return TRUE;
-}
-
-char *
-utils_ether_ntop (const struct ether_addr *mac)
-{
- /* we like leading zeros and all-caps, instead
- * of what glibc's ether_ntop() gives us
- */
- return g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X",
- mac->ether_addr_octet[0], mac->ether_addr_octet[1],
- mac->ether_addr_octet[2], mac->ether_addr_octet[3],
- mac->ether_addr_octet[4], mac->ether_addr_octet[5]);
-}
-
-char *
-utils_next_available_name (GSList *connections, const char *format)
-{
- GSList *names = NULL, *iter;
- char *cname = NULL;
- int i = 0;
-
- for (iter = connections; iter; iter = g_slist_next (iter)) {
- NMConnection *candidate = NM_CONNECTION (iter->data);
- NMSettingConnection *s_con;
- const char *id;
-
- s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (candidate, NM_TYPE_SETTING_CONNECTION));
- id = nm_setting_connection_get_id (s_con);
- g_assert (id);
- names = g_slist_append (names, (gpointer) id);
- }
-
- /* Find the next available unique connection name */
- while (!cname && (i++ < 10000)) {
- char *temp;
- gboolean found = FALSE;
-
- temp = g_strdup_printf (format, i);
- for (iter = names; iter; iter = g_slist_next (iter)) {
- if (!strcmp (iter->data, temp)) {
- found = TRUE;
- break;
- }
- }
- if (!found)
- cname = temp;
- else
- g_free (temp);
- }
-
- g_slist_free (names);
- return cname;
-}
static MplPanelClient *main_widget = NULL;
diff --git a/src/utils.h b/src/utils.h
index d4dd553..e6cce21 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -1,59 +1,13 @@
-/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
- *
- * Dan Williams <dcbw redhat com>
- *
- * 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 2007 Red Hat, Inc.
- */
+/* NetworkManager Wireless Applet -- Display wireless access points and allow user control */
-#ifndef UTILS_H
-#define UTILS_H
+#ifndef HACK_H
+#define HACK_H
-#include <glib.h>
-#include <gtk/gtk.h>
-#include <nm-connection.h>
-#include <nm-device.h>
-#include <net/ethernet.h>
-#include <nm-access-point.h>
-
-char * utils_bin2hexstr (const char *bytes, int len, int final_len);
-
-const char *utils_get_device_description (NMDevice *device);
-
-guint32 utils_freq_to_channel (guint32 freq);
-guint32 utils_channel_to_freq (guint32 channel, char *band);
-guint32 utils_find_next_channel (guint32 channel, int direction, char *band);
-
-gboolean utils_ether_addr_valid (const struct ether_addr *test_addr);
-
-gboolean utils_connection_valid_for_device (NMConnection *connection,
- NMDevice *device,
- gpointer specific_object);
-
-GSList *utils_filter_connections_for_device (NMDevice *device, GSList *connections);
-
-char *utils_ether_ntop (const struct ether_addr *mac);
-
-gboolean utils_mac_valid (const struct ether_addr *addr);
-
-char *utils_next_available_name (GSList *connections, const char *format);
+#include <glib-object.h>
/* Ugh, please avert your eyes... */
void utils_set_main_widget (GObject *panel_client);
void utils_hide_main_widget (void);
-#endif /* UTILS_H */
+#endif /* HACK_H */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]