]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-irc-network-chooser.c
Merge branch 'sasl'
[empathy.git] / libempathy-gtk / empathy-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
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/stat.h>
27
28 #include <glib/gi18n-lib.h>
29 #include <gtk/gtk.h>
30
31 #include <libempathy/empathy-utils.h>
32 #include <libempathy/empathy-irc-network-manager.h>
33
34 #include "empathy-irc-network-dialog.h"
35 #include "empathy-ui-utils.h"
36 #include "empathy-irc-network-chooser-dialog.h"
37
38 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT | EMPATHY_DEBUG_IRC
39 #include <libempathy/empathy-debug.h>
40
41 #include "empathy-irc-network-chooser.h"
42
43 #define DEFAULT_IRC_NETWORK "irc.gimp.org"
44
45 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyIrcNetworkChooser)
46
47 enum {
48     PROP_SETTINGS = 1
49 };
50
51 enum {
52     SIG_CHANGED,
53     LAST_SIGNAL
54 };
55
56 static guint signals[LAST_SIGNAL] = { 0 };
57
58 typedef struct {
59     EmpathyAccountSettings *settings;
60
61     EmpathyIrcNetworkManager *network_manager;
62     GtkWidget *dialog;
63     /* Displayed network */
64     EmpathyIrcNetwork *network;
65 } EmpathyIrcNetworkChooserPriv;
66
67 G_DEFINE_TYPE (EmpathyIrcNetworkChooser, empathy_irc_network_chooser,
68     GTK_TYPE_BUTTON);
69
70 static void
71 empathy_irc_network_chooser_set_property (GObject *object,
72     guint prop_id,
73     const GValue *value,
74     GParamSpec *pspec)
75 {
76   EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (object);
77
78   switch (prop_id)
79     {
80       case PROP_SETTINGS:
81         priv->settings = g_value_dup_object (value);
82         break;
83       default:
84         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
85         break;
86     }
87 }
88
89 static void
90 empathy_irc_network_chooser_get_property (GObject *object,
91     guint prop_id,
92     GValue *value,
93     GParamSpec *pspec)
94 {
95   EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (object);
96
97   switch (prop_id)
98     {
99       case PROP_SETTINGS:
100         g_value_set_object (value, priv->settings);
101         break;
102       default:
103         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
104         break;
105     }
106 }
107
108 static void
109 unset_server_params (EmpathyIrcNetworkChooser *self)
110 {
111   EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
112
113   DEBUG ("Unset server, port and use-ssl");
114   empathy_account_settings_unset (priv->settings, "server");
115   empathy_account_settings_unset (priv->settings, "port");
116   empathy_account_settings_unset (priv->settings, "use-ssl");
117 }
118
119 static void
120 update_server_params (EmpathyIrcNetworkChooser *self)
121 {
122   EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
123   GSList *servers;
124   const gchar *charset;
125
126   g_assert (priv->network != NULL);
127
128   charset = empathy_irc_network_get_charset (priv->network);
129   DEBUG ("Setting charset to %s", charset);
130   empathy_account_settings_set_string (priv->settings, "charset", charset);
131
132   servers = empathy_irc_network_get_servers (priv->network);
133   if (g_slist_length (servers) > 0)
134     {
135       /* set the first server as CM server */
136       EmpathyIrcServer *server = servers->data;
137       gchar *address;
138       guint port;
139       gboolean ssl;
140
141       g_object_get (server,
142           "address", &address,
143           "port", &port,
144           "ssl", &ssl,
145           NULL);
146
147       DEBUG ("Setting server to %s", address);
148       empathy_account_settings_set_string (priv->settings, "server", address);
149       DEBUG ("Setting port to %u", port);
150       empathy_account_settings_set_uint32 (priv->settings, "port", port);
151       DEBUG ("Setting use-ssl to %s", ssl ? "TRUE": "FALSE" );
152       empathy_account_settings_set_boolean (priv->settings, "use-ssl", ssl);
153
154       g_free (address);
155     }
156   else
157     {
158       /* No server. Unset values */
159       unset_server_params (self);
160     }
161
162   g_slist_foreach (servers, (GFunc) g_object_unref, NULL);
163   g_slist_free (servers);
164 }
165
166 static void
167 set_label (EmpathyIrcNetworkChooser *self)
168 {
169   EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
170
171   g_assert (priv->network != NULL);
172
173   gtk_button_set_label (GTK_BUTTON (self),
174       empathy_irc_network_get_name (priv->network));
175 }
176
177 static void
178 set_label_from_settings (EmpathyIrcNetworkChooser *self)
179 {
180   EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
181   const gchar *server;
182
183   tp_clear_object (&priv->network);
184
185   server = empathy_account_settings_get_string (priv->settings, "server");
186
187   if (server != NULL)
188     {
189       EmpathyIrcServer *srv;
190       gint port;
191       gboolean ssl;
192
193       priv->network = empathy_irc_network_manager_find_network_by_address (
194           priv->network_manager, server);
195
196       if (priv->network != NULL)
197         {
198           /* The network is known */
199           g_object_ref (priv->network);
200           set_label (self);
201           return;
202         }
203
204       /* We don't have this network. Let's create it */
205       port = empathy_account_settings_get_uint32 (priv->settings, "port");
206       ssl = empathy_account_settings_get_boolean (priv->settings,
207           "use-ssl");
208
209       DEBUG ("Create a network %s", server);
210       priv->network = empathy_irc_network_new (server);
211       srv = empathy_irc_server_new (server, port, ssl);
212
213       empathy_irc_network_append_server (priv->network, srv);
214       empathy_irc_network_manager_add (priv->network_manager, priv->network);
215
216       set_label (self);
217
218       g_object_unref (srv);
219       return;
220     }
221
222   /* Set default network */
223   priv->network = empathy_irc_network_manager_find_network_by_address (
224           priv->network_manager, DEFAULT_IRC_NETWORK);
225   g_assert (priv->network != NULL);
226
227   set_label (self);
228   update_server_params (self);
229   g_object_ref (priv->network);
230 }
231
232 static void
233 dialog_response_cb (GtkDialog *dialog,
234     gint response,
235     EmpathyIrcNetworkChooser *self)
236 {
237   EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
238   EmpathyIrcNetworkChooserDialog *chooser =
239     EMPATHY_IRC_NETWORK_CHOOSER_DIALOG (priv->dialog);
240
241   if (response != GTK_RESPONSE_CLOSE &&
242       response != GTK_RESPONSE_DELETE_EVENT)
243     return;
244
245   if (empathy_irc_network_chooser_dialog_get_changed (chooser))
246     {
247       tp_clear_object (&priv->network);
248
249       priv->network = g_object_ref (
250           empathy_irc_network_chooser_dialog_get_network (chooser));
251
252       update_server_params (self);
253       set_label (self);
254
255       g_signal_emit (self, signals[SIG_CHANGED], 0);
256     }
257
258   gtk_widget_destroy (priv->dialog);
259   priv->dialog = NULL;
260 }
261
262 static void
263 clicked_cb (GtkButton *button,
264     gpointer user_data)
265 {
266   EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (button);
267   GtkWindow *window;
268
269   if (priv->dialog != NULL)
270     goto out;
271
272   window = empathy_get_toplevel_window (GTK_WIDGET (button));
273
274   priv->dialog = empathy_irc_network_chooser_dialog_new (priv->settings,
275       priv->network, window);
276   gtk_widget_show_all (priv->dialog);
277
278   tp_g_signal_connect_object (priv->dialog, "response",
279       G_CALLBACK (dialog_response_cb), button, 0);
280
281 out:
282   empathy_window_present (GTK_WINDOW (priv->dialog));
283 }
284
285 static void
286 empathy_irc_network_chooser_constructed (GObject *object)
287 {
288   EmpathyIrcNetworkChooser *self = (EmpathyIrcNetworkChooser *) object;
289   EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
290
291   g_assert (priv->settings != NULL);
292
293   set_label_from_settings (self);
294
295   g_signal_connect (self, "clicked", G_CALLBACK (clicked_cb), self);
296 }
297
298 static void
299 empathy_irc_network_chooser_dispose (GObject *object)
300 {
301   EmpathyIrcNetworkManager *self = (EmpathyIrcNetworkManager *) object;
302   EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
303
304   tp_clear_object (&priv->settings);
305   tp_clear_object (&priv->network_manager);
306   tp_clear_object (&priv->network);
307
308   if (G_OBJECT_CLASS (empathy_irc_network_chooser_parent_class)->dispose)
309     G_OBJECT_CLASS (empathy_irc_network_chooser_parent_class)->dispose (object);
310 }
311
312 static void
313 empathy_irc_network_chooser_class_init (EmpathyIrcNetworkChooserClass *klass)
314 {
315   GObjectClass *object_class = G_OBJECT_CLASS (klass);
316
317   object_class->get_property = empathy_irc_network_chooser_get_property;
318   object_class->set_property = empathy_irc_network_chooser_set_property;
319   object_class->constructed = empathy_irc_network_chooser_constructed;
320   object_class->dispose = empathy_irc_network_chooser_dispose;
321
322   g_object_class_install_property (object_class, PROP_SETTINGS,
323     g_param_spec_object ("settings",
324       "Settings",
325       "The EmpathyAccountSettings to show and edit",
326       EMPATHY_TYPE_ACCOUNT_SETTINGS,
327       G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
328
329   signals[SIG_CHANGED] = g_signal_new ("changed",
330       G_OBJECT_CLASS_TYPE (object_class),
331       G_SIGNAL_RUN_LAST,
332       0,
333       NULL, NULL,
334       g_cclosure_marshal_VOID__VOID,
335       G_TYPE_NONE,
336       0);
337
338   g_type_class_add_private (object_class,
339       sizeof (EmpathyIrcNetworkChooserPriv));
340 }
341
342 static void
343 empathy_irc_network_chooser_init (EmpathyIrcNetworkChooser *self)
344 {
345   EmpathyIrcNetworkChooserPriv *priv;
346
347   priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
348       EMPATHY_TYPE_IRC_NETWORK_CHOOSER, EmpathyIrcNetworkChooserPriv);
349   self->priv = priv;
350
351   priv->network_manager = empathy_irc_network_manager_dup_default ();
352 }
353
354 GtkWidget *
355 empathy_irc_network_chooser_new (EmpathyAccountSettings *settings)
356 {
357   return g_object_new (EMPATHY_TYPE_IRC_NETWORK_CHOOSER,
358       "settings", settings,
359       NULL);
360 }
361
362 EmpathyIrcNetwork *
363 empathy_irc_network_chooser_get_network (EmpathyIrcNetworkChooser *self)
364 {
365   EmpathyIrcNetworkChooserPriv *priv = GET_PRIV (self);
366
367   return priv->network;
368 }