[gnome-control-center/wip/add-account: 4/15] user-accounts: Cleaner interaction with UmAccountDialog actions



commit c9a19dcbca30a7a1d79c484bf33b8fad93c8edf4
Author: Stef Walter <stefw gnome org>
Date:   Wed Jun 6 22:51:19 2012 +0200

    user-accounts: Cleaner interaction with UmAccountDialog actions
    
    More clear scoping and interaction with running actions in
    UmAccountDialog. In later 'enterprise login' patches we have long
    running actions that's why this needs cleaning up.
    
    In particular:
    
     * Show errors as children of the dialog.
     * Errors don't make the account dialog go away, user can correct
       problems.
     * Use more standard GAsyncResult style callbacks:
       um_account_dialog_perform() um_account_dialog_finish()
     * Disable controls while the operation is happening.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=677548

 panels/user-accounts/um-account-dialog.c |  124 +++++++++++++++++++++--------
 panels/user-accounts/um-account-dialog.h |   10 +-
 panels/user-accounts/um-user-panel.c     |   18 ++++-
 3 files changed, 109 insertions(+), 43 deletions(-)
---
diff --git a/panels/user-accounts/um-account-dialog.c b/panels/user-accounts/um-account-dialog.c
index a378ce4..8a4b803 100644
--- a/panels/user-accounts/um-account-dialog.c
+++ b/panels/user-accounts/um-account-dialog.c
@@ -37,15 +37,15 @@
 
 struct _UmAccountDialog {
         GtkDialog parent;
+        GtkWidget *widgets;
+        GSimpleAsyncResult *async;
+
         GtkWidget *username_combo;
         GtkWidget *name_entry;
         GtkWidget *account_type_combo;
 
         gboolean valid_name;
         gboolean valid_username;
-
-        UserCreatedCallback user_created_callback;
-        gpointer            user_created_data;
 };
 
 typedef struct {
@@ -55,8 +55,50 @@ typedef struct {
 G_DEFINE_TYPE (UmAccountDialog, um_account_dialog, GTK_TYPE_DIALOG);
 
 static void
-cancel_account_dialog (UmAccountDialog *self)
+show_error_dialog (UmAccountDialog *self,
+                   const gchar *message,
+                   GError *error)
 {
+        GtkWidget *dialog;
+
+        dialog = gtk_message_dialog_new (GTK_WINDOW (self),
+                                         GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                         GTK_MESSAGE_ERROR,
+                                         GTK_BUTTONS_CLOSE,
+                                         message);
+
+        gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                                                  "%s", error->message);
+
+        g_signal_connect (dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
+        gtk_window_present (GTK_WINDOW (dialog));
+}
+
+static void
+begin_action (UmAccountDialog *self)
+{
+        gtk_widget_set_sensitive (self->widgets, FALSE);
+        gtk_dialog_set_response_sensitive (GTK_DIALOG (self), GTK_RESPONSE_OK, FALSE);
+}
+
+static void
+finish_action (UmAccountDialog *self)
+{
+        gtk_widget_set_sensitive (self->widgets, TRUE);
+        gtk_dialog_set_response_sensitive (GTK_DIALOG (self), GTK_RESPONSE_OK, TRUE);
+}
+
+static void
+complete_dialog (UmAccountDialog *self,
+                 UmUser *user)
+{
+        if (user != NULL) {
+                g_simple_async_result_set_op_res_gpointer (self->async,
+                                                           g_object_ref (user),
+                                                           g_object_unref);
+        }
+
+        g_simple_async_result_complete_in_idle (self->async);
         gtk_widget_hide (GTK_WIDGET (self));
 }
 
@@ -68,29 +110,18 @@ create_user_done (UmUserManager   *manager,
         UmUser *user;
         GError *error;
 
-        error = NULL;
-        if (!um_user_manager_create_user_finish (manager, res, &user, &error)) {
+        finish_action (self);
 
-                if (!g_error_matches (error, UM_USER_MANAGER_ERROR, UM_USER_MANAGER_ERROR_PERMISSION_DENIED)) {
-                        GtkWidget *dialog;
+        /* Note that user is returned without an extra reference */
 
-                        dialog = gtk_message_dialog_new (gtk_window_get_transient_for (GTK_WINDOW (self)),
-                                                         GTK_DIALOG_DESTROY_WITH_PARENT,
-                                                         GTK_MESSAGE_ERROR,
-                                                         GTK_BUTTONS_CLOSE,
-                                                         _("Failed to create user"));
-
-                        gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
-                                                                  "%s", error->message);
-
-                        g_signal_connect (G_OBJECT (dialog), "response",
-                                          G_CALLBACK (gtk_widget_destroy), NULL);
-                        gtk_window_present (GTK_WINDOW (dialog));
-                }
+        error = NULL;
+        if (!um_user_manager_create_user_finish (manager, res, &user, &error)) {
+                if (!g_error_matches (error, UM_USER_MANAGER_ERROR, UM_USER_MANAGER_ERROR_PERMISSION_DENIED))
+                       show_error_dialog (self, _("Failed to create user"), error);
                 g_error_free (error);
-        }
-        else {
-                self->user_created_callback (user, self->user_created_data);
+                gtk_widget_grab_focus (self->name_entry);
+        } else {
+                complete_dialog (self, user);
         }
 }
 
@@ -104,6 +135,8 @@ accept_account_dialog (UmAccountDialog *self)
         GtkTreeModel *model;
         GtkTreeIter iter;
 
+        begin_action (self);
+
         name = gtk_entry_get_text (GTK_ENTRY (self->name_entry));
         username = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (self->username_combo));
         model = gtk_combo_box_get_model (GTK_COMBO_BOX (self->account_type_combo));
@@ -119,8 +152,6 @@ accept_account_dialog (UmAccountDialog *self)
                                      self,
                                      NULL);
         g_object_unref (manager);
-
-        gtk_widget_hide (GTK_WIDGET (self));
 }
 
 static void
@@ -212,6 +243,7 @@ um_account_dialog_init (UmAccountDialog *self)
 
         widget = (GtkWidget *) gtk_builder_get_object (builder, "account-dialog");
         gtk_container_add (GTK_CONTAINER (content), widget);
+        self->widgets = widget;
 
         widget = (GtkWidget *) gtk_builder_get_object (builder, "username-combo");
         g_signal_connect (widget, "changed",
@@ -239,7 +271,7 @@ um_account_dialog_response (GtkDialog *dialog,
                 break;
         case GTK_RESPONSE_CANCEL:
         case GTK_RESPONSE_DELETE_EVENT:
-                cancel_account_dialog (self);
+                complete_dialog (self, NULL);
                 break;
         default:
                 g_warn_if_reached ();
@@ -262,26 +294,50 @@ um_account_dialog_new (void)
 }
 
 void
-um_account_dialog_show (UmAccountDialog     *self,
-                        GtkWindow           *parent,
-                        UserCreatedCallback  user_created_callback,
-                        gpointer             user_created_data)
+um_account_dialog_perform (UmAccountDialog     *self,
+                           GtkWindow           *parent,
+                           GAsyncReadyCallback  callback,
+                           gpointer             user_data)
 {
         GtkTreeModel *model;
 
+        g_return_if_fail (UM_IS_ACCOUNT_DIALOG (self));
+
+        /* Make sure not already doing an operation */
+        g_return_if_fail (self->async == NULL);
+
+        self->async = g_simple_async_result_new (G_OBJECT (self), callback, user_data,
+                                                 um_account_dialog_perform);
+
         gtk_entry_set_text (GTK_ENTRY (self->name_entry), "");
         gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (self->username_combo))), "");
         model = gtk_combo_box_get_model (GTK_COMBO_BOX (self->username_combo));
         gtk_list_store_clear (GTK_LIST_STORE (model));
         gtk_combo_box_set_active (GTK_COMBO_BOX (self->account_type_combo), 0);
 
+        self->valid_name = self->valid_username = TRUE;
+
         gtk_window_set_modal (GTK_WINDOW (self), parent != NULL);
         gtk_window_set_transient_for (GTK_WINDOW (self), parent);
         gtk_window_present (GTK_WINDOW (self));
         gtk_widget_grab_focus (self->name_entry);
+}
 
-        self->valid_name = self->valid_username = TRUE;
+UmUser *
+um_account_dialog_finish (UmAccountDialog     *self,
+                          GAsyncResult        *result)
+{
+        UmUser *user;
+
+        g_return_val_if_fail (UM_IS_ACCOUNT_DIALOG (self), NULL);
+        g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (self),
+                              um_account_dialog_perform), NULL);
+        g_return_val_if_fail (result == G_ASYNC_RESULT (self->async), NULL);
+
+        user = g_simple_async_result_get_op_res_gpointer (self->async);
+        if (user != NULL)
+                g_object_ref (user);
 
-        self->user_created_callback = user_created_callback;
-        self->user_created_data = user_created_data;
+        g_clear_object (&self->async);
+        return user;
 }
diff --git a/panels/user-accounts/um-account-dialog.h b/panels/user-accounts/um-account-dialog.h
index dc35ba6..bf46052 100644
--- a/panels/user-accounts/um-account-dialog.h
+++ b/panels/user-accounts/um-account-dialog.h
@@ -33,14 +33,14 @@ G_BEGIN_DECLS
 
 typedef struct _UmAccountDialog UmAccountDialog;
 
-typedef void (*UserCreatedCallback) (UmUser *user, gpointer data);
-
 GType            um_account_dialog_get_type (void) G_GNUC_CONST;
 UmAccountDialog *um_account_dialog_new      (void);
-void             um_account_dialog_show     (UmAccountDialog     *self,
+void             um_account_dialog_perform  (UmAccountDialog     *self,
                                              GtkWindow           *parent,
-                                             UserCreatedCallback  user_created,
-                                             gpointer             data);
+                                             GAsyncReadyCallback  callback,
+                                             gpointer             user_data);
+UmUser *         um_account_dialog_finish   (UmAccountDialog     *self,
+                                             GAsyncResult        *result);
 
 G_END_DECLS
 
diff --git a/panels/user-accounts/um-user-panel.c b/panels/user-accounts/um-user-panel.c
index 3793862..b369fb8 100644
--- a/panels/user-accounts/um-user-panel.c
+++ b/panels/user-accounts/um-user-panel.c
@@ -299,14 +299,22 @@ user_changed (UmUserManager *um, UmUser *user, UmUserPanelPrivate *d)
 }
 
 static void
-select_created_user (UmUser *user, UmUserPanelPrivate *d)
+select_created_user (GObject *object,
+                     GAsyncResult *result,
+                     gpointer user_data)
 {
+        UmUserPanelPrivate *d = user_data;
         GtkTreeView *tv;
         GtkTreeModel *model;
         GtkTreeSelection *selection;
         GtkTreeIter iter;
         UmUser *current;
         GtkTreePath *path;
+        UmUser *user;
+
+        user = um_account_dialog_finish (UM_ACCOUNT_DIALOG (object), result);
+        if (user == NULL)
+                return;
 
         tv = (GtkTreeView *)get_widget (d, "list-treeview");
         model = gtk_tree_view_get_model (tv);
@@ -326,14 +334,16 @@ select_created_user (UmUser *user, UmUserPanelPrivate *d)
                 if (current)
                         g_object_unref (current);
         } while (gtk_tree_model_iter_next (model, &iter));
+
+        g_object_unref (user);
 }
 
 static void
 add_user (GtkButton *button, UmUserPanelPrivate *d)
 {
-        um_account_dialog_show (d->account_dialog,
-                                GTK_WINDOW (gtk_widget_get_toplevel (d->main_box)),
-                                (UserCreatedCallback)select_created_user, d);
+        um_account_dialog_perform (d->account_dialog,
+                                   GTK_WINDOW (gtk_widget_get_toplevel (d->main_box)),
+                                   select_created_user, d);
 }
 
 static void



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