2011-02-24 04:14:30 +01:00
/* X-Chat
* Copyright ( C ) 2004 - 2008 Peter Zelezny .
2013-03-31 21:44:48 +02:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
2011-02-24 04:14:30 +01:00
*/
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <ctype.h>
2026-03-24 23:00:09 -06:00
# include <sys/stat.h>
2011-02-24 04:14:30 +01:00
# include <gdk/gdkkeysyms.h>
2026-01-05 23:12:38 -07:00
# include "../common/zoitechat.h"
# include "../common/zoitechatc.h"
2011-02-24 04:14:30 +01:00
# include "../common/servlist.h"
# include "../common/cfgfiles.h"
# include "../common/fe.h"
2026-06-02 15:57:28 -06:00
# include "../common/secretstore.h"
2012-07-21 14:26:19 +02:00
# include "../common/util.h"
2011-02-24 04:14:30 +01:00
# include "fe-gtk.h"
# include "gtkutil.h"
# include "menu.h"
# include "pixmaps.h"
2012-10-21 03:03:38 +02:00
# include "fkeys.h"
2026-03-04 23:28:01 -07:00
# include "theme/theme-manager.h"
2011-02-24 04:14:30 +01:00
2013-05-11 15:22:28 +02:00
# define SERVLIST_X_PADDING 4 /* horizontal paddig in the network editor */
# define SERVLIST_Y_PADDING 0 /* vertical padding in the network editor */
2011-02-24 04:14:30 +01:00
2026-02-18 01:30:45 -07:00
# define ICON_SERVLIST_CONNECT "zc-menu-connect"
2026-01-30 15:27:01 -07:00
# define ICON_SERVLIST_ADD "list-add"
# define ICON_SERVLIST_REMOVE "list-remove"
2026-03-13 13:32:08 -06:00
# define ICON_SERVLIST_CLOSE "gtk-close"
2026-01-30 15:27:01 -07:00
# define ICON_SERVLIST_ERROR "dialog-error"
2021-05-23 06:58:18 +01:00
# ifdef USE_OPENSSL
2021-05-30 18:45:22 +01:00
# define DEFAULT_SERVER "newserver / 6697"
2021-05-23 06:58:18 +01:00
# else
2021-05-30 18:45:22 +01:00
# define DEFAULT_SERVER "newserver / 6667"
2021-05-23 06:58:18 +01:00
# endif
2011-02-24 04:14:30 +01:00
/* servlistgui.c globals */
static GtkWidget * serverlist_win = NULL ;
2013-05-11 15:58:52 +02:00
static GtkWidget * networks_tree ; /* network TreeView */
static int netlist_win_width = 0 ; /* don't hardcode pixels, just use as much as needed by default, save if resized */
static int netlist_win_height = 0 ;
static int netedit_win_width = 0 ;
static int netedit_win_height = 0 ;
2011-02-24 04:14:30 +01:00
2013-05-12 16:59:21 +02:00
static int netedit_active_tab = 0 ;
2011-02-24 04:14:30 +01:00
/* global user info */
static GtkWidget * entry_nick1 ;
static GtkWidget * entry_nick2 ;
static GtkWidget * entry_nick3 ;
static GtkWidget * entry_guser ;
2012-05-16 19:47:12 +02:00
/* static GtkWidget *entry_greal; */
2011-02-24 04:14:30 +01:00
2013-05-11 09:20:03 -04:00
enum {
SERVER_TREE ,
CHANNEL_TREE ,
CMD_TREE ,
N_TREES ,
} ;
2011-02-24 04:14:30 +01:00
/* edit area */
static GtkWidget * edit_win ;
static GtkWidget * edit_entry_nick ;
static GtkWidget * edit_entry_nick2 ;
static GtkWidget * edit_entry_user ;
static GtkWidget * edit_entry_real ;
static GtkWidget * edit_entry_pass ;
2026-06-02 15:57:28 -06:00
static GtkWidget * edit_check_show_pass ;
static GtkWidget * edit_check_use_keyring ;
static GtkWidget * edit_button_load_pass ;
static int edit_pass_changed ;
static char * edit_loaded_password ;
2011-02-24 04:14:30 +01:00
static GtkWidget * edit_label_nick ;
static GtkWidget * edit_label_nick2 ;
static GtkWidget * edit_label_real ;
static GtkWidget * edit_label_user ;
2013-05-11 09:20:03 -04:00
static GtkWidget * edit_trees [ N_TREES ] ;
2026-03-24 23:00:09 -06:00
static GtkWidget * edit_button_cert_generate ;
2026-03-30 11:46:08 -06:00
static GtkWidget * edit_button_cert_import ;
2026-03-24 23:00:09 -06:00
static GtkWidget * edit_button_cert_info ;
static GtkWidget * edit_button_cert_delete ;
2011-02-24 04:14:30 +01:00
static ircnet * selected_net = NULL ;
static ircserver * selected_serv = NULL ;
2013-05-20 13:19:20 -03:00
static commandentry * selected_cmd = NULL ;
static favchannel * selected_chan = NULL ;
2011-02-24 04:14:30 +01:00
static session * servlist_sess ;
static void servlist_network_row_cb ( GtkTreeSelection * sel , gpointer user_data ) ;
static GtkWidget * servlist_open_edit ( GtkWidget * parent , ircnet * net ) ;
2026-06-02 15:57:28 -06:00
static void
servlist_toggle_show_password_cb ( GtkToggleButton * toggle , gpointer userdata )
{
if ( gtk_toggle_button_get_active ( toggle ) )
{
if ( edit_loaded_password )
gtk_entry_set_text ( GTK_ENTRY ( userdata ) , edit_loaded_password ) ;
gtk_entry_set_visibility ( GTK_ENTRY ( userdata ) , TRUE ) ;
}
else
{
gtk_entry_set_visibility ( GTK_ENTRY ( userdata ) , FALSE ) ;
if ( edit_loaded_password & & ! edit_pass_changed )
gtk_entry_set_text ( GTK_ENTRY ( userdata ) , " *** " ) ;
}
}
static void
servlist_toggle_keyring_cb ( GtkToggleButton * toggle , gpointer userdata )
{
gboolean active = gtk_toggle_button_get_active ( toggle ) ;
gtk_widget_set_sensitive ( edit_button_load_pass , active ) ;
gtk_widget_set_sensitive ( edit_check_show_pass , active ) ;
if ( ! active )
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( edit_check_show_pass ) , FALSE ) ;
}
static void
servlist_password_changed_cb ( GtkEditable * editable , gpointer userdata )
{
edit_pass_changed = 1 ;
if ( edit_loaded_password & & strcmp ( gtk_entry_get_text ( GTK_ENTRY ( editable ) ) , " *** " ) )
{
memset ( edit_loaded_password , 0 , strlen ( edit_loaded_password ) ) ;
g_free ( edit_loaded_password ) ;
edit_loaded_password = NULL ;
}
}
static void
servlist_load_password_cb ( GtkWidget * button , gpointer userdata )
{
ircnet * net = userdata ;
char * password ;
if ( ! net | | ! net - > name )
return ;
password = secretstore_get_network_password ( net - > name ) ;
if ( ! password )
return ;
if ( edit_loaded_password )
{
memset ( edit_loaded_password , 0 , strlen ( edit_loaded_password ) ) ;
g_free ( edit_loaded_password ) ;
}
edit_loaded_password = g_strdup ( password ) ;
gtk_entry_set_text ( GTK_ENTRY ( edit_entry_pass ) , " *** " ) ;
edit_pass_changed = 0 ;
memset ( password , 0 , strlen ( password ) ) ;
g_free ( password ) ;
}
2026-03-24 23:00:09 -06:00
static char *
servlist_get_cert_file ( ircnet * net )
{
if ( ! net | | ! net - > name | | ! net - > name [ 0 ] )
return NULL ;
return g_strdup_printf ( " %s " G_DIR_SEPARATOR_S " certs " G_DIR_SEPARATOR_S " %s.pem " ,
get_xdir ( ) , net - > name ) ;
}
static gboolean
servlist_network_cert_exists ( ircnet * net )
{
char * cert_file ;
gboolean exists ;
cert_file = servlist_get_cert_file ( net ) ;
if ( ! cert_file )
return FALSE ;
exists = g_file_test ( cert_file , G_FILE_TEST_IS_REGULAR ) ;
g_free ( cert_file ) ;
return exists ;
}
static void
servlist_update_cert_buttons ( ircnet * net )
{
gboolean has_cert = servlist_network_cert_exists ( net ) ;
if ( edit_button_cert_generate )
gtk_widget_set_visible ( edit_button_cert_generate , ! has_cert ) ;
2026-03-30 11:46:08 -06:00
if ( edit_button_cert_import )
gtk_widget_set_visible ( edit_button_cert_import , ! has_cert ) ;
2026-03-24 23:00:09 -06:00
if ( edit_button_cert_info )
gtk_widget_set_visible ( edit_button_cert_info , has_cert ) ;
if ( edit_button_cert_delete )
gtk_widget_set_visible ( edit_button_cert_delete , has_cert ) ;
}
2026-03-30 11:46:08 -06:00
static void
servlist_import_client_cert_cb ( GtkWidget * button , gpointer userdata )
{
ircnet * net = ( ircnet * ) userdata ;
GtkWidget * dialog ;
GtkWidget * message ;
GtkFileFilter * filter ;
char * cert_dir ;
char * cert_file ;
char * source_file ;
char * contents ;
gsize length ;
if ( ! net | | ! net - > name | | ! net - > name [ 0 ] )
return ;
dialog = gtk_file_chooser_dialog_new ( _ ( " Import Client Certificate " ) ,
GTK_WINDOW ( edit_win ) ,
GTK_FILE_CHOOSER_ACTION_OPEN ,
_ ( " _Cancel " ) , GTK_RESPONSE_CANCEL ,
_ ( " _Open " ) , GTK_RESPONSE_ACCEPT ,
NULL ) ;
filter = gtk_file_filter_new ( ) ;
gtk_file_filter_set_name ( filter , _ ( " Certificate files " ) ) ;
gtk_file_filter_add_pattern ( filter , " *.pem " ) ;
gtk_file_filter_add_pattern ( filter , " *.crt " ) ;
gtk_file_filter_add_pattern ( filter , " *.cer " ) ;
gtk_file_chooser_add_filter ( GTK_FILE_CHOOSER ( dialog ) , filter ) ;
filter = gtk_file_filter_new ( ) ;
gtk_file_filter_set_name ( filter , _ ( " All files " ) ) ;
gtk_file_filter_add_pattern ( filter , " * " ) ;
gtk_file_chooser_add_filter ( GTK_FILE_CHOOSER ( dialog ) , filter ) ;
theme_manager_attach_window ( dialog ) ;
if ( gtk_dialog_run ( GTK_DIALOG ( dialog ) ) ! = GTK_RESPONSE_ACCEPT )
{
gtk_widget_destroy ( dialog ) ;
return ;
}
source_file = gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER ( dialog ) ) ;
gtk_widget_destroy ( dialog ) ;
if ( ! source_file )
return ;
cert_dir = g_build_filename ( get_xdir ( ) , " certs " , NULL ) ;
cert_file = servlist_get_cert_file ( net ) ;
contents = NULL ;
length = 0 ;
if ( cert_file & &
g_mkdir_with_parents ( cert_dir , 0700 ) = = 0 & &
g_file_get_contents ( source_file , & contents , & length , NULL ) & &
g_file_set_contents ( cert_file , contents , length , NULL ) )
{
chmod ( cert_file , 0600 ) ;
servlist_update_cert_buttons ( net ) ;
message = gtk_message_dialog_new ( GTK_WINDOW ( edit_win ) ,
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL ,
GTK_MESSAGE_INFO ,
GTK_BUTTONS_CLOSE ,
_ ( " Client certificate imported for \" %s \" . " ) ,
net - > name ) ;
}
else
{
message = gtk_message_dialog_new ( GTK_WINDOW ( edit_win ) ,
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL ,
GTK_MESSAGE_ERROR ,
GTK_BUTTONS_CLOSE ,
_ ( " Failed to import client certificate for \" %s \" . " ) ,
net - > name ) ;
}
theme_manager_attach_window ( message ) ;
g_signal_connect_swapped ( message , " response " , G_CALLBACK ( gtk_widget_destroy ) , message ) ;
gtk_widget_show ( message ) ;
g_free ( contents ) ;
g_free ( cert_file ) ;
g_free ( cert_dir ) ;
g_free ( source_file ) ;
}
2026-03-24 23:00:09 -06:00
static void
servlist_generate_client_cert_cb ( GtkWidget * button , gpointer userdata )
{
# ifdef USE_OPENSSL
ircnet * net = ( ircnet * ) userdata ;
GtkWidget * dialog ;
char * cert_dir ;
char * cert_file ;
char * key_file ;
char * crt_file ;
char * subject ;
2026-03-25 00:26:23 -06:00
char * openssl_conf ;
const char * conf_data ;
2026-03-24 23:00:09 -06:00
char * key_data ;
char * crt_data ;
char * pem_data ;
char * stderr_data ;
char * stdout_data ;
gsize key_len ;
gsize crt_len ;
gboolean spawned ;
gboolean success ;
gint status ;
2026-03-25 00:26:23 -06:00
char * argv [ 20 ] ;
2026-03-30 11:57:58 -06:00
char * * envp ;
2026-03-24 23:00:09 -06:00
if ( ! net | | ! net - > name | | ! net - > name [ 0 ] )
return ;
cert_dir = g_build_filename ( get_xdir ( ) , " certs " , NULL ) ;
cert_file = servlist_get_cert_file ( net ) ;
key_file = g_strdup_printf ( " %s " G_DIR_SEPARATOR_S " %s.key " , cert_dir , net - > name ) ;
crt_file = g_strdup_printf ( " %s " G_DIR_SEPARATOR_S " %s.crt " , cert_dir , net - > name ) ;
subject = g_strdup_printf ( " /CN=%s " , net - > name ) ;
2026-03-25 00:26:23 -06:00
openssl_conf = g_build_filename ( cert_dir , " openssl.cnf " , NULL ) ;
conf_data = " [req] \n "
" distinguished_name=req_distinguished_name \n "
" [req_distinguished_name] \n " ;
2026-03-24 23:00:09 -06:00
key_data = NULL ;
crt_data = NULL ;
pem_data = NULL ;
stderr_data = NULL ;
stdout_data = NULL ;
key_len = 0 ;
crt_len = 0 ;
success = FALSE ;
status = 0 ;
2026-03-30 11:57:58 -06:00
envp = g_environ_unsetenv ( g_get_environ ( ) , " LD_LIBRARY_PATH " ) ;
2026-03-24 23:00:09 -06:00
2026-03-25 00:26:23 -06:00
if ( g_mkdir_with_parents ( cert_dir , 0700 ) = = 0 & &
g_file_set_contents ( openssl_conf , conf_data , - 1 , NULL ) )
2026-03-24 23:00:09 -06:00
{
argv [ 0 ] = " openssl " ;
argv [ 1 ] = " req " ;
argv [ 2 ] = " -x509 " ;
argv [ 3 ] = " -newkey " ;
argv [ 4 ] = " ec " ;
argv [ 5 ] = " -pkeyopt " ;
argv [ 6 ] = " ec_paramgen_curve:P-256 " ;
argv [ 7 ] = " -sha256 " ;
argv [ 8 ] = " -days " ;
argv [ 9 ] = " 3650 " ;
argv [ 10 ] = " -nodes " ;
argv [ 11 ] = " -keyout " ;
argv [ 12 ] = key_file ;
argv [ 13 ] = " -out " ;
argv [ 14 ] = crt_file ;
2026-03-25 00:26:23 -06:00
argv [ 15 ] = " -config " ;
argv [ 16 ] = openssl_conf ;
argv [ 17 ] = " -subj " ;
argv [ 18 ] = subject ;
argv [ 19 ] = NULL ;
2026-03-24 23:00:09 -06:00
2026-03-30 11:57:58 -06:00
spawned = g_spawn_sync ( NULL , argv , envp , G_SPAWN_SEARCH_PATH , NULL , NULL ,
2026-03-24 23:00:09 -06:00
& stdout_data , & stderr_data , & status , NULL ) ;
if ( spawned & & g_spawn_check_exit_status ( status , NULL ) & &
g_file_get_contents ( key_file , & key_data , & key_len , NULL ) & &
g_file_get_contents ( crt_file , & crt_data , & crt_len , NULL ) )
{
pem_data = g_strconcat ( key_data , crt_data , NULL ) ;
if ( pem_data & & g_file_set_contents ( cert_file , pem_data , - 1 , NULL ) )
{
chmod ( cert_file , 0600 ) ;
success = TRUE ;
}
}
}
g_remove ( key_file ) ;
g_remove ( crt_file ) ;
2026-03-25 00:26:23 -06:00
g_remove ( openssl_conf ) ;
2026-03-24 23:00:09 -06:00
if ( success )
{
servlist_update_cert_buttons ( net ) ;
dialog = gtk_message_dialog_new ( GTK_WINDOW ( edit_win ) ,
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL ,
GTK_MESSAGE_INFO ,
GTK_BUTTONS_CLOSE ,
_ ( " Client certificate generated for \" %s \" . " ) ,
net - > name ) ;
}
else
{
dialog = gtk_message_dialog_new ( GTK_WINDOW ( edit_win ) ,
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL ,
GTK_MESSAGE_ERROR ,
GTK_BUTTONS_CLOSE ,
_ ( " Failed to generate the client certificate for \" %s \" . " ) ,
net - > name ) ;
if ( stderr_data & & stderr_data [ 0 ] )
gtk_message_dialog_format_secondary_text ( GTK_MESSAGE_DIALOG ( dialog ) , " %s " , stderr_data ) ;
}
theme_manager_attach_window ( dialog ) ;
g_signal_connect_swapped ( dialog , " response " , G_CALLBACK ( gtk_widget_destroy ) , dialog ) ;
gtk_widget_show ( dialog ) ;
g_free ( stdout_data ) ;
g_free ( stderr_data ) ;
g_free ( pem_data ) ;
g_free ( key_data ) ;
g_free ( crt_data ) ;
g_free ( subject ) ;
g_free ( crt_file ) ;
g_free ( key_file ) ;
2026-03-25 00:26:23 -06:00
g_free ( openssl_conf ) ;
2026-03-24 23:00:09 -06:00
g_free ( cert_file ) ;
g_free ( cert_dir ) ;
2026-03-30 11:57:58 -06:00
g_strfreev ( envp ) ;
2026-03-24 23:00:09 -06:00
# else
return ;
# endif
}
static void
servlist_cert_info_cb ( GtkWidget * button , gpointer userdata )
{
# ifdef USE_OPENSSL
ircnet * net = ( ircnet * ) userdata ;
GtkWidget * dialog ;
char * cert_file ;
char * stdout_data ;
char * stderr_data ;
gboolean spawned ;
gint status ;
char * argv [ 12 ] ;
2026-03-30 11:57:58 -06:00
char * * envp ;
2026-03-24 23:00:09 -06:00
cert_file = servlist_get_cert_file ( net ) ;
if ( ! cert_file )
return ;
stdout_data = NULL ;
stderr_data = NULL ;
status = 0 ;
2026-03-30 11:57:58 -06:00
envp = g_environ_unsetenv ( g_get_environ ( ) , " LD_LIBRARY_PATH " ) ;
2026-03-24 23:00:09 -06:00
argv [ 0 ] = " openssl " ;
argv [ 1 ] = " x509 " ;
argv [ 2 ] = " -in " ;
argv [ 3 ] = cert_file ;
argv [ 4 ] = " -noout " ;
argv [ 5 ] = " -subject " ;
argv [ 6 ] = " -issuer " ;
argv [ 7 ] = " -startdate " ;
argv [ 8 ] = " -enddate " ;
argv [ 9 ] = " -fingerprint " ;
argv [ 10 ] = " -sha256 " ;
argv [ 11 ] = NULL ;
2026-03-30 11:57:58 -06:00
spawned = g_spawn_sync ( NULL , argv , envp , G_SPAWN_SEARCH_PATH , NULL , NULL ,
2026-03-24 23:00:09 -06:00
& stdout_data , & stderr_data , & status , NULL ) ;
if ( spawned & & g_spawn_check_exit_status ( status , NULL ) & & stdout_data & & stdout_data [ 0 ] )
{
dialog = gtk_message_dialog_new ( GTK_WINDOW ( edit_win ) ,
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL ,
GTK_MESSAGE_INFO ,
GTK_BUTTONS_CLOSE ,
_ ( " Client certificate information for \" %s \" . " ) ,
net - > name ) ;
gtk_message_dialog_format_secondary_text ( GTK_MESSAGE_DIALOG ( dialog ) , " %s " , stdout_data ) ;
}
else
{
dialog = gtk_message_dialog_new ( GTK_WINDOW ( edit_win ) ,
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL ,
GTK_MESSAGE_ERROR ,
GTK_BUTTONS_CLOSE ,
_ ( " Failed to read client certificate information for \" %s \" . " ) ,
net - > name ) ;
if ( stderr_data & & stderr_data [ 0 ] )
gtk_message_dialog_format_secondary_text ( GTK_MESSAGE_DIALOG ( dialog ) , " %s " , stderr_data ) ;
}
theme_manager_attach_window ( dialog ) ;
g_signal_connect_swapped ( dialog , " response " , G_CALLBACK ( gtk_widget_destroy ) , dialog ) ;
gtk_widget_show ( dialog ) ;
g_free ( stdout_data ) ;
g_free ( stderr_data ) ;
g_free ( cert_file ) ;
2026-03-30 11:57:58 -06:00
g_strfreev ( envp ) ;
2026-03-24 23:00:09 -06:00
# else
return ;
# endif
}
static void
servlist_delete_client_cert_cb ( GtkWidget * button , gpointer userdata )
{
ircnet * net = ( ircnet * ) userdata ;
GtkWidget * dialog ;
char * cert_file ;
cert_file = servlist_get_cert_file ( net ) ;
if ( ! cert_file )
return ;
if ( g_remove ( cert_file ) = = 0 )
{
servlist_update_cert_buttons ( net ) ;
dialog = gtk_message_dialog_new ( GTK_WINDOW ( edit_win ) ,
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL ,
GTK_MESSAGE_INFO ,
GTK_BUTTONS_CLOSE ,
_ ( " Client certificate removed for \" %s \" . " ) ,
net - > name ) ;
}
else
{
dialog = gtk_message_dialog_new ( GTK_WINDOW ( edit_win ) ,
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL ,
GTK_MESSAGE_ERROR ,
GTK_BUTTONS_CLOSE ,
_ ( " Failed to remove client certificate for \" %s \" . " ) ,
net - > name ) ;
}
theme_manager_attach_window ( dialog ) ;
g_signal_connect_swapped ( dialog , " response " , G_CALLBACK ( gtk_widget_destroy ) , dialog ) ;
gtk_widget_show ( dialog ) ;
g_free ( cert_file ) ;
}
2026-01-30 15:27:01 -07:00
static GtkWidget *
servlist_icon_button_new ( const char * label , const char * icon_name )
{
GtkWidget * button ;
2026-03-27 10:38:26 -06:00
( void ) icon_name ;
2026-01-30 15:27:01 -07:00
button = gtk_button_new_with_mnemonic ( label ) ;
return button ;
}
2011-02-24 04:14:30 +01:00
static const char * pages [ ] =
{
2012-10-13 06:17:27 +02:00
IRC_DEFAULT_CHARSET ,
2015-01-18 02:10:04 -08:00
" CP1252 (Windows-1252) " ,
2011-02-24 04:14:30 +01:00
" ISO-8859-15 (Western Europe) " ,
" ISO-8859-2 (Central Europe) " ,
" ISO-8859-7 (Greek) " ,
" ISO-8859-8 (Hebrew) " ,
" ISO-8859-9 (Turkish) " ,
" ISO-2022-JP (Japanese) " ,
" SJIS (Japanese) " ,
" CP949 (Korean) " ,
" KOI8-R (Cyrillic) " ,
" CP1251 (Cyrillic) " ,
" CP1256 (Arabic) " ,
" CP1257 (Baltic) " ,
" GB18030 (Chinese) " ,
" TIS-620 (Thai) " ,
NULL
} ;
2013-05-10 23:52:47 +02:00
/* This is our dictionary for authentication types. Keep these in sync with
* login_types [ ] ! This allows us to re - order the login type dropdown in the
* network list without breaking config compatibility .
2013-05-11 02:40:08 +02:00
*
* Also make sure inbound_nickserv_login ( ) won ' t break , i . e . if you add a new
2026-01-05 23:12:38 -07:00
* type that is NickServ - based , add it there as well so that ZoiteChat knows to
2013-05-11 02:40:08 +02:00
* treat it as such .
2013-05-10 23:52:47 +02:00
*/
static int login_types_conf [ ] =
{
2013-05-13 13:22:25 +02:00
LOGIN_DEFAULT , /* default entry - we don't use this but it makes indexing consistent with login_types[] so it's nice */
LOGIN_SASL ,
2013-09-04 17:34:57 -04:00
# ifdef USE_OPENSSL
2013-09-02 14:24:37 -04:00
LOGIN_SASLEXTERNAL ,
2023-11-01 19:12:32 +01:00
LOGIN_SASL_SCRAM_SHA_1 ,
LOGIN_SASL_SCRAM_SHA_256 ,
LOGIN_SASL_SCRAM_SHA_512 ,
2013-09-04 17:34:57 -04:00
# endif
2013-05-13 13:22:25 +02:00
LOGIN_PASS ,
LOGIN_MSG_NICKSERV ,
LOGIN_NICKSERV ,
2013-09-04 17:34:57 -04:00
# ifdef USE_OPENSSL
2013-05-19 04:34:20 +02:00
LOGIN_CHALLENGEAUTH ,
2013-09-04 17:34:57 -04:00
# endif
2013-05-19 04:34:20 +02:00
LOGIN_CUSTOM
2013-05-11 20:42:29 +02:00
#if 0
2013-05-13 13:22:25 +02:00
LOGIN_NS ,
2013-05-19 05:17:13 +02:00
LOGIN_MSG_NS ,
2013-05-13 13:22:25 +02:00
LOGIN_AUTH ,
2013-05-17 01:39:28 +02:00
# endif
2013-05-10 23:52:47 +02:00
} ;
static const char * login_types [ ] =
2013-04-28 21:24:53 +02:00
{
2013-05-10 23:52:47 +02:00
" Default " ,
2023-11-01 19:12:32 +01:00
" SASL PLAIN (username + password) " ,
2013-09-04 17:34:57 -04:00
# ifdef USE_OPENSSL
2013-09-02 14:24:37 -04:00
" SASL EXTERNAL (cert) " ,
2023-11-01 19:12:32 +01:00
" SASL SCRAM-SHA-1 " ,
" SASL SCRAM-SHA-256 " ,
" SASL SCRAM-SHA-512 " ,
2013-09-04 17:34:57 -04:00
# endif
2017-08-19 20:48:50 +02:00
" Server password (/PASS password) " ,
2013-05-11 20:42:29 +02:00
" NickServ (/MSG NickServ + password) " ,
2013-05-12 16:37:32 +02:00
" NickServ (/NICKSERV + password) " ,
2013-09-04 17:34:57 -04:00
# ifdef USE_OPENSSL
2013-05-17 01:39:28 +02:00
" Challenge Auth (username + password) " ,
2013-09-04 17:34:57 -04:00
# endif
2013-05-19 04:34:20 +02:00
" Custom... (connect commands) " ,
2013-05-11 20:42:29 +02:00
#if 0
" NickServ (/NS + password) " ,
2013-05-19 05:17:13 +02:00
" NickServ (/MSG NS + password) " ,
2013-05-11 20:42:29 +02:00
" AUTH (/AUTH nickname password) " ,
2013-05-17 01:39:28 +02:00
# endif
2013-04-28 21:24:53 +02:00
NULL
} ;
2013-05-10 23:52:47 +02:00
/* poor man's IndexOf() - find the dropdown string index that belongs to the given config value */
static int
servlist_get_login_desc_index ( int conf_value )
{
int i ;
int length = sizeof ( login_types_conf ) / sizeof ( login_types_conf [ 0 ] ) ; /* the number of elements in the conf array */
for ( i = 0 ; i < length ; i + + )
{
if ( login_types_conf [ i ] = = conf_value )
{
return i ;
}
}
return 0 ; /* make the compiler happy */
}
2011-02-24 04:14:30 +01:00
static void
servlist_select_and_show ( GtkTreeView * treeview , GtkTreeIter * iter ,
GtkListStore * store )
{
GtkTreePath * path ;
GtkTreeSelection * sel ;
sel = gtk_tree_view_get_selection ( treeview ) ;
/* select this network */
gtk_tree_selection_select_iter ( sel , iter ) ;
/* and make sure it's visible */
path = gtk_tree_model_get_path ( GTK_TREE_MODEL ( store ) , iter ) ;
if ( path )
{
gtk_tree_view_scroll_to_cell ( treeview , path , NULL , TRUE , 0.5 , 0.5 ) ;
gtk_tree_view_set_cursor ( treeview , path , NULL , FALSE ) ;
gtk_tree_path_free ( path ) ;
}
}
2013-05-11 09:20:03 -04:00
static void
servlist_channels_populate ( ircnet * net , GtkWidget * treeview )
{
GtkListStore * store ;
GtkTreeIter iter ;
2013-05-12 05:44:32 +02:00
int i ;
favchannel * favchan ;
GSList * list = net - > favchanlist ;
2013-05-11 09:20:03 -04:00
2013-05-12 05:44:32 +02:00
store = ( GtkListStore * ) gtk_tree_view_get_model ( GTK_TREE_VIEW ( treeview ) ) ;
gtk_list_store_clear ( store ) ;
2013-05-11 09:20:03 -04:00
2013-05-12 05:44:32 +02:00
i = 0 ;
while ( list )
{
favchan = list - > data ;
gtk_list_store_append ( store , & iter ) ;
gtk_list_store_set ( store , & iter , 0 , favchan - > name , 1 , favchan - > key , 2 , TRUE , - 1 ) ;
2013-05-11 09:20:03 -04:00
2013-05-12 05:44:32 +02:00
if ( net - > selected = = i )
2013-05-11 09:20:03 -04:00
{
2013-05-12 05:44:32 +02:00
/* select this server */
servlist_select_and_show ( GTK_TREE_VIEW ( treeview ) , & iter , store ) ;
2013-05-11 09:20:03 -04:00
}
2013-05-12 05:44:32 +02:00
i + + ;
list = list - > next ;
2013-05-11 09:20:03 -04:00
}
}
2011-02-24 04:14:30 +01:00
static void
servlist_servers_populate ( ircnet * net , GtkWidget * treeview )
{
GtkListStore * store ;
GtkTreeIter iter ;
int i ;
ircserver * serv ;
GSList * list = net - > servlist ;
store = ( GtkListStore * ) gtk_tree_view_get_model ( GTK_TREE_VIEW ( treeview ) ) ;
gtk_list_store_clear ( store ) ;
i = 0 ;
while ( list )
{
serv = list - > data ;
gtk_list_store_append ( store , & iter ) ;
gtk_list_store_set ( store , & iter , 0 , serv - > hostname , 1 , 1 , - 1 ) ;
if ( net - > selected = = i )
2013-05-12 05:44:32 +02:00
{
2011-02-24 04:14:30 +01:00
/* select this server */
servlist_select_and_show ( GTK_TREE_VIEW ( treeview ) , & iter , store ) ;
2013-05-12 05:44:32 +02:00
}
2011-02-24 04:14:30 +01:00
i + + ;
list = list - > next ;
}
}
2013-05-11 20:06:22 +02:00
static void
servlist_commands_populate ( ircnet * net , GtkWidget * treeview )
{
GtkListStore * store ;
GtkTreeIter iter ;
int i ;
commandentry * entry ;
GSList * list = net - > commandlist ;
store = ( GtkListStore * ) gtk_tree_view_get_model ( GTK_TREE_VIEW ( treeview ) ) ;
gtk_list_store_clear ( store ) ;
i = 0 ;
while ( list )
{
entry = list - > data ;
gtk_list_store_append ( store , & iter ) ;
gtk_list_store_set ( store , & iter , 0 , entry - > command , 1 , 1 , - 1 ) ;
if ( net - > selected = = i )
{
/* select this server */
servlist_select_and_show ( GTK_TREE_VIEW ( treeview ) , & iter , store ) ;
}
i + + ;
list = list - > next ;
}
}
2011-02-24 04:14:30 +01:00
static void
servlist_networks_populate_ ( GtkWidget * treeview , GSList * netlist , gboolean favorites )
{
GtkListStore * store ;
GtkTreeIter iter ;
int i ;
ircnet * net ;
if ( ! netlist )
{
net = servlist_net_add ( _ ( " New Network " ) , " " , FALSE ) ;
2021-05-23 06:58:18 +01:00
servlist_server_add ( net , DEFAULT_SERVER ) ;
2011-02-24 04:14:30 +01:00
netlist = network_list ;
}
store = ( GtkListStore * ) gtk_tree_view_get_model ( GTK_TREE_VIEW ( treeview ) ) ;
gtk_list_store_clear ( store ) ;
i = 0 ;
while ( netlist )
{
net = netlist - > data ;
if ( ! favorites | | ( net - > flags & FLAG_FAVORITE ) )
{
if ( favorites )
gtk_list_store_insert_with_values ( store , & iter , 0x7fffffff , 0 , net - > name , 1 , 1 , 2 , 400 , - 1 ) ;
else
gtk_list_store_insert_with_values ( store , & iter , 0x7fffffff , 0 , net - > name , 1 , 1 , 2 , ( net - > flags & FLAG_FAVORITE ) ? 800 : 400 , - 1 ) ;
2012-10-22 13:49:28 +02:00
if ( i = = prefs . hex_gui_slist_select )
2011-02-24 04:14:30 +01:00
{
/* select this network */
servlist_select_and_show ( GTK_TREE_VIEW ( treeview ) , & iter , store ) ;
selected_net = net ;
}
}
i + + ;
netlist = netlist - > next ;
}
}
static void
servlist_networks_populate ( GtkWidget * treeview , GSList * netlist )
{
2012-10-22 13:49:28 +02:00
servlist_networks_populate_ ( treeview , netlist , prefs . hex_gui_slist_fav ) ;
2011-02-24 04:14:30 +01:00
}
static void
servlist_server_row_cb ( GtkTreeSelection * sel , gpointer user_data )
{
GtkTreeModel * model ;
GtkTreeIter iter ;
ircserver * serv ;
char * servname ;
int pos ;
if ( ! selected_net )
return ;
if ( gtk_tree_selection_get_selected ( sel , & model , & iter ) )
{
gtk_tree_model_get ( model , & iter , 0 , & servname , - 1 ) ;
serv = servlist_server_find ( selected_net , servname , & pos ) ;
g_free ( servname ) ;
if ( serv )
selected_net - > selected = pos ;
selected_serv = serv ;
}
}
2013-05-20 13:19:20 -03:00
static void
servlist_command_row_cb ( GtkTreeSelection * sel , gpointer user_data )
{
GtkTreeModel * model ;
GtkTreeIter iter ;
commandentry * cmd ;
char * cmdname ;
int pos ;
if ( ! selected_net )
return ;
if ( gtk_tree_selection_get_selected ( sel , & model , & iter ) )
{
gtk_tree_model_get ( model , & iter , 0 , & cmdname , - 1 ) ;
cmd = servlist_command_find ( selected_net , cmdname , & pos ) ;
g_free ( cmdname ) ;
if ( cmd )
selected_net - > selected = pos ;
selected_cmd = cmd ;
}
}
static void
servlist_channel_row_cb ( GtkTreeSelection * sel , gpointer user_data )
{
GtkTreeModel * model ;
GtkTreeIter iter ;
favchannel * channel ;
char * channame ;
int pos ;
if ( ! selected_net )
return ;
if ( gtk_tree_selection_get_selected ( sel , & model , & iter ) )
{
gtk_tree_model_get ( model , & iter , 0 , & channame , - 1 ) ;
channel = servlist_favchan_find ( selected_net , channame , & pos ) ;
g_free ( channame ) ;
if ( channel )
selected_net - > selected = pos ;
selected_chan = channel ;
}
}
2011-02-24 04:14:30 +01:00
static void
servlist_start_editing ( GtkTreeView * tree )
{
GtkTreeSelection * sel ;
GtkTreeModel * model ;
GtkTreeIter iter ;
GtkTreePath * path ;
sel = gtk_tree_view_get_selection ( tree ) ;
if ( gtk_tree_selection_get_selected ( sel , & model , & iter ) )
{
path = gtk_tree_model_get_path ( GTK_TREE_MODEL ( model ) , & iter ) ;
if ( path )
{
gtk_tree_view_set_cursor ( tree , path ,
gtk_tree_view_get_column ( tree , 0 ) , TRUE ) ;
gtk_tree_path_free ( path ) ;
}
}
}
static void
2013-05-11 09:20:03 -04:00
servlist_addserver ( void )
2011-02-24 04:14:30 +01:00
{
GtkTreeIter iter ;
GtkListStore * store ;
if ( ! selected_net )
return ;
2013-05-11 09:20:03 -04:00
store = GTK_LIST_STORE ( gtk_tree_view_get_model ( GTK_TREE_VIEW ( edit_trees [ SERVER_TREE ] ) ) ) ;
2021-05-23 06:58:18 +01:00
servlist_server_add ( selected_net , DEFAULT_SERVER ) ;
2011-02-24 04:14:30 +01:00
gtk_list_store_append ( store , & iter ) ;
2021-05-23 06:58:18 +01:00
gtk_list_store_set ( store , & iter , 0 , DEFAULT_SERVER , 1 , TRUE , - 1 ) ;
2011-02-24 04:14:30 +01:00
/* select this server */
2013-05-11 09:20:03 -04:00
servlist_select_and_show ( GTK_TREE_VIEW ( edit_trees [ SERVER_TREE ] ) , & iter , store ) ;
2013-05-11 20:06:22 +02:00
servlist_start_editing ( GTK_TREE_VIEW ( edit_trees [ SERVER_TREE ] ) ) ;
2011-02-24 04:14:30 +01:00
servlist_server_row_cb ( gtk_tree_view_get_selection ( GTK_TREE_VIEW ( networks_tree ) ) , NULL ) ;
}
2013-05-11 09:20:03 -04:00
static void
servlist_addcommand ( void )
{
GtkTreeIter iter ;
GtkListStore * store ;
if ( ! selected_net )
return ;
store = GTK_LIST_STORE ( gtk_tree_view_get_model ( GTK_TREE_VIEW ( edit_trees [ CMD_TREE ] ) ) ) ;
2013-05-11 20:06:22 +02:00
servlist_command_add ( selected_net , " ECHO hello " ) ;
2013-05-11 09:20:03 -04:00
gtk_list_store_append ( store , & iter ) ;
2013-05-12 05:44:32 +02:00
gtk_list_store_set ( store , & iter , 0 , " ECHO hello " , 1 , TRUE , - 1 ) ;
2013-05-11 09:20:03 -04:00
servlist_select_and_show ( GTK_TREE_VIEW ( edit_trees [ CMD_TREE ] ) , & iter , store ) ;
2013-05-11 20:06:22 +02:00
servlist_start_editing ( GTK_TREE_VIEW ( edit_trees [ CMD_TREE ] ) ) ;
2013-05-11 09:20:03 -04:00
2013-05-20 13:19:20 -03:00
servlist_command_row_cb ( gtk_tree_view_get_selection ( GTK_TREE_VIEW ( networks_tree ) ) , NULL ) ;
2013-05-11 09:20:03 -04:00
}
2013-05-12 05:44:32 +02:00
static void
servlist_addchannel ( void )
{
GtkTreeIter iter ;
GtkListStore * store ;
if ( ! selected_net )
return ;
store = GTK_LIST_STORE ( gtk_tree_view_get_model ( GTK_TREE_VIEW ( edit_trees [ CHANNEL_TREE ] ) ) ) ;
servlist_favchan_add ( selected_net , " #channel " ) ;
gtk_list_store_append ( store , & iter ) ;
gtk_list_store_set ( store , & iter , 0 , " #channel " , 1 , " " , 2 , TRUE , - 1 ) ;
/* select this server */
servlist_select_and_show ( GTK_TREE_VIEW ( edit_trees [ CHANNEL_TREE ] ) , & iter , store ) ;
servlist_start_editing ( GTK_TREE_VIEW ( edit_trees [ CHANNEL_TREE ] ) ) ;
2013-05-20 13:19:20 -03:00
servlist_channel_row_cb ( gtk_tree_view_get_selection ( GTK_TREE_VIEW ( networks_tree ) ) , NULL ) ;
2013-05-12 05:44:32 +02:00
}
2011-02-24 04:14:30 +01:00
static void
servlist_addnet_cb ( GtkWidget * item , GtkTreeView * treeview )
{
GtkTreeIter iter ;
GtkListStore * store ;
ircnet * net ;
net = servlist_net_add ( _ ( " New Network " ) , " " , TRUE ) ;
2014-12-28 06:37:25 -05:00
net - > encoding = g_strdup ( IRC_DEFAULT_CHARSET ) ;
2021-05-23 06:58:18 +01:00
servlist_server_add ( net , DEFAULT_SERVER ) ;
2011-02-24 04:14:30 +01:00
store = ( GtkListStore * ) gtk_tree_view_get_model ( treeview ) ;
gtk_list_store_prepend ( store , & iter ) ;
gtk_list_store_set ( store , & iter , 0 , net - > name , 1 , 1 , - 1 ) ;
/* select this network */
servlist_select_and_show ( GTK_TREE_VIEW ( networks_tree ) , & iter , store ) ;
servlist_start_editing ( GTK_TREE_VIEW ( networks_tree ) ) ;
servlist_network_row_cb ( gtk_tree_view_get_selection ( GTK_TREE_VIEW ( networks_tree ) ) , NULL ) ;
}
static void
servlist_deletenetwork ( ircnet * net )
{
GtkTreeSelection * sel ;
GtkTreeModel * model ;
GtkTreeIter iter ;
/* remove from GUI */
sel = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( networks_tree ) ) ;
if ( gtk_tree_selection_get_selected ( sel , & model , & iter ) )
gtk_list_store_remove ( GTK_LIST_STORE ( model ) , & iter ) ;
/* remove from list */
servlist_net_remove ( net ) ;
/* force something to be selected */
gtk_tree_model_get_iter_first ( model , & iter ) ;
servlist_select_and_show ( GTK_TREE_VIEW ( networks_tree ) , & iter ,
GTK_LIST_STORE ( model ) ) ;
servlist_network_row_cb ( sel , NULL ) ;
}
static void
servlist_deletenetdialog_cb ( GtkDialog * dialog , gint arg1 , ircnet * net )
{
gtk_widget_destroy ( GTK_WIDGET ( dialog ) ) ;
if ( arg1 = = GTK_RESPONSE_OK )
servlist_deletenetwork ( net ) ;
}
2013-05-20 13:19:20 -03:00
static GSList *
servlist_move_item ( GtkTreeView * view , GSList * list , gpointer item , int delta )
2011-02-24 04:14:30 +01:00
{
2013-05-20 13:19:20 -03:00
GtkTreeModel * store ;
GtkTreeIter iter1 , iter2 ;
GtkTreeSelection * sel ;
GtkTreePath * path ;
2011-02-24 04:14:30 +01:00
int pos ;
2013-05-20 13:19:20 -03:00
/* Keep tree in sync w/ list, there has to be an easier way to get iters */
sel = gtk_tree_view_get_selection ( view ) ;
gtk_tree_selection_get_selected ( sel , & store , & iter1 ) ;
path = gtk_tree_model_get_path ( store , & iter1 ) ;
if ( delta = = 1 )
gtk_tree_path_next ( path ) ;
else
gtk_tree_path_prev ( path ) ;
gtk_tree_model_get_iter ( store , & iter2 , path ) ;
2013-06-04 12:32:51 -03:00
gtk_tree_path_free ( path ) ;
2013-05-20 13:19:20 -03:00
pos = g_slist_index ( list , item ) ;
2011-02-24 04:14:30 +01:00
if ( pos > = 0 )
{
pos + = delta ;
if ( pos > = 0 )
{
2013-05-20 13:19:20 -03:00
list = g_slist_remove ( list , item ) ;
list = g_slist_insert ( list , item , pos ) ;
2011-02-24 04:14:30 +01:00
2013-05-20 13:19:20 -03:00
gtk_list_store_swap ( GTK_LIST_STORE ( store ) , & iter1 , & iter2 ) ;
2011-02-24 04:14:30 +01:00
}
}
2013-05-20 13:19:20 -03:00
return list ;
2011-02-24 04:14:30 +01:00
}
static gboolean
servlist_net_keypress_cb ( GtkWidget * wid , GdkEventKey * evt , gpointer tree )
{
2013-05-20 13:19:20 -03:00
gboolean handled = FALSE ;
if ( ! selected_net | | prefs . hex_gui_slist_fav )
2011-02-24 04:14:30 +01:00
return FALSE ;
2012-10-21 03:03:38 +02:00
if ( evt - > state & STATE_SHIFT )
2011-02-24 04:14:30 +01:00
{
2013-09-15 03:21:56 -04:00
if ( evt - > keyval = = GDK_KEY_Up )
2011-02-24 04:14:30 +01:00
{
2013-05-20 13:19:20 -03:00
handled = TRUE ;
network_list = servlist_move_item ( GTK_TREE_VIEW ( tree ) , network_list , selected_net , - 1 ) ;
2011-02-24 04:14:30 +01:00
}
2013-09-15 03:21:56 -04:00
else if ( evt - > keyval = = GDK_KEY_Down )
2011-02-24 04:14:30 +01:00
{
2013-05-20 13:19:20 -03:00
handled = TRUE ;
network_list = servlist_move_item ( GTK_TREE_VIEW ( tree ) , network_list , selected_net , + 1 ) ;
2011-02-24 04:14:30 +01:00
}
}
2013-05-20 13:19:20 -03:00
return handled ;
2011-02-24 04:14:30 +01:00
}
static gint
servlist_compare ( ircnet * net1 , ircnet * net2 )
{
gchar * net1_casefolded , * net2_casefolded ;
int result = 0 ;
net1_casefolded = g_utf8_casefold ( net1 - > name , - 1 ) ,
net2_casefolded = g_utf8_casefold ( net2 - > name , - 1 ) ,
result = g_utf8_collate ( net1_casefolded , net2_casefolded ) ;
g_free ( net1_casefolded ) ;
g_free ( net2_casefolded ) ;
return result ;
}
static void
servlist_sort ( GtkWidget * button , gpointer none )
{
network_list = g_slist_sort ( network_list , ( GCompareFunc ) servlist_compare ) ;
servlist_networks_populate ( networks_tree , network_list ) ;
}
static gboolean
servlist_has_selection ( GtkTreeView * tree )
{
GtkTreeSelection * sel ;
GtkTreeModel * model ;
GtkTreeIter iter ;
/* make sure something is selected */
sel = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( tree ) ) ;
return gtk_tree_selection_get_selected ( sel , & model , & iter ) ;
}
static void
servlist_favor ( GtkWidget * button , gpointer none )
{
GtkTreeSelection * sel ;
GtkTreeModel * model ;
GtkTreeIter iter ;
if ( ! selected_net )
return ;
sel = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( networks_tree ) ) ;
if ( gtk_tree_selection_get_selected ( sel , & model , & iter ) )
{
if ( selected_net - > flags & FLAG_FAVORITE )
{
gtk_list_store_set ( GTK_LIST_STORE ( model ) , & iter , 2 , 400 , - 1 ) ;
selected_net - > flags & = ~ FLAG_FAVORITE ;
}
else
{
gtk_list_store_set ( GTK_LIST_STORE ( model ) , & iter , 2 , 800 , - 1 ) ;
selected_net - > flags | = FLAG_FAVORITE ;
}
}
}
static void
servlist_update_from_entry ( char * * str , GtkWidget * entry )
{
2014-12-28 06:37:25 -05:00
g_free ( * str ) ;
2011-02-24 04:14:30 +01:00
2013-05-12 01:43:27 -04:00
if ( gtk_entry_get_text ( GTK_ENTRY ( entry ) ) [ 0 ] = = 0 )
2011-02-24 04:14:30 +01:00
* str = NULL ;
else
2014-12-28 06:37:25 -05:00
* str = g_strdup ( gtk_entry_get_text ( GTK_ENTRY ( entry ) ) ) ;
2011-02-24 04:14:30 +01:00
}
static void
servlist_edit_update ( ircnet * net )
{
2026-06-02 15:57:28 -06:00
const char * password ;
2011-02-24 04:14:30 +01:00
servlist_update_from_entry ( & net - > nick , edit_entry_nick ) ;
servlist_update_from_entry ( & net - > nick2 , edit_entry_nick2 ) ;
servlist_update_from_entry ( & net - > user , edit_entry_user ) ;
servlist_update_from_entry ( & net - > real , edit_entry_real ) ;
2026-06-02 15:57:28 -06:00
password = gtk_entry_get_text ( GTK_ENTRY ( edit_entry_pass ) ) ;
if ( net & & net - > name )
{
if ( ! edit_pass_changed )
return ;
if ( gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( edit_check_use_keyring ) ) )
{
net - > flags | = FLAG_USE_KEYRING ;
g_free ( net - > pass ) ;
net - > pass = NULL ;
if ( password & & * password )
{
if ( ! secretstore_set_network_password ( net - > name , password ) )
fe_message ( _ ( " No system keyring is available. ZoiteChat can save this password using local encrypted fallback storage, but it is less protected than your desktop keyring. " ) , FE_MSG_WARN ) ;
}
else
secretstore_delete_network_password ( net - > name ) ;
}
else
{
char * enc = NULL ;
net - > flags & = ~ FLAG_USE_KEYRING ;
secretstore_delete_network_password ( net - > name ) ;
if ( password & & * password )
enc = servlist_password_encrypt_for_storage ( password ) ;
g_free ( net - > pass ) ;
net - > pass = enc ;
}
}
2011-02-24 04:14:30 +01:00
}
static void
servlist_edit_close_cb ( GtkWidget * button , gpointer userdata )
{
if ( selected_net )
servlist_edit_update ( selected_net ) ;
2026-06-02 15:57:28 -06:00
if ( edit_loaded_password )
{
memset ( edit_loaded_password , 0 , strlen ( edit_loaded_password ) ) ;
g_free ( edit_loaded_password ) ;
edit_loaded_password = NULL ;
}
2011-02-24 04:14:30 +01:00
gtk_widget_destroy ( edit_win ) ;
edit_win = NULL ;
}
static gint
servlist_editwin_delete_cb ( GtkWidget * win , GdkEventAny * event , gpointer none )
{
servlist_edit_close_cb ( NULL , NULL ) ;
return FALSE ;
}
static gboolean
servlist_configure_cb ( GtkWindow * win , GdkEventConfigure * event , gpointer none )
{
/* remember the window size */
2013-05-11 15:58:52 +02:00
gtk_window_get_size ( win , & netlist_win_width , & netlist_win_height ) ;
return FALSE ;
}
static gboolean
servlist_edit_configure_cb ( GtkWindow * win , GdkEventConfigure * event , gpointer none )
{
/* remember the window size */
gtk_window_get_size ( win , & netedit_win_width , & netedit_win_height ) ;
2011-02-24 04:14:30 +01:00
return FALSE ;
}
static void
servlist_edit_cb ( GtkWidget * but , gpointer none )
{
if ( ! servlist_has_selection ( GTK_TREE_VIEW ( networks_tree ) ) )
return ;
2026-06-02 15:57:28 -06:00
if ( ! selected_net | | ! selected_net - > name )
return ;
if ( ( selected_net - > flags & FLAG_USE_KEYRING ) & & ! secretstore_require_unlock ( selected_net - > name ) )
return ;
2011-02-24 04:14:30 +01:00
edit_win = servlist_open_edit ( serverlist_win , selected_net ) ;
gtkutil_set_icon ( edit_win ) ;
2013-05-11 09:20:03 -04:00
servlist_servers_populate ( selected_net , edit_trees [ SERVER_TREE ] ) ;
2013-05-12 05:44:32 +02:00
servlist_channels_populate ( selected_net , edit_trees [ CHANNEL_TREE ] ) ;
2013-05-11 20:06:22 +02:00
servlist_commands_populate ( selected_net , edit_trees [ CMD_TREE ] ) ;
2026-03-17 10:30:54 -06:00
g_signal_connect ( G_OBJECT ( edit_win ) , " delete-event " ,
2011-02-24 04:14:30 +01:00
G_CALLBACK ( servlist_editwin_delete_cb ) , 0 ) ;
2026-03-17 10:30:54 -06:00
g_signal_connect ( G_OBJECT ( edit_win ) , " configure-event " ,
2013-05-11 15:58:52 +02:00
G_CALLBACK ( servlist_edit_configure_cb ) , 0 ) ;
2011-02-24 04:14:30 +01:00
gtk_widget_show ( edit_win ) ;
}
static void
servlist_deletenet_cb ( GtkWidget * item , ircnet * net )
{
GtkWidget * dialog ;
if ( ! servlist_has_selection ( GTK_TREE_VIEW ( networks_tree ) ) )
return ;
net = selected_net ;
if ( ! net )
return ;
dialog = gtk_message_dialog_new ( GTK_WINDOW ( serverlist_win ) ,
GTK_DIALOG_DESTROY_WITH_PARENT |
GTK_DIALOG_MODAL ,
GTK_MESSAGE_QUESTION ,
GTK_BUTTONS_OK_CANCEL ,
_ ( " Really remove network \" %s \" and all its servers? " ) ,
net - > name ) ;
2026-03-04 23:28:01 -07:00
theme_manager_attach_window ( dialog ) ;
2011-02-24 04:14:30 +01:00
g_signal_connect ( dialog , " response " ,
G_CALLBACK ( servlist_deletenetdialog_cb ) , net ) ;
gtk_window_set_position ( GTK_WINDOW ( dialog ) , GTK_WIN_POS_MOUSE ) ;
gtk_widget_show ( dialog ) ;
}
static void
servlist_deleteserver ( ircserver * serv , GtkTreeModel * model )
{
GtkTreeSelection * sel ;
GtkTreeIter iter ;
/* don't remove the last server */
if ( selected_net & & g_slist_length ( selected_net - > servlist ) < 2 )
return ;
/* remove from GUI */
2013-05-11 09:20:03 -04:00
sel = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( edit_trees [ SERVER_TREE ] ) ) ;
2011-02-24 04:14:30 +01:00
if ( gtk_tree_selection_get_selected ( sel , & model , & iter ) )
gtk_list_store_remove ( GTK_LIST_STORE ( model ) , & iter ) ;
/* remove from list */
if ( selected_net )
servlist_server_remove ( selected_net , serv ) ;
}
static void
2013-05-11 09:20:03 -04:00
servlist_editbutton_cb ( GtkWidget * item , GtkNotebook * notebook )
2011-02-24 04:14:30 +01:00
{
2013-05-11 09:20:03 -04:00
servlist_start_editing ( GTK_TREE_VIEW ( edit_trees [ gtk_notebook_get_current_page ( notebook ) ] ) ) ;
2011-02-24 04:14:30 +01:00
}
static void
2013-05-11 09:20:03 -04:00
servlist_deleteserver_cb ( void )
2011-02-24 04:14:30 +01:00
{
GtkTreeSelection * sel ;
GtkTreeModel * model ;
GtkTreeIter iter ;
char * servname ;
ircserver * serv ;
int pos ;
/* find the selected item in the GUI */
2013-05-11 09:20:03 -04:00
model = gtk_tree_view_get_model ( GTK_TREE_VIEW ( edit_trees [ SERVER_TREE ] ) ) ;
sel = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( edit_trees [ SERVER_TREE ] ) ) ;
2011-02-24 04:14:30 +01:00
if ( gtk_tree_selection_get_selected ( sel , & model , & iter ) )
{
gtk_tree_model_get ( model , & iter , 0 , & servname , - 1 ) ;
serv = servlist_server_find ( selected_net , servname , & pos ) ;
g_free ( servname ) ;
if ( serv )
2013-05-11 20:06:22 +02:00
{
2011-02-24 04:14:30 +01:00
servlist_deleteserver ( serv , model ) ;
2013-05-11 20:06:22 +02:00
}
}
}
static void
servlist_deletecommand ( commandentry * entry , GtkTreeModel * model )
{
GtkTreeSelection * sel ;
GtkTreeIter iter ;
/* remove from GUI */
sel = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( edit_trees [ CMD_TREE ] ) ) ;
if ( gtk_tree_selection_get_selected ( sel , & model , & iter ) )
{
gtk_list_store_remove ( GTK_LIST_STORE ( model ) , & iter ) ;
}
/* remove from list */
if ( selected_net )
{
servlist_command_remove ( selected_net , entry ) ;
}
}
static void
servlist_deletecommand_cb ( void )
{
GtkTreeSelection * sel ;
GtkTreeModel * model ;
GtkTreeIter iter ;
char * command ;
commandentry * entry ;
int pos ;
/* find the selected item in the GUI */
model = gtk_tree_view_get_model ( GTK_TREE_VIEW ( edit_trees [ CMD_TREE ] ) ) ;
sel = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( edit_trees [ CMD_TREE ] ) ) ;
if ( gtk_tree_selection_get_selected ( sel , & model , & iter ) )
{
gtk_tree_model_get ( model , & iter , 0 , & command , - 1 ) ; /* query the content of the selection */
entry = servlist_command_find ( selected_net , command , & pos ) ;
g_free ( command ) ;
if ( entry )
{
servlist_deletecommand ( entry , model ) ;
}
2011-02-24 04:14:30 +01:00
}
}
2013-05-12 05:44:32 +02:00
static void
servlist_deletechannel ( favchannel * favchan , GtkTreeModel * model )
{
GtkTreeSelection * sel ;
GtkTreeIter iter ;
/* remove from GUI */
sel = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( edit_trees [ CHANNEL_TREE ] ) ) ;
if ( gtk_tree_selection_get_selected ( sel , & model , & iter ) )
{
gtk_list_store_remove ( GTK_LIST_STORE ( model ) , & iter ) ;
}
/* remove from list */
if ( selected_net )
{
servlist_favchan_remove ( selected_net , favchan ) ;
}
}
static void
servlist_deletechannel_cb ( void )
{
GtkTreeSelection * sel ;
GtkTreeModel * model ;
GtkTreeIter iter ;
char * name ;
char * key ;
favchannel * favchan ;
int pos ;
/* find the selected item in the GUI */
model = gtk_tree_view_get_model ( GTK_TREE_VIEW ( edit_trees [ CHANNEL_TREE ] ) ) ;
sel = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( edit_trees [ CHANNEL_TREE ] ) ) ;
if ( gtk_tree_selection_get_selected ( sel , & model , & iter ) )
{
gtk_tree_model_get ( model , & iter , 0 , & name , 1 , & key , - 1 ) ; /* query the content of the selection */
favchan = servlist_favchan_find ( selected_net , name , & pos ) ;
g_free ( name ) ;
if ( favchan )
{
servlist_deletechannel ( favchan , model ) ;
}
}
}
2011-02-24 04:14:30 +01:00
static ircnet *
servlist_find_selected_net ( GtkTreeSelection * sel )
{
GtkTreeModel * model ;
GtkTreeIter iter ;
char * netname ;
int pos ;
ircnet * net = NULL ;
if ( gtk_tree_selection_get_selected ( sel , & model , & iter ) )
{
gtk_tree_model_get ( model , & iter , 0 , & netname , - 1 ) ;
net = servlist_net_find ( netname , & pos , strcmp ) ;
g_free ( netname ) ;
if ( net )
2012-10-22 13:49:28 +02:00
prefs . hex_gui_slist_select = pos ;
2011-02-24 04:14:30 +01:00
}
return net ;
}
static void
servlist_network_row_cb ( GtkTreeSelection * sel , gpointer user_data )
{
ircnet * net ;
selected_net = NULL ;
net = servlist_find_selected_net ( sel ) ;
if ( net )
selected_net = net ;
}
static int
servlist_savegui ( void )
{
char * sp ;
2014-02-02 19:07:52 -05:00
const char * nick1 , * nick2 ;
2011-02-24 04:14:30 +01:00
/* check for blank username, ircd will not allow this */
2013-05-12 01:43:27 -04:00
if ( gtk_entry_get_text ( GTK_ENTRY ( entry_guser ) ) [ 0 ] = = 0 )
2011-02-24 04:14:30 +01:00
return 1 ;
2013-05-12 01:43:27 -04:00
/* if (gtk_entry_get_text (GTK_ENTRY (entry_greal))[0] == 0)
2012-05-16 19:47:12 +02:00
return 1 ; */
2011-02-24 04:14:30 +01:00
2014-02-01 13:31:42 -05:00
nick1 = gtk_entry_get_text ( GTK_ENTRY ( entry_nick1 ) ) ;
nick2 = gtk_entry_get_text ( GTK_ENTRY ( entry_nick2 ) ) ;
/* ensure unique nicknames */
if ( ! rfc_casecmp ( nick1 , nick2 ) )
return 2 ;
2014-12-10 09:32:16 -05:00
safe_strcpy ( prefs . hex_irc_nick1 , nick1 , sizeof ( prefs . hex_irc_nick1 ) ) ;
safe_strcpy ( prefs . hex_irc_nick2 , nick2 , sizeof ( prefs . hex_irc_nick2 ) ) ;
safe_strcpy ( prefs . hex_irc_nick3 , gtk_entry_get_text ( GTK_ENTRY ( entry_nick3 ) ) , sizeof ( prefs . hex_irc_nick3 ) ) ;
safe_strcpy ( prefs . hex_irc_user_name , gtk_entry_get_text ( GTK_ENTRY ( entry_guser ) ) , sizeof ( prefs . hex_irc_user_name ) ) ;
2012-10-22 14:50:36 +02:00
sp = strchr ( prefs . hex_irc_user_name , ' ' ) ;
2011-02-24 04:14:30 +01:00
if ( sp )
sp [ 0 ] = 0 ; /* spaces will break the login */
2013-05-12 01:43:27 -04:00
/* strcpy (prefs.hex_irc_real_name, gtk_entry_get_text (GTK_ENTRY (entry_greal))); */
2011-02-24 04:14:30 +01:00
servlist_save ( ) ;
2026-03-16 21:55:36 -06:00
if ( ! save_config ( ) )
fe_message ( _ ( " Could not save zoitechat.conf. " ) , FE_MSG_WARN ) ;
2011-02-24 04:14:30 +01:00
return 0 ;
}
static gboolean
servlist_get_iter_from_name ( GtkTreeModel * model , gchar * name , GtkTreeIter * iter )
{
GtkTreePath * path = gtk_tree_path_new_from_string ( name ) ;
if ( ! gtk_tree_model_get_iter ( model , iter , path ) )
{
gtk_tree_path_free ( path ) ;
return FALSE ;
}
gtk_tree_path_free ( path ) ;
return TRUE ;
}
static void
2013-05-11 09:20:03 -04:00
servlist_addbutton_cb ( GtkWidget * item , GtkNotebook * notebook )
2011-02-24 04:14:30 +01:00
{
2013-05-11 09:20:03 -04:00
switch ( gtk_notebook_get_current_page ( notebook ) )
{
case SERVER_TREE :
servlist_addserver ( ) ;
break ;
case CHANNEL_TREE :
2013-05-12 05:44:32 +02:00
servlist_addchannel ( ) ;
2013-05-11 09:20:03 -04:00
break ;
case CMD_TREE :
servlist_addcommand ( ) ;
break ;
default :
break ;
}
2011-02-24 04:14:30 +01:00
}
static void
2013-05-11 09:20:03 -04:00
servlist_deletebutton_cb ( GtkWidget * item , GtkNotebook * notebook )
2011-02-24 04:14:30 +01:00
{
2013-05-11 09:20:03 -04:00
switch ( gtk_notebook_get_current_page ( notebook ) )
2011-02-24 04:14:30 +01:00
{
2013-05-11 09:20:03 -04:00
case SERVER_TREE :
servlist_deleteserver_cb ( ) ;
break ;
case CHANNEL_TREE :
2013-05-11 20:06:22 +02:00
servlist_deletechannel_cb ( ) ;
2013-05-11 09:20:03 -04:00
break ;
case CMD_TREE :
2013-05-11 20:06:22 +02:00
servlist_deletecommand_cb ( ) ;
2013-05-11 09:20:03 -04:00
break ;
default :
break ;
2011-02-24 04:14:30 +01:00
}
}
2013-05-20 13:19:20 -03:00
static gboolean
servlist_keypress_cb ( GtkWidget * wid , GdkEventKey * evt , GtkNotebook * notebook )
{
gboolean handled = FALSE ;
int delta = 0 ;
if ( ! selected_net )
return FALSE ;
if ( evt - > state & STATE_SHIFT )
{
2013-09-15 03:21:56 -04:00
if ( evt - > keyval = = GDK_KEY_Up )
2013-05-20 13:19:20 -03:00
{
handled = TRUE ;
delta = - 1 ;
}
2013-09-15 03:21:56 -04:00
else if ( evt - > keyval = = GDK_KEY_Down )
2013-05-20 13:19:20 -03:00
{
handled = TRUE ;
delta = + 1 ;
}
}
if ( handled )
{
switch ( gtk_notebook_get_current_page ( notebook ) )
{
case SERVER_TREE :
if ( selected_serv )
selected_net - > servlist = servlist_move_item ( GTK_TREE_VIEW ( edit_trees [ SERVER_TREE ] ) ,
selected_net - > servlist , selected_serv , delta ) ;
break ;
case CHANNEL_TREE :
if ( selected_chan )
selected_net - > favchanlist = servlist_move_item ( GTK_TREE_VIEW ( edit_trees [ CHANNEL_TREE ] ) ,
selected_net - > favchanlist , selected_chan , delta ) ;
break ;
case CMD_TREE :
if ( selected_cmd )
selected_net - > commandlist = servlist_move_item ( GTK_TREE_VIEW ( edit_trees [ CMD_TREE ] ) ,
selected_net - > commandlist , selected_cmd , delta ) ;
break ;
}
}
return handled ;
}
2011-02-24 04:14:30 +01:00
void
servlist_autojoinedit ( ircnet * net , char * channel , gboolean add )
{
2013-05-12 05:44:32 +02:00
favchannel * fav ;
2011-02-24 04:14:30 +01:00
2013-05-12 05:44:32 +02:00
if ( add )
2011-02-24 04:14:30 +01:00
{
2013-05-12 05:44:32 +02:00
servlist_favchan_add ( net , channel ) ;
servlist_save ( ) ;
2011-02-24 04:14:30 +01:00
}
2013-05-12 05:44:32 +02:00
else
2011-02-24 04:14:30 +01:00
{
2013-05-12 05:44:32 +02:00
fav = servlist_favchan_find ( net , channel , NULL ) ;
2014-04-18 20:40:16 -04:00
if ( fav )
{
servlist_favchan_remove ( net , fav ) ;
servlist_save ( ) ;
}
2011-02-24 04:14:30 +01:00
}
}
2013-05-11 03:13:50 +02:00
static void
servlist_toggle_global_user ( gboolean sensitive )
{
gtk_widget_set_sensitive ( edit_entry_nick , sensitive ) ;
gtk_widget_set_sensitive ( edit_label_nick , sensitive ) ;
gtk_widget_set_sensitive ( edit_entry_nick2 , sensitive ) ;
gtk_widget_set_sensitive ( edit_label_nick2 , sensitive ) ;
gtk_widget_set_sensitive ( edit_entry_user , sensitive ) ;
gtk_widget_set_sensitive ( edit_label_user , sensitive ) ;
gtk_widget_set_sensitive ( edit_entry_real , sensitive ) ;
gtk_widget_set_sensitive ( edit_label_real , sensitive ) ;
}
2011-02-24 04:14:30 +01:00
static void
servlist_connect_cb ( GtkWidget * button , gpointer userdata )
{
2014-02-01 13:31:42 -05:00
int servlist_err ;
2011-02-24 04:14:30 +01:00
if ( ! selected_net )
return ;
2014-02-01 13:31:42 -05:00
servlist_err = servlist_savegui ( ) ;
if ( servlist_err = = 1 )
{
fe_message ( _ ( " User name cannot be left blank. " ) , FE_MSG_ERROR ) ;
return ;
}
2011-02-24 04:14:30 +01:00
if ( ! is_session ( servlist_sess ) )
servlist_sess = NULL ; /* open a new one */
{
GSList * list ;
session * sess ;
session * chosen = servlist_sess ;
servlist_sess = NULL ; /* open a new one */
for ( list = sess_list ; list ; list = list - > next )
{
sess = list - > data ;
if ( sess - > server - > network = = selected_net )
{
servlist_sess = sess ;
if ( sess - > server - > connected )
servlist_sess = NULL ; /* open a new one */
break ;
}
}
/* use the chosen one, if it's empty */
if ( ! servlist_sess & &
chosen & &
! chosen - > server - > connected & &
chosen - > server - > server_session - > channel [ 0 ] = = 0 )
{
servlist_sess = chosen ;
}
}
servlist_connect ( servlist_sess , selected_net , TRUE ) ;
gtk_widget_destroy ( serverlist_win ) ;
serverlist_win = NULL ;
selected_net = NULL ;
}
static void
servlist_celledit_cb ( GtkCellRendererText * cell , gchar * arg1 , gchar * arg2 ,
gpointer user_data )
{
GtkTreeModel * model = ( GtkTreeModel * ) user_data ;
GtkTreeIter iter ;
GtkTreePath * path ;
char * netname ;
ircnet * net ;
if ( ! arg1 | | ! arg2 )
return ;
path = gtk_tree_path_new_from_string ( arg1 ) ;
if ( ! path )
return ;
if ( ! gtk_tree_model_get_iter ( model , & iter , path ) )
{
gtk_tree_path_free ( path ) ;
return ;
}
gtk_tree_model_get ( model , & iter , 0 , & netname , - 1 ) ;
net = servlist_net_find ( netname , NULL , strcmp ) ;
g_free ( netname ) ;
if ( net )
{
/* delete empty item */
if ( arg2 [ 0 ] = = 0 )
{
servlist_deletenetwork ( net ) ;
gtk_tree_path_free ( path ) ;
return ;
}
netname = net - > name ;
2014-12-28 06:37:25 -05:00
net - > name = g_strdup ( arg2 ) ;
2011-02-24 04:14:30 +01:00
gtk_list_store_set ( GTK_LIST_STORE ( model ) , & iter , 0 , net - > name , - 1 ) ;
2014-12-28 06:37:25 -05:00
g_free ( netname ) ;
2011-02-24 04:14:30 +01:00
}
gtk_tree_path_free ( path ) ;
}
static void
servlist_check_cb ( GtkWidget * but , gpointer num_p )
{
int num = GPOINTER_TO_INT ( num_p ) ;
if ( ! selected_net )
return ;
if ( ( 1 < < num ) = = FLAG_CYCLE | | ( 1 < < num ) = = FLAG_USE_PROXY )
{
/* these ones are reversed, so it's compat with 2.0.x */
2013-05-12 01:43:27 -04:00
if ( gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( but ) ) )
2011-02-24 04:14:30 +01:00
selected_net - > flags & = ~ ( 1 < < num ) ;
else
selected_net - > flags | = ( 1 < < num ) ;
} else
{
2013-05-12 01:43:27 -04:00
if ( gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( but ) ) )
2011-02-24 04:14:30 +01:00
selected_net - > flags | = ( 1 < < num ) ;
else
selected_net - > flags & = ~ ( 1 < < num ) ;
}
if ( ( 1 < < num ) = = FLAG_USE_GLOBAL )
{
2013-05-12 01:43:27 -04:00
servlist_toggle_global_user ( ! gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( but ) ) ) ;
2011-02-24 04:14:30 +01:00
}
}
2026-01-30 16:04:50 -07:00
typedef enum
{
SERVLIST_ALIGN_START ,
SERVLIST_ALIGN_CENTER ,
SERVLIST_ALIGN_FILL
} servlist_align ;
static GtkAlign
servlist_align_to_gtk ( servlist_align align )
{
switch ( align )
{
case SERVLIST_ALIGN_FILL :
return GTK_ALIGN_FILL ;
case SERVLIST_ALIGN_CENTER :
return GTK_ALIGN_CENTER ;
case SERVLIST_ALIGN_START :
default :
return GTK_ALIGN_START ;
}
}
static void
servlist_table_attach ( GtkWidget * table , GtkWidget * child ,
guint left_attach , guint right_attach ,
guint top_attach , guint bottom_attach ,
gboolean hexpand , gboolean vexpand ,
servlist_align halign , servlist_align valign ,
guint xpad , guint ypad )
{
gtk_widget_set_hexpand ( child , hexpand ) ;
gtk_widget_set_vexpand ( child , vexpand ) ;
gtk_widget_set_halign ( child , servlist_align_to_gtk ( halign ) ) ;
gtk_widget_set_valign ( child , servlist_align_to_gtk ( valign ) ) ;
gtk_widget_set_margin_start ( child , xpad ) ;
gtk_widget_set_margin_end ( child , xpad ) ;
gtk_widget_set_margin_top ( child , ypad ) ;
gtk_widget_set_margin_bottom ( child , ypad ) ;
2026-01-30 17:13:44 -07:00
gtk_grid_attach ( GTK_GRID ( table ) , child , left_attach , top_attach ,
right_attach - left_attach , bottom_attach - top_attach ) ;
2026-01-30 16:04:50 -07:00
}
2011-02-24 04:14:30 +01:00
static GtkWidget *
servlist_create_check ( int num , int state , GtkWidget * table , int row , int col , char * labeltext )
{
GtkWidget * but ;
but = gtk_check_button_new_with_label ( labeltext ) ;
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( but ) , state ) ;
g_signal_connect ( G_OBJECT ( but ) , " toggled " ,
G_CALLBACK ( servlist_check_cb ) , GINT_TO_POINTER ( num ) ) ;
2026-01-30 16:04:50 -07:00
servlist_table_attach ( table , but , col , col + 2 , row , row + 1 ,
TRUE , FALSE ,
SERVLIST_ALIGN_FILL , SERVLIST_ALIGN_CENTER ,
SERVLIST_X_PADDING , SERVLIST_Y_PADDING ) ;
2011-02-24 04:14:30 +01:00
gtk_widget_show ( but ) ;
return but ;
}
static GtkWidget *
servlist_create_entry ( GtkWidget * table , char * labeltext , int row ,
char * def , GtkWidget * * label_ret , char * tip )
{
GtkWidget * label , * entry ;
label = gtk_label_new_with_mnemonic ( labeltext ) ;
if ( label_ret )
* label_ret = label ;
gtk_widget_show ( label ) ;
2026-01-30 16:04:50 -07:00
servlist_table_attach ( table , label , 0 , 1 , row , row + 1 ,
FALSE , FALSE ,
SERVLIST_ALIGN_START , SERVLIST_ALIGN_CENTER ,
SERVLIST_X_PADDING , SERVLIST_Y_PADDING ) ;
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( label , GTK_ALIGN_START ) ;
gtk_widget_set_valign ( label , GTK_ALIGN_CENTER ) ;
2011-02-24 04:14:30 +01:00
entry = gtk_entry_new ( ) ;
2014-01-18 04:08:32 -05:00
gtk_widget_set_tooltip_text ( entry , tip ) ;
2011-02-24 04:14:30 +01:00
gtk_widget_show ( entry ) ;
gtk_entry_set_text ( GTK_ENTRY ( entry ) , def ? def : " " ) ;
gtk_label_set_mnemonic_widget ( GTK_LABEL ( label ) , entry ) ;
2026-01-30 16:04:50 -07:00
servlist_table_attach ( table , entry , 1 , 2 , row , row + 1 ,
TRUE , FALSE ,
SERVLIST_ALIGN_FILL , SERVLIST_ALIGN_CENTER ,
SERVLIST_X_PADDING , SERVLIST_Y_PADDING ) ;
2011-02-24 04:14:30 +01:00
return entry ;
}
static gint
servlist_delete_cb ( GtkWidget * win , GdkEventAny * event , gpointer userdata )
{
servlist_savegui ( ) ;
serverlist_win = NULL ;
selected_net = NULL ;
if ( sess_list = = NULL )
2026-01-05 23:12:38 -07:00
zoitechat_exit ( ) ;
2011-02-24 04:14:30 +01:00
return FALSE ;
}
static void
servlist_close_cb ( GtkWidget * button , gpointer userdata )
{
servlist_savegui ( ) ;
gtk_widget_destroy ( serverlist_win ) ;
serverlist_win = NULL ;
selected_net = NULL ;
if ( sess_list = = NULL )
2026-01-05 23:12:38 -07:00
zoitechat_exit ( ) ;
2011-02-24 04:14:30 +01:00
}
/* convert "host:port" format to "host/port" */
static char *
servlist_sanitize_hostname ( char * host )
{
char * ret , * c , * e ;
2014-12-28 06:37:25 -05:00
ret = g_strdup ( host ) ;
2011-02-24 04:14:30 +01:00
c = strchr ( ret , ' : ' ) ;
e = strrchr ( ret , ' : ' ) ;
/* if only one colon exists it's probably not IPv6 */
if ( c & & c = = e )
* c = ' / ' ;
2016-03-21 04:36:24 +08:00
return g_strstrip ( ret ) ;
2011-02-24 04:14:30 +01:00
}
2013-05-11 20:06:22 +02:00
/* remove leading slash */
static char *
servlist_sanitize_command ( char * cmd )
{
if ( cmd [ 0 ] = = ' / ' )
{
return ( g_strdup ( cmd + 1 ) ) ;
}
else
{
return ( g_strdup ( cmd ) ) ;
}
}
2011-02-24 04:14:30 +01:00
static void
2013-05-12 05:44:32 +02:00
servlist_editserver_cb ( GtkCellRendererText * cell , gchar * name , gchar * newval , gpointer user_data )
2011-02-24 04:14:30 +01:00
{
GtkTreeModel * model = ( GtkTreeModel * ) user_data ;
GtkTreeIter iter ;
char * servname ;
ircserver * serv ;
if ( ! selected_net )
2013-05-12 05:44:32 +02:00
{
2011-02-24 04:14:30 +01:00
return ;
2013-05-12 05:44:32 +02:00
}
2011-02-24 04:14:30 +01:00
2013-05-12 05:44:32 +02:00
if ( ! servlist_get_iter_from_name ( model , name , & iter ) )
2011-02-24 04:14:30 +01:00
{
return ;
}
gtk_tree_model_get ( model , & iter , 0 , & servname , - 1 ) ;
serv = servlist_server_find ( selected_net , servname , NULL ) ;
g_free ( servname ) ;
if ( serv )
{
/* delete empty item */
2013-05-12 05:44:32 +02:00
if ( newval [ 0 ] = = 0 )
2011-02-24 04:14:30 +01:00
{
servlist_deleteserver ( serv , model ) ;
return ;
}
servname = serv - > hostname ;
2013-05-12 05:44:32 +02:00
serv - > hostname = servlist_sanitize_hostname ( newval ) ;
2011-02-24 04:14:30 +01:00
gtk_list_store_set ( GTK_LIST_STORE ( model ) , & iter , 0 , serv - > hostname , - 1 ) ;
2014-12-28 06:37:25 -05:00
g_free ( servname ) ;
2011-02-24 04:14:30 +01:00
}
}
2013-05-11 20:06:22 +02:00
static void
2013-05-12 05:44:32 +02:00
servlist_editcommand_cb ( GtkCellRendererText * cell , gchar * name , gchar * newval , gpointer user_data )
2013-05-11 20:06:22 +02:00
{
GtkTreeModel * model = ( GtkTreeModel * ) user_data ;
GtkTreeIter iter ;
char * cmd ;
commandentry * entry ;
if ( ! selected_net )
2013-05-12 05:44:32 +02:00
{
2013-05-11 20:06:22 +02:00
return ;
2013-05-12 05:44:32 +02:00
}
2013-05-11 20:06:22 +02:00
2013-05-12 05:44:32 +02:00
if ( ! servlist_get_iter_from_name ( model , name , & iter ) )
2013-05-11 20:06:22 +02:00
{
return ;
}
gtk_tree_model_get ( model , & iter , 0 , & cmd , - 1 ) ;
entry = servlist_command_find ( selected_net , cmd , NULL ) ;
g_free ( cmd ) ;
if ( entry )
{
/* delete empty item */
2013-05-12 05:44:32 +02:00
if ( newval [ 0 ] = = 0 )
2013-05-11 20:06:22 +02:00
{
servlist_deletecommand ( entry , model ) ;
return ;
}
cmd = entry - > command ;
2013-05-12 05:44:32 +02:00
entry - > command = servlist_sanitize_command ( newval ) ;
2013-05-11 20:06:22 +02:00
gtk_list_store_set ( GTK_LIST_STORE ( model ) , & iter , 0 , entry - > command , - 1 ) ;
2014-12-28 06:37:25 -05:00
g_free ( cmd ) ;
2013-05-11 20:06:22 +02:00
}
2013-05-12 05:44:32 +02:00
}
2013-05-11 20:06:22 +02:00
2013-05-12 05:44:32 +02:00
static void
servlist_editchannel_cb ( GtkCellRendererText * cell , gchar * name , gchar * newval , gpointer user_data )
{
GtkTreeModel * model = ( GtkTreeModel * ) user_data ;
GtkTreeIter iter ;
char * chan ;
char * key ;
favchannel * favchan ;
if ( ! selected_net )
{
return ;
}
if ( ! servlist_get_iter_from_name ( model , name , & iter ) )
{
return ;
}
gtk_tree_model_get ( model , & iter , 0 , & chan , 1 , & key , - 1 ) ;
favchan = servlist_favchan_find ( selected_net , chan , NULL ) ;
g_free ( chan ) ;
if ( favchan )
{
/* delete empty item */
if ( newval [ 0 ] = = 0 )
{
servlist_deletechannel ( favchan , model ) ;
return ;
}
chan = favchan - > name ;
favchan - > name = g_strdup ( newval ) ;
gtk_list_store_set ( GTK_LIST_STORE ( model ) , & iter , 0 , favchan - > name , - 1 ) ;
g_free ( chan ) ;
}
}
static void
servlist_editkey_cb ( GtkCellRendererText * cell , gchar * name , gchar * newval , gpointer user_data )
{
GtkTreeModel * model = ( GtkTreeModel * ) user_data ;
GtkTreeIter iter ;
char * chan ;
char * key ;
favchannel * favchan ;
if ( ! selected_net )
{
return ;
}
if ( ! servlist_get_iter_from_name ( model , name , & iter ) )
{
return ;
}
gtk_tree_model_get ( model , & iter , 0 , & chan , 1 , & key , - 1 ) ;
favchan = servlist_favchan_find ( selected_net , chan , NULL ) ;
g_free ( chan ) ;
if ( favchan )
{
key = favchan - > key ;
2013-05-17 02:24:47 +02:00
if ( strlen ( newval ) ) /* check key length, the field can be empty in order to delete the key! */
{
favchan - > key = g_strdup ( newval ) ;
}
else /* if key's empty, make sure we actually remove the key */
{
favchan - > key = NULL ;
}
2013-05-12 05:44:32 +02:00
gtk_list_store_set ( GTK_LIST_STORE ( model ) , & iter , 1 , favchan - > key , - 1 ) ;
g_free ( key ) ;
}
2013-05-11 20:06:22 +02:00
}
2013-05-12 16:59:21 +02:00
static gboolean
servlist_edit_tabswitch_cb ( GtkNotebook * nb , gpointer * newtab , guint newindex , gpointer user_data )
{
/* remember the active tab */
netedit_active_tab = newindex ;
return FALSE ;
}
2011-02-24 04:14:30 +01:00
static void
servlist_combo_cb ( GtkEntry * entry , gpointer userdata )
{
if ( ! selected_net )
return ;
2014-12-28 06:37:25 -05:00
g_free ( selected_net - > encoding ) ;
selected_net - > encoding = g_strdup ( gtk_entry_get_text ( entry ) ) ;
2011-02-24 04:14:30 +01:00
}
2013-05-10 23:52:47 +02:00
/* Fills up the network's authentication type so that it's guaranteed to be either NULL or a valid value. */
2013-04-28 21:24:53 +02:00
static void
2013-05-19 04:34:20 +02:00
servlist_logintypecombo_cb ( GtkComboBox * cb , gpointer * userdata )
2013-04-28 21:24:53 +02:00
{
2013-05-10 23:52:47 +02:00
int index ;
2013-04-28 21:24:53 +02:00
if ( ! selected_net )
{
return ;
}
2013-05-11 09:20:03 -04:00
index = gtk_combo_box_get_active ( cb ) ; /* starts at 0, returns -1 for invalid selections */
2013-05-10 23:52:47 +02:00
2014-08-23 14:13:34 -04:00
if ( index = = - 1 )
return ; /* Invalid */
/* The selection is valid. It can be 0, which is the default type, but we need to allow
* that so that you can revert from other types . servlist_save ( ) will dump 0 anyway .
*/
selected_net - > logintype = login_types_conf [ index ] ;
2013-05-19 04:34:20 +02:00
if ( login_types_conf [ index ] = = LOGIN_CUSTOM )
{
gtk_notebook_set_current_page ( GTK_NOTEBOOK ( userdata ) , 2 ) ; /* FIXME avoid hardcoding? */
}
2013-09-02 14:24:37 -04:00
/* EXTERNAL uses a cert, not a pass */
if ( login_types_conf [ index ] = = LOGIN_SASLEXTERNAL )
gtk_widget_set_sensitive ( edit_entry_pass , FALSE ) ;
else
gtk_widget_set_sensitive ( edit_entry_pass , TRUE ) ;
2013-04-28 21:24:53 +02:00
}
2014-04-18 23:45:27 -04:00
static void
servlist_username_changed_cb ( GtkEntry * entry , gpointer userdata )
{
GtkWidget * connect_btn = GTK_WIDGET ( userdata ) ;
if ( gtk_entry_get_text ( entry ) [ 0 ] = = 0 )
{
2026-01-30 15:27:01 -07:00
gtk_entry_set_icon_from_icon_name ( entry , GTK_ENTRY_ICON_SECONDARY , ICON_SERVLIST_ERROR ) ;
2014-04-18 23:45:27 -04:00
gtk_entry_set_icon_tooltip_text ( entry , GTK_ENTRY_ICON_SECONDARY ,
_ ( " User name cannot be left blank. " ) ) ;
gtk_widget_set_sensitive ( connect_btn , FALSE ) ;
}
else
{
2026-01-23 12:57:52 -07:00
gtk_entry_set_icon_from_icon_name ( entry , GTK_ENTRY_ICON_SECONDARY , NULL ) ;
2014-04-18 23:45:27 -04:00
gtk_widget_set_sensitive ( connect_btn , TRUE ) ;
}
}
static void
servlist_nick_changed_cb ( GtkEntry * entry , gpointer userdata )
{
GtkWidget * connect_btn = GTK_WIDGET ( userdata ) ;
const gchar * nick1 = gtk_entry_get_text ( GTK_ENTRY ( entry_nick1 ) ) ;
const gchar * nick2 = gtk_entry_get_text ( GTK_ENTRY ( entry_nick2 ) ) ;
2016-06-12 15:01:39 -04:00
if ( ! nick1 [ 0 ] | | ! nick2 [ 0 ] )
{
entry = GTK_ENTRY ( ! nick1 [ 0 ] ? entry_nick1 : entry_nick2 ) ;
2026-01-30 15:27:01 -07:00
gtk_entry_set_icon_from_icon_name ( entry , GTK_ENTRY_ICON_SECONDARY , ICON_SERVLIST_ERROR ) ;
2016-06-12 15:01:39 -04:00
gtk_entry_set_icon_tooltip_text ( entry , GTK_ENTRY_ICON_SECONDARY ,
_ ( " You cannot have an empty nick name. " ) ) ;
gtk_widget_set_sensitive ( connect_btn , FALSE ) ;
}
else if ( ! rfc_casecmp ( nick1 , nick2 ) )
2014-04-18 23:45:27 -04:00
{
2026-01-30 15:27:01 -07:00
gtk_entry_set_icon_from_icon_name ( entry , GTK_ENTRY_ICON_SECONDARY , ICON_SERVLIST_ERROR ) ;
2014-04-18 23:45:27 -04:00
gtk_entry_set_icon_tooltip_text ( entry , GTK_ENTRY_ICON_SECONDARY ,
_ ( " You must have two unique nick names. " ) ) ;
gtk_widget_set_sensitive ( connect_btn , FALSE ) ;
}
else
{
2026-01-23 12:57:52 -07:00
gtk_entry_set_icon_from_icon_name ( GTK_ENTRY ( entry_nick1 ) , GTK_ENTRY_ICON_SECONDARY , NULL ) ;
gtk_entry_set_icon_from_icon_name ( GTK_ENTRY ( entry_nick2 ) , GTK_ENTRY_ICON_SECONDARY , NULL ) ;
2014-04-18 23:45:27 -04:00
gtk_widget_set_sensitive ( connect_btn , TRUE ) ;
}
}
2013-04-28 21:24:53 +02:00
2011-02-24 04:14:30 +01:00
static GtkWidget *
servlist_create_charsetcombo ( void )
{
GtkWidget * cb ;
int i ;
2013-05-11 09:20:03 -04:00
cb = gtk_combo_box_text_new_with_entry ( ) ;
2011-02-24 04:14:30 +01:00
i = 0 ;
while ( pages [ i ] )
{
2013-05-11 09:20:03 -04:00
gtk_combo_box_text_append_text ( GTK_COMBO_BOX_TEXT ( cb ) , ( char * ) pages [ i ] ) ;
2011-02-24 04:14:30 +01:00
i + + ;
}
2013-05-11 09:20:03 -04:00
2015-01-18 02:10:05 -08:00
gtk_entry_set_text ( GTK_ENTRY ( gtk_bin_get_child ( GTK_BIN ( cb ) ) ) , selected_net - > encoding ? selected_net - > encoding : pages [ 0 ] ) ;
2013-05-11 09:20:03 -04:00
2013-05-12 01:43:27 -04:00
g_signal_connect ( G_OBJECT ( gtk_bin_get_child ( GTK_BIN ( cb ) ) ) , " changed " ,
2011-02-24 04:14:30 +01:00
G_CALLBACK ( servlist_combo_cb ) , NULL ) ;
return cb ;
}
2013-04-28 21:24:53 +02:00
static GtkWidget *
2013-05-19 04:34:20 +02:00
servlist_create_logintypecombo ( GtkWidget * data )
2013-04-28 21:24:53 +02:00
{
GtkWidget * cb ;
int i ;
2013-05-11 09:20:03 -04:00
cb = gtk_combo_box_text_new ( ) ;
2013-04-28 21:24:53 +02:00
2013-05-10 23:52:47 +02:00
i = 0 ;
2013-04-28 21:24:53 +02:00
2013-05-10 23:52:47 +02:00
while ( login_types [ i ] )
2013-04-28 21:24:53 +02:00
{
2013-05-11 09:20:03 -04:00
gtk_combo_box_text_append_text ( GTK_COMBO_BOX_TEXT ( cb ) , ( char * ) login_types [ i ] ) ;
2013-04-28 21:24:53 +02:00
i + + ;
}
2013-05-11 11:54:42 +02:00
gtk_combo_box_set_active ( GTK_COMBO_BOX ( cb ) , servlist_get_login_desc_index ( selected_net - > logintype ) ) ;
2013-05-11 09:20:03 -04:00
2014-01-18 04:08:32 -05:00
gtk_widget_set_tooltip_text ( cb , _ ( " The way you identify yourself to the server. For custom login methods use connect commands. " ) ) ;
2013-05-19 04:34:20 +02:00
g_signal_connect ( G_OBJECT ( GTK_BIN ( cb ) ) , " changed " , G_CALLBACK ( servlist_logintypecombo_cb ) , data ) ;
2013-04-28 21:24:53 +02:00
return cb ;
}
2011-02-24 04:14:30 +01:00
static void
no_servlist ( GtkWidget * igad , gpointer serv )
{
2013-05-12 01:43:27 -04:00
if ( gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( igad ) ) )
2012-10-22 13:49:28 +02:00
prefs . hex_gui_slist_skip = TRUE ;
2011-02-24 04:14:30 +01:00
else
2012-10-22 13:49:28 +02:00
prefs . hex_gui_slist_skip = FALSE ;
2011-02-24 04:14:30 +01:00
}
static void
fav_servlist ( GtkWidget * igad , gpointer serv )
{
2013-05-12 01:43:27 -04:00
if ( gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( igad ) ) )
2012-10-22 13:49:28 +02:00
prefs . hex_gui_slist_fav = TRUE ;
2011-02-24 04:14:30 +01:00
else
2012-10-22 13:49:28 +02:00
prefs . hex_gui_slist_fav = FALSE ;
2011-02-24 04:14:30 +01:00
servlist_networks_populate ( networks_tree , network_list ) ;
}
static GtkWidget *
bold_label ( char * text )
{
char buf [ 128 ] ;
GtkWidget * label ;
2014-12-17 18:49:59 -05:00
g_snprintf ( buf , sizeof ( buf ) , " <b>%s</b> " , text ) ;
2011-02-24 04:14:30 +01:00
label = gtk_label_new ( buf ) ;
gtk_label_set_use_markup ( GTK_LABEL ( label ) , TRUE ) ;
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( label , GTK_ALIGN_START ) ;
gtk_widget_set_valign ( label , GTK_ALIGN_CENTER ) ;
2011-02-24 04:14:30 +01:00
gtk_widget_show ( label ) ;
return label ;
}
static GtkWidget *
servlist_open_edit ( GtkWidget * parent , ircnet * net )
{
GtkWidget * editwindow ;
GtkWidget * vbox5 ;
GtkWidget * table3 ;
GtkWidget * label34 ;
2013-05-10 23:52:47 +02:00
GtkWidget * label_logintype ;
2011-02-24 04:14:30 +01:00
GtkWidget * comboboxentry_charset ;
2013-05-11 09:20:03 -04:00
GtkWidget * combobox_logintypes ;
2011-02-24 04:14:30 +01:00
GtkWidget * hbox1 ;
GtkWidget * scrolledwindow2 ;
2013-05-11 01:20:53 +02:00
GtkWidget * scrolledwindow4 ;
GtkWidget * scrolledwindow5 ;
2011-02-24 04:14:30 +01:00
GtkWidget * treeview_servers ;
2013-05-11 09:20:03 -04:00
GtkWidget * treeview_channels ;
GtkWidget * treeview_commands ;
2011-02-24 04:14:30 +01:00
GtkWidget * vbuttonbox1 ;
GtkWidget * buttonadd ;
GtkWidget * buttonremove ;
GtkWidget * buttonedit ;
2026-03-24 23:00:09 -06:00
GtkWidget * hbox_cert_buttons ;
2011-02-24 04:14:30 +01:00
GtkWidget * hseparator2 ;
GtkWidget * hbuttonbox4 ;
GtkWidget * button10 ;
GtkWidget * check ;
2013-05-11 01:20:53 +02:00
GtkWidget * notebook ;
2011-02-24 04:14:30 +01:00
GtkTreeModel * model ;
GtkListStore * store ;
GtkCellRenderer * renderer ;
char buf [ 128 ] ;
editwindow = gtk_window_new ( GTK_WINDOW_TOPLEVEL ) ;
2026-03-04 23:28:01 -07:00
theme_manager_attach_window ( editwindow ) ;
2011-02-24 04:14:30 +01:00
gtk_container_set_border_width ( GTK_CONTAINER ( editwindow ) , 4 ) ;
2017-09-15 17:36:02 -04:00
g_snprintf ( buf , sizeof ( buf ) , _ ( " Edit %s - %s " ) , net - > name , _ ( DISPLAY_NAME ) ) ;
2011-02-24 04:14:30 +01:00
gtk_window_set_title ( GTK_WINDOW ( editwindow ) , buf ) ;
2013-05-11 15:58:52 +02:00
gtk_window_set_default_size ( GTK_WINDOW ( editwindow ) , netedit_win_width , netedit_win_height ) ;
2011-02-24 04:14:30 +01:00
gtk_window_set_transient_for ( GTK_WINDOW ( editwindow ) , GTK_WINDOW ( parent ) ) ;
gtk_window_set_modal ( GTK_WINDOW ( editwindow ) , TRUE ) ;
gtk_window_set_type_hint ( GTK_WINDOW ( editwindow ) , GDK_WINDOW_TYPE_HINT_DIALOG ) ;
gtk_window_set_role ( GTK_WINDOW ( editwindow ) , " editserv " ) ;
2026-02-05 01:59:15 -07:00
vbox5 = gtkutil_box_new ( GTK_ORIENTATION_VERTICAL , FALSE , 0 ) ;
2011-02-24 04:14:30 +01:00
gtk_container_add ( GTK_CONTAINER ( editwindow ) , vbox5 ) ;
2013-05-11 20:06:22 +02:00
/* Tabs and buttons */
2026-02-05 01:59:15 -07:00
hbox1 = gtkutil_box_new ( GTK_ORIENTATION_HORIZONTAL , FALSE , 0 ) ;
2013-05-11 15:22:28 +02:00
gtk_box_pack_start ( GTK_BOX ( vbox5 ) , hbox1 , TRUE , TRUE , 4 ) ;
2011-02-24 04:14:30 +01:00
scrolledwindow2 = gtk_scrolled_window_new ( NULL , NULL ) ;
2013-05-11 01:20:53 +02:00
scrolledwindow4 = gtk_scrolled_window_new ( NULL , NULL ) ;
scrolledwindow5 = gtk_scrolled_window_new ( NULL , NULL ) ;
notebook = gtk_notebook_new ( ) ;
2013-06-02 20:50:43 -04:00
gtk_notebook_append_page ( GTK_NOTEBOOK ( notebook ) , scrolledwindow2 , gtk_label_new ( _ ( " Servers " ) ) ) ;
gtk_notebook_append_page ( GTK_NOTEBOOK ( notebook ) , scrolledwindow4 , gtk_label_new ( _ ( " Autojoin channels " ) ) ) ;
gtk_notebook_append_page ( GTK_NOTEBOOK ( notebook ) , scrolledwindow5 , gtk_label_new ( _ ( " Connect commands " ) ) ) ;
2013-05-11 16:30:45 +02:00
gtk_notebook_set_tab_pos ( GTK_NOTEBOOK ( notebook ) , GTK_POS_BOTTOM ) ;
2013-05-11 15:22:28 +02:00
gtk_box_pack_start ( GTK_BOX ( hbox1 ) , notebook , TRUE , TRUE , SERVLIST_X_PADDING ) ;
2013-05-11 01:20:53 +02:00
2013-05-11 20:06:22 +02:00
gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( scrolledwindow2 ) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC ) ;
gtk_scrolled_window_set_shadow_type ( GTK_SCROLLED_WINDOW ( scrolledwindow2 ) , GTK_SHADOW_IN ) ;
gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( scrolledwindow4 ) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC ) ;
gtk_scrolled_window_set_shadow_type ( GTK_SCROLLED_WINDOW ( scrolledwindow4 ) , GTK_SHADOW_IN ) ;
gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( scrolledwindow5 ) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC ) ;
gtk_scrolled_window_set_shadow_type ( GTK_SCROLLED_WINDOW ( scrolledwindow5 ) , GTK_SHADOW_IN ) ;
2014-01-18 04:08:32 -05:00
gtk_widget_set_tooltip_text ( scrolledwindow5 , _ ( " %n=Nick name \n %p=Password \n %r=Real name \n %u=User name " ) ) ;
2011-02-24 04:14:30 +01:00
2013-05-11 09:20:03 -04:00
/* Server Tree */
2011-02-24 04:14:30 +01:00
store = gtk_list_store_new ( 2 , G_TYPE_STRING , G_TYPE_BOOLEAN ) ;
model = GTK_TREE_MODEL ( store ) ;
2013-05-11 09:20:03 -04:00
edit_trees [ SERVER_TREE ] = treeview_servers = gtk_tree_view_new_with_model ( model ) ;
2026-03-17 10:30:54 -06:00
g_signal_connect ( G_OBJECT ( treeview_servers ) , " key-press-event " ,
2013-05-20 13:19:20 -03:00
G_CALLBACK ( servlist_keypress_cb ) , notebook ) ;
g_signal_connect ( G_OBJECT ( gtk_tree_view_get_selection ( GTK_TREE_VIEW ( treeview_servers ) ) ) ,
" changed " , G_CALLBACK ( servlist_server_row_cb ) , NULL ) ;
2011-02-24 04:14:30 +01:00
g_object_unref ( model ) ;
gtk_container_add ( GTK_CONTAINER ( scrolledwindow2 ) , treeview_servers ) ;
2013-05-11 09:20:03 -04:00
gtk_widget_set_size_request ( treeview_servers , - 1 , 80 ) ;
2011-02-24 04:14:30 +01:00
gtk_tree_view_set_headers_visible ( GTK_TREE_VIEW ( treeview_servers ) ,
FALSE ) ;
renderer = gtk_cell_renderer_text_new ( ) ;
g_signal_connect ( G_OBJECT ( renderer ) , " edited " ,
G_CALLBACK ( servlist_editserver_cb ) , model ) ;
gtk_tree_view_insert_column_with_attributes (
GTK_TREE_VIEW ( treeview_servers ) , - 1 ,
0 , renderer ,
" text " , 0 ,
" editable " , 1 ,
NULL ) ;
2013-05-11 09:20:03 -04:00
/* Channel Tree */
store = gtk_list_store_new ( 3 , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_BOOLEAN ) ;
model = GTK_TREE_MODEL ( store ) ;
edit_trees [ CHANNEL_TREE ] = treeview_channels = gtk_tree_view_new_with_model ( model ) ;
2026-03-17 10:30:54 -06:00
g_signal_connect ( G_OBJECT ( treeview_channels ) , " key-press-event " ,
2013-05-20 13:19:20 -03:00
G_CALLBACK ( servlist_keypress_cb ) , notebook ) ;
g_signal_connect ( G_OBJECT ( gtk_tree_view_get_selection ( GTK_TREE_VIEW ( treeview_channels ) ) ) ,
" changed " , G_CALLBACK ( servlist_channel_row_cb ) , NULL ) ;
2013-05-11 09:20:03 -04:00
g_object_unref ( model ) ;
gtk_container_add ( GTK_CONTAINER ( scrolledwindow4 ) , treeview_channels ) ;
gtk_tree_view_set_headers_visible ( GTK_TREE_VIEW ( treeview_channels ) , TRUE ) ;
renderer = gtk_cell_renderer_text_new ( ) ;
g_signal_connect ( G_OBJECT ( renderer ) , " edited " ,
G_CALLBACK ( servlist_editchannel_cb ) , model ) ;
gtk_tree_view_insert_column_with_attributes (
GTK_TREE_VIEW ( treeview_channels ) , - 1 ,
_ ( " Channel " ) , renderer ,
" text " , 0 ,
" editable " , 2 ,
NULL ) ;
renderer = gtk_cell_renderer_text_new ( ) ;
g_signal_connect ( G_OBJECT ( renderer ) , " edited " ,
G_CALLBACK ( servlist_editkey_cb ) , model ) ;
gtk_tree_view_insert_column_with_attributes (
GTK_TREE_VIEW ( treeview_channels ) , - 1 ,
_ ( " Key (Password) " ) , renderer ,
" text " , 1 ,
" editable " , 2 ,
NULL ) ;
gtk_tree_view_column_set_expand ( gtk_tree_view_get_column ( GTK_TREE_VIEW ( treeview_channels ) , 0 ) , TRUE ) ;
gtk_tree_view_column_set_expand ( gtk_tree_view_get_column ( GTK_TREE_VIEW ( treeview_channels ) , 1 ) , TRUE ) ;
2013-05-11 20:06:22 +02:00
2013-05-11 09:20:03 -04:00
/* Command Tree */
store = gtk_list_store_new ( 2 , G_TYPE_STRING , G_TYPE_BOOLEAN ) ;
model = GTK_TREE_MODEL ( store ) ;
edit_trees [ CMD_TREE ] = treeview_commands = gtk_tree_view_new_with_model ( model ) ;
2026-03-17 10:30:54 -06:00
g_signal_connect ( G_OBJECT ( treeview_commands ) , " key-press-event " ,
2013-05-20 13:19:20 -03:00
G_CALLBACK ( servlist_keypress_cb ) , notebook ) ;
g_signal_connect ( G_OBJECT ( gtk_tree_view_get_selection ( GTK_TREE_VIEW ( treeview_commands ) ) ) ,
" changed " , G_CALLBACK ( servlist_command_row_cb ) , NULL ) ;
2013-05-11 09:20:03 -04:00
g_object_unref ( model ) ;
gtk_container_add ( GTK_CONTAINER ( scrolledwindow5 ) , treeview_commands ) ;
gtk_tree_view_set_headers_visible ( GTK_TREE_VIEW ( treeview_commands ) ,
FALSE ) ;
renderer = gtk_cell_renderer_text_new ( ) ;
g_signal_connect ( G_OBJECT ( renderer ) , " edited " ,
G_CALLBACK ( servlist_editcommand_cb ) , model ) ;
gtk_tree_view_insert_column_with_attributes (
GTK_TREE_VIEW ( treeview_commands ) , - 1 ,
0 , renderer ,
" text " , 0 ,
" editable " , 1 ,
NULL ) ;
2013-05-11 20:06:22 +02:00
2013-05-11 09:20:03 -04:00
/* Button Box */
2026-01-30 17:48:25 -07:00
vbuttonbox1 = gtk_button_box_new ( GTK_ORIENTATION_VERTICAL ) ;
2011-02-24 04:14:30 +01:00
gtk_box_set_spacing ( GTK_BOX ( vbuttonbox1 ) , 3 ) ;
gtk_button_box_set_layout ( GTK_BUTTON_BOX ( vbuttonbox1 ) , GTK_BUTTONBOX_START ) ;
gtk_box_pack_start ( GTK_BOX ( hbox1 ) , vbuttonbox1 , FALSE , FALSE , 3 ) ;
2026-01-30 15:27:01 -07:00
buttonadd = servlist_icon_button_new ( _ ( " _Add " ) , ICON_SERVLIST_ADD ) ;
2011-02-24 04:14:30 +01:00
g_signal_connect ( G_OBJECT ( buttonadd ) , " clicked " ,
2013-05-11 09:20:03 -04:00
G_CALLBACK ( servlist_addbutton_cb ) , notebook ) ;
2011-02-24 04:14:30 +01:00
gtk_container_add ( GTK_CONTAINER ( vbuttonbox1 ) , buttonadd ) ;
2013-05-12 01:43:27 -04:00
gtk_widget_set_can_default ( buttonadd , TRUE ) ;
2011-02-24 04:14:30 +01:00
2026-01-30 15:27:01 -07:00
buttonremove = servlist_icon_button_new ( _ ( " _Remove " ) , ICON_SERVLIST_REMOVE ) ;
2011-02-24 04:14:30 +01:00
g_signal_connect ( G_OBJECT ( buttonremove ) , " clicked " ,
2013-05-11 09:20:03 -04:00
G_CALLBACK ( servlist_deletebutton_cb ) , notebook ) ;
2011-02-24 04:14:30 +01:00
gtk_container_add ( GTK_CONTAINER ( vbuttonbox1 ) , buttonremove ) ;
2013-05-12 01:43:27 -04:00
gtk_widget_set_can_default ( buttonremove , TRUE ) ;
2011-02-24 04:14:30 +01:00
buttonedit = gtk_button_new_with_mnemonic ( _ ( " _Edit " ) ) ;
g_signal_connect ( G_OBJECT ( buttonedit ) , " clicked " ,
2013-05-11 09:20:03 -04:00
G_CALLBACK ( servlist_editbutton_cb ) , notebook ) ;
2011-02-24 04:14:30 +01:00
gtk_container_add ( GTK_CONTAINER ( vbuttonbox1 ) , buttonedit ) ;
2013-05-12 01:43:27 -04:00
gtk_widget_set_can_default ( buttonedit , TRUE ) ;
2011-02-24 04:14:30 +01:00
2013-05-11 20:06:22 +02:00
/* Checkboxes and entries */
2026-06-02 15:57:28 -06:00
table3 = gtkutil_grid_new ( 16 , 2 , FALSE ) ;
2026-01-30 17:13:44 -07:00
gtk_box_pack_start ( GTK_BOX ( vbox5 ) , table3 , FALSE , FALSE , 0 ) ;
gtk_grid_set_row_spacing ( GTK_GRID ( table3 ) , 2 ) ;
gtk_grid_set_column_spacing ( GTK_GRID ( table3 ) , 8 ) ;
2013-05-11 15:22:28 +02:00
check = servlist_create_check ( 0 , ! ( net - > flags & FLAG_CYCLE ) , table3 , 0 , 0 , _ ( " Connect to selected server only " ) ) ;
2014-01-18 04:08:32 -05:00
gtk_widget_set_tooltip_text ( check , _ ( " Don't cycle through all the servers when the connection fails. " ) ) ;
2013-05-11 15:22:28 +02:00
servlist_create_check ( 3 , net - > flags & FLAG_AUTO_CONNECT , table3 , 1 , 0 , _ ( " Connect to this network automatically " ) ) ;
servlist_create_check ( 4 , ! ( net - > flags & FLAG_USE_PROXY ) , table3 , 2 , 0 , _ ( " Bypass proxy server " ) ) ;
check = servlist_create_check ( 2 , net - > flags & FLAG_USE_SSL , table3 , 3 , 0 , _ ( " Use SSL for all the servers on this network " ) ) ;
# ifndef USE_OPENSSL
gtk_widget_set_sensitive ( check , FALSE ) ;
# endif
check = servlist_create_check ( 5 , net - > flags & FLAG_ALLOW_INVALID , table3 , 4 , 0 , _ ( " Accept invalid SSL certificates " ) ) ;
# ifndef USE_OPENSSL
gtk_widget_set_sensitive ( check , FALSE ) ;
# endif
servlist_create_check ( 1 , net - > flags & FLAG_USE_GLOBAL , table3 , 5 , 0 , _ ( " Use global user information " ) ) ;
2026-06-02 15:57:28 -06:00
edit_check_use_keyring = gtk_check_button_new_with_mnemonic ( _ ( " Use system keyring " ) ) ;
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( edit_check_use_keyring ) , net - > flags & FLAG_USE_KEYRING ) ;
servlist_table_attach ( table3 , edit_check_use_keyring , 0 , 2 , 6 , 7 ,
FALSE , FALSE ,
SERVLIST_ALIGN_START , SERVLIST_ALIGN_CENTER ,
SERVLIST_X_PADDING , SERVLIST_Y_PADDING ) ;
g_signal_connect ( G_OBJECT ( edit_check_use_keyring ) , " toggled " ,
G_CALLBACK ( servlist_toggle_keyring_cb ) , NULL ) ;
edit_entry_nick = servlist_create_entry ( table3 , _ ( " _Nick name: " ) , 7 , net - > nick , & edit_label_nick , 0 ) ;
edit_entry_nick2 = servlist_create_entry ( table3 , _ ( " Second choice: " ) , 8 , net - > nick2 , & edit_label_nick2 , 0 ) ;
edit_entry_real = servlist_create_entry ( table3 , _ ( " Rea_l name: " ) , 9 , net - > real , & edit_label_real , 0 ) ;
edit_entry_user = servlist_create_entry ( table3 , _ ( " _User name: " ) , 10 , net - > user , & edit_label_user , 0 ) ;
2013-05-11 15:22:28 +02:00
label_logintype = gtk_label_new ( _ ( " Login method: " ) ) ;
2026-06-02 15:57:28 -06:00
servlist_table_attach ( table3 , label_logintype , 0 , 1 , 11 , 12 ,
2026-01-30 16:04:50 -07:00
FALSE , FALSE ,
SERVLIST_ALIGN_START , SERVLIST_ALIGN_CENTER ,
SERVLIST_X_PADDING , SERVLIST_Y_PADDING ) ;
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( label_logintype , GTK_ALIGN_START ) ;
gtk_widget_set_valign ( label_logintype , GTK_ALIGN_CENTER ) ;
2013-05-19 04:34:20 +02:00
combobox_logintypes = servlist_create_logintypecombo ( notebook ) ;
2026-06-02 15:57:28 -06:00
servlist_table_attach ( table3 , combobox_logintypes , 1 , 2 , 11 , 12 ,
2026-01-30 16:04:50 -07:00
FALSE , FALSE ,
SERVLIST_ALIGN_FILL , SERVLIST_ALIGN_FILL ,
4 , 2 ) ;
2013-05-11 15:22:28 +02:00
2026-06-02 15:57:28 -06:00
edit_entry_pass = servlist_create_entry ( table3 , _ ( " Password: " ) , 12 , NULL , 0 , _ ( " Password used for login. If in doubt, leave blank. " ) ) ;
if ( edit_loaded_password )
{
memset ( edit_loaded_password , 0 , strlen ( edit_loaded_password ) ) ;
g_free ( edit_loaded_password ) ;
edit_loaded_password = NULL ;
}
edit_pass_changed = 0 ;
g_signal_connect ( G_OBJECT ( edit_entry_pass ) , " changed " ,
G_CALLBACK ( servlist_password_changed_cb ) , NULL ) ;
if ( net - > flags & FLAG_USE_KEYRING )
{
char * stored = secretstore_get_network_password ( net - > name ) ;
if ( stored & & * stored )
gtk_entry_set_text ( GTK_ENTRY ( edit_entry_pass ) , " *** " ) ;
if ( stored )
{
memset ( stored , 0 , strlen ( stored ) ) ;
g_free ( stored ) ;
}
}
else if ( net - > pass & & * net - > pass )
{
gtk_entry_set_text ( GTK_ENTRY ( edit_entry_pass ) , " *** " ) ;
}
edit_pass_changed = 0 ;
2013-05-11 15:22:28 +02:00
gtk_entry_set_visibility ( GTK_ENTRY ( edit_entry_pass ) , FALSE ) ;
2013-09-02 14:24:37 -04:00
if ( selected_net & & selected_net - > logintype = = LOGIN_SASLEXTERNAL )
gtk_widget_set_sensitive ( edit_entry_pass , FALSE ) ;
2026-06-02 15:57:28 -06:00
edit_button_load_pass = gtk_button_new_with_mnemonic ( _ ( " Load from keyring " ) ) ;
servlist_table_attach ( table3 , edit_button_load_pass , 0 , 1 , 13 , 14 ,
FALSE , FALSE ,
SERVLIST_ALIGN_START , SERVLIST_ALIGN_CENTER ,
SERVLIST_X_PADDING , SERVLIST_Y_PADDING ) ;
g_signal_connect ( G_OBJECT ( edit_button_load_pass ) , " clicked " ,
G_CALLBACK ( servlist_load_password_cb ) , net ) ;
edit_check_show_pass = gtk_check_button_new_with_mnemonic ( _ ( " Show password " ) ) ;
servlist_table_attach ( table3 , edit_check_show_pass , 1 , 2 , 13 , 14 ,
FALSE , FALSE ,
SERVLIST_ALIGN_START , SERVLIST_ALIGN_CENTER ,
4 , 2 ) ;
g_signal_connect ( G_OBJECT ( edit_check_show_pass ) , " toggled " ,
G_CALLBACK ( servlist_toggle_show_password_cb ) , edit_entry_pass ) ;
2013-05-11 15:22:28 +02:00
label34 = gtk_label_new ( _ ( " Character set: " ) ) ;
2026-06-02 15:57:28 -06:00
servlist_table_attach ( table3 , label34 , 0 , 1 , 14 , 15 ,
2026-01-30 16:04:50 -07:00
FALSE , FALSE ,
SERVLIST_ALIGN_START , SERVLIST_ALIGN_CENTER ,
SERVLIST_X_PADDING , SERVLIST_Y_PADDING ) ;
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( label34 , GTK_ALIGN_START ) ;
gtk_widget_set_valign ( label34 , GTK_ALIGN_CENTER ) ;
2013-05-11 15:22:28 +02:00
comboboxentry_charset = servlist_create_charsetcombo ( ) ;
2026-06-02 15:57:28 -06:00
servlist_table_attach ( table3 , comboboxentry_charset , 1 , 2 , 14 , 15 ,
2026-01-30 16:04:50 -07:00
FALSE , FALSE ,
SERVLIST_ALIGN_FILL , SERVLIST_ALIGN_FILL ,
4 , 2 ) ;
2013-05-11 15:22:28 +02:00
2026-03-24 23:00:09 -06:00
hbox_cert_buttons = gtkutil_box_new ( GTK_ORIENTATION_HORIZONTAL , FALSE , 6 ) ;
edit_button_cert_generate = gtk_button_new_with_mnemonic ( _ ( " Generate client SSL cert " ) ) ;
g_signal_connect ( G_OBJECT ( edit_button_cert_generate ) , " clicked " ,
G_CALLBACK ( servlist_generate_client_cert_cb ) , net ) ;
gtk_box_pack_start ( GTK_BOX ( hbox_cert_buttons ) , edit_button_cert_generate , FALSE , FALSE , 0 ) ;
2026-03-30 11:46:08 -06:00
edit_button_cert_import = gtk_button_new_with_mnemonic ( _ ( " Import client SSL cert " ) ) ;
g_signal_connect ( G_OBJECT ( edit_button_cert_import ) , " clicked " ,
G_CALLBACK ( servlist_import_client_cert_cb ) , net ) ;
gtk_box_pack_start ( GTK_BOX ( hbox_cert_buttons ) , edit_button_cert_import , FALSE , FALSE , 0 ) ;
2026-03-24 23:00:09 -06:00
edit_button_cert_info = gtk_button_new_with_mnemonic ( _ ( " Client SSL cert info " ) ) ;
g_signal_connect ( G_OBJECT ( edit_button_cert_info ) , " clicked " ,
G_CALLBACK ( servlist_cert_info_cb ) , net ) ;
gtk_box_pack_start ( GTK_BOX ( hbox_cert_buttons ) , edit_button_cert_info , FALSE , FALSE , 0 ) ;
edit_button_cert_delete = gtk_button_new_with_mnemonic ( _ ( " Delete cert " ) ) ;
g_signal_connect ( G_OBJECT ( edit_button_cert_delete ) , " clicked " ,
G_CALLBACK ( servlist_delete_client_cert_cb ) , net ) ;
gtk_box_pack_start ( GTK_BOX ( hbox_cert_buttons ) , edit_button_cert_delete , FALSE , FALSE , 0 ) ;
2026-06-02 15:57:28 -06:00
servlist_table_attach ( table3 , hbox_cert_buttons , 0 , 2 , 15 , 16 ,
2026-03-24 23:00:09 -06:00
FALSE , FALSE ,
SERVLIST_ALIGN_START , SERVLIST_ALIGN_CENTER ,
SERVLIST_X_PADDING , SERVLIST_Y_PADDING ) ;
2013-05-11 20:06:22 +02:00
/* Rule and Close button */
2026-01-30 17:48:25 -07:00
hseparator2 = gtk_separator_new ( GTK_ORIENTATION_HORIZONTAL ) ;
2011-02-24 04:14:30 +01:00
gtk_box_pack_start ( GTK_BOX ( vbox5 ) , hseparator2 , FALSE , FALSE , 8 ) ;
2026-01-30 17:03:27 -07:00
hbuttonbox4 = gtk_button_box_new ( GTK_ORIENTATION_HORIZONTAL ) ;
gtk_button_box_set_layout ( GTK_BUTTON_BOX ( hbuttonbox4 ) , GTK_BUTTONBOX_END ) ;
gtk_box_pack_start ( GTK_BOX ( vbox5 ) , hbuttonbox4 , FALSE , FALSE , 0 ) ;
2011-02-24 04:14:30 +01:00
2026-01-30 15:27:01 -07:00
button10 = servlist_icon_button_new ( _ ( " _Close " ) , ICON_SERVLIST_CLOSE ) ;
2011-02-24 04:14:30 +01:00
g_signal_connect ( G_OBJECT ( button10 ) , " clicked " ,
G_CALLBACK ( servlist_edit_close_cb ) , 0 ) ;
gtk_container_add ( GTK_CONTAINER ( hbuttonbox4 ) , button10 ) ;
2013-05-12 01:43:27 -04:00
gtk_widget_set_can_default ( button10 , TRUE ) ;
2011-02-24 04:14:30 +01:00
if ( net - > flags & FLAG_USE_GLOBAL )
{
2013-05-11 03:13:50 +02:00
servlist_toggle_global_user ( FALSE ) ;
2011-02-24 04:14:30 +01:00
}
2026-06-02 15:57:28 -06:00
servlist_toggle_keyring_cb ( GTK_TOGGLE_BUTTON ( edit_check_use_keyring ) , NULL ) ;
2011-02-24 04:14:30 +01:00
gtk_widget_grab_focus ( button10 ) ;
gtk_widget_grab_default ( button10 ) ;
2013-05-11 09:20:03 -04:00
gtk_widget_show_all ( editwindow ) ;
2026-03-24 23:00:09 -06:00
servlist_update_cert_buttons ( net ) ;
2013-05-11 09:20:03 -04:00
2013-05-12 16:59:21 +02:00
/* We can't set the active tab without child elements being shown, so this must be *after* gtk_widget_show()s! */
gtk_notebook_set_current_page ( GTK_NOTEBOOK ( notebook ) , netedit_active_tab ) ;
/* We need to connect this *after* setting the active tab so that the value doesn't get overriden. */
g_signal_connect ( G_OBJECT ( notebook ) , " switch-page " , G_CALLBACK ( servlist_edit_tabswitch_cb ) , notebook ) ;
2011-02-24 04:14:30 +01:00
return editwindow ;
}
static GtkWidget *
servlist_open_networks ( void )
{
GtkWidget * servlist ;
GtkWidget * vbox1 ;
GtkWidget * label2 ;
GtkWidget * table1 ;
GtkWidget * label3 ;
GtkWidget * label4 ;
GtkWidget * label5 ;
GtkWidget * label6 ;
2012-05-16 19:47:12 +02:00
/* GtkWidget *label7; */
2011-02-24 04:14:30 +01:00
GtkWidget * entry1 ;
GtkWidget * entry2 ;
GtkWidget * entry3 ;
GtkWidget * entry4 ;
2012-05-16 19:47:12 +02:00
/* GtkWidget *entry5; */
2011-02-24 04:14:30 +01:00
GtkWidget * vbox2 ;
GtkWidget * label1 ;
GtkWidget * table4 ;
GtkWidget * scrolledwindow3 ;
GtkWidget * treeview_networks ;
GtkWidget * checkbutton_skip ;
GtkWidget * checkbutton_fav ;
GtkWidget * hbox ;
GtkWidget * vbuttonbox2 ;
GtkWidget * button_add ;
GtkWidget * button_remove ;
GtkWidget * button_edit ;
GtkWidget * button_sort ;
GtkWidget * hseparator1 ;
GtkWidget * hbuttonbox1 ;
GtkWidget * button_connect ;
GtkWidget * button_close ;
GtkTreeModel * model ;
GtkListStore * store ;
GtkCellRenderer * renderer ;
2017-09-15 17:36:02 -04:00
char buf [ 128 ] ;
2011-02-24 04:14:30 +01:00
servlist = gtk_window_new ( GTK_WINDOW_TOPLEVEL ) ;
2026-03-04 23:28:01 -07:00
theme_manager_attach_window ( servlist ) ;
2011-02-24 04:14:30 +01:00
gtk_container_set_border_width ( GTK_CONTAINER ( servlist ) , 4 ) ;
2017-09-15 17:36:02 -04:00
g_snprintf ( buf , sizeof ( buf ) , _ ( " Network List - %s " ) , _ ( DISPLAY_NAME ) ) ;
gtk_window_set_title ( GTK_WINDOW ( servlist ) , buf ) ;
2013-05-11 15:58:52 +02:00
gtk_window_set_default_size ( GTK_WINDOW ( servlist ) , netlist_win_width , netlist_win_height ) ;
2011-02-24 04:14:30 +01:00
gtk_window_set_role ( GTK_WINDOW ( servlist ) , " servlist " ) ;
gtk_window_set_type_hint ( GTK_WINDOW ( servlist ) , GDK_WINDOW_TYPE_HINT_DIALOG ) ;
if ( current_sess )
gtk_window_set_transient_for ( GTK_WINDOW ( servlist ) , GTK_WINDOW ( current_sess - > gui - > window ) ) ;
2026-02-05 01:59:15 -07:00
vbox1 = gtkutil_box_new ( GTK_ORIENTATION_VERTICAL , FALSE , 0 ) ;
2011-02-24 04:14:30 +01:00
gtk_widget_show ( vbox1 ) ;
gtk_container_add ( GTK_CONTAINER ( servlist ) , vbox1 ) ;
label2 = bold_label ( _ ( " User Information " ) ) ;
gtk_box_pack_start ( GTK_BOX ( vbox1 ) , label2 , FALSE , FALSE , 0 ) ;
2026-02-05 01:59:15 -07:00
table1 = gtkutil_grid_new ( 5 , 2 , FALSE ) ;
2026-01-30 17:13:44 -07:00
gtk_widget_show ( table1 ) ;
gtk_box_pack_start ( GTK_BOX ( vbox1 ) , table1 , FALSE , FALSE , 0 ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( table1 ) , 8 ) ;
gtk_grid_set_row_spacing ( GTK_GRID ( table1 ) , 2 ) ;
gtk_grid_set_column_spacing ( GTK_GRID ( table1 ) , 4 ) ;
2011-02-24 04:14:30 +01:00
label3 = gtk_label_new_with_mnemonic ( _ ( " _Nick name: " ) ) ;
gtk_widget_show ( label3 ) ;
2026-01-30 16:04:50 -07:00
servlist_table_attach ( table1 , label3 , 0 , 1 , 0 , 1 ,
FALSE , FALSE ,
SERVLIST_ALIGN_START , SERVLIST_ALIGN_CENTER ,
0 , 0 ) ;
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( label3 , GTK_ALIGN_START ) ;
gtk_widget_set_valign ( label3 , GTK_ALIGN_CENTER ) ;
2011-02-24 04:14:30 +01:00
label4 = gtk_label_new ( _ ( " Second choice: " ) ) ;
gtk_widget_show ( label4 ) ;
2026-01-30 16:04:50 -07:00
servlist_table_attach ( table1 , label4 , 0 , 1 , 1 , 2 ,
FALSE , FALSE ,
SERVLIST_ALIGN_START , SERVLIST_ALIGN_CENTER ,
0 , 0 ) ;
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( label4 , GTK_ALIGN_START ) ;
gtk_widget_set_valign ( label4 , GTK_ALIGN_CENTER ) ;
2011-02-24 04:14:30 +01:00
label5 = gtk_label_new ( _ ( " Third choice: " ) ) ;
gtk_widget_show ( label5 ) ;
2026-01-30 16:04:50 -07:00
servlist_table_attach ( table1 , label5 , 0 , 1 , 2 , 3 ,
FALSE , FALSE ,
SERVLIST_ALIGN_START , SERVLIST_ALIGN_CENTER ,
0 , 0 ) ;
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( label5 , GTK_ALIGN_START ) ;
gtk_widget_set_valign ( label5 , GTK_ALIGN_CENTER ) ;
2011-02-24 04:14:30 +01:00
label6 = gtk_label_new_with_mnemonic ( _ ( " _User name: " ) ) ;
gtk_widget_show ( label6 ) ;
2026-01-30 16:04:50 -07:00
servlist_table_attach ( table1 , label6 , 0 , 1 , 3 , 4 ,
FALSE , FALSE ,
SERVLIST_ALIGN_START , SERVLIST_ALIGN_CENTER ,
0 , 0 ) ;
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( label6 , GTK_ALIGN_START ) ;
gtk_widget_set_valign ( label6 , GTK_ALIGN_CENTER ) ;
2011-02-24 04:14:30 +01:00
2012-05-16 19:47:12 +02:00
/* label7 = gtk_label_new_with_mnemonic (_("Rea_l name:"));
2011-02-24 04:14:30 +01:00
gtk_widget_show ( label7 ) ;
gtk_table_attach ( GTK_TABLE ( table1 ) , label7 , 0 , 1 , 4 , 5 ,
( GtkAttachOptions ) ( GTK_FILL ) ,
( GtkAttachOptions ) ( 0 ) , 0 , 0 ) ;
2026-01-23 21:16:43 -07:00
*/
2011-02-24 04:14:30 +01:00
entry_nick1 = entry1 = gtk_entry_new ( ) ;
2012-10-22 14:50:36 +02:00
gtk_entry_set_text ( GTK_ENTRY ( entry1 ) , prefs . hex_irc_nick1 ) ;
2011-02-24 04:14:30 +01:00
gtk_widget_show ( entry1 ) ;
2026-01-30 16:04:50 -07:00
servlist_table_attach ( table1 , entry1 , 1 , 2 , 0 , 1 ,
TRUE , FALSE ,
SERVLIST_ALIGN_FILL , SERVLIST_ALIGN_CENTER ,
0 , 0 ) ;
2011-02-24 04:14:30 +01:00
entry_nick2 = entry2 = gtk_entry_new ( ) ;
2012-10-22 14:50:36 +02:00
gtk_entry_set_text ( GTK_ENTRY ( entry2 ) , prefs . hex_irc_nick2 ) ;
2011-02-24 04:14:30 +01:00
gtk_widget_show ( entry2 ) ;
2026-01-30 16:04:50 -07:00
servlist_table_attach ( table1 , entry2 , 1 , 2 , 1 , 2 ,
TRUE , FALSE ,
SERVLIST_ALIGN_FILL , SERVLIST_ALIGN_CENTER ,
0 , 0 ) ;
2011-02-24 04:14:30 +01:00
entry_nick3 = entry3 = gtk_entry_new ( ) ;
2012-10-22 14:50:36 +02:00
gtk_entry_set_text ( GTK_ENTRY ( entry3 ) , prefs . hex_irc_nick3 ) ;
2011-02-24 04:14:30 +01:00
gtk_widget_show ( entry3 ) ;
2026-01-30 16:04:50 -07:00
servlist_table_attach ( table1 , entry3 , 1 , 2 , 2 , 3 ,
TRUE , FALSE ,
SERVLIST_ALIGN_FILL , SERVLIST_ALIGN_CENTER ,
0 , 0 ) ;
2011-02-24 04:14:30 +01:00
entry_guser = entry4 = gtk_entry_new ( ) ;
2012-10-22 14:50:36 +02:00
gtk_entry_set_text ( GTK_ENTRY ( entry4 ) , prefs . hex_irc_user_name ) ;
2011-02-24 04:14:30 +01:00
gtk_widget_show ( entry4 ) ;
2026-01-30 16:04:50 -07:00
servlist_table_attach ( table1 , entry4 , 1 , 2 , 3 , 4 ,
TRUE , FALSE ,
SERVLIST_ALIGN_FILL , SERVLIST_ALIGN_CENTER ,
0 , 0 ) ;
2011-02-24 04:14:30 +01:00
2012-05-16 19:47:12 +02:00
/* entry_greal = entry5 = gtk_entry_new ();
2012-10-22 14:50:36 +02:00
gtk_entry_set_text ( GTK_ENTRY ( entry5 ) , prefs . hex_irc_real_name ) ;
2011-02-24 04:14:30 +01:00
gtk_widget_show ( entry5 ) ;
gtk_table_attach ( GTK_TABLE ( table1 ) , entry5 , 1 , 2 , 4 , 5 ,
( GtkAttachOptions ) ( GTK_EXPAND | GTK_FILL ) ,
2012-05-16 19:47:12 +02:00
( GtkAttachOptions ) ( 0 ) , 0 , 0 ) ; */
2011-02-24 04:14:30 +01:00
2026-02-05 01:59:15 -07:00
vbox2 = gtkutil_box_new ( GTK_ORIENTATION_VERTICAL , FALSE , 0 ) ;
2011-02-24 04:14:30 +01:00
gtk_widget_show ( vbox2 ) ;
gtk_box_pack_start ( GTK_BOX ( vbox1 ) , vbox2 , TRUE , TRUE , 0 ) ;
label1 = bold_label ( _ ( " Networks " ) ) ;
gtk_box_pack_start ( GTK_BOX ( vbox2 ) , label1 , FALSE , FALSE , 0 ) ;
2026-02-05 01:59:15 -07:00
table4 = gtkutil_grid_new ( 2 , 2 , FALSE ) ;
2026-01-30 17:13:44 -07:00
gtk_widget_show ( table4 ) ;
gtk_box_pack_start ( GTK_BOX ( vbox2 ) , table4 , TRUE , TRUE , 0 ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( table4 ) , 8 ) ;
gtk_grid_set_row_spacing ( GTK_GRID ( table4 ) , 2 ) ;
gtk_grid_set_column_spacing ( GTK_GRID ( table4 ) , 3 ) ;
2011-02-24 04:14:30 +01:00
scrolledwindow3 = gtk_scrolled_window_new ( NULL , NULL ) ;
gtk_widget_show ( scrolledwindow3 ) ;
2026-01-30 16:04:50 -07:00
servlist_table_attach ( table4 , scrolledwindow3 , 0 , 1 , 0 , 1 ,
TRUE , TRUE ,
SERVLIST_ALIGN_FILL , SERVLIST_ALIGN_FILL ,
0 , 0 ) ;
2011-02-24 04:14:30 +01:00
gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( scrolledwindow3 ) ,
GTK_POLICY_NEVER , GTK_POLICY_ALWAYS ) ;
gtk_scrolled_window_set_shadow_type ( GTK_SCROLLED_WINDOW ( scrolledwindow3 ) ,
GTK_SHADOW_IN ) ;
store = gtk_list_store_new ( 3 , G_TYPE_STRING , G_TYPE_BOOLEAN , G_TYPE_INT ) ;
model = GTK_TREE_MODEL ( store ) ;
networks_tree = treeview_networks = gtk_tree_view_new_with_model ( model ) ;
g_object_unref ( model ) ;
gtk_widget_show ( treeview_networks ) ;
gtk_container_add ( GTK_CONTAINER ( scrolledwindow3 ) , treeview_networks ) ;
gtk_tree_view_set_headers_visible ( GTK_TREE_VIEW ( treeview_networks ) ,
FALSE ) ;
renderer = gtk_cell_renderer_text_new ( ) ;
g_signal_connect ( G_OBJECT ( renderer ) , " edited " ,
G_CALLBACK ( servlist_celledit_cb ) , model ) ;
gtk_tree_view_insert_column_with_attributes (
GTK_TREE_VIEW ( treeview_networks ) , - 1 ,
0 , renderer ,
" text " , 0 ,
" editable " , 1 ,
" weight " , 2 ,
NULL ) ;
2026-02-05 01:59:15 -07:00
hbox = gtkutil_box_new ( GTK_ORIENTATION_HORIZONTAL , FALSE , 0 ) ;
2026-01-30 16:04:50 -07:00
servlist_table_attach ( table4 , hbox , 0 , 2 , 1 , 2 ,
FALSE , FALSE ,
SERVLIST_ALIGN_FILL , SERVLIST_ALIGN_CENTER ,
0 , 0 ) ;
2011-02-24 04:14:30 +01:00
gtk_widget_show ( hbox ) ;
checkbutton_skip =
gtk_check_button_new_with_mnemonic ( _ ( " Skip network list on startup " ) ) ;
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( checkbutton_skip ) ,
2012-10-22 13:49:28 +02:00
prefs . hex_gui_slist_skip ) ;
2011-02-24 04:14:30 +01:00
gtk_container_add ( GTK_CONTAINER ( hbox ) , checkbutton_skip ) ;
g_signal_connect ( G_OBJECT ( checkbutton_skip ) , " toggled " ,
G_CALLBACK ( no_servlist ) , 0 ) ;
gtk_widget_show ( checkbutton_skip ) ;
checkbutton_fav =
gtk_check_button_new_with_mnemonic ( _ ( " Show favorites only " ) ) ;
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( checkbutton_fav ) ,
2012-10-22 13:49:28 +02:00
prefs . hex_gui_slist_fav ) ;
2011-02-24 04:14:30 +01:00
gtk_container_add ( GTK_CONTAINER ( hbox ) , checkbutton_fav ) ;
g_signal_connect ( G_OBJECT ( checkbutton_fav ) , " toggled " ,
G_CALLBACK ( fav_servlist ) , 0 ) ;
gtk_widget_show ( checkbutton_fav ) ;
2026-01-30 17:48:25 -07:00
vbuttonbox2 = gtk_button_box_new ( GTK_ORIENTATION_VERTICAL ) ;
2011-02-24 04:14:30 +01:00
gtk_box_set_spacing ( GTK_BOX ( vbuttonbox2 ) , 3 ) ;
gtk_button_box_set_layout ( GTK_BUTTON_BOX ( vbuttonbox2 ) , GTK_BUTTONBOX_START ) ;
gtk_widget_show ( vbuttonbox2 ) ;
2026-01-30 16:04:50 -07:00
servlist_table_attach ( table4 , vbuttonbox2 , 1 , 2 , 0 , 1 ,
FALSE , FALSE ,
SERVLIST_ALIGN_FILL , SERVLIST_ALIGN_FILL ,
0 , 0 ) ;
2011-02-24 04:14:30 +01:00
2026-01-30 15:27:01 -07:00
button_add = servlist_icon_button_new ( _ ( " _Add " ) , ICON_SERVLIST_ADD ) ;
2011-02-24 04:14:30 +01:00
g_signal_connect ( G_OBJECT ( button_add ) , " clicked " ,
G_CALLBACK ( servlist_addnet_cb ) , networks_tree ) ;
gtk_widget_show ( button_add ) ;
gtk_container_add ( GTK_CONTAINER ( vbuttonbox2 ) , button_add ) ;
2013-05-12 01:43:27 -04:00
gtk_widget_set_can_default ( button_add , TRUE ) ;
2011-02-24 04:14:30 +01:00
2026-01-30 15:27:01 -07:00
button_remove = servlist_icon_button_new ( _ ( " _Remove " ) , ICON_SERVLIST_REMOVE ) ;
2011-02-24 04:14:30 +01:00
g_signal_connect ( G_OBJECT ( button_remove ) , " clicked " ,
G_CALLBACK ( servlist_deletenet_cb ) , 0 ) ;
gtk_widget_show ( button_remove ) ;
gtk_container_add ( GTK_CONTAINER ( vbuttonbox2 ) , button_remove ) ;
2013-05-12 01:43:27 -04:00
gtk_widget_set_can_default ( button_remove , TRUE ) ;
2011-02-24 04:14:30 +01:00
button_edit = gtk_button_new_with_mnemonic ( _ ( " _Edit... " ) ) ;
g_signal_connect ( G_OBJECT ( button_edit ) , " clicked " ,
G_CALLBACK ( servlist_edit_cb ) , 0 ) ;
gtk_widget_show ( button_edit ) ;
gtk_container_add ( GTK_CONTAINER ( vbuttonbox2 ) , button_edit ) ;
2013-05-12 01:43:27 -04:00
gtk_widget_set_can_default ( button_edit , TRUE ) ;
2011-02-24 04:14:30 +01:00
button_sort = gtk_button_new_with_mnemonic ( _ ( " _Sort " ) ) ;
2014-01-18 04:08:32 -05:00
gtk_widget_set_tooltip_text ( button_sort , _ ( " Sorts the network list in alphabetical order. "
2017-08-19 20:48:50 +02:00
" Use Shift+Up and Shift+Down keys to move a row. " ) ) ;
2011-02-24 04:14:30 +01:00
g_signal_connect ( G_OBJECT ( button_sort ) , " clicked " ,
G_CALLBACK ( servlist_sort ) , 0 ) ;
gtk_widget_show ( button_sort ) ;
gtk_container_add ( GTK_CONTAINER ( vbuttonbox2 ) , button_sort ) ;
2013-05-12 01:43:27 -04:00
gtk_widget_set_can_default ( button_sort , TRUE ) ;
2011-02-24 04:14:30 +01:00
button_sort = gtk_button_new_with_mnemonic ( _ ( " _Favor " ) ) ;
2014-01-18 04:08:32 -05:00
gtk_widget_set_tooltip_text ( button_sort , _ ( " Mark or unmark this network as a favorite. " ) ) ;
2011-02-24 04:14:30 +01:00
g_signal_connect ( G_OBJECT ( button_sort ) , " clicked " ,
G_CALLBACK ( servlist_favor ) , 0 ) ;
gtk_widget_show ( button_sort ) ;
gtk_container_add ( GTK_CONTAINER ( vbuttonbox2 ) , button_sort ) ;
2013-05-12 01:43:27 -04:00
gtk_widget_set_can_default ( button_sort , TRUE ) ;
2011-02-24 04:14:30 +01:00
2026-01-30 17:48:25 -07:00
hseparator1 = gtk_separator_new ( GTK_ORIENTATION_HORIZONTAL ) ;
2011-02-24 04:14:30 +01:00
gtk_widget_show ( hseparator1 ) ;
gtk_box_pack_start ( GTK_BOX ( vbox1 ) , hseparator1 , FALSE , TRUE , 4 ) ;
2026-01-30 17:03:27 -07:00
hbuttonbox1 = gtk_button_box_new ( GTK_ORIENTATION_HORIZONTAL ) ;
gtk_button_box_set_layout ( GTK_BUTTON_BOX ( hbuttonbox1 ) , GTK_BUTTONBOX_SPREAD ) ;
2011-02-24 04:14:30 +01:00
gtk_widget_show ( hbuttonbox1 ) ;
gtk_box_pack_start ( GTK_BOX ( vbox1 ) , hbuttonbox1 , FALSE , TRUE , 0 ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( hbuttonbox1 ) , 8 ) ;
2026-01-30 15:27:01 -07:00
button_close = servlist_icon_button_new ( _ ( " _Close " ) , ICON_SERVLIST_CLOSE ) ;
2011-02-24 04:14:30 +01:00
gtk_widget_show ( button_close ) ;
g_signal_connect ( G_OBJECT ( button_close ) , " clicked " ,
G_CALLBACK ( servlist_close_cb ) , 0 ) ;
gtk_container_add ( GTK_CONTAINER ( hbuttonbox1 ) , button_close ) ;
2013-05-12 01:43:27 -04:00
gtk_widget_set_can_default ( button_close , TRUE ) ;
2011-02-24 04:14:30 +01:00
2026-01-30 15:27:01 -07:00
button_connect = gtkutil_button ( hbuttonbox1 , ICON_SERVLIST_CONNECT , NULL ,
2011-02-24 04:14:30 +01:00
servlist_connect_cb , NULL , _ ( " C_onnect " ) ) ;
2013-05-12 01:43:27 -04:00
gtk_widget_set_can_default ( button_connect , TRUE ) ;
2011-02-24 04:14:30 +01:00
2014-04-18 23:45:27 -04:00
g_signal_connect ( G_OBJECT ( entry_guser ) , " changed " ,
2014-04-18 23:50:27 -04:00
G_CALLBACK ( servlist_username_changed_cb ) , button_connect ) ;
2014-04-18 23:45:27 -04:00
g_signal_connect ( G_OBJECT ( entry_nick1 ) , " changed " ,
2014-04-18 23:50:27 -04:00
G_CALLBACK ( servlist_nick_changed_cb ) , button_connect ) ;
2014-04-18 23:45:27 -04:00
g_signal_connect ( G_OBJECT ( entry_nick2 ) , " changed " ,
2014-04-18 23:50:27 -04:00
G_CALLBACK ( servlist_nick_changed_cb ) , button_connect ) ;
2014-04-18 23:45:27 -04:00
2016-05-16 08:50:13 -04:00
/* Run validity checks now */
servlist_nick_changed_cb ( GTK_ENTRY ( entry_nick2 ) , button_connect ) ;
servlist_username_changed_cb ( GTK_ENTRY ( entry_guser ) , button_connect ) ;
2011-02-24 04:14:30 +01:00
gtk_label_set_mnemonic_widget ( GTK_LABEL ( label3 ) , entry1 ) ;
gtk_label_set_mnemonic_widget ( GTK_LABEL ( label6 ) , entry4 ) ;
2012-05-16 19:47:12 +02:00
/* gtk_label_set_mnemonic_widget (GTK_LABEL (label7), entry5); */
2011-02-24 04:14:30 +01:00
gtk_widget_grab_focus ( networks_tree ) ;
gtk_widget_grab_default ( button_close ) ;
return servlist ;
}
void
fe_serverlist_open ( session * sess )
{
if ( serverlist_win )
{
gtk_window_present ( GTK_WINDOW ( serverlist_win ) ) ;
return ;
}
servlist_sess = sess ;
serverlist_win = servlist_open_networks ( ) ;
gtkutil_set_icon ( serverlist_win ) ;
servlist_networks_populate ( networks_tree , network_list ) ;
2026-03-17 10:30:54 -06:00
g_signal_connect ( G_OBJECT ( serverlist_win ) , " delete-event " ,
2011-02-24 04:14:30 +01:00
G_CALLBACK ( servlist_delete_cb ) , 0 ) ;
2026-03-17 10:30:54 -06:00
g_signal_connect ( G_OBJECT ( serverlist_win ) , " configure-event " ,
2011-02-24 04:14:30 +01:00
G_CALLBACK ( servlist_configure_cb ) , 0 ) ;
g_signal_connect ( G_OBJECT ( gtk_tree_view_get_selection ( GTK_TREE_VIEW ( networks_tree ) ) ) ,
" changed " , G_CALLBACK ( servlist_network_row_cb ) , NULL ) ;
2026-03-17 10:30:54 -06:00
g_signal_connect ( G_OBJECT ( networks_tree ) , " key-press-event " ,
2011-02-24 04:14:30 +01:00
G_CALLBACK ( servlist_net_keypress_cb ) , networks_tree ) ;
gtk_widget_show ( serverlist_win ) ;
}