]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-account-widget-irc.c
widget-irc: call update_server_params in setup so buttons are updated (#626620)
[empathy.git] / libempathy-gtk / empathy-account-widget-irc.c
1 /*
2  * Copyright (C) 2007-2008 Guillaume Desmottes
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  *
18  * Authors: Guillaume Desmottes <gdesmott@gnome.org>
19  */
20
21 #include "config.h"
22
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/stat.h>
26
27 #include <glib/gi18n-lib.h>
28 #include <gtk/gtk.h>
29
30 #include <libempathy/empathy-utils.h>
31 #include <libempathy/empathy-irc-network-manager.h>
32
33 #include "empathy-irc-network-dialog.h"
34 #include "empathy-account-widget.h"
35 #include "empathy-account-widget-private.h"
36 #include "empathy-account-widget-irc.h"
37 #include "empathy-ui-utils.h"
38
39 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT | EMPATHY_DEBUG_IRC
40 #include <libempathy/empathy-debug.h>
41
42 #define IRC_NETWORKS_FILENAME "irc-networks.xml"
43 #define DEFAULT_IRC_NETWORK "irc.gimp.org"
44
45 typedef struct {
46   EmpathyAccountWidget *self;
47   EmpathyIrcNetworkManager *network_manager;
48
49   GtkWidget *vbox_settings;
50
51   GtkWidget *combobox_network;
52 } EmpathyAccountWidgetIrc;
53
54 enum {
55   COL_NETWORK_OBJ,
56   COL_NETWORK_NAME,
57 };
58
59 static void
60 account_widget_irc_destroy_cb (GtkWidget *widget,
61                                EmpathyAccountWidgetIrc *settings)
62 {
63   g_object_unref (settings->network_manager);
64   g_slice_free (EmpathyAccountWidgetIrc, settings);
65 }
66
67 static void
68 unset_server_params (EmpathyAccountWidgetIrc *settings)
69 {
70   EmpathyAccountSettings *ac_settings;
71
72   g_object_get (settings->self, "settings", &ac_settings, NULL);
73   DEBUG ("Unset server, port and use-ssl");
74   empathy_account_settings_unset (ac_settings, "server");
75   empathy_account_settings_unset (ac_settings, "port");
76   empathy_account_settings_unset (ac_settings, "use-ssl");
77 }
78
79 static void
80 update_server_params (EmpathyAccountWidgetIrc *settings)
81 {
82   GtkTreeIter iter;
83   GtkTreeModel *model;
84   EmpathyIrcNetwork *network;
85   GSList *servers;
86   gchar *charset;
87   EmpathyAccountSettings *ac_settings;
88
89   g_object_get (settings->self, "settings", &ac_settings, NULL);
90
91   if (!gtk_combo_box_get_active_iter (
92         GTK_COMBO_BOX (settings->combobox_network), &iter))
93     {
94       unset_server_params (settings);
95       return;
96     }
97
98   model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
99   gtk_tree_model_get (model, &iter, COL_NETWORK_OBJ, &network, -1);
100
101   g_assert (network != NULL);
102
103   g_object_get (network, "charset", &charset, NULL);
104   DEBUG ("Setting charset to %s", charset);
105   empathy_account_settings_set_string (ac_settings, "charset", charset);
106   g_free (charset);
107
108   servers = empathy_irc_network_get_servers (network);
109   if (g_slist_length (servers) > 0)
110     {
111       /* set the first server as CM server */
112       EmpathyIrcServer *server = servers->data;
113       gchar *address;
114       guint port;
115       gboolean ssl;
116
117       g_object_get (server,
118           "address", &address,
119           "port", &port,
120           "ssl", &ssl,
121           NULL);
122
123       DEBUG ("Setting server to %s", address);
124       empathy_account_settings_set_string (ac_settings, "server", address);
125       DEBUG ("Setting port to %u", port);
126       empathy_account_settings_set_uint32 (ac_settings, "port", port);
127       DEBUG ("Setting use-ssl to %s", ssl ? "TRUE": "FALSE" );
128       empathy_account_settings_set_boolean (ac_settings, "use-ssl", ssl);
129
130       g_free (address);
131     }
132   else
133     {
134       /* No server. Unset values */
135       unset_server_params (settings);
136     }
137
138   g_slist_foreach (servers, (GFunc) g_object_unref, NULL);
139   g_slist_free (servers);
140   g_object_unref (network);
141 }
142
143 static void
144 irc_network_dialog_destroy_cb (GtkWidget *widget,
145                                EmpathyAccountWidgetIrc *settings)
146 {
147   GtkTreeIter iter;
148   GtkTreeModel *model;
149   EmpathyIrcNetwork *network;
150   gchar *name;
151
152   /* name could be changed */
153   gtk_combo_box_get_active_iter (GTK_COMBO_BOX (settings->combobox_network),
154       &iter);
155   model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
156   gtk_tree_model_get (model, &iter, COL_NETWORK_OBJ, &network, -1);
157
158   g_object_get (network, "name", &name, NULL);
159   gtk_list_store_set (GTK_LIST_STORE (model), &iter,
160       COL_NETWORK_NAME, name, -1);
161
162   update_server_params (settings);
163   empathy_account_widget_changed (settings->self);
164
165   g_object_unref (network);
166   g_free (name);
167 }
168
169 static void
170 display_irc_network_dialog (EmpathyAccountWidgetIrc *settings,
171                             EmpathyIrcNetwork *network)
172 {
173   GtkWindow *window;
174   GtkWidget *dialog;
175
176   window = empathy_get_toplevel_window (settings->vbox_settings);
177   dialog = empathy_irc_network_dialog_show (network, GTK_WIDGET (window));
178   g_signal_connect (dialog, "destroy",
179       G_CALLBACK (irc_network_dialog_destroy_cb), settings);
180 }
181
182 static void
183 account_widget_irc_button_edit_network_clicked_cb (
184     GtkWidget *button,
185     EmpathyAccountWidgetIrc *settings)
186 {
187   GtkTreeIter iter;
188   GtkTreeModel *model;
189   EmpathyIrcNetwork *network;
190
191   gtk_combo_box_get_active_iter (GTK_COMBO_BOX (settings->combobox_network),
192       &iter);
193   model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
194   gtk_tree_model_get (model, &iter, COL_NETWORK_OBJ, &network, -1);
195
196   g_assert (network != NULL);
197
198   display_irc_network_dialog (settings, network);
199
200   g_object_unref (network);
201 }
202
203 static void
204 account_widget_irc_button_remove_clicked_cb (GtkWidget *button,
205                                              EmpathyAccountWidgetIrc *settings)
206 {
207   EmpathyIrcNetwork *network;
208   GtkTreeIter iter;
209   GtkTreeModel *model;
210   gchar *name;
211
212   gtk_combo_box_get_active_iter (GTK_COMBO_BOX (settings->combobox_network),
213       &iter);
214   model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
215   gtk_tree_model_get (model, &iter, COL_NETWORK_OBJ, &network, -1);
216
217   g_assert (network != NULL);
218
219   g_object_get (network, "name", &name, NULL);
220   DEBUG ("Remove network %s", name);
221
222   gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
223   empathy_irc_network_manager_remove (settings->network_manager, network);
224
225   /* Select the first network */
226   if (gtk_tree_model_get_iter_first (model, &iter))
227     {
228       gtk_combo_box_set_active_iter (
229           GTK_COMBO_BOX (settings->combobox_network), &iter);
230     }
231
232   g_free (name);
233   g_object_unref (network);
234 }
235
236 static void
237 account_widget_irc_button_add_network_clicked_cb (GtkWidget *button,
238                                                   EmpathyAccountWidgetIrc *settings)
239 {
240   EmpathyIrcNetwork *network;
241   GtkTreeModel *model;
242   GtkListStore *store;
243   gchar *name;
244   GtkTreeIter iter;
245
246   network = empathy_irc_network_new (_("New Network"));
247   empathy_irc_network_manager_add (settings->network_manager, network);
248
249   model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
250   store = GTK_LIST_STORE (model);
251
252   g_object_get (network, "name", &name, NULL);
253
254   gtk_list_store_insert_with_values (store, &iter, -1,
255       COL_NETWORK_OBJ, network,
256       COL_NETWORK_NAME, name,
257       -1);
258
259   gtk_combo_box_set_active_iter (GTK_COMBO_BOX (settings->combobox_network),
260       &iter);
261
262   display_irc_network_dialog (settings, network);
263
264   g_free (name);
265   g_object_unref (network);
266 }
267
268 static void
269 account_widget_irc_combobox_network_changed_cb (GtkWidget *combobox,
270                                                 EmpathyAccountWidgetIrc *settings)
271 {
272   update_server_params (settings);
273   empathy_account_widget_changed (settings->self);
274 }
275
276 static void
277 fill_networks_model (EmpathyAccountWidgetIrc *settings,
278                      EmpathyIrcNetwork *network_to_select)
279 {
280   GSList *networks, *l;
281   GtkTreeModel *model;
282   GtkListStore *store;
283
284   networks = empathy_irc_network_manager_get_networks (
285       settings->network_manager);
286
287   model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
288   store = GTK_LIST_STORE (model);
289
290   for (l = networks; l != NULL; l = g_slist_next (l))
291     {
292       gchar *name;
293       EmpathyIrcNetwork *network = l->data;
294       GtkTreeIter iter;
295
296       g_object_get (network, "name", &name, NULL);
297
298       gtk_list_store_insert_with_values (store, &iter, -1,
299           COL_NETWORK_OBJ, network,
300           COL_NETWORK_NAME, name,
301           -1);
302
303        if (network == network_to_select)
304          {
305            gtk_combo_box_set_active_iter (
306                GTK_COMBO_BOX (settings->combobox_network), &iter);
307          }
308
309       g_free (name);
310       g_object_unref (network);
311     }
312
313   if (network_to_select == NULL)
314     {
315       /* Select the first network */
316       GtkTreeIter iter;
317
318       if (gtk_tree_model_get_iter_first (model, &iter))
319         {
320           gtk_combo_box_set_active_iter (
321               GTK_COMBO_BOX (settings->combobox_network), &iter);
322
323           update_server_params (settings);
324         }
325     }
326
327   g_slist_free (networks);
328 }
329
330 static void
331 account_widget_irc_setup (EmpathyAccountWidgetIrc *settings)
332 {
333   const gchar *nick = NULL;
334   const gchar *fullname = NULL;
335   const gchar *server = NULL;
336   gint port = 6667;
337   const gchar *charset;
338   gboolean ssl = FALSE;
339   EmpathyIrcNetwork *network = NULL;
340   EmpathyAccountSettings *ac_settings;
341
342   g_object_get (settings->self, "settings", &ac_settings, NULL);
343
344   nick = empathy_account_settings_get_string (ac_settings, "account");
345   fullname = empathy_account_settings_get_string (ac_settings,
346       "fullname");
347   server = empathy_account_settings_get_string (ac_settings, "server");
348   charset = empathy_account_settings_get_string (ac_settings, "charset");
349   port = empathy_account_settings_get_uint32 (ac_settings, "port");
350   ssl = empathy_account_settings_get_boolean (ac_settings, "use-ssl");
351
352   if (!nick)
353     {
354       nick = g_strdup (g_get_user_name ());
355       empathy_account_settings_set_string (ac_settings,
356         "account", nick);
357     }
358
359   if (!fullname)
360     {
361       fullname = g_strdup (g_get_real_name ());
362       if (!fullname)
363         {
364           fullname = g_strdup (nick);
365         }
366       empathy_account_settings_set_string (ac_settings,
367           "fullname", fullname);
368     }
369
370   if (server != NULL)
371     {
372       GtkListStore *store;
373
374       network = empathy_irc_network_manager_find_network_by_address (
375           settings->network_manager, server);
376
377
378       store = GTK_LIST_STORE (gtk_combo_box_get_model (
379             GTK_COMBO_BOX (settings->combobox_network)));
380
381       if (network != NULL)
382         {
383           gchar *name;
384
385           g_object_set (network, "charset", charset, NULL);
386
387           g_object_get (network, "name", &name, NULL);
388           DEBUG ("Account use network %s", name);
389
390           g_free (name);
391         }
392       else
393         {
394           /* We don't have this network. Let's create it */
395           EmpathyIrcServer *srv;
396           GtkTreeIter iter;
397
398           DEBUG ("Create a network %s", server);
399           network = empathy_irc_network_new (server);
400           srv = empathy_irc_server_new (server, port, ssl);
401
402           empathy_irc_network_append_server (network, srv);
403           empathy_irc_network_manager_add (settings->network_manager, network);
404
405           gtk_list_store_insert_with_values (store, &iter, -1,
406               COL_NETWORK_OBJ, network,
407               COL_NETWORK_NAME, server,
408               -1);
409
410           gtk_combo_box_set_active_iter (
411               GTK_COMBO_BOX (settings->combobox_network), &iter);
412
413           g_object_unref (srv);
414           g_object_unref (network);
415         }
416     }
417
418   if (network == NULL)
419     {
420       network = empathy_irc_network_manager_find_network_by_address (
421           settings->network_manager, DEFAULT_IRC_NETWORK);
422     }
423
424   fill_networks_model (settings, network);
425   update_server_params (settings);
426 }
427
428 void
429 empathy_account_widget_irc_build (EmpathyAccountWidget *self,
430     const char *filename,
431     GtkWidget **table_common_settings)
432 {
433   EmpathyAccountWidgetIrc *settings;
434   gchar *dir, *user_file_with_path, *global_file_with_path;
435   GtkListStore *store;
436   GtkCellRenderer *renderer;
437
438   settings = g_slice_new0 (EmpathyAccountWidgetIrc);
439   settings->self = self;
440
441   dir = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, NULL);
442   g_mkdir_with_parents (dir, S_IRUSR | S_IWUSR | S_IXUSR);
443   user_file_with_path = g_build_filename (dir, IRC_NETWORKS_FILENAME, NULL);
444   g_free (dir);
445
446   global_file_with_path = g_build_filename (g_getenv ("EMPATHY_SRCDIR"),
447       "libempathy", IRC_NETWORKS_FILENAME, NULL);
448   if (!g_file_test (global_file_with_path, G_FILE_TEST_EXISTS))
449     {
450       g_free (global_file_with_path);
451       global_file_with_path = g_build_filename (DATADIR, "empathy",
452           IRC_NETWORKS_FILENAME, NULL);
453     }
454
455   settings->network_manager = empathy_irc_network_manager_new (
456       global_file_with_path,
457       user_file_with_path);
458
459   g_free (global_file_with_path);
460   g_free (user_file_with_path);
461
462   self->ui_details->gui = empathy_builder_get_file (filename,
463       "table_irc_settings", table_common_settings,
464       "vbox_irc", &self->ui_details->widget,
465       "table_irc_settings", &settings->vbox_settings,
466       "combobox_network", &settings->combobox_network,
467       NULL);
468
469   /* Fill the networks combobox */
470   store = gtk_list_store_new (2, G_TYPE_OBJECT, G_TYPE_STRING);
471
472   gtk_cell_layout_clear (GTK_CELL_LAYOUT (settings->combobox_network));
473   renderer = gtk_cell_renderer_text_new ();
474   gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (settings->combobox_network),
475       renderer, TRUE);
476   gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (settings->combobox_network),
477       renderer,
478       "text", COL_NETWORK_NAME,
479       NULL);
480
481   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
482       COL_NETWORK_NAME,
483       GTK_SORT_ASCENDING);
484
485   gtk_combo_box_set_model (GTK_COMBO_BOX (settings->combobox_network),
486       GTK_TREE_MODEL (store));
487   g_object_unref (store);
488
489   account_widget_irc_setup (settings);
490
491   empathy_account_widget_handle_params (self,
492       "entry_nick", "account",
493       "entry_fullname", "fullname",
494       "entry_password", "password",
495       "entry_quit_message", "quit-message",
496       NULL);
497
498   empathy_builder_connect (self->ui_details->gui, settings,
499       "table_irc_settings", "destroy", account_widget_irc_destroy_cb,
500       "button_network", "clicked",
501           account_widget_irc_button_edit_network_clicked_cb,
502       "button_add_network", "clicked",
503           account_widget_irc_button_add_network_clicked_cb,
504       "button_remove_network", "clicked",
505           account_widget_irc_button_remove_clicked_cb,
506       "combobox_network", "changed",
507           account_widget_irc_combobox_network_changed_cb,
508       NULL);
509
510   self->ui_details->default_focus = g_strdup ("entry_nick");
511 }