2011-02-24 04:14:30 +01:00
/* X-Chat
* Copyright ( C ) 2004 - 2007 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 <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <sys/stat.h>
# include <sys/types.h>
2026-01-16 17:52:57 -07:00
# include <gio/gio.h>
# include <glib/gstdio.h>
2026-01-05 23:12:38 -07:00
# include "../common/zoitechat.h"
2011-02-24 04:14:30 +01:00
# include "../common/cfgfiles.h"
# include "../common/fe.h"
# include "../common/text.h"
# include "../common/userlist.h"
# include "../common/util.h"
2026-01-05 23:12:38 -07:00
# include "../common/zoitechatc.h"
2016-01-25 21:01:56 -05:00
# include "../common/outbound.h"
2011-02-24 04:14:30 +01:00
# include "fe-gtk.h"
# include "gtkutil.h"
# include "maingui.h"
2026-01-11 12:02:58 -07:00
# include "chanview.h"
2011-02-24 04:14:30 +01:00
# include "palette.h"
# include "pixmaps.h"
# include "menu.h"
2012-07-21 14:26:19 +02:00
# include "plugin-tray.h"
2015-02-02 19:35:49 -05:00
# include "notifications/notification-backend.h"
2011-02-24 04:14:30 +01:00
# ifdef WIN32
# include "../common/fe.h"
# endif
# include "sexy-spell-entry.h"
GtkStyle * create_input_style ( GtkStyle * ) ;
# define LABEL_INDENT 12
2022-04-16 18:41:34 -05:00
static GtkWidget * setup_window = NULL ;
2011-02-24 04:14:30 +01:00
static int last_selected_page = 0 ;
static int last_selected_row = 0 ; /* sound row */
static gboolean color_change ;
2026-01-05 23:12:38 -07:00
static struct zoitechatprefs setup_prefs ;
2026-01-12 21:24:09 -07:00
static GSList * color_selector_widgets ;
2011-02-24 04:14:30 +01:00
static GtkWidget * cancel_button ;
static GtkWidget * font_dialog = NULL ;
2026-01-16 17:52:57 -07:00
void setup_apply_real ( int new_pix , int do_ulist , int do_layout , int do_identd ) ;
typedef struct
{
GtkWidget * combo ;
GtkWidget * apply_button ;
GtkWidget * status_label ;
} setup_theme_ui ;
2011-02-24 04:14:30 +01:00
enum
{
2026-01-16 17:52:57 -07:00
ST_END ,
ST_TOGGLE ,
ST_TOGGLR ,
ST_3OGGLE ,
ST_ENTRY ,
ST_EFONT ,
ST_EFILE ,
ST_EFOLDER ,
ST_MENU ,
ST_RADIO ,
ST_NUMBER ,
ST_HSCALE ,
ST_HEADER ,
ST_LABEL ,
ST_ALERTHEAD
2011-02-24 04:14:30 +01:00
} ;
typedef struct
{
2026-01-16 17:52:57 -07:00
int type ;
char * label ;
int offset ;
char * tooltip ;
char const * const * list ;
int extra ;
2011-02-24 04:14:30 +01:00
} setting ;
2012-10-18 23:26:06 +02:00
# ifdef WIN32
2012-10-18 22:57:55 +02:00
static const char * const langsmenu [ ] =
{
2026-01-16 17:52:57 -07:00
N_ ( " Afrikaans " ) ,
N_ ( " Albanian " ) ,
N_ ( " Amharic " ) ,
N_ ( " Asturian " ) ,
N_ ( " Azerbaijani " ) ,
N_ ( " Basque " ) ,
N_ ( " Belarusian " ) ,
N_ ( " Bulgarian " ) ,
N_ ( " Catalan " ) ,
N_ ( " Chinese (Simplified) " ) ,
N_ ( " Chinese (Traditional) " ) ,
N_ ( " Czech " ) ,
N_ ( " Danish " ) ,
N_ ( " Dutch " ) ,
N_ ( " English (British) " ) ,
N_ ( " English " ) ,
N_ ( " Estonian " ) ,
N_ ( " Finnish " ) ,
N_ ( " French " ) ,
N_ ( " Galician " ) ,
N_ ( " German " ) ,
N_ ( " Greek " ) ,
N_ ( " Gujarati " ) ,
N_ ( " Hindi " ) ,
N_ ( " Hungarian " ) ,
N_ ( " Indonesian " ) ,
N_ ( " Italian " ) ,
N_ ( " Japanese " ) ,
N_ ( " Kannada " ) ,
N_ ( " Kinyarwanda " ) ,
N_ ( " Korean " ) ,
N_ ( " Latvian " ) ,
N_ ( " Lithuanian " ) ,
N_ ( " Macedonian " ) ,
N_ ( " Malay " ) ,
N_ ( " Malayalam " ) ,
N_ ( " Norwegian (Bokmal) " ) ,
N_ ( " Norwegian (Nynorsk) " ) ,
N_ ( " Polish " ) ,
N_ ( " Portuguese " ) ,
N_ ( " Portuguese (Brazilian) " ) ,
N_ ( " Punjabi " ) ,
N_ ( " Russian " ) ,
N_ ( " Serbian " ) ,
N_ ( " Slovak " ) ,
N_ ( " Slovenian " ) ,
N_ ( " Spanish " ) ,
N_ ( " Swedish " ) ,
N_ ( " Thai " ) ,
N_ ( " Turkish " ) ,
N_ ( " Ukrainian " ) ,
N_ ( " Vietnamese " ) ,
N_ ( " Walloon " ) ,
NULL
2012-10-18 22:57:55 +02:00
} ;
2012-10-18 23:26:06 +02:00
# endif
2011-02-24 04:14:30 +01:00
2012-10-18 16:34:40 +02:00
static const setting appearance_settings [ ] =
2011-02-24 04:14:30 +01:00
{
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " General " ) , 0 , 0 , 0 } ,
2012-10-18 16:34:40 +02:00
# ifdef WIN32
2026-01-16 17:52:57 -07:00
{ ST_MENU , N_ ( " Language: " ) , P_OFFINTNL ( hex_gui_lang ) , 0 , langsmenu , 0 } ,
{ ST_EFONT , N_ ( " Main font: " ) , P_OFFSETNL ( hex_text_font_main ) , 0 , 0 , sizeof prefs . hex_text_font_main } ,
2012-02-15 22:56:52 +01:00
# else
2026-01-16 17:52:57 -07:00
{ ST_EFONT , N_ ( " Font: " ) , P_OFFSETNL ( hex_text_font ) , 0 , 0 , sizeof prefs . hex_text_font } ,
2012-02-15 22:56:52 +01:00
# endif
2012-10-22 07:24:52 +02:00
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Text Box " ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Colored nick names " ) , P_OFFINTNL ( hex_text_color_nicks ) , N_ ( " Give each person on IRC a different color " ) , 0 , 0 } ,
{ ST_TOGGLR , N_ ( " Indent nick names " ) , P_OFFINTNL ( hex_text_indent ) , N_ ( " Make nick names right-justified " ) , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Show marker line " ) , P_OFFINTNL ( hex_text_show_marker ) , N_ ( " Insert a red line after the last read text. " ) , 0 , 0 } ,
{ ST_EFILE , N_ ( " Background image: " ) , P_OFFSETNL ( hex_text_background ) , 0 , 0 , sizeof prefs . hex_text_background } ,
2012-11-04 00:31:09 +01:00
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Transparency Settings " ) , 0 , 0 , 0 } ,
{ ST_HSCALE , N_ ( " Window opacity: " ) , P_OFFINTNL ( hex_gui_transparency ) , 0 , 0 , 0 } ,
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Timestamps " ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Enable timestamps " ) , P_OFFINTNL ( hex_stamp_text ) , 0 , 0 , 1 } ,
{ ST_ENTRY , N_ ( " Timestamp format: " ) , P_OFFSETNL ( hex_stamp_text_format ) ,
2012-01-30 14:37:07 +01:00
# ifdef WIN32
2026-01-16 17:52:57 -07:00
N_ ( " See the strftime MSDN article for details. " ) , 0 , sizeof prefs . hex_stamp_text_format } ,
2012-01-30 14:37:07 +01:00
# else
2026-01-16 17:52:57 -07:00
N_ ( " See the strftime manpage for details. " ) , 0 , sizeof prefs . hex_stamp_text_format } ,
2012-01-30 14:37:07 +01:00
# endif
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Title Bar " ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Show channel modes " ) , P_OFFINTNL ( hex_gui_win_modes ) , 0 , 0 , 0 } ,
{ ST_TOGGLR , N_ ( " Show number of users " ) , P_OFFINTNL ( hex_gui_win_ucount ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Show nickname " ) , P_OFFINTNL ( hex_gui_win_nick ) , 0 , 0 , 0 } ,
2012-10-25 20:39:45 +02:00
2026-01-16 17:52:57 -07:00
{ ST_END , 0 , 0 , 0 , 0 , 0 }
2011-02-24 04:14:30 +01:00
} ;
static const char * const tabcompmenu [ ] =
{
2026-01-16 17:52:57 -07:00
N_ ( " A-Z " ) ,
N_ ( " Last-spoke order " ) ,
NULL
2011-02-24 04:14:30 +01:00
} ;
static const setting inputbox_settings [ ] =
{
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Input Box " ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Use the text box font and colors " ) , P_OFFINTNL ( hex_gui_input_style ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Render colors and attributes " ) , P_OFFINTNL ( hex_gui_input_attr ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Show nick box " ) , P_OFFINTNL ( hex_gui_input_nick ) , 0 , 0 , 1 } ,
{ ST_TOGGLE , N_ ( " Show user mode icon in nick box " ) , P_OFFINTNL ( hex_gui_input_icon ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Spell checking " ) , P_OFFINTNL ( hex_gui_input_spell ) , 0 , 0 , 1 } ,
{ ST_ENTRY , N_ ( " Dictionaries to use: " ) , P_OFFSETNL ( hex_text_spell_langs ) , 0 , 0 , sizeof prefs . hex_text_spell_langs } ,
2011-12-11 17:34:02 +01:00
# ifdef WIN32
2026-01-16 17:52:57 -07:00
{ ST_LABEL , N_ ( " Use language codes (as in \" %LOCALAPPDATA% \\ enchant \\ myspell \\ dicts \" ). \n Separate multiple entries with commas. " ) } ,
2011-12-11 17:34:02 +01:00
# else
2026-01-16 17:52:57 -07:00
{ ST_LABEL , N_ ( " Use language codes. Separate multiple entries with commas. " ) } ,
2011-02-24 04:14:30 +01:00
# endif
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Nick Completion " ) , 0 , 0 , 0 } ,
{ ST_ENTRY , N_ ( " Nick completion suffix: " ) , P_OFFSETNL ( hex_completion_suffix ) , 0 , 0 , sizeof prefs . hex_completion_suffix } ,
{ ST_MENU , N_ ( " Nick completion sorted: " ) , P_OFFINTNL ( hex_completion_sort ) , 0 , tabcompmenu , 0 } ,
{ ST_NUMBER , N_ ( " Nick completion amount: " ) , P_OFFINTNL ( hex_completion_amount ) , N_ ( " Threshold of nicks to start listing instead of completing " ) , ( const char * * ) N_ ( " nicks. " ) , 1000 } ,
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
{ ST_END , 0 , 0 , 0 , 0 , 0 }
2011-02-24 04:14:30 +01:00
} ;
2012-10-22 13:49:28 +02:00
static const char * const lagmenutext [ ] =
2011-02-24 04:14:30 +01:00
{
2026-01-16 17:52:57 -07:00
N_ ( " Off " ) ,
N_ ( " Graphical " ) ,
N_ ( " Text " ) ,
N_ ( " Both " ) ,
NULL
2012-10-22 13:49:28 +02:00
} ;
2011-02-24 04:14:30 +01:00
static const char * const ulmenutext [ ] =
{
2026-01-16 17:52:57 -07:00
N_ ( " A-Z, ops first " ) ,
N_ ( " A-Z " ) ,
N_ ( " Z-A, ops last " ) ,
N_ ( " Z-A " ) ,
N_ ( " Unsorted " ) ,
NULL
2011-02-24 04:14:30 +01:00
} ;
static const char * const cspos [ ] =
{
2026-01-16 17:52:57 -07:00
N_ ( " Left (upper) " ) ,
N_ ( " Left (lower) " ) ,
N_ ( " Right (upper) " ) ,
N_ ( " Right (lower) " ) ,
N_ ( " Top " ) ,
N_ ( " Bottom " ) ,
N_ ( " Hidden " ) ,
NULL
2011-02-24 04:14:30 +01:00
} ;
static const char * const ulpos [ ] =
{
2026-01-16 17:52:57 -07:00
N_ ( " Left (upper) " ) ,
N_ ( " Left (lower) " ) ,
N_ ( " Right (upper) " ) ,
N_ ( " Right (lower) " ) ,
NULL
2011-02-24 04:14:30 +01:00
} ;
static const setting userlist_settings [ ] =
{
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " User List " ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Show hostnames in user list " ) , P_OFFINTNL ( hex_gui_ulist_show_hosts ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Use the Text box font and colors " ) , P_OFFINTNL ( hex_gui_ulist_style ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Show icons for user modes " ) , P_OFFINTNL ( hex_gui_ulist_icons ) , N_ ( " Use graphical icons instead of text symbols in the user list. " ) , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Color nicknames in userlist " ) , P_OFFINTNL ( hex_gui_ulist_color ) , N_ ( " Will color nicknames the same as in chat. " ) , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Show user count in channels " ) , P_OFFINTNL ( hex_gui_ulist_count ) , 0 , 0 , 0 } ,
{ ST_MENU , N_ ( " User list sorted by: " ) , P_OFFINTNL ( hex_gui_ulist_sort ) , 0 , ulmenutext , 0 } ,
{ ST_MENU , N_ ( " Show user list at: " ) , P_OFFINTNL ( hex_gui_ulist_pos ) , 0 , ulpos , 1 } ,
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Away Tracking " ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Track the away status of users and mark them in a different color " ) , P_OFFINTNL ( hex_away_track ) , 0 , 0 , 1 } ,
{ ST_NUMBER , N_ ( " On channels smaller than: " ) , P_OFFINTNL ( hex_away_size_max ) , 0 , 0 , 10000 } ,
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Action Upon Double Click " ) , 0 , 0 , 0 } ,
{ ST_ENTRY , N_ ( " Execute command: " ) , P_OFFSETNL ( hex_gui_ulist_doubleclick ) , 0 , 0 , sizeof prefs . hex_gui_ulist_doubleclick } ,
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Extra Gadgets " ) , 0 , 0 , 0 } ,
{ ST_MENU , N_ ( " Lag meter: " ) , P_OFFINTNL ( hex_gui_lagometer ) , 0 , lagmenutext , 0 } ,
{ ST_MENU , N_ ( " Throttle meter: " ) , P_OFFINTNL ( hex_gui_throttlemeter ) , 0 , lagmenutext , 0 } ,
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
{ ST_END , 0 , 0 , 0 , 0 , 0 }
2011-02-24 04:14:30 +01:00
} ;
static const char * const tabwin [ ] =
{
2026-01-16 17:52:57 -07:00
N_ ( " Windows " ) ,
N_ ( " Tabs " ) ,
NULL
2011-02-24 04:14:30 +01:00
} ;
static const char * const focusnewtabsmenu [ ] =
{
2026-01-16 17:52:57 -07:00
N_ ( " Never " ) ,
N_ ( " Always " ) ,
N_ ( " Only requested tabs " ) ,
NULL
2011-02-24 04:14:30 +01:00
} ;
2013-03-09 17:09:38 -05:00
static const char * const noticeposmenu [ ] =
{
2026-01-16 17:52:57 -07:00
N_ ( " Automatic " ) ,
N_ ( " In an extra tab " ) ,
N_ ( " In the front tab " ) ,
NULL
2013-03-09 17:09:38 -05:00
} ;
2011-02-24 04:14:30 +01:00
static const char * const swtype [ ] =
{
2026-01-16 17:52:57 -07:00
N_ ( " Tabs " ) , /* 0 tabs */
" " , /* 1 reserved */
N_ ( " Tree " ) , /* 2 tree */
NULL
2011-02-24 04:14:30 +01:00
} ;
static const setting tabs_settings [ ] =
{
2026-01-16 17:52:57 -07:00
/*{ST_HEADER, N_("Channel Switcher"),0,0,0},*/
{ ST_RADIO , N_ ( " Switcher type: " ) , P_OFFINTNL ( hex_gui_tab_layout ) , 0 , swtype , 0 } ,
{ ST_TOGGLE , N_ ( " Open an extra tab for server messages " ) , P_OFFINTNL ( hex_gui_tab_server ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Open a new tab when you receive a private message " ) , P_OFFINTNL ( hex_gui_autoopen_dialog ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Sort tabs in alphabetical order " ) , P_OFFINTNL ( hex_gui_tab_sort ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Show icons in the channel tree " ) , P_OFFINTNL ( hex_gui_tab_icons ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Show dotted lines in the channel tree " ) , P_OFFINTNL ( hex_gui_tab_dots ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Scroll mouse-wheel to change tabs " ) , P_OFFINTNL ( hex_gui_tab_scrollchans ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Middle click to close tab " ) , P_OFFINTNL ( hex_gui_tab_middleclose ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Smaller text " ) , P_OFFINTNL ( hex_gui_tab_small ) , 0 , 0 , 0 } ,
{ ST_MENU , N_ ( " Focus new tabs: " ) , P_OFFINTNL ( hex_gui_tab_newtofront ) , 0 , focusnewtabsmenu , 0 } ,
{ ST_MENU , N_ ( " Placement of notices: " ) , P_OFFINTNL ( hex_irc_notice_pos ) , 0 , noticeposmenu , 0 } ,
{ ST_MENU , N_ ( " Show channel switcher at: " ) , P_OFFINTNL ( hex_gui_tab_pos ) , 0 , cspos , 1 } ,
{ ST_NUMBER , N_ ( " Shorten tab labels to: " ) , P_OFFINTNL ( hex_gui_tab_trunc ) , 0 , ( const char * * ) N_ ( " letters. " ) , 99 } ,
{ ST_HEADER , N_ ( " Tabs or Windows " ) , 0 , 0 , 0 } ,
{ ST_MENU , N_ ( " Open channels in: " ) , P_OFFINTNL ( hex_gui_tab_chans ) , 0 , tabwin , 0 } ,
{ ST_MENU , N_ ( " Open dialogs in: " ) , P_OFFINTNL ( hex_gui_tab_dialogs ) , 0 , tabwin , 0 } ,
{ ST_MENU , N_ ( " Open utilities in: " ) , P_OFFINTNL ( hex_gui_tab_utils ) , N_ ( " Open DCC, Ignore, Notify etc, in tabs or windows? " ) , tabwin , 0 } ,
{ ST_END , 0 , 0 , 0 , 0 , 0 }
2011-02-24 04:14:30 +01:00
} ;
2012-09-01 21:38:00 +02:00
static const setting color_settings [ ] =
{
2026-01-17 23:09:38 -07:00
{ ST_TOGGLE , N_ ( " Messages " ) , P_OFFINTNL ( hex_text_stripcolor_msg ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Scrollback " ) , P_OFFINTNL ( hex_text_stripcolor_replay ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Topic " ) , P_OFFINTNL ( hex_text_stripcolor_topic ) , 0 , 0 , 0 } ,
2012-09-01 21:38:00 +02:00
2026-01-17 23:09:38 -07:00
{ ST_END , 0 , 0 , 0 , 0 , 0 }
} ;
static const char * const dark_mode_modes [ ] =
{
N_ ( " Auto (system) " ) ,
N_ ( " Dark " ) ,
N_ ( " Light " ) ,
NULL
2012-09-01 21:38:00 +02:00
} ;
2026-01-11 12:02:58 -07:00
static const setting dark_mode_setting =
{
2026-01-17 23:09:38 -07:00
ST_MENU ,
N_ ( " Dark mode: " ) ,
P_OFFINTNL ( hex_gui_dark_mode ) ,
N_ ( " Choose how ZoiteChat selects its color palette for the chat buffer, channel list, and user list. \n "
" This includes message colors, selection colors, and interface highlights. \n " ) ,
dark_mode_modes ,
0
2026-01-11 12:02:58 -07:00
} ;
2011-02-24 04:14:30 +01:00
static const char * const dccaccept [ ] =
{
2026-01-16 17:52:57 -07:00
N_ ( " Ask for confirmation " ) ,
N_ ( " Ask for download folder " ) ,
N_ ( " Save without interaction " ) ,
NULL
2011-02-24 04:14:30 +01:00
} ;
static const setting filexfer_settings [ ] =
{
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Files and Directories " ) , 0 , 0 , 0 } ,
{ ST_MENU , N_ ( " Auto accept file offers: " ) , P_OFFINTNL ( hex_dcc_auto_recv ) , 0 , dccaccept , 0 } ,
{ ST_EFOLDER , N_ ( " Download files to: " ) , P_OFFSETNL ( hex_dcc_dir ) , 0 , 0 , sizeof prefs . hex_dcc_dir } ,
{ ST_EFOLDER , N_ ( " Move completed files to: " ) , P_OFFSETNL ( hex_dcc_completed_dir ) , 0 , 0 , sizeof prefs . hex_dcc_completed_dir } ,
{ ST_TOGGLE , N_ ( " Save nick name in filenames " ) , P_OFFINTNL ( hex_dcc_save_nick ) , 0 , 0 , 0 } ,
{ ST_HEADER , N_ ( " Auto Open DCC Windows " ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Send window " ) , P_OFFINTNL ( hex_gui_autoopen_send ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Receive window " ) , P_OFFINTNL ( hex_gui_autoopen_recv ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Chat window " ) , P_OFFINTNL ( hex_gui_autoopen_chat ) , 0 , 0 , 0 } ,
{ ST_HEADER , N_ ( " Maximum File Transfer Speeds (Byte per Second) " ) , 0 , 0 , 0 } ,
{ ST_NUMBER , N_ ( " One upload: " ) , P_OFFINTNL ( hex_dcc_max_send_cps ) ,
N_ ( " Maximum speed for one transfer " ) , 0 , 10000000 } ,
{ ST_NUMBER , N_ ( " One download: " ) , P_OFFINTNL ( hex_dcc_max_get_cps ) ,
N_ ( " Maximum speed for one transfer " ) , 0 , 10000000 } ,
{ ST_NUMBER , N_ ( " All uploads combined: " ) , P_OFFINTNL ( hex_dcc_global_max_send_cps ) ,
N_ ( " Maximum speed for all files " ) , 0 , 10000000 } ,
{ ST_NUMBER , N_ ( " All downloads combined: " ) , P_OFFINTNL ( hex_dcc_global_max_get_cps ) ,
N_ ( " Maximum speed for all files " ) , 0 , 10000000 } ,
{ ST_END , 0 , 0 , 0 , 0 , 0 }
2011-02-24 04:14:30 +01:00
} ;
static const int balloonlist [ 3 ] =
{
2026-01-16 17:52:57 -07:00
P_OFFINTNL ( hex_input_balloon_chans ) , P_OFFINTNL ( hex_input_balloon_priv ) , P_OFFINTNL ( hex_input_balloon_hilight )
2011-02-24 04:14:30 +01:00
} ;
static const int trayblinklist [ 3 ] =
{
2026-01-16 17:52:57 -07:00
P_OFFINTNL ( hex_input_tray_chans ) , P_OFFINTNL ( hex_input_tray_priv ) , P_OFFINTNL ( hex_input_tray_hilight )
2011-02-24 04:14:30 +01:00
} ;
static const int taskbarlist [ 3 ] =
{
2026-01-16 17:52:57 -07:00
P_OFFINTNL ( hex_input_flash_chans ) , P_OFFINTNL ( hex_input_flash_priv ) , P_OFFINTNL ( hex_input_flash_hilight )
2011-02-24 04:14:30 +01:00
} ;
static const int beeplist [ 3 ] =
{
2026-01-16 17:52:57 -07:00
P_OFFINTNL ( hex_input_beep_chans ) , P_OFFINTNL ( hex_input_beep_priv ) , P_OFFINTNL ( hex_input_beep_hilight )
2011-02-24 04:14:30 +01:00
} ;
static const setting alert_settings [ ] =
{
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Alerts " ) , 0 , 0 , 0 } ,
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
{ ST_ALERTHEAD } ,
2015-02-02 19:35:49 -05:00
2026-01-16 17:52:57 -07:00
{ ST_3OGGLE , N_ ( " Show notifications on: " ) , 0 , 0 , ( void * ) balloonlist , 0 } ,
{ ST_3OGGLE , N_ ( " Blink tray icon on: " ) , 0 , 0 , ( void * ) trayblinklist , 0 } ,
{ ST_3OGGLE , N_ ( " Blink task bar on: " ) , 0 , 0 , ( void * ) taskbarlist , 0 } ,
2015-02-02 19:35:49 -05:00
# ifdef WIN32
2026-01-16 17:52:57 -07:00
{ ST_3OGGLE , N_ ( " Make a beep sound on: " ) , 0 , N_ ( " Play the \" Instant Message Notification \" system sound upon the selected events " ) , ( void * ) beeplist , 0 } ,
2015-02-02 19:35:49 -05:00
# else
# ifdef USE_LIBCANBERRA
2026-01-16 17:52:57 -07:00
{ ST_3OGGLE , N_ ( " Make a beep sound on: " ) , 0 , N_ ( " Play \" message-new-instant \" from the freedesktop.org sound theme upon the selected events " ) , ( void * ) beeplist , 0 } ,
2015-02-02 19:35:49 -05:00
# else
2026-01-16 17:52:57 -07:00
{ ST_3OGGLE , N_ ( " Make a beep sound on: " ) , 0 , N_ ( " Play a GTK beep upon the selected events " ) , ( void * ) beeplist , 0 } ,
2015-02-02 19:35:49 -05:00
# endif
2011-02-24 04:14:30 +01:00
# endif
2015-02-02 19:35:49 -05:00
2026-01-16 17:52:57 -07:00
{ ST_TOGGLE , N_ ( " Omit alerts when marked as being away " ) , P_OFFINTNL ( hex_away_omit_alerts ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Omit alerts while the window is focused " ) , P_OFFINTNL ( hex_gui_focus_omitalerts ) , 0 , 0 , 0 } ,
2015-02-02 19:35:49 -05:00
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Tray Behavior " ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Enable system tray icon " ) , P_OFFINTNL ( hex_gui_tray ) , 0 , 0 , 4 } ,
{ ST_TOGGLE , N_ ( " Minimize to tray " ) , P_OFFINTNL ( hex_gui_tray_minimize ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Close to tray " ) , P_OFFINTNL ( hex_gui_tray_close ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Automatically mark away/back " ) , P_OFFINTNL ( hex_gui_tray_away ) , N_ ( " Automatically change status when hiding to tray. " ) , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Only show notifications when hidden or iconified " ) , P_OFFINTNL ( hex_gui_tray_quiet ) , 0 , 0 , 0 } ,
2015-02-02 19:35:49 -05:00
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Highlighted Messages " ) , 0 , 0 , 0 } ,
{ ST_LABEL , N_ ( " Highlighted messages are ones where your nickname is mentioned, but also: " ) , 0 , 0 , 0 , 1 } ,
2015-02-02 19:35:49 -05:00
2026-01-16 17:52:57 -07:00
{ ST_ENTRY , N_ ( " Extra words to highlight: " ) , P_OFFSETNL ( hex_irc_extra_hilight ) , 0 , 0 , sizeof prefs . hex_irc_extra_hilight } ,
{ ST_ENTRY , N_ ( " Nick names not to highlight: " ) , P_OFFSETNL ( hex_irc_no_hilight ) , 0 , 0 , sizeof prefs . hex_irc_no_hilight } ,
{ ST_ENTRY , N_ ( " Nick names to always highlight: " ) , P_OFFSETNL ( hex_irc_nick_hilight ) , 0 , 0 , sizeof prefs . hex_irc_nick_hilight } ,
{ ST_LABEL , N_ ( " Separate multiple words with commas. \n Wildcards are accepted. " ) } ,
2015-02-02 19:35:49 -05:00
2026-01-16 17:52:57 -07:00
{ ST_END , 0 , 0 , 0 , 0 , 0 }
2015-02-02 19:35:49 -05:00
} ;
static const setting alert_settings_nonotifications [ ] =
{
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Alerts " ) , 0 , 0 , 0 } ,
2015-02-02 19:35:49 -05:00
2026-01-16 17:52:57 -07:00
{ ST_ALERTHEAD } ,
{ ST_3OGGLE , N_ ( " Blink tray icon on: " ) , 0 , 0 , ( void * ) trayblinklist , 0 } ,
2014-05-11 04:43:01 -04:00
# ifdef HAVE_GTK_MAC
2026-01-16 17:52:57 -07:00
{ ST_3OGGLE , N_ ( " Bounce dock icon on: " ) , 0 , 0 , ( void * ) taskbarlist , 0 } ,
2014-05-11 04:43:01 -04:00
# else
# ifndef __APPLE__
2026-01-16 17:52:57 -07:00
{ ST_3OGGLE , N_ ( " Blink task bar on: " ) , 0 , 0 , ( void * ) taskbarlist , 0 } ,
2014-05-11 04:43:01 -04:00
# endif
# endif
2013-04-28 05:31:45 +02:00
# ifdef WIN32
2026-01-16 17:52:57 -07:00
{ ST_3OGGLE , N_ ( " Make a beep sound on: " ) , 0 , N_ ( " Play the \" Instant Message Notification \" system sound upon the selected events " ) , ( void * ) beeplist , 0 } ,
2013-04-28 05:31:45 +02:00
# else
2013-09-14 12:46:38 -04:00
# ifdef USE_LIBCANBERRA
2026-01-16 17:52:57 -07:00
{ ST_3OGGLE , N_ ( " Make a beep sound on: " ) , 0 , N_ ( " Play \" message-new-instant \" from the freedesktop.org sound theme upon the selected events " ) , ( void * ) beeplist , 0 } ,
2013-09-14 12:46:38 -04:00
# else
2026-01-16 17:52:57 -07:00
{ ST_3OGGLE , N_ ( " Make a beep sound on: " ) , 0 , N_ ( " Play a GTK beep upon the selected events " ) , ( void * ) beeplist , 0 } ,
2013-09-14 12:46:38 -04:00
# endif
2013-04-28 05:31:45 +02:00
# endif
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
{ ST_TOGGLE , N_ ( " Omit alerts when marked as being away " ) , P_OFFINTNL ( hex_away_omit_alerts ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Omit alerts while the window is focused " ) , P_OFFINTNL ( hex_gui_focus_omitalerts ) , 0 , 0 , 0 } ,
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Tray Behavior " ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Enable system tray icon " ) , P_OFFINTNL ( hex_gui_tray ) , 0 , 0 , 4 } ,
{ ST_TOGGLE , N_ ( " Minimize to tray " ) , P_OFFINTNL ( hex_gui_tray_minimize ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Close to tray " ) , P_OFFINTNL ( hex_gui_tray_close ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Automatically mark away/back " ) , P_OFFINTNL ( hex_gui_tray_away ) , N_ ( " Automatically change status when hiding to tray. " ) , 0 , 0 } ,
2012-11-10 19:29:12 +01:00
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Highlighted Messages " ) , 0 , 0 , 0 } ,
{ ST_LABEL , N_ ( " Highlighted messages are ones where your nickname is mentioned, but also: " ) , 0 , 0 , 0 , 1 } ,
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
{ ST_ENTRY , N_ ( " Extra words to highlight: " ) , P_OFFSETNL ( hex_irc_extra_hilight ) , 0 , 0 , sizeof prefs . hex_irc_extra_hilight } ,
{ ST_ENTRY , N_ ( " Nick names not to highlight: " ) , P_OFFSETNL ( hex_irc_no_hilight ) , 0 , 0 , sizeof prefs . hex_irc_no_hilight } ,
{ ST_ENTRY , N_ ( " Nick names to always highlight: " ) , P_OFFSETNL ( hex_irc_nick_hilight ) , 0 , 0 , sizeof prefs . hex_irc_nick_hilight } ,
{ ST_LABEL , N_ ( " Separate multiple words with commas. \n Wildcards are accepted. " ) } ,
2012-07-20 17:15:20 +02:00
2026-01-16 17:52:57 -07:00
{ ST_END , 0 , 0 , 0 , 0 , 0 }
2011-02-24 04:14:30 +01:00
} ;
2013-03-25 02:41:13 -04:00
static const setting alert_settings_unity [ ] =
{
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Alerts " ) , 0 , 0 , 0 } ,
2013-03-25 02:41:13 -04:00
2026-01-16 17:52:57 -07:00
{ ST_ALERTHEAD } ,
{ ST_3OGGLE , N_ ( " Show notifications on: " ) , 0 , 0 , ( void * ) balloonlist , 0 } ,
{ ST_3OGGLE , N_ ( " Blink task bar on: " ) , 0 , 0 , ( void * ) taskbarlist , 0 } ,
{ ST_3OGGLE , N_ ( " Make a beep sound on: " ) , 0 , 0 , ( void * ) beeplist , 0 } ,
2013-03-25 02:41:13 -04:00
2026-01-16 17:52:57 -07:00
{ ST_TOGGLE , N_ ( " Omit alerts when marked as being away " ) , P_OFFINTNL ( hex_away_omit_alerts ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Omit alerts while the window is focused " ) , P_OFFINTNL ( hex_gui_focus_omitalerts ) , 0 , 0 , 0 } ,
2013-03-25 02:41:13 -04:00
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Highlighted Messages " ) , 0 , 0 , 0 } ,
{ ST_LABEL , N_ ( " Highlighted messages are ones where your nickname is mentioned, but also: " ) , 0 , 0 , 0 , 1 } ,
2013-03-25 02:41:13 -04:00
2026-01-16 17:52:57 -07:00
{ ST_ENTRY , N_ ( " Extra words to highlight: " ) , P_OFFSETNL ( hex_irc_extra_hilight ) , 0 , 0 , sizeof prefs . hex_irc_extra_hilight } ,
{ ST_ENTRY , N_ ( " Nick names not to highlight: " ) , P_OFFSETNL ( hex_irc_no_hilight ) , 0 , 0 , sizeof prefs . hex_irc_no_hilight } ,
{ ST_ENTRY , N_ ( " Nick names to always highlight: " ) , P_OFFSETNL ( hex_irc_nick_hilight ) , 0 , 0 , sizeof prefs . hex_irc_nick_hilight } ,
{ ST_LABEL , N_ ( " Separate multiple words with commas. \n Wildcards are accepted. " ) } ,
2013-03-25 02:41:13 -04:00
2026-01-16 17:52:57 -07:00
{ ST_END , 0 , 0 , 0 , 0 , 0 }
2013-03-25 02:41:13 -04:00
} ;
2015-02-02 19:35:49 -05:00
static const setting alert_settings_unityandnonotifications [ ] =
{
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Alerts " ) , 0 , 0 , 0 } ,
2015-02-02 19:35:49 -05:00
2026-01-16 17:52:57 -07:00
{ ST_ALERTHEAD } ,
{ ST_3OGGLE , N_ ( " Blink task bar on: " ) , 0 , 0 , ( void * ) taskbarlist , 0 } ,
{ ST_3OGGLE , N_ ( " Make a beep sound on: " ) , 0 , 0 , ( void * ) beeplist , 0 } ,
2015-02-02 19:35:49 -05:00
2026-01-16 17:52:57 -07:00
{ ST_TOGGLE , N_ ( " Omit alerts when marked as being away " ) , P_OFFINTNL ( hex_away_omit_alerts ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Omit alerts while the window is focused " ) , P_OFFINTNL ( hex_gui_focus_omitalerts ) , 0 , 0 , 0 } ,
2015-02-02 19:35:49 -05:00
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Highlighted Messages " ) , 0 , 0 , 0 } ,
{ ST_LABEL , N_ ( " Highlighted messages are ones where your nickname is mentioned, but also: " ) , 0 , 0 , 0 , 1 } ,
2015-02-02 19:35:49 -05:00
2026-01-16 17:52:57 -07:00
{ ST_ENTRY , N_ ( " Extra words to highlight: " ) , P_OFFSETNL ( hex_irc_extra_hilight ) , 0 , 0 , sizeof prefs . hex_irc_extra_hilight } ,
{ ST_ENTRY , N_ ( " Nick names not to highlight: " ) , P_OFFSETNL ( hex_irc_no_hilight ) , 0 , 0 , sizeof prefs . hex_irc_no_hilight } ,
{ ST_ENTRY , N_ ( " Nick names to always highlight: " ) , P_OFFSETNL ( hex_irc_nick_hilight ) , 0 , 0 , sizeof prefs . hex_irc_nick_hilight } ,
{ ST_LABEL , N_ ( " Separate multiple words with commas. \n Wildcards are accepted. " ) } ,
2015-02-02 19:35:49 -05:00
2026-01-16 17:52:57 -07:00
{ ST_END , 0 , 0 , 0 , 0 , 0 }
2015-02-02 19:35:49 -05:00
} ;
2011-02-24 04:14:30 +01:00
static const setting general_settings [ ] =
{
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Default Messages " ) , 0 , 0 , 0 } ,
{ ST_ENTRY , N_ ( " Quit: " ) , P_OFFSETNL ( hex_irc_quit_reason ) , 0 , 0 , sizeof prefs . hex_irc_quit_reason } ,
{ ST_ENTRY , N_ ( " Leave channel: " ) , P_OFFSETNL ( hex_irc_part_reason ) , 0 , 0 , sizeof prefs . hex_irc_part_reason } ,
{ ST_ENTRY , N_ ( " Away: " ) , P_OFFSETNL ( hex_away_reason ) , 0 , 0 , sizeof prefs . hex_away_reason } ,
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Away " ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Show away once " ) , P_OFFINTNL ( hex_away_show_once ) , N_ ( " Show identical away messages only once. " ) , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Automatically unmark away " ) , P_OFFINTNL ( hex_away_auto_unmark ) , N_ ( " Unmark yourself as away before sending messages. " ) , 0 , 0 } ,
2012-07-20 17:15:20 +02:00
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Miscellaneous " ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Display MODEs in raw form " ) , P_OFFINTNL ( hex_irc_raw_modes ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " WHOIS on notify " ) , P_OFFINTNL ( hex_notify_whois_online ) , N_ ( " Sends a /WHOIS when a user comes online in your notify list. " ) , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Hide join and part messages " ) , P_OFFINTNL ( hex_irc_conf_mode ) , N_ ( " Hide channel join/part messages by default. " ) , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Hide nick change messages " ) , P_OFFINTNL ( hex_irc_hide_nickchange ) , 0 , 0 , 0 } ,
2013-05-19 20:43:21 +02:00
2026-01-16 17:52:57 -07:00
{ ST_END , 0 , 0 , 0 , 0 , 0 }
2011-02-24 04:14:30 +01:00
} ;
2013-06-09 16:51:57 -03:00
static const char * const bantypemenu [ ] =
{
2026-01-16 17:52:57 -07:00
N_ ( " *!*@*.host " ) ,
N_ ( " *!*@domain " ) ,
N_ ( " *!*user@*.host " ) ,
N_ ( " *!*user@domain " ) ,
NULL
2013-06-09 16:51:57 -03:00
} ;
2011-02-24 04:14:30 +01:00
static const setting advanced_settings [ ] =
2011-11-25 10:10:11 +01:00
{
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Auto Copy Behavior " ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Automatically copy selected text " ) , P_OFFINTNL ( hex_text_autocopy_text ) ,
N_ ( " Copy selected text to clipboard when left mouse button is released. "
" Otherwise, Ctrl+Shift+C will copy the "
" selected text to the clipboard. " ) , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Automatically include timestamps " ) , P_OFFINTNL ( hex_text_autocopy_stamp ) ,
N_ ( " Automatically include timestamps in copied lines of text. Otherwise, "
" include timestamps if the Shift key is held down while selecting. " ) , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Automatically include color information " ) , P_OFFINTNL ( hex_text_autocopy_color ) ,
N_ ( " Automatically include color information in copied lines of text. "
" Otherwise, include color information if the Ctrl key is held down "
" while selecting. " ) , 0 , 0 } ,
{ ST_HEADER , N_ ( " Miscellaneous " ) , 0 , 0 , 0 } ,
{ ST_ENTRY , N_ ( " Real name: " ) , P_OFFSETNL ( hex_irc_real_name ) , 0 , 0 , sizeof prefs . hex_irc_real_name } ,
2013-05-19 20:43:21 +02:00
# ifdef WIN32
2026-01-16 17:52:57 -07:00
{ ST_ENTRY , N_ ( " Alternative fonts: " ) , P_OFFSETNL ( hex_text_font_alternative ) , N_ ( " Separate multiple entries with commas without spaces before or after. " ) , 0 , sizeof prefs . hex_text_font_alternative } ,
2013-05-19 20:43:21 +02:00
# endif
2026-01-16 17:52:57 -07:00
{ ST_TOGGLE , N_ ( " Display lists in compact mode " ) , P_OFFINTNL ( hex_gui_compact ) , N_ ( " Use less spacing between user list/channel tree rows. " ) , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Use server time if supported " ) , P_OFFINTNL ( hex_irc_cap_server_time ) , N_ ( " Display timestamps obtained from server if it supports the time-server extension. " ) , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Automatically reconnect to servers on disconnect " ) , P_OFFINTNL ( hex_net_auto_reconnect ) , 0 , 0 , 1 } ,
{ ST_NUMBER , N_ ( " Auto reconnect delay: " ) , P_OFFINTNL ( hex_net_reconnect_delay ) , 0 , 0 , 9999 } ,
{ ST_NUMBER , N_ ( " Auto join delay: " ) , P_OFFINTNL ( hex_irc_join_delay ) , 0 , 0 , 9999 } ,
{ ST_MENU , N_ ( " Ban Type: " ) , P_OFFINTNL ( hex_irc_ban_type ) , N_ ( " Attempt to use this banmask when banning or quieting. (requires irc_who_join) " ) , bantypemenu , 0 } ,
{ ST_END , 0 , 0 , 0 , 0 , 0 }
2011-11-25 10:10:11 +01:00
} ;
2011-02-24 04:14:30 +01:00
static const setting logging_settings [ ] =
{
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Logging " ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Display scrollback from previous session " ) , P_OFFINTNL ( hex_text_replay ) , 0 , 0 , 0 } ,
{ ST_NUMBER , N_ ( " Scrollback lines: " ) , P_OFFINTNL ( hex_text_max_lines ) , 0 , 0 , 100000 } ,
{ ST_TOGGLE , N_ ( " Enable logging of conversations to disk " ) , P_OFFINTNL ( hex_irc_logging ) , 0 , 0 , 0 } ,
{ ST_ENTRY , N_ ( " Log filename: " ) , P_OFFSETNL ( hex_irc_logmask ) , 0 , 0 , sizeof prefs . hex_irc_logmask } ,
{ ST_LABEL , N_ ( " %s=Server %c=Channel %n=Network. " ) } ,
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Timestamps " ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Insert timestamps in logs " ) , P_OFFINTNL ( hex_stamp_log ) , 0 , 0 , 1 } ,
{ ST_ENTRY , N_ ( " Log timestamp format: " ) , P_OFFSETNL ( hex_stamp_log_format ) , 0 , 0 , sizeof prefs . hex_stamp_log_format } ,
2012-02-16 17:21:15 +01:00
# ifdef WIN32
2026-01-16 17:52:57 -07:00
{ ST_LABEL , N_ ( " See the strftime MSDN article for details. " ) } ,
2012-02-16 17:21:15 +01:00
# else
2026-01-16 17:52:57 -07:00
{ ST_LABEL , N_ ( " See the strftime manpage for details. " ) } ,
2012-02-16 17:21:15 +01:00
# endif
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " URLs " ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Enable logging of URLs to disk " ) , P_OFFINTNL ( hex_url_logging ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Enable URL grabber " ) , P_OFFINTNL ( hex_url_grabber ) , 0 , 0 , 1 } ,
{ ST_NUMBER , N_ ( " Maximum number of URLs to grab: " ) , P_OFFINTNL ( hex_url_grabber_limit ) , 0 , 0 , 9999 } ,
2012-09-29 01:54:11 +02:00
2026-01-16 17:52:57 -07:00
{ ST_END , 0 , 0 , 0 , 0 , 0 }
2011-02-24 04:14:30 +01:00
} ;
static const char * const proxytypes [ ] =
{
2026-01-16 17:52:57 -07:00
N_ ( " (Disabled) " ) ,
N_ ( " Wingate " ) ,
N_ ( " SOCKS4 " ) ,
N_ ( " SOCKS5 " ) ,
N_ ( " HTTP " ) ,
N_ ( " Auto " ) ,
NULL
2011-02-24 04:14:30 +01:00
} ;
static const char * const proxyuse [ ] =
{
2026-01-16 17:52:57 -07:00
N_ ( " All connections " ) ,
N_ ( " IRC server only " ) ,
N_ ( " DCC only " ) ,
NULL
2011-02-24 04:14:30 +01:00
} ;
static const setting network_settings [ ] =
{
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Your Address " ) , 0 , 0 , 0 , 0 } ,
{ ST_ENTRY , N_ ( " Bind to: " ) , P_OFFSETNL ( hex_net_bind_host ) , 0 , 0 , sizeof prefs . hex_net_bind_host } ,
{ ST_LABEL , N_ ( " Only useful for computers with multiple addresses. " ) } ,
{ ST_HEADER , N_ ( " File Transfers " ) , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Get my address from the IRC server " ) , P_OFFINTNL ( hex_dcc_ip_from_server ) ,
N_ ( " Asks the IRC server for your real address. Use this if you have a 192.168.*.* address! " ) , 0 , 0 } ,
{ ST_ENTRY , N_ ( " DCC IP address: " ) , P_OFFSETNL ( hex_dcc_ip ) ,
N_ ( " Claim you are at this address when offering files. " ) , 0 , sizeof prefs . hex_dcc_ip } ,
{ ST_NUMBER , N_ ( " First DCC listen port: " ) , P_OFFINTNL ( hex_dcc_port_first ) , 0 , 0 , 65535 } ,
{ ST_NUMBER , N_ ( " Last DCC listen port: " ) , P_OFFINTNL ( hex_dcc_port_last ) , 0 ,
( const char * * ) N_ ( " !Leave ports at zero for full range. " ) , 65535 } ,
{ ST_HEADER , N_ ( " Proxy Server " ) , 0 , 0 , 0 , 0 } ,
{ ST_ENTRY , N_ ( " Hostname: " ) , P_OFFSETNL ( hex_net_proxy_host ) , 0 , 0 , sizeof prefs . hex_net_proxy_host } ,
{ ST_NUMBER , N_ ( " Port: " ) , P_OFFINTNL ( hex_net_proxy_port ) , 0 , 0 , 65535 } ,
{ ST_MENU , N_ ( " Type: " ) , P_OFFINTNL ( hex_net_proxy_type ) , 0 , proxytypes , 0 } ,
{ ST_MENU , N_ ( " Use proxy for: " ) , P_OFFINTNL ( hex_net_proxy_use ) , 0 , proxyuse , 0 } ,
{ ST_HEADER , N_ ( " Proxy Authentication " ) , 0 , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Use authentication (HTTP or SOCKS5 only) " ) , P_OFFINTNL ( hex_net_proxy_auth ) , 0 , 0 , 0 } ,
{ ST_ENTRY , N_ ( " Username: " ) , P_OFFSETNL ( hex_net_proxy_user ) , 0 , 0 , sizeof prefs . hex_net_proxy_user } ,
{ ST_ENTRY , N_ ( " Password: " ) , P_OFFSETNL ( hex_net_proxy_pass ) , 0 , GINT_TO_POINTER ( 1 ) , sizeof prefs . hex_net_proxy_pass } ,
{ ST_END , 0 , 0 , 0 , 0 , 0 }
2011-02-24 04:14:30 +01:00
} ;
2016-01-25 21:01:56 -05:00
static const setting identd_settings [ ] =
{
2026-01-16 17:52:57 -07:00
{ ST_HEADER , N_ ( " Identd Server " ) , 0 , 0 , 0 , 0 } ,
{ ST_TOGGLE , N_ ( " Enabled " ) , P_OFFINTNL ( hex_identd_server ) , N_ ( " Server will respond with the networks username " ) , 0 , 1 } ,
{ ST_NUMBER , N_ ( " Port: " ) , P_OFFINTNL ( hex_identd_port ) , N_ ( " You must have permissions to listen on this port. "
" If not 113 (0 defaults to this) then you must configure port-forwarding. " ) , 0 , 65535 } ,
2016-01-25 21:01:56 -05:00
2026-01-16 17:52:57 -07:00
{ ST_END , 0 , 0 , 0 , 0 , 0 }
2016-01-25 21:01:56 -05:00
} ;
2011-02-24 04:14:30 +01:00
# define setup_get_str(pr,set) (((char *)pr)+set->offset)
# define setup_get_int(pr,set) *(((int *)pr)+set->offset)
# define setup_get_int3(pr,off) *(((int *)pr)+off)
# define setup_set_int(pr,set,num) *((int *)pr+set->offset)=num
# define setup_set_str(pr,set,str) strcpy(((char *)pr)+set->offset,str)
static void
setup_3oggle_cb ( GtkToggleButton * but , unsigned int * setting )
{
2026-01-16 17:52:57 -07:00
* setting = gtk_toggle_button_get_active ( but ) ;
2011-02-24 04:14:30 +01:00
}
static void
setup_headlabel ( GtkWidget * tab , int row , int col , char * text )
{
2026-01-16 17:52:57 -07:00
GtkWidget * label ;
char buf [ 128 ] ;
char * sp ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
g_snprintf ( buf , sizeof ( buf ) , " <b><span size= \" smaller \" >%s</span></b> " , text ) ;
sp = strchr ( buf + 17 , ' ' ) ;
if ( sp )
* sp = ' \n ' ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
label = gtk_label_new ( NULL ) ;
gtk_label_set_markup ( GTK_LABEL ( label ) , buf ) ;
gtk_misc_set_alignment ( GTK_MISC ( label ) , 0.0 , 0.5 ) ;
gtk_table_attach ( GTK_TABLE ( tab ) , label , col , col + 1 , row , row + 1 , 0 , 0 , 4 , 0 ) ;
2011-02-24 04:14:30 +01:00
}
static void
setup_create_alert_header ( GtkWidget * tab , int row , const setting * set )
{
2026-01-16 17:52:57 -07:00
setup_headlabel ( tab , row , 3 , _ ( " Channel Message " ) ) ;
setup_headlabel ( tab , row , 4 , _ ( " Private Message " ) ) ;
setup_headlabel ( tab , row , 5 , _ ( " Highlighted Message " ) ) ;
2011-02-24 04:14:30 +01:00
}
/* makes 3 toggles side-by-side */
static void
setup_create_3oggle ( GtkWidget * tab , int row , const setting * set )
{
2026-01-16 17:52:57 -07:00
GtkWidget * label , * wid ;
int * offsets = ( int * ) set - > list ;
label = gtk_label_new ( _ ( set - > label ) ) ;
gtk_misc_set_alignment ( GTK_MISC ( label ) , 0.0 , 0.5 ) ;
if ( set - > tooltip )
{
gtk_widget_set_tooltip_text ( label , _ ( set - > tooltip ) ) ;
}
gtk_table_attach ( GTK_TABLE ( tab ) , label , 2 , 3 , row , row + 1 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , LABEL_INDENT , 0 ) ;
wid = gtk_check_button_new ( ) ;
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( wid ) ,
setup_get_int3 ( & setup_prefs , offsets [ 0 ] ) ) ;
g_signal_connect ( G_OBJECT ( wid ) , " toggled " ,
G_CALLBACK ( setup_3oggle_cb ) , ( ( int * ) & setup_prefs ) + offsets [ 0 ] ) ;
gtk_table_attach ( GTK_TABLE ( tab ) , wid , 3 , 4 , row , row + 1 , 0 , 0 , 0 , 0 ) ;
wid = gtk_check_button_new ( ) ;
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( wid ) ,
setup_get_int3 ( & setup_prefs , offsets [ 1 ] ) ) ;
g_signal_connect ( G_OBJECT ( wid ) , " toggled " ,
G_CALLBACK ( setup_3oggle_cb ) , ( ( int * ) & setup_prefs ) + offsets [ 1 ] ) ;
gtk_table_attach ( GTK_TABLE ( tab ) , wid , 4 , 5 , row , row + 1 , 0 , 0 , 0 , 0 ) ;
wid = gtk_check_button_new ( ) ;
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( wid ) ,
setup_get_int3 ( & setup_prefs , offsets [ 2 ] ) ) ;
g_signal_connect ( G_OBJECT ( wid ) , " toggled " ,
G_CALLBACK ( setup_3oggle_cb ) , ( ( int * ) & setup_prefs ) + offsets [ 2 ] ) ;
gtk_table_attach ( GTK_TABLE ( tab ) , wid , 5 , 6 , row , row + 1 , 0 , 0 , 0 , 0 ) ;
2011-02-24 04:14:30 +01:00
}
static void
setup_toggle_cb ( GtkToggleButton * but , const setting * set )
{
2026-01-16 17:52:57 -07:00
GtkWidget * label , * disable_wid ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
setup_set_int ( & setup_prefs , set , gtk_toggle_button_get_active ( but ) ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
/* does this toggle also enable/disable another widget? */
disable_wid = g_object_get_data ( G_OBJECT ( but ) , " nxt " ) ;
if ( disable_wid )
{
gtk_widget_set_sensitive ( disable_wid , gtk_toggle_button_get_active ( but ) ) ;
label = g_object_get_data ( G_OBJECT ( disable_wid ) , " lbl " ) ;
gtk_widget_set_sensitive ( label , gtk_toggle_button_get_active ( but ) ) ;
}
2011-02-24 04:14:30 +01:00
}
2013-04-13 20:54:42 -04:00
static void
setup_toggle_sensitive_cb ( GtkToggleButton * but , GtkWidget * wid )
{
2026-01-16 17:52:57 -07:00
gtk_widget_set_sensitive ( wid , gtk_toggle_button_get_active ( but ) ) ;
2013-04-13 20:54:42 -04:00
}
2011-02-24 04:14:30 +01:00
static void
setup_create_toggleR ( GtkWidget * tab , int row , const setting * set )
{
2026-01-16 17:52:57 -07:00
GtkWidget * wid ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
wid = gtk_check_button_new_with_label ( _ ( set - > label ) ) ;
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( wid ) ,
setup_get_int ( & setup_prefs , set ) ) ;
g_signal_connect ( G_OBJECT ( wid ) , " toggled " ,
G_CALLBACK ( setup_toggle_cb ) , ( gpointer ) set ) ;
if ( set - > tooltip )
gtk_widget_set_tooltip_text ( wid , _ ( set - > tooltip ) ) ;
gtk_table_attach ( GTK_TABLE ( tab ) , wid , 4 , 5 , row , row + 1 ,
GTK_EXPAND | GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , 0 , 0 ) ;
2011-02-24 04:14:30 +01:00
}
static GtkWidget *
setup_create_toggleL ( GtkWidget * tab , int row , const setting * set )
{
2026-01-16 17:52:57 -07:00
GtkWidget * wid ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
wid = gtk_check_button_new_with_label ( _ ( set - > label ) ) ;
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( wid ) ,
setup_get_int ( & setup_prefs , set ) ) ;
g_signal_connect ( G_OBJECT ( wid ) , " toggled " ,
G_CALLBACK ( setup_toggle_cb ) , ( gpointer ) set ) ;
if ( set - > tooltip )
gtk_widget_set_tooltip_text ( wid , _ ( set - > tooltip ) ) ;
gtk_table_attach ( GTK_TABLE ( tab ) , wid , 2 , row = = 6 ? 6 : 4 , row , row + 1 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , LABEL_INDENT , 0 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
return wid ;
2011-02-24 04:14:30 +01:00
}
static GtkWidget *
setup_create_italic_label ( char * text )
{
2026-01-16 17:52:57 -07:00
GtkWidget * label ;
char buf [ 256 ] ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
label = gtk_label_new ( NULL ) ;
g_snprintf ( buf , sizeof ( buf ) , " <i><span size= \" smaller \" >%s</span></i> " , text ) ;
gtk_label_set_markup ( GTK_LABEL ( label ) , buf ) ;
gtk_label_set_justify ( GTK_LABEL ( label ) , GTK_JUSTIFY_CENTER ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
return label ;
2011-02-24 04:14:30 +01:00
}
static void
setup_spin_cb ( GtkSpinButton * spin , const setting * set )
{
2026-01-16 17:52:57 -07:00
setup_set_int ( & setup_prefs , set , gtk_spin_button_get_value_as_int ( spin ) ) ;
2011-02-24 04:14:30 +01:00
}
static GtkWidget *
setup_create_spin ( GtkWidget * table , int row , const setting * set )
{
2026-01-16 17:52:57 -07:00
GtkWidget * label , * wid , * rbox , * align ;
char * text ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
label = gtk_label_new ( _ ( set - > label ) ) ;
gtk_misc_set_alignment ( GTK_MISC ( label ) , 0.0 , 0.5 ) ;
gtk_table_attach ( GTK_TABLE ( table ) , label , 2 , 3 , row , row + 1 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , LABEL_INDENT , 0 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
align = gtk_alignment_new ( 0.0 , 0.5 , 0.0 , 0.0 ) ;
gtk_table_attach ( GTK_TABLE ( table ) , align , 3 , 4 , row , row + 1 ,
GTK_EXPAND | GTK_FILL , GTK_SHRINK | GTK_FILL , 0 , 0 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
rbox = gtk_hbox_new ( 0 , 0 ) ;
gtk_container_add ( GTK_CONTAINER ( align ) , rbox ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
wid = gtk_spin_button_new_with_range ( 0 , set - > extra , 1 ) ;
g_object_set_data ( G_OBJECT ( wid ) , " lbl " , label ) ;
if ( set - > tooltip )
gtk_widget_set_tooltip_text ( wid , _ ( set - > tooltip ) ) ;
gtk_spin_button_set_value ( GTK_SPIN_BUTTON ( wid ) ,
setup_get_int ( & setup_prefs , set ) ) ;
g_signal_connect ( G_OBJECT ( wid ) , " value_changed " ,
G_CALLBACK ( setup_spin_cb ) , ( gpointer ) set ) ;
gtk_box_pack_start ( GTK_BOX ( rbox ) , wid , 0 , 0 , 0 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
if ( set - > list )
{
text = _ ( ( char * ) set - > list ) ;
if ( text [ 0 ] = = ' ! ' )
label = setup_create_italic_label ( text + 1 ) ;
else
label = gtk_label_new ( text ) ;
gtk_box_pack_start ( GTK_BOX ( rbox ) , label , 0 , 0 , 6 ) ;
}
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
return wid ;
2011-02-24 04:14:30 +01:00
}
static gint
2013-09-26 23:24:27 -04:00
setup_apply_trans ( int * tag )
2011-02-24 04:14:30 +01:00
{
2026-01-16 17:52:57 -07:00
prefs . hex_gui_transparency = setup_prefs . hex_gui_transparency ;
gtk_window_set_opacity ( GTK_WINDOW ( current_sess - > gui - > window ) ,
( prefs . hex_gui_transparency / 255. ) ) ;
2013-09-26 23:24:27 -04:00
2026-01-16 17:52:57 -07:00
/* mg_update_xtext (current_sess->gui->xtext); */
* tag = 0 ;
return 0 ;
2011-02-24 04:14:30 +01:00
}
static void
setup_hscale_cb ( GtkHScale * wid , const setting * set )
{
2026-01-16 17:52:57 -07:00
static int tag = 0 ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
setup_set_int ( & setup_prefs , set , ( int ) gtk_range_get_value ( GTK_RANGE ( wid ) ) ) ;
2012-11-10 18:26:45 +01:00
2026-01-16 17:52:57 -07:00
if ( tag = = 0 )
{
tag = g_idle_add ( ( GSourceFunc ) setup_apply_trans , & tag ) ;
}
2011-02-24 04:14:30 +01:00
}
static void
setup_create_hscale ( GtkWidget * table , int row , const setting * set )
{
2026-01-16 17:52:57 -07:00
GtkWidget * wid ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
wid = gtk_label_new ( _ ( set - > label ) ) ;
gtk_misc_set_alignment ( GTK_MISC ( wid ) , 0.0 , 0.5 ) ;
gtk_table_attach ( GTK_TABLE ( table ) , wid , 2 , 3 , row , row + 1 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , LABEL_INDENT , 0 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
wid = gtk_hscale_new_with_range ( 0. , 255. , 1. ) ;
gtk_scale_set_value_pos ( GTK_SCALE ( wid ) , GTK_POS_RIGHT ) ;
gtk_range_set_value ( GTK_RANGE ( wid ) , setup_get_int ( & setup_prefs , set ) ) ;
g_signal_connect ( G_OBJECT ( wid ) , " value_changed " ,
G_CALLBACK ( setup_hscale_cb ) , ( gpointer ) set ) ;
gtk_table_attach ( GTK_TABLE ( table ) , wid , 3 , 6 , row , row + 1 ,
GTK_EXPAND | GTK_FILL , GTK_FILL , 0 , 0 ) ;
2013-09-26 23:24:27 -04:00
# ifndef WIN32 /* Windows always supports this */
2026-01-16 17:52:57 -07:00
/* Only used for transparency currently */
if ( ! gtk_widget_is_composited ( current_sess - > gui - > window ) )
gtk_widget_set_sensitive ( wid , FALSE ) ;
2013-09-26 23:24:27 -04:00
# endif
2011-02-24 04:14:30 +01:00
}
2026-01-16 17:52:57 -07:00
static GtkWidget * proxy_user ; /* username GtkEntry */
static GtkWidget * proxy_pass ; /* password GtkEntry */
2011-02-24 04:14:30 +01:00
static void
setup_menu_cb ( GtkWidget * cbox , const setting * set )
{
2026-01-16 17:52:57 -07:00
int n = gtk_combo_box_get_active ( GTK_COMBO_BOX ( cbox ) ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
/* set the prefs.<field> */
setup_set_int ( & setup_prefs , set , n + set - > extra ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
if ( set - > list = = proxytypes )
{
/* only HTTP and SOCKS5 can use a username/pass */
gtk_widget_set_sensitive ( proxy_user , ( n = = 3 | | n = = 4 | | n = = 5 ) ) ;
gtk_widget_set_sensitive ( proxy_pass , ( n = = 3 | | n = = 4 | | n = = 5 ) ) ;
}
2011-02-24 04:14:30 +01:00
}
static void
setup_radio_cb ( GtkWidget * item , const setting * set )
{
2026-01-16 17:52:57 -07:00
if ( gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( item ) ) )
{
int n = GPOINTER_TO_INT ( g_object_get_data ( G_OBJECT ( item ) , " n " ) ) ;
/* set the prefs.<field> */
setup_set_int ( & setup_prefs , set , n ) ;
}
2011-02-24 04:14:30 +01:00
}
static int
setup_create_radio ( GtkWidget * table , int row , const setting * set )
{
2026-01-16 17:52:57 -07:00
GtkWidget * wid , * hbox ;
int i ;
const char * * text = ( const char * * ) set - > list ;
GSList * group ;
wid = gtk_label_new ( _ ( set - > label ) ) ;
gtk_misc_set_alignment ( GTK_MISC ( wid ) , 0.0 , 0.5 ) ;
gtk_table_attach ( GTK_TABLE ( table ) , wid , 2 , 3 , row , row + 1 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , LABEL_INDENT , 0 ) ;
hbox = gtk_hbox_new ( 0 , 0 ) ;
gtk_table_attach ( GTK_TABLE ( table ) , hbox , 3 , 4 , row , row + 1 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , 0 , 0 ) ;
i = 0 ;
group = NULL ;
while ( text [ i ] )
{
if ( text [ i ] [ 0 ] ! = 0 )
{
wid = gtk_radio_button_new_with_mnemonic ( group , _ ( text [ i ] ) ) ;
/*if (set->tooltip)
gtk_widget_set_tooltip_text ( wid , _ ( set - > tooltip ) ) ; */
group = gtk_radio_button_get_group ( GTK_RADIO_BUTTON ( wid ) ) ;
gtk_container_add ( GTK_CONTAINER ( hbox ) , wid ) ;
if ( i = = setup_get_int ( & setup_prefs , set ) )
gtk_toggle_button_set_active ( GTK_TOGGLE_BUTTON ( wid ) , TRUE ) ;
g_object_set_data ( G_OBJECT ( wid ) , " n " , GINT_TO_POINTER ( i ) ) ;
g_signal_connect ( G_OBJECT ( wid ) , " toggled " ,
G_CALLBACK ( setup_radio_cb ) , ( gpointer ) set ) ;
}
i + + ;
row + + ;
}
return i ;
2011-02-24 04:14:30 +01:00
}
/*
static const char * id_strings [ ] =
{
2026-01-16 17:52:57 -07:00
" " ,
" * " ,
" %C4*%C18%B%B " ,
" %U "
2011-02-24 04:14:30 +01:00
} ;
static void
setup_id_menu_cb ( GtkWidget * item , char * dest )
{
2026-01-16 17:52:57 -07:00
int n = GPOINTER_TO_INT ( g_object_get_data ( G_OBJECT ( item ) , " n " ) ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
strcpy ( dest , id_strings [ n ] ) ;
2011-02-24 04:14:30 +01:00
}
static void
setup_create_id_menu ( GtkWidget * table , char * label , int row , char * dest )
{
2026-01-16 17:52:57 -07:00
GtkWidget * wid , * menu , * item ;
int i , def = 0 ;
static const char * text [ ] =
{
( " (disabled) " ) ,
( " A star (*) " ) ,
( " A red star (*) " ) ,
( " Underlined " )
} ;
wid = gtk_label_new ( label ) ;
gtk_misc_set_alignment ( GTK_MISC ( wid ) , 0.0 , 0.5 ) ;
gtk_table_attach ( GTK_TABLE ( table ) , wid , 2 , 3 , row , row + 1 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , LABEL_INDENT , 0 ) ;
wid = gtk_option_menu_new ( ) ;
menu = gtk_menu_new ( ) ;
for ( i = 0 ; i < 4 ; i + + )
{
if ( strcmp ( id_strings [ i ] , dest ) = = 0 )
{
def = i ;
break ;
}
}
i = 0 ;
while ( text [ i ] )
{
item = gtk_menu_item_new_with_label ( _ ( text [ i ] ) ) ;
g_object_set_data ( G_OBJECT ( item ) , " n " , GINT_TO_POINTER ( i ) ) ;
gtk_widget_show ( item ) ;
gtk_menu_shell_append ( GTK_MENU_SHELL ( menu ) , item ) ;
g_signal_connect ( G_OBJECT ( item ) , " activate " ,
G_CALLBACK ( setup_id_menu_cb ) , dest ) ;
i + + ;
}
gtk_option_menu_set_menu ( GTK_OPTION_MENU ( wid ) , menu ) ;
gtk_option_menu_set_history ( GTK_OPTION_MENU ( wid ) , def ) ;
gtk_table_attach ( GTK_TABLE ( table ) , wid , 3 , 4 , row , row + 1 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , 0 , 0 ) ;
2011-02-24 04:14:30 +01:00
}
*/
static void
setup_create_menu ( GtkWidget * table , int row , const setting * set )
{
2026-01-16 17:52:57 -07:00
GtkWidget * wid , * cbox , * box ;
const char * * text = ( const char * * ) set - > list ;
int i ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
wid = gtk_label_new ( _ ( set - > label ) ) ;
gtk_misc_set_alignment ( GTK_MISC ( wid ) , 0.0 , 0.5 ) ;
gtk_table_attach ( GTK_TABLE ( table ) , wid , 2 , 3 , row , row + 1 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , LABEL_INDENT , 0 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
cbox = gtk_combo_box_text_new ( ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
for ( i = 0 ; text [ i ] ; i + + )
gtk_combo_box_text_append_text ( GTK_COMBO_BOX_TEXT ( cbox ) , _ ( text [ i ] ) ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
gtk_combo_box_set_active ( GTK_COMBO_BOX ( cbox ) ,
setup_get_int ( & setup_prefs , set ) - set - > extra ) ;
g_signal_connect ( G_OBJECT ( cbox ) , " changed " ,
G_CALLBACK ( setup_menu_cb ) , ( gpointer ) set ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
box = gtk_hbox_new ( 0 , 0 ) ;
gtk_box_pack_start ( GTK_BOX ( box ) , cbox , 0 , 0 , 0 ) ;
gtk_table_attach ( GTK_TABLE ( table ) , box , 3 , 4 , row , row + 1 ,
GTK_EXPAND | GTK_FILL , GTK_SHRINK | GTK_FILL , 0 , 0 ) ;
2011-02-24 04:14:30 +01:00
}
static void
setup_filereq_cb ( GtkWidget * entry , char * file )
{
2026-01-16 17:52:57 -07:00
if ( file )
{
if ( file [ 0 ] )
gtk_entry_set_text ( GTK_ENTRY ( entry ) , file ) ;
}
2011-02-24 04:14:30 +01:00
}
static void
setup_browsefile_cb ( GtkWidget * button , GtkWidget * entry )
{
2026-01-16 17:52:57 -07:00
/* used for background image only */
char * filter ;
int filter_type ;
2013-08-31 15:38:29 -04:00
# ifdef WIN32
2026-01-16 17:52:57 -07:00
filter = " *png;*.tiff;*.gif;*.jpeg;*.jpg " ;
filter_type = FRF_EXTENSIONS ;
2013-08-31 15:38:29 -04:00
# else
2026-01-16 17:52:57 -07:00
filter = " image/* " ;
filter_type = FRF_MIMETYPES ;
2013-08-31 15:38:29 -04:00
# endif
2026-01-16 17:52:57 -07:00
gtkutil_file_req ( GTK_WINDOW ( setup_window ) , _ ( " Select an Image File " ) , setup_filereq_cb ,
entry , NULL , filter , filter_type | FRF_RECENTLYUSED | FRF_MODAL ) ;
2011-02-24 04:14:30 +01:00
}
static void
setup_fontsel_destroy ( GtkWidget * button , GtkFontSelectionDialog * dialog )
{
2026-01-16 17:52:57 -07:00
font_dialog = NULL ;
2011-02-24 04:14:30 +01:00
}
static void
setup_fontsel_cb ( GtkWidget * button , GtkFontSelectionDialog * dialog )
{
2026-01-16 17:52:57 -07:00
GtkWidget * entry ;
char * font_name ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
entry = g_object_get_data ( G_OBJECT ( button ) , " e " ) ;
font_name = gtk_font_selection_dialog_get_font_name ( dialog ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
gtk_entry_set_text ( GTK_ENTRY ( entry ) , font_name ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
g_free ( font_name ) ;
gtk_widget_destroy ( GTK_WIDGET ( dialog ) ) ;
font_dialog = NULL ;
2011-02-24 04:14:30 +01:00
}
static void
setup_fontsel_cancel ( GtkWidget * button , GtkFontSelectionDialog * dialog )
{
2026-01-16 17:52:57 -07:00
gtk_widget_destroy ( GTK_WIDGET ( dialog ) ) ;
font_dialog = NULL ;
2011-02-24 04:14:30 +01:00
}
static void
setup_browsefolder_cb ( GtkWidget * button , GtkEntry * entry )
{
2026-01-16 17:52:57 -07:00
gtkutil_file_req ( GTK_WINDOW ( setup_window ) , _ ( " Select Download Folder " ) , setup_filereq_cb , entry , ( char * ) gtk_entry_get_text ( entry ) , NULL , FRF_CHOOSEFOLDER | FRF_MODAL ) ;
2011-02-24 04:14:30 +01:00
}
static void
setup_browsefont_cb ( GtkWidget * button , GtkWidget * entry )
{
2026-01-16 17:52:57 -07:00
GtkFontSelection * sel ;
GtkFontSelectionDialog * dialog ;
GtkWidget * ok_button ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
dialog = ( GtkFontSelectionDialog * ) gtk_font_selection_dialog_new ( _ ( " Select font " ) ) ;
font_dialog = ( GtkWidget * ) dialog ; /* global var */
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
gtk_window_set_transient_for ( GTK_WINDOW ( font_dialog ) , GTK_WINDOW ( setup_window ) ) ;
gtk_window_set_modal ( GTK_WINDOW ( font_dialog ) , TRUE ) ;
2022-04-16 18:41:34 -05:00
2026-01-16 17:52:57 -07:00
sel = ( GtkFontSelection * ) gtk_font_selection_dialog_get_font_selection ( dialog ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
if ( gtk_entry_get_text ( GTK_ENTRY ( entry ) ) [ 0 ] )
gtk_font_selection_set_font_name ( sel , gtk_entry_get_text ( GTK_ENTRY ( entry ) ) ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
ok_button = gtk_font_selection_dialog_get_ok_button ( dialog ) ;
g_object_set_data ( G_OBJECT ( ok_button ) , " e " , entry ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
g_signal_connect ( G_OBJECT ( dialog ) , " destroy " ,
G_CALLBACK ( setup_fontsel_destroy ) , dialog ) ;
g_signal_connect ( G_OBJECT ( ok_button ) , " clicked " ,
G_CALLBACK ( setup_fontsel_cb ) , dialog ) ;
g_signal_connect ( G_OBJECT ( gtk_font_selection_dialog_get_cancel_button ( dialog ) ) , " clicked " ,
G_CALLBACK ( setup_fontsel_cancel ) , dialog ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
gtk_widget_show ( GTK_WIDGET ( dialog ) ) ;
2011-02-24 04:14:30 +01:00
}
static void
setup_entry_cb ( GtkEntry * entry , setting * set )
{
2026-01-16 17:52:57 -07:00
int size ;
int pos ;
unsigned char * p = ( unsigned char * ) gtk_entry_get_text ( entry ) ;
int len = strlen ( p ) ;
/* need to truncate? */
if ( len > = set - > extra )
{
len = pos = 0 ;
while ( 1 )
{
size = g_utf8_skip [ * p ] ;
len + = size ;
p + = size ;
/* truncate to "set->extra" BYTES */
if ( len > = set - > extra )
{
gtk_editable_delete_text ( GTK_EDITABLE ( entry ) , pos , - 1 ) ;
break ;
}
pos + + ;
}
}
else
{
setup_set_str ( & setup_prefs , set , gtk_entry_get_text ( entry ) ) ;
}
2011-02-24 04:14:30 +01:00
}
static void
setup_create_label ( GtkWidget * table , int row , const setting * set )
{
2026-01-16 17:52:57 -07:00
gtk_table_attach ( GTK_TABLE ( table ) , setup_create_italic_label ( _ ( set - > label ) ) ,
set - > extra ? 1 : 3 , 5 , row , row + 1 , GTK_FILL ,
GTK_SHRINK | GTK_FILL , 0 , 0 ) ;
2011-02-24 04:14:30 +01:00
}
static GtkWidget *
setup_create_entry ( GtkWidget * table , int row , const setting * set )
{
2026-01-16 17:52:57 -07:00
GtkWidget * label ;
GtkWidget * wid , * bwid ;
label = gtk_label_new ( _ ( set - > label ) ) ;
gtk_misc_set_alignment ( GTK_MISC ( label ) , 0.0 , 0.5 ) ;
gtk_table_attach ( GTK_TABLE ( table ) , label , 2 , 3 , row , row + 1 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , LABEL_INDENT , 0 ) ;
wid = gtk_entry_new ( ) ;
g_object_set_data ( G_OBJECT ( wid ) , " lbl " , label ) ;
if ( set - > list )
gtk_entry_set_visibility ( GTK_ENTRY ( wid ) , FALSE ) ;
if ( set - > tooltip )
gtk_widget_set_tooltip_text ( wid , _ ( set - > tooltip ) ) ;
gtk_entry_set_max_length ( GTK_ENTRY ( wid ) , set - > extra - 1 ) ;
gtk_entry_set_text ( GTK_ENTRY ( wid ) , setup_get_str ( & setup_prefs , set ) ) ;
g_signal_connect ( G_OBJECT ( wid ) , " changed " ,
G_CALLBACK ( setup_entry_cb ) , ( gpointer ) set ) ;
if ( set - > offset = = P_OFFSETNL ( hex_net_proxy_user ) )
proxy_user = wid ;
if ( set - > offset = = P_OFFSETNL ( hex_net_proxy_pass ) )
proxy_pass = wid ;
/* only http and Socks5 can auth */
if ( ( set - > offset = = P_OFFSETNL ( hex_net_proxy_pass ) | |
set - > offset = = P_OFFSETNL ( hex_net_proxy_user ) ) & &
( setup_prefs . hex_net_proxy_type ! = 4 & & setup_prefs . hex_net_proxy_type ! = 3 & & setup_prefs . hex_net_proxy_type ! = 5 ) )
gtk_widget_set_sensitive ( wid , FALSE ) ;
if ( set - > type = = ST_ENTRY )
gtk_table_attach ( GTK_TABLE ( table ) , wid , 3 , 6 , row , row + 1 ,
GTK_EXPAND | GTK_FILL , GTK_FILL , 0 , 0 ) ;
else
{
gtk_table_attach ( GTK_TABLE ( table ) , wid , 3 , 5 , row , row + 1 ,
GTK_EXPAND | GTK_FILL , GTK_SHRINK , 0 , 0 ) ;
bwid = gtk_button_new_with_label ( _ ( " Browse... " ) ) ;
gtk_table_attach ( GTK_TABLE ( table ) , bwid , 5 , 6 , row , row + 1 ,
GTK_SHRINK | GTK_FILL , GTK_FILL , 0 , 0 ) ;
if ( set - > type = = ST_EFILE )
g_signal_connect ( G_OBJECT ( bwid ) , " clicked " ,
G_CALLBACK ( setup_browsefile_cb ) , wid ) ;
if ( set - > type = = ST_EFONT )
g_signal_connect ( G_OBJECT ( bwid ) , " clicked " ,
G_CALLBACK ( setup_browsefont_cb ) , wid ) ;
if ( set - > type = = ST_EFOLDER )
g_signal_connect ( G_OBJECT ( bwid ) , " clicked " ,
G_CALLBACK ( setup_browsefolder_cb ) , wid ) ;
}
return wid ;
2011-02-24 04:14:30 +01:00
}
static void
setup_create_header ( GtkWidget * table , int row , char * labeltext )
{
2026-01-16 17:52:57 -07:00
GtkWidget * label ;
char buf [ 128 ] ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
if ( row = = 0 )
g_snprintf ( buf , sizeof ( buf ) , " <b>%s</b> " , _ ( labeltext ) ) ;
else
g_snprintf ( buf , sizeof ( buf ) , " \n <b>%s</b> " , _ ( labeltext ) ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
label = gtk_label_new ( NULL ) ;
gtk_label_set_markup ( GTK_LABEL ( label ) , buf ) ;
gtk_misc_set_alignment ( GTK_MISC ( label ) , 0.0 , 0.5 ) ;
gtk_table_attach ( GTK_TABLE ( table ) , label , 0 , 4 , row , row + 1 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , 0 , 5 ) ;
2011-02-24 04:14:30 +01:00
}
2014-02-07 22:20:43 -05:00
static void
setup_create_button ( GtkWidget * table , int row , char * label , GCallback callback )
{
2026-01-16 17:52:57 -07:00
GtkWidget * but = gtk_button_new_with_label ( label ) ;
gtk_table_attach ( GTK_TABLE ( table ) , but , 2 , 3 , row , row + 1 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , 0 , 5 ) ;
g_signal_connect ( G_OBJECT ( but ) , " clicked " , callback , NULL ) ;
2014-02-07 22:20:43 -05:00
}
2011-02-24 04:14:30 +01:00
static GtkWidget *
2014-02-07 22:20:43 -05:00
setup_create_frame ( void )
2011-02-24 04:14:30 +01:00
{
2026-01-16 17:52:57 -07:00
GtkWidget * tab ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
tab = gtk_table_new ( 3 , 2 , FALSE ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( tab ) , 6 ) ;
gtk_table_set_row_spacings ( GTK_TABLE ( tab ) , 2 ) ;
gtk_table_set_col_spacings ( GTK_TABLE ( tab ) , 3 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
return tab ;
2011-02-24 04:14:30 +01:00
}
static void
open_data_cb ( GtkWidget * button , gpointer data )
{
2026-01-16 17:52:57 -07:00
fe_open_url ( get_xdir ( ) ) ;
2011-02-24 04:14:30 +01:00
}
static GtkWidget *
setup_create_page ( const setting * set )
{
2026-01-16 17:52:57 -07:00
int i , row , do_disable ;
GtkWidget * tab ;
GtkWidget * wid = NULL , * parentwid = NULL ;
tab = setup_create_frame ( ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( tab ) , 6 ) ;
i = row = do_disable = 0 ;
while ( set [ i ] . type ! = ST_END )
{
switch ( set [ i ] . type )
{
case ST_HEADER :
setup_create_header ( tab , row , set [ i ] . label ) ;
break ;
case ST_EFONT :
case ST_ENTRY :
case ST_EFILE :
case ST_EFOLDER :
wid = setup_create_entry ( tab , row , & set [ i ] ) ;
break ;
case ST_TOGGLR :
row - - ;
setup_create_toggleR ( tab , row , & set [ i ] ) ;
break ;
case ST_TOGGLE :
wid = setup_create_toggleL ( tab , row , & set [ i ] ) ;
if ( set [ i ] . extra )
do_disable = set [ i ] . extra ;
break ;
case ST_3OGGLE :
setup_create_3oggle ( tab , row , & set [ i ] ) ;
break ;
case ST_MENU :
setup_create_menu ( tab , row , & set [ i ] ) ;
break ;
case ST_RADIO :
row + = setup_create_radio ( tab , row , & set [ i ] ) ;
break ;
case ST_NUMBER :
wid = setup_create_spin ( tab , row , & set [ i ] ) ;
break ;
case ST_HSCALE :
setup_create_hscale ( tab , row , & set [ i ] ) ;
break ;
case ST_LABEL :
setup_create_label ( tab , row , & set [ i ] ) ;
break ;
case ST_ALERTHEAD :
setup_create_alert_header ( tab , row , & set [ i ] ) ;
}
if ( do_disable )
{
if ( GTK_IS_WIDGET ( parentwid ) )
{
g_signal_connect ( G_OBJECT ( parentwid ) , " toggled " , G_CALLBACK ( setup_toggle_sensitive_cb ) , wid ) ;
gtk_widget_set_sensitive ( wid , gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON ( parentwid ) ) ) ;
do_disable - - ;
if ( ! do_disable )
parentwid = NULL ;
}
else
parentwid = wid ;
}
i + + ;
row + + ;
}
if ( set = = logging_settings )
{
setup_create_button ( tab , row , _ ( " Open Data Folder " ) , G_CALLBACK ( open_data_cb ) ) ;
}
return tab ;
2011-02-24 04:14:30 +01:00
}
2026-01-12 21:24:09 -07:00
static void
setup_color_selectors_set_sensitive ( gboolean sensitive )
{
2026-01-16 17:52:57 -07:00
GSList * l = color_selector_widgets ;
while ( l )
{
GtkWidget * w = ( GtkWidget * ) l - > data ;
if ( GTK_IS_WIDGET ( w ) )
gtk_widget_set_sensitive ( w , sensitive ) ;
l = l - > next ;
}
2026-01-12 21:24:09 -07:00
}
static void
2026-01-17 23:09:38 -07:00
setup_dark_mode_menu_cb ( GtkWidget * cbox , const setting * set )
{
setup_menu_cb ( cbox , set ) ;
/* Keep color selectors usable even when dark mode is enabled. */
setup_color_selectors_set_sensitive ( TRUE ) ;
}
static GtkWidget *
setup_create_dark_mode_menu ( GtkWidget * table , int row , const setting * set )
2026-01-12 21:24:09 -07:00
{
2026-01-17 23:09:38 -07:00
GtkWidget * wid , * cbox , * box ;
const char * * text = ( const char * * ) set - > list ;
int i ;
wid = gtk_label_new ( _ ( set - > label ) ) ;
gtk_misc_set_alignment ( GTK_MISC ( wid ) , 0.0 , 0.5 ) ;
gtk_table_attach ( GTK_TABLE ( table ) , wid , 2 , 3 , row , row + 1 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , LABEL_INDENT , 0 ) ;
cbox = gtk_combo_box_text_new ( ) ;
for ( i = 0 ; text [ i ] ; i + + )
gtk_combo_box_text_append_text ( GTK_COMBO_BOX_TEXT ( cbox ) , _ ( text [ i ] ) ) ;
gtk_combo_box_set_active ( GTK_COMBO_BOX ( cbox ) ,
setup_get_int ( & setup_prefs , set ) - set - > extra ) ;
g_signal_connect ( G_OBJECT ( cbox ) , " changed " ,
G_CALLBACK ( setup_dark_mode_menu_cb ) , ( gpointer ) set ) ;
box = gtk_hbox_new ( 0 , 0 ) ;
gtk_box_pack_start ( GTK_BOX ( box ) , cbox , 0 , 0 , 0 ) ;
gtk_table_attach ( GTK_TABLE ( table ) , box , 3 , 4 , row , row + 1 ,
GTK_EXPAND | GTK_FILL , GTK_SHRINK | GTK_FILL , 0 , 0 ) ;
return cbox ;
2026-01-12 21:24:09 -07:00
}
2026-01-17 23:50:44 -07:00
static void
2026-01-19 22:50:17 -07:00
setup_color_button_apply ( GtkWidget * button , const PaletteColor * color )
2026-01-17 23:50:44 -07:00
{
GtkWidget * target = g_object_get_data ( G_OBJECT ( button ) , " zoitechat-color-box " ) ;
2026-01-19 22:50:17 -07:00
GtkWidget * apply_widget = GTK_IS_WIDGET ( target ) ? target : button ;
# if GTK_CHECK_VERSION(3,0,0)
GtkStateFlags states [ ] = {
GTK_STATE_FLAG_NORMAL ,
GTK_STATE_FLAG_PRELIGHT ,
GTK_STATE_FLAG_ACTIVE ,
GTK_STATE_FLAG_SELECTED ,
GTK_STATE_FLAG_INSENSITIVE
} ;
# else
2026-01-17 23:50:44 -07:00
GtkStateType states [ ] = {
GTK_STATE_NORMAL ,
GTK_STATE_PRELIGHT ,
GTK_STATE_ACTIVE ,
GTK_STATE_SELECTED ,
GTK_STATE_INSENSITIVE
} ;
2026-01-19 22:50:17 -07:00
# endif
2026-01-17 23:50:44 -07:00
guint i ;
for ( i = 0 ; i < G_N_ELEMENTS ( states ) ; i + + )
2026-01-19 22:50:17 -07:00
# if GTK_CHECK_VERSION(3,0,0)
gtk_widget_override_background_color ( apply_widget , states [ i ] , color ) ;
# else
2026-01-17 23:50:44 -07:00
gtk_widget_modify_bg ( apply_widget , states [ i ] , color ) ;
2026-01-19 22:50:17 -07:00
# endif
2026-01-17 23:50:44 -07:00
if ( apply_widget ! = button )
for ( i = 0 ; i < G_N_ELEMENTS ( states ) ; i + + )
2026-01-19 22:50:17 -07:00
# if GTK_CHECK_VERSION(3,0,0)
gtk_widget_override_background_color ( button , states [ i ] , color ) ;
# else
2026-01-17 23:50:44 -07:00
gtk_widget_modify_bg ( button , states [ i ] , color ) ;
2026-01-19 22:50:17 -07:00
# endif
2026-01-17 23:50:44 -07:00
gtk_widget_queue_draw ( button ) ;
}
2026-01-19 22:50:17 -07:00
# if GTK_CHECK_VERSION(3,0,0)
typedef struct
{
GtkWidget * button ;
PaletteColor * color ;
} setup_color_dialog_data ;
static void
setup_color_response_cb ( GtkDialog * dialog , gint response_id , gpointer user_data )
{
setup_color_dialog_data * data = user_data ;
if ( response_id = = GTK_RESPONSE_OK )
{
2026-01-20 12:26:01 -07:00
GdkRGBA rgba ;
gtk_color_chooser_get_rgba ( GTK_COLOR_CHOOSER ( dialog ) , & rgba ) ;
* data - > color = rgba ;
2026-01-19 22:50:17 -07:00
color_change = TRUE ;
setup_color_button_apply ( data - > button , data - > color ) ;
if ( fe_dark_mode_is_enabled_for ( setup_prefs . hex_gui_dark_mode ) )
palette_dark_set_color ( ( int ) ( data - > color - colors ) , data - > color ) ;
else
palette_user_set_color ( ( int ) ( data - > color - colors ) , data - > color ) ;
}
gtk_widget_destroy ( GTK_WIDGET ( dialog ) ) ;
g_free ( data ) ;
}
# else
2011-02-24 04:14:30 +01:00
static void
setup_color_ok_cb ( GtkWidget * button , GtkWidget * dialog )
{
2026-01-16 17:52:57 -07:00
GtkColorSelectionDialog * cdialog = GTK_COLOR_SELECTION_DIALOG ( dialog ) ;
GdkColor * col ;
col = g_object_get_data ( G_OBJECT ( button ) , " c " ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
button = g_object_get_data ( G_OBJECT ( button ) , " b " ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
if ( ! GTK_IS_WIDGET ( button ) )
{
gtk_widget_destroy ( dialog ) ;
return ;
}
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
color_change = TRUE ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
gtk_color_selection_get_current_color ( GTK_COLOR_SELECTION ( gtk_color_selection_dialog_get_color_selection ( cdialog ) ) , col ) ;
2011-02-24 04:14:30 +01:00
2026-01-17 23:50:44 -07:00
setup_color_button_apply ( button , col ) ;
2011-02-24 04:14:30 +01:00
2026-01-17 23:09:38 -07:00
/* Persist custom colors for the palette the user is editing. */
if ( fe_dark_mode_is_enabled_for ( setup_prefs . hex_gui_dark_mode ) )
palette_dark_set_color ( ( int ) ( col - colors ) , col ) ;
else
palette_user_set_color ( ( int ) ( col - colors ) , col ) ;
2026-01-12 21:24:09 -07:00
2026-01-16 17:52:57 -07:00
gtk_widget_destroy ( dialog ) ;
2011-02-24 04:14:30 +01:00
}
2026-01-19 22:50:17 -07:00
# endif
2011-02-24 04:14:30 +01:00
static void
setup_color_cb ( GtkWidget * button , gpointer userdata )
{
2026-01-19 22:50:17 -07:00
# if GTK_CHECK_VERSION(3,0,0)
GtkWidget * dialog ;
PaletteColor * color ;
2026-01-22 22:03:31 -07:00
GdkRGBA rgba ;
2026-01-22 22:36:49 -07:00
gboolean parsed_ok ;
char * color_string ;
2026-01-19 22:50:17 -07:00
setup_color_dialog_data * data ;
color = & colors [ GPOINTER_TO_INT ( userdata ) ] ;
dialog = gtk_color_chooser_dialog_new ( _ ( " Select color " ) , GTK_WINDOW ( setup_window ) ) ;
2026-01-22 22:36:49 -07:00
color_string = gdk_rgba_to_string ( color ) ;
parsed_ok = gdk_rgba_parse ( & rgba , color_string ) ;
g_free ( color_string ) ;
if ( ! parsed_ok )
rgba = * color ;
2026-01-22 22:03:31 -07:00
gtk_color_chooser_set_rgba ( GTK_COLOR_CHOOSER ( dialog ) , & rgba ) ;
2026-01-19 22:50:17 -07:00
gtk_window_set_modal ( GTK_WINDOW ( dialog ) , TRUE ) ;
data = g_new0 ( setup_color_dialog_data , 1 ) ;
data - > button = button ;
data - > color = color ;
g_signal_connect ( dialog , " response " , G_CALLBACK ( setup_color_response_cb ) , data ) ;
gtk_widget_show ( dialog ) ;
# else
2026-01-16 17:52:57 -07:00
GtkWidget * dialog , * cancel_button , * ok_button , * help_button ;
GtkColorSelectionDialog * cdialog ;
GdkColor * color ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
color = & colors [ GPOINTER_TO_INT ( userdata ) ] ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
dialog = gtk_color_selection_dialog_new ( _ ( " Select color " ) ) ;
cdialog = GTK_COLOR_SELECTION_DIALOG ( dialog ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
g_object_get ( G_OBJECT ( cdialog ) , " cancel-button " , & cancel_button ,
" ok-button " , & ok_button ,
" help-button " , & help_button , NULL ) ;
2013-10-29 00:54:12 -04:00
2026-01-16 17:52:57 -07:00
gtk_widget_hide ( help_button ) ;
g_signal_connect ( G_OBJECT ( ok_button ) , " clicked " ,
G_CALLBACK ( setup_color_ok_cb ) , dialog ) ;
g_signal_connect ( G_OBJECT ( cancel_button ) , " clicked " ,
G_CALLBACK ( gtkutil_destroy ) , dialog ) ;
g_object_set_data ( G_OBJECT ( ok_button ) , " c " , color ) ;
g_object_set_data ( G_OBJECT ( ok_button ) , " b " , button ) ;
gtk_widget_set_sensitive ( help_button , FALSE ) ;
gtk_color_selection_set_current_color ( GTK_COLOR_SELECTION ( gtk_color_selection_dialog_get_color_selection ( cdialog ) ) , color ) ;
gtk_window_set_transient_for ( GTK_WINDOW ( dialog ) , GTK_WINDOW ( setup_window ) ) ;
gtk_window_set_modal ( GTK_WINDOW ( dialog ) , TRUE ) ;
gtk_widget_show ( dialog ) ;
2013-10-29 00:54:12 -04:00
2026-01-16 17:52:57 -07:00
g_object_unref ( cancel_button ) ;
g_object_unref ( ok_button ) ;
g_object_unref ( help_button ) ;
2026-01-19 22:50:17 -07:00
# endif
2011-02-24 04:14:30 +01:00
}
static void
setup_create_color_button ( GtkWidget * table , int num , int row , int col )
{
2026-01-16 17:52:57 -07:00
GtkWidget * but ;
2026-01-17 23:50:44 -07:00
GtkWidget * label ;
GtkWidget * box ;
GtkWidget * alignment ;
2026-01-16 17:52:57 -07:00
char buf [ 64 ] ;
if ( num > 31 )
2026-01-18 01:14:49 -07:00
strcpy ( buf , " <span size= \" x-small \" >  </span> " ) ;
2026-01-17 23:50:44 -07:00
else if ( num < 10 )
sprintf ( buf , " <span size= \" x-small \" > %d</span> " , num ) ;
2026-01-16 17:52:57 -07:00
else
/* 12345678901 23456789 01 23456789 */
sprintf ( buf , " <span size= \" x-small \" >%d</span> " , num ) ;
2026-01-17 23:50:44 -07:00
but = gtk_button_new ( ) ;
label = gtk_label_new ( " " ) ;
gtk_label_set_markup ( GTK_LABEL ( label ) , buf ) ;
box = gtk_event_box_new ( ) ;
gtk_event_box_set_visible_window ( GTK_EVENT_BOX ( box ) , TRUE ) ;
gtk_container_add ( GTK_CONTAINER ( box ) , label ) ;
gtk_container_add ( GTK_CONTAINER ( but ) , box ) ;
alignment = gtk_bin_get_child ( GTK_BIN ( but ) ) ;
if ( GTK_IS_ALIGNMENT ( alignment ) )
{
gtk_alignment_set ( GTK_ALIGNMENT ( alignment ) , 0.5 , 0.5 , 1.0 , 1.0 ) ;
gtk_alignment_set_padding ( GTK_ALIGNMENT ( alignment ) , 0 , 0 , 0 , 0 ) ;
}
gtk_widget_show ( label ) ;
gtk_widget_show ( box ) ;
2026-01-16 17:52:57 -07:00
/* win32 build uses this to turn off themeing */
g_object_set_data ( G_OBJECT ( but ) , " zoitechat-color " , ( gpointer ) 1 ) ;
2026-01-17 23:50:44 -07:00
g_object_set_data ( G_OBJECT ( but ) , " zoitechat-color-box " , box ) ;
2026-01-16 17:52:57 -07:00
gtk_table_attach ( GTK_TABLE ( table ) , but , col , col + 1 , row , row + 1 ,
2026-01-18 01:14:49 -07:00
GTK_SHRINK , GTK_SHRINK , 0 , 0 ) ;
2026-01-16 17:52:57 -07:00
g_signal_connect ( G_OBJECT ( but ) , " clicked " ,
G_CALLBACK ( setup_color_cb ) , GINT_TO_POINTER ( num ) ) ;
2026-01-17 23:50:44 -07:00
setup_color_button_apply ( but , & colors [ num ] ) ;
2026-01-16 17:52:57 -07:00
/* Track all color selector widgets (used for dark mode UI behavior). */
color_selector_widgets = g_slist_prepend ( color_selector_widgets , but ) ;
2011-02-24 04:14:30 +01:00
}
static void
setup_create_other_colorR ( char * text , int num , int row , GtkWidget * tab )
{
2026-01-16 17:52:57 -07:00
GtkWidget * label ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
label = gtk_label_new ( text ) ;
gtk_misc_set_alignment ( GTK_MISC ( label ) , 0.0 , 0.5 ) ;
gtk_table_attach ( GTK_TABLE ( tab ) , label , 5 , 9 , row , row + 1 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , LABEL_INDENT , 0 ) ;
setup_create_color_button ( tab , num , row , 9 ) ;
2011-02-24 04:14:30 +01:00
}
static void
setup_create_other_color ( char * text , int num , int row , GtkWidget * tab )
{
2026-01-16 17:52:57 -07:00
GtkWidget * label ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
label = gtk_label_new ( text ) ;
gtk_misc_set_alignment ( GTK_MISC ( label ) , 0.0 , 0.5 ) ;
gtk_table_attach ( GTK_TABLE ( tab ) , label , 2 , 3 , row , row + 1 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , LABEL_INDENT , 0 ) ;
setup_create_color_button ( tab , num , row , 3 ) ;
2011-02-24 04:14:30 +01:00
}
static GtkWidget *
setup_create_color_page ( void )
{
2026-01-17 23:09:38 -07:00
color_selector_widgets = NULL ;
2026-01-16 17:52:57 -07:00
2026-01-17 23:09:38 -07:00
GtkWidget * tab , * box , * label ;
int i ;
2026-01-16 17:52:57 -07:00
box = gtk_vbox_new ( FALSE , 0 ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( box ) , 6 ) ;
tab = gtk_table_new ( 9 , 2 , FALSE ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( tab ) , 6 ) ;
gtk_table_set_row_spacings ( GTK_TABLE ( tab ) , 2 ) ;
gtk_table_set_col_spacings ( GTK_TABLE ( tab ) , 3 ) ;
gtk_container_add ( GTK_CONTAINER ( box ) , tab ) ;
setup_create_header ( tab , 0 , N_ ( " Text Colors " ) ) ;
2026-01-12 21:24:09 -07:00
2026-01-16 17:52:57 -07:00
label = gtk_label_new ( _ ( " mIRC colors: " ) ) ;
gtk_misc_set_alignment ( GTK_MISC ( label ) , 0.0 , 0.5 ) ;
gtk_table_attach ( GTK_TABLE ( tab ) , label , 2 , 3 , 1 , 2 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , LABEL_INDENT , 0 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
for ( i = 0 ; i < 16 ; i + + )
setup_create_color_button ( tab , i , 1 , i + 3 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
label = gtk_label_new ( _ ( " Local colors: " ) ) ;
gtk_misc_set_alignment ( GTK_MISC ( label ) , 0.0 , 0.5 ) ;
gtk_table_attach ( GTK_TABLE ( tab ) , label , 2 , 3 , 2 , 3 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , LABEL_INDENT , 0 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
for ( i = 16 ; i < 32 ; i + + )
setup_create_color_button ( tab , i , 2 , ( i + 3 ) - 16 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
setup_create_other_color ( _ ( " Foreground: " ) , COL_FG , 3 , tab ) ;
setup_create_other_colorR ( _ ( " Background: " ) , COL_BG , 3 , tab ) ;
setup_create_header ( tab , 5 , N_ ( " Selected Text " ) ) ;
setup_create_other_color ( _ ( " Foreground: " ) , COL_MARK_FG , 6 , tab ) ;
setup_create_other_colorR ( _ ( " Background: " ) , COL_MARK_BG , 6 , tab ) ;
setup_create_header ( tab , 8 , N_ ( " Interface Colors " ) ) ;
setup_create_other_color ( _ ( " New data: " ) , COL_NEW_DATA , 9 , tab ) ;
setup_create_other_colorR ( _ ( " Marker line: " ) , COL_MARKER , 9 , tab ) ;
2026-01-17 23:09:38 -07:00
setup_create_other_color ( _ ( " New message: " ) , COL_NEW_MSG , 10 , tab ) ;
setup_create_other_colorR ( _ ( " Away user: " ) , COL_AWAY , 10 , tab ) ;
setup_create_other_color ( _ ( " Highlight: " ) , COL_HILIGHT , 11 , tab ) ;
setup_create_other_colorR ( _ ( " Spell checker: " ) , COL_SPELL , 11 , tab ) ;
setup_create_dark_mode_menu ( tab , 13 , & dark_mode_setting ) ;
setup_color_selectors_set_sensitive ( TRUE ) ;
setup_create_header ( tab , 15 , N_ ( " Color Stripping " ) ) ;
2026-01-16 17:52:57 -07:00
/* label = gtk_label_new (_("Strip colors from:"));
gtk_misc_set_alignment ( GTK_MISC ( label ) , 0.0 , 0.5 ) ;
gtk_table_attach ( GTK_TABLE ( tab ) , label , 2 , 3 , 16 , 17 ,
GTK_SHRINK | GTK_FILL , GTK_SHRINK | GTK_FILL , LABEL_INDENT , 0 ) ; */
for ( i = 0 ; i < 3 ; i + + )
{
setup_create_toggleL ( tab , i + 16 , & color_settings [ i ] ) ;
}
return box ;
}
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
static void
setup_theme_show_message ( GtkMessageType message_type , const char * primary )
{
GtkWidget * dialog ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
dialog = gtk_message_dialog_new ( GTK_WINDOW ( setup_window ) , GTK_DIALOG_MODAL ,
message_type , GTK_BUTTONS_CLOSE , " %s " , primary ) ;
gtk_dialog_run ( GTK_DIALOG ( dialog ) ) ;
gtk_widget_destroy ( dialog ) ;
}
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
static gboolean
setup_theme_copy_file ( const char * src , const char * dest , GError * * error )
{
GFile * src_file ;
GFile * dest_file ;
gboolean success ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
src_file = g_file_new_for_path ( src ) ;
dest_file = g_file_new_for_path ( dest ) ;
success = g_file_copy ( src_file , dest_file , G_FILE_COPY_OVERWRITE , NULL , NULL , NULL , error ) ;
g_object_unref ( src_file ) ;
g_object_unref ( dest_file ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
return success ;
}
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
static void
setup_theme_populate ( setup_theme_ui * ui )
{
char * themes_dir ;
GDir * dir ;
const char * name ;
GtkTreeModel * model ;
GtkTreeIter iter ;
int count ;
model = gtk_combo_box_get_model ( GTK_COMBO_BOX ( ui - > combo ) ) ;
while ( gtk_tree_model_get_iter_first ( model , & iter ) )
gtk_combo_box_text_remove ( GTK_COMBO_BOX_TEXT ( ui - > combo ) , 0 ) ;
themes_dir = g_build_filename ( get_xdir ( ) , " themes " , NULL ) ;
if ( ! g_file_test ( themes_dir , G_FILE_TEST_IS_DIR ) )
g_mkdir_with_parents ( themes_dir , 0700 ) ;
dir = g_dir_open ( themes_dir , 0 , NULL ) ;
if ( dir )
{
while ( ( name = g_dir_read_name ( dir ) ) )
{
char * path = g_build_filename ( themes_dir , name , NULL ) ;
if ( g_file_test ( path , G_FILE_TEST_IS_DIR ) )
gtk_combo_box_text_append_text ( GTK_COMBO_BOX_TEXT ( ui - > combo ) , name ) ;
g_free ( path ) ;
}
g_dir_close ( dir ) ;
}
count = gtk_tree_model_iter_n_children ( gtk_combo_box_get_model ( GTK_COMBO_BOX ( ui - > combo ) ) , NULL ) ;
if ( count > 0 )
gtk_combo_box_set_active ( GTK_COMBO_BOX ( ui - > combo ) , 0 ) ;
gtk_widget_set_sensitive ( ui - > apply_button , count > 0 ) ;
gtk_label_set_text ( GTK_LABEL ( ui - > status_label ) ,
count > 0 ? _ ( " Select a theme to apply. " ) : _ ( " No themes found. " ) ) ;
g_free ( themes_dir ) ;
}
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
static void
setup_theme_refresh_cb ( GtkWidget * button , gpointer user_data )
{
setup_theme_ui * ui = user_data ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
setup_theme_populate ( ui ) ;
}
2012-09-01 21:38:00 +02:00
2026-01-16 19:26:22 -07:00
static void
setup_theme_open_folder_cb ( GtkWidget * button , gpointer user_data )
{
char * themes_dir ;
themes_dir = g_build_filename ( get_xdir ( ) , " themes " , NULL ) ;
g_mkdir_with_parents ( themes_dir , 0700 ) ;
fe_open_url ( themes_dir ) ;
g_free ( themes_dir ) ;
}
2026-01-16 17:52:57 -07:00
static void
setup_theme_selection_changed ( GtkComboBox * combo , gpointer user_data )
{
setup_theme_ui * ui = user_data ;
gboolean has_selection = gtk_combo_box_get_active ( combo ) > = 0 ;
2012-09-01 21:38:00 +02:00
2026-01-16 17:52:57 -07:00
gtk_widget_set_sensitive ( ui - > apply_button , has_selection ) ;
}
2012-09-01 21:38:00 +02:00
2026-01-16 17:52:57 -07:00
static void
setup_theme_apply_cb ( GtkWidget * button , gpointer user_data )
{
setup_theme_ui * ui = user_data ;
GtkWidget * dialog ;
gint response ;
char * theme ;
char * theme_dir = NULL ;
char * colors_src = NULL ;
char * colors_dest = NULL ;
char * events_src = NULL ;
char * events_dest = NULL ;
GError * error = NULL ;
theme = gtk_combo_box_text_get_active_text ( GTK_COMBO_BOX_TEXT ( ui - > combo ) ) ;
if ( ! theme )
return ;
dialog = gtk_message_dialog_new ( GTK_WINDOW ( setup_window ) , GTK_DIALOG_MODAL ,
GTK_MESSAGE_WARNING , GTK_BUTTONS_OK_CANCEL ,
" %s " , _ ( " Applying a theme will overwrite your current colors and event settings. \n Continue? " ) ) ;
response = gtk_dialog_run ( GTK_DIALOG ( dialog ) ) ;
gtk_widget_destroy ( dialog ) ;
if ( response ! = GTK_RESPONSE_OK )
{
g_free ( theme ) ;
return ;
}
theme_dir = g_build_filename ( get_xdir ( ) , " themes " , theme , NULL ) ;
colors_src = g_build_filename ( theme_dir , " colors.conf " , NULL ) ;
colors_dest = g_build_filename ( get_xdir ( ) , " colors.conf " , NULL ) ;
if ( ! g_file_test ( colors_src , G_FILE_TEST_IS_REGULAR ) )
{
setup_theme_show_message ( GTK_MESSAGE_ERROR , _ ( " This theme is missing a colors.conf file. " ) ) ;
goto cleanup ;
}
if ( ! setup_theme_copy_file ( colors_src , colors_dest , & error ) )
{
setup_theme_show_message ( GTK_MESSAGE_ERROR , error ? error - > message : _ ( " Failed to apply theme. " ) ) ;
g_clear_error ( & error ) ;
goto cleanup ;
}
events_src = g_build_filename ( theme_dir , " pevents.conf " , NULL ) ;
events_dest = g_build_filename ( get_xdir ( ) , " pevents.conf " , NULL ) ;
if ( g_file_test ( events_src , G_FILE_TEST_IS_REGULAR ) )
{
if ( ! setup_theme_copy_file ( events_src , events_dest , & error ) )
{
setup_theme_show_message ( GTK_MESSAGE_ERROR , error ? error - > message : _ ( " Failed to apply event settings. " ) ) ;
g_clear_error ( & error ) ;
goto cleanup ;
}
}
else if ( g_file_test ( events_dest , G_FILE_TEST_EXISTS ) )
{
g_unlink ( events_dest ) ;
}
2026-01-17 23:09:38 -07:00
palette_load ( ) ;
palette_apply_dark_mode ( fe_dark_mode_is_enabled ( ) ) ;
color_change = TRUE ;
2026-01-16 17:52:57 -07:00
setup_apply_real ( 0 , TRUE , FALSE , FALSE ) ;
setup_theme_show_message ( GTK_MESSAGE_INFO , _ ( " Theme applied. Some changes may require a restart to take full effect. " ) ) ;
cleanup :
g_free ( events_dest ) ;
g_free ( events_src ) ;
g_free ( colors_dest ) ;
g_free ( colors_src ) ;
g_free ( theme_dir ) ;
g_free ( theme ) ;
}
static GtkWidget *
setup_create_theme_page ( void )
{
setup_theme_ui * ui ;
GtkWidget * box ;
GtkWidget * label ;
GtkWidget * hbox ;
GtkWidget * button_box ;
char * themes_dir ;
char * markup ;
ui = g_new0 ( setup_theme_ui , 1 ) ;
box = gtk_vbox_new ( FALSE , 6 ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( box ) , 6 ) ;
themes_dir = g_build_filename ( get_xdir ( ) , " themes " , NULL ) ;
markup = g_markup_printf_escaped ( _ ( " Theme files are loaded from <tt>%s</tt>. " ) , themes_dir ) ;
label = gtk_label_new ( NULL ) ;
gtk_label_set_markup ( GTK_LABEL ( label ) , markup ) ;
gtk_label_set_line_wrap ( GTK_LABEL ( label ) , TRUE ) ;
gtk_misc_set_alignment ( GTK_MISC ( label ) , 0.0 , 0.5 ) ;
gtk_box_pack_start ( GTK_BOX ( box ) , label , FALSE , FALSE , 0 ) ;
g_free ( markup ) ;
g_free ( themes_dir ) ;
hbox = gtk_hbox_new ( FALSE , 6 ) ;
gtk_box_pack_start ( GTK_BOX ( box ) , hbox , FALSE , FALSE , 0 ) ;
ui - > combo = gtk_combo_box_text_new ( ) ;
gtk_box_pack_start ( GTK_BOX ( hbox ) , ui - > combo , TRUE , TRUE , 0 ) ;
g_signal_connect ( G_OBJECT ( ui - > combo ) , " changed " ,
G_CALLBACK ( setup_theme_selection_changed ) , ui ) ;
button_box = gtk_hbox_new ( FALSE , 6 ) ;
gtk_box_pack_start ( GTK_BOX ( hbox ) , button_box , FALSE , FALSE , 0 ) ;
ui - > apply_button = gtk_button_new_with_mnemonic ( _ ( " _Apply Theme " ) ) ;
gtk_box_pack_start ( GTK_BOX ( button_box ) , ui - > apply_button , FALSE , FALSE , 0 ) ;
g_signal_connect ( G_OBJECT ( ui - > apply_button ) , " clicked " ,
G_CALLBACK ( setup_theme_apply_cb ) , ui ) ;
label = gtk_button_new_with_mnemonic ( _ ( " _Refresh " ) ) ;
gtk_box_pack_start ( GTK_BOX ( button_box ) , label , FALSE , FALSE , 0 ) ;
g_signal_connect ( G_OBJECT ( label ) , " clicked " ,
G_CALLBACK ( setup_theme_refresh_cb ) , ui ) ;
2026-01-16 19:26:22 -07:00
label = gtk_button_new_with_mnemonic ( _ ( " _Open Folder " ) ) ;
gtk_box_pack_start ( GTK_BOX ( button_box ) , label , FALSE , FALSE , 0 ) ;
g_signal_connect ( G_OBJECT ( label ) , " clicked " ,
G_CALLBACK ( setup_theme_open_folder_cb ) , ui ) ;
2026-01-16 17:52:57 -07:00
ui - > status_label = gtk_label_new ( NULL ) ;
gtk_misc_set_alignment ( GTK_MISC ( ui - > status_label ) , 0.0 , 0.5 ) ;
gtk_box_pack_start ( GTK_BOX ( box ) , ui - > status_label , FALSE , FALSE , 0 ) ;
setup_theme_populate ( ui ) ;
g_object_set_data_full ( G_OBJECT ( box ) , " setup-theme-ui " , ui , g_free ) ;
return box ;
2011-02-24 04:14:30 +01:00
}
/* === GLOBALS for sound GUI === */
static GtkWidget * sndfile_entry ;
static int ignore_changed = FALSE ;
extern struct text_event te [ ] ; /* text.c */
extern char * sound_files [ ] ;
static void
setup_snd_populate ( GtkTreeView * treeview )
{
2026-01-16 17:52:57 -07:00
GtkListStore * store ;
GtkTreeIter iter ;
GtkTreeSelection * sel ;
GtkTreePath * path ;
int i ;
sel = gtk_tree_view_get_selection ( treeview ) ;
store = ( GtkListStore * ) gtk_tree_view_get_model ( treeview ) ;
for ( i = NUM_XP - 1 ; i > = 0 ; i - - )
{
gtk_list_store_prepend ( store , & iter ) ;
if ( sound_files [ i ] )
gtk_list_store_set ( store , & iter , 0 , te [ i ] . name , 1 , sound_files [ i ] , 2 , i , - 1 ) ;
else
gtk_list_store_set ( store , & iter , 0 , te [ i ] . name , 1 , " " , 2 , i , - 1 ) ;
if ( i = = last_selected_row )
{
gtk_tree_selection_select_iter ( sel , & iter ) ;
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 ) ;
}
}
}
2011-02-24 04:14:30 +01:00
}
static int
setup_snd_get_selected ( GtkTreeSelection * sel , GtkTreeIter * iter )
{
2026-01-16 17:52:57 -07:00
int n ;
GtkTreeModel * model ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
if ( ! gtk_tree_selection_get_selected ( sel , & model , iter ) )
return - 1 ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
gtk_tree_model_get ( model , iter , 2 , & n , - 1 ) ;
return n ;
2011-02-24 04:14:30 +01:00
}
static void
setup_snd_row_cb ( GtkTreeSelection * sel , gpointer user_data )
{
2026-01-16 17:52:57 -07:00
int n ;
GtkTreeIter iter ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
n = setup_snd_get_selected ( sel , & iter ) ;
if ( n = = - 1 )
return ;
last_selected_row = n ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
ignore_changed = TRUE ;
if ( sound_files [ n ] )
gtk_entry_set_text ( GTK_ENTRY ( sndfile_entry ) , sound_files [ n ] ) ;
else
gtk_entry_set_text ( GTK_ENTRY ( sndfile_entry ) , " " ) ;
ignore_changed = FALSE ;
2011-02-24 04:14:30 +01:00
}
static void
setup_snd_add_columns ( GtkTreeView * treeview )
{
2026-01-16 17:52:57 -07:00
GtkCellRenderer * renderer ;
GtkTreeModel * model ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
/* event column */
renderer = gtk_cell_renderer_text_new ( ) ;
gtk_tree_view_insert_column_with_attributes ( GTK_TREE_VIEW ( treeview ) ,
- 1 , _ ( " Event " ) , renderer ,
" text " , 0 , NULL ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
/* file column */
renderer = gtk_cell_renderer_text_new ( ) ;
gtk_tree_view_insert_column_with_attributes ( GTK_TREE_VIEW ( treeview ) ,
- 1 , _ ( " Sound file " ) , renderer ,
" text " , 1 , NULL ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
model = GTK_TREE_MODEL ( gtk_list_store_new ( 3 , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_INT ) ) ;
gtk_tree_view_set_model ( GTK_TREE_VIEW ( treeview ) , model ) ;
g_object_unref ( model ) ;
2011-02-24 04:14:30 +01:00
}
static void
setup_snd_filereq_cb ( GtkWidget * entry , char * file )
{
2026-01-16 17:52:57 -07:00
if ( file )
{
if ( file [ 0 ] )
{
/* Use just the filename if the given sound file is in the default <config>/sounds directory.
* We ' re comparing absolute paths so this won ' t work in portable mode which uses a relative path .
*/
if ( ! strcmp ( g_path_get_dirname ( file ) , g_build_filename ( get_xdir ( ) , HEXCHAT_SOUND_DIR , NULL ) ) )
{
gtk_entry_set_text ( GTK_ENTRY ( entry ) , g_path_get_basename ( file ) ) ;
}
else
{
gtk_entry_set_text ( GTK_ENTRY ( entry ) , file ) ;
}
}
}
2011-02-24 04:14:30 +01:00
}
static void
setup_snd_browse_cb ( GtkWidget * button , GtkEntry * entry )
{
2026-01-16 17:52:57 -07:00
char * sounds_dir = g_build_filename ( get_xdir ( ) , HEXCHAT_SOUND_DIR , NULL ) ;
char * filter = NULL ;
int filter_type ;
2013-08-30 20:19:10 -04:00
# ifdef WIN32 /* win32 only supports wav, others could support anything */
2026-01-16 17:52:57 -07:00
filter = " *.wav " ;
filter_type = FRF_EXTENSIONS ;
2013-08-31 15:31:22 -04:00
# else
2026-01-16 17:52:57 -07:00
filter = " audio/* " ;
filter_type = FRF_MIMETYPES ;
2013-08-30 20:19:10 -04:00
# endif
2026-01-16 17:52:57 -07:00
gtkutil_file_req ( GTK_WINDOW ( setup_window ) , _ ( " Select a sound file " ) , setup_snd_filereq_cb , entry ,
sounds_dir , filter , FRF_MODAL | FRF_FILTERISINITIAL | filter_type ) ;
g_free ( sounds_dir ) ;
2011-02-24 04:14:30 +01:00
}
static void
setup_snd_play_cb ( GtkWidget * button , GtkEntry * entry )
{
2026-01-16 17:52:57 -07:00
sound_play ( gtk_entry_get_text ( entry ) , FALSE ) ;
2011-02-24 04:14:30 +01:00
}
static void
setup_snd_changed_cb ( GtkEntry * ent , GtkTreeView * tree )
{
2026-01-16 17:52:57 -07:00
int n ;
GtkTreeIter iter ;
GtkListStore * store ;
GtkTreeSelection * sel ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
if ( ignore_changed )
return ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
sel = gtk_tree_view_get_selection ( tree ) ;
n = setup_snd_get_selected ( sel , & iter ) ;
if ( n = = - 1 )
return ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
/* get the new sound file */
g_free ( sound_files [ n ] ) ;
sound_files [ n ] = g_strdup ( gtk_entry_get_text ( GTK_ENTRY ( ent ) ) ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
/* update the TreeView list */
store = ( GtkListStore * ) gtk_tree_view_get_model ( tree ) ;
gtk_list_store_set ( store , & iter , 1 , sound_files [ n ] , - 1 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
gtk_widget_set_sensitive ( cancel_button , FALSE ) ;
2011-02-24 04:14:30 +01:00
}
static GtkWidget *
setup_create_sound_page ( void )
{
2026-01-16 17:52:57 -07:00
GtkWidget * vbox1 ;
GtkWidget * vbox2 ;
GtkWidget * scrolledwindow1 ;
GtkWidget * sound_tree ;
GtkWidget * table1 ;
GtkWidget * sound_label ;
GtkWidget * sound_browse ;
GtkWidget * sound_play ;
GtkTreeSelection * sel ;
vbox1 = gtk_vbox_new ( FALSE , 0 ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( vbox1 ) , 6 ) ;
gtk_widget_show ( vbox1 ) ;
vbox2 = gtk_vbox_new ( FALSE , 0 ) ;
gtk_widget_show ( vbox2 ) ;
gtk_container_add ( GTK_CONTAINER ( vbox1 ) , vbox2 ) ;
scrolledwindow1 = gtk_scrolled_window_new ( NULL , NULL ) ;
gtk_widget_show ( scrolledwindow1 ) ;
gtk_container_add ( GTK_CONTAINER ( vbox2 ) , scrolledwindow1 ) ;
gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW ( scrolledwindow1 ) ,
GTK_POLICY_AUTOMATIC , GTK_POLICY_ALWAYS ) ;
gtk_scrolled_window_set_shadow_type ( GTK_SCROLLED_WINDOW ( scrolledwindow1 ) ,
GTK_SHADOW_IN ) ;
sound_tree = gtk_tree_view_new ( ) ;
sel = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( sound_tree ) ) ;
gtk_tree_selection_set_mode ( sel , GTK_SELECTION_SINGLE ) ;
setup_snd_add_columns ( GTK_TREE_VIEW ( sound_tree ) ) ;
setup_snd_populate ( GTK_TREE_VIEW ( sound_tree ) ) ;
g_signal_connect ( G_OBJECT ( sel ) , " changed " ,
G_CALLBACK ( setup_snd_row_cb ) , NULL ) ;
gtk_widget_show ( sound_tree ) ;
gtk_container_add ( GTK_CONTAINER ( scrolledwindow1 ) , sound_tree ) ;
gtk_tree_view_set_rules_hint ( GTK_TREE_VIEW ( sound_tree ) , TRUE ) ;
table1 = gtk_table_new ( 2 , 3 , FALSE ) ;
gtk_widget_show ( table1 ) ;
gtk_box_pack_start ( GTK_BOX ( vbox2 ) , table1 , FALSE , TRUE , 8 ) ;
gtk_table_set_row_spacings ( GTK_TABLE ( table1 ) , 2 ) ;
gtk_table_set_col_spacings ( GTK_TABLE ( table1 ) , 4 ) ;
sound_label = gtk_label_new_with_mnemonic ( _ ( " Sound file: " ) ) ;
gtk_widget_show ( sound_label ) ;
gtk_table_attach ( GTK_TABLE ( table1 ) , sound_label , 0 , 1 , 0 , 1 ,
( GtkAttachOptions ) ( GTK_FILL ) ,
( GtkAttachOptions ) ( 0 ) , 0 , 0 ) ;
gtk_misc_set_alignment ( GTK_MISC ( sound_label ) , 0 , 0.5 ) ;
sndfile_entry = gtk_entry_new ( ) ;
g_signal_connect ( G_OBJECT ( sndfile_entry ) , " changed " ,
G_CALLBACK ( setup_snd_changed_cb ) , sound_tree ) ;
gtk_widget_show ( sndfile_entry ) ;
gtk_table_attach ( GTK_TABLE ( table1 ) , sndfile_entry , 0 , 1 , 1 , 2 ,
( GtkAttachOptions ) ( GTK_EXPAND | GTK_FILL ) ,
( GtkAttachOptions ) ( 0 ) , 0 , 0 ) ;
sound_browse = gtk_button_new_with_mnemonic ( _ ( " _Browse... " ) ) ;
g_signal_connect ( G_OBJECT ( sound_browse ) , " clicked " ,
G_CALLBACK ( setup_snd_browse_cb ) , sndfile_entry ) ;
gtk_widget_show ( sound_browse ) ;
gtk_table_attach ( GTK_TABLE ( table1 ) , sound_browse , 1 , 2 , 1 , 2 ,
( GtkAttachOptions ) ( GTK_FILL ) ,
( GtkAttachOptions ) ( 0 ) , 0 , 0 ) ;
2011-02-24 04:14:30 +01:00
# ifdef GTK_STOCK_MEDIA_PLAY
2026-01-16 17:52:57 -07:00
sound_play = gtk_button_new_from_stock ( GTK_STOCK_MEDIA_PLAY ) ;
2011-02-24 04:14:30 +01:00
# else
2026-01-16 17:52:57 -07:00
sound_play = gtk_button_new_with_mnemonic ( _ ( " _Play " ) ) ;
2011-02-24 04:14:30 +01:00
# endif
2026-01-16 17:52:57 -07:00
g_signal_connect ( G_OBJECT ( sound_play ) , " clicked " ,
G_CALLBACK ( setup_snd_play_cb ) , sndfile_entry ) ;
gtk_widget_show ( sound_play ) ;
gtk_table_attach ( GTK_TABLE ( table1 ) , sound_play , 2 , 3 , 1 , 2 ,
( GtkAttachOptions ) ( GTK_FILL ) ,
( GtkAttachOptions ) ( 0 ) , 0 , 0 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
setup_snd_row_cb ( sel , NULL ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
return vbox1 ;
2011-02-24 04:14:30 +01:00
}
static void
setup_add_page ( const char * title , GtkWidget * book , GtkWidget * tab )
{
2026-01-16 17:52:57 -07:00
GtkWidget * label , * vvbox , * viewport ;
GtkScrolledWindow * sw ;
char buf [ 128 ] ;
vvbox = gtk_vbox_new ( FALSE , 0 ) ;
/* label */
label = gtk_label_new ( NULL ) ;
g_snprintf ( buf , sizeof ( buf ) , " <b><big>%s</big></b> " , _ ( title ) ) ;
gtk_label_set_markup ( GTK_LABEL ( label ) , buf ) ;
gtk_misc_set_alignment ( GTK_MISC ( label ) , 0.0 , 0.5 ) ;
gtk_misc_set_padding ( GTK_MISC ( label ) , 2 , 1 ) ;
gtk_box_pack_start ( GTK_BOX ( vvbox ) , label , FALSE , FALSE , 2 ) ;
gtk_container_add ( GTK_CONTAINER ( vvbox ) , tab ) ;
sw = GTK_SCROLLED_WINDOW ( gtk_scrolled_window_new ( NULL , NULL ) ) ;
gtk_scrolled_window_set_shadow_type ( sw , GTK_SHADOW_IN ) ;
gtk_scrolled_window_set_policy ( sw , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC ) ;
gtk_scrolled_window_add_with_viewport ( sw , vvbox ) ;
viewport = gtk_bin_get_child ( GTK_BIN ( sw ) ) ;
gtk_viewport_set_shadow_type ( GTK_VIEWPORT ( viewport ) , GTK_SHADOW_NONE ) ;
gtk_notebook_append_page ( GTK_NOTEBOOK ( book ) , GTK_WIDGET ( sw ) , NULL ) ;
}
static const char * const cata_interface [ ] =
{
N_ ( " Appearance " ) ,
N_ ( " Input box " ) ,
N_ ( " User list " ) ,
N_ ( " Channel switcher " ) ,
N_ ( " Themes " ) ,
N_ ( " Colors " ) ,
NULL
} ;
static const char * const cata_chatting [ ] =
{
N_ ( " General " ) ,
N_ ( " Alerts " ) ,
N_ ( " Sounds " ) ,
N_ ( " Logging " ) ,
N_ ( " Advanced " ) ,
NULL
} ;
static const char * const cata_network [ ] =
{
N_ ( " Network setup " ) ,
N_ ( " File transfers " ) ,
N_ ( " Identd " ) ,
NULL
2011-02-24 04:14:30 +01:00
} ;
static GtkWidget *
setup_create_pages ( GtkWidget * box )
{
2026-01-16 17:52:57 -07:00
GtkWidget * book ;
GtkWindow * win = GTK_WINDOW ( gtk_widget_get_toplevel ( box ) ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
book = gtk_notebook_new ( ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
setup_add_page ( cata_interface [ 0 ] , book , setup_create_page ( appearance_settings ) ) ;
setup_add_page ( cata_interface [ 1 ] , book , setup_create_page ( inputbox_settings ) ) ;
setup_add_page ( cata_interface [ 2 ] , book , setup_create_page ( userlist_settings ) ) ;
setup_add_page ( cata_interface [ 3 ] , book , setup_create_page ( tabs_settings ) ) ;
setup_add_page ( cata_interface [ 4 ] , book , setup_create_theme_page ( ) ) ;
setup_add_page ( cata_interface [ 5 ] , book , setup_create_color_page ( ) ) ;
2011-02-28 18:59:32 +01:00
2026-01-16 17:52:57 -07:00
setup_add_page ( cata_chatting [ 0 ] , book , setup_create_page ( general_settings ) ) ;
2013-04-28 04:57:01 +02:00
2026-01-16 17:52:57 -07:00
if ( ! gtkutil_tray_icon_supported ( win ) & & ! notification_backend_supported ( ) )
{
setup_add_page ( cata_chatting [ 1 ] , book , setup_create_page ( alert_settings_unityandnonotifications ) ) ;
}
else if ( ! gtkutil_tray_icon_supported ( win ) )
{
setup_add_page ( cata_chatting [ 1 ] , book , setup_create_page ( alert_settings_unity ) ) ;
}
else if ( ! notification_backend_supported ( ) )
{
setup_add_page ( cata_chatting [ 1 ] , book , setup_create_page ( alert_settings_nonotifications ) ) ;
}
else
{
setup_add_page ( cata_chatting [ 1 ] , book , setup_create_page ( alert_settings ) ) ;
}
2011-02-28 18:59:32 +01:00
2026-01-16 17:52:57 -07:00
setup_add_page ( cata_chatting [ 2 ] , book , setup_create_sound_page ( ) ) ;
setup_add_page ( cata_chatting [ 3 ] , book , setup_create_page ( logging_settings ) ) ;
setup_add_page ( cata_chatting [ 4 ] , book , setup_create_page ( advanced_settings ) ) ;
2011-11-25 10:10:11 +01:00
2026-01-16 17:52:57 -07:00
setup_add_page ( cata_network [ 0 ] , book , setup_create_page ( network_settings ) ) ;
setup_add_page ( cata_network [ 1 ] , book , setup_create_page ( filexfer_settings ) ) ;
setup_add_page ( cata_network [ 2 ] , book , setup_create_page ( identd_settings ) ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
gtk_notebook_set_show_tabs ( GTK_NOTEBOOK ( book ) , FALSE ) ;
gtk_notebook_set_show_border ( GTK_NOTEBOOK ( book ) , FALSE ) ;
gtk_container_add ( GTK_CONTAINER ( box ) , book ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
return book ;
2011-02-24 04:14:30 +01:00
}
static void
setup_tree_cb ( GtkTreeView * treeview , GtkWidget * book )
{
2026-01-16 17:52:57 -07:00
GtkTreeSelection * selection = gtk_tree_view_get_selection ( treeview ) ;
GtkTreeIter iter ;
GtkTreeModel * model ;
int page ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
if ( gtk_tree_selection_get_selected ( selection , & model , & iter ) )
{
gtk_tree_model_get ( model , & iter , 1 , & page , - 1 ) ;
if ( page ! = - 1 )
{
gtk_notebook_set_current_page ( GTK_NOTEBOOK ( book ) , page ) ;
last_selected_page = page ;
}
}
2011-02-24 04:14:30 +01:00
}
static gboolean
setup_tree_select_filter ( GtkTreeSelection * selection , GtkTreeModel * model ,
2026-01-16 17:52:57 -07:00
GtkTreePath * path , gboolean path_selected ,
gpointer data )
2011-02-24 04:14:30 +01:00
{
2026-01-16 17:52:57 -07:00
if ( gtk_tree_path_get_depth ( path ) > 1 )
return TRUE ;
return FALSE ;
2011-02-24 04:14:30 +01:00
}
static void
setup_create_tree ( GtkWidget * box , GtkWidget * book )
{
2026-01-16 17:52:57 -07:00
GtkWidget * tree ;
GtkWidget * frame ;
GtkTreeStore * model ;
GtkTreeIter iter ;
GtkTreeIter child_iter ;
GtkTreeIter * sel_iter = NULL ;
GtkCellRenderer * renderer ;
GtkTreeSelection * sel ;
int i , page ;
model = gtk_tree_store_new ( 2 , G_TYPE_STRING , G_TYPE_INT ) ;
page = 0 ;
gtk_tree_store_append ( model , & iter , NULL ) ;
gtk_tree_store_set ( model , & iter , 0 , _ ( " Interface " ) , 1 , - 1 , - 1 ) ;
for ( i = 0 ; cata_interface [ i ] ; i + + )
{
gtk_tree_store_append ( model , & child_iter , & iter ) ;
gtk_tree_store_set ( model , & child_iter , 0 , _ ( cata_interface [ i ] ) , 1 , page , - 1 ) ;
if ( page = = last_selected_page )
sel_iter = gtk_tree_iter_copy ( & child_iter ) ;
page + + ;
}
gtk_tree_store_append ( model , & iter , NULL ) ;
gtk_tree_store_set ( model , & iter , 0 , _ ( " Chatting " ) , 1 , - 1 , - 1 ) ;
for ( i = 0 ; cata_chatting [ i ] ; i + + )
{
gtk_tree_store_append ( model , & child_iter , & iter ) ;
gtk_tree_store_set ( model , & child_iter , 0 , _ ( cata_chatting [ i ] ) , 1 , page , - 1 ) ;
if ( page = = last_selected_page )
sel_iter = gtk_tree_iter_copy ( & child_iter ) ;
page + + ;
}
gtk_tree_store_append ( model , & iter , NULL ) ;
gtk_tree_store_set ( model , & iter , 0 , _ ( " Network " ) , 1 , - 1 , - 1 ) ;
for ( i = 0 ; cata_network [ i ] ; i + + )
{
gtk_tree_store_append ( model , & child_iter , & iter ) ;
gtk_tree_store_set ( model , & child_iter , 0 , _ ( cata_network [ i ] ) , 1 , page , - 1 ) ;
if ( page = = last_selected_page )
sel_iter = gtk_tree_iter_copy ( & child_iter ) ;
page + + ;
}
tree = gtk_tree_view_new_with_model ( GTK_TREE_MODEL ( model ) ) ;
g_object_unref ( G_OBJECT ( model ) ) ;
sel = gtk_tree_view_get_selection ( GTK_TREE_VIEW ( tree ) ) ;
gtk_tree_selection_set_mode ( sel , GTK_SELECTION_BROWSE ) ;
gtk_tree_selection_set_select_function ( sel , setup_tree_select_filter ,
NULL , NULL ) ;
g_signal_connect ( G_OBJECT ( tree ) , " cursor_changed " ,
G_CALLBACK ( setup_tree_cb ) , book ) ;
renderer = gtk_cell_renderer_text_new ( ) ;
gtk_tree_view_insert_column_with_attributes ( GTK_TREE_VIEW ( tree ) ,
- 1 , _ ( " Categories " ) , renderer , " text " , 0 , NULL ) ;
gtk_tree_view_expand_all ( GTK_TREE_VIEW ( tree ) ) ;
frame = gtk_frame_new ( NULL ) ;
gtk_container_add ( GTK_CONTAINER ( frame ) , tree ) ;
gtk_box_pack_start ( GTK_BOX ( box ) , frame , 0 , 0 , 0 ) ;
gtk_box_reorder_child ( GTK_BOX ( box ) , frame , 0 ) ;
if ( sel_iter )
{
gtk_tree_selection_select_iter ( sel , sel_iter ) ;
gtk_tree_iter_free ( sel_iter ) ;
}
2011-02-24 04:14:30 +01:00
}
static void
setup_apply_entry_style ( GtkWidget * entry )
{
2026-01-19 22:50:17 -07:00
# if GTK_CHECK_VERSION(3,0,0)
gtk_widget_override_background_color ( entry , GTK_STATE_FLAG_NORMAL , & colors [ COL_BG ] ) ;
gtk_widget_override_color ( entry , GTK_STATE_FLAG_NORMAL , & colors [ COL_FG ] ) ;
gtk_widget_override_font ( entry , input_style - > font_desc ) ;
# else
2026-01-16 17:52:57 -07:00
gtk_widget_modify_base ( entry , GTK_STATE_NORMAL , & colors [ COL_BG ] ) ;
gtk_widget_modify_text ( entry , GTK_STATE_NORMAL , & colors [ COL_FG ] ) ;
gtk_widget_modify_font ( entry , input_style - > font_desc ) ;
2026-01-19 22:50:17 -07:00
# endif
2011-02-24 04:14:30 +01:00
}
static void
setup_apply_to_sess ( session_gui * gui )
{
2026-01-16 17:52:57 -07:00
mg_update_xtext ( gui - > xtext ) ;
chanview_apply_theme ( ( chanview * ) gui - > chanview ) ;
if ( prefs . hex_gui_ulist_style )
2026-01-17 18:31:04 -07:00
gtk_widget_modify_font ( gui - > user_tree , input_style - > font_desc ) ;
2026-01-16 17:52:57 -07:00
2026-01-19 22:50:17 -07:00
# if GTK_CHECK_VERSION(3,0,0)
if ( prefs . hex_gui_ulist_style | | fe_dark_mode_is_enabled ( ) )
{
gtk_widget_override_background_color ( gui - > user_tree , GTK_STATE_FLAG_NORMAL , & colors [ COL_BG ] ) ;
if ( fe_dark_mode_is_enabled ( ) )
gtk_widget_override_color ( gui - > user_tree , GTK_STATE_FLAG_NORMAL , & colors [ COL_FG ] ) ;
else
gtk_widget_override_color ( gui - > user_tree , GTK_STATE_FLAG_NORMAL , NULL ) ;
}
else
{
gtk_widget_override_background_color ( gui - > user_tree , GTK_STATE_FLAG_NORMAL , NULL ) ;
gtk_widget_override_color ( gui - > user_tree , GTK_STATE_FLAG_NORMAL , NULL ) ;
}
# else
if ( prefs . hex_gui_ulist_style | | fe_dark_mode_is_enabled ( ) )
2026-01-17 23:09:38 -07:00
{
gtk_widget_modify_base ( gui - > user_tree , GTK_STATE_NORMAL , & colors [ COL_BG ] ) ;
if ( fe_dark_mode_is_enabled ( ) )
gtk_widget_modify_text ( gui - > user_tree , GTK_STATE_NORMAL , & colors [ COL_FG ] ) ;
else
gtk_widget_modify_text ( gui - > user_tree , GTK_STATE_NORMAL , NULL ) ;
2026-01-16 17:52:57 -07:00
}
else
{
gtk_widget_modify_base ( gui - > user_tree , GTK_STATE_NORMAL , NULL ) ;
gtk_widget_modify_text ( gui - > user_tree , GTK_STATE_NORMAL , NULL ) ;
}
2026-01-19 22:50:17 -07:00
# endif
2026-01-16 17:52:57 -07:00
if ( prefs . hex_gui_input_style )
{
2026-01-19 22:50:17 -07:00
# if GTK_CHECK_VERSION(3,0,0)
char buf [ 128 ] ;
GtkCssProvider * provider = gtk_css_provider_new ( ) ;
GtkStyleContext * context ;
2026-01-22 22:25:26 -07:00
char * color_string = gdk_rgba_to_string ( & colors [ COL_FG ] ) ;
2026-01-19 22:50:17 -07:00
2026-01-22 22:25:26 -07:00
g_snprintf ( buf , sizeof ( buf ) , " .zoitechat-inputbox { caret-color: %s; } " ,
color_string ) ;
2026-01-19 22:50:17 -07:00
gtk_css_provider_load_from_data ( provider , buf , - 1 , NULL ) ;
2026-01-22 22:25:26 -07:00
g_free ( color_string ) ;
2026-01-19 22:50:17 -07:00
context = gtk_widget_get_style_context ( gui - > input_box ) ;
gtk_style_context_add_provider ( context , GTK_STYLE_PROVIDER ( provider ) ,
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION ) ;
context = gtk_widget_get_style_context ( gui - > limit_entry ) ;
gtk_style_context_add_provider ( context , GTK_STYLE_PROVIDER ( provider ) ,
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION ) ;
context = gtk_widget_get_style_context ( gui - > key_entry ) ;
gtk_style_context_add_provider ( context , GTK_STYLE_PROVIDER ( provider ) ,
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION ) ;
context = gtk_widget_get_style_context ( gui - > topic_entry ) ;
gtk_style_context_add_provider ( context , GTK_STYLE_PROVIDER ( provider ) ,
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION ) ;
g_object_unref ( provider ) ;
# else
2026-01-16 17:52:57 -07:00
extern char cursor_color_rc [ ] ;
char buf [ 256 ] ;
sprintf ( buf , cursor_color_rc ,
( colors [ COL_FG ] . red > > 8 ) ,
( colors [ COL_FG ] . green > > 8 ) ,
( colors [ COL_FG ] . blue > > 8 ) ) ;
gtk_rc_parse_string ( buf ) ;
2026-01-19 22:50:17 -07:00
# endif
2026-01-16 17:52:57 -07:00
setup_apply_entry_style ( gui - > input_box ) ;
setup_apply_entry_style ( gui - > limit_entry ) ;
setup_apply_entry_style ( gui - > key_entry ) ;
setup_apply_entry_style ( gui - > topic_entry ) ;
}
if ( prefs . hex_gui_ulist_buttons )
gtk_widget_show ( gui - > button_box ) ;
else
gtk_widget_hide ( gui - > button_box ) ;
/* update active languages */
sexy_spell_entry_deactivate_language ( ( SexySpellEntry * ) gui - > input_box , NULL ) ;
sexy_spell_entry_activate_default_languages ( ( SexySpellEntry * ) gui - > input_box ) ;
sexy_spell_entry_set_checked ( ( SexySpellEntry * ) gui - > input_box , prefs . hex_gui_input_spell ) ;
sexy_spell_entry_set_parse_attributes ( ( SexySpellEntry * ) gui - > input_box , prefs . hex_gui_input_attr ) ;
2011-02-24 04:14:30 +01:00
}
static void
unslash ( char * dir )
{
2026-01-16 17:52:57 -07:00
if ( dir [ 0 ] )
{
int len = strlen ( dir ) - 1 ;
2011-02-24 04:14:30 +01:00
# ifdef WIN32
2026-01-16 17:52:57 -07:00
if ( dir [ len ] = = ' / ' | | dir [ len ] = = ' \\ ' )
2011-02-24 04:14:30 +01:00
# else
2026-01-16 17:52:57 -07:00
if ( dir [ len ] = = ' / ' )
2011-02-24 04:14:30 +01:00
# endif
2026-01-16 17:52:57 -07:00
dir [ len ] = 0 ;
}
2011-02-24 04:14:30 +01:00
}
void
2016-01-25 21:01:56 -05:00
setup_apply_real ( int new_pix , int do_ulist , int do_layout , int do_identd )
2011-02-24 04:14:30 +01:00
{
2026-01-16 17:52:57 -07:00
GSList * list ;
session * sess ;
int done_main = FALSE ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
/* remove trailing slashes */
unslash ( prefs . hex_dcc_dir ) ;
unslash ( prefs . hex_dcc_completed_dir ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
g_mkdir ( prefs . hex_dcc_dir , 0700 ) ;
g_mkdir ( prefs . hex_dcc_completed_dir , 0700 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
if ( new_pix )
{
if ( channelwin_pix )
2026-01-17 18:19:00 -07:00
cairo_surface_destroy ( channelwin_pix ) ;
2026-01-16 17:52:57 -07:00
channelwin_pix = pixmap_load_from_file ( prefs . hex_text_background ) ;
}
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
input_style = create_input_style ( input_style ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
list = sess_list ;
while ( list )
{
sess = list - > data ;
if ( sess - > gui - > is_tab )
{
/* only apply to main tabwindow once */
if ( ! done_main )
{
done_main = TRUE ;
setup_apply_to_sess ( sess - > gui ) ;
}
} else
{
setup_apply_to_sess ( sess - > gui ) ;
}
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
log_open_or_close ( sess ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
if ( do_ulist )
userlist_rehash ( sess ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
list = list - > next ;
}
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
mg_apply_setup ( ) ;
tray_apply_setup ( ) ;
zoitechat_reinit_timers ( ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
if ( do_layout )
menu_change_layout ( ) ;
2016-01-25 21:01:56 -05:00
2026-01-16 17:52:57 -07:00
if ( do_identd )
handle_command ( current_sess , " IDENTD reload " , FALSE ) ;
2011-02-24 04:14:30 +01:00
}
static void
2026-01-05 23:12:38 -07:00
setup_apply ( struct zoitechatprefs * pr )
2011-02-24 04:14:30 +01:00
{
2012-02-15 22:56:52 +01:00
# ifdef WIN32
2026-01-16 17:52:57 -07:00
PangoFontDescription * old_desc ;
PangoFontDescription * new_desc ;
char buffer [ 4 * FONTNAMELEN + 1 ] ;
2012-02-15 22:56:52 +01:00
# endif
2026-01-16 17:52:57 -07:00
int new_pix = FALSE ;
int noapply = FALSE ;
int do_ulist = FALSE ;
int do_layout = FALSE ;
int do_identd = FALSE ;
int old_dark_mode = prefs . hex_gui_dark_mode ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
if ( strcmp ( pr - > hex_text_background , prefs . hex_text_background ) ! = 0 )
new_pix = TRUE ;
2011-02-24 04:14:30 +01:00
# define DIFF(a) (pr->a != prefs.a)
2012-10-18 16:34:40 +02:00
# ifdef WIN32
2026-01-16 17:52:57 -07:00
if ( DIFF ( hex_gui_lang ) )
noapply = TRUE ;
2012-10-18 16:34:40 +02:00
# endif
2026-01-16 17:52:57 -07:00
if ( DIFF ( hex_gui_compact ) )
noapply = TRUE ;
if ( DIFF ( hex_gui_input_icon ) )
noapply = TRUE ;
if ( DIFF ( hex_gui_input_nick ) )
noapply = TRUE ;
if ( DIFF ( hex_gui_lagometer ) )
noapply = TRUE ;
if ( DIFF ( hex_gui_tab_icons ) )
noapply = TRUE ;
if ( DIFF ( hex_gui_tab_server ) )
noapply = TRUE ;
if ( DIFF ( hex_gui_tab_small ) )
noapply = TRUE ;
if ( DIFF ( hex_gui_tab_sort ) )
noapply = TRUE ;
if ( DIFF ( hex_gui_tab_trunc ) )
noapply = TRUE ;
if ( DIFF ( hex_gui_throttlemeter ) )
noapply = TRUE ;
if ( DIFF ( hex_gui_ulist_count ) )
noapply = TRUE ;
if ( DIFF ( hex_gui_ulist_icons ) )
noapply = TRUE ;
if ( DIFF ( hex_gui_ulist_show_hosts ) )
noapply = TRUE ;
if ( DIFF ( hex_gui_ulist_style ) )
noapply = TRUE ;
if ( DIFF ( hex_gui_ulist_sort ) )
noapply = TRUE ;
if ( DIFF ( hex_gui_input_style ) & & prefs . hex_gui_input_style = = TRUE )
noapply = TRUE ; /* Requires restart to *disable* */
if ( DIFF ( hex_gui_tab_dots ) )
do_layout = TRUE ;
if ( DIFF ( hex_gui_tab_layout ) )
do_layout = TRUE ;
if ( DIFF ( hex_identd_server ) | | DIFF ( hex_identd_port ) )
do_identd = TRUE ;
if ( color_change | | ( DIFF ( hex_gui_ulist_color ) ) | | ( DIFF ( hex_away_size_max ) ) | | ( DIFF ( hex_away_track ) ) )
do_ulist = TRUE ;
if ( ( pr - > hex_gui_tab_pos = = 5 | | pr - > hex_gui_tab_pos = = 6 ) & &
pr - > hex_gui_tab_layout = = 2 & & pr - > hex_gui_tab_pos ! = prefs . hex_gui_tab_pos )
fe_message ( _ ( " You cannot place the tree on the top or bottom! \n "
" Please change to the <b>Tabs</b> layout in the <b>View</b> "
" menu first. " ) ,
FE_MSG_WARN | FE_MSG_MARKUP ) ;
/* format cannot be blank, there is already a setting for this */
if ( pr - > hex_stamp_text_format [ 0 ] = = 0 )
{
pr - > hex_stamp_text = 0 ;
strcpy ( pr - > hex_stamp_text_format , prefs . hex_stamp_text_format ) ;
}
memcpy ( & prefs , pr , sizeof ( prefs ) ) ;
/*
* " Dark mode " applies ZoiteChat ' s built - in dark palette to the chat views .
*
* IMPORTANT : don ' t short - circuit this call .
2026-01-17 23:09:38 -07:00
* We MUST run palette_apply_dark_mode ( ) when the setting changes , otherwise
* the preference flips but the palette stays the same ( aka : " nothing happens " ) .
*/
{
gboolean pal_changed = palette_apply_dark_mode ( fe_dark_mode_is_enabled_for ( prefs . hex_gui_dark_mode ) ) ;
if ( prefs . hex_gui_dark_mode ! = old_dark_mode | | pal_changed )
color_change = TRUE ;
}
if ( prefs . hex_gui_dark_mode = = ZOITECHAT_DARK_MODE_AUTO )
fe_set_auto_dark_mode_state ( fe_dark_mode_is_enabled_for ( ZOITECHAT_DARK_MODE_AUTO ) ) ;
2026-01-11 12:02:58 -07:00
2012-02-16 17:21:15 +01:00
# ifdef WIN32
2026-01-16 17:52:57 -07:00
/* merge hex_font_main and hex_font_alternative into hex_font_normal */
old_desc = pango_font_description_from_string ( prefs . hex_text_font_main ) ;
sprintf ( buffer , " %s,%s " , pango_font_description_get_family ( old_desc ) , prefs . hex_text_font_alternative ) ;
new_desc = pango_font_description_from_string ( buffer ) ;
pango_font_description_set_weight ( new_desc , pango_font_description_get_weight ( old_desc ) ) ;
pango_font_description_set_style ( new_desc , pango_font_description_get_style ( old_desc ) ) ;
pango_font_description_set_size ( new_desc , pango_font_description_get_size ( old_desc ) ) ;
sprintf ( prefs . hex_text_font , " %s " , pango_font_description_to_string ( new_desc ) ) ;
/* FIXME this is not required after pango_font_description_from_string()
g_free ( old_desc ) ;
g_free ( new_desc ) ;
*/
2012-02-15 22:56:52 +01:00
# endif
2026-01-16 17:52:57 -07:00
if ( prefs . hex_irc_real_name [ 0 ] = = 0 )
{
fe_message ( _ ( " The Real name option cannot be left blank. Falling back to \" realname \" . " ) , FE_MSG_WARN ) ;
strcpy ( prefs . hex_irc_real_name , " realname " ) ;
}
setup_apply_real ( new_pix , do_ulist , do_layout , do_identd ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
if ( noapply )
fe_message ( _ ( " Some settings were changed that require a "
" restart to take full effect. " ) , FE_MSG_WARN ) ;
2011-02-24 04:14:30 +01:00
# ifndef WIN32
2026-01-16 17:52:57 -07:00
if ( prefs . hex_dcc_auto_recv = = 2 ) /* Auto */
{
if ( ! strcmp ( ( char * ) g_get_home_dir ( ) , prefs . hex_dcc_dir ) )
{
fe_message ( _ ( " *WARNING* \n "
" Auto accepting DCC to your home directory \n "
" can be dangerous and is exploitable. Eg: \n "
" Someone could send you a .bash_profile " ) , FE_MSG_WARN ) ;
}
}
2011-02-24 04:14:30 +01:00
# endif
}
static void
setup_ok_cb ( GtkWidget * but , GtkWidget * win )
{
2026-01-16 17:52:57 -07:00
gtk_widget_destroy ( win ) ;
setup_apply ( & setup_prefs ) ;
save_config ( ) ;
palette_save ( ) ;
2011-02-24 04:14:30 +01:00
}
static GtkWidget *
setup_window_open ( void )
{
2026-01-16 17:52:57 -07:00
GtkWidget * wid , * win , * vbox , * hbox , * hbbox ;
char buf [ 128 ] ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
g_snprintf ( buf , sizeof ( buf ) , _ ( " Preferences - %s " ) , _ ( DISPLAY_NAME ) ) ;
win = gtkutil_window_new ( buf , " prefs " , 0 , 600 , 2 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
vbox = gtk_vbox_new ( FALSE , 5 ) ;
gtk_container_set_border_width ( GTK_CONTAINER ( vbox ) , 6 ) ;
gtk_container_add ( GTK_CONTAINER ( win ) , vbox ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
hbox = gtk_hbox_new ( FALSE , 4 ) ;
gtk_container_add ( GTK_CONTAINER ( vbox ) , hbox ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
setup_create_tree ( hbox , setup_create_pages ( hbox ) ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
/* prepare the button box */
hbbox = gtk_hbutton_box_new ( ) ;
gtk_button_box_set_layout ( GTK_BUTTON_BOX ( hbbox ) , GTK_BUTTONBOX_END ) ;
gtk_box_set_spacing ( GTK_BOX ( hbbox ) , 4 ) ;
gtk_box_pack_end ( GTK_BOX ( vbox ) , hbbox , FALSE , FALSE , 0 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
cancel_button = wid = gtk_button_new_from_stock ( GTK_STOCK_CANCEL ) ;
g_signal_connect ( G_OBJECT ( wid ) , " clicked " ,
G_CALLBACK ( gtkutil_destroy ) , win ) ;
gtk_box_pack_start ( GTK_BOX ( hbbox ) , wid , FALSE , FALSE , 0 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
wid = gtk_button_new_from_stock ( GTK_STOCK_OK ) ;
g_signal_connect ( G_OBJECT ( wid ) , " clicked " ,
G_CALLBACK ( setup_ok_cb ) , win ) ;
gtk_box_pack_start ( GTK_BOX ( hbbox ) , wid , FALSE , FALSE , 0 ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
gtk_widget_show_all ( win ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
return win ;
2011-02-24 04:14:30 +01:00
}
static void
setup_close_cb ( GtkWidget * win , GtkWidget * * swin )
{
2026-01-16 17:52:57 -07:00
* swin = NULL ;
2011-02-24 04:14:30 +01:00
2026-01-17 23:09:38 -07:00
if ( color_selector_widgets )
{
g_slist_free ( color_selector_widgets ) ;
color_selector_widgets = NULL ;
}
2026-01-12 21:24:09 -07:00
2026-01-16 17:52:57 -07:00
if ( font_dialog )
{
gtk_widget_destroy ( font_dialog ) ;
font_dialog = NULL ;
}
2011-02-24 04:14:30 +01:00
}
void
setup_open ( void )
{
2026-01-16 17:52:57 -07:00
if ( setup_window )
{
gtk_window_present ( GTK_WINDOW ( setup_window ) ) ;
return ;
}
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
memcpy ( & setup_prefs , & prefs , sizeof ( prefs ) ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
color_change = FALSE ;
setup_window = setup_window_open ( ) ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
g_signal_connect ( G_OBJECT ( setup_window ) , " destroy " ,
G_CALLBACK ( setup_close_cb ) , & setup_window ) ;
2011-02-24 04:14:30 +01:00
}