]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-irc-network-dialog.c
Updated Basque language
[empathy.git] / libempathy-gtk / empathy-irc-network-dialog.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-account.h>
32
33 #include <libempathy/empathy-irc-network-manager.h>
34 #include "empathy-ui-utils.h"
35 #include "totem-subtitle-encoding.h"
36
37 #include "empathy-irc-network-dialog.h"
38
39 typedef struct {
40   EmpathyIrcNetwork *network;
41
42   GtkWidget *dialog;
43   GtkWidget *button_close;
44
45   GtkWidget *entry_network;
46   GtkWidget *combobox_charset;
47
48   GtkWidget *treeview_servers;
49   GtkWidget *button_add;
50   GtkWidget *button_remove;
51   GtkWidget *button_up;
52   GtkWidget *button_down;
53 } EmpathyIrcNetworkDialog;
54
55 static void
56 irc_network_dialog_destroy_cb (GtkWidget *widget,
57                                EmpathyIrcNetworkDialog *dialog)
58 {
59   g_object_unref (dialog->network);
60
61   g_slice_free (EmpathyIrcNetworkDialog, dialog);
62 }
63
64 static void
65 irc_network_dialog_close_clicked_cb (GtkWidget *widget,
66                                      EmpathyIrcNetworkDialog *dialog)
67 {
68   gtk_widget_destroy (dialog->dialog);
69 }
70
71 enum {
72   COL_SRV_OBJ,
73   COL_ADR,
74   COL_PORT,
75   COL_SSL
76 };
77
78 static void
79 add_server_to_store (GtkListStore *store,
80                      EmpathyIrcServer *server,
81                      GtkTreeIter *iter)
82 {
83   gchar *address;
84   guint port;
85   gboolean ssl;
86
87   g_object_get (server,
88       "address", &address,
89       "port", &port,
90       "ssl", &ssl,
91       NULL);
92
93   gtk_list_store_insert_with_values (store, iter, -1,
94       COL_SRV_OBJ, server,
95       COL_ADR, address,
96       COL_PORT, port,
97       COL_SSL, ssl,
98       -1);
99
100   g_free (address);
101 }
102
103 static void
104 irc_network_dialog_setup (EmpathyIrcNetworkDialog *dialog)
105 {
106   gchar *name, *charset;
107   GSList *servers, *l;
108   GtkListStore *store;
109
110   g_object_get (dialog->network,
111       "name", &name,
112       "charset", &charset,
113       NULL);
114   gtk_entry_set_text (GTK_ENTRY (dialog->entry_network), name);
115
116   store = GTK_LIST_STORE (gtk_tree_view_get_model (
117         GTK_TREE_VIEW (dialog->treeview_servers)));
118
119   servers = empathy_irc_network_get_servers (dialog->network);
120   for (l = servers; l != NULL; l = g_slist_next (l))
121     {
122       EmpathyIrcServer *server = l->data;
123       GtkTreeIter iter;
124
125       add_server_to_store (store, server, &iter);
126     }
127
128   totem_subtitle_encoding_set (GTK_COMBO_BOX (dialog->combobox_charset),
129       charset);
130
131   g_slist_foreach (servers, (GFunc) g_object_unref, NULL);
132   g_slist_free (servers);
133   g_free (name);
134   g_free (charset);
135 }
136
137 static void
138 irc_network_dialog_address_edited_cb (GtkCellRendererText *renderer,
139                                       gchar *path,
140                                       gchar *new_text,
141                                       EmpathyIrcNetworkDialog *dialog)
142 {
143   EmpathyIrcServer *server;
144   GtkTreeModel *model;
145   GtkTreePath  *treepath;
146   GtkTreeIter iter;
147
148   model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview_servers));
149   treepath = gtk_tree_path_new_from_string (path);
150   gtk_tree_model_get_iter (model, &iter, treepath);
151   gtk_tree_model_get (model, &iter,
152       COL_SRV_OBJ, &server,
153       -1);
154   gtk_list_store_set (GTK_LIST_STORE (model), &iter,
155       COL_ADR, new_text,
156       -1);
157
158   g_object_set (server, "address", new_text, NULL);
159
160   gtk_tree_path_free (treepath);
161   g_object_unref (server);
162 }
163
164 static void
165 irc_network_dialog_port_edited_cb (GtkCellRendererText *renderer,
166                                    gchar *path,
167                                    gchar *new_text,
168                                    EmpathyIrcNetworkDialog *dialog)
169 {
170   EmpathyIrcServer *server;
171   GtkTreeModel *model;
172   GtkTreePath  *treepath;
173   GtkTreeIter iter;
174   guint port;
175
176   port = strtoul (new_text, NULL, 10);
177   model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview_servers));
178   treepath = gtk_tree_path_new_from_string (path);
179   gtk_tree_model_get_iter (model, &iter, treepath);
180   gtk_tree_model_get (model, &iter,
181       COL_SRV_OBJ, &server,
182       -1);
183   gtk_list_store_set (GTK_LIST_STORE (model), &iter,
184       COL_PORT, port,
185       -1);
186
187   g_object_set (server, "port", port, NULL);
188
189   gtk_tree_path_free (treepath);
190   g_object_unref (server);
191 }
192
193 static void
194 irc_network_dialog_ssl_toggled_cb (GtkCellRendererText *renderer,
195                                    gchar *path,
196                                    EmpathyIrcNetworkDialog *dialog)
197 {
198   EmpathyIrcServer *server;
199   GtkTreeModel *model;
200   GtkTreePath  *treepath;
201   GtkTreeIter iter;
202   gboolean ssl;
203
204   model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview_servers));
205   treepath = gtk_tree_path_new_from_string (path);
206   gtk_tree_model_get_iter (model, &iter, treepath);
207   gtk_tree_model_get (model, &iter,
208       COL_SRV_OBJ, &server,
209       COL_SSL, &ssl,
210       -1);
211   ssl = !ssl;
212   gtk_list_store_set (GTK_LIST_STORE (model), &iter,
213       COL_SSL, ssl,
214       -1);
215
216   g_object_set (server, "ssl", ssl, NULL);
217
218   gtk_tree_path_free (treepath);
219   g_object_unref (server);
220 }
221
222 static gboolean
223 irc_network_dialog_network_focus_cb (GtkWidget *widget,
224                                      GdkEventFocus *event,
225                                      EmpathyIrcNetworkDialog *dialog)
226 {
227   const gchar *str;
228
229   str = gtk_entry_get_text (GTK_ENTRY (widget));
230
231   g_object_set (dialog->network, "name", str, NULL);
232
233   return FALSE;
234 }
235
236 static void
237 irc_network_dialog_network_update_buttons (EmpathyIrcNetworkDialog *dialog)
238 {
239   GtkTreeSelection *selection;
240   GtkTreeModel *model;
241   GtkTreePath *path;
242   GtkTreeIter iter;
243   gboolean can_remove = FALSE, can_move_up = FALSE, can_move_down = FALSE;
244   int selected;
245
246   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (
247         dialog->treeview_servers));
248
249   if (gtk_tree_selection_get_selected (selection, &model, &iter))
250   {
251     path = gtk_tree_model_get_path (model, &iter);
252
253     selected = gtk_tree_path_get_indices (path)[0];
254
255     can_remove = TRUE;
256     can_move_up = selected > 0;
257     can_move_down =
258       selected < gtk_tree_model_iter_n_children (model, NULL) - 1;
259
260     gtk_tree_path_free (path);
261   }
262
263   gtk_widget_set_sensitive (dialog->button_remove, can_remove);
264   gtk_widget_set_sensitive (dialog->button_up, can_move_up);
265   gtk_widget_set_sensitive (dialog->button_down, can_move_down);
266 }
267
268 static void
269 irc_network_dialog_button_add_clicked_cb (GtkWidget *widget,
270                                           EmpathyIrcNetworkDialog *dialog)
271 {
272   EmpathyIrcServer *server;
273   GtkListStore *store;
274   GtkTreeIter iter;
275   GtkTreePath *path;
276   GtkTreeViewColumn *column;
277
278   store = GTK_LIST_STORE (gtk_tree_view_get_model (
279         GTK_TREE_VIEW (dialog->treeview_servers)));
280
281   server = empathy_irc_server_new (_("new server"), 6667, FALSE);
282   empathy_irc_network_append_server (dialog->network, server);
283   add_server_to_store (store, server, &iter);
284
285   path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
286   column = gtk_tree_view_get_column (GTK_TREE_VIEW (dialog->treeview_servers),
287       0);
288   gtk_tree_view_set_cursor (GTK_TREE_VIEW (dialog->treeview_servers), path,
289       column, TRUE);
290
291   irc_network_dialog_network_update_buttons (dialog);
292
293   gtk_tree_path_free (path);
294   g_object_unref (server);
295 }
296
297 static void
298 irc_network_dialog_button_remove_clicked_cb (GtkWidget *widget,
299                                              EmpathyIrcNetworkDialog *dialog)
300 {
301   GtkTreeSelection *selection;
302   GtkTreeModel *model;
303   GtkTreeIter iter;
304   EmpathyIrcServer *server;
305
306   selection = gtk_tree_view_get_selection (
307       GTK_TREE_VIEW (dialog->treeview_servers));
308
309   if (!gtk_tree_selection_get_selected (selection, &model, &iter))
310     return;
311
312   gtk_tree_model_get (model, &iter, COL_SRV_OBJ, &server, -1);
313
314   gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
315   empathy_irc_network_remove_server (dialog->network, server);
316
317   irc_network_dialog_network_update_buttons (dialog);
318
319   g_object_unref (server);
320 }
321
322 static void
323 irc_network_dialog_button_up_clicked_cb (GtkWidget *widget,
324                                          EmpathyIrcNetworkDialog *dialog)
325 {
326   GtkTreeSelection *selection;
327   GtkTreeModel *model;
328   GtkTreeIter iter, iter_prev;
329   GtkTreePath *path;
330   gint *pos;
331   EmpathyIrcServer *server;
332
333   selection = gtk_tree_view_get_selection (
334       GTK_TREE_VIEW (dialog->treeview_servers));
335
336   if (!gtk_tree_selection_get_selected (selection, &model, &iter))
337     return;
338
339   path = gtk_tree_model_get_path (model, &iter);
340
341   if (!gtk_tree_path_prev (path))
342   {
343     gtk_tree_path_free (path);
344     return;
345   }
346
347   gtk_tree_model_get (model, &iter, COL_SRV_OBJ, &server, -1);
348
349   gtk_tree_model_get_iter (model, &iter_prev, path);
350   gtk_list_store_swap (GTK_LIST_STORE (model), &iter_prev, &iter);
351
352   pos = gtk_tree_path_get_indices (path);
353   empathy_irc_network_set_server_position (dialog->network, server, *pos);
354
355   irc_network_dialog_network_update_buttons (dialog);
356
357   g_object_unref (server);
358   gtk_tree_path_free (path);
359 }
360
361 static void
362 irc_network_dialog_button_down_clicked_cb (GtkWidget *widget,
363                                            EmpathyIrcNetworkDialog *dialog)
364 {
365   GtkTreeSelection *selection;
366   GtkTreeModel *model;
367   GtkTreeIter iter, iter_prev;
368   GtkTreePath *path;
369   EmpathyIrcServer *server;
370   gint *pos;
371
372   selection = gtk_tree_view_get_selection (
373       GTK_TREE_VIEW (dialog->treeview_servers));
374
375   if (!gtk_tree_selection_get_selected (selection, &model, &iter))
376     return;
377
378   path = gtk_tree_model_get_path (model, &iter);
379
380   gtk_tree_path_next (path);
381   if (!gtk_tree_model_get_iter (model, &iter_prev, path))
382     {
383       gtk_tree_path_free (path);
384       return;
385     }
386
387   gtk_tree_model_get (model, &iter, COL_SRV_OBJ, &server, -1);
388
389   gtk_list_store_swap (GTK_LIST_STORE (model), &iter_prev, &iter);
390
391   pos = gtk_tree_path_get_indices (path);
392   empathy_irc_network_set_server_position (dialog->network, server, *pos);
393
394   irc_network_dialog_network_update_buttons (dialog);
395
396   gtk_tree_path_free (path);
397 }
398
399 static void
400 irc_network_dialog_selection_changed_cb (GtkTreeSelection  *treeselection,
401                                          EmpathyIrcNetworkDialog *dialog)
402 {
403   irc_network_dialog_network_update_buttons (dialog);
404 }
405
406 static void
407 irc_network_dialog_combobox_charset_changed_cb (GtkWidget *combobox,
408                                                 EmpathyIrcNetworkDialog *dialog)
409 {
410   const gchar *charset;
411
412   charset = totem_subtitle_encoding_get_selected (GTK_COMBO_BOX (combobox));
413   g_object_set (dialog->network, "charset", charset, NULL);
414 }
415
416 static void
417 change_network (EmpathyIrcNetworkDialog *dialog,
418                 EmpathyIrcNetwork *network)
419 {
420   GtkListStore *store;
421
422   if (dialog->network == network)
423     /* No need to change */
424     return;
425
426   if (dialog->network != NULL)
427     {
428       g_object_unref (dialog->network);
429     }
430
431   dialog->network = network;
432   g_object_ref (network);
433
434   store = GTK_LIST_STORE (gtk_tree_view_get_model (
435         GTK_TREE_VIEW (dialog->treeview_servers)));
436   gtk_list_store_clear (store);
437
438   irc_network_dialog_setup (dialog);
439 }
440
441 /**
442  * empathy_irc_network_dialog_show:
443  * @network: the #EmpathyIrcNetwork to configure
444  * @parent: the parent of this dialog
445  *
446  * Display a dialog to configure a given #EmpathyIrcNetwork.
447  * This function is a singleton so if a configuration dialog already
448  * exists we use this one to edit the network.
449  *
450  * Returns: The displayed #GtkDialog
451  */
452 GtkWidget *
453 empathy_irc_network_dialog_show (EmpathyIrcNetwork *network,
454                                  GtkWidget *parent)
455 {
456   static EmpathyIrcNetworkDialog *dialog = NULL;
457   GtkBuilder *gui;
458   GtkListStore *store;
459   GtkCellRenderer *renderer;
460   GtkAdjustment *adjustment;
461   GtkTreeSelection *selection;
462   GtkTreeViewColumn *column;
463   gchar *filename;
464
465   g_return_val_if_fail (network != NULL, NULL);
466
467   if (dialog != NULL)
468     {
469       change_network (dialog, network);
470       gtk_window_present (GTK_WINDOW (dialog->dialog));
471
472       return dialog->dialog;
473     }
474
475   dialog = g_slice_new0 (EmpathyIrcNetworkDialog);
476
477   dialog->network = network;
478   g_object_ref (dialog->network);
479
480   filename = empathy_file_lookup ("empathy-account-widget-irc.ui",
481       "libempathy-gtk");
482   gui = empathy_builder_get_file (filename,
483       "irc_network_dialog", &dialog->dialog,
484       "button_close", &dialog->button_close,
485       "entry_network", &dialog->entry_network,
486       "combobox_charset", &dialog->combobox_charset,
487       "treeview_servers", &dialog->treeview_servers,
488       "button_add", &dialog->button_add,
489       "button_remove", &dialog->button_remove,
490       "button_up", &dialog->button_up,
491       "button_down", &dialog->button_down,
492       NULL);
493   g_free (filename);
494
495   store = gtk_list_store_new (4, G_TYPE_OBJECT, G_TYPE_STRING,
496       G_TYPE_UINT, G_TYPE_BOOLEAN);
497   gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->treeview_servers),
498       GTK_TREE_MODEL (store));
499   g_object_unref (store);
500
501   /* address */
502   renderer = gtk_cell_renderer_text_new ();
503   g_object_set (renderer, "editable", TRUE, NULL);
504   g_signal_connect (renderer, "edited",
505       G_CALLBACK (irc_network_dialog_address_edited_cb), dialog);
506   gtk_tree_view_insert_column_with_attributes (
507       GTK_TREE_VIEW (dialog->treeview_servers),
508       -1, _("Server"), renderer, "text", COL_ADR,
509       NULL);
510
511   /* port */
512   adjustment = (GtkAdjustment *) gtk_adjustment_new (6667, 1, G_MAXUINT16,
513       1, 10, 0);
514   renderer = gtk_cell_renderer_spin_new ();
515   g_object_set (renderer,
516       "editable", TRUE,
517       "adjustment", adjustment,
518       NULL);
519   g_signal_connect (renderer, "edited",
520       G_CALLBACK (irc_network_dialog_port_edited_cb), dialog);
521   gtk_tree_view_insert_column_with_attributes (
522       GTK_TREE_VIEW (dialog->treeview_servers),
523       -1, _("Port"), renderer, "text", COL_PORT,
524       NULL);
525   column = gtk_tree_view_get_column (GTK_TREE_VIEW (dialog->treeview_servers),
526       1);
527   gtk_tree_view_column_set_expand (column, TRUE);
528
529   /* SSL */
530   renderer = gtk_cell_renderer_toggle_new ();
531   g_object_set (renderer, "activatable", TRUE, NULL);
532   g_signal_connect (renderer, "toggled",
533       G_CALLBACK (irc_network_dialog_ssl_toggled_cb), dialog);
534   gtk_tree_view_insert_column_with_attributes (
535       GTK_TREE_VIEW (dialog->treeview_servers),
536       -1, _("SSL"), renderer, "active", COL_SSL,
537       NULL);
538
539   selection = gtk_tree_view_get_selection (
540       GTK_TREE_VIEW (dialog->treeview_servers));
541   gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
542
543   /* charset */
544   totem_subtitle_encoding_init (GTK_COMBO_BOX (dialog->combobox_charset));
545
546   irc_network_dialog_setup (dialog);
547
548   empathy_builder_connect (gui, dialog,
549       "irc_network_dialog", "destroy", irc_network_dialog_destroy_cb,
550       "button_close", "clicked", irc_network_dialog_close_clicked_cb,
551       "entry_network", "focus-out-event", irc_network_dialog_network_focus_cb,
552       "button_add", "clicked", irc_network_dialog_button_add_clicked_cb,
553       "button_remove", "clicked", irc_network_dialog_button_remove_clicked_cb,
554       "button_up", "clicked", irc_network_dialog_button_up_clicked_cb,
555       "button_down", "clicked", irc_network_dialog_button_down_clicked_cb,
556       "combobox_charset", "changed", irc_network_dialog_combobox_charset_changed_cb,
557       NULL);
558
559   g_object_unref (gui);
560
561   g_object_add_weak_pointer (G_OBJECT (dialog->dialog),
562       (gpointer) &dialog);
563
564   g_signal_connect (selection, "changed",
565       G_CALLBACK (irc_network_dialog_selection_changed_cb),
566       dialog);
567
568   gtk_window_set_transient_for (GTK_WINDOW (dialog->dialog),
569       GTK_WINDOW (parent));
570   gtk_window_set_modal (GTK_WINDOW (dialog->dialog), TRUE);
571
572   irc_network_dialog_network_update_buttons (dialog);
573   gtk_widget_show_all (dialog->dialog);
574
575   return dialog->dialog;
576 }