]> git.0d.be Git - empathy.git/blob - tp-account-widgets/tpaw-irc-network-chooser.c
tpaw-utils: use self->priv instead of EMPATHY_GET_PRIV(self)
[empathy.git] / tp-account-widgets / tpaw-irc-network-chooser.c
1 /*
2  * Copyright (C) 2007-2008 Guillaume Desmottes
3  * Copyright (C) 2010 Collabora Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  *
19  * Authors: Guillaume Desmottes <gdesmott@gnome.org>
20  */
21
22 #include "config.h"
23 #include "tpaw-irc-network-chooser.h"
24
25 #include "tpaw-irc-network-chooser-dialog.h"
26 #include "tpaw-irc-network-manager.h"
27 #include "tpaw-utils.h"
28 #include "empathy-ui-utils.h"
29 #include "empathy-utils.h"
30
31 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT | EMPATHY_DEBUG_IRC
32 #include "empathy-debug.h"
33
34 #define DEFAULT_IRC_NETWORK "irc.gimp.org"
35 #define DEFAULT_IRC_PORT 6667
36 #define DEFAULT_IRC_SSL FALSE
37
38 enum {
39     PROP_SETTINGS = 1
40 };
41
42 enum {
43     SIG_CHANGED,
44     LAST_SIGNAL
45 };
46
47 static guint signals[LAST_SIGNAL] = { 0 };
48
49 struct _TpawIrcNetworkChooserPriv {
50     TpawAccountSettings *settings;
51
52     TpawIrcNetworkManager *network_manager;
53     GtkWidget *dialog;
54     /* Displayed network */
55     TpawIrcNetwork *network;
56 };
57
58 G_DEFINE_TYPE (TpawIrcNetworkChooser, tpaw_irc_network_chooser,
59     GTK_TYPE_BUTTON);
60
61 static void
62 tpaw_irc_network_chooser_set_property (GObject *object,
63     guint prop_id,
64     const GValue *value,
65     GParamSpec *pspec)
66 {
67   TpawIrcNetworkChooser *self = TPAW_IRC_NETWORK_CHOOSER (object);
68
69   switch (prop_id)
70     {
71       case PROP_SETTINGS:
72         self->priv->settings = g_value_dup_object (value);
73         break;
74       default:
75         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
76         break;
77     }
78 }
79
80 static void
81 tpaw_irc_network_chooser_get_property (GObject *object,
82     guint prop_id,
83     GValue *value,
84     GParamSpec *pspec)
85 {
86   TpawIrcNetworkChooser *self = TPAW_IRC_NETWORK_CHOOSER (object);
87
88   switch (prop_id)
89     {
90       case PROP_SETTINGS:
91         g_value_set_object (value, self->priv->settings);
92         break;
93       default:
94         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
95         break;
96     }
97 }
98
99 static void
100 unset_server_params (TpawIrcNetworkChooser *self)
101 {
102   DEBUG ("Unset server, port and use-ssl");
103   tpaw_account_settings_unset (self->priv->settings, "server");
104   tpaw_account_settings_unset (self->priv->settings, "port");
105   tpaw_account_settings_unset (self->priv->settings, "use-ssl");
106 }
107
108 static gchar *
109 dup_network_service (TpawIrcNetwork *network)
110 {
111   /* Account.Service has to be a lower case alphanumeric string which may
112    * also contain '-' but not start with it. */
113 #define VALID G_CSET_a_2_z G_CSET_DIGITS "-"
114   gchar *service, *tmp;
115
116   service = g_strdup (tpaw_irc_network_get_name (network));
117   service = g_strstrip (service);
118
119   if (tp_str_empty (service))
120     {
121       g_free (service);
122       return NULL;
123     }
124
125   tmp = service;
126   service = g_ascii_strdown (service, -1);
127   g_free (tmp);
128
129   service = g_strcanon (service, VALID, '-');
130
131   if (service[0] == '-')
132     {
133       tmp = service;
134       service = g_strdup (service + 1);
135
136       g_free (tmp);
137     }
138
139   return service;
140 }
141
142 static void
143 update_server_params (TpawIrcNetworkChooser *self)
144 {
145   GSList *servers;
146   const gchar *charset;
147
148   g_assert (self->priv->network != NULL);
149
150   charset = tpaw_irc_network_get_charset (self->priv->network);
151   DEBUG ("Setting charset to %s", charset);
152   tpaw_account_settings_set (self->priv->settings, "charset",
153       g_variant_new_string (charset));
154
155   servers = tpaw_irc_network_get_servers (self->priv->network);
156   if (g_slist_length (servers) > 0)
157     {
158       /* set the first server as CM server */
159       TpawIrcServer *server = servers->data;
160       gchar *address;
161       guint port;
162       gboolean ssl;
163       gchar *service;
164
165       g_object_get (server,
166           "address", &address,
167           "port", &port,
168           "ssl", &ssl,
169           NULL);
170
171       DEBUG ("Setting server to %s", address);
172       tpaw_account_settings_set (self->priv->settings, "server",
173           g_variant_new_string (address));
174       DEBUG ("Setting port to %u", port);
175       tpaw_account_settings_set (self->priv->settings, "port",
176           g_variant_new_uint32 (port));
177       DEBUG ("Setting use-ssl to %s", ssl ? "TRUE": "FALSE" );
178       tpaw_account_settings_set (self->priv->settings, "use-ssl",
179           g_variant_new_boolean (ssl));
180
181       /* Set Account.Service */
182       service = dup_network_service (self->priv->network);
183       DEBUG ("Setting Service to %s", service);
184       tpaw_account_settings_set_service (self->priv->settings, service);
185
186       g_free (address);
187       g_free (service);
188     }
189   else
190     {
191       /* No server. Unset values */
192       unset_server_params (self);
193     }
194
195   g_slist_foreach (servers, (GFunc) g_object_unref, NULL);
196   g_slist_free (servers);
197 }
198
199 static void
200 set_label (TpawIrcNetworkChooser *self)
201 {
202   g_assert (self->priv->network != NULL);
203
204   gtk_button_set_label (GTK_BUTTON (self),
205       tpaw_irc_network_get_name (self->priv->network));
206 }
207
208 static void
209 set_label_from_settings (TpawIrcNetworkChooser *self)
210 {
211   gchar *server;
212
213   tp_clear_object (&self->priv->network);
214
215   server = tpaw_account_settings_dup_string (self->priv->settings, "server");
216
217   if (server != NULL)
218     {
219       TpawIrcServer *srv;
220       gint port;
221       gboolean ssl;
222
223       self->priv->network =
224         tpaw_irc_network_manager_find_network_by_address (
225             self->priv->network_manager, server);
226
227       if (self->priv->network != NULL)
228         {
229           /* The network is known */
230           g_object_ref (self->priv->network);
231           set_label (self);
232           return;
233         }
234
235       /* We don't have this network. Let's create it */
236       port = tpaw_account_settings_get_uint32 (self->priv->settings, "port");
237       ssl = tpaw_account_settings_get_boolean (self->priv->settings,
238           "use-ssl");
239
240       DEBUG ("Create a network %s", server);
241       self->priv->network = tpaw_irc_network_new (server);
242       srv = tpaw_irc_server_new (server, port, ssl);
243
244       tpaw_irc_network_append_server (self->priv->network, srv);
245       tpaw_irc_network_manager_add (self->priv->network_manager,
246           self->priv->network);
247
248       set_label (self);
249
250       g_object_unref (srv);
251       g_free (server);
252       return;
253     }
254
255   /* Set default network */
256   self->priv->network = tpaw_irc_network_manager_find_network_by_address (
257           self->priv->network_manager, DEFAULT_IRC_NETWORK);
258
259   if (self->priv->network == NULL)
260     {
261       /* Default network is not known, recreate it */
262       TpawIrcServer *srv;
263
264       self->priv->network = tpaw_irc_network_new (DEFAULT_IRC_NETWORK);
265
266       srv = tpaw_irc_server_new (DEFAULT_IRC_NETWORK, DEFAULT_IRC_PORT,
267           DEFAULT_IRC_SSL);
268
269       tpaw_irc_network_append_server (self->priv->network, srv);
270       tpaw_irc_network_manager_add (self->priv->network_manager,
271           self->priv->network);
272
273       g_object_unref (srv);
274     }
275
276   set_label (self);
277   update_server_params (self);
278   g_object_ref (self->priv->network);
279 }
280
281 static void
282 dialog_response_cb (GtkDialog *dialog,
283     gint response,
284     TpawIrcNetworkChooser *self)
285 {
286   TpawIrcNetworkChooserDialog *chooser =
287     TPAW_IRC_NETWORK_CHOOSER_DIALOG (self->priv->dialog);
288
289   if (response != GTK_RESPONSE_CLOSE &&
290       response != GTK_RESPONSE_DELETE_EVENT)
291     return;
292
293   if (tpaw_irc_network_chooser_dialog_get_changed (chooser))
294     {
295       tp_clear_object (&self->priv->network);
296
297       self->priv->network = g_object_ref (
298           tpaw_irc_network_chooser_dialog_get_network (chooser));
299
300       update_server_params (self);
301       set_label (self);
302
303       g_signal_emit (self, signals[SIG_CHANGED], 0);
304     }
305
306   gtk_widget_destroy (self->priv->dialog);
307   self->priv->dialog = NULL;
308 }
309
310 static void
311 clicked_cb (GtkButton *button,
312     gpointer user_data)
313 {
314   TpawIrcNetworkChooser *self = TPAW_IRC_NETWORK_CHOOSER (button);
315   GtkWindow *window;
316
317   if (self->priv->dialog != NULL)
318     goto out;
319
320   window = tpaw_get_toplevel_window (GTK_WIDGET (button));
321
322   self->priv->dialog = tpaw_irc_network_chooser_dialog_new (
323       self->priv->settings, self->priv->network, window);
324   gtk_widget_show_all (self->priv->dialog);
325
326   tp_g_signal_connect_object (self->priv->dialog, "response",
327       G_CALLBACK (dialog_response_cb), button, 0);
328
329 out:
330   tpaw_window_present (GTK_WINDOW (self->priv->dialog));
331 }
332
333 static void
334 tpaw_irc_network_chooser_constructed (GObject *object)
335 {
336   TpawIrcNetworkChooser *self = (TpawIrcNetworkChooser *) object;
337
338   g_assert (self->priv->settings != NULL);
339
340   set_label_from_settings (self);
341
342   g_signal_connect (self, "clicked", G_CALLBACK (clicked_cb), self);
343 }
344
345 static void
346 tpaw_irc_network_chooser_dispose (GObject *object)
347 {
348   TpawIrcNetworkChooser *self = (TpawIrcNetworkChooser *) object;
349
350   tp_clear_object (&self->priv->settings);
351   tp_clear_object (&self->priv->network_manager);
352   tp_clear_object (&self->priv->network);
353
354   if (G_OBJECT_CLASS (tpaw_irc_network_chooser_parent_class)->dispose)
355     G_OBJECT_CLASS (tpaw_irc_network_chooser_parent_class)->dispose (object);
356 }
357
358 static void
359 tpaw_irc_network_chooser_class_init (TpawIrcNetworkChooserClass *klass)
360 {
361   GObjectClass *object_class = G_OBJECT_CLASS (klass);
362
363   object_class->get_property = tpaw_irc_network_chooser_get_property;
364   object_class->set_property = tpaw_irc_network_chooser_set_property;
365   object_class->constructed = tpaw_irc_network_chooser_constructed;
366   object_class->dispose = tpaw_irc_network_chooser_dispose;
367
368   g_object_class_install_property (object_class, PROP_SETTINGS,
369     g_param_spec_object ("settings",
370       "Settings",
371       "The TpawAccountSettings to show and edit",
372       TPAW_TYPE_ACCOUNT_SETTINGS,
373       G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
374
375   signals[SIG_CHANGED] = g_signal_new ("changed",
376       G_OBJECT_CLASS_TYPE (object_class),
377       G_SIGNAL_RUN_LAST,
378       0,
379       NULL, NULL,
380       g_cclosure_marshal_generic,
381       G_TYPE_NONE,
382       0);
383
384   g_type_class_add_private (object_class,
385       sizeof (TpawIrcNetworkChooserPriv));
386 }
387
388 static void
389 tpaw_irc_network_chooser_init (TpawIrcNetworkChooser *self)
390 {
391   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
392       TPAW_TYPE_IRC_NETWORK_CHOOSER, TpawIrcNetworkChooserPriv);
393
394   self->priv->network_manager = tpaw_irc_network_manager_dup_default ();
395 }
396
397 GtkWidget *
398 tpaw_irc_network_chooser_new (TpawAccountSettings *settings)
399 {
400   return g_object_new (TPAW_TYPE_IRC_NETWORK_CHOOSER,
401       "settings", settings,
402       NULL);
403 }
404
405 TpawIrcNetwork *
406 tpaw_irc_network_chooser_get_network (TpawIrcNetworkChooser *self)
407 {
408   return self->priv->network;
409 }