]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-account-widget-irc.c
Make use of tp-glib debug system.
[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.h>
28 #include <gtk/gtk.h>
29 #include <glade/glade.h>
30
31 #include <libmissioncontrol/mc-account.h>
32 #include <libmissioncontrol/mc-protocol.h>
33
34 #include <libempathy/empathy-utils.h>
35 #include <libempathy/empathy-irc-network-manager.h>
36
37 #include "empathy-irc-network-dialog.h"
38 #include "empathy-account-widget.h"
39 #include "empathy-account-widget-irc.h"
40 #include "empathy-ui-utils.h"
41
42 #define DEBUG_FLAG EMPATHY_DEBUG_ACCOUNT | EMPATHY_DEBUG_IRC
43 #include <libempathy/empathy-debug.h>
44
45 #define IRC_NETWORKS_FILENAME "irc-networks.xml"
46
47 typedef struct {
48   McAccount *account;
49   EmpathyIrcNetworkManager *network_manager;
50
51   GtkWidget *vbox_settings;
52
53   GtkWidget *combobox_network;
54   GtkWidget *button_add_network;
55   GtkWidget *button_network;
56   GtkWidget *button_remove;
57 } EmpathyAccountWidgetIrc;
58
59 enum {
60   COL_NETWORK_OBJ,
61   COL_NETWORK_NAME,
62 };
63
64 static void
65 account_widget_irc_destroy_cb (GtkWidget *widget,
66                                EmpathyAccountWidgetIrc *settings)
67 {
68   g_object_unref (settings->network_manager);
69   g_object_unref (settings->account);
70   g_slice_free (EmpathyAccountWidgetIrc, settings);
71 }
72
73 static void
74 unset_server_params (EmpathyAccountWidgetIrc *settings)
75 {
76   DEBUG ("Unset server, port and use-ssl");
77   mc_account_unset_param (settings->account, "server");
78   mc_account_unset_param (settings->account, "port");
79   mc_account_unset_param (settings->account, "use-ssl");
80 }
81
82 static void
83 update_server_params (EmpathyAccountWidgetIrc *settings)
84 {
85   GtkTreeIter iter;
86   GtkTreeModel *model;
87   EmpathyIrcNetwork *network;
88   GSList *servers;
89   gchar *charset;
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   mc_account_set_param_string (settings->account, "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       mc_account_set_param_string (settings->account, "server", address);
125       DEBUG ("Setting port to %u", port);
126       mc_account_set_param_int (settings->account, "port", port);
127       DEBUG ("Setting use-ssl to %s", ssl ? "TRUE": "FALSE" );
128       mc_account_set_param_boolean (settings->account, "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
164   g_object_unref (network);
165   g_free (name);
166 }
167
168 static void
169 display_irc_network_dialog (EmpathyAccountWidgetIrc *settings,
170                             EmpathyIrcNetwork *network)
171 {
172   GtkWindow *window;
173   GtkWidget *dialog;
174
175   window = empathy_get_toplevel_window (settings->vbox_settings);
176   dialog = empathy_irc_network_dialog_show (network, GTK_WIDGET (window));
177   g_signal_connect (dialog, "destroy",
178       G_CALLBACK (irc_network_dialog_destroy_cb), settings);
179 }
180
181 static void
182 account_widget_irc_button_edit_network_clicked_cb (
183     GtkWidget *button,
184     EmpathyAccountWidgetIrc *settings)
185 {
186   GtkTreeIter iter;
187   GtkTreeModel *model;
188   EmpathyIrcNetwork *network;
189
190   gtk_combo_box_get_active_iter (GTK_COMBO_BOX (settings->combobox_network),
191       &iter);
192   model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
193   gtk_tree_model_get (model, &iter, COL_NETWORK_OBJ, &network, -1);
194
195   g_assert (network != NULL);
196
197   display_irc_network_dialog (settings, network);
198
199   g_object_unref (network);
200 }
201
202 static void
203 account_widget_irc_button_remove_clicked_cb (GtkWidget *button,
204                                              EmpathyAccountWidgetIrc *settings)
205 {
206   EmpathyIrcNetwork *network;
207   GtkTreeIter iter;
208   GtkTreeModel *model;
209   gchar *name;
210
211   gtk_combo_box_get_active_iter (GTK_COMBO_BOX (settings->combobox_network),
212       &iter);
213   model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
214   gtk_tree_model_get (model, &iter, COL_NETWORK_OBJ, &network, -1);
215
216   g_assert (network != NULL);
217
218   g_object_get (network, "name", &name, NULL);
219   DEBUG ("Remove network %s", name);
220
221   gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
222   empathy_irc_network_manager_remove (settings->network_manager, network);
223
224   /* Select the first network */
225   if (gtk_tree_model_get_iter_first (model, &iter))
226     {
227       gtk_combo_box_set_active_iter (
228           GTK_COMBO_BOX (settings->combobox_network), &iter);
229     }
230
231   g_free (name);
232   g_object_unref (network);
233 }
234
235 static void
236 account_widget_irc_button_add_network_clicked_cb (GtkWidget *button,
237                                                   EmpathyAccountWidgetIrc *settings)
238 {
239   EmpathyIrcNetwork *network;
240   GtkTreeModel *model;
241   GtkListStore *store;
242   gchar *name;
243   GtkTreeIter iter;
244
245   network = empathy_irc_network_new (_("New Network"));
246   empathy_irc_network_manager_add (settings->network_manager, network);
247
248   model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
249   store = GTK_LIST_STORE (model);
250
251   g_object_get (network, "name", &name, NULL);
252
253   gtk_list_store_insert_with_values (store, &iter, -1,
254       COL_NETWORK_OBJ, network,
255       COL_NETWORK_NAME, name,
256       -1);
257
258   gtk_combo_box_set_active_iter (GTK_COMBO_BOX (settings->combobox_network),
259       &iter);
260
261   display_irc_network_dialog (settings, network);
262
263   g_free (name);
264   g_object_unref (network);
265 }
266
267 static void
268 account_widget_irc_combobox_network_changed_cb (GtkWidget *combobox,
269                                                 EmpathyAccountWidgetIrc *settings)
270 {
271   update_server_params (settings);
272 }
273
274 static void
275 fill_networks_model (EmpathyAccountWidgetIrc *settings,
276                      EmpathyIrcNetwork *network_to_select)
277 {
278   GSList *networks, *l;
279   GtkTreeModel *model;
280   GtkListStore *store;
281
282   networks = empathy_irc_network_manager_get_networks (
283       settings->network_manager);
284
285   model = gtk_combo_box_get_model (GTK_COMBO_BOX (settings->combobox_network));
286   store = GTK_LIST_STORE (model);
287
288   for (l = networks; l != NULL; l = g_slist_next (l))
289     {
290       gchar *name;
291       EmpathyIrcNetwork *network = l->data;
292       GtkTreeIter iter;
293
294       g_object_get (network, "name", &name, NULL);
295
296       gtk_list_store_insert_with_values (store, &iter, -1,
297           COL_NETWORK_OBJ, network,
298           COL_NETWORK_NAME, name,
299           -1);
300
301        if (network == network_to_select)
302          {
303            gtk_combo_box_set_active_iter (
304                GTK_COMBO_BOX (settings->combobox_network), &iter);
305          }
306
307       g_free (name);
308       g_object_unref (network);
309     }
310
311   if (network_to_select == NULL)
312     {
313       /* Select the first network */
314       GtkTreeIter iter;
315
316       if (gtk_tree_model_get_iter_first (model, &iter))
317         {
318           gtk_combo_box_set_active_iter (
319               GTK_COMBO_BOX (settings->combobox_network), &iter);
320
321           update_server_params (settings);
322         }
323     }
324
325   g_slist_free (networks);
326 }
327
328 static void
329 account_widget_irc_setup (EmpathyAccountWidgetIrc *settings)
330 {
331   gchar *nick = NULL;
332   gchar *fullname = NULL;
333   gchar *server = NULL;
334   gint port = 6667;
335   gchar *charset;
336   gboolean ssl = FALSE;
337   EmpathyIrcNetwork *network = NULL;
338
339   mc_account_get_param_string (settings->account, "account", &nick);
340   mc_account_get_param_string (settings->account, "fullname", &fullname);
341   mc_account_get_param_string (settings->account, "server", &server);
342   mc_account_get_param_string (settings->account, "charset", &charset);
343   mc_account_get_param_int (settings->account, "port", &port);
344   mc_account_get_param_boolean (settings->account, "use-ssl", &ssl);
345
346   if (!nick)
347     {
348       nick = g_strdup (g_get_user_name ());
349       mc_account_set_param_string (settings->account, "account", nick);
350     }
351
352   if (!fullname)
353     {
354       fullname = g_strdup (g_get_real_name ());
355       if (!fullname)
356         {
357           fullname = g_strdup (nick);
358         }
359       mc_account_set_param_string (settings->account, "fullname", fullname);
360     }
361
362   if (server != NULL)
363     {
364       GtkListStore *store;
365
366       network = empathy_irc_network_manager_find_network_by_address (
367           settings->network_manager, server);
368
369
370       store = GTK_LIST_STORE (gtk_combo_box_get_model (
371             GTK_COMBO_BOX (settings->combobox_network)));
372
373       if (network != NULL)
374         {
375           gchar *name;
376
377           g_object_set (network, "charset", charset, NULL);
378
379           g_object_get (network, "name", &name, NULL);
380           DEBUG ("Account use network %s", name);
381
382           g_free (name);
383         }
384       else
385         {
386           /* We don't have this network. Let's create it */
387           EmpathyIrcServer *srv;
388           GtkTreeIter iter;
389
390           DEBUG ("Create a network %s", server);
391           network = empathy_irc_network_new (server);
392           srv = empathy_irc_server_new (server, port, ssl);
393
394           empathy_irc_network_append_server (network, srv);
395           empathy_irc_network_manager_add (settings->network_manager, network);
396
397           gtk_list_store_insert_with_values (store, &iter, -1,
398               COL_NETWORK_OBJ, network,
399               COL_NETWORK_NAME, server,
400               -1);
401
402           gtk_combo_box_set_active_iter (
403               GTK_COMBO_BOX (settings->combobox_network), &iter);
404
405           g_object_unref (srv);
406           g_object_unref (network);
407         }
408     }
409
410
411   fill_networks_model (settings, network);
412
413   g_free (nick);
414   g_free (fullname);
415   g_free (server);
416   g_free (charset);
417 }
418
419 /**
420  * empathy_account_widget_irc_new:
421  * @account: the #McAccount to configure
422  *
423  * Creates a new IRC account widget to configure a given #McAccount
424  *
425  * Returns: The toplevel container of the configuration widget
426  */
427 GtkWidget *
428 empathy_account_widget_irc_new (McAccount *account)
429 {
430   EmpathyAccountWidgetIrc *settings;
431   gchar *dir, *user_file_with_path, *global_file_with_path;
432   GladeXML *glade;
433   GtkListStore *store;
434   GtkCellRenderer *renderer;
435   gchar *filename;
436
437   settings = g_slice_new0 (EmpathyAccountWidgetIrc);
438   settings->account = g_object_ref (account);
439
440   dir = g_build_filename (g_get_home_dir (), ".gnome2", PACKAGE_NAME, NULL);
441   g_mkdir_with_parents (dir, S_IRUSR | S_IWUSR | S_IXUSR);
442   user_file_with_path = g_build_filename (dir, IRC_NETWORKS_FILENAME, NULL);
443   g_free (dir);
444
445   global_file_with_path = g_build_filename (g_getenv ("EMPATHY_SRCDIR"),
446       "libempathy-gtk", IRC_NETWORKS_FILENAME, NULL);
447   if (!g_file_test (global_file_with_path, G_FILE_TEST_EXISTS))
448     {
449       g_free (global_file_with_path);
450       global_file_with_path = g_build_filename (DATADIR, "empathy",
451           IRC_NETWORKS_FILENAME, NULL);
452     }
453
454   settings->network_manager = empathy_irc_network_manager_new (
455       global_file_with_path,
456       user_file_with_path);
457
458   g_free (global_file_with_path);
459   g_free (user_file_with_path);
460
461   filename = empathy_file_lookup ("empathy-account-widget-irc.glade",
462       "libempathy-gtk");
463   glade = empathy_glade_get_file (filename,
464       "vbox_irc_settings",
465       NULL,
466       "vbox_irc_settings", &settings->vbox_settings,
467       "combobox_network", &settings->combobox_network,
468       "button_network", &settings->button_network,
469       "button_add_network", &settings->button_add_network,
470       "button_remove", &settings->button_remove,
471       NULL);
472   g_free (filename);
473
474   /* Fill the networks combobox */
475   store = gtk_list_store_new (2, G_TYPE_OBJECT, G_TYPE_STRING);
476
477   gtk_cell_layout_clear (GTK_CELL_LAYOUT (settings->combobox_network)); 
478   renderer = gtk_cell_renderer_text_new ();
479   gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (settings->combobox_network),
480       renderer, TRUE);
481   gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (settings->combobox_network),
482       renderer,
483       "text", COL_NETWORK_NAME,
484       NULL);
485
486   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (store),
487       COL_NETWORK_NAME,
488       GTK_SORT_ASCENDING);
489
490   gtk_combo_box_set_model (GTK_COMBO_BOX (settings->combobox_network),
491       GTK_TREE_MODEL (store));
492   g_object_unref (store);
493
494   account_widget_irc_setup (settings);
495
496   empathy_account_widget_handle_params (account, glade,
497       "entry_nick", "account",
498       "entry_fullname", "fullname",
499       "entry_password", "password",
500       "entry_quit_message", "quit-message",
501       NULL);
502
503   empathy_glade_connect (glade, settings,
504       "vbox_irc_settings", "destroy", account_widget_irc_destroy_cb,
505       "button_network", "clicked", account_widget_irc_button_edit_network_clicked_cb,
506       "button_add_network", "clicked", account_widget_irc_button_add_network_clicked_cb,
507       "button_remove", "clicked", account_widget_irc_button_remove_clicked_cb,
508       "combobox_network", "changed", account_widget_irc_combobox_network_changed_cb,
509       NULL);
510
511   g_object_unref (glade);
512
513   return settings->vbox_settings;
514 }