diff options
-rw-r--r-- | libempathy-gtk/empathy-account-widget.c | 44 | ||||
-rw-r--r-- | libempathy-gtk/empathy-account-widget.h | 3 | ||||
-rw-r--r-- | src/cc-empathy-accounts-page.c | 26 | ||||
-rw-r--r-- | src/empathy-accounts-dialog.c | 118 |
4 files changed, 148 insertions, 43 deletions
diff --git a/libempathy-gtk/empathy-account-widget.c b/libempathy-gtk/empathy-account-widget.c index 8ce6b5f52..8862c3ba4 100644 --- a/libempathy-gtk/empathy-account-widget.c +++ b/libempathy-gtk/empathy-account-widget.c @@ -73,6 +73,11 @@ typedef struct { * modify it. When we are creating an account, this member is set to TRUE */ gboolean creating_account; + /* whether there are any other real accounts. Necessary so we know whether + * it's safe to dismiss this widget in some cases (eg, whether the Cancel + * button should be sensitive) */ + gboolean other_accounts_exist; + /* if TRUE, the GTK+ destroy signal has been fired and so the widgets * embedded in this account widget can't be used any more * workaround because some async callbacks can be called after the @@ -91,7 +96,8 @@ enum { PROP_PROTOCOL = 1, PROP_SETTINGS, PROP_SIMPLE, - PROP_CREATING_ACCOUNT + PROP_CREATING_ACCOUNT, + PROP_OTHER_ACCOUNTS_EXIST, }; enum { @@ -114,9 +120,14 @@ account_widget_set_control_buttons_sensitivity (EmpathyAccountWidget *self, if (!priv->simple) { + /* we hit this case because of the 'other-accounts-exist' property handler + * being called during init (before constructed()) */ + if (priv->apply_button == NULL || priv->cancel_button == NULL) + return; + gtk_widget_set_sensitive (priv->apply_button, sensitive); - gtk_widget_set_sensitive ( - priv->cancel_button, sensitive || priv->creating_account); + gtk_widget_set_sensitive (priv->cancel_button, + (sensitive || priv->creating_account) && priv->other_accounts_exist); } } @@ -1348,6 +1359,18 @@ account_widget_enabled_released_cb (GtkToggleButton *toggle_button, account_widget_account_enabled_cb, user_data); } +void +empathy_account_widget_set_other_accounts_exist (EmpathyAccountWidget *self, + gboolean others_exist) +{ + EmpathyAccountWidgetPriv *priv = GET_PRIV (self); + + priv->other_accounts_exist = others_exist; + + if (priv->creating_account) + account_widget_handle_control_buttons_sensitivity (self); +} + static void do_set_property (GObject *object, guint prop_id, @@ -1367,6 +1390,10 @@ do_set_property (GObject *object, case PROP_CREATING_ACCOUNT: priv->creating_account = g_value_get_boolean (value); break; + case PROP_OTHER_ACCOUNTS_EXIST: + empathy_account_widget_set_other_accounts_exist ( + EMPATHY_ACCOUNT_WIDGET (object), g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -1395,6 +1422,9 @@ do_get_property (GObject *object, case PROP_CREATING_ACCOUNT: g_value_set_boolean (value, priv->creating_account); break; + case PROP_OTHER_ACCOUNTS_EXIST: + g_value_set_boolean (value, priv->other_accounts_exist); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -1826,6 +1856,14 @@ empathy_account_widget_class_init (EmpathyAccountWidgetClass *klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (oclass, PROP_CREATING_ACCOUNT, param_spec); + param_spec = g_param_spec_boolean ("other-accounts-exist", + "other-accounts-exist", + "TRUE if there are any other accounts (even if this isn't yet saved)", + FALSE, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (oclass, PROP_OTHER_ACCOUNTS_EXIST, + param_spec); + signals[HANDLE_APPLY] = g_signal_new ("handle-apply", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, diff --git a/libempathy-gtk/empathy-account-widget.h b/libempathy-gtk/empathy-account-widget.h index 9ed989434..ecc52e6c6 100644 --- a/libempathy-gtk/empathy-account-widget.h +++ b/libempathy-gtk/empathy-account-widget.h @@ -79,6 +79,9 @@ void empathy_account_widget_set_account_param (EmpathyAccountWidget *widget, void empathy_account_widget_set_password_param (EmpathyAccountWidget *self, const gchar *password); +void empathy_account_widget_set_other_accounts_exist ( + EmpathyAccountWidget *self, gboolean others_exist); + /* protected methods */ void empathy_account_widget_changed (EmpathyAccountWidget *widget); diff --git a/src/cc-empathy-accounts-page.c b/src/cc-empathy-accounts-page.c index bf4d46af7..ef9b17557 100644 --- a/src/cc-empathy-accounts-page.c +++ b/src/cc-empathy-accounts-page.c @@ -54,20 +54,24 @@ page_pack_with_accounts_dialog (CcEmpathyAccountsPage *page) GtkWidget *content; GtkWidget *action_area; - if (!page->priv->accounts_window) + if (page->priv->accounts_window != NULL) { - page->priv->accounts_window = empathy_accounts_dialog_show (NULL, NULL); - gtk_widget_hide (page->priv->accounts_window); + gtk_widget_destroy (page->priv->accounts_window); + gtk_container_remove (GTK_CONTAINER (page), + gtk_bin_get_child (GTK_BIN (page))); + } - content = gtk_dialog_get_content_area ( - GTK_DIALOG (page->priv->accounts_window)); - action_area = gtk_dialog_get_action_area ( - GTK_DIALOG (page->priv->accounts_window)); - gtk_widget_set_no_show_all (action_area, TRUE); - gtk_widget_hide (action_area); + page->priv->accounts_window = empathy_accounts_dialog_show (NULL, NULL); + gtk_widget_hide (page->priv->accounts_window); - gtk_widget_reparent (content, GTK_WIDGET (page)); - } + content = gtk_dialog_get_content_area ( + GTK_DIALOG (page->priv->accounts_window)); + action_area = gtk_dialog_get_action_area ( + GTK_DIALOG (page->priv->accounts_window)); + gtk_widget_set_no_show_all (action_area, TRUE); + gtk_widget_hide (action_area); + + gtk_widget_reparent (content, GTK_WIDGET (page)); } static void diff --git a/src/empathy-accounts-dialog.c b/src/empathy-accounts-dialog.c index b2e21dc8d..5843c0d74 100644 --- a/src/empathy-accounts-dialog.c +++ b/src/empathy-accounts-dialog.c @@ -72,8 +72,6 @@ #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyAccountsDialog) G_DEFINE_TYPE (EmpathyAccountsDialog, empathy_accounts_dialog, GTK_TYPE_DIALOG); -static EmpathyAccountsDialog *dialog_singleton = NULL; - typedef struct { GtkWidget *alignment_settings; GtkWidget *alignment_infobar; @@ -431,6 +429,28 @@ empathy_account_dialog_account_created_cb (EmpathyAccountWidget *widget_object, g_object_unref (settings); } +static gboolean +accounts_dialog_has_valid_accounts (EmpathyAccountsDialog *dialog) +{ + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + GtkTreeModel *model; + GtkTreeIter iter; + gboolean creating; + + g_object_get (priv->setting_widget_object, + "creating-account", &creating, NULL); + + if (!creating) + return TRUE; + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + + if (gtk_tree_model_get_iter_first (model, &iter)) + return gtk_tree_model_iter_next (model, &iter); + + return FALSE; +} + static void account_dialog_create_settings_widget (EmpathyAccountsDialog *dialog, EmpathyAccountSettings *settings) @@ -442,6 +462,10 @@ account_dialog_create_settings_widget (EmpathyAccountsDialog *dialog, priv->setting_widget_object = empathy_account_widget_new_for_protocol (settings, FALSE); + if (accounts_dialog_has_valid_accounts (dialog)) + empathy_account_widget_set_other_accounts_exist ( + priv->setting_widget_object, TRUE); + priv->settings_widget = empathy_account_widget_get_widget (priv->setting_widget_object); @@ -625,8 +649,17 @@ accounts_dialog_protocol_changed_cb (GtkWidget *widget, /* We are creating a new widget to replace the current one, don't ask * confirmation to the user. */ priv->force_change_row = TRUE; + + /* We'll update the selection after we create the new account widgets; + * updating it right now causes problems for the # of accounts = zero case */ + g_signal_handlers_block_by_func (selection, + accounts_dialog_model_selection_changed, dialog); + gtk_list_store_remove (GTK_LIST_STORE (model), &iter); + g_signal_handlers_unblock_by_func (selection, + accounts_dialog_model_selection_changed, dialog); + accounts_dialog_setup_ui_to_add_account (dialog); /* Restore "account" and "password" parameters in the new widget */ @@ -1227,6 +1260,7 @@ accounts_dialog_model_selection_changed (GtkTreeSelection *selection, GtkTreeModel *model; GtkTreeIter iter; gboolean is_selection; + gboolean creating = FALSE; is_selection = gtk_tree_selection_get_selected (selection, &model, &iter); @@ -1236,8 +1270,14 @@ accounts_dialog_model_selection_changed (GtkTreeSelection *selection, if (settings != NULL) g_object_unref (settings); + if (priv->setting_widget_object != NULL) + { + g_object_get (priv->setting_widget_object, + "creating-account", &creating, NULL); + } + /* Update remove button sensitivity */ - gtk_widget_set_sensitive (priv->button_remove, is_selection); + gtk_widget_set_sensitive (priv->button_remove, is_selection && !creating); } static void @@ -1660,6 +1700,37 @@ accounts_dialog_account_validity_changed_cb (TpAccountManager *manager, } static void +accounts_dialog_accounts_model_row_inserted_cb (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + EmpathyAccountsDialog *dialog) +{ + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + if (priv->setting_widget_object != NULL && + accounts_dialog_has_valid_accounts (dialog)) + { + empathy_account_widget_set_other_accounts_exist ( + priv->setting_widget_object, TRUE); + } +} + +static void +accounts_dialog_accounts_model_row_deleted_cb (GtkTreeModel *model, + GtkTreePath *path, + EmpathyAccountsDialog *dialog) +{ + EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + + if (priv->setting_widget_object != NULL && + !accounts_dialog_has_valid_accounts (dialog)) + { + empathy_account_widget_set_other_accounts_exist ( + priv->setting_widget_object, FALSE); + } +} + +static void accounts_dialog_account_removed_cb (TpAccountManager *manager, TpAccount *account, EmpathyAccountsDialog *dialog) @@ -1670,7 +1741,7 @@ accounts_dialog_account_removed_cb (TpAccountManager *manager, if (accounts_dialog_get_account_iter (dialog, account, &iter)) { gtk_list_store_remove (GTK_LIST_STORE ( - gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview))), &iter); + gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview))), &iter); } } @@ -2021,6 +2092,7 @@ do_dispose (GObject *obj) { EmpathyAccountsDialog *dialog = EMPATHY_ACCOUNTS_DIALOG (obj); EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); + GtkTreeModel *model; if (priv->dispose_has_run) return; @@ -2028,6 +2100,12 @@ do_dispose (GObject *obj) priv->dispose_has_run = TRUE; /* Disconnect signals */ + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + g_signal_handlers_disconnect_by_func (model, + accounts_dialog_accounts_model_row_inserted_cb, dialog); + g_signal_handlers_disconnect_by_func (model, + accounts_dialog_accounts_model_row_deleted_cb, dialog); + g_signal_handlers_disconnect_by_func (priv->account_manager, accounts_dialog_account_validity_changed_cb, dialog); @@ -2066,30 +2144,6 @@ do_dispose (GObject *obj) G_OBJECT_CLASS (empathy_accounts_dialog_parent_class)->dispose (obj); } -static GObject * -do_constructor (GType type, - guint n_props, - GObjectConstructParam *props) -{ - GObject *retval; - - if (dialog_singleton) - { - retval = G_OBJECT (dialog_singleton); - } - else - { - retval = - G_OBJECT_CLASS (empathy_accounts_dialog_parent_class)->constructor - (type, n_props, props); - - dialog_singleton = EMPATHY_ACCOUNTS_DIALOG (retval); - g_object_add_weak_pointer (retval, (gpointer) &dialog_singleton); - } - - return retval; -} - static void do_get_property (GObject *object, guint property_id, @@ -2132,10 +2186,17 @@ do_constructed (GObject *object) EmpathyAccountsDialog *dialog = EMPATHY_ACCOUNTS_DIALOG (object); EmpathyAccountsDialogPriv *priv = GET_PRIV (dialog); gboolean import_asked; + GtkTreeModel *model; accounts_dialog_build_ui (dialog); accounts_dialog_model_setup (dialog); + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + g_signal_connect (model, "row-inserted", + (GCallback) accounts_dialog_accounts_model_row_inserted_cb, dialog); + g_signal_connect (model, "row-deleted", + (GCallback) accounts_dialog_accounts_model_row_deleted_cb, dialog); + /* Set up signalling */ priv->account_manager = tp_account_manager_dup (); @@ -2168,7 +2229,6 @@ empathy_accounts_dialog_class_init (EmpathyAccountsDialogClass *klass) GObjectClass *oclass = G_OBJECT_CLASS (klass); GParamSpec *param_spec; - oclass->constructor = do_constructor; oclass->dispose = do_dispose; oclass->constructed = do_constructed; oclass->set_property = do_set_property; |