[network-manager-applet/new-editor: 3/7] connection-editor: move VPN import/export
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-applet/new-editor: 3/7] connection-editor: move VPN import/export
- Date: Fri, 16 Mar 2012 11:35:35 +0000 (UTC)
commit 7bba147ee645905ad721d01f6b3ad336d006e530
Author: Dan Winship <danw gnome org>
Date: Thu Mar 8 10:35:01 2012 -0500
connection-editor: move VPN import/export
Make VPN Import be an option underneath the other VPN types in the
"Add" dialog box, and make VPN Export be a button in the connection
editor.
(Prelude to merging all the connection-list pages together.)
src/connection-editor/nm-connection-editor.c | 44 ++++++
src/connection-editor/nm-connection-editor.h | 1 +
src/connection-editor/nm-connection-editor.ui | 145 +++++++-----------
src/connection-editor/nm-connection-list.c | 205 -------------------------
src/connection-editor/page-vpn.c | 82 ++++++++++
src/connection-editor/page-vpn.h | 2 +
src/connection-editor/vpn-helpers.c | 106 +++++++------
7 files changed, 239 insertions(+), 346 deletions(-)
---
diff --git a/src/connection-editor/nm-connection-editor.c b/src/connection-editor/nm-connection-editor.c
index 93d0e51..c921e57 100644
--- a/src/connection-editor/nm-connection-editor.c
+++ b/src/connection-editor/nm-connection-editor.c
@@ -64,6 +64,7 @@
#include "page-ppp.h"
#include "page-vpn.h"
#include "ce-polkit-button.h"
+#include "vpn-helpers.h"
G_DEFINE_TYPE (NMConnectionEditor, nm_connection_editor, G_TYPE_OBJECT)
@@ -231,6 +232,7 @@ connection_editor_validate (NMConnectionEditor *editor)
done:
ce_polkit_button_set_master_sensitive (CE_POLKIT_BUTTON (editor->ok_button), valid);
+ gtk_widget_set_sensitive (editor->export_button, valid);
update_sensitivity (editor);
}
@@ -294,6 +296,7 @@ nm_connection_editor_init (NMConnectionEditor *editor)
editor->window = GTK_WIDGET (gtk_builder_get_object (editor->builder, "nm-connection-editor"));
editor->cancel_button = GTK_WIDGET (gtk_builder_get_object (editor->builder, "cancel_button"));
+ editor->export_button = GTK_WIDGET (gtk_builder_get_object (editor->builder, "export_button"));
editor->all_checkbutton = GTK_WIDGET (gtk_builder_get_object (editor->builder, "system_checkbutton"));
}
@@ -585,6 +588,9 @@ page_initialized (CEPage *page, GError *error, gpointer user_data)
gtk_container_remove (GTK_CONTAINER (parent), widget);
gtk_notebook_append_page (notebook, widget, label);
+ if (CE_IS_PAGE_VPN (page) && ce_page_vpn_can_export (CE_PAGE_VPN (page)))
+ gtk_widget_show (editor->export_button);
+
/* Move the page from the initializing list to the main page list */
editor->initializing_pages = g_slist_remove (editor->initializing_pages, page);
editor->pages = g_slist_append (editor->pages, page);
@@ -875,6 +881,42 @@ ok_button_clicked_cb (GtkWidget *widget, gpointer user_data)
g_signal_emit (self, editor_signals[EDITOR_DONE], 0, GTK_RESPONSE_OK, NULL);
}
+static void
+vpn_export_get_secrets_cb (NMRemoteConnection *connection,
+ GHashTable *secrets,
+ GError *error,
+ gpointer user_data)
+{
+ NMConnection *tmp;
+
+ /* We don't really care about errors; if the user couldn't authenticate
+ * then just let them export everything except secrets. Duplicate the
+ * connection so that we don't let secrets sit around in the original
+ * one.
+ */
+ tmp = nm_connection_duplicate (NM_CONNECTION (connection));
+ g_assert (tmp);
+ if (secrets)
+ nm_connection_update_secrets (tmp, NM_SETTING_VPN_SETTING_NAME, secrets, NULL);
+ vpn_export (tmp);
+ g_object_unref (tmp);
+}
+
+static void
+export_button_clicked_cb (GtkWidget *widget, gpointer user_data)
+{
+ NMConnectionEditor *self = NM_CONNECTION_EDITOR (user_data);
+
+ if (NM_IS_REMOTE_CONNECTION (self->orig_connection)) {
+ /* Grab secrets if we can */
+ nm_remote_connection_get_secrets (NM_REMOTE_CONNECTION (self->orig_connection),
+ NM_SETTING_VPN_SETTING_NAME,
+ vpn_export_get_secrets_cb,
+ self);
+ } else
+ vpn_export (self->connection);
+}
+
void
nm_connection_editor_run (NMConnectionEditor *self)
{
@@ -887,6 +929,8 @@ nm_connection_editor_run (NMConnectionEditor *self)
G_CALLBACK (ok_button_clicked_cb), self);
g_signal_connect (G_OBJECT (self->cancel_button), "clicked",
G_CALLBACK (cancel_button_clicked_cb), self);
+ g_signal_connect (G_OBJECT (self->export_button), "clicked",
+ G_CALLBACK (export_button_clicked_cb), self);
nm_connection_editor_present (self);
}
diff --git a/src/connection-editor/nm-connection-editor.h b/src/connection-editor/nm-connection-editor.h
index 250f7b9..d1cfeee 100644
--- a/src/connection-editor/nm-connection-editor.h
+++ b/src/connection-editor/nm-connection-editor.h
@@ -56,6 +56,7 @@ typedef struct {
GtkWidget *window;
GtkWidget *ok_button;
GtkWidget *cancel_button;
+ GtkWidget *export_button;
guint nag_id;
gboolean busy;
diff --git a/src/connection-editor/nm-connection-editor.ui b/src/connection-editor/nm-connection-editor.ui
index 2e24c9d..3406fb7 100644
--- a/src/connection-editor/nm-connection-editor.ui
+++ b/src/connection-editor/nm-connection-editor.ui
@@ -316,98 +316,32 @@
</packing>
</child>
<child>
- <object class="GtkVBox" id="vbox1">
+ <object class="GtkVButtonBox" id="vpn_button_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
+ <property name="layout_style">start</property>
<child>
- <object class="GtkVButtonBox" id="vpn_button_box">
+ <object class="GtkButton" id="vpn_add">
+ <property name="label">gtk-add</property>
<property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <property name="layout_style">start</property>
- <child>
- <object class="GtkButton" id="vpn_add">
- <property name="label">gtk-add</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="can_default">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_stock">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
+ <property name="can_focus">True</property>
+ <property name="can_default">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
- <property name="fill">True</property>
+ <property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
- <object class="GtkHSeparator" id="hseparator1">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
+ <placeholder/>
</child>
<child>
- <object class="GtkVButtonBox" id="vpn_ix_button_box">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="spacing">6</property>
- <property name="layout_style">end</property>
- <child>
- <object class="GtkButton" id="vpn_import">
- <property name="label" translatable="yes">_Import</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkButton" id="vpn_export">
- <property name="label" translatable="yes">E_xport</property>
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">False</property>
- <property name="position">1</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
+ <placeholder/>
</child>
</object>
<packing>
@@ -580,15 +514,43 @@
</packing>
</child>
<child>
- <object class="GtkCheckButton" id="connection_autoconnect">
- <property name="label" translatable="yes">Connect _automatically</property>
+ <object class="GtkVBox" id="vbox1">
<property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">False</property>
- <property name="use_action_appearance">False</property>
- <property name="use_underline">True</property>
- <property name="active">True</property>
- <property name="draw_indicator">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkCheckButton" id="connection_autoconnect">
+ <property name="label" translatable="yes">Connect _automatically</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="use_underline">True</property>
+ <property name="xalign">0</property>
+ <property name="active">True</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkCheckButton" id="system_checkbutton">
+ <property name="label" translatable="yes">Available to all users</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">False</property>
+ <property name="use_action_appearance">False</property>
+ <property name="xalign">0</property>
+ <property name="draw_indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="expand">False</property>
@@ -625,17 +587,16 @@
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
- <object class="GtkCheckButton" id="system_checkbutton">
- <property name="label" translatable="yes">Available to all users</property>
- <property name="visible">True</property>
+ <object class="GtkButton" id="export_button">
+ <property name="label" translatable="yes">_Export...</property>
<property name="can_focus">True</property>
- <property name="receives_default">False</property>
+ <property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
- <property name="draw_indicator">True</property>
+ <property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
- <property name="fill">False</property>
+ <property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
diff --git a/src/connection-editor/nm-connection-list.c b/src/connection-editor/nm-connection-list.c
index 09e84ea..c9a0929 100644
--- a/src/connection-editor/nm-connection-list.c
+++ b/src/connection-editor/nm-connection-list.c
@@ -42,7 +42,6 @@
#include <nm-setting-pppoe.h>
#include <nm-setting-ppp.h>
#include <nm-setting-serial.h>
-#include <nm-vpn-plugin-ui-interface.h>
#include <nm-utils.h>
#include <nm-remote-settings.h>
@@ -841,169 +840,6 @@ pk_button_selection_changed_cb (GtkTreeSelection *selection, gpointer user_data)
}
static void
-vpn_list_selection_changed_cb (GtkTreeSelection *selection, gpointer user_data)
-{
- ActionInfo *info = (ActionInfo *) user_data;
- NMVpnPluginUiInterface *plugin;
- NMRemoteConnection *connection;
- NMSettingVPN *s_vpn;
- const char *service_type;
- GtkTreeIter iter;
- GtkTreeModel *model;
- guint32 caps;
- gboolean supported = FALSE;
-
- if (!gtk_tree_selection_get_selected (selection, &model, &iter))
- goto done;
-
- connection = get_active_connection (info->treeview);
- if (!connection)
- goto done;
-
- s_vpn = nm_connection_get_setting_vpn (NM_CONNECTION (connection));
- service_type = s_vpn ? nm_setting_vpn_get_service_type (s_vpn) : NULL;
-
- if (!service_type)
- goto done;
-
- plugin = vpn_get_plugin_by_service (service_type);
- if (!plugin)
- goto done;
-
- caps = nm_vpn_plugin_ui_interface_get_capabilities (plugin);
- if (caps & NM_VPN_PLUGIN_UI_CAPABILITY_EXPORT)
- supported = TRUE;
-
-done:
- gtk_widget_set_sensitive (info->button, supported);
-}
-
-static void
-import_success_cb (NMConnection *connection, gpointer user_data)
-{
- ActionInfo *info = (ActionInfo *) user_data;
- NMConnectionEditor *editor;
- NMSettingConnection *s_con;
- NMSettingVPN *s_vpn;
- const char *service_type;
- char *s;
- GError *error = NULL;
- const char *message = _("The connection editor dialog could not be initialized due to an unknown error.");
-
- /* Basic sanity checks of the connection */
- s_con = nm_connection_get_setting_connection (connection);
- if (!s_con) {
- s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
- nm_connection_add_setting (connection, NM_SETTING (s_con));
- }
-
- s = (char *) nm_setting_connection_get_id (s_con);
- if (!s) {
- GSList *connections;
-
- connections = nm_remote_settings_list_connections (info->list->settings);
- s = ce_page_get_next_available_name (connections, _("VPN connection %d"));
- g_object_set (s_con, NM_SETTING_CONNECTION_ID, s, NULL);
- g_free (s);
-
- g_slist_free (connections);
- }
-
- s = (char *) nm_setting_connection_get_connection_type (s_con);
- if (!s || strcmp (s, NM_SETTING_VPN_SETTING_NAME))
- g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, NM_SETTING_VPN_SETTING_NAME, NULL);
-
- s = (char *) nm_setting_connection_get_uuid (s_con);
- if (!s) {
- s = nm_utils_uuid_generate ();
- g_object_set (s_con, NM_SETTING_CONNECTION_UUID, s, NULL);
- g_free (s);
- }
-
- s_vpn = nm_connection_get_setting_vpn (connection);
- service_type = s_vpn ? nm_setting_vpn_get_service_type (s_vpn) : NULL;
-
- if (!service_type || !strlen (service_type)) {
- GtkWidget *dialog;
-
- g_object_unref (connection);
-
- dialog = gtk_message_dialog_new (NULL,
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_ERROR,
- GTK_BUTTONS_OK,
- _("Cannot import VPN connection"));
- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
- _("The VPN plugin failed to import the VPN connection correctly\n\nError: no VPN service type."));
- gtk_window_set_transient_for (GTK_WINDOW (dialog), info->list_window);
- g_signal_connect (dialog, "delete-event", G_CALLBACK (gtk_widget_destroy), NULL);
- g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
- gtk_widget_show_all (dialog);
- gtk_window_present (GTK_WINDOW (dialog));
- return;
- }
-
- editor = nm_connection_editor_new (connection, info->list->nm_client, &error);
- if (!editor) {
- g_object_unref (connection);
- error_dialog (info->list_window,
- _("Could not edit imported connection"),
- "%s",
- (error && error->message) ? error->message : message);
- return;
- }
-
- g_signal_connect (editor, "done", G_CALLBACK (add_response_cb), info);
- g_hash_table_insert (info->list->editors, connection, editor);
-
- nm_connection_editor_run (editor);
-}
-
-static void
-import_vpn_cb (GtkButton *button, gpointer user_data)
-{
- vpn_import (import_success_cb, (ActionInfo *) user_data);
-}
-
-static void
-vpn_export_get_secrets_cb (NMRemoteConnection *connection,
- GHashTable *secrets,
- GError *error,
- gpointer user_data)
-{
- NMConnection *tmp;
-
- /* We don't really care about errors; if the user couldn't authenticate
- * then just let them export everything except secrets. Duplicate the
- * connection so that we don't let secrets sit around in the original
- * one.
- */
- tmp = nm_connection_duplicate (NM_CONNECTION (connection));
- g_assert (tmp);
- if (secrets)
- nm_connection_update_secrets (tmp, NM_SETTING_VPN_SETTING_NAME, secrets, NULL);
- vpn_export (tmp);
- g_object_unref (tmp);
-}
-
-
-static void
-export_vpn_cb (GtkButton *button, gpointer user_data)
-{
- ActionInfo *info = (ActionInfo *) user_data;
- NMRemoteConnection *connection;
-
- connection = get_active_connection (info->treeview);
- if (connection) {
- /* Grab secrets if we can */
- nm_remote_connection_get_secrets (connection,
- NM_SETTING_VPN_SETTING_NAME,
- vpn_export_get_secrets_cb,
- NULL);
- }
-}
-
-static void
connection_double_clicked_cb (GtkTreeView *tree_view,
GtkTreePath *path,
GtkTreeViewColumn *column,
@@ -1225,19 +1061,6 @@ action_info_set_new_func (ActionInfo *info,
}
static void
-check_vpn_import_supported (gpointer key, gpointer data, gpointer user_data)
-{
- NMVpnPluginUiInterface *plugin = NM_VPN_PLUGIN_UI_INTERFACE (data);
- gboolean *import_supported = user_data;
-
- if (*import_supported)
- return;
-
- if (nm_vpn_plugin_ui_interface_get_capabilities (plugin) & NM_VPN_PLUGIN_UI_CAPABILITY_IMPORT)
- *import_supported = TRUE;
-}
-
-static void
add_connection_buttons (NMConnectionList *self,
const char *prefix,
GtkTreeView *treeview,
@@ -1309,34 +1132,6 @@ add_connection_buttons (NMConnectionList *self,
g_signal_connect (button, "clicked", G_CALLBACK (delete_clicked), info);
g_signal_connect (selection, "changed", G_CALLBACK (pk_button_selection_changed_cb), info);
pk_button_selection_changed_cb (selection, info);
-
- /* Import */
- name = g_strdup_printf ("%s_import", prefix);
- button = GTK_WIDGET (gtk_builder_get_object (self->gui, name));
- g_free (name);
- if (button) {
- gboolean import_supported = FALSE;
- GHashTable *plugins;
-
- 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);
- if (plugins)
- g_hash_table_foreach (plugins, check_vpn_import_supported, &import_supported);
- gtk_widget_set_sensitive (button, import_supported);
- }
-
- /* Export */
- name = g_strdup_printf ("%s_export", prefix);
- button = GTK_WIDGET (gtk_builder_get_object (self->gui, name));
- g_free (name);
- if (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);
- }
}
static void
diff --git a/src/connection-editor/page-vpn.c b/src/connection-editor/page-vpn.c
index 70910eb..8e9f1a9 100644
--- a/src/connection-editor/page-vpn.c
+++ b/src/connection-editor/page-vpn.c
@@ -29,6 +29,7 @@
#include <nm-setting-connection.h>
#include <nm-setting-vpn.h>
+#include <nm-utils.h>
#define NM_VPN_API_SUBJECT_TO_CHANGE
#include <nm-vpn-plugin-ui-interface.h>
@@ -135,6 +136,14 @@ ce_page_vpn_new (NMConnection *connection,
return CE_PAGE (self);
}
+gboolean
+ce_page_vpn_can_export (CEPageVpn *page)
+{
+ CEPageVpnPrivate *priv = CE_PAGE_VPN_GET_PRIVATE (page);
+
+ return (nm_vpn_plugin_ui_interface_get_capabilities (priv->plugin) & NM_VPN_PLUGIN_UI_CAPABILITY_EXPORT) != 0;
+}
+
static gboolean
validate (CEPage *page, NMConnection *connection, GError **error)
{
@@ -181,6 +190,67 @@ ce_page_vpn_class_init (CEPageVpnClass *vpn_class)
parent_class->validate = validate;
}
+typedef struct {
+ PageNewConnectionResultFunc result_func;
+ PageGetConnectionsFunc get_connections_func;
+ gpointer user_data;
+} NewVpnInfo;
+
+static void
+import_cb (NMConnection *connection, gpointer user_data)
+{
+ NewVpnInfo *info = (NewVpnInfo *) user_data;
+ NMSettingConnection *s_con;
+ NMSettingVPN *s_vpn;
+ const char *service_type;
+ char *s;
+ GError *error = NULL;
+
+ /* Basic sanity checks of the connection */
+ s_con = nm_connection_get_setting_connection (connection);
+ if (!s_con) {
+ s_con = NM_SETTING_CONNECTION (nm_setting_connection_new ());
+ nm_connection_add_setting (connection, NM_SETTING (s_con));
+ }
+
+ s = (char *) nm_setting_connection_get_id (s_con);
+ if (!s) {
+ GSList *connections;
+
+ connections = info->get_connections_func (info->user_data);
+ s = ce_page_get_next_available_name (connections, _("VPN connection %d"));
+ g_object_set (s_con, NM_SETTING_CONNECTION_ID, s, NULL);
+ g_free (s);
+
+ g_slist_free (connections);
+ }
+
+ s = (char *) nm_setting_connection_get_connection_type (s_con);
+ if (!s || strcmp (s, NM_SETTING_VPN_SETTING_NAME))
+ g_object_set (s_con, NM_SETTING_CONNECTION_TYPE, NM_SETTING_VPN_SETTING_NAME, NULL);
+
+ s = (char *) nm_setting_connection_get_uuid (s_con);
+ if (!s) {
+ s = nm_utils_uuid_generate ();
+ g_object_set (s_con, NM_SETTING_CONNECTION_UUID, s, NULL);
+ g_free (s);
+ }
+
+ s_vpn = nm_connection_get_setting_vpn (connection);
+ service_type = s_vpn ? nm_setting_vpn_get_service_type (s_vpn) : NULL;
+
+ if (!service_type || !strlen (service_type)) {
+ g_object_unref (connection);
+ connection = NULL;
+
+ error = g_error_new_literal (NMA_ERROR, NMA_ERROR_GENERIC,
+ _("The VPN plugin failed to import the VPN connection correctly\n\nError: no VPN service type."));
+ }
+
+ info->result_func (connection, FALSE, error, info->user_data);
+ g_clear_error (&error);
+ g_slice_free (NewVpnInfo, info);
+}
void
vpn_connection_new (GtkWindow *parent,
@@ -198,6 +268,18 @@ vpn_connection_new (GtkWindow *parent,
return;
}
+ if (!strcmp (service, "import")) {
+ NewVpnInfo *info;
+
+ g_free (service);
+ info = g_slice_new (NewVpnInfo);
+ info->result_func = result_func;
+ info->get_connections_func = get_connections_func;
+ info->user_data = user_data;
+ vpn_import (import_cb, info);
+ return;
+ }
+
connection = ce_page_new_connection (_("VPN connection %d"),
NM_SETTING_VPN_SETTING_NAME,
FALSE,
diff --git a/src/connection-editor/page-vpn.h b/src/connection-editor/page-vpn.h
index dad5ca4..d9a4106 100644
--- a/src/connection-editor/page-vpn.h
+++ b/src/connection-editor/page-vpn.h
@@ -53,6 +53,8 @@ CEPage *ce_page_vpn_new (NMConnection *connection,
const char **out_secrets_setting_name,
GError **error);
+gboolean ce_page_vpn_can_export (CEPageVpn *page);
+
void vpn_connection_new (GtkWindow *parent,
PageNewConnectionResultFunc result_func,
PageGetConnectionsFunc get_connections_func,
diff --git a/src/connection-editor/vpn-helpers.c b/src/connection-editor/vpn-helpers.c
index d81071b..7bb4fe1 100644
--- a/src/connection-editor/vpn-helpers.c
+++ b/src/connection-editor/vpn-helpers.c
@@ -163,30 +163,6 @@ vpn_get_plugins (GError **error)
return plugins;
}
-
-typedef struct {
- char *filename;
- NMConnection *connection;
- GError *error;
-} VpnImportInfo;
-
-static void
-try_import (gpointer key, gpointer value, gpointer user_data)
-{
- VpnImportInfo *info = user_data;
- NMVpnPluginUiInterface *plugin = NM_VPN_PLUGIN_UI_INTERFACE (value);
-
- if (info->connection)
- return;
-
- if (info->error) {
- g_error_free (info->error);
- info->error = NULL;
- }
-
- info->connection = nm_vpn_plugin_ui_interface_import (plugin, info->filename, &(info->error));
-}
-
typedef struct {
VpnImportSuccessCallback callback;
gpointer user_data;
@@ -197,8 +173,11 @@ import_vpn_from_file_cb (GtkWidget *dialog, gint response, gpointer user_data)
{
char *filename = NULL;
ActionInfo *info = (ActionInfo *) user_data;
- VpnImportInfo import_info;
- NMConnection *connection;
+ GHashTableIter iter;
+ gpointer key;
+ NMVpnPluginUiInterface *plugin;
+ NMConnection *connection = NULL;
+ GError *error = NULL;
if (response != GTK_RESPONSE_ACCEPT)
goto out;
@@ -209,12 +188,12 @@ import_vpn_from_file_cb (GtkWidget *dialog, gint response, gpointer user_data)
goto out;
}
- import_info.filename = filename;
- import_info.connection = NULL;
- import_info.error = NULL;
- g_hash_table_foreach (plugins, try_import, (gpointer) &import_info);
+ g_hash_table_iter_init (&iter, plugins);
+ while (!connection && g_hash_table_iter_next (&iter, &key, (gpointer *)&plugin)) {
+ g_clear_error (&error);
+ connection = nm_vpn_plugin_ui_interface_import (plugin, filename, &error);
+ }
- connection = import_info.connection;
if (connection)
info->callback (connection, info->user_data);
else {
@@ -228,7 +207,7 @@ import_vpn_from_file_cb (GtkWidget *dialog, gint response, gpointer user_data)
_("Cannot import VPN connection"));
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (err_dialog),
_("The file '%s' could not be read or does not contain recognized VPN connection information\n\nError: %s."),
- bname, import_info.error ? import_info.error->message : "unknown error");
+ bname, error ? error->message : "unknown error");
g_free (bname);
g_signal_connect (err_dialog, "delete-event", G_CALLBACK (gtk_widget_destroy), NULL);
g_signal_connect (err_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
@@ -236,8 +215,7 @@ import_vpn_from_file_cb (GtkWidget *dialog, gint response, gpointer user_data)
gtk_window_present (GTK_WINDOW (err_dialog));
}
- if (import_info.error)
- g_error_free (import_info.error);
+ g_clear_error (&error);
g_free (filename);
out:
@@ -266,8 +244,8 @@ vpn_import (VpnImportSuccessCallback callback, gpointer user_data)
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
- home_folder = g_get_home_dir ();
- gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), home_folder);
+ home_folder = g_get_home_dir ();
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), home_folder);
info = g_malloc0 (sizeof (ActionInfo));
info->callback = callback;
@@ -414,14 +392,6 @@ vpn_export (NMConnection *connection)
gtk_window_present (GTK_WINDOW (dialog));
}
-static void
-add_plugins_to_list (gpointer key, gpointer data, gpointer user_data)
-{
- GSList **list = (GSList **) user_data;
-
- *list = g_slist_append (*list, NM_VPN_PLUGIN_UI_INTERFACE (data));
-}
-
static gint
sort_plugins (gconstpointer a, gconstpointer b)
{
@@ -448,6 +418,23 @@ sort_plugins (gconstpointer a, gconstpointer b)
#define COL_PLUGIN_DESC 0
#define COL_PLUGIN_OBJ 1
+static gboolean
+combo_row_separator_func (GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer data)
+{
+ char *desc;
+
+ gtk_tree_model_get (model, iter,
+ COL_PLUGIN_DESC, &desc,
+ -1);
+ if (desc) {
+ g_free (desc);
+ return FALSE;
+ } else
+ return TRUE;
+}
+
static void
combo_changed_cb (GtkComboBox *combo, gpointer user_data)
{
@@ -490,11 +477,14 @@ vpn_ask_connection_type (GtkWindow *parent)
GtkBuilder *builder;
GtkWidget *dialog, *combo, *widget;
GtkTreeModel *model;
+ GHashTableIter hash_iter;
+ gpointer key, value;
GSList *plugin_list = NULL, *iter;
gint response;
GtkTreeIter tree_iter;
char *service_type = NULL;
GError *error = NULL;
+ gboolean import_supported = FALSE;
if (!plugins || !g_hash_table_size (plugins)) {
g_warning ("%s: no VPN plugins could be found!", __func__);
@@ -517,9 +507,12 @@ vpn_ask_connection_type (GtkWindow *parent)
}
model = GTK_TREE_MODEL (gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_OBJECT));
- g_hash_table_foreach (plugins, add_plugins_to_list, &plugin_list);
+ g_hash_table_iter_init (&hash_iter, plugins);
+ while (g_hash_table_iter_next (&hash_iter, &key, &value))
+ plugin_list = g_slist_prepend (plugin_list, value);
plugin_list = g_slist_sort (plugin_list, sort_plugins);
+
for (iter = plugin_list; iter; iter = g_slist_next (iter)) {
NMVpnPluginUiInterface *plugin = NM_VPN_PLUGIN_UI_INTERFACE (iter->data);
char *desc;
@@ -530,6 +523,21 @@ vpn_ask_connection_type (GtkWindow *parent)
COL_PLUGIN_DESC, desc,
COL_PLUGIN_OBJ, plugin, -1);
g_free (desc);
+
+ if (nm_vpn_plugin_ui_interface_get_capabilities (plugin) & NM_VPN_PLUGIN_UI_CAPABILITY_IMPORT)
+ import_supported = TRUE;
+ }
+ g_slist_free (plugin_list);
+
+ if (import_supported) {
+ gtk_list_store_append (GTK_LIST_STORE (model), &tree_iter);
+ gtk_list_store_set (GTK_LIST_STORE (model), &tree_iter,
+ COL_PLUGIN_DESC, NULL,
+ COL_PLUGIN_OBJ, NULL, -1);
+ gtk_list_store_append (GTK_LIST_STORE (model), &tree_iter);
+ gtk_list_store_set (GTK_LIST_STORE (model), &tree_iter,
+ COL_PLUGIN_DESC, _("Import a saved VPN configuration..."),
+ COL_PLUGIN_OBJ, NULL, -1);
}
combo = GTK_WIDGET (gtk_builder_get_object (builder, "vpn_type_combo"));
@@ -537,6 +545,7 @@ vpn_ask_connection_type (GtkWindow *parent)
g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (combo_changed_cb), widget);
gtk_combo_box_set_model (GTK_COMBO_BOX (combo), model);
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
+ gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo), combo_row_separator_func, NULL, NULL);
gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
gtk_widget_show_all (dialog);
@@ -551,14 +560,13 @@ vpn_ask_connection_type (GtkWindow *parent)
if (plugin) {
g_object_get (G_OBJECT (plugin), NM_VPN_PLUGIN_UI_INTERFACE_SERVICE, &service_type, NULL);
g_object_unref (plugin);
- }
+ } else
+ service_type = g_strdup ("import");
}
out:
gtk_widget_destroy (dialog);
g_object_unref (builder);
- if (service_type)
- return service_type;
- return NULL;
+ return service_type;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]