2 * Copyright (C) 2004-2008 Peter Zelezny.
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"
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
;
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
[]=
90 "IRC (Latin/Unicode Hybrid)",
91 "ISO-8859-15 (Western Europe)",
92 "ISO-8859-2 (Central Europe)",
94 "ISO-8859-8 (Hebrew)",
95 "ISO-8859-9 (Turkish)",
96 "ISO-2022-JP (Japanese)",
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
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 */
137 static const char *login_types
[]=
140 "SASL (username + password)",
142 "SASL EXTERNAL (cert)",
144 "Server Password (/PASS password)",
145 "NickServ (/MSG NickServ + password)",
146 "NickServ (/NICKSERV + password)",
148 "Challenge Auth (username + password)",
150 "Custom... (connect commands)",
152 "NickServ (/NS + password)",
153 "NickServ (/MSG NS + password)",
154 "AUTH (/AUTH nickname password)",
159 /* poor man's IndexOf() - find the dropdown string index that belongs to the given config value */
161 servlist_get_login_desc_index (int conf_value
)
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
)
174 return 0; /* make the compiler happy */
178 servlist_select_and_show (GtkTreeView
*treeview
, GtkTreeIter
*iter
,
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
);
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
);
199 servlist_servers_populate (ircnet
*net
, GtkWidget
*treeview
)
205 GSList
*list
= net
->servlist
;
207 store
= (GtkListStore
*)gtk_tree_view_get_model (GTK_TREE_VIEW (treeview
));
208 gtk_list_store_clear (store
);
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
);
227 servlist_networks_populate_ (GtkWidget
*treeview
, GSList
*netlist
, gboolean favorites
)
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
);
247 if (!favorites
|| (net
->flags
& FLAG_FAVORITE
))
250 gtk_list_store_insert_with_values (store
, &iter
, 0x7fffffff, 0, net
->name
, 1, 1, 2, 400, -1);
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
);
261 netlist
= netlist
->next
;
266 servlist_networks_populate (GtkWidget
*treeview
, GSList
*netlist
)
268 servlist_networks_populate_ (treeview
, netlist
, prefs
.slist_fav
);
272 servlist_server_row_cb (GtkTreeSelection
*sel
, gpointer user_data
)
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
);
289 selected_net
->selected
= pos
;
290 selected_serv
= serv
;
295 servlist_start_editing (GtkTreeView
*tree
)
297 GtkTreeSelection
*sel
;
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
);
309 gtk_tree_view_set_cursor (tree
, path
,
310 gtk_tree_view_get_column (tree
, 0), TRUE
);
311 gtk_tree_path_free (path
);
317 servlist_addserver_cb (GtkWidget
*item
, GtkWidget
*treeview
)
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
);
339 servlist_addnet_cb (GtkWidget
*item
, GtkTreeView
*treeview
)
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
);
361 servlist_deletenetwork (ircnet
*net
)
363 GtkTreeSelection
*sel
;
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
);
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
);
391 servlist_move_server (ircserver
*serv
, int delta
)
395 pos
= g_slist_index (selected_net
->servlist
, serv
);
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
);
409 servlist_move_network (ircnet
*net
, int delta
)
413 pos
= g_slist_index (network_list
, net
);
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
);
428 servlist_net_keypress_cb (GtkWidget
*wid
, GdkEventKey
*evt
, gpointer tree
)
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);
449 servlist_serv_keypress_cb (GtkWidget
*wid
, GdkEventKey
*evt
, gpointer userdata
)
451 if (!selected_net
|| !selected_serv
)
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);
470 servlist_compare (ircnet
*net1
, ircnet
*net2
)
472 gchar
*net1_casefolded
, *net2_casefolded
;
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
);
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
);
495 servlist_has_selection (GtkTreeView
*tree
)
497 GtkTreeSelection
*sel
;
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
);
507 servlist_favor (GtkWidget
*button
, gpointer none
)
509 GtkTreeSelection
*sel
;
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
;
526 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
, 2, 800, -1);
527 selected_net
->flags
|= FLAG_FAVORITE
;
533 servlist_update_from_entry (char **str
, GtkWidget
*entry
)
538 if (GTK_ENTRY (entry
)->text
[0] == 0)
541 *str
= strdup (GTK_ENTRY (entry
)->text
);
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
);
558 servlist_edit_close_cb (GtkWidget
*button
, gpointer userdata
)
561 servlist_edit_update (selected_net
);
563 gtk_widget_destroy (edit_win
);
568 servlist_editwin_delete_cb (GtkWidget
*win
, GdkEventAny
*event
, gpointer none
)
570 servlist_edit_close_cb (NULL
, NULL
);
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
);
583 servlist_edit_cb (GtkWidget
*but
, gpointer none
)
585 if (!servlist_has_selection (GTK_TREE_VIEW (networks_tree
)))
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
);
601 servlist_deletenet_cb (GtkWidget
*item
, ircnet
*net
)
605 if (!servlist_has_selection (GTK_TREE_VIEW (networks_tree
)))
611 dialog
= gtk_message_dialog_new (GTK_WINDOW (serverlist_win
),
612 GTK_DIALOG_DESTROY_WITH_PARENT
|
614 GTK_MESSAGE_QUESTION
,
615 GTK_BUTTONS_OK_CANCEL
,
616 _("Really remove network \"%s\" and all its servers?"),
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
);
625 servlist_deleteserver (ircserver
*serv
, GtkTreeModel
*model
)
627 GtkTreeSelection
*sel
;
630 /* don't remove the last server */
631 if (selected_net
&& g_slist_length (selected_net
->servlist
) < 2)
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 */
641 servlist_server_remove (selected_net
, serv
);
645 servlist_editserverbutton_cb (GtkWidget
*item
, gpointer none
)
647 servlist_start_editing (GTK_TREE_VIEW (edit_tree
));
651 servlist_deleteserver_cb (GtkWidget
*item
, gpointer none
)
653 GtkTreeSelection
*sel
;
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
);
670 servlist_deleteserver (serv
, model
);
675 servlist_find_selected_net (GtkTreeSelection
*sel
)
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
);
689 prefs
.slist_select
= pos
;
696 servlist_network_row_cb (GtkTreeSelection
*sel
, gpointer user_data
)
702 net
= servlist_find_selected_net (sel
);
708 servlist_savegui (void)
712 /* check for blank username, ircd will not allow this */
713 if (GTK_ENTRY (entry_guser
)->text
[0] == 0)
716 if (GTK_ENTRY (entry_greal
)->text
[0] == 0)
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
, ' ');
725 sp
[0] = 0; /* spaces will break the login */
726 strcpy (prefs
.realname
, GTK_ENTRY (entry_greal
)->text
);
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
);
743 gtk_tree_path_free (path
);
748 servlist_editchannel_cb (GtkCellRendererText
*cell
, gchar
*name
, gchar
*newval
, GtkTreeModel
*model
)
751 static int loop_guard
= FALSE
;
756 if (!servlist_get_iter_from_name (model
, name
, &iter
))
760 /* delete empty item */
762 gtk_list_store_remove (GTK_LIST_STORE (model
), &iter
);
764 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
, 0, newval
, -1);
769 servlist_editkey_cb (GtkCellRendererText
*cell
, gchar
*name
, gchar
*newval
, GtkTreeModel
*model
)
773 if (!servlist_get_iter_from_name (model
, name
, &iter
))
776 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
, 1, newval
, -1);
780 servlist_addchannel (GtkWidget
*tree
, char *channel
)
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
));
796 servlist_addchannel_cb (GtkWidget
*item
, GtkWidget
*tree
)
798 servlist_addchannel (tree
, _("#channel"));
802 servlist_deletechannel_cb (GtkWidget
*item
, GtkWidget
*tree
)
804 GtkTreeSelection
*sel
;
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
);
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 */
825 servlist_autojoineditok_cb (GtkWidget
*button
, GtkWidget
*tree
)
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 */
845 keys
= g_slist_append (keys
, NULL
);
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
);
858 if (edit_win
&& selected_net
)
859 gtk_entry_set_text (GTK_ENTRY (edit_entry_join
), autojoin
);
862 if (fav_add_net
->autojoin
)
863 free (fav_add_net
->autojoin
);
864 fav_add_net
->autojoin
= strdup (autojoin
);
869 /* this does g_free too */
870 joinlist_free (channels
, keys
);
877 servlist_autojoinedit (ircnet
*net
, char *channel
, gboolean add
)
880 GtkWidget
*scrolledwindow
;
883 GtkCellRenderer
*renderer
;
891 GtkWidget
*vbuttonbox1
;
892 GtkWidget
*buttonadd
;
893 GtkWidget
*buttonremove
;
894 GtkWidget
*buttonedit
;
898 GSList
*channels
, *keys
;
899 GSList
*clist
, *klist
;
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
);
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
),
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
,
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
,
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
);
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
);
1022 joinlist_split (net
->autojoin
, &channels
, &keys
);
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
);
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
);
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
);
1058 gtk_widget_show (win
);
1062 servlist_autojoinedit_cb (GtkWidget
*button
, ircnet
*net
)
1064 servlist_autojoinedit (net
, NULL
, FALSE
);
1068 servlist_connect_cb (GtkWidget
*button
, gpointer userdata
)
1073 if (servlist_savegui () != 0)
1075 fe_message (_("User name and Real name cannot be left blank."), FE_MSG_ERROR
);
1079 if (!is_session (servlist_sess
))
1080 servlist_sess
= NULL
; /* open a new one */
1085 session
*chosen
= servlist_sess
;
1087 servlist_sess
= NULL
; /* open a new one */
1089 for (list
= sess_list
; list
; list
= list
->next
)
1092 if (sess
->server
->network
== selected_net
)
1094 servlist_sess
= sess
;
1095 if (sess
->server
->connected
)
1096 servlist_sess
= NULL
; /* open a new one */
1101 /* use the chosen one, if it's empty */
1102 if (!servlist_sess
&&
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
;
1119 servlist_celledit_cb (GtkCellRendererText
*cell
, gchar
*arg1
, gchar
*arg2
,
1122 GtkTreeModel
*model
= (GtkTreeModel
*)user_data
;
1131 path
= gtk_tree_path_new_from_string (arg1
);
1135 if (!gtk_tree_model_get_iter (model
, &iter
, path
))
1137 gtk_tree_path_free (path
);
1140 gtk_tree_model_get (model
, &iter
, 0, &netname
, -1);
1142 net
= servlist_net_find (netname
, NULL
, strcmp
);
1146 /* delete empty item */
1149 servlist_deletenetwork (net
);
1150 gtk_tree_path_free (path
);
1154 netname
= net
->name
;
1155 net
->name
= strdup (arg2
);
1156 gtk_list_store_set (GTK_LIST_STORE (model
), &iter
, 0, net
->name
, -1);
1160 gtk_tree_path_free (path
);
1164 servlist_check_cb (GtkWidget
*but
, gpointer num_p
)
1166 int num
= GPOINTER_TO_INT (num_p
);
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
);
1177 selected_net
->flags
|= (1 << num
);
1180 if (GTK_TOGGLE_BUTTON (but
)->active
)
1181 selected_net
->flags
|= (1 << num
);
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
);
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
);
1219 servlist_create_check (int num
, int state
, GtkWidget
*table
, int row
, int col
, char *labeltext
)
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
);
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
);
1243 gtk_widget_show (label
);
1244 gtk_table_attach (GTK_TABLE (table
), label
, 1, 2, row
, row
+1,
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);
1272 gtk_table_attach (GTK_TABLE (table
), entry
, 2, 3, row
, row
+1,
1273 GTK_FILL
|GTK_EXPAND
, 0, 0, 0);
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
)
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
)
1304 /* convert "host:port" format to "host/port" */
1307 servlist_sanitize_hostname (char *host
)
1311 ret
= strdup (host
);
1313 c
= strchr (ret
, ':');
1314 e
= strrchr (ret
, ':');
1316 /* if only one colon exists it's probably not IPv6 */
1324 servlist_editserver_cb (GtkCellRendererText
*cell
, gchar
*arg1
, gchar
*arg2
,
1327 GtkTreeModel
*model
= (GtkTreeModel
*)user_data
;
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
);
1344 gtk_tree_model_get (model
, &iter
, 0, &servname
, -1);
1345 serv
= servlist_server_find (selected_net
, servname
, NULL
);
1350 /* delete empty item */
1353 servlist_deleteserver (serv
, model
);
1354 gtk_tree_path_free (path
);
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);
1364 gtk_tree_path_free (path
);
1368 servlist_combo_cb (GtkEntry
*entry
, gpointer userdata
)
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
);
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. */
1389 servlist_logintypecombo_cb (GtkEntry
*entry
, gpointer userdata
)
1398 if (!ignore_changed
)
1400 index
= gtk_combo_box_get_active (GTK_COMBO_BOX (entry
)); /* starts at 0, returns -1 for invalid selections */
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
];
1411 if (login_types_conf
[index
] == LOGIN_CUSTOM
)
1413 gtk_notebook_set_current_page (GTK_NOTEBOOK (userdata
), 2); /* FIXME avoid hardcoding? */
1420 servlist_create_charsetcombo (void)
1425 cb
= gtk_combo_box_entry_new_text ();
1426 gtk_combo_box_append_text (GTK_COMBO_BOX (cb
), "System default");
1430 gtk_combo_box_append_text (GTK_COMBO_BOX (cb
), (char *)pages
[i
]);
1433 g_signal_connect (G_OBJECT (GTK_BIN (cb
)->child
), "changed",
1434 G_CALLBACK (servlist_combo_cb
), NULL
);
1440 servlist_create_logintypecombo (void)
1445 cb
= gtk_combo_box_entry_new_text ();
1449 while (login_types
[i
])
1451 gtk_combo_box_append_text (GTK_COMBO_BOX (cb
), (char *)login_types
[i
]);
1455 g_signal_connect (G_OBJECT (GTK_BIN (cb
)), "changed", G_CALLBACK (servlist_logintypecombo_cb
), NULL
);
1461 no_servlist (GtkWidget
* igad
, gpointer serv
)
1463 if (GTK_TOGGLE_BUTTON (igad
)->active
)
1464 prefs
.slist_skip
= TRUE
;
1466 prefs
.slist_skip
= FALSE
;
1470 fav_servlist (GtkWidget
* igad
, gpointer serv
)
1472 if (GTK_TOGGLE_BUTTON (igad
)->active
)
1473 prefs
.slist_fav
= TRUE
;
1475 prefs
.slist_fav
= FALSE
;
1477 servlist_networks_populate (networks_tree
, network_list
);
1481 bold_label (char *text
)
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
);
1496 servlist_open_edit (GtkWidget
*parent
, ircnet
*net
)
1498 GtkWidget
*editwindow
;
1505 GtkWidget
*label_logintype
;
1506 GtkWidget
*comboboxentry_charset
;
1507 GtkWidget
*comboboxentry_logintypes
;
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
;
1519 GtkTreeModel
*model
;
1520 GtkListStore
*store
;
1521 GtkCellRenderer
*renderer
;
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"));
1569 servlist_create_entry (table3
, _("_Nick name:"), 5, net
->nick
,
1570 &edit_label_nick
, 0);
1573 servlist_create_entry (table3
, _("Second choice:"), 6, net
->nick2
,
1574 &edit_label_nick2
, 0);
1577 servlist_create_entry (table3
, _("_User name:"), 7, net
->user
,
1578 &edit_label_user
, 0);
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"));
1596 gtk_widget_set_sensitive (check
, FALSE
);
1598 check
= servlist_create_check (5, net
->flags
& FLAG_ALLOW_INVALID
, table3
,
1599 14, 1, _("Accept invalid SSL certificate"));
1601 gtk_widget_set_sensitive (check
, FALSE
);
1605 servlist_create_entry (table3
, _("_Favorite channels:"), 15,
1607 _("Channels to join, separated by commas, but not spaces!"));
1610 servlist_create_entry (table3
, _("Connect command:"), 16,
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);
1631 servlist_create_entry (table3
, _("Password:"), 20,
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
),
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
),
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,
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
),
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
);
1755 servlist_open_networks (void)
1757 GtkWidget
*servlist
;
1774 GtkWidget
*scrolledwindow3
;
1775 GtkWidget
*treeview_networks
;
1776 GtkWidget
*checkbutton_skip
;
1777 GtkWidget
*checkbutton_fav
;
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
);
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
),
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
),
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,
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
);
1938 gtk_check_button_new_with_mnemonic (_("Skip network list on startup"));
1939 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton_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
);
1947 gtk_check_button_new_with_mnemonic (_("Show favorites only"));
1948 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (checkbutton_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
);
2031 fe_serverlist_open (session
*sess
)
2035 gtk_window_present (GTK_WINDOW (serverlist_win
));
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
);