fix implicit declarations
[rofl0r-ixchat.git] / src / fe-gtk / servlistgui.c
blob3b780f581c9cbf7846882b3f8f7716a3af99c358
1 /* X-Chat
2 * Copyright (C) 2004-2008 Peter Zelezny.
3 */
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <ctype.h>
10 #include <gtk/gtkversion.h>
11 #include <gtk/gtkcheckbutton.h>
12 #include <gtk/gtkcellrenderertext.h>
13 #include <gtk/gtkcomboboxentry.h>
14 #include <gtk/gtkentry.h>
15 #include <gtk/gtkhbox.h>
16 #include <gtk/gtkhbbox.h>
17 #include <gtk/gtkhseparator.h>
18 #include <gtk/gtkimage.h>
19 #include <gtk/gtklabel.h>
20 #include <gtk/gtkliststore.h>
21 #include <gtk/gtkmenuitem.h>
22 #include <gtk/gtkmessagedialog.h>
23 #include <gtk/gtkscrolledwindow.h>
24 #include <gtk/gtkstock.h>
25 #include <gtk/gtktable.h>
26 #include <gtk/gtktogglebutton.h>
27 #include <gtk/gtktree.h>
28 #include <gtk/gtktreeselection.h>
29 #include <gtk/gtktreeview.h>
30 #include <gtk/gtkvbbox.h>
31 #include <gtk/gtkvbox.h>
32 #include <gtk/gtkwindow.h>
33 #include <gdk/gdkkeysyms.h>
35 #include "../common/xchat.h"
36 #include "../common/xchatc.h"
37 #include "../common/servlist.h"
38 #include "../common/cfgfiles.h"
39 #include "../common/fe.h"
40 #include "../common/util.h"
42 #include "fe-gtk.h"
43 #include "gtkutil.h"
44 #include "menu.h"
45 #include "pixmaps.h"
46 #include "servlistgui.h"
49 /* servlistgui.c globals */
50 static GtkWidget *serverlist_win = NULL;
51 static GtkWidget *networks_tree; /* network TreeView */
52 static int ignore_changed = FALSE;
53 static int win_width = 364;
54 static int win_height = 478;
56 /* global user info */
57 static GtkWidget *entry_nick1;
58 static GtkWidget *entry_nick2;
59 static GtkWidget *entry_nick3;
60 static GtkWidget *entry_guser;
61 static GtkWidget *entry_greal;
63 /* edit area */
64 static GtkWidget *edit_win;
65 static GtkWidget *edit_entry_nick;
66 static GtkWidget *edit_entry_nick2;
67 static GtkWidget *edit_entry_user;
68 static GtkWidget *edit_entry_real;
69 static GtkWidget *edit_entry_join;
70 static GtkWidget *edit_entry_pass;
71 static GtkWidget *edit_entry_cmd;
72 static GtkWidget *edit_label_nick;
73 static GtkWidget *edit_label_nick2;
74 static GtkWidget *edit_label_real;
75 static GtkWidget *edit_label_user;
76 static GtkWidget *edit_tree;
78 static ircnet *selected_net = NULL;
79 static ircserver *selected_serv = NULL;
80 static ircnet *fav_add_net = NULL; /* used in Add/Remove fav context menus */
81 static session *servlist_sess;
83 static void servlist_network_row_cb (GtkTreeSelection *sel, gpointer user_data);
84 static GtkWidget *servlist_open_edit (GtkWidget *parent, ircnet *net);
87 static const char *pages[]=
89 "UTF-8 (Unicode)",
90 "IRC (Latin/Unicode Hybrid)",
91 "ISO-8859-15 (Western Europe)",
92 "ISO-8859-2 (Central Europe)",
93 "ISO-8859-7 (Greek)",
94 "ISO-8859-8 (Hebrew)",
95 "ISO-8859-9 (Turkish)",
96 "ISO-2022-JP (Japanese)",
97 "SJIS (Japanese)",
98 "CP949 (Korean)",
99 "KOI8-R (Cyrillic)",
100 "CP1251 (Cyrillic)",
101 "CP1256 (Arabic)",
102 "CP1257 (Baltic)",
103 "GB18030 (Chinese)",
104 "TIS-620 (Thai)",
105 NULL
108 /* This is our dictionary for authentication types. Keep these in sync with
109 * login_types[]! This allows us to re-order the login type dropdown in the
110 * network list without breaking config compatibility.
112 * Also make sure inbound_nickserv_login() won't break, i.e. if you add a new
113 * type that is NickServ-based, add it there as well so that HexChat knows to
114 * treat it as such.
116 static int login_types_conf[] =
118 LOGIN_DEFAULT, /* default entry - we don't use this but it makes indexing consistent with login_types[] so it's nice */
119 LOGIN_SASL,
120 #ifdef USE_OPENSSL
121 LOGIN_SASLEXTERNAL,
122 #endif
123 LOGIN_PASS,
124 LOGIN_MSG_NICKSERV,
125 LOGIN_NICKSERV,
126 #ifdef USE_OPENSSL
127 LOGIN_CHALLENGEAUTH,
128 #endif
129 LOGIN_CUSTOM
130 #if 0
131 LOGIN_NS,
132 LOGIN_MSG_NS,
133 LOGIN_AUTH,
134 #endif
137 static const char *login_types[]=
139 "Default",
140 "SASL (username + password)",
141 #ifdef USE_OPENSSL
142 "SASL EXTERNAL (cert)",
143 #endif
144 "Server Password (/PASS password)",
145 "NickServ (/MSG NickServ + password)",
146 "NickServ (/NICKSERV + password)",
147 #ifdef USE_OPENSSL
148 "Challenge Auth (username + password)",
149 #endif
150 "Custom... (connect commands)",
151 #if 0
152 "NickServ (/NS + password)",
153 "NickServ (/MSG NS + password)",
154 "AUTH (/AUTH nickname password)",
155 #endif
156 NULL
159 /* poor man's IndexOf() - find the dropdown string index that belongs to the given config value */
160 static int
161 servlist_get_login_desc_index (int conf_value)
163 int i;
164 int length = sizeof (login_types_conf) / sizeof (login_types_conf[0]); /* the number of elements in the conf array */
166 for (i = 0; i < length; i++)
168 if (login_types_conf[i] == conf_value)
170 return i;
174 return 0; /* make the compiler happy */
177 static void
178 servlist_select_and_show (GtkTreeView *treeview, GtkTreeIter *iter,
179 GtkListStore *store)
181 GtkTreePath *path;
182 GtkTreeSelection *sel;
184 sel = gtk_tree_view_get_selection (treeview);
186 /* select this network */
187 gtk_tree_selection_select_iter (sel, iter);
188 /* and make sure it's visible */
189 path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), iter);
190 if (path)
192 gtk_tree_view_scroll_to_cell (treeview, path, NULL, TRUE, 0.5, 0.5);
193 gtk_tree_view_set_cursor (treeview, path, NULL, FALSE);
194 gtk_tree_path_free (path);
198 static void
199 servlist_servers_populate (ircnet *net, GtkWidget *treeview)
201 GtkListStore *store;
202 GtkTreeIter iter;
203 int i;
204 ircserver *serv;
205 GSList *list = net->servlist;
207 store = (GtkListStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
208 gtk_list_store_clear (store);
210 i = 0;
211 while (list)
213 serv = list->data;
214 gtk_list_store_append (store, &iter);
215 gtk_list_store_set (store, &iter, 0, serv->hostname, 1, 1, -1);
217 if (net->selected == i)
218 /* select this server */
219 servlist_select_and_show (GTK_TREE_VIEW (treeview), &iter, store);
221 i++;
222 list = list->next;
226 static void
227 servlist_networks_populate_ (GtkWidget *treeview, GSList *netlist, gboolean favorites)
229 GtkListStore *store;
230 GtkTreeIter iter;
231 int i;
232 ircnet *net;
234 if (!netlist)
236 net = servlist_net_add (_("New Network"), "", FALSE);
237 servlist_server_add (net, "newserver/6667");
238 netlist = network_list;
240 store = (GtkListStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
241 gtk_list_store_clear (store);
243 i = 0;
244 while (netlist)
246 net = netlist->data;
247 if (!favorites || (net->flags & FLAG_FAVORITE))
249 if (favorites)
250 gtk_list_store_insert_with_values (store, &iter, 0x7fffffff, 0, net->name, 1, 1, 2, 400, -1);
251 else
252 gtk_list_store_insert_with_values (store, &iter, 0x7fffffff, 0, net->name, 1, 1, 2, (net->flags & FLAG_FAVORITE) ? 800 : 400, -1);
253 if (i == prefs.slist_select)
255 /* select this network */
256 servlist_select_and_show (GTK_TREE_VIEW (treeview), &iter, store);
257 selected_net = net;
260 i++;
261 netlist = netlist->next;
265 static void
266 servlist_networks_populate (GtkWidget *treeview, GSList *netlist)
268 servlist_networks_populate_ (treeview, netlist, prefs.slist_fav);
271 static void
272 servlist_server_row_cb (GtkTreeSelection *sel, gpointer user_data)
274 GtkTreeModel *model;
275 GtkTreeIter iter;
276 ircserver *serv;
277 char *servname;
278 int pos;
280 if (!selected_net)
281 return;
283 if (gtk_tree_selection_get_selected (sel, &model, &iter))
285 gtk_tree_model_get (model, &iter, 0, &servname, -1);
286 serv = servlist_server_find (selected_net, servname, &pos);
287 g_free (servname);
288 if (serv)
289 selected_net->selected = pos;
290 selected_serv = serv;
294 static void
295 servlist_start_editing (GtkTreeView *tree)
297 GtkTreeSelection *sel;
298 GtkTreeModel *model;
299 GtkTreeIter iter;
300 GtkTreePath *path;
302 sel = gtk_tree_view_get_selection (tree);
304 if (gtk_tree_selection_get_selected (sel, &model, &iter))
306 path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &iter);
307 if (path)
309 gtk_tree_view_set_cursor (tree, path,
310 gtk_tree_view_get_column (tree, 0), TRUE);
311 gtk_tree_path_free (path);
316 static void
317 servlist_addserver_cb (GtkWidget *item, GtkWidget *treeview)
319 GtkTreeIter iter;
320 GtkListStore *store;
322 if (!selected_net)
323 return;
325 store = (GtkListStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
326 servlist_server_add (selected_net, "newserver/6667");
328 gtk_list_store_append (store, &iter);
329 gtk_list_store_set (store, &iter, 0, "newserver/6667", 1, 1, -1);
331 /* select this server */
332 servlist_select_and_show (GTK_TREE_VIEW (treeview), &iter, store);
333 /*servlist_start_editing (GTK_TREE_VIEW (treeview));*/
335 servlist_server_row_cb (gtk_tree_view_get_selection (GTK_TREE_VIEW (networks_tree)), NULL);
338 static void
339 servlist_addnet_cb (GtkWidget *item, GtkTreeView *treeview)
341 GtkTreeIter iter;
342 GtkListStore *store;
343 ircnet *net;
345 net = servlist_net_add (_("New Network"), "", TRUE);
346 net->encoding = strdup ("IRC (Latin/Unicode Hybrid)");
347 servlist_server_add (net, "newserver/6667");
349 store = (GtkListStore *)gtk_tree_view_get_model (treeview);
350 gtk_list_store_prepend (store, &iter);
351 gtk_list_store_set (store, &iter, 0, net->name, 1, 1, -1);
353 /* select this network */
354 servlist_select_and_show (GTK_TREE_VIEW (networks_tree), &iter, store);
355 servlist_start_editing (GTK_TREE_VIEW (networks_tree));
357 servlist_network_row_cb (gtk_tree_view_get_selection (GTK_TREE_VIEW (networks_tree)), NULL);
360 static void
361 servlist_deletenetwork (ircnet *net)
363 GtkTreeSelection *sel;
364 GtkTreeModel *model;
365 GtkTreeIter iter;
367 /* remove from GUI */
368 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (networks_tree));
369 if (gtk_tree_selection_get_selected (sel, &model, &iter))
370 gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
372 /* remove from list */
373 servlist_net_remove (net);
375 /* force something to be selected */
376 gtk_tree_model_get_iter_first (model, &iter);
377 servlist_select_and_show (GTK_TREE_VIEW (networks_tree), &iter,
378 GTK_LIST_STORE (model));
379 servlist_network_row_cb (sel, NULL);
382 static void
383 servlist_deletenetdialog_cb (GtkDialog *dialog, gint arg1, ircnet *net)
385 gtk_widget_destroy (GTK_WIDGET (dialog));
386 if (arg1 == GTK_RESPONSE_OK)
387 servlist_deletenetwork (net);
390 static void
391 servlist_move_server (ircserver *serv, int delta)
393 int pos;
395 pos = g_slist_index (selected_net->servlist, serv);
396 if (pos >= 0)
398 pos += delta;
399 if (pos >= 0)
401 selected_net->servlist = g_slist_remove (selected_net->servlist, serv);
402 selected_net->servlist = g_slist_insert (selected_net->servlist, serv, pos);
403 servlist_servers_populate (selected_net, edit_tree);
408 static void
409 servlist_move_network (ircnet *net, int delta)
411 int pos;
413 pos = g_slist_index (network_list, net);
414 if (pos >= 0)
416 pos += delta;
417 if (pos >= 0)
419 /*prefs.slist_select += delta;*/
420 network_list = g_slist_remove (network_list, net);
421 network_list = g_slist_insert (network_list, net, pos);
422 servlist_networks_populate (networks_tree, network_list);
427 static gboolean
428 servlist_net_keypress_cb (GtkWidget *wid, GdkEventKey *evt, gpointer tree)
430 if (!selected_net)
431 return FALSE;
433 if (evt->state & GDK_SHIFT_MASK)
435 if (evt->keyval == GDK_Up)
437 servlist_move_network (selected_net, -1);
439 else if (evt->keyval == GDK_Down)
441 servlist_move_network (selected_net, +1);
445 return FALSE;
448 static gboolean
449 servlist_serv_keypress_cb (GtkWidget *wid, GdkEventKey *evt, gpointer userdata)
451 if (!selected_net || !selected_serv)
452 return FALSE;
454 if (evt->state & GDK_SHIFT_MASK)
456 if (evt->keyval == GDK_Up)
458 servlist_move_server (selected_serv, -1);
460 else if (evt->keyval == GDK_Down)
462 servlist_move_server (selected_serv, +1);
466 return FALSE;
469 static gint
470 servlist_compare (ircnet *net1, ircnet *net2)
472 gchar *net1_casefolded, *net2_casefolded;
473 int result=0;
475 net1_casefolded=g_utf8_casefold(net1->name,-1),
476 net2_casefolded=g_utf8_casefold(net2->name,-1),
478 result=g_utf8_collate(net1_casefolded,net2_casefolded);
480 g_free(net1_casefolded);
481 g_free(net2_casefolded);
483 return result;
487 static void
488 servlist_sort (GtkWidget *button, gpointer none)
490 network_list=g_slist_sort(network_list,(GCompareFunc)servlist_compare);
491 servlist_networks_populate (networks_tree, network_list);
494 static gboolean
495 servlist_has_selection (GtkTreeView *tree)
497 GtkTreeSelection *sel;
498 GtkTreeModel *model;
499 GtkTreeIter iter;
501 /* make sure something is selected */
502 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
503 return gtk_tree_selection_get_selected (sel, &model, &iter);
506 static void
507 servlist_favor (GtkWidget *button, gpointer none)
509 GtkTreeSelection *sel;
510 GtkTreeModel *model;
511 GtkTreeIter iter;
513 if (!selected_net)
514 return;
516 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (networks_tree));
517 if (gtk_tree_selection_get_selected (sel, &model, &iter))
519 if (selected_net->flags & FLAG_FAVORITE)
521 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 2, 400, -1);
522 selected_net->flags &= ~FLAG_FAVORITE;
524 else
526 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 2, 800, -1);
527 selected_net->flags |= FLAG_FAVORITE;
532 static void
533 servlist_update_from_entry (char **str, GtkWidget *entry)
535 if (*str)
536 free (*str);
538 if (GTK_ENTRY (entry)->text[0] == 0)
539 *str = NULL;
540 else
541 *str = strdup (GTK_ENTRY (entry)->text);
544 static void
545 servlist_edit_update (ircnet *net)
547 servlist_update_from_entry (&net->nick, edit_entry_nick);
548 servlist_update_from_entry (&net->nick2, edit_entry_nick2);
549 servlist_update_from_entry (&net->user, edit_entry_user);
550 servlist_update_from_entry (&net->real, edit_entry_real);
552 servlist_update_from_entry (&net->autojoin, edit_entry_join);
553 servlist_update_from_entry (&net->command, edit_entry_cmd);
554 servlist_update_from_entry (&net->pass, edit_entry_pass);
557 static void
558 servlist_edit_close_cb (GtkWidget *button, gpointer userdata)
560 if (selected_net)
561 servlist_edit_update (selected_net);
563 gtk_widget_destroy (edit_win);
564 edit_win = NULL;
567 static gint
568 servlist_editwin_delete_cb (GtkWidget *win, GdkEventAny *event, gpointer none)
570 servlist_edit_close_cb (NULL, NULL);
571 return FALSE;
574 static gboolean
575 servlist_configure_cb (GtkWindow *win, GdkEventConfigure *event, gpointer none)
577 /* remember the window size */
578 gtk_window_get_size (win, &win_width, &win_height);
579 return FALSE;
582 static void
583 servlist_edit_cb (GtkWidget *but, gpointer none)
585 if (!servlist_has_selection (GTK_TREE_VIEW (networks_tree)))
586 return;
588 edit_win = servlist_open_edit (serverlist_win, selected_net);
589 gtkutil_set_icon (edit_win);
590 servlist_servers_populate (selected_net, edit_tree);
591 g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_tree))),
592 "changed", G_CALLBACK (servlist_server_row_cb), NULL);
593 g_signal_connect (G_OBJECT (edit_win), "delete_event",
594 G_CALLBACK (servlist_editwin_delete_cb), 0);
595 g_signal_connect (G_OBJECT (edit_tree), "key_press_event",
596 G_CALLBACK (servlist_serv_keypress_cb), 0);
597 gtk_widget_show (edit_win);
600 static void
601 servlist_deletenet_cb (GtkWidget *item, ircnet *net)
603 GtkWidget *dialog;
605 if (!servlist_has_selection (GTK_TREE_VIEW (networks_tree)))
606 return;
608 net = selected_net;
609 if (!net)
610 return;
611 dialog = gtk_message_dialog_new (GTK_WINDOW (serverlist_win),
612 GTK_DIALOG_DESTROY_WITH_PARENT |
613 GTK_DIALOG_MODAL,
614 GTK_MESSAGE_QUESTION,
615 GTK_BUTTONS_OK_CANCEL,
616 _("Really remove network \"%s\" and all its servers?"),
617 net->name);
618 g_signal_connect (dialog, "response",
619 G_CALLBACK (servlist_deletenetdialog_cb), net);
620 gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE);
621 gtk_widget_show (dialog);
624 static void
625 servlist_deleteserver (ircserver *serv, GtkTreeModel *model)
627 GtkTreeSelection *sel;
628 GtkTreeIter iter;
630 /* don't remove the last server */
631 if (selected_net && g_slist_length (selected_net->servlist) < 2)
632 return;
634 /* remove from GUI */
635 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_tree));
636 if (gtk_tree_selection_get_selected (sel, &model, &iter))
637 gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
639 /* remove from list */
640 if (selected_net)
641 servlist_server_remove (selected_net, serv);
644 static void
645 servlist_editserverbutton_cb (GtkWidget *item, gpointer none)
647 servlist_start_editing (GTK_TREE_VIEW (edit_tree));
650 static void
651 servlist_deleteserver_cb (GtkWidget *item, gpointer none)
653 GtkTreeSelection *sel;
654 GtkTreeModel *model;
655 GtkTreeIter iter;
656 char *servname;
657 ircserver *serv;
658 int pos;
660 /* find the selected item in the GUI */
661 model = gtk_tree_view_get_model (GTK_TREE_VIEW (edit_tree));
662 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (edit_tree));
664 if (gtk_tree_selection_get_selected (sel, &model, &iter))
666 gtk_tree_model_get (model, &iter, 0, &servname, -1);
667 serv = servlist_server_find (selected_net, servname, &pos);
668 g_free (servname);
669 if (serv)
670 servlist_deleteserver (serv, model);
674 static ircnet *
675 servlist_find_selected_net (GtkTreeSelection *sel)
677 GtkTreeModel *model;
678 GtkTreeIter iter;
679 char *netname;
680 int pos;
681 ircnet *net = NULL;
683 if (gtk_tree_selection_get_selected (sel, &model, &iter))
685 gtk_tree_model_get (model, &iter, 0, &netname, -1);
686 net = servlist_net_find (netname, &pos, strcmp);
687 g_free (netname);
688 if (net)
689 prefs.slist_select = pos;
692 return net;
695 static void
696 servlist_network_row_cb (GtkTreeSelection *sel, gpointer user_data)
698 ircnet *net;
700 selected_net = NULL;
702 net = servlist_find_selected_net (sel);
703 if (net)
704 selected_net = net;
707 static int
708 servlist_savegui (void)
710 char *sp;
712 /* check for blank username, ircd will not allow this */
713 if (GTK_ENTRY (entry_guser)->text[0] == 0)
714 return 1;
716 if (GTK_ENTRY (entry_greal)->text[0] == 0)
717 return 1;
719 strcpy (prefs.nick1, GTK_ENTRY (entry_nick1)->text);
720 strcpy (prefs.nick2, GTK_ENTRY (entry_nick2)->text);
721 strcpy (prefs.nick3, GTK_ENTRY (entry_nick3)->text);
722 strcpy (prefs.username, GTK_ENTRY (entry_guser)->text);
723 sp = strchr (prefs.username, ' ');
724 if (sp)
725 sp[0] = 0; /* spaces will break the login */
726 strcpy (prefs.realname, GTK_ENTRY (entry_greal)->text);
727 servlist_save ();
729 return 0;
732 static gboolean
733 servlist_get_iter_from_name (GtkTreeModel *model, gchar *name, GtkTreeIter *iter)
735 GtkTreePath *path = gtk_tree_path_new_from_string (name);
737 if (!gtk_tree_model_get_iter (model, iter, path))
739 gtk_tree_path_free (path);
740 return FALSE;
743 gtk_tree_path_free (path);
744 return TRUE;
747 static void
748 servlist_editchannel_cb (GtkCellRendererText *cell, gchar *name, gchar *newval, GtkTreeModel *model)
750 GtkTreeIter iter;
751 static int loop_guard = FALSE;
753 if (loop_guard)
754 return;
756 if (!servlist_get_iter_from_name (model, name, &iter))
757 return;
759 loop_guard = TRUE;
760 /* delete empty item */
761 if (newval[0] == 0)
762 gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
763 else
764 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, newval, -1);
765 loop_guard = FALSE;
768 static void
769 servlist_editkey_cb (GtkCellRendererText *cell, gchar *name, gchar *newval, GtkTreeModel *model)
771 GtkTreeIter iter;
773 if (!servlist_get_iter_from_name (model, name, &iter))
774 return;
776 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 1, newval, -1);
779 static void
780 servlist_addchannel (GtkWidget *tree, char *channel)
782 GtkTreeIter iter;
783 GtkListStore *store;
785 store = (GtkListStore *)gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
787 gtk_list_store_append (store, &iter);
788 gtk_list_store_set (store, &iter, 0, channel, 1, "", 2, TRUE, -1);
790 /* select this server */
791 servlist_select_and_show (GTK_TREE_VIEW (tree), &iter, store);
792 servlist_start_editing (GTK_TREE_VIEW (tree));
795 static void
796 servlist_addchannel_cb (GtkWidget *item, GtkWidget *tree)
798 servlist_addchannel (tree, _("#channel"));
801 static void
802 servlist_deletechannel_cb (GtkWidget *item, GtkWidget *tree)
804 GtkTreeSelection *sel;
805 GtkTreeModel *model;
806 GtkTreeIter iter;
808 /* find the selected item in the GUI */
809 model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
810 sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree));
812 if (gtk_tree_selection_get_selected (sel, &model, &iter))
813 gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
816 static void
817 servlist_editchannelbutton_cb (GtkWidget *item, GtkWidget *tree)
819 servlist_start_editing (GTK_TREE_VIEW (tree));
822 /* save everything from the GUI to the GtkEntry */
824 static void
825 servlist_autojoineditok_cb (GtkWidget *button, GtkWidget *tree)
827 GtkTreeModel *model;
828 GtkTreeIter iter;
829 char *channel, *key;
830 char *autojoin;
831 GSList *channels = NULL, *keys = NULL;
833 model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree));
835 if (gtk_tree_model_get_iter_first (model, &iter))
839 gtk_tree_model_get (model, &iter, 0, &channel, 1, &key, -1);
840 channels = g_slist_append (channels, channel);
841 if (key && key[0] == 0)
843 /* NULL out empty keys */
844 g_free (key);
845 keys = g_slist_append (keys, NULL);
847 else
848 keys = g_slist_append (keys, key);
850 while (gtk_tree_model_iter_next (model, &iter));
853 gtk_widget_destroy (gtk_widget_get_toplevel (button));
855 autojoin = joinlist_merge (channels, keys);
856 if (autojoin)
858 if (edit_win && selected_net)
859 gtk_entry_set_text (GTK_ENTRY (edit_entry_join), autojoin);
860 else
862 if (fav_add_net->autojoin)
863 free (fav_add_net->autojoin);
864 fav_add_net->autojoin = strdup (autojoin);
866 g_free (autojoin);
869 /* this does g_free too */
870 joinlist_free (channels, keys);
872 if (fav_add_net)
873 servlist_save ();
876 void
877 servlist_autojoinedit (ircnet *net, char *channel, gboolean add)
879 GtkWidget *win;
880 GtkWidget *scrolledwindow;
881 GtkTreeModel *model;
882 GtkListStore *store;
883 GtkCellRenderer *renderer;
884 GtkWidget *tree;
885 GtkWidget *table;
886 GtkWidget *label;
887 GtkWidget *label2;
888 GtkWidget *bbox;
889 GtkWidget *wid;
891 GtkWidget *vbuttonbox1;
892 GtkWidget *buttonadd;
893 GtkWidget *buttonremove;
894 GtkWidget *buttonedit;
896 char buf[128];
897 char lab[128];
898 GSList *channels, *keys;
899 GSList *clist, *klist;
900 GtkTreeIter iter;
902 if (edit_win && selected_net)
903 /* update net->autojoin */
904 servlist_edit_update (selected_net);
906 win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
907 gtk_container_set_border_width (GTK_CONTAINER (win), 4);
908 gtk_window_set_title (GTK_WINDOW (win), _("XChat: Favorite Channels (Auto-Join List)"));
909 gtk_window_set_default_size (GTK_WINDOW (win), 354, 256);
910 gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_MOUSE);
911 if (edit_win)
912 gtk_window_set_transient_for (GTK_WINDOW (win), GTK_WINDOW (edit_win));
913 gtk_window_set_modal (GTK_WINDOW (win), TRUE);
914 gtk_window_set_type_hint (GTK_WINDOW (win), GDK_WINDOW_TYPE_HINT_DIALOG);
915 gtk_window_set_role (GTK_WINDOW (win), "editserv");
917 table = gtk_table_new (1, 1, FALSE);
918 gtk_container_add (GTK_CONTAINER (win), table);
919 gtk_widget_show (table);
921 snprintf (buf, sizeof (buf), _("These channels will be joined whenever you connect to %s."), net->name);
922 label = gtk_label_new (buf);
923 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_CENTER);
924 gtk_table_attach (GTK_TABLE (table), label, 0, 2, 0, 1, GTK_FILL|GTK_EXPAND, GTK_FILL, 3, 3);
925 gtk_widget_show (label);
927 label2 = gtk_label_new ("");
928 gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_CENTER);
929 gtk_table_attach (GTK_TABLE (table), label2, 0, 2, 1, 2, GTK_FILL, 0, 3, 3);
930 gtk_widget_show (label2);
932 scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
933 gtk_table_attach (GTK_TABLE (table), scrolledwindow, 0, 1, 2, 3, GTK_FILL|GTK_EXPAND, GTK_FILL|GTK_EXPAND, 0, 0);
934 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow),
935 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
936 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
937 GTK_SHADOW_IN);
938 gtk_widget_show (scrolledwindow);
940 store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN);
941 model = GTK_TREE_MODEL (store);
943 tree = gtk_tree_view_new_with_model (model);
944 g_object_unref (model);
945 gtk_container_add (GTK_CONTAINER (scrolledwindow), tree);
946 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree), TRUE);
947 gtk_widget_show (tree);
949 renderer = gtk_cell_renderer_text_new ();
950 g_signal_connect (G_OBJECT (renderer), "edited",
951 G_CALLBACK (servlist_editchannel_cb), model);
952 gtk_tree_view_insert_column_with_attributes (
953 GTK_TREE_VIEW (tree), -1,
954 _("Channel"), renderer,
955 "text", 0,
956 "editable", 2,
957 NULL);
959 renderer = gtk_cell_renderer_text_new ();
960 g_signal_connect (G_OBJECT (renderer), "edited",
961 G_CALLBACK (servlist_editkey_cb), model);
962 gtk_tree_view_insert_column_with_attributes (
963 GTK_TREE_VIEW (tree), -1,
964 _("Key (Password)"), renderer,
965 "text", 1,
966 "editable", 2,
967 NULL);
969 gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (tree), 0), TRUE);
970 gtk_tree_view_column_set_expand (gtk_tree_view_get_column (GTK_TREE_VIEW (tree), 1), TRUE);
972 gtk_tree_sortable_set_sort_column_id ((GtkTreeSortable *)model, 0, GTK_SORT_ASCENDING);
974 /* ===BUTTONS=== */
975 vbuttonbox1 = gtk_vbutton_box_new ();
976 gtk_box_set_spacing (GTK_BOX (vbuttonbox1), 3);
977 gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox1), GTK_BUTTONBOX_START);
978 gtk_widget_show (vbuttonbox1);
979 gtk_table_attach (GTK_TABLE (table), vbuttonbox1, 1, 2, 2, 3, GTK_FILL, GTK_FILL, 3, 0);
981 buttonadd = gtk_button_new_from_stock ("gtk-add");
982 g_signal_connect (G_OBJECT (buttonadd), "clicked",
983 G_CALLBACK (servlist_addchannel_cb), tree);
984 gtk_widget_show (buttonadd);
985 gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonadd);
986 GTK_WIDGET_SET_FLAGS (buttonadd, GTK_CAN_DEFAULT);
988 buttonremove = gtk_button_new_from_stock ("gtk-remove");
989 g_signal_connect (G_OBJECT (buttonremove), "clicked",
990 G_CALLBACK (servlist_deletechannel_cb), tree);
991 gtk_widget_show (buttonremove);
992 gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonremove);
993 GTK_WIDGET_SET_FLAGS (buttonremove, GTK_CAN_DEFAULT);
995 buttonedit = gtk_button_new_with_mnemonic (_("_Edit"));
996 g_signal_connect (G_OBJECT (buttonedit), "clicked",
997 G_CALLBACK (servlist_editchannelbutton_cb), tree);
998 gtk_widget_show (buttonedit);
999 gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonedit);
1000 GTK_WIDGET_SET_FLAGS (buttonedit, GTK_CAN_DEFAULT);
1002 bbox = gtk_hbutton_box_new ();
1003 gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
1004 gtk_box_set_spacing (GTK_BOX (bbox), 4);
1005 gtk_table_attach (GTK_TABLE (table), bbox, 0, 1, 3, 4, GTK_FILL|GTK_EXPAND, GTK_FILL, 0, 4);
1006 gtk_widget_show (bbox);
1008 wid = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
1009 g_signal_connect (G_OBJECT (wid), "clicked", G_CALLBACK (gtkutil_destroy), win);
1010 gtk_container_add (GTK_CONTAINER (bbox), wid);
1011 gtk_widget_show (wid);
1013 wid = gtk_button_new_from_stock (GTK_STOCK_OK);
1014 g_signal_connect (G_OBJECT (wid), "clicked", G_CALLBACK (servlist_autojoineditok_cb), tree);
1015 gtk_container_add (GTK_CONTAINER (bbox), wid);
1016 gtk_widget_show (wid);
1017 gtk_widget_grab_focus (wid);
1018 /* =========== */
1020 if (net->autojoin)
1022 joinlist_split (net->autojoin, &channels, &keys);
1024 clist = channels;
1025 klist = keys;
1027 while (clist)
1029 if (channel && !add && !rfc_casecmp (channel, clist->data))
1031 snprintf (buf, sizeof (buf), _("%s has been removed."), channel);
1032 snprintf (lab, sizeof (lab), "<span foreground=\"#2222DD\">%s</span>", buf);
1033 gtk_label_set_markup (GTK_LABEL (label2), lab);
1035 else
1037 gtk_list_store_append (store, &iter);
1038 gtk_list_store_set (store, &iter, 0, clist->data, 1, klist->data, 2, TRUE, -1);
1041 klist = klist->next;
1042 clist = clist->next;
1045 joinlist_free (channels, keys);
1048 if (channel && add)
1050 servlist_addchannel (tree, channel);
1051 snprintf (buf, sizeof (buf), _("%s has been added."), channel);
1052 snprintf (lab, sizeof (lab), "<span foreground=\"#2222DD\">%s</span>", buf);
1053 gtk_label_set_markup (GTK_LABEL (label2), lab);
1056 fav_add_net = net;
1058 gtk_widget_show (win);
1061 static void
1062 servlist_autojoinedit_cb (GtkWidget *button, ircnet *net)
1064 servlist_autojoinedit (net, NULL, FALSE);
1067 static void
1068 servlist_connect_cb (GtkWidget *button, gpointer userdata)
1070 if (!selected_net)
1071 return;
1073 if (servlist_savegui () != 0)
1075 fe_message (_("User name and Real name cannot be left blank."), FE_MSG_ERROR);
1076 return;
1079 if (!is_session (servlist_sess))
1080 servlist_sess = NULL; /* open a new one */
1083 GSList *list;
1084 session *sess;
1085 session *chosen = servlist_sess;
1087 servlist_sess = NULL; /* open a new one */
1089 for (list = sess_list; list; list = list->next)
1091 sess = list->data;
1092 if (sess->server->network == selected_net)
1094 servlist_sess = sess;
1095 if (sess->server->connected)
1096 servlist_sess = NULL; /* open a new one */
1097 break;
1101 /* use the chosen one, if it's empty */
1102 if (!servlist_sess &&
1103 chosen &&
1104 !chosen->server->connected &&
1105 chosen->server->server_session->channel[0] == 0)
1107 servlist_sess = chosen;
1111 servlist_connect (servlist_sess, selected_net, TRUE);
1113 gtk_widget_destroy (serverlist_win);
1114 serverlist_win = NULL;
1115 selected_net = NULL;
1118 static void
1119 servlist_celledit_cb (GtkCellRendererText *cell, gchar *arg1, gchar *arg2,
1120 gpointer user_data)
1122 GtkTreeModel *model = (GtkTreeModel *)user_data;
1123 GtkTreeIter iter;
1124 GtkTreePath *path;
1125 char *netname;
1126 ircnet *net;
1128 if (!arg1 || !arg2)
1129 return;
1131 path = gtk_tree_path_new_from_string (arg1);
1132 if (!path)
1133 return;
1135 if (!gtk_tree_model_get_iter (model, &iter, path))
1137 gtk_tree_path_free (path);
1138 return;
1140 gtk_tree_model_get (model, &iter, 0, &netname, -1);
1142 net = servlist_net_find (netname, NULL, strcmp);
1143 g_free (netname);
1144 if (net)
1146 /* delete empty item */
1147 if (arg2[0] == 0)
1149 servlist_deletenetwork (net);
1150 gtk_tree_path_free (path);
1151 return;
1154 netname = net->name;
1155 net->name = strdup (arg2);
1156 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, net->name, -1);
1157 free (netname);
1160 gtk_tree_path_free (path);
1163 static void
1164 servlist_check_cb (GtkWidget *but, gpointer num_p)
1166 int num = GPOINTER_TO_INT (num_p);
1168 if (!selected_net)
1169 return;
1171 if ((1 << num) == FLAG_CYCLE || (1 << num) == FLAG_USE_PROXY)
1173 /* these ones are reversed, so it's compat with 2.0.x */
1174 if (GTK_TOGGLE_BUTTON (but)->active)
1175 selected_net->flags &= ~(1 << num);
1176 else
1177 selected_net->flags |= (1 << num);
1178 } else
1180 if (GTK_TOGGLE_BUTTON (but)->active)
1181 selected_net->flags |= (1 << num);
1182 else
1183 selected_net->flags &= ~(1 << num);
1186 if ((1 << num) == FLAG_USE_GLOBAL)
1188 if (GTK_TOGGLE_BUTTON (but)->active)
1190 gtk_widget_hide (edit_label_nick);
1191 gtk_widget_hide (edit_entry_nick);
1193 gtk_widget_hide (edit_label_nick2);
1194 gtk_widget_hide (edit_entry_nick2);
1196 gtk_widget_hide (edit_label_user);
1197 gtk_widget_hide (edit_entry_user);
1199 gtk_widget_hide (edit_label_real);
1200 gtk_widget_hide (edit_entry_real);
1201 } else
1203 gtk_widget_show (edit_label_nick);
1204 gtk_widget_show (edit_entry_nick);
1206 gtk_widget_show (edit_label_nick2);
1207 gtk_widget_show (edit_entry_nick2);
1209 gtk_widget_show (edit_label_user);
1210 gtk_widget_show (edit_entry_user);
1212 gtk_widget_show (edit_label_real);
1213 gtk_widget_show (edit_entry_real);
1218 static GtkWidget *
1219 servlist_create_check (int num, int state, GtkWidget *table, int row, int col, char *labeltext)
1221 GtkWidget *but;
1223 but = gtk_check_button_new_with_label (labeltext);
1224 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (but), state);
1225 g_signal_connect (G_OBJECT (but), "toggled",
1226 G_CALLBACK (servlist_check_cb), GINT_TO_POINTER (num));
1227 gtk_table_attach (GTK_TABLE (table), but, col, col+2, row, row+1,
1228 GTK_FILL|GTK_EXPAND, 0, 0, 0);
1229 gtk_widget_show (but);
1231 return but;
1234 static GtkWidget *
1235 servlist_create_entry (GtkWidget *table, char *labeltext, int row,
1236 char *def, GtkWidget **label_ret, char *tip)
1238 GtkWidget *label, *entry;
1240 label = gtk_label_new_with_mnemonic (labeltext);
1241 if (label_ret)
1242 *label_ret = label;
1243 gtk_widget_show (label);
1244 gtk_table_attach (GTK_TABLE (table), label, 1, 2, row, row+1,
1245 GTK_FILL, 0, 0, 0);
1246 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1248 entry = gtk_entry_new ();
1249 add_tip (entry, tip);
1250 gtk_widget_show (entry);
1251 gtk_entry_set_text (GTK_ENTRY (entry), def ? def : "");
1252 gtk_label_set_mnemonic_widget (GTK_LABEL (label), entry);
1254 if (row == 15) /* for "Channels to Join:" */
1256 GtkWidget *button, *box;
1258 box = gtk_hbox_new (0, 0);
1259 button = gtk_button_new_with_label ("...");
1260 g_signal_connect (G_OBJECT (button), "clicked",
1261 G_CALLBACK (servlist_autojoinedit_cb), selected_net);
1263 gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 0);
1264 gtk_box_pack_end (GTK_BOX (box), button, 0, 0, 0);
1265 gtk_widget_show_all (box);
1267 gtk_table_attach (GTK_TABLE (table), box, 2, 3, row, row+1,
1268 GTK_FILL|GTK_EXPAND, 0, 0, 0);
1270 else
1272 gtk_table_attach (GTK_TABLE (table), entry, 2, 3, row, row+1,
1273 GTK_FILL|GTK_EXPAND, 0, 0, 0);
1276 return entry;
1279 static gint
1280 servlist_delete_cb (GtkWidget *win, GdkEventAny *event, gpointer userdata)
1282 servlist_savegui ();
1283 serverlist_win = NULL;
1284 selected_net = NULL;
1286 if (sess_list == NULL)
1287 xchat_exit ();
1289 return FALSE;
1292 static void
1293 servlist_close_cb (GtkWidget *button, gpointer userdata)
1295 servlist_savegui ();
1296 gtk_widget_destroy (serverlist_win);
1297 serverlist_win = NULL;
1298 selected_net = NULL;
1300 if (sess_list == NULL)
1301 xchat_exit ();
1304 /* convert "host:port" format to "host/port" */
1306 static char *
1307 servlist_sanitize_hostname (char *host)
1309 char *ret, *c, *e;
1311 ret = strdup (host);
1313 c = strchr (ret, ':');
1314 e = strrchr (ret, ':');
1316 /* if only one colon exists it's probably not IPv6 */
1317 if (c && c == e)
1318 *c = '/';
1320 return ret;
1323 static void
1324 servlist_editserver_cb (GtkCellRendererText *cell, gchar *arg1, gchar *arg2,
1325 gpointer user_data)
1327 GtkTreeModel *model = (GtkTreeModel *)user_data;
1328 GtkTreeIter iter;
1329 GtkTreePath *path;
1330 char *servname;
1331 ircserver *serv;
1333 if (!selected_net)
1334 return;
1336 path = gtk_tree_path_new_from_string (arg1);
1338 if (!gtk_tree_model_get_iter (model, &iter, path))
1340 gtk_tree_path_free (path);
1341 return;
1344 gtk_tree_model_get (model, &iter, 0, &servname, -1);
1345 serv = servlist_server_find (selected_net, servname, NULL);
1346 g_free (servname);
1348 if (serv)
1350 /* delete empty item */
1351 if (arg2[0] == 0)
1353 servlist_deleteserver (serv, model);
1354 gtk_tree_path_free (path);
1355 return;
1358 servname = serv->hostname;
1359 serv->hostname = servlist_sanitize_hostname (arg2);
1360 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, serv->hostname, -1);
1361 free (servname);
1364 gtk_tree_path_free (path);
1367 static void
1368 servlist_combo_cb (GtkEntry *entry, gpointer userdata)
1370 if (!selected_net)
1371 return;
1373 if (!ignore_changed)
1375 if (selected_net->encoding)
1376 free (selected_net->encoding);
1377 selected_net->encoding = strdup (entry->text);
1380 /* EXTERNAL uses a cert, not a pass */
1381 if (selected_net->logintype == LOGIN_SASLEXTERNAL)
1382 gtk_widget_set_sensitive (edit_entry_pass, FALSE);
1383 else
1384 gtk_widget_set_sensitive (edit_entry_pass, TRUE);
1387 /* Fills up the network's authentication type so that it's guaranteed to be either NULL or a valid value. */
1388 static void
1389 servlist_logintypecombo_cb (GtkEntry *entry, gpointer userdata)
1391 int index;
1393 if (!selected_net)
1395 return;
1398 if (!ignore_changed)
1400 index = gtk_combo_box_get_active (GTK_COMBO_BOX (entry)); /* starts at 0, returns -1 for invalid selections */
1402 if (index != -1)
1404 /* The selection is valid. It can be 0, which is the default type, but we need to allow
1405 * that so that you can revert from other types. servlist_save() will dump 0 anyway.
1407 selected_net->logintype = login_types_conf[index];
1410 #if 0
1411 if (login_types_conf[index] == LOGIN_CUSTOM)
1413 gtk_notebook_set_current_page (GTK_NOTEBOOK (userdata), 2); /* FIXME avoid hardcoding? */
1415 #endif
1419 static GtkWidget *
1420 servlist_create_charsetcombo (void)
1422 GtkWidget *cb;
1423 int i;
1425 cb = gtk_combo_box_entry_new_text ();
1426 gtk_combo_box_append_text (GTK_COMBO_BOX (cb), "System default");
1427 i = 0;
1428 while (pages[i])
1430 gtk_combo_box_append_text (GTK_COMBO_BOX (cb), (char *)pages[i]);
1431 i++;
1433 g_signal_connect (G_OBJECT (GTK_BIN (cb)->child), "changed",
1434 G_CALLBACK (servlist_combo_cb), NULL);
1436 return cb;
1439 static GtkWidget *
1440 servlist_create_logintypecombo (void)
1442 GtkWidget *cb;
1443 int i;
1445 cb = gtk_combo_box_entry_new_text ();
1447 i = 0;
1449 while (login_types[i])
1451 gtk_combo_box_append_text (GTK_COMBO_BOX (cb), (char *)login_types[i]);
1452 i++;
1455 g_signal_connect (G_OBJECT (GTK_BIN (cb)), "changed", G_CALLBACK (servlist_logintypecombo_cb), NULL);
1457 return cb;
1460 static void
1461 no_servlist (GtkWidget * igad, gpointer serv)
1463 if (GTK_TOGGLE_BUTTON (igad)->active)
1464 prefs.slist_skip = TRUE;
1465 else
1466 prefs.slist_skip = FALSE;
1469 static void
1470 fav_servlist (GtkWidget * igad, gpointer serv)
1472 if (GTK_TOGGLE_BUTTON (igad)->active)
1473 prefs.slist_fav = TRUE;
1474 else
1475 prefs.slist_fav = FALSE;
1477 servlist_networks_populate (networks_tree, network_list);
1480 static GtkWidget *
1481 bold_label (char *text)
1483 char buf[128];
1484 GtkWidget *label;
1486 snprintf (buf, sizeof (buf), "<b>%s</b>", text);
1487 label = gtk_label_new (buf);
1488 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
1489 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
1490 gtk_widget_show (label);
1492 return label;
1495 static GtkWidget *
1496 servlist_open_edit (GtkWidget *parent, ircnet *net)
1498 GtkWidget *editwindow;
1499 GtkWidget *vbox5;
1500 GtkWidget *table3;
1501 GtkWidget *label17;
1502 GtkWidget *label16;
1503 GtkWidget *label21;
1504 GtkWidget *label34;
1505 GtkWidget *label_logintype;
1506 GtkWidget *comboboxentry_charset;
1507 GtkWidget *comboboxentry_logintypes;
1508 GtkWidget *hbox1;
1509 GtkWidget *scrolledwindow2;
1510 GtkWidget *treeview_servers;
1511 GtkWidget *vbuttonbox1;
1512 GtkWidget *buttonadd;
1513 GtkWidget *buttonremove;
1514 GtkWidget *buttonedit;
1515 GtkWidget *hseparator2;
1516 GtkWidget *hbuttonbox4;
1517 GtkWidget *button10;
1518 GtkWidget *check;
1519 GtkTreeModel *model;
1520 GtkListStore *store;
1521 GtkCellRenderer *renderer;
1522 char buf[128];
1523 char buf2[128 + 8];
1525 editwindow = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1526 gtk_container_set_border_width (GTK_CONTAINER (editwindow), 4);
1527 snprintf (buf, sizeof (buf), _("XChat: Edit %s"), net->name);
1528 gtk_window_set_title (GTK_WINDOW (editwindow), buf);
1529 gtk_window_set_default_size (GTK_WINDOW (editwindow), 354, 0);
1530 gtk_window_set_position (GTK_WINDOW (editwindow), GTK_WIN_POS_MOUSE);
1531 gtk_window_set_transient_for (GTK_WINDOW (editwindow), GTK_WINDOW (parent));
1532 gtk_window_set_modal (GTK_WINDOW (editwindow), TRUE);
1533 gtk_window_set_type_hint (GTK_WINDOW (editwindow), GDK_WINDOW_TYPE_HINT_DIALOG);
1534 gtk_window_set_role (GTK_WINDOW (editwindow), "editserv");
1536 vbox5 = gtk_vbox_new (FALSE, 0);
1537 gtk_widget_show (vbox5);
1538 gtk_container_add (GTK_CONTAINER (editwindow), vbox5);
1540 table3 = gtk_table_new (17, 3, FALSE);
1541 gtk_widget_show (table3);
1542 gtk_box_pack_start (GTK_BOX (vbox5), table3, TRUE, TRUE, 0);
1543 gtk_table_set_row_spacings (GTK_TABLE (table3), 2);
1544 gtk_table_set_col_spacings (GTK_TABLE (table3), 8);
1546 snprintf (buf, sizeof (buf), _("Servers for %s"), net->name);
1547 snprintf (buf2, sizeof (buf2), "<b>%s</b>", buf);
1548 label16 = gtk_label_new (buf2);
1549 gtk_widget_show (label16);
1550 gtk_table_attach (GTK_TABLE (table3), label16, 0, 3, 0, 1,
1551 (GtkAttachOptions) (GTK_FILL),
1552 (GtkAttachOptions) (0), 0, 3);
1553 gtk_label_set_use_markup (GTK_LABEL (label16), TRUE);
1554 gtk_misc_set_alignment (GTK_MISC (label16), 0, 0.5);
1556 check = servlist_create_check (0, !(net->flags & FLAG_CYCLE), table3,
1557 2, 1, _("Connect to selected server only"));
1558 add_tip (check, _("Don't cycle through all the servers when the connection fails."));
1560 label17 = bold_label (_("Your Details"));
1561 gtk_table_attach (GTK_TABLE (table3), label17, 0, 3, 3, 4,
1562 (GtkAttachOptions) (GTK_FILL),
1563 (GtkAttachOptions) (0), 0, 3);
1565 servlist_create_check (1, net->flags & FLAG_USE_GLOBAL, table3,
1566 4, 1, _("Use global user information"));
1568 edit_entry_nick =
1569 servlist_create_entry (table3, _("_Nick name:"), 5, net->nick,
1570 &edit_label_nick, 0);
1572 edit_entry_nick2 =
1573 servlist_create_entry (table3, _("Second choice:"), 6, net->nick2,
1574 &edit_label_nick2, 0);
1576 edit_entry_user =
1577 servlist_create_entry (table3, _("_User name:"), 7, net->user,
1578 &edit_label_user, 0);
1580 edit_entry_real =
1581 servlist_create_entry (table3, _("Rea_l name:"), 8, net->real,
1582 &edit_label_real, 0);
1584 label21 = bold_label (_("Connecting"));
1585 gtk_table_attach (GTK_TABLE (table3), label21, 0, 3, 9, 10,
1586 (GtkAttachOptions) (GTK_FILL),
1587 (GtkAttachOptions) (0), 0, 3);
1589 servlist_create_check (3, net->flags & FLAG_AUTO_CONNECT, table3,
1590 11, 1, _("Auto connect to this network at startup"));
1591 servlist_create_check (4, !(net->flags & FLAG_USE_PROXY), table3,
1592 12, 1, _("Bypass proxy server"));
1593 check = servlist_create_check (2, net->flags & FLAG_USE_SSL, table3,
1594 13, 1, _("Use SSL for all the servers on this network"));
1595 #ifndef USE_OPENSSL
1596 gtk_widget_set_sensitive (check, FALSE);
1597 #endif
1598 check = servlist_create_check (5, net->flags & FLAG_ALLOW_INVALID, table3,
1599 14, 1, _("Accept invalid SSL certificate"));
1600 #ifndef USE_OPENSSL
1601 gtk_widget_set_sensitive (check, FALSE);
1602 #endif
1604 edit_entry_join =
1605 servlist_create_entry (table3, _("_Favorite channels:"), 15,
1606 net->autojoin, 0,
1607 _("Channels to join, separated by commas, but not spaces!"));
1609 edit_entry_cmd =
1610 servlist_create_entry (table3, _("Connect command:"), 16,
1611 net->command, 0,
1612 _("Extra command to execute after connecting. If you need more than one, set this to LOAD -e <filename>, where <filename> is a text-file full of commands to execute."));
1614 label_logintype = gtk_label_new (_("Login method:"));
1615 gtk_widget_show (label_logintype);
1616 gtk_table_attach (GTK_TABLE (table3), label_logintype, 1, 2, 18, 19,
1617 (GtkAttachOptions) (GTK_FILL),
1618 (GtkAttachOptions) (0), 0, 0);
1619 gtk_misc_set_alignment (GTK_MISC (label_logintype), 0, 0.5);
1621 comboboxentry_logintypes = servlist_create_logintypecombo ();
1622 ignore_changed = TRUE;
1623 gtk_entry_set_text (GTK_ENTRY (GTK_BIN (comboboxentry_logintypes)->child), net->logintype ? login_types[servlist_get_login_desc_index (net->logintype)] : login_types[0]);
1624 ignore_changed = FALSE;
1625 gtk_widget_show (comboboxentry_logintypes);
1626 gtk_table_attach (GTK_TABLE (table3), comboboxentry_logintypes, 2, 3, 18, 19,
1627 (GtkAttachOptions) (GTK_FILL),
1628 (GtkAttachOptions) (GTK_FILL), 0, 0);
1630 edit_entry_pass =
1631 servlist_create_entry (table3, _("Password:"), 20,
1632 net->pass, 0,
1633 _("Password used for login. If in doubt, leave blank."));
1634 gtk_entry_set_visibility (GTK_ENTRY (edit_entry_pass), FALSE);
1635 if (selected_net && selected_net->logintype == LOGIN_SASLEXTERNAL)
1636 gtk_widget_set_sensitive (edit_entry_pass, FALSE);
1639 label34 = gtk_label_new (_("Character set:"));
1640 gtk_widget_show (label34);
1641 gtk_table_attach (GTK_TABLE (table3), label34, 1, 2, 21, 22,
1642 (GtkAttachOptions) (GTK_FILL),
1643 (GtkAttachOptions) (0), 0, 0);
1644 gtk_misc_set_alignment (GTK_MISC (label34), 0, 0.5);
1646 comboboxentry_charset = servlist_create_charsetcombo ();
1647 ignore_changed = TRUE;
1648 gtk_entry_set_text (GTK_ENTRY (GTK_BIN (comboboxentry_charset)->child), net->encoding ? net->encoding : "System default");
1649 ignore_changed = FALSE;
1650 gtk_widget_show (comboboxentry_charset);
1651 gtk_table_attach (GTK_TABLE (table3), comboboxentry_charset, 2, 3, 21, 22,
1652 (GtkAttachOptions) (GTK_FILL),
1653 (GtkAttachOptions) (GTK_FILL), 0, 0);
1655 hbox1 = gtk_hbox_new (FALSE, 0);
1656 gtk_widget_show (hbox1);
1657 gtk_table_attach (GTK_TABLE (table3), hbox1, 1, 3, 1, 2,
1658 (GtkAttachOptions) (GTK_FILL),
1659 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1661 scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL);
1662 gtk_widget_show (scrolledwindow2);
1663 gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow2, TRUE, TRUE, 0);
1664 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2),
1665 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
1666 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow2),
1667 GTK_SHADOW_IN);
1669 store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN);
1670 model = GTK_TREE_MODEL (store);
1672 edit_tree = treeview_servers = gtk_tree_view_new_with_model (model);
1673 g_object_unref (model);
1674 gtk_widget_show (treeview_servers);
1675 gtk_container_add (GTK_CONTAINER (scrolledwindow2), treeview_servers);
1676 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview_servers),
1677 FALSE);
1679 renderer = gtk_cell_renderer_text_new ();
1680 g_signal_connect (G_OBJECT (renderer), "edited",
1681 G_CALLBACK (servlist_editserver_cb), model);
1682 gtk_tree_view_insert_column_with_attributes (
1683 GTK_TREE_VIEW (treeview_servers), -1,
1684 0, renderer,
1685 "text", 0,
1686 "editable", 1,
1687 NULL);
1689 vbuttonbox1 = gtk_vbutton_box_new ();
1690 gtk_box_set_spacing (GTK_BOX (vbuttonbox1), 3);
1691 gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox1), GTK_BUTTONBOX_START);
1692 gtk_widget_show (vbuttonbox1);
1693 gtk_box_pack_start (GTK_BOX (hbox1), vbuttonbox1, FALSE, FALSE, 3);
1695 buttonadd = gtk_button_new_from_stock ("gtk-add");
1696 g_signal_connect (G_OBJECT (buttonadd), "clicked",
1697 G_CALLBACK (servlist_addserver_cb), edit_tree);
1698 gtk_widget_show (buttonadd);
1699 gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonadd);
1700 GTK_WIDGET_SET_FLAGS (buttonadd, GTK_CAN_DEFAULT);
1702 buttonremove = gtk_button_new_from_stock ("gtk-remove");
1703 g_signal_connect (G_OBJECT (buttonremove), "clicked",
1704 G_CALLBACK (servlist_deleteserver_cb), NULL);
1705 gtk_widget_show (buttonremove);
1706 gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonremove);
1707 GTK_WIDGET_SET_FLAGS (buttonremove, GTK_CAN_DEFAULT);
1709 buttonedit = gtk_button_new_with_mnemonic (_("_Edit"));
1710 g_signal_connect (G_OBJECT (buttonedit), "clicked",
1711 G_CALLBACK (servlist_editserverbutton_cb), NULL);
1712 gtk_widget_show (buttonedit);
1713 gtk_container_add (GTK_CONTAINER (vbuttonbox1), buttonedit);
1714 GTK_WIDGET_SET_FLAGS (buttonedit, GTK_CAN_DEFAULT);
1716 hseparator2 = gtk_hseparator_new ();
1717 gtk_widget_show (hseparator2);
1718 gtk_box_pack_start (GTK_BOX (vbox5), hseparator2, FALSE, FALSE, 8);
1720 hbuttonbox4 = gtk_hbutton_box_new ();
1721 gtk_widget_show (hbuttonbox4);
1722 gtk_box_pack_start (GTK_BOX (vbox5), hbuttonbox4, FALSE, FALSE, 0);
1723 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox4),
1724 GTK_BUTTONBOX_END);
1726 button10 = gtk_button_new_from_stock ("gtk-close");
1727 g_signal_connect (G_OBJECT (button10), "clicked",
1728 G_CALLBACK (servlist_edit_close_cb), 0);
1729 gtk_widget_show (button10);
1730 gtk_container_add (GTK_CONTAINER (hbuttonbox4), button10);
1731 GTK_WIDGET_SET_FLAGS (button10, GTK_CAN_DEFAULT);
1733 if (net->flags & FLAG_USE_GLOBAL)
1735 gtk_widget_hide (edit_label_nick);
1736 gtk_widget_hide (edit_entry_nick);
1738 gtk_widget_hide (edit_label_nick2);
1739 gtk_widget_hide (edit_entry_nick2);
1741 gtk_widget_hide (edit_label_user);
1742 gtk_widget_hide (edit_entry_user);
1744 gtk_widget_hide (edit_label_real);
1745 gtk_widget_hide (edit_entry_real);
1748 gtk_widget_grab_focus (button10);
1749 gtk_widget_grab_default (button10);
1751 return editwindow;
1754 static GtkWidget *
1755 servlist_open_networks (void)
1757 GtkWidget *servlist;
1758 GtkWidget *vbox1;
1759 GtkWidget *label2;
1760 GtkWidget *table1;
1761 GtkWidget *label3;
1762 GtkWidget *label4;
1763 GtkWidget *label5;
1764 GtkWidget *label6;
1765 GtkWidget *label7;
1766 GtkWidget *entry1;
1767 GtkWidget *entry2;
1768 GtkWidget *entry3;
1769 GtkWidget *entry4;
1770 GtkWidget *entry5;
1771 GtkWidget *vbox2;
1772 GtkWidget *label1;
1773 GtkWidget *table4;
1774 GtkWidget *scrolledwindow3;
1775 GtkWidget *treeview_networks;
1776 GtkWidget *checkbutton_skip;
1777 GtkWidget *checkbutton_fav;
1778 GtkWidget *hbox;
1779 GtkWidget *vbuttonbox2;
1780 GtkWidget *button_add;
1781 GtkWidget *button_remove;
1782 GtkWidget *button_edit;
1783 GtkWidget *button_sort;
1784 GtkWidget *hseparator1;
1785 GtkWidget *hbuttonbox1;
1786 GtkWidget *button_connect;
1787 GtkWidget *button_close;
1788 GtkTreeModel *model;
1789 GtkListStore *store;
1790 GtkCellRenderer *renderer;
1792 servlist = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1793 gtk_container_set_border_width (GTK_CONTAINER (servlist), 4);
1794 gtk_window_set_title (GTK_WINDOW (servlist), _("XChat: Network List"));
1795 gtk_window_set_default_size (GTK_WINDOW (servlist), win_width, win_height);
1796 gtk_window_set_position (GTK_WINDOW (servlist), GTK_WIN_POS_MOUSE);
1797 gtk_window_set_role (GTK_WINDOW (servlist), "servlist");
1798 gtk_window_set_type_hint (GTK_WINDOW (servlist), GDK_WINDOW_TYPE_HINT_DIALOG);
1799 if (current_sess)
1800 gtk_window_set_transient_for (GTK_WINDOW (servlist), GTK_WINDOW (current_sess->gui->window));
1802 vbox1 = gtk_vbox_new (FALSE, 0);
1803 gtk_widget_show (vbox1);
1804 gtk_container_add (GTK_CONTAINER (servlist), vbox1);
1806 label2 = bold_label (_("User Information"));
1807 gtk_box_pack_start (GTK_BOX (vbox1), label2, FALSE, FALSE, 0);
1809 table1 = gtk_table_new (5, 2, FALSE);
1810 gtk_widget_show (table1);
1811 gtk_box_pack_start (GTK_BOX (vbox1), table1, FALSE, FALSE, 0);
1812 gtk_container_set_border_width (GTK_CONTAINER (table1), 8);
1813 gtk_table_set_row_spacings (GTK_TABLE (table1), 2);
1814 gtk_table_set_col_spacings (GTK_TABLE (table1), 4);
1816 label3 = gtk_label_new_with_mnemonic (_("_Nick name:"));
1817 gtk_widget_show (label3);
1818 gtk_table_attach (GTK_TABLE (table1), label3, 0, 1, 0, 1,
1819 (GtkAttachOptions) (GTK_FILL),
1820 (GtkAttachOptions) (0), 0, 0);
1821 gtk_misc_set_alignment (GTK_MISC (label3), 0, 0.5);
1823 label4 = gtk_label_new (_("Second choice:"));
1824 gtk_widget_show (label4);
1825 gtk_table_attach (GTK_TABLE (table1), label4, 0, 1, 1, 2,
1826 (GtkAttachOptions) (GTK_FILL),
1827 (GtkAttachOptions) (0), 0, 0);
1828 gtk_misc_set_alignment (GTK_MISC (label4), 0, 0.5);
1830 label5 = gtk_label_new (_("Third choice:"));
1831 gtk_widget_show (label5);
1832 gtk_table_attach (GTK_TABLE (table1), label5, 0, 1, 2, 3,
1833 (GtkAttachOptions) (GTK_FILL),
1834 (GtkAttachOptions) (0), 0, 0);
1835 gtk_misc_set_alignment (GTK_MISC (label5), 0, 0.5);
1837 label6 = gtk_label_new_with_mnemonic (_("_User name:"));
1838 gtk_widget_show (label6);
1839 gtk_table_attach (GTK_TABLE (table1), label6, 0, 1, 3, 4,
1840 (GtkAttachOptions) (GTK_FILL),
1841 (GtkAttachOptions) (0), 0, 0);
1842 gtk_misc_set_alignment (GTK_MISC (label6), 0, 0.5);
1844 label7 = gtk_label_new_with_mnemonic (_("Rea_l name:"));
1845 gtk_widget_show (label7);
1846 gtk_table_attach (GTK_TABLE (table1), label7, 0, 1, 4, 5,
1847 (GtkAttachOptions) (GTK_FILL),
1848 (GtkAttachOptions) (0), 0, 0);
1849 gtk_misc_set_alignment (GTK_MISC (label7), 0, 0.5);
1851 entry_nick1 = entry1 = gtk_entry_new ();
1852 gtk_entry_set_text (GTK_ENTRY (entry1), prefs.nick1);
1853 gtk_widget_show (entry1);
1854 gtk_table_attach (GTK_TABLE (table1), entry1, 1, 2, 0, 1,
1855 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1856 (GtkAttachOptions) (0), 0, 0);
1858 entry_nick2 = entry2 = gtk_entry_new ();
1859 gtk_entry_set_text (GTK_ENTRY (entry2), prefs.nick2);
1860 gtk_widget_show (entry2);
1861 gtk_table_attach (GTK_TABLE (table1), entry2, 1, 2, 1, 2,
1862 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1863 (GtkAttachOptions) (0), 0, 0);
1865 entry_nick3 = entry3 = gtk_entry_new ();
1866 gtk_entry_set_text (GTK_ENTRY (entry3), prefs.nick3);
1867 gtk_widget_show (entry3);
1868 gtk_table_attach (GTK_TABLE (table1), entry3, 1, 2, 2, 3,
1869 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1870 (GtkAttachOptions) (0), 0, 0);
1872 entry_guser = entry4 = gtk_entry_new ();
1873 gtk_entry_set_text (GTK_ENTRY (entry4), prefs.username);
1874 gtk_widget_show (entry4);
1875 gtk_table_attach (GTK_TABLE (table1), entry4, 1, 2, 3, 4,
1876 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1877 (GtkAttachOptions) (0), 0, 0);
1879 entry_greal = entry5 = gtk_entry_new ();
1880 gtk_entry_set_text (GTK_ENTRY (entry5), prefs.realname);
1881 gtk_widget_show (entry5);
1882 gtk_table_attach (GTK_TABLE (table1), entry5, 1, 2, 4, 5,
1883 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1884 (GtkAttachOptions) (0), 0, 0);
1886 vbox2 = gtk_vbox_new (FALSE, 0);
1887 gtk_widget_show (vbox2);
1888 gtk_box_pack_start (GTK_BOX (vbox1), vbox2, TRUE, TRUE, 0);
1890 label1 = bold_label (_("Networks"));
1891 gtk_box_pack_start (GTK_BOX (vbox2), label1, FALSE, FALSE, 0);
1893 table4 = gtk_table_new (2, 2, FALSE);
1894 gtk_widget_show (table4);
1895 gtk_box_pack_start (GTK_BOX (vbox2), table4, TRUE, TRUE, 0);
1896 gtk_container_set_border_width (GTK_CONTAINER (table4), 8);
1897 gtk_table_set_row_spacings (GTK_TABLE (table4), 2);
1898 gtk_table_set_col_spacings (GTK_TABLE (table4), 3);
1900 scrolledwindow3 = gtk_scrolled_window_new (NULL, NULL);
1901 gtk_widget_show (scrolledwindow3);
1902 gtk_table_attach (GTK_TABLE (table4), scrolledwindow3, 0, 1, 0, 1,
1903 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
1904 (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
1905 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow3),
1906 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
1907 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow3),
1908 GTK_SHADOW_IN);
1910 store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INT);
1911 model = GTK_TREE_MODEL (store);
1913 networks_tree = treeview_networks = gtk_tree_view_new_with_model (model);
1914 g_object_unref (model);
1915 gtk_widget_show (treeview_networks);
1916 gtk_container_add (GTK_CONTAINER (scrolledwindow3), treeview_networks);
1917 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview_networks),
1918 FALSE);
1920 renderer = gtk_cell_renderer_text_new ();
1921 g_signal_connect (G_OBJECT (renderer), "edited",
1922 G_CALLBACK (servlist_celledit_cb), model);
1923 gtk_tree_view_insert_column_with_attributes (
1924 GTK_TREE_VIEW (treeview_networks), -1,
1925 0, renderer,
1926 "text", 0,
1927 "editable", 1,
1928 "weight", 2,
1929 NULL);
1931 hbox = gtk_hbox_new (0, FALSE);
1932 gtk_table_attach (GTK_TABLE (table4), hbox, 0, 2, 1, 2,
1933 (GtkAttachOptions) (GTK_FILL),
1934 (GtkAttachOptions) (0), 0, 0);
1935 gtk_widget_show (hbox);
1937 checkbutton_skip =
1938 gtk_check_button_new_with_mnemonic (_("Skip network list on startup"));
1939 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton_skip),
1940 prefs.slist_skip);
1941 gtk_container_add (GTK_CONTAINER (hbox), checkbutton_skip);
1942 g_signal_connect (G_OBJECT (checkbutton_skip), "toggled",
1943 G_CALLBACK (no_servlist), 0);
1944 gtk_widget_show (checkbutton_skip);
1946 checkbutton_fav =
1947 gtk_check_button_new_with_mnemonic (_("Show favorites only"));
1948 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton_fav),
1949 prefs.slist_fav);
1950 gtk_container_add (GTK_CONTAINER (hbox), checkbutton_fav);
1951 g_signal_connect (G_OBJECT (checkbutton_fav), "toggled",
1952 G_CALLBACK (fav_servlist), 0);
1953 gtk_widget_show (checkbutton_fav);
1955 vbuttonbox2 = gtk_vbutton_box_new ();
1956 gtk_box_set_spacing (GTK_BOX (vbuttonbox2), 3);
1957 gtk_button_box_set_layout (GTK_BUTTON_BOX (vbuttonbox2), GTK_BUTTONBOX_START);
1958 gtk_widget_show (vbuttonbox2);
1959 gtk_table_attach (GTK_TABLE (table4), vbuttonbox2, 1, 2, 0, 1,
1960 (GtkAttachOptions) (GTK_FILL),
1961 (GtkAttachOptions) (GTK_FILL), 0, 0);
1963 button_add = gtk_button_new_from_stock ("gtk-add");
1964 g_signal_connect (G_OBJECT (button_add), "clicked",
1965 G_CALLBACK (servlist_addnet_cb), networks_tree);
1966 gtk_widget_show (button_add);
1967 gtk_container_add (GTK_CONTAINER (vbuttonbox2), button_add);
1968 GTK_WIDGET_SET_FLAGS (button_add, GTK_CAN_DEFAULT);
1970 button_remove = gtk_button_new_from_stock ("gtk-remove");
1971 g_signal_connect (G_OBJECT (button_remove), "clicked",
1972 G_CALLBACK (servlist_deletenet_cb), 0);
1973 gtk_widget_show (button_remove);
1974 gtk_container_add (GTK_CONTAINER (vbuttonbox2), button_remove);
1975 GTK_WIDGET_SET_FLAGS (button_remove, GTK_CAN_DEFAULT);
1977 button_edit = gtk_button_new_with_mnemonic (_("_Edit..."));
1978 g_signal_connect (G_OBJECT (button_edit), "clicked",
1979 G_CALLBACK (servlist_edit_cb), 0);
1980 gtk_widget_show (button_edit);
1981 gtk_container_add (GTK_CONTAINER (vbuttonbox2), button_edit);
1982 GTK_WIDGET_SET_FLAGS (button_edit, GTK_CAN_DEFAULT);
1984 button_sort = gtk_button_new_with_mnemonic (_("_Sort"));
1985 add_tip (button_sort, _("Sorts the network list in alphabetical order. "
1986 "Use SHIFT-UP and SHIFT-DOWN keys to move a row."));
1987 g_signal_connect (G_OBJECT (button_sort), "clicked",
1988 G_CALLBACK (servlist_sort), 0);
1989 gtk_widget_show (button_sort);
1990 gtk_container_add (GTK_CONTAINER (vbuttonbox2), button_sort);
1991 GTK_WIDGET_SET_FLAGS (button_sort, GTK_CAN_DEFAULT);
1993 button_sort = gtk_button_new_with_mnemonic (_("_Favor"));
1994 add_tip (button_sort, _("Mark or unmark this network as a favorite."));
1995 g_signal_connect (G_OBJECT (button_sort), "clicked",
1996 G_CALLBACK (servlist_favor), 0);
1997 gtk_widget_show (button_sort);
1998 gtk_container_add (GTK_CONTAINER (vbuttonbox2), button_sort);
1999 GTK_WIDGET_SET_FLAGS (button_sort, GTK_CAN_DEFAULT);
2001 hseparator1 = gtk_hseparator_new ();
2002 gtk_widget_show (hseparator1);
2003 gtk_box_pack_start (GTK_BOX (vbox1), hseparator1, FALSE, TRUE, 4);
2005 hbuttonbox1 = gtk_hbutton_box_new ();
2006 gtk_widget_show (hbuttonbox1);
2007 gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox1, FALSE, TRUE, 0);
2008 gtk_container_set_border_width (GTK_CONTAINER (hbuttonbox1), 8);
2010 button_close = gtk_button_new_from_stock ("gtk-close");
2011 gtk_widget_show (button_close);
2012 g_signal_connect (G_OBJECT (button_close), "clicked",
2013 G_CALLBACK (servlist_close_cb), 0);
2014 gtk_container_add (GTK_CONTAINER (hbuttonbox1), button_close);
2015 GTK_WIDGET_SET_FLAGS (button_close, GTK_CAN_DEFAULT);
2017 button_connect = gtkutil_button (hbuttonbox1, GTK_STOCK_CONNECT, NULL,
2018 servlist_connect_cb, NULL, _("C_onnect"));
2019 GTK_WIDGET_SET_FLAGS (button_connect, GTK_CAN_DEFAULT);
2021 gtk_label_set_mnemonic_widget (GTK_LABEL (label3), entry1);
2022 gtk_label_set_mnemonic_widget (GTK_LABEL (label6), entry4);
2023 gtk_label_set_mnemonic_widget (GTK_LABEL (label7), entry5);
2025 gtk_widget_grab_focus (networks_tree);
2026 gtk_widget_grab_default (button_close);
2027 return servlist;
2030 void
2031 fe_serverlist_open (session *sess)
2033 if (serverlist_win)
2035 gtk_window_present (GTK_WINDOW (serverlist_win));
2036 return;
2039 servlist_sess = sess;
2041 serverlist_win = servlist_open_networks ();
2042 gtkutil_set_icon (serverlist_win);
2044 servlist_networks_populate (networks_tree, network_list);
2046 g_signal_connect (G_OBJECT (serverlist_win), "delete_event",
2047 G_CALLBACK (servlist_delete_cb), 0);
2048 g_signal_connect (G_OBJECT (serverlist_win), "configure_event",
2049 G_CALLBACK (servlist_configure_cb), 0);
2050 g_signal_connect (G_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (networks_tree))),
2051 "changed", G_CALLBACK (servlist_network_row_cb), NULL);
2052 g_signal_connect (G_OBJECT (networks_tree), "key_press_event",
2053 G_CALLBACK (servlist_net_keypress_cb), networks_tree);
2055 gtk_widget_show (serverlist_win);