2 * empathy-accounts-plugin-widget.c
4 * Copyright (C) 2012 Collabora Ltd. <http://www.collabora.co.uk/>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "empathy-accounts-plugin-widget.h"
26 #include <glib/gi18n-lib.h>
28 #include <telepathy-glib/telepathy-glib.h>
30 #include <libaccounts-glib/ag-service.h>
31 #include <libaccounts-glib/ag-account-service.h>
33 #include <libempathy-gtk/empathy-account-widget.h>
35 G_DEFINE_TYPE (EmpathyAccountsPluginWidget, empathy_accounts_plugin_widget, GTK_TYPE_BOX)
49 static guint signals[LAST_SIGNAL];
51 struct _EmpathyAccountsPluginWidgetPriv
55 EmpathyAccountSettings *settings;
57 EmpathyAccountWidget *account_widget;
58 GtkWidget *done_button;
62 empathy_accounts_plugin_widget_get_property (GObject *object,
67 EmpathyAccountsPluginWidget *self = EMPATHY_ACCOUNTS_PLUGIN_WIDGET (object);
72 g_value_set_object (value, self->priv->account);
75 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
81 empathy_accounts_plugin_widget_set_property (GObject *object,
86 EmpathyAccountsPluginWidget *self = EMPATHY_ACCOUNTS_PLUGIN_WIDGET (object);
91 self->priv->account = g_value_dup_object (value);
94 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
99 static EmpathyAccountSettings *
100 create_account_settings (AgAccount *account)
104 AgAccountService *account_service;
105 GValue v = G_VALUE_INIT;
106 gchar *manager = NULL, *protocol = NULL;
107 EmpathyAccountSettings *settings;
109 g_assert (account->id == 0);
111 services = ag_account_list_services_by_type (account, "IM");
112 g_return_val_if_fail (services != NULL, NULL);
113 service = (AgService *) services->data;
115 account_service = ag_account_service_new (account, service);
117 g_value_init (&v, G_TYPE_STRING);
118 if (ag_account_service_get_value (account_service,
119 "telepathy/manager", &v) != AG_SETTING_SOURCE_NONE)
120 manager = g_value_dup_string (&v);
123 g_value_init (&v, G_TYPE_STRING);
124 if (ag_account_service_get_value (account_service,
125 "telepathy/protocol", &v) != AG_SETTING_SOURCE_NONE)
126 protocol = g_value_dup_string (&v);
129 g_return_val_if_fail (manager != NULL, NULL);
130 g_return_val_if_fail (protocol != NULL, NULL);
132 settings = empathy_account_settings_new (manager, protocol, NULL,
133 ag_service_get_display_name (service));
135 empathy_account_settings_set_storage_provider (settings,
136 EMPATHY_UOA_PROVIDER);
138 empathy_account_settings_set_icon_name_async (settings,
139 ag_service_get_icon_name (service), NULL, NULL);
148 response_cb (GtkWidget *widget,
150 EmpathyAccountsPluginWidget *self)
152 if (response == GTK_RESPONSE_OK)
154 empathy_account_widget_apply_and_log_in (self->priv->account_widget);
156 /* Rely on account_widget_close_cb to fire the 'done' signal */
160 empathy_account_widget_discard_pending_changes (
161 self->priv->account_widget);
163 g_signal_emit (self, signals[SIG_DONE], 0);
168 create_top_bar (EmpathyAccountsPluginWidget *self)
170 GtkWidget *bar, *content, *action, *label;
172 GError *error = NULL;
174 bar = gtk_info_bar_new_with_buttons (
175 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
178 self->priv->done_button = gtk_info_bar_add_button (GTK_INFO_BAR (bar),
179 _("Done"), GTK_RESPONSE_OK);
181 gtk_widget_set_hexpand (bar, TRUE);
182 gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_QUESTION);
183 action = gtk_info_bar_get_action_area (GTK_INFO_BAR (bar));
184 gtk_orientable_set_orientation (GTK_ORIENTABLE (action),
185 GTK_ORIENTATION_HORIZONTAL);
186 gtk_widget_set_name (bar, "authorization-infobar");
187 css = gtk_css_provider_new ();
188 if (gtk_css_provider_load_from_data (css,
189 "@define-color question_bg_color rgb (222, 222, 222);"
190 "GtkInfoBar#authorization-infobar"
196 GtkStyleContext *context = gtk_widget_get_style_context (bar);
198 gtk_style_context_add_provider (context, (GtkStyleProvider *) css,
199 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
203 g_warning ("Error processing CSS theme override: %s", error->message);
204 g_clear_error (&error);
206 g_object_unref (css);
208 content = gtk_info_bar_get_content_area (GTK_INFO_BAR (bar));
210 label = gtk_label_new (_("Please enter your account details"));
211 gtk_container_add (GTK_CONTAINER (content), label);
212 gtk_widget_show (label);
214 g_signal_connect (bar, "response",
215 G_CALLBACK (response_cb), self);
221 account_widget_handle_apply_cb (EmpathyAccountWidget *widget,
223 EmpathyAccountsPluginWidget *self)
225 gtk_widget_set_sensitive (self->priv->done_button, valid);
229 account_widget_close_cb (EmpathyAccountWidget *widget,
230 GtkResponseType response,
231 EmpathyAccountsPluginWidget *self)
233 g_signal_emit (self, signals[SIG_DONE], 0);
237 add_account_widget (EmpathyAccountsPluginWidget *self)
242 alig = gtk_alignment_new (0.5, 0, 0, 0);
244 gtk_box_pack_start (GTK_BOX (self), alig, TRUE, TRUE, 0);
245 gtk_widget_show (GTK_WIDGET (alig));
247 /* Use the simple widget only when creating the account */
248 simple = (self->priv->account->id == 0);
250 self->priv->account_widget = empathy_account_widget_new_for_protocol (
251 self->priv->settings, simple);
253 empathy_account_widget_hide_buttons (self->priv->account_widget);
255 gtk_widget_set_valign (GTK_WIDGET (self->priv->account_widget),
258 gtk_container_add (GTK_CONTAINER (alig),
259 GTK_WIDGET (self->priv->account_widget));
260 gtk_widget_show (GTK_WIDGET (self->priv->account_widget));
262 if (!empathy_account_settings_is_valid (self->priv->settings))
264 gtk_widget_set_sensitive (self->priv->done_button, FALSE);
267 g_signal_connect (self->priv->account_widget, "handle-apply",
268 G_CALLBACK (account_widget_handle_apply_cb), self);
269 g_signal_connect (self->priv->account_widget, "close",
270 G_CALLBACK (account_widget_close_cb), self);
274 maybe_add_account_widget (EmpathyAccountsPluginWidget *self)
276 g_return_if_fail (self->priv->settings != NULL);
278 if (empathy_account_settings_is_ready (self->priv->settings))
280 add_account_widget (self);
284 g_signal_connect_swapped (self->priv->settings, "notify::ready",
285 G_CALLBACK (add_account_widget), self);
290 manager_prepared_cb (GObject *source,
291 GAsyncResult *result,
294 TpWeakRef *wr = user_data;
295 EmpathyAccountsPluginWidget *self = tp_weak_ref_dup_object (wr);
296 TpAccountManager *manager = (TpAccountManager *) source;
298 GError *error = NULL;
302 tp_weak_ref_destroy (wr);
306 if (!tp_proxy_prepare_finish (manager, result, &error))
308 g_debug ("Error preparing Account Manager: %s", error->message);
309 g_clear_error (&error);
313 accounts = tp_account_manager_get_valid_accounts (manager);
314 while (accounts != NULL)
316 TpAccount *account = accounts->data;
319 value = tp_account_get_storage_identifier (account);
320 if (G_VALUE_HOLDS_UINT (value) &&
321 g_value_get_uint (value) == self->priv->account->id)
323 self->priv->settings = empathy_account_settings_new_for_account (
325 maybe_add_account_widget (self);
329 accounts = g_list_delete_link (accounts, accounts);
331 g_list_free (accounts);
334 tp_weak_ref_destroy (wr);
335 g_object_unref (self);
339 empathy_accounts_plugin_widget_constructed (GObject *object)
341 EmpathyAccountsPluginWidget *self = EMPATHY_ACCOUNTS_PLUGIN_WIDGET (object);
342 void (*chain_up) (GObject *) =
343 ((GObjectClass *) empathy_accounts_plugin_widget_parent_class)->constructed;
346 if (chain_up != NULL)
349 g_return_if_fail (AG_IS_ACCOUNT (self->priv->account));
352 top = create_top_bar (self);
353 gtk_widget_show (top);
354 gtk_box_pack_start (GTK_BOX (self), top, FALSE, FALSE, 0);
356 if (self->priv->account->id != 0)
358 TpAccountManager *manager;
360 /* Prepare tp's account manager to find the TpAccount corresponding to our
362 manager = tp_account_manager_dup ();
364 tp_proxy_prepare_async (manager, NULL,
365 manager_prepared_cb, tp_weak_ref_new (self, NULL, NULL));
366 g_object_unref (manager);
370 self->priv->settings = create_account_settings (self->priv->account);
371 maybe_add_account_widget (self);
375 empathy_accounts_plugin_widget_dispose (GObject *object)
377 EmpathyAccountsPluginWidget *self = EMPATHY_ACCOUNTS_PLUGIN_WIDGET (object);
378 void (*chain_up) (GObject *) =
379 ((GObjectClass *) empathy_accounts_plugin_widget_parent_class)->dispose;
381 g_clear_object (&self->priv->account);
382 g_clear_object (&self->priv->settings);
384 if (chain_up != NULL)
389 empathy_accounts_plugin_widget_class_init (
390 EmpathyAccountsPluginWidgetClass *klass)
392 GObjectClass *oclass = G_OBJECT_CLASS (klass);
395 oclass->get_property = empathy_accounts_plugin_widget_get_property;
396 oclass->set_property = empathy_accounts_plugin_widget_set_property;
397 oclass->constructed = empathy_accounts_plugin_widget_constructed;
398 oclass->dispose = empathy_accounts_plugin_widget_dispose;
400 spec = g_param_spec_object ("account", "account",
403 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
404 g_object_class_install_property (oclass, PROP_ACCOUNT, spec);
406 signals[SIG_DONE] = g_signal_new ("done",
407 G_OBJECT_CLASS_TYPE (klass),
413 g_type_class_add_private (klass, sizeof (EmpathyAccountsPluginWidgetPriv));
417 empathy_accounts_plugin_widget_init (EmpathyAccountsPluginWidget *self)
419 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
420 EMPATHY_TYPE_ACCOUNTS_PLUGIN_WIDGET, EmpathyAccountsPluginWidgetPriv);
424 empathy_accounts_plugin_widget_new (AgAccount *account)
426 return g_object_new (EMPATHY_TYPE_ACCOUNTS_PLUGIN_WIDGET,
428 "orientation", GTK_ORIENTATION_VERTICAL,