[network-manager-applet/lr/hold-import] connection-editor: hold GApplication while the import dialog is running



commit 280cb266099374e7564f0ef9ba18d86df0544d98
Author: Lubomir Rintel <lkundrak v3 sk>
Date:   Mon Jul 23 18:15:30 2018 +0200

    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.

 src/connection-editor/connection-helpers.c | 44 ++++++++-------------
 src/connection-editor/connection-helpers.h |  2 +-
 src/connection-editor/main.c               | 16 ++++++--
 src/connection-editor/nm-connection-list.c | 61 ++++++++++++++++++++++++------
 src/connection-editor/nm-connection-list.h | 13 ++++++-
 5 files changed, 90 insertions(+), 46 deletions(-)
---
diff --git a/src/connection-editor/connection-helpers.c b/src/connection-editor/connection-helpers.c
index d7a434a9..a38217ee 100644
--- a/src/connection-editor/connection-helpers.c
+++ b/src/connection-editor/connection-helpers.c
@@ -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);
diff --git a/src/connection-editor/connection-helpers.h b/src/connection-editor/connection-helpers.h
index 17de5699..52a30aae 100644
--- a/src/connection-editor/connection-helpers.h
+++ b/src/connection-editor/connection-helpers.h
@@ -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__ */
 
diff --git a/src/connection-editor/main.c b/src/connection-editor/main.c
index 29d10154..478a06c0 100644
--- a/src/connection-editor/main.c
+++ b/src/connection-editor/main.c
@@ -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 */
diff --git a/src/connection-editor/nm-connection-list.c b/src/connection-editor/nm-connection-list.c
index c3d886b6..d81aaae5 100644
--- a/src/connection-editor/nm-connection-list.c
+++ b/src/connection-editor/nm-connection-list.c
@@ -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);
        }
 }
 
diff --git a/src/connection-editor/nm-connection-list.h b/src/connection-editor/nm-connection-list.h
index a4a9cc0a..842584c9 100644
--- a/src/connection-editor/nm-connection-list.h
+++ b/src/connection-editor/nm-connection-list.h
@@ -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


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