Break after deleting current item in chatroom list
[empathy-mirror.git] / libempathy-gtk / empathy-irc-network-dialog.c
blob63222badc0e9dbb832b83a0aceb91511e92b5c2c
1 /*
2 * Copyright (C) 2007-2008 Guillaume Desmottes
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.
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.
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
18 * Authors: Guillaume Desmottes <gdesmott@gnome.org>
21 #include "config.h"
23 #include <stdlib.h>
24 #include <string.h>
25 #include <sys/stat.h>
27 #include <glib/gi18n-lib.h>
28 #include <gtk/gtk.h>
30 #include <libmissioncontrol/mc-account.h>
31 #include <libmissioncontrol/mc-protocol.h>
33 #include <libempathy/empathy-utils.h>
35 #include <libempathy/empathy-irc-network-manager.h>
36 #include "empathy-ui-utils.h"
37 #include "totem-subtitle-encoding.h"
39 #include "empathy-irc-network-dialog.h"
41 typedef struct {
42 EmpathyIrcNetwork *network;
44 GtkWidget *dialog;
45 GtkWidget *button_close;
47 GtkWidget *entry_network;
48 GtkWidget *combobox_charset;
50 GtkWidget *treeview_servers;
51 GtkWidget *button_add;
52 GtkWidget *button_remove;
53 GtkWidget *button_up;
54 GtkWidget *button_down;
55 } EmpathyIrcNetworkDialog;
57 static void
58 irc_network_dialog_destroy_cb (GtkWidget *widget,
59 EmpathyIrcNetworkDialog *dialog)
61 g_object_unref (dialog->network);
63 g_slice_free (EmpathyIrcNetworkDialog, dialog);
66 static void
67 irc_network_dialog_close_clicked_cb (GtkWidget *widget,
68 EmpathyIrcNetworkDialog *dialog)
70 gtk_widget_destroy (dialog->dialog);
73 enum {
74 COL_SRV_OBJ,
75 COL_ADR,
76 COL_PORT,
77 COL_SSL
80 static void
81 add_server_to_store (GtkListStore *store,
82 EmpathyIrcServer *server,
83 GtkTreeIter *iter)
85 gchar *address;
86 guint port;
87 gboolean ssl;
89 g_object_get (server,
90 "address", &address,
91 "port", &port,
92 "ssl", &ssl,
93 NULL);
95 gtk_list_store_insert_with_values (store, iter, -1,
96 COL_SRV_OBJ, server,
97 COL_ADR, address,
98 COL_PORT, port,
99 COL_SSL, ssl,
100 -1);
102 g_free (address);
105 static void
106 irc_network_dialog_setup (EmpathyIrcNetworkDialog *dialog)
108 gchar *name, *charset;
109 GSList *servers, *l;
110 GtkListStore *store;
112 g_object_get (dialog->network,
113 "name", &name,
114 "charset", &charset,
115 NULL);
116 gtk_entry_set_text (GTK_ENTRY (dialog->entry_network), name);
118 store = GTK_LIST_STORE (gtk_tree_view_get_model (
119 GTK_TREE_VIEW (dialog->treeview_servers)));
121 servers = empathy_irc_network_get_servers (dialog->network);
122 for (l = servers; l != NULL; l = g_slist_next (l))
124 EmpathyIrcServer *server = l->data;
125 GtkTreeIter iter;
127 add_server_to_store (store, server, &iter);
130 totem_subtitle_encoding_set (GTK_COMBO_BOX (dialog->combobox_charset),
131 charset);
133 g_slist_foreach (servers, (GFunc) g_object_unref, NULL);
134 g_slist_free (servers);
135 g_free (name);
136 g_free (charset);
139 static void
140 irc_network_dialog_address_edited_cb (GtkCellRendererText *renderer,
141 gchar *path,
142 gchar *new_text,
143 EmpathyIrcNetworkDialog *dialog)
145 EmpathyIrcServer *server;
146 GtkTreeModel *model;
147 GtkTreePath *treepath;
148 GtkTreeIter iter;
150 model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview_servers));
151 treepath = gtk_tree_path_new_from_string (path);
152 gtk_tree_model_get_iter (model, &iter, treepath);
153 gtk_tree_model_get (model, &iter,
154 COL_SRV_OBJ, &server,
155 -1);
156 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
157 COL_ADR, new_text,
158 -1);
160 g_object_set (server, "address", new_text, NULL);
162 gtk_tree_path_free (treepath);
163 g_object_unref (server);
166 static void
167 irc_network_dialog_port_edited_cb (GtkCellRendererText *renderer,
168 gchar *path,
169 gchar *new_text,
170 EmpathyIrcNetworkDialog *dialog)
172 EmpathyIrcServer *server;
173 GtkTreeModel *model;
174 GtkTreePath *treepath;
175 GtkTreeIter iter;
176 guint port;
178 port = strtoul (new_text, NULL, 10);
179 model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview_servers));
180 treepath = gtk_tree_path_new_from_string (path);
181 gtk_tree_model_get_iter (model, &iter, treepath);
182 gtk_tree_model_get (model, &iter,
183 COL_SRV_OBJ, &server,
184 -1);
185 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
186 COL_PORT, port,
187 -1);
189 g_object_set (server, "port", port, NULL);
191 gtk_tree_path_free (treepath);
192 g_object_unref (server);
195 static void
196 irc_network_dialog_ssl_toggled_cb (GtkCellRendererText *renderer,
197 gchar *path,
198 EmpathyIrcNetworkDialog *dialog)
200 EmpathyIrcServer *server;
201 GtkTreeModel *model;
202 GtkTreePath *treepath;
203 GtkTreeIter iter;
204 gboolean ssl;
206 model = gtk_tree_view_get_model (GTK_TREE_VIEW (dialog->treeview_servers));
207 treepath = gtk_tree_path_new_from_string (path);
208 gtk_tree_model_get_iter (model, &iter, treepath);
209 gtk_tree_model_get (model, &iter,
210 COL_SRV_OBJ, &server,
211 COL_SSL, &ssl,
212 -1);
213 ssl = !ssl;
214 gtk_list_store_set (GTK_LIST_STORE (model), &iter,
215 COL_SSL, ssl,
216 -1);
218 g_object_set (server, "ssl", ssl, NULL);
220 gtk_tree_path_free (treepath);
221 g_object_unref (server);
224 static gboolean
225 irc_network_dialog_network_focus_cb (GtkWidget *widget,
226 GdkEventFocus *event,
227 EmpathyIrcNetworkDialog *dialog)
229 const gchar *str;
231 str = gtk_entry_get_text (GTK_ENTRY (widget));
233 g_object_set (dialog->network, "name", str, NULL);
235 return FALSE;
238 static void
239 irc_network_dialog_network_update_buttons (EmpathyIrcNetworkDialog *dialog)
241 GtkTreeSelection *selection;
242 GtkTreeModel *model;
243 GtkTreePath *path;
244 GtkTreeIter iter;
245 gboolean can_remove = FALSE, can_move_up = FALSE, can_move_down = FALSE;
246 int selected;
248 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (
249 dialog->treeview_servers));
251 if (gtk_tree_selection_get_selected (selection, &model, &iter))
253 path = gtk_tree_model_get_path (model, &iter);
255 selected = gtk_tree_path_get_indices (path)[0];
257 can_remove = TRUE;
258 can_move_up = selected > 0;
259 can_move_down =
260 selected < gtk_tree_model_iter_n_children (model, NULL) - 1;
262 gtk_tree_path_free (path);
265 gtk_widget_set_sensitive (dialog->button_remove, can_remove);
266 gtk_widget_set_sensitive (dialog->button_up, can_move_up);
267 gtk_widget_set_sensitive (dialog->button_down, can_move_down);
270 static void
271 irc_network_dialog_button_add_clicked_cb (GtkWidget *widget,
272 EmpathyIrcNetworkDialog *dialog)
274 EmpathyIrcServer *server;
275 GtkListStore *store;
276 GtkTreeIter iter;
277 GtkTreePath *path;
278 GtkTreeViewColumn *column;
280 store = GTK_LIST_STORE (gtk_tree_view_get_model (
281 GTK_TREE_VIEW (dialog->treeview_servers)));
283 server = empathy_irc_server_new (_("new server"), 6667, FALSE);
284 empathy_irc_network_append_server (dialog->network, server);
285 add_server_to_store (store, server, &iter);
287 path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
288 column = gtk_tree_view_get_column (GTK_TREE_VIEW (dialog->treeview_servers),
290 gtk_tree_view_set_cursor (GTK_TREE_VIEW (dialog->treeview_servers), path,
291 column, TRUE);
293 irc_network_dialog_network_update_buttons (dialog);
295 gtk_tree_path_free (path);
296 g_object_unref (server);
299 static void
300 irc_network_dialog_button_remove_clicked_cb (GtkWidget *widget,
301 EmpathyIrcNetworkDialog *dialog)
303 GtkTreeSelection *selection;
304 GtkTreeModel *model;
305 GtkTreeIter iter;
306 EmpathyIrcServer *server;
308 selection = gtk_tree_view_get_selection (
309 GTK_TREE_VIEW (dialog->treeview_servers));
311 if (!gtk_tree_selection_get_selected (selection, &model, &iter))
312 return;
314 gtk_tree_model_get (model, &iter, COL_SRV_OBJ, &server, -1);
316 gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
317 empathy_irc_network_remove_server (dialog->network, server);
319 irc_network_dialog_network_update_buttons (dialog);
321 g_object_unref (server);
324 static void
325 irc_network_dialog_button_up_clicked_cb (GtkWidget *widget,
326 EmpathyIrcNetworkDialog *dialog)
328 GtkTreeSelection *selection;
329 GtkTreeModel *model;
330 GtkTreeIter iter, iter_prev;
331 GtkTreePath *path;
332 gint *pos;
333 EmpathyIrcServer *server;
335 selection = gtk_tree_view_get_selection (
336 GTK_TREE_VIEW (dialog->treeview_servers));
338 if (!gtk_tree_selection_get_selected (selection, &model, &iter))
339 return;
341 path = gtk_tree_model_get_path (model, &iter);
343 if (!gtk_tree_path_prev (path))
345 gtk_tree_path_free (path);
346 return;
349 gtk_tree_model_get (model, &iter, COL_SRV_OBJ, &server, -1);
351 gtk_tree_model_get_iter (model, &iter_prev, path);
352 gtk_list_store_swap (GTK_LIST_STORE (model), &iter_prev, &iter);
354 pos = gtk_tree_path_get_indices (path);
355 empathy_irc_network_set_server_position (dialog->network, server, *pos);
357 irc_network_dialog_network_update_buttons (dialog);
359 g_object_unref (server);
360 gtk_tree_path_free (path);
363 static void
364 irc_network_dialog_button_down_clicked_cb (GtkWidget *widget,
365 EmpathyIrcNetworkDialog *dialog)
367 GtkTreeSelection *selection;
368 GtkTreeModel *model;
369 GtkTreeIter iter, iter_prev;
370 GtkTreePath *path;
371 EmpathyIrcServer *server;
372 gint *pos;
374 selection = gtk_tree_view_get_selection (
375 GTK_TREE_VIEW (dialog->treeview_servers));
377 if (!gtk_tree_selection_get_selected (selection, &model, &iter))
378 return;
380 path = gtk_tree_model_get_path (model, &iter);
382 gtk_tree_path_next (path);
383 if (!gtk_tree_model_get_iter (model, &iter_prev, path))
385 gtk_tree_path_free (path);
386 return;
389 gtk_tree_model_get (model, &iter, COL_SRV_OBJ, &server, -1);
391 gtk_list_store_swap (GTK_LIST_STORE (model), &iter_prev, &iter);
393 pos = gtk_tree_path_get_indices (path);
394 empathy_irc_network_set_server_position (dialog->network, server, *pos);
396 irc_network_dialog_network_update_buttons (dialog);
398 gtk_tree_path_free (path);
401 static void
402 irc_network_dialog_selection_changed_cb (GtkTreeSelection *treeselection,
403 EmpathyIrcNetworkDialog *dialog)
405 irc_network_dialog_network_update_buttons (dialog);
408 static void
409 irc_network_dialog_combobox_charset_changed_cb (GtkWidget *combobox,
410 EmpathyIrcNetworkDialog *dialog)
412 const gchar *charset;
414 charset = totem_subtitle_encoding_get_selected (GTK_COMBO_BOX (combobox));
415 g_object_set (dialog->network, "charset", charset, NULL);
418 static void
419 change_network (EmpathyIrcNetworkDialog *dialog,
420 EmpathyIrcNetwork *network)
422 GtkListStore *store;
424 if (dialog->network == network)
425 /* No need to change */
426 return;
428 if (dialog->network != NULL)
430 g_object_unref (dialog->network);
433 dialog->network = network;
434 g_object_ref (network);
436 store = GTK_LIST_STORE (gtk_tree_view_get_model (
437 GTK_TREE_VIEW (dialog->treeview_servers)));
438 gtk_list_store_clear (store);
440 irc_network_dialog_setup (dialog);
444 * empathy_irc_network_dialog_show:
445 * @network: the #EmpathyIrcNetwork to configure
446 * @parent: the parent of this dialog
448 * Display a dialog to configure a given #EmpathyIrcNetwork.
449 * This function is a singleton so if a configuration dialog already
450 * exists we use this one to edit the network.
452 * Returns: The displayed #GtkDialog
454 GtkWidget *
455 empathy_irc_network_dialog_show (EmpathyIrcNetwork *network,
456 GtkWidget *parent)
458 static EmpathyIrcNetworkDialog *dialog = NULL;
459 GtkBuilder *gui;
460 GtkListStore *store;
461 GtkCellRenderer *renderer;
462 GtkAdjustment *adjustment;
463 GtkTreeSelection *selection;
464 GtkTreeViewColumn *column;
465 gchar *filename;
467 g_return_val_if_fail (network != NULL, NULL);
469 if (dialog != NULL)
471 change_network (dialog, network);
472 gtk_window_present (GTK_WINDOW (dialog->dialog));
474 return dialog->dialog;
477 dialog = g_slice_new0 (EmpathyIrcNetworkDialog);
479 dialog->network = network;
480 g_object_ref (dialog->network);
482 filename = empathy_file_lookup ("empathy-account-widget-irc.ui",
483 "libempathy-gtk");
484 gui = empathy_builder_get_file (filename,
485 "irc_network_dialog", &dialog->dialog,
486 "button_close", &dialog->button_close,
487 "entry_network", &dialog->entry_network,
488 "combobox_charset", &dialog->combobox_charset,
489 "treeview_servers", &dialog->treeview_servers,
490 "button_add", &dialog->button_add,
491 "button_remove", &dialog->button_remove,
492 "button_up", &dialog->button_up,
493 "button_down", &dialog->button_down,
494 NULL);
495 g_free (filename);
497 store = gtk_list_store_new (4, G_TYPE_OBJECT, G_TYPE_STRING,
498 G_TYPE_UINT, G_TYPE_BOOLEAN);
499 gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->treeview_servers),
500 GTK_TREE_MODEL (store));
501 g_object_unref (store);
503 /* address */
504 renderer = gtk_cell_renderer_text_new ();
505 g_object_set (renderer, "editable", TRUE, NULL);
506 g_signal_connect (renderer, "edited",
507 G_CALLBACK (irc_network_dialog_address_edited_cb), dialog);
508 gtk_tree_view_insert_column_with_attributes (
509 GTK_TREE_VIEW (dialog->treeview_servers),
510 -1, _("Server"), renderer, "text", COL_ADR,
511 NULL);
513 /* port */
514 adjustment = (GtkAdjustment *) gtk_adjustment_new (6667, 1, G_MAXUINT16,
515 1, 10, 0);
516 renderer = gtk_cell_renderer_spin_new ();
517 g_object_set (renderer,
518 "editable", TRUE,
519 "adjustment", adjustment,
520 NULL);
521 g_signal_connect (renderer, "edited",
522 G_CALLBACK (irc_network_dialog_port_edited_cb), dialog);
523 gtk_tree_view_insert_column_with_attributes (
524 GTK_TREE_VIEW (dialog->treeview_servers),
525 -1, _("Port"), renderer, "text", COL_PORT,
526 NULL);
527 column = gtk_tree_view_get_column (GTK_TREE_VIEW (dialog->treeview_servers),
529 gtk_tree_view_column_set_expand (column, TRUE);
531 /* SSL */
532 renderer = gtk_cell_renderer_toggle_new ();
533 g_object_set (renderer, "activatable", TRUE, NULL);
534 g_signal_connect (renderer, "toggled",
535 G_CALLBACK (irc_network_dialog_ssl_toggled_cb), dialog);
536 gtk_tree_view_insert_column_with_attributes (
537 GTK_TREE_VIEW (dialog->treeview_servers),
538 -1, _("SSL"), renderer, "active", COL_SSL,
539 NULL);
541 selection = gtk_tree_view_get_selection (
542 GTK_TREE_VIEW (dialog->treeview_servers));
543 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
545 /* charset */
546 totem_subtitle_encoding_init (GTK_COMBO_BOX (dialog->combobox_charset));
548 irc_network_dialog_setup (dialog);
550 empathy_builder_connect (gui, dialog,
551 "irc_network_dialog", "destroy", irc_network_dialog_destroy_cb,
552 "button_close", "clicked", irc_network_dialog_close_clicked_cb,
553 "entry_network", "focus-out-event", irc_network_dialog_network_focus_cb,
554 "button_add", "clicked", irc_network_dialog_button_add_clicked_cb,
555 "button_remove", "clicked", irc_network_dialog_button_remove_clicked_cb,
556 "button_up", "clicked", irc_network_dialog_button_up_clicked_cb,
557 "button_down", "clicked", irc_network_dialog_button_down_clicked_cb,
558 "combobox_charset", "changed", irc_network_dialog_combobox_charset_changed_cb,
559 NULL);
561 g_object_unref (gui);
563 g_object_add_weak_pointer (G_OBJECT (dialog->dialog),
564 (gpointer) &dialog);
566 g_signal_connect (selection, "changed",
567 G_CALLBACK (irc_network_dialog_selection_changed_cb),
568 dialog);
570 gtk_window_set_transient_for (GTK_WINDOW (dialog->dialog),
571 GTK_WINDOW (parent));
572 gtk_window_set_modal (GTK_WINDOW (dialog->dialog), TRUE);
574 irc_network_dialog_network_update_buttons (dialog);
575 gtk_widget_show_all (dialog->dialog);
577 return dialog->dialog;