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