[network-manager-applet] editor: enhance launch options with create and edit capabilities (bgo #644498)
- From: Dan Williams <dcbw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-applet] editor: enhance launch options with create and edit capabilities (bgo #644498)
- Date: Tue, 15 Mar 2011 04:59:58 +0000 (UTC)
commit 98899ba4470c90e8bf3c2c874d2c25bfac3d6878
Author: Matthias Clasen <mclasen redhat com>
Date: Mon Mar 14 23:58:11 2011 -0500
editor: enhance launch options with create and edit capabilities (bgo #644498)
Allow the editor to be launched with --create and --edit options
to suppress showing the main window while creating or editing
different types of connections.
(significantly reworked and cleaned up by dcbw)
src/connection-editor/main.c | 252 +++++++++++++------
.../nm-connection-editor-service.xml | 2 +-
src/connection-editor/nm-connection-list.c | 258 +++++++++++++++-----
src/connection-editor/nm-connection-list.h | 11 +-
4 files changed, 378 insertions(+), 145 deletions(-)
---
diff --git a/src/connection-editor/main.c b/src/connection-editor/main.c
index 82226e0..50d5d3f 100644
--- a/src/connection-editor/main.c
+++ b/src/connection-editor/main.c
@@ -17,7 +17,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
- * (C) Copyright 2004-2005 Red Hat, Inc.
+ * Copyright (C) 2004 - 2011 Red Hat, Inc.
*/
#ifdef HAVE_CONFIG_H
@@ -40,14 +40,21 @@
#include <nm-setting-gsm.h>
#include <nm-setting-cdma.h>
#include "nm-connection-list.h"
+#include "nm-connection-editor.h"
+#include "page-wired.h"
static GMainLoop *loop = NULL;
-#define ARG_TYPE "type"
+#define ARG_TYPE "type"
+#define ARG_CREATE "create"
+#define ARG_SHOW "show"
+#define ARG_UUID "uuid"
-#define DBUS_TYPE_G_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
+#define DBUS_TYPE_G_MAP_OF_VARIANT (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
-#define NM_CE_DBUS_SERVICE_NAME "org.freedesktop.NetworkManager.Gnome.ConnectionEditor"
+#define NM_CE_DBUS_SERVICE_NAME "org.gnome.nm_connection_editor"
+
+/*************************************************/
#define NM_TYPE_CE_SERVICE (nm_ce_service_get_type ())
#define NM_CE_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_CE_SERVICE, NMCEService))
@@ -96,21 +103,20 @@ nm_ce_service_new (DBusGConnection *bus, DBusGProxy *proxy, NMConnectionList *li
/* Register our single-instance service. Don't care if it fails. */
if (!dbus_g_proxy_call (proxy, "RequestName", &err,
- G_TYPE_STRING, NM_CE_DBUS_SERVICE_NAME,
- G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
- G_TYPE_INVALID,
- G_TYPE_UINT, &result,
- G_TYPE_INVALID)) {
+ G_TYPE_STRING, NM_CE_DBUS_SERVICE_NAME,
+ G_TYPE_UINT, DBUS_NAME_FLAG_DO_NOT_QUEUE,
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &result,
+ G_TYPE_INVALID)) {
g_warning ("Could not acquire the connection editor service.\n"
- " Message: '%s'", err->message);
+ " Message: '%s'", err->message);
g_error_free (err);
- } else {
- if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
- g_warning ("Could not acquire the connection editor service as it is already taken.");
- else {
- /* success */
- dbus_g_connection_register_g_object (bus, "/", object);
- }
+ return (NMCEService *) object;
+ }
+
+ if (result == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
+ /* success; grab the bus name */
+ dbus_g_connection_register_g_object (bus, "/", object);
}
return (NMCEService *) object;
@@ -122,66 +128,110 @@ nm_ce_service_init (NMCEService *self)
}
static void
-nm_ce_service_class_init (NMCEServiceClass *config_class)
+nm_ce_service_class_init (NMCEServiceClass *service_class)
{
- dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (config_class),
- &dbus_glib_nm_connection_editor_service_object_info);
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (service_class),
+ &dbus_glib_nm_connection_editor_service_object_info);
+}
+
+/*************************************************/
+
+static gboolean
+handle_arguments (NMConnectionList *list,
+ const char *type,
+ gboolean create,
+ gboolean show,
+ const char *edit_uuid,
+ gboolean quit_after)
+{
+ gboolean show_list = TRUE;
+ GType ctype;
+
+ /* Grab type to create or show */
+ ctype = nm_connection_lookup_setting_type (type ? type : NM_SETTING_WIRED_SETTING_NAME);
+ if (ctype == 0) {
+ g_warning ("Unknown connection type '%s'", type);
+ return TRUE;
+ }
+
+ if (show) {
+ /* Just show the given connection type page */
+ nm_connection_list_set_type (list, ctype);
+ } else if (create) {
+ if (!type) {
+ g_warning ("'create' requested but no connection type given.");
+ return TRUE;
+ }
+ nm_connection_list_create (list, ctype);
+
+ show_list = FALSE;
+ } else if (edit_uuid) {
+ /* Show the edit dialog for the given UUID */
+ nm_connection_list_edit (list, edit_uuid);
+ show_list = FALSE;
+ }
+
+ /* If only editing a single connection, exit when done with that connection */
+ if (show_list == FALSE && quit_after == TRUE)
+ g_signal_connect_swapped (list, "editing-done", G_CALLBACK (g_main_loop_quit), loop);
+
+ return show_list;
}
static gboolean
impl_start (NMCEService *self, GHashTable *table, GError **error)
{
GValue *value;
- GType def_type;
- const char *str_type;
+ const char *type = NULL;
+ const char *uuid = NULL;
+ gboolean create = FALSE;
+ gboolean show = FALSE;
+ gboolean show_list;
value = g_hash_table_lookup (table, ARG_TYPE);
if (value && G_VALUE_HOLDS_STRING (value)) {
- str_type = g_value_get_string (value);
- g_assert (str_type);
-
- if (!strcmp (str_type, NM_SETTING_CDMA_SETTING_NAME))
- str_type = NM_SETTING_GSM_SETTING_NAME;
- def_type = nm_connection_lookup_setting_type (str_type);
- nm_connection_list_set_type (self->list, def_type);
+ type = g_value_get_string (value);
+ g_assert (type);
}
- nm_connection_list_present (self->list);
- return TRUE;
-}
+ value = g_hash_table_lookup (table, ARG_UUID);
+ if (value && G_VALUE_HOLDS_STRING (value)) {
+ uuid = g_value_get_string (value);
+ g_assert (uuid);
+ }
+ value = g_hash_table_lookup (table, ARG_CREATE);
+ if (value && G_VALUE_HOLDS_BOOLEAN (value))
+ create = g_value_get_boolean (value);
-static void
-signal_handler (int signo)
-{
- if (signo == SIGINT || signo == SIGTERM) {
- g_message ("Caught signal %d, shutting down...", signo);
- g_main_loop_quit (loop);
- }
-}
+ value = g_hash_table_lookup (table, ARG_SHOW);
+ if (value && G_VALUE_HOLDS_BOOLEAN (value))
+ show = g_value_get_boolean (value);
-static void
-setup_signals (void)
-{
- struct sigaction action;
- sigset_t mask;
+ show_list = handle_arguments (self->list, type, create, show, uuid, FALSE);
+ if (show_list)
+ nm_connection_list_present (self->list);
- sigemptyset (&mask);
- action.sa_handler = signal_handler;
- action.sa_mask = mask;
- action.sa_flags = 0;
- sigaction (SIGTERM, &action, NULL);
- sigaction (SIGINT, &action, NULL);
+ return TRUE;
}
static gboolean
-try_existing_instance (DBusGConnection *bus, DBusGProxy *proxy, const char *type)
+try_existing_instance (DBusGConnection *bus,
+ DBusGProxy *proxy,
+ const char *type,
+ gboolean create,
+ gboolean show,
+ const char *uuid)
{
gboolean has_owner = FALSE;
DBusGProxy *instance;
GHashTable *args;
GValue type_value = { 0, };
+ GValue create_value = { 0, };
+ GValue show_value = { 0, };
+ GValue uuid_value = { 0, };
gboolean success = FALSE;
+ GError *error = NULL;
if (!dbus_g_proxy_call (proxy, "NameHasOwner", NULL,
G_TYPE_STRING, NM_CE_DBUS_SERVICE_NAME, G_TYPE_INVALID,
@@ -203,19 +253,57 @@ try_existing_instance (DBusGConnection *bus, DBusGProxy *proxy, const char *type
if (type) {
g_value_init (&type_value, G_TYPE_STRING);
g_value_set_static_string (&type_value, type);
- g_hash_table_insert (args, "type", &type_value);
+ g_hash_table_insert (args, ARG_TYPE, &type_value);
+ }
+ if (create) {
+ g_value_init (&create_value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (&create_value, TRUE);
+ g_hash_table_insert (args, ARG_CREATE, &create_value);
+ }
+ if (show) {
+ g_value_init (&show_value, G_TYPE_BOOLEAN);
+ g_value_set_boolean (&show_value, TRUE);
+ g_hash_table_insert (args, ARG_SHOW, &show_value);
+ }
+ if (uuid) {
+ g_value_init (&uuid_value, G_TYPE_BOOLEAN);
+ g_value_set_static_string (&uuid_value, uuid);
+ g_hash_table_insert (args, ARG_UUID, &uuid_value);
}
- if (dbus_g_proxy_call (instance, "Start", NULL,
+ if (dbus_g_proxy_call (instance, "Start", &error,
DBUS_TYPE_G_MAP_OF_VARIANT, args, G_TYPE_INVALID,
G_TYPE_INVALID))
success = TRUE;
+ else
+ g_warning ("%s: error calling start: %s", __func__, error->message);
g_hash_table_destroy (args);
g_object_unref (instance);
return success;
}
+static void
+signal_handler (int signo)
+{
+ if (signo == SIGINT || signo == SIGTERM)
+ g_main_loop_quit (loop);
+}
+
+static void
+setup_signals (void)
+{
+ struct sigaction action;
+ sigset_t mask;
+
+ sigemptyset (&mask);
+ action.sa_handler = signal_handler;
+ action.sa_mask = mask;
+ action.sa_flags = 0;
+ sigaction (SIGTERM, &action, NULL);
+ sigaction (SIGINT, &action, NULL);
+}
+
int
main (int argc, char *argv[])
{
@@ -224,12 +312,19 @@ main (int argc, char *argv[])
NMConnectionList *list;
DBusGConnection *bus;
char *type = NULL;
- GType ctype;
+ gboolean create = FALSE;
+ gboolean show = FALSE;
+ gboolean success;
+ char *uuid = NULL;
NMCEService *service = NULL;
DBusGProxy *proxy = NULL;
+ gboolean show_list;
GOptionEntry entries[] = {
- { ARG_TYPE, 0, 0, G_OPTION_ARG_STRING, &type, "Type of connection to show at launch", NM_SETTING_WIRED_SETTING_NAME },
+ { ARG_TYPE, 0, 0, G_OPTION_ARG_STRING, &type, "Type of connection to show or create", NM_SETTING_WIRED_SETTING_NAME },
+ { ARG_CREATE, 0, 0, G_OPTION_ARG_NONE, &create, "Create a new connection", NULL },
+ { ARG_SHOW, 0, 0, G_OPTION_ARG_NONE, &show, "Show a given connection type page", NULL },
+ { "edit", 0, 0, G_OPTION_ARG_STRING, &uuid, "Edit an existing connection with a given UUID", "UUID" },
{ NULL }
};
@@ -238,20 +333,21 @@ main (int argc, char *argv[])
gtk_init (&argc, &argv);
textdomain (GETTEXT_PACKAGE);
- /* parse arguments: an idea is to use gconf://$setting_name / system://$setting_name to
- allow this program to work with both GConf and system-wide settings */
-
opt_ctx = g_option_context_new (NULL);
g_option_context_set_summary (opt_ctx, "Allows users to view and edit network connection settings");
g_option_context_add_main_entries (opt_ctx, entries, NULL);
+ success = g_option_context_parse (opt_ctx, &argc, &argv, &error);
+ g_option_context_free (opt_ctx);
- if (!g_option_context_parse (opt_ctx, &argc, &argv, &error)) {
+ if (!success) {
g_warning ("%s\n", error->message);
g_error_free (error);
return 1;
}
- g_option_context_free (opt_ctx);
+ /* Just one page for both CDMA & GSM, handle that here */
+ if (type && g_strcmp0 (type, NM_SETTING_CDMA_SETTING_NAME) == 0)
+ type = (char *) NM_SETTING_GSM_SETTING_NAME;
/* Inits the dbus-glib type system too */
bus = dbus_g_bus_get (DBUS_BUS_SESSION, NULL);
@@ -260,42 +356,44 @@ main (int argc, char *argv[])
"org.freedesktop.DBus",
"/org/freedesktop/DBus",
"org.freedesktop.DBus");
- /* Check for an existing instance on the bus */
- if (proxy) {
- if (try_existing_instance (bus, proxy, type))
- goto exit;
- }
+ g_assert (proxy);
+
+ /* Check for an existing instance on the bus, and if there
+ * is one, send the arguments to it and exit instead of opening
+ * a second instance of the connection editor.
+ */
+ if (try_existing_instance (bus, proxy, type, create, show, uuid))
+ return 0;
}
loop = g_main_loop_new (NULL, FALSE);
- if (!type)
- type = (char *) NM_SETTING_WIRED_SETTING_NAME;
- if (!strcmp (type, NM_SETTING_CDMA_SETTING_NAME))
- type = (char *) NM_SETTING_GSM_SETTING_NAME;
-
- ctype = nm_connection_lookup_setting_type (type);
- list = nm_connection_list_new (ctype);
+ list = nm_connection_list_new ();
if (!list) {
g_warning ("Failed to initialize the UI, exiting...");
return 1;
}
+ g_signal_connect_swapped (list, "done", G_CALLBACK (g_main_loop_quit), loop);
/* Create our single-instance-app service if we can */
if (proxy)
service = nm_ce_service_new (bus, proxy, list);
- g_signal_connect_swapped (G_OBJECT (list), "done", G_CALLBACK (g_main_loop_quit), loop);
- nm_connection_list_run (list);
+ /* Show the dialog */
+ g_signal_connect_swapped (list, "done", G_CALLBACK (g_main_loop_quit), loop);
+
+ /* Figure out what page or editor window we'll show initially */
+ show_list = handle_arguments (list, type, create, show, uuid, (create || show || uuid));
+ if (show_list)
+ nm_connection_list_present (list);
setup_signals ();
g_main_loop_run (loop);
+ /* Cleanup */
g_object_unref (list);
if (service)
g_object_unref (service);
-
-exit:
if (proxy)
g_object_unref (proxy);
if (bus)
diff --git a/src/connection-editor/nm-connection-editor-service.xml b/src/connection-editor/nm-connection-editor-service.xml
index 69bd0cd..8370449 100644
--- a/src/connection-editor/nm-connection-editor-service.xml
+++ b/src/connection-editor/nm-connection-editor-service.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<node name="/">
- <interface name="org.freedesktop.NetworkManager.Gnome.ConnectionEditor">
+ <interface name="org.gnome.nm_connection_editor">
<method name="Start">
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_start"/>
<arg name="args" type="a{sv}" direction="in"/>
diff --git a/src/connection-editor/nm-connection-list.c b/src/connection-editor/nm-connection-list.c
index 95b35b4..c55c674 100644
--- a/src/connection-editor/nm-connection-list.c
+++ b/src/connection-editor/nm-connection-list.c
@@ -33,6 +33,7 @@
#include <nm-setting-connection.h>
#include <nm-connection.h>
#include <nm-setting.h>
+#include <nm-setting-connection.h>
#include <nm-setting-wired.h>
#include <nm-setting-wireless.h>
#include <nm-setting-vpn.h>
@@ -60,6 +61,7 @@ G_DEFINE_TYPE (NMConnectionList, nm_connection_list, G_TYPE_OBJECT)
enum {
LIST_DONE,
+ EDITING_DONE,
LIST_LAST_SIGNAL
};
@@ -528,8 +530,10 @@ add_response_cb (NMConnectionEditor *editor, gint response, GError *error, gpoin
}
g_hash_table_remove (info->list->editors, nm_connection_editor_get_connection (editor));
+ g_signal_emit (info->list, list_signals[EDITING_DONE], 0, 0);
}
+
static void
really_add_connection (NMConnection *connection,
gboolean canceled,
@@ -543,14 +547,17 @@ really_add_connection (NMConnection *connection,
g_return_if_fail (info != NULL);
- if (canceled)
+ if (canceled) {
+ g_signal_emit (info->list, list_signals[EDITING_DONE], 0, 0);
return;
+ }
if (!connection) {
error_dialog (info->list_window,
_("Could not create new connection"),
"%s",
(error && error->message) ? error->message : message);
+ g_signal_emit (info->list, list_signals[EDITING_DONE], 0, 0);
return;
}
@@ -563,6 +570,7 @@ really_add_connection (NMConnection *connection,
"%s",
(editor_error && editor_error->message) ? editor_error->message : message);
g_clear_error (&editor_error);
+ g_signal_emit (info->list, list_signals[EDITING_DONE], 0, 0);
return;
}
@@ -594,10 +602,10 @@ add_clicked (GtkButton *button, gpointer user_data)
return;
}
- (*(info->new_func)) (GTK_WINDOW (list->dialog),
- really_add_connection,
- page_get_connections,
- info);
+ info->new_func (GTK_WINDOW (list->dialog),
+ really_add_connection,
+ page_get_connections,
+ info);
}
typedef struct {
@@ -666,6 +674,7 @@ edit_done_cb (NMConnectionEditor *editor, gint response, GError *error, gpointer
info);
g_error_free (edit_error);
}
+ g_signal_emit (info->list, list_signals[EDITING_DONE], 0, 0);
break;
case GTK_RESPONSE_NONE:
/* Show an error dialog if the editor initialization failed */
@@ -676,21 +685,20 @@ edit_done_cb (NMConnectionEditor *editor, gint response, GError *error, gpointer
case GTK_RESPONSE_CANCEL:
default:
g_hash_table_remove (info->list->editors, connection);
+ g_signal_emit (info->list, list_signals[EDITING_DONE], 0, 0);
g_free (info);
break;
}
}
static void
-do_edit (ActionInfo *info)
+edit_connection (ActionInfo *info, NMConnection *connection)
{
- NMRemoteConnection *connection;
NMConnectionEditor *editor;
EditInfo *edit_info;
GError *error = NULL;
const char *message = _("The connection editor dialog could not be initialized due to an unknown error.");
- connection = get_active_connection (info->treeview);
g_return_if_fail (connection != NULL);
/* Don't allow two editors for the same connection */
@@ -720,6 +728,12 @@ do_edit (ActionInfo *info)
}
static void
+do_edit (ActionInfo *info)
+{
+ edit_connection (info, NM_CONNECTION (get_active_connection (info->treeview)));
+}
+
+static void
delete_result_cb (NMConnectionList *list,
GError *error,
gpointer user_data)
@@ -972,6 +986,9 @@ dispose (GObject *object)
if (list->editors)
g_hash_table_destroy (list->editors);
+ if (list->actions)
+ g_hash_table_destroy (list->actions);
+
if (list->wired_icon)
g_object_unref (list->wired_icon);
if (list->wireless_icon)
@@ -1013,6 +1030,15 @@ nm_connection_list_class_init (NMConnectionListClass *klass)
NULL, NULL,
g_cclosure_marshal_VOID__INT,
G_TYPE_NONE, 1, G_TYPE_INT);
+
+ list_signals[EDITING_DONE] =
+ g_signal_new ("editing-done",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMConnectionListClass, done),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
}
static GtkTreeView *
@@ -1070,8 +1096,28 @@ action_info_free (ActionInfo *info)
g_free (info);
}
+static char *
+get_action_name (GType ctype, const char *action)
+{
+ return g_strdup_printf ("%s_%s", g_type_name (ctype), action);
+}
+
+static ActionInfo *
+find_action_info (NMConnectionList *list, GType ctype, const char *action)
+{
+ ActionInfo *ret;
+ char *name;
+
+ name = get_action_name (ctype, action);
+ ret = g_hash_table_lookup (list->actions, name);
+ g_free (name);
+ return ret;
+}
+
static ActionInfo *
action_info_new (NMConnectionList *list,
+ gchar *action,
+ GType ctype,
GtkTreeView *treeview,
GtkWindow *list_window,
GtkWidget *button)
@@ -1079,7 +1125,7 @@ action_info_new (NMConnectionList *list,
ActionInfo *info;
info = g_malloc0 (sizeof (ActionInfo));
- g_object_weak_ref (G_OBJECT (list), (GWeakNotify) action_info_free, info);
+ g_hash_table_insert (list->actions, get_action_name (ctype, action), info);
info->list = list;
info->treeview = treeview;
@@ -1137,7 +1183,7 @@ add_connection_buttons (NMConnectionList *self,
name = g_strdup_printf ("%s_add", prefix);
button = GTK_WIDGET (gtk_builder_get_object (self->gui, name));
g_free (name);
- info = action_info_new (self, treeview, GTK_WINDOW (self->dialog), NULL);
+ info = action_info_new (self, "add", ctype, treeview, GTK_WINDOW (self->dialog), NULL);
g_signal_connect (button, "clicked", G_CALLBACK (add_clicked), info);
if (ctype == NM_TYPE_SETTING_VPN) {
GHashTable *plugins;
@@ -1158,7 +1204,7 @@ add_connection_buttons (NMConnectionList *self,
g_free (name);
/* Edit */
- info = action_info_new (self, treeview, GTK_WINDOW (self->dialog), NULL);
+ info = action_info_new (self, "edit", ctype, treeview, GTK_WINDOW (self->dialog), NULL);
button = ce_polkit_button_new (_("_Edit"),
_("Edit the selected connection"),
_("_Edit..."),
@@ -1176,7 +1222,7 @@ add_connection_buttons (NMConnectionList *self,
pk_button_selection_changed_cb (selection, info);
/* Delete */
- info = action_info_new (self, treeview, GTK_WINDOW (self->dialog), NULL);
+ info = action_info_new (self, "delete", ctype, treeview, GTK_WINDOW (self->dialog), NULL);
button = ce_polkit_button_new (_("_Delete"),
_("Delete the selected connection"),
_("_Delete..."),
@@ -1200,7 +1246,7 @@ add_connection_buttons (NMConnectionList *self,
gboolean import_supported = FALSE;
GHashTable *plugins;
- info = action_info_new (self, treeview, GTK_WINDOW (self->dialog), button);
+ info = action_info_new (self, "import", ctype, treeview, GTK_WINDOW (self->dialog), button);
g_signal_connect (button, "clicked", G_CALLBACK (import_vpn_cb), info);
plugins = vpn_get_plugins (NULL);
@@ -1214,7 +1260,7 @@ add_connection_buttons (NMConnectionList *self,
button = GTK_WIDGET (gtk_builder_get_object (self->gui, name));
g_free (name);
if (button) {
- info = action_info_new (self, treeview, GTK_WINDOW (self->dialog), button);
+ info = action_info_new (self, "export", ctype, treeview, GTK_WINDOW (self->dialog), button);
g_signal_connect (button, "clicked", G_CALLBACK (export_vpn_cb), info);
g_signal_connect (selection, "changed", G_CALLBACK (vpn_list_selection_changed_cb), info);
gtk_widget_set_sensitive (button, FALSE);
@@ -1223,7 +1269,6 @@ add_connection_buttons (NMConnectionList *self,
static void
add_connection_tab (NMConnectionList *self,
- GType def_type,
GType ctype,
GdkPixbuf *pixbuf,
const char *prefix,
@@ -1233,7 +1278,6 @@ add_connection_tab (NMConnectionList *self,
char *name;
GtkWidget *child, *hbox, *notebook;
GtkTreeView *treeview;
- int pnum;
name = g_strdup_printf ("%s_child", prefix);
child = GTK_WIDGET (gtk_builder_get_object (self->gui, name));
@@ -1257,37 +1301,11 @@ add_connection_tab (NMConnectionList *self,
add_connection_buttons (self, prefix, treeview, ctype, new_func);
gtk_widget_show_all (GTK_WIDGET (notebook));
- g_object_set_data (G_OBJECT (treeview), TV_TYPE_TAG, GSIZE_TO_POINTER (ctype));
self->treeviews = g_slist_prepend (self->treeviews, treeview);
- if (def_type == ctype) {
- pnum = gtk_notebook_page_num (GTK_NOTEBOOK (notebook), child);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), pnum);
- }
-}
-
-static void
-add_connection_tabs (NMConnectionList *self, GType def_type)
-{
- add_connection_tab (self, def_type, NM_TYPE_SETTING_WIRED,
- self->wired_icon, "wired", _("Wired"),
- wired_connection_new);
-
- add_connection_tab (self, def_type, NM_TYPE_SETTING_WIRELESS,
- self->wireless_icon, "wireless", _("Wireless"),
- wifi_connection_new);
-
- add_connection_tab (self, def_type, NM_TYPE_SETTING_GSM,
- self->wwan_icon, "wwan", _("Mobile Broadband"),
- mobile_connection_new);
-
- add_connection_tab (self, def_type, NM_TYPE_SETTING_VPN,
- self->vpn_icon, "vpn", _("VPN"),
- vpn_connection_new);
-
- add_connection_tab (self, def_type, NM_TYPE_SETTING_PPPOE,
- self->wired_icon, "dsl", _("DSL"),
- dsl_connection_new);
+ /* Tag the notebook child and the treeview with the type of connection they contain */
+ g_object_set_data (G_OBJECT (child), TV_TYPE_TAG, GSIZE_TO_POINTER (ctype));
+ g_object_set_data (G_OBJECT (treeview), TV_TYPE_TAG, GSIZE_TO_POINTER (ctype));
}
static void
@@ -1354,7 +1372,7 @@ connection_added (NMRemoteSettings *settings,
}
NMConnectionList *
-nm_connection_list_new (GType def_type)
+nm_connection_list_new (void)
{
NMConnectionList *list;
DBusGConnection *bus;
@@ -1402,10 +1420,31 @@ nm_connection_list_new (GType def_type)
G_CALLBACK (connection_added),
list);
- add_connection_tabs (list, def_type);
-
list->editors = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_object_unref);
+ list->actions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) action_info_free);
+
+ /* Add each connection type tab */
+ add_connection_tab (list, NM_TYPE_SETTING_WIRED,
+ list->wired_icon, "wired", _("Wired"),
+ wired_connection_new);
+
+ add_connection_tab (list, NM_TYPE_SETTING_WIRELESS,
+ list->wireless_icon, "wireless", _("Wireless"),
+ wifi_connection_new);
+
+ add_connection_tab (list, NM_TYPE_SETTING_GSM,
+ list->wwan_icon, "wwan", _("Mobile Broadband"),
+ mobile_connection_new);
+
+ add_connection_tab (list, NM_TYPE_SETTING_VPN,
+ list->vpn_icon, "vpn", _("VPN"),
+ vpn_connection_new);
+
+ add_connection_tab (list, NM_TYPE_SETTING_PPPOE,
+ list->wired_icon, "dsl", _("DSL"),
+ dsl_connection_new);
+ /* Connect to the main dialog's response handler */
list->dialog = GTK_WIDGET (gtk_builder_get_object (list->gui, "NMConnectionList"));
if (!list->dialog)
goto error;
@@ -1424,14 +1463,6 @@ error:
}
void
-nm_connection_list_present (NMConnectionList *list)
-{
- g_return_if_fail (NM_IS_CONNECTION_LIST (list));
-
- gtk_window_present (GTK_WINDOW (list->dialog));
-}
-
-void
nm_connection_list_set_type (NMConnectionList *self, GType ctype)
{
GtkNotebook *notebook;
@@ -1454,9 +1485,105 @@ nm_connection_list_set_type (NMConnectionList *self, GType ctype)
break;
}
}
+}
+
+void
+nm_connection_list_create (NMConnectionList *self, GType ctype)
+{
+ ActionInfo *info;
+
+ g_return_if_fail (NM_IS_CONNECTION_LIST (self));
+
+ info = find_action_info (self, ctype, "add");
+ if (info == NULL) {
+ error_dialog (NULL,
+ _("Error creating connection"),
+ _("Don't know how to create '%s' connections"), g_type_name (ctype));
+ } else {
+ info->new_func (GTK_WINDOW (info->list->dialog),
+ really_add_connection,
+ page_get_connections,
+ info);
+ }
+}
+
+static NMConnection *
+get_connection (NMRemoteSettings *settings, const gchar *id)
+{
+ const gchar *uuid;
+ NMConnection *connection = NULL;
+ GSList *list, *l;
+
+ list = nm_remote_settings_list_connections (settings);
+ for (l = list; l; l = l->next) {
+ connection = l->data;
+ uuid = nm_connection_get_uuid (connection);
+ if (g_strcmp0 (uuid, id) == 0) {
+ g_slist_free (list);
+ return connection;
+ }
+ }
+
+ g_slist_free (list);
+ return NULL;
+}
+
+typedef struct {
+ NMConnectionList *self;
+ const gchar *uuid;
+ gboolean wait;
+} EditData;
+
+static void
+connections_read (NMRemoteSettings *settings, EditData *data)
+{
+ NMConnection *connection;
+
+ connection = get_connection (data->self->settings, data->uuid);
+ if (connection) {
+ NMSettingConnection *s_con;
+ const char *type;
+ ActionInfo *info;
+
+ s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
+ type = nm_setting_connection_get_connection_type (s_con);
+ info = find_action_info (data->self, nm_connection_lookup_setting_type (type), "edit");
+ if (info != NULL)
+ edit_connection (info, connection);
+ else {
+ error_dialog (NULL,
+ _("Error editing connection"),
+ _("Don't know how to edit '%s' connections"), type);
+ }
+
+ g_object_unref (connection);
+ } else if (data->wait) {
+ data->wait = FALSE;
+ g_signal_connect (data->self->settings, "connections-read",
+ G_CALLBACK (connections_read), data);
+ return;
+ } else {
+ error_dialog (NULL,
+ _("Error editing connection"),
+ _("Did not find a connection with UUID '%s'"), data->uuid);
+ }
+
+ g_free (data);
+}
+
+void
+nm_connection_list_edit (NMConnectionList *self, const gchar *uuid)
+{
+ EditData *data;
- /* Bring the connection list to the front */
- nm_connection_list_present (self);
+ g_return_if_fail (NM_IS_CONNECTION_LIST (self));
+
+ data = g_new0 (EditData, 1);
+ data->self = self;
+ data->uuid = uuid;
+ data->wait = TRUE;
+
+ connections_read (self->settings, data);
}
static void
@@ -1472,15 +1599,18 @@ list_close_cb (GtkDialog *dialog, gpointer user_data)
}
void
-nm_connection_list_run (NMConnectionList *list)
+nm_connection_list_present (NMConnectionList *list)
{
g_return_if_fail (NM_IS_CONNECTION_LIST (list));
- g_signal_connect (G_OBJECT (list->dialog), "response",
- G_CALLBACK (list_response_cb), list);
- g_signal_connect (G_OBJECT (list->dialog), "close",
- G_CALLBACK (list_close_cb), list);
+ if (!list->signals_connected) {
+ g_signal_connect (G_OBJECT (list->dialog), "response",
+ G_CALLBACK (list_response_cb), list);
+ g_signal_connect (G_OBJECT (list->dialog), "close",
+ G_CALLBACK (list_close_cb), list);
+ list->signals_connected = TRUE;
+ }
- nm_connection_list_present (list);
+ gtk_window_present (GTK_WINDOW (list->dialog));
}
diff --git a/src/connection-editor/nm-connection-list.h b/src/connection-editor/nm-connection-list.h
index 314cc5e..2db6c23 100644
--- a/src/connection-editor/nm-connection-list.h
+++ b/src/connection-editor/nm-connection-list.h
@@ -40,6 +40,8 @@ typedef struct {
GHashTable *editors;
GSList *treeviews;
+ GHashTable *actions;
+
NMClient *nm_client;
NMRemoteSettings *settings;
@@ -52,6 +54,8 @@ typedef struct {
GdkPixbuf *vpn_icon;
GdkPixbuf *unknown_icon;
GtkIconTheme *icon_theme;
+
+ gboolean signals_connected;
} NMConnectionList;
typedef struct {
@@ -59,15 +63,16 @@ typedef struct {
/* Signals */
void (*done) (NMConnectionList *list, gint result);
+ void (*editing_done) (NMConnectionList *list, gint result);
} NMConnectionListClass;
GType nm_connection_list_get_type (void);
-NMConnectionList *nm_connection_list_new (GType def_type);
-
-void nm_connection_list_run (NMConnectionList *list);
+NMConnectionList *nm_connection_list_new (void);
void nm_connection_list_set_type (NMConnectionList *list, GType ctype);
void nm_connection_list_present (NMConnectionList *list);
+void nm_connection_list_create (NMConnectionList *list, GType ctype);
+void nm_connection_list_edit (NMConnectionList *list, const gchar *uuid);
#endif
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]