Commit 419c459e authored by Lubomir Rintel's avatar Lubomir Rintel

connection-editor: hold GApplication while the import dialog is running

This is done from new callbacks of nm_connection_list_create() and
nm_connection_list_add().

In order for this to work, import_vpn_from_file_cb() had to be fixed to
always invoke its callback. In turn, vpn_connection_from_file() had to
be changed to pass its error result up to its callers instead of
presenting a potentially redundant error message itself.
parent 1f92eb17
......@@ -175,18 +175,17 @@ no_description:
}
NMConnection *
vpn_connection_from_file (const char *filename)
vpn_connection_from_file (const char *filename, GError **error)
{
NMConnection *connection = NULL;
GError *error = NULL;
GSList *iter;
for (iter = vpn_get_plugin_infos (); !connection && iter; iter = iter->next) {
NMVpnEditorPlugin *plugin;
plugin = nm_vpn_plugin_info_get_editor_plugin (iter->data);
g_clear_error (&error);
connection = nm_vpn_editor_plugin_import (plugin, filename, &error);
g_clear_error (error);
connection = nm_vpn_editor_plugin_import (plugin, filename, error);
if (connection)
break;
}
......@@ -202,32 +201,12 @@ vpn_connection_from_file (const char *filename)
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."));
g_set_error_literal (error, NMA_ERROR, NMA_ERROR_GENERIC, _("No VPN service type."));
}
}
if (!connection) {
GtkWidget *err_dialog;
char *bname = g_path_get_basename (filename);
err_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 (err_dialog),
_("The file “%s” could not be read or does not contain recognized VPN connection information\n\nError: %s."),
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);
gtk_widget_show_all (err_dialog);
gtk_window_present (GTK_WINDOW (err_dialog));
}
g_clear_error (&error);
if (!connection)
g_prefix_error (error, _("The VPN plugin failed to import the VPN connection correctly: "));
return connection;
}
......@@ -245,6 +224,8 @@ import_vpn_from_file_cb (GtkWidget *dialog, gint response, gpointer user_data)
char *filename = NULL;
ImportVpnInfo *info = (ImportVpnInfo *) user_data;
NMConnection *connection = NULL;
GError *error = NULL;
gboolean canceled = TRUE;
if (response != GTK_RESPONSE_ACCEPT)
goto out;
......@@ -255,7 +236,8 @@ import_vpn_from_file_cb (GtkWidget *dialog, gint response, gpointer user_data)
goto out;
}
connection = vpn_connection_from_file (filename);
canceled = FALSE;
connection = vpn_connection_from_file (filename, &error);
if (connection) {
/* Wrap around the actual new function so that the page can complete
* the missing parts, such as UUID or make up the connection name. */
......@@ -270,7 +252,13 @@ import_vpn_from_file_cb (GtkWidget *dialog, gint response, gpointer user_data)
}
g_free (filename);
out:
if (!connection) {
info->result_func (FUNC_TAG_PAGE_NEW_CONNECTION_RESULT_CALL,
connection, canceled, error, info->user_data);
}
gtk_widget_hide (dialog);
gtk_widget_destroy (dialog);
g_object_unref (info->parent);
......
......@@ -87,7 +87,7 @@ gboolean connection_supports_proxy (NMConnection *connection);
gboolean connection_supports_ip4 (NMConnection *connection);
gboolean connection_supports_ip6 (NMConnection *connection);
NMConnection *vpn_connection_from_file (const char *filename);
NMConnection *vpn_connection_from_file (const char *filename, GError **error);
#endif /* __CONNECTION_HELPERS_H__ */
......@@ -39,6 +39,12 @@ gboolean nm_ce_keep_above;
/*************************************************/
static void
editor_created (NMConnectionList *list, gpointer user_data)
{
g_application_release (G_APPLICATION (user_data));
}
static gboolean
handle_arguments (GApplication *application,
const char *type,
......@@ -80,14 +86,18 @@ handle_arguments (GApplication *application,
/* Just show the given connection type page */
nm_connection_list_set_type (list, ctype);
} else if (create) {
g_application_hold (application);
if (!ctype)
nm_connection_list_add (list);
nm_connection_list_add (list, editor_created, application);
else
nm_connection_list_create (list, ctype, detail, NULL);
nm_connection_list_create (list, ctype, detail, NULL,
editor_created, application);
show_list = FALSE;
} else if (import) {
/* import */
nm_connection_list_create (list, ctype, detail, import);
g_application_hold (application);
nm_connection_list_create (list, ctype, detail, import,
editor_created, application);
show_list = FALSE;
} else if (edit_uuid) {
/* Show the edit dialog for the given UUID */
......
......@@ -295,17 +295,24 @@ new_editor_cb (NMConnectionEditor *editor, NMConnectionEditor *new_editor, gpoin
g_signal_emit (list, list_signals[NEW_EDITOR], 0, new_editor);
}
typedef struct {
NMConnectionList *list;
NMConnectionListCallbackFunc callback;
gpointer user_data;
} ConnectionResultData;
static void
really_add_connection (FUNC_TAG_NEW_CONNECTION_RESULT_IMPL,
NMConnection *connection,
gpointer user_data)
{
NMConnectionList *list = user_data;
ConnectionResultData *data = user_data;
NMConnectionList *list = data->list;
NMConnectionListPrivate *priv = NM_CONNECTION_LIST_GET_PRIVATE (list);
NMConnectionEditor *editor;
NMConnectionEditor *editor = NULL;
if (!connection)
return;
goto out;
if (connection_supports_proxy (connection) && !nm_connection_get_setting_proxy (connection))
nm_connection_add_setting (connection, nm_setting_proxy_new ());
......@@ -316,34 +323,49 @@ really_add_connection (FUNC_TAG_NEW_CONNECTION_RESULT_IMPL,
editor = nm_connection_editor_new (GTK_WINDOW (list), connection, priv->client);
if (!editor)
return;
goto out;
g_signal_connect (editor, NM_CONNECTION_EDITOR_DONE, G_CALLBACK (add_response_cb), list);
g_signal_connect (editor, NM_CONNECTION_EDITOR_NEW_EDITOR, G_CALLBACK (new_editor_cb), list);
g_signal_emit (list, list_signals[NEW_EDITOR], 0, editor);
nm_connection_editor_run (editor);
out:
if (data->callback)
data->callback (data->list, data->user_data);
g_slice_free (ConnectionResultData, data);
if (editor)
nm_connection_editor_run (editor);
}
static void
add_clicked (GtkButton *button, gpointer user_data)
{
nm_connection_list_add (user_data);
nm_connection_list_add (user_data, NULL, NULL);
}
void
nm_connection_list_add (NMConnectionList *list)
nm_connection_list_add (NMConnectionList *list,
NMConnectionListCallbackFunc callback,
gpointer user_data)
{
NMConnectionListPrivate *priv;
ConnectionResultData *data;
g_return_if_fail (NM_IS_CONNECTION_LIST (list));
priv = NM_CONNECTION_LIST_GET_PRIVATE (list);
data = g_slice_new0 (ConnectionResultData);
data->list = list;
data->callback = callback;
data->user_data = user_data;
new_connection_dialog (GTK_WINDOW (list),
priv->client,
NULL,
really_add_connection,
list);
data);
}
static void
......@@ -1013,10 +1035,14 @@ void
nm_connection_list_create (NMConnectionList *list,
GType ctype,
const char *detail,
const char *import_filename)
const char *import_filename,
NMConnectionListCallbackFunc callback,
gpointer user_data)
{
NMConnectionListPrivate *priv;
ConnectionTypeData *types;
ConnectionResultData *data;
GError *error = NULL;
int i;
g_return_if_fail (NM_IS_CONNECTION_LIST (list));
......@@ -1038,14 +1064,25 @@ nm_connection_list_create (NMConnectionList *list,
nm_connection_editor_error (NULL, _("Error creating connection"),
_("Don’t know how to create “%s” connections"), g_type_name (ctype));
}
callback (list, user_data);
} else {
gs_unref_object NMConnection *connection = NULL;
if (import_filename) {
connection = vpn_connection_from_file (import_filename);
if (!connection)
connection = vpn_connection_from_file (import_filename, &error);
if (!connection) {
nm_connection_editor_error (NULL, _("Error importing connection"), error->message);
callback (list, user_data);
return;
}
}
data = g_slice_new0 (ConnectionResultData);
data->list = list;
data->callback = callback;
data->user_data = user_data;
new_connection_of_type (GTK_WINDOW (list),
detail,
NULL,
......@@ -1053,7 +1090,7 @@ nm_connection_list_create (NMConnectionList *list,
priv->client,
types[i].new_connection_func,
really_add_connection,
list);
data);
}
}
......
......@@ -48,14 +48,23 @@ typedef struct {
GtkApplicationWindowClass parent_class;
} NMConnectionListClass;
typedef void (*NMConnectionListCallbackFunc) (NMConnectionList *list, gpointer user_data);
GType nm_connection_list_get_type (void);
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, const char *detail, const char *import_filename);
void nm_connection_list_create (NMConnectionList *list,
GType ctype,
const char *detail,
const char *import_filename,
NMConnectionListCallbackFunc callback,
gpointer user_data);
void nm_connection_list_edit (NMConnectionList *list, const gchar *uuid);
void nm_connection_list_add (NMConnectionList *list);
void nm_connection_list_add (NMConnectionList *list,
NMConnectionListCallbackFunc callback,
gpointer user_data);
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment