]> git.0d.be Git - empathy.git/blob - ubuntu-online-accounts/cc-plugins/app-plugin/empathy-app-plugin-widget.c
7e1a5f206108faba544a738fd0dca104ab1eca29
[empathy.git] / ubuntu-online-accounts / cc-plugins / app-plugin / empathy-app-plugin-widget.c
1 /*
2  * empathy-app-plugin-widget.c
3  *
4  * Copyright (C) 2012 Collabora Ltd. <http://www.collabora.co.uk/>
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include "config.h"
22
23 #include <glib/gi18n-lib.h>
24
25 #include <telepathy-glib/telepathy-glib.h>
26
27 #include <libaccounts-glib/ag-manager.h>
28 #include <libaccounts-glib/ag-provider.h>
29
30 #include "libempathy/empathy-contact.h"
31 #include "libempathy-gtk/empathy-user-info.h"
32
33 #include "empathy-app-plugin-widget.h"
34
35 G_DEFINE_TYPE (EmpathyAppPluginWidget, empathy_app_plugin_widget, GTK_TYPE_BOX)
36
37 enum
38 {
39   PROP_ACCOUNT = 1,
40   N_PROPS
41 };
42
43 enum
44 {
45   SIG_DONE,
46   LAST_SIGNAL
47 };
48
49 static guint signals[LAST_SIGNAL];
50
51 struct _EmpathyAppPluginWidgetPriv
52 {
53   AgAccount *account;
54
55   GtkWidget *user_info;
56 };
57
58 static void
59 empathy_app_plugin_widget_get_property (GObject *object,
60     guint property_id,
61     GValue *value,
62     GParamSpec *pspec)
63 {
64   EmpathyAppPluginWidget *self = EMPATHY_APP_PLUGIN_WIDGET (object);
65
66   switch (property_id)
67     {
68       case PROP_ACCOUNT:
69         g_value_set_object (value, self->priv->account);
70         break;
71       default:
72         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
73         break;
74     }
75 }
76
77 static void
78 empathy_app_plugin_widget_set_property (GObject *object,
79     guint property_id,
80     const GValue *value,
81     GParamSpec *pspec)
82 {
83   EmpathyAppPluginWidget *self = EMPATHY_APP_PLUGIN_WIDGET (object);
84
85   switch (property_id)
86     {
87       case PROP_ACCOUNT:
88         g_assert (self->priv->account == NULL); /* construct only */
89         self->priv->account = g_value_dup_object (value);
90         break;
91       default:
92         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
93         break;
94     }
95 }
96
97 static void
98 response_cb (GtkWidget *widget,
99     gint response,
100     EmpathyAppPluginWidget *self)
101 {
102   if (self->priv->user_info != NULL)
103     {
104       EmpathyUserInfo *user_info = (EmpathyUserInfo *) self->priv->user_info;
105
106       if (response == GTK_RESPONSE_OK)
107         empathy_user_info_apply_async (user_info, NULL, NULL);
108       else
109         empathy_user_info_discard (user_info);
110     }
111
112   g_signal_emit (self, signals[SIG_DONE], 0);
113 }
114
115 static GtkWidget *
116 create_top_bar (EmpathyAppPluginWidget *self)
117 {
118   GtkWidget *bar, *content, *action, *label;
119   GtkCssProvider *css;
120   AgProvider *provider;
121   gchar *str;
122   GError *error = NULL;
123
124   bar = gtk_info_bar_new_with_buttons (
125       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
126       _("Done"), GTK_RESPONSE_OK,
127       NULL);
128   gtk_widget_set_hexpand (bar, TRUE);
129   gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_QUESTION);
130   action = gtk_info_bar_get_action_area (GTK_INFO_BAR (bar));
131   gtk_orientable_set_orientation (GTK_ORIENTABLE (action),
132       GTK_ORIENTATION_HORIZONTAL);
133   gtk_widget_set_name (bar, "authorization-infobar");
134   css = gtk_css_provider_new ();
135   if (gtk_css_provider_load_from_data (css,
136           "@define-color question_bg_color rgb (222, 222, 222);"
137           "GtkInfoBar#authorization-infobar"
138           "{"
139           "  color: @fg_color;"
140           "}",
141           -1, &error))
142     {
143       GtkStyleContext *context = gtk_widget_get_style_context (bar);
144
145       gtk_style_context_add_provider (context, (GtkStyleProvider *) css,
146           GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
147     }
148   else
149     {
150       g_warning ("Error processing CSS theme override: %s", error->message);
151       g_clear_error (&error);
152     }
153   g_object_unref (css);
154
155   content = gtk_info_bar_get_content_area (GTK_INFO_BAR (bar));
156
157   provider = ag_manager_get_provider (
158       ag_account_get_manager (self->priv->account),
159       ag_account_get_provider_name (self->priv->account));
160   str = g_strdup_printf (_("Edit %s account options"),
161       ag_provider_get_display_name (provider));
162   label = gtk_label_new (str);
163   gtk_container_add (GTK_CONTAINER (content), label);
164   gtk_widget_show (label);
165   ag_provider_unref (provider);
166   g_free (str);
167
168   g_signal_connect (bar, "response",
169       G_CALLBACK (response_cb), self);
170
171   return bar;
172 }
173
174 static void
175 manager_prepared_cb (GObject *source,
176     GAsyncResult *result,
177     gpointer user_data)
178 {
179   TpWeakRef *wr = user_data;
180   EmpathyAppPluginWidget *self = tp_weak_ref_dup_object (wr);
181   TpAccountManager *manager = (TpAccountManager *) source;
182   GList *accounts;
183   GError *error = NULL;
184
185   if (self == NULL)
186     {
187       tp_weak_ref_destroy (wr);
188       return;
189     }
190
191   if (!tp_proxy_prepare_finish (manager, result, &error))
192     {
193       g_debug ("Error preparing Account Manager: %s", error->message);
194       g_clear_error (&error);
195       goto out;
196     }
197
198   accounts = tp_account_manager_dup_valid_accounts (manager);
199   while (accounts != NULL)
200     {
201       TpAccount *account = accounts->data;
202       const GValue *value;
203
204       value = tp_account_get_storage_identifier (account);
205       if (G_VALUE_HOLDS_UINT (value) &&
206           g_value_get_uint (value) == self->priv->account->id)
207         {
208           GtkWidget *alig;
209
210           alig = gtk_alignment_new (0.5, 0, 0, 0);
211           self->priv->user_info = empathy_user_info_new (account);
212           gtk_container_add (GTK_CONTAINER (alig), self->priv->user_info);
213           gtk_widget_show (self->priv->user_info);
214
215           gtk_box_pack_start (GTK_BOX (self), alig, TRUE, TRUE, 0);
216           gtk_widget_show (alig);
217           break;
218         }
219
220       accounts = g_list_delete_link (accounts, accounts);
221     }
222   g_list_free_full (accounts, g_object_unref);
223
224 out:
225   tp_weak_ref_destroy (wr);
226   g_object_unref (self);
227 }
228
229 static void
230 empathy_app_plugin_widget_constructed (GObject *object)
231 {
232   EmpathyAppPluginWidget *self = EMPATHY_APP_PLUGIN_WIDGET (object);
233   void (*chain_up) (GObject *) =
234       ((GObjectClass *) empathy_app_plugin_widget_parent_class)->constructed;
235   GtkWidget *top;
236   TpAccountManager *manager;
237
238   if (chain_up != NULL)
239     chain_up (object);
240
241   g_assert (AG_IS_ACCOUNT (self->priv->account));
242
243   /* Top bar */
244   top = create_top_bar (self);
245   gtk_widget_show (top);
246   gtk_box_pack_start (GTK_BOX (self), top, FALSE, FALSE, 0);
247
248   /* Prepare tp's account manager to find the TpAccount corresponding to our
249    * AgAccount */
250   manager = tp_account_manager_dup ();
251   tp_proxy_prepare_async (manager, NULL,
252       manager_prepared_cb, tp_weak_ref_new (self, NULL, NULL));
253   g_object_unref (manager);
254 }
255
256 static void
257 empathy_app_plugin_widget_dispose (GObject *object)
258 {
259   EmpathyAppPluginWidget *self = EMPATHY_APP_PLUGIN_WIDGET (object);
260   void (*chain_up) (GObject *) =
261       ((GObjectClass *) empathy_app_plugin_widget_parent_class)->dispose;
262
263   g_clear_object (&self->priv->account);
264
265   if (chain_up != NULL)
266     chain_up (object);
267 }
268
269 static void
270 empathy_app_plugin_widget_class_init (
271     EmpathyAppPluginWidgetClass *klass)
272 {
273   GObjectClass *oclass = G_OBJECT_CLASS (klass);
274   GParamSpec *spec;
275
276   oclass->get_property = empathy_app_plugin_widget_get_property;
277   oclass->set_property = empathy_app_plugin_widget_set_property;
278   oclass->constructed = empathy_app_plugin_widget_constructed;
279   oclass->dispose = empathy_app_plugin_widget_dispose;
280
281   spec = g_param_spec_object ("account", "account",
282       "Account",
283       AG_TYPE_ACCOUNT,
284       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
285   g_object_class_install_property (oclass, PROP_ACCOUNT, spec);
286
287   signals[SIG_DONE] = g_signal_new ("done",
288       G_OBJECT_CLASS_TYPE (klass),
289       G_SIGNAL_RUN_LAST,
290       0, NULL, NULL, NULL,
291       G_TYPE_NONE,
292       0);
293
294   g_type_class_add_private (klass, sizeof (EmpathyAppPluginWidgetPriv));
295 }
296
297 static void
298 empathy_app_plugin_widget_init (EmpathyAppPluginWidget *self)
299 {
300   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
301       EMPATHY_TYPE_APP_PLUGIN_WIDGET, EmpathyAppPluginWidgetPriv);
302 }
303
304 GtkWidget *
305 empathy_app_plugin_widget_new (AgAccount *account)
306 {
307   return g_object_new (EMPATHY_TYPE_APP_PLUGIN_WIDGET,
308       "account", account,
309       "orientation", GTK_ORIENTATION_VERTICAL,
310       "spacing", 10,
311       NULL);
312 }