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-03-09 14:21:20 -06:00
#include "../common/zoitechat.h"
2026-01-16 17:52:57 -07:00
#include <gio/gio.h>
#include <glib/gstdio.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"
2026-03-02 19:42:48 -07:00
#include "theme/theme-manager.h"
#include "theme/theme-preferences.h"
2011-02-24 04:14:30 +01:00
#include "gtkutil.h"
#include "maingui.h"
#include "pixmaps.h"
#include "menu.h"
2026-03-16 22:45:30 -06:00
#include "preferences-persistence.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"
#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 ;
2011-02-24 04:14:30 +01:00
static GtkWidget * cancel_button ;
static GtkWidget * font_dialog = NULL ;
2026-06-20 04:09:45 -06:00
static GtkWidget * setup_topicbar_multiline_toggle = NULL ;
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 ;
2026-03-27 09:30:27 -06:00
typedef GtkWidget * ( * setup_page_factory ) ( const setting * settings );
#define SETUP_MAX_PAGES 12
static setup_page_factory setup_page_factories [ SETUP_MAX_PAGES ];
static const setting * setup_page_settings [ SETUP_MAX_PAGES ];
static GtkWidget * setup_page_containers [ SETUP_MAX_PAGES ];
static int setup_page_count = 0 ;
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 },
2026-08-31 00:26:18 -06:00
{ ST_TOGGLE , N_ ( "Keep search position when closing" ), P_OFFINTNL ( hex_text_search_keep_position ), 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-06-20 04:48:47 -06:00
{ ST_HEADER , N_ ( "Topic Bar" ), 0 , 0 , 0 },
{ ST_TOGGLE , N_ ( "Place mode buttons beside the topic" ), P_OFFINTNL ( hex_gui_mode_buttons_inline ), 0 , 0 , 0 },
{ ST_TOGGLE , N_ ( "Allow multi-line topics" ), P_OFFINTNL ( hex_gui_topicbar_multiline ), 0 , 0 , 0 },
2026-01-16 17:52:57 -07:00
{ ST_END , 0 , 0 , 0 , 0 , 0 }
2011-02-24 04:14:30 +01:00
};
2026-03-08 10:10:59 -06:00
static const setting appearance_advanced_settings [] =
{
{ ST_HEADER , N_ ( "Advanced" ), 0 , 0 , 0 },
{ ST_EFILE , N_ ( "Background image:" ), P_OFFSETNL ( hex_text_background ), 0 , 0 , sizeof prefs . hex_text_background },
{ ST_HSCALE , N_ ( "Window opacity:" ), P_OFFINTNL ( hex_gui_transparency ), 0 , 0 , 0 },
2026-05-25 09:45:22 -06:00
{ ST_HSCALE , N_ ( "Mouse wheel scroll speed (Slower ← → Faster):" ), P_OFFINTNL ( hex_gui_mouse_scroll_speed ), 0 , 0 , 100 },
2026-03-08 10:10:59 -06: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_ ( "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-08-31 12:20:49 +02:00
{ ST_LABEL , N_ ( "Use language codes (for example, \" en_US \" ). \n On Windows 8 and newer, dictionaries are provided by Windows. 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_ ( "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-02-25 00:55:37 -07:00
N_ ( "Tabs" ),
"" ,
N_ ( "Tree" ),
2026-01-16 17:52:57 -07:00
NULL
2011-02-24 04:14:30 +01:00
};
static const setting tabs_settings [] =
{
2026-01-16 17:52:57 -07:00
{ 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 },
2026-03-31 18:10:28 -06:00
{ ST_TOGGLE , N_ ( "Show close button on tabs" ), P_OFFINTNL ( hex_gui_tab_closebuttons ), 0 , 0 , 0 },
2026-01-16 17:52:57 -07:00
{ 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
};
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 },
2026-04-20 10:38:22 -06:00
{ ST_HEADER , N_ ( "Maximum File Transfer Speeds (KiB/s or MiB/s)" ), 0 , 0 , 0 },
2026-01-16 17:52:57 -07:00
{ 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 },
2026-06-10 15:05:00 -06:00
{ ST_TOGGLE , N_ ( "Hide hostmasks in join and part messages" ), P_OFFINTNL ( hex_irc_hide_join_part_hostmask ), 0 , 0 , 0 },
2026-03-23 14:46:23 -06:00
{ ST_TOGGLE , N_ ( "Enable Ctrl+Q to quit" ), P_OFFINTNL ( hex_gui_ctrlq_quit ), 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 },
2026-05-25 11:43:10 -06:00
{ ST_NUMBER , N_ ( "Lag check interval:" ), P_OFFINTNL ( hex_net_lag_check ), 0 , ( const char ** ) N_ ( "seconds." ), 9999 },
2026-01-16 17:52:57 -07:00
{ 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 },
2026-05-25 11:43:10 -06:00
{ ST_HEADER , N_ ( "Connection Health" ), 0 , 0 , 0 , 0 },
{ ST_NUMBER , N_ ( "TCP keepalive idle:" ), P_OFFINTNL ( hex_net_keepalive_idle ), 0 , ( const char ** ) N_ ( "seconds." ), 7200 },
{ ST_NUMBER , N_ ( "TCP keepalive interval:" ), P_OFFINTNL ( hex_net_keepalive_interval ), 0 , ( const char ** ) N_ ( "seconds." ), 600 },
{ ST_NUMBER , N_ ( "TCP keepalive probes:" ), P_OFFINTNL ( hex_net_keepalive_count ), 0 , 0 , 20 },
2026-01-16 17:52:57 -07:00
{ 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)
2026-01-30 08:30:18 -07:00
typedef enum
{
SETUP_ALIGN_START ,
SETUP_ALIGN_CENTER ,
SETUP_ALIGN_FILL
} setup_align ;
static GtkAlign
setup_align_to_gtk ( setup_align align )
{
switch ( align )
{
case SETUP_ALIGN_FILL :
return GTK_ALIGN_FILL ;
case SETUP_ALIGN_CENTER :
return GTK_ALIGN_CENTER ;
case SETUP_ALIGN_START :
default :
return GTK_ALIGN_START ;
}
}
static void
setup_table_attach ( GtkWidget * table , GtkWidget * child ,
guint left_attach , guint right_attach ,
guint top_attach , guint bottom_attach ,
gboolean hexpand , gboolean vexpand ,
setup_align halign , setup_align valign ,
guint xpad , guint ypad )
{
gtk_widget_set_hexpand ( child , hexpand );
gtk_widget_set_vexpand ( child , vexpand );
gtk_widget_set_halign ( child , setup_align_to_gtk ( halign ));
gtk_widget_set_valign ( child , setup_align_to_gtk ( valign ));
gtk_widget_set_margin_start ( child , xpad );
gtk_widget_set_margin_end ( child , xpad );
gtk_widget_set_margin_top ( child , ypad );
gtk_widget_set_margin_bottom ( child , ypad );
2026-01-30 17:13:44 -07:00
gtk_grid_attach ( GTK_GRID ( table ), child , left_attach , top_attach ,
right_attach - left_attach , bottom_attach - top_attach );
2026-01-30 08:30:18 -07:00
}
2011-02-24 04:14:30 +01:00
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 );
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( label , GTK_ALIGN_START );
gtk_widget_set_valign ( label , GTK_ALIGN_CENTER );
2026-01-30 17:13:44 -07:00
setup_table_attach ( tab , label , col , col + 1 , row , row + 1 , FALSE , FALSE ,
SETUP_ALIGN_START , SETUP_ALIGN_CENTER , 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 ));
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( label , GTK_ALIGN_START );
gtk_widget_set_valign ( label , GTK_ALIGN_CENTER );
2026-01-16 17:52:57 -07:00
if ( set -> tooltip )
{
gtk_widget_set_tooltip_text ( label , _ ( set -> tooltip ));
}
2026-01-30 08:30:18 -07:00
setup_table_attach ( tab , label , 2 , 3 , row , row + 1 , FALSE , FALSE ,
SETUP_ALIGN_START , SETUP_ALIGN_CENTER ,
LABEL_INDENT , 0 );
2026-01-16 17:52:57 -07:00
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 ]);
2026-01-30 17:13:44 -07:00
setup_table_attach ( tab , wid , 3 , 4 , row , row + 1 , FALSE , FALSE ,
SETUP_ALIGN_CENTER , SETUP_ALIGN_CENTER , 0 , 0 );
2026-01-16 17:52:57 -07:00
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 ]);
2026-01-30 17:13:44 -07:00
setup_table_attach ( tab , wid , 4 , 5 , row , row + 1 , FALSE , FALSE ,
SETUP_ALIGN_CENTER , SETUP_ALIGN_CENTER , 0 , 0 );
2026-01-16 17:52:57 -07:00
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 ]);
2026-01-30 17:13:44 -07:00
setup_table_attach ( tab , wid , 5 , 6 , row , row + 1 , FALSE , FALSE ,
SETUP_ALIGN_CENTER , SETUP_ALIGN_CENTER , 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
}
2026-06-20 04:09:45 -06:00
static void
setup_topicbar_inline_toggled_cb ( GtkToggleButton * but , gpointer userdata )
{
( void ) userdata ;
if ( setup_topicbar_multiline_toggle )
gtk_widget_set_sensitive ( setup_topicbar_multiline_toggle ,
! gtk_toggle_button_get_active ( but ));
}
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 ));
2026-01-30 08:30:18 -07:00
setup_table_attach ( tab , wid , 4 , 5 , row , row + 1 , TRUE , FALSE ,
SETUP_ALIGN_FILL , SETUP_ALIGN_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 );
2026-06-20 04:09:45 -06:00
if ( set -> offset == STRUCT_OFFSET_INT ( struct zoitechatprefs , hex_gui_mode_buttons_inline ))
g_signal_connect ( G_OBJECT ( wid ), "toggled" ,
G_CALLBACK ( setup_topicbar_inline_toggled_cb ), NULL );
if ( set -> offset == STRUCT_OFFSET_INT ( struct zoitechatprefs , hex_gui_topicbar_multiline ))
{
setup_topicbar_multiline_toggle = wid ;
gtk_widget_set_sensitive ( wid , ! setup_prefs . hex_gui_mode_buttons_inline );
}
2026-01-16 17:52:57 -07:00
if ( set -> tooltip )
gtk_widget_set_tooltip_text ( wid , _ ( set -> tooltip ));
2026-01-30 08:30:18 -07:00
setup_table_attach ( tab , wid , 2 , row == 6 ? 6 : 4 , row , row + 1 , FALSE , FALSE ,
SETUP_ALIGN_FILL , SETUP_ALIGN_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
}
2026-04-20 10:38:22 -06:00
typedef struct
{
const setting * set ;
GtkSpinButton * spin ;
GtkComboBox * unit ;
} setup_dcc_speed_data ;
static gboolean
setup_is_dcc_speed_setting ( const setting * set )
{
return set -> offset == P_OFFINTNL ( hex_dcc_max_send_cps )
|| set -> offset == P_OFFINTNL ( hex_dcc_max_get_cps )
|| set -> offset == P_OFFINTNL ( hex_dcc_global_max_send_cps )
|| set -> offset == P_OFFINTNL ( hex_dcc_global_max_get_cps );
}
static int
setup_dcc_speed_multiplier ( GtkComboBox * combo )
{
return gtk_combo_box_get_active ( combo ) == 1 ? 1024 * 1024 : 1024 ;
}
static void
setup_dcc_speed_spin_range ( setup_dcc_speed_data * data )
{
int max = data -> set -> extra / setup_dcc_speed_multiplier ( data -> unit );
gtk_spin_button_set_range ( data -> spin , 0 , max > 0 ? max : 0 );
}
static void
setup_dcc_speed_store ( setup_dcc_speed_data * data )
{
int value = gtk_spin_button_get_value_as_int ( data -> spin );
int speed = value * setup_dcc_speed_multiplier ( data -> unit );
if ( speed > data -> set -> extra )
speed = data -> set -> extra ;
setup_set_int ( & setup_prefs , data -> set , speed );
}
static void
setup_dcc_speed_spin_cb ( GtkSpinButton * spin , setup_dcc_speed_data * data )
{
( void ) spin ;
setup_dcc_speed_store ( data );
}
static void
setup_dcc_speed_unit_cb ( GtkComboBox * combo , setup_dcc_speed_data * data )
{
int speed = setup_get_int ( & setup_prefs , data -> set );
int multiplier ;
int value ;
( void ) combo ;
setup_dcc_speed_spin_range ( data );
multiplier = setup_dcc_speed_multiplier ( data -> unit );
value = ( speed + ( multiplier / 2 )) / multiplier ;
gtk_spin_button_set_value ( data -> spin , value );
setup_dcc_speed_store ( data );
}
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-02-04 21:03:04 -07:00
GtkWidget * label , * wid , * rbox ;
2026-01-16 17:52:57 -07:00
char * text ;
2011-02-24 04:14:30 +01:00
2026-01-16 17:52:57 -07:00
label = gtk_label_new ( _ ( set -> label ));
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( label , GTK_ALIGN_START );
gtk_widget_set_valign ( label , GTK_ALIGN_CENTER );
2026-01-30 08:30:18 -07:00
setup_table_attach ( table , label , 2 , 3 , row , row + 1 , FALSE , FALSE ,
SETUP_ALIGN_START , SETUP_ALIGN_CENTER ,
LABEL_INDENT , 0 );
2011-02-24 04:14:30 +01:00
2026-02-05 01:59:15 -07:00
rbox = gtkutil_box_new ( GTK_ORIENTATION_HORIZONTAL , FALSE , 0 );
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( rbox , GTK_ALIGN_START );
gtk_widget_set_valign ( rbox , GTK_ALIGN_CENTER );
2026-01-30 08:30:18 -07:00
setup_table_attach ( table , rbox , 3 , 4 , row , row + 1 , TRUE , FALSE ,
SETUP_ALIGN_FILL , SETUP_ALIGN_FILL , 0 , 0 );
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 ));
2026-04-20 10:38:22 -06:00
if ( setup_is_dcc_speed_setting ( set ))
{
GtkWidget * unit ;
setup_dcc_speed_data * data = g_new0 ( setup_dcc_speed_data , 1 );
int speed = setup_get_int ( & setup_prefs , set );
int use_mib = speed >= ( 1024 * 1024 ) && speed % ( 1024 * 1024 ) == 0 ;
int multiplier ;
data -> set = set ;
data -> spin = GTK_SPIN_BUTTON ( wid );
unit = gtk_combo_box_text_new ();
gtk_combo_box_text_append_text ( GTK_COMBO_BOX_TEXT ( unit ), _ ( "KiB/s" ));
gtk_combo_box_text_append_text ( GTK_COMBO_BOX_TEXT ( unit ), _ ( "MiB/s" ));
gtk_combo_box_set_wrap_width ( GTK_COMBO_BOX ( unit ), 1 );
gtk_combo_box_set_active ( GTK_COMBO_BOX ( unit ), use_mib ? 1 : 0 );
data -> unit = GTK_COMBO_BOX ( unit );
setup_dcc_speed_spin_range ( data );
multiplier = setup_dcc_speed_multiplier ( data -> unit );
gtk_spin_button_set_value ( GTK_SPIN_BUTTON ( wid ), ( speed + ( multiplier / 2 )) / multiplier );
g_signal_connect ( G_OBJECT ( wid ), "value-changed" ,
G_CALLBACK ( setup_dcc_speed_spin_cb ), data );
g_signal_connect ( G_OBJECT ( unit ), "changed" ,
G_CALLBACK ( setup_dcc_speed_unit_cb ), data );
gtk_box_pack_start ( GTK_BOX ( rbox ), wid , 0 , 0 , 0 );
gtk_box_pack_start ( GTK_BOX ( rbox ), unit , 0 , 0 , 6 );
} else
{
gtk_spin_button_set_value ( GTK_SPIN_BUTTON ( wid ),
2026-01-16 17:52:57 -07:00
setup_get_int ( & setup_prefs , set ));
2026-04-20 10:38:22 -06:00
g_signal_connect ( G_OBJECT ( wid ), "value-changed" ,
2026-01-16 17:52:57 -07:00
G_CALLBACK ( setup_spin_cb ), ( gpointer ) set );
2026-04-20 10:38:22 -06:00
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
}
2026-07-16 08:48:33 -06:00
static guint setup_trans_apply_tag = 0 ;
/* the window opacity the dialog opened with, so cancelling can undo the
* live preview done by the slider */
static int setup_transparency_snapshot ;
2011-02-24 04:14:30 +01:00
static gint
2026-07-16 08:48:33 -06:00
setup_apply_trans ( gpointer userdata )
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 ;
2026-07-16 08:48:33 -06:00
if ( current_sess )
gtk_widget_set_opacity ( current_sess -> gui -> window ,
( prefs . hex_gui_transparency / 255. ));
2013-09-26 23:24:27 -04:00
2026-07-16 08:48:33 -06:00
setup_trans_apply_tag = 0 ;
2026-01-16 17:52:57 -07:00
return 0 ;
2011-02-24 04:14:30 +01:00
}
static void
2026-01-30 17:52:14 -07:00
setup_hscale_cb ( GtkRange * wid , const setting * set )
2011-02-24 04:14:30 +01:00
{
2026-01-30 17:52:14 -07:00
setup_set_int ( & setup_prefs , set , ( int ) gtk_range_get_value ( wid ));
2012-11-10 18:26:45 +01:00
2026-07-16 08:48:33 -06:00
if ( setup_trans_apply_tag == 0 )
setup_trans_apply_tag = g_idle_add (( GSourceFunc ) setup_apply_trans , NULL );
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 ));
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( wid , GTK_ALIGN_START );
gtk_widget_set_valign ( wid , GTK_ALIGN_CENTER );
2026-01-30 08:30:18 -07:00
setup_table_attach ( table , wid , 2 , 3 , row , row + 1 , FALSE , FALSE ,
SETUP_ALIGN_START , SETUP_ALIGN_CENTER ,
LABEL_INDENT , 0 );
2011-02-24 04:14:30 +01:00
2026-01-30 17:52:14 -07:00
wid = gtk_scale_new_with_range ( GTK_ORIENTATION_HORIZONTAL , 0. , 255. , 1. );
2026-01-16 17:52:57 -07:00
gtk_scale_set_value_pos ( GTK_SCALE ( wid ), GTK_POS_RIGHT );
gtk_range_set_value ( GTK_RANGE ( wid ), setup_get_int ( & setup_prefs , set ));
2026-03-17 10:30:54 -06:00
g_signal_connect ( G_OBJECT ( wid ), "value-changed" ,
2026-01-16 17:52:57 -07:00
G_CALLBACK ( setup_hscale_cb ), ( gpointer ) set );
2026-01-30 08:36:01 -07:00
setup_table_attach ( table , wid , 3 , 6 , row , row + 1 , TRUE , FALSE ,
SETUP_ALIGN_FILL , SETUP_ALIGN_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 */
2026-07-16 08:48:33 -06:00
if ( current_sess &&
! gdk_screen_is_composited ( gtk_widget_get_screen ( current_sess -> gui -> window )))
2026-01-16 17:52:57 -07:00
gtk_widget_set_sensitive ( wid , FALSE );
2013-09-26 23:24:27 -04:00
#endif
2011-02-24 04:14:30 +01:00
}
2026-02-25 00:55:37 -07:00
static GtkWidget * proxy_user ;
static GtkWidget * proxy_pass ;
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 ));
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( wid , GTK_ALIGN_START );
gtk_widget_set_valign ( wid , GTK_ALIGN_CENTER );
2026-01-30 08:30:18 -07:00
setup_table_attach ( table , wid , 2 , 3 , row , row + 1 , FALSE , FALSE ,
SETUP_ALIGN_START , SETUP_ALIGN_CENTER ,
LABEL_INDENT , 0 );
2026-01-16 17:52:57 -07:00
2026-02-05 01:59:15 -07:00
hbox = gtkutil_box_new ( GTK_ORIENTATION_HORIZONTAL , FALSE , 0 );
2026-01-30 08:30:18 -07:00
setup_table_attach ( table , hbox , 3 , 4 , row , row + 1 , FALSE , FALSE ,
SETUP_ALIGN_FILL , SETUP_ALIGN_FILL , 0 , 0 );
2026-01-16 17:52:57 -07:00
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);
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign (wid, GTK_ALIGN_START);
gtk_widget_set_valign (wid, GTK_ALIGN_CENTER);
2026-01-30 08:30:18 -07:00
setup_table_attach (table, wid, 2, 3, row, row + 1, FALSE, FALSE,
SETUP_ALIGN_START, SETUP_ALIGN_CENTER,
LABEL_INDENT, 0);
2026-01-16 17:52:57 -07:00
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);
2026-01-30 08:36:01 -07:00
setup_table_attach (table, wid, 3, 4, row, row + 1, FALSE, FALSE,
SETUP_ALIGN_FILL, SETUP_ALIGN_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 ));
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( wid , GTK_ALIGN_START );
gtk_widget_set_valign ( wid , GTK_ALIGN_CENTER );
2026-01-30 08:30:18 -07:00
setup_table_attach ( table , wid , 2 , 3 , row , row + 1 , FALSE , FALSE ,
SETUP_ALIGN_START , SETUP_ALIGN_CENTER ,
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-02-05 01:59:15 -07:00
box = gtkutil_box_new ( GTK_ORIENTATION_HORIZONTAL , FALSE , 0 );
2026-01-16 17:52:57 -07:00
gtk_box_pack_start ( GTK_BOX ( box ), cbox , 0 , 0 , 0 );
2026-01-30 08:30:18 -07:00
setup_table_attach ( table , box , 3 , 4 , row , row + 1 , TRUE , FALSE ,
SETUP_ALIGN_FILL , SETUP_ALIGN_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
}
2026-03-08 10:10:59 -06:00
static void
setup_browsefile_response_cb ( GtkNativeDialog * dialog , gint response , gpointer user_data )
{
GtkWidget * entry = user_data ;
if ( response == GTK_RESPONSE_ACCEPT )
{
char * file = gtk_file_chooser_get_filename ( GTK_FILE_CHOOSER ( dialog ));
setup_filereq_cb ( entry , file );
g_free ( file );
}
g_object_unref ( dialog );
}
2011-02-24 04:14:30 +01:00
static void
setup_browsefile_cb ( GtkWidget * button , GtkWidget * entry )
{
2026-03-08 10:10:59 -06:00
GtkFileChooserNative * dialog ;
GtkFileFilter * filefilter ;
const char * current ;
char * dirname ;
( void ) button ;
dialog = gtk_file_chooser_native_new ( _ ( "Select an Image File" ),
GTK_WINDOW ( setup_window ),
GTK_FILE_CHOOSER_ACTION_OPEN ,
_ ( "_Open" ),
_ ( "_Cancel" ));
gtk_native_dialog_set_modal ( GTK_NATIVE_DIALOG ( dialog ), TRUE );
current = gtk_entry_get_text ( GTK_ENTRY ( entry ));
if ( current && current [ 0 ])
{
dirname = g_path_get_dirname ( current );
if ( dirname && dirname [ 0 ] && g_file_test ( dirname , G_FILE_TEST_IS_DIR ))
gtk_file_chooser_set_current_folder ( GTK_FILE_CHOOSER ( dialog ), dirname );
else if ( g_file_test ( current , G_FILE_TEST_IS_DIR ))
gtk_file_chooser_set_current_folder ( GTK_FILE_CHOOSER ( dialog ), current );
g_free ( dirname );
}
2013-08-31 15:38:29 -04:00
2026-03-08 10:10:59 -06:00
filefilter = gtk_file_filter_new ();
2013-08-31 15:38:29 -04:00
#ifdef WIN32
2026-03-08 10:10:59 -06:00
gtk_file_filter_add_pattern ( filefilter , "*.png" );
gtk_file_filter_add_pattern ( filefilter , "*.tiff" );
gtk_file_filter_add_pattern ( filefilter , "*.gif" );
gtk_file_filter_add_pattern ( filefilter , "*.jpeg" );
gtk_file_filter_add_pattern ( filefilter , "*.jpg" );
2013-08-31 15:38:29 -04:00
#else
2026-03-08 10:10:59 -06:00
gtk_file_filter_add_mime_type ( filefilter , "image/*" );
2013-08-31 15:38:29 -04:00
#endif
2026-03-08 10:10:59 -06:00
gtk_file_filter_set_name ( filefilter , _ ( "Images" ));
gtk_file_chooser_set_filter ( GTK_FILE_CHOOSER ( dialog ), filefilter );
g_signal_connect ( G_OBJECT ( dialog ), "response" ,
G_CALLBACK ( setup_browsefile_response_cb ), entry );
gtk_native_dialog_show ( GTK_NATIVE_DIALOG ( dialog ));
2011-02-24 04:14:30 +01:00
}
2026-01-30 17:21:49 -07:00
static void
setup_fontchooser_response ( GtkDialog * dialog , gint response , GtkWidget * entry )
{
if ( response == GTK_RESPONSE_OK )
{
char * font_name ;
font_name = gtk_font_chooser_get_font ( GTK_FONT_CHOOSER ( dialog ));
if ( font_name )
{
gtk_entry_set_text ( GTK_ENTRY ( entry ), font_name );
g_free ( font_name );
}
}
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-30 17:21:49 -07:00
GtkWidget * dialog ;
const char * font_name ;
dialog = gtk_font_chooser_dialog_new ( _ ( "Select font" ), GTK_WINDOW ( setup_window ));
2026-03-04 23:28:01 -07:00
theme_manager_attach_window ( dialog );
2026-01-30 17:21:49 -07:00
font_dialog = dialog ; /* global var */
gtk_window_set_modal ( GTK_WINDOW ( dialog ), TRUE );
font_name = gtk_entry_get_text ( GTK_ENTRY ( entry ));
if ( font_name [ 0 ])
gtk_font_chooser_set_font ( GTK_FONT_CHOOSER ( dialog ), font_name );
g_signal_connect ( G_OBJECT ( dialog ), "response" ,
G_CALLBACK ( setup_fontchooser_response ), entry );
gtk_widget_show ( 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 );
2026-05-20 15:34:19 -06:00
size_t len = strlen (( const char * ) p );
2026-01-16 17:52:57 -07:00
/* 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-30 08:30:18 -07:00
setup_table_attach ( table , setup_create_italic_label ( _ ( set -> label )),
set -> extra ? 1 : 3 , 5 , row , row + 1 , FALSE , FALSE ,
SETUP_ALIGN_FILL , SETUP_ALIGN_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 ));
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( label , GTK_ALIGN_START );
gtk_widget_set_valign ( label , GTK_ALIGN_CENTER );
2026-01-30 08:30:18 -07:00
setup_table_attach ( table , label , 2 , 3 , row , row + 1 , FALSE , FALSE ,
SETUP_ALIGN_START , SETUP_ALIGN_CENTER ,
LABEL_INDENT , 0 );
2026-01-16 17:52:57 -07:00
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 )
2026-01-30 08:36:01 -07:00
setup_table_attach ( table , wid , 3 , 6 , row , row + 1 , TRUE , FALSE ,
SETUP_ALIGN_FILL , SETUP_ALIGN_FILL , 0 , 0 );
2026-01-16 17:52:57 -07:00
else
{
2026-01-30 08:30:18 -07:00
setup_table_attach ( table , wid , 3 , 5 , row , row + 1 , TRUE , FALSE ,
SETUP_ALIGN_FILL , SETUP_ALIGN_CENTER , 0 , 0 );
2026-01-16 17:52:57 -07:00
bwid = gtk_button_new_with_label ( _ ( "Browse..." ));
2026-01-30 08:30:18 -07:00
setup_table_attach ( table , bwid , 5 , 6 , row , row + 1 , FALSE , FALSE ,
SETUP_ALIGN_FILL , SETUP_ALIGN_FILL , 0 , 0 );
2026-01-16 17:52:57 -07:00
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 );
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( label , GTK_ALIGN_START );
gtk_widget_set_valign ( label , GTK_ALIGN_CENTER );
2026-01-30 08:30:18 -07:00
setup_table_attach ( table , label , 0 , 4 , row , row + 1 , FALSE , FALSE ,
SETUP_ALIGN_START , SETUP_ALIGN_CENTER , 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 );
2026-01-30 08:30:18 -07:00
setup_table_attach ( table , but , 2 , 3 , row , row + 1 , FALSE , FALSE ,
SETUP_ALIGN_FILL , SETUP_ALIGN_FILL , 0 , 5 );
2026-01-16 17:52:57 -07:00
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-02-05 01:59:15 -07:00
tab = gtkutil_grid_new ( 3 , 2 , FALSE );
2026-01-30 17:13:44 -07:00
gtk_container_set_border_width ( GTK_CONTAINER ( tab ), 6 );
gtk_grid_set_row_spacing ( GTK_GRID ( tab ), 2 );
gtk_grid_set_column_spacing ( GTK_GRID ( 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
}
static GtkWidget *
2026-03-04 23:28:01 -07:00
setup_create_theme_page ( void )
2011-02-24 04:14:30 +01:00
{
2026-03-04 23:28:01 -07:00
return theme_preferences_create_page ( GTK_WINDOW ( setup_window ),
2026-03-02 19:42:48 -07:00
& setup_prefs ,
& color_change );
2026-01-16 17:52:57 -07:00
}
2026-03-08 10:10:59 -06:00
static GtkWidget *
setup_create_appearance_page ( void )
{
GtkWidget * box ;
GtkWidget * appearance_page ;
GtkWidget * theme_label ;
GtkWidget * theme_page ;
GtkWidget * advanced_page ;
box = gtk_box_new ( GTK_ORIENTATION_VERTICAL , 6 );
appearance_page = setup_create_page ( appearance_settings );
theme_label = gtk_label_new ( NULL );
theme_page = setup_create_theme_page ();
advanced_page = setup_create_page ( appearance_advanced_settings );
{
char * markup = g_markup_printf_escaped ( "<b>%s</b>" , _ ( "GTK3 Theme" ));
gtk_label_set_markup ( GTK_LABEL ( theme_label ), markup );
g_free ( markup );
}
gtk_widget_set_halign ( theme_label , GTK_ALIGN_START );
gtk_widget_set_valign ( theme_label , GTK_ALIGN_CENTER );
gtk_widget_set_margin_start ( theme_label , 2 );
gtk_widget_set_margin_end ( theme_label , 2 );
gtk_widget_set_margin_top ( theme_label , 1 );
gtk_widget_set_margin_bottom ( theme_label , 1 );
gtk_box_pack_start ( GTK_BOX ( box ), appearance_page , FALSE , FALSE , 0 );
gtk_box_pack_start ( GTK_BOX ( box ), theme_label , FALSE , FALSE , 2 );
gtk_box_pack_start ( GTK_BOX ( box ), theme_page , FALSE , FALSE , 0 );
gtk_box_pack_start ( GTK_BOX ( box ), advanced_page , FALSE , FALSE , 0 );
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.
*/
2026-01-25 16:13:47 -07:00
if ( ! strcmp ( g_path_get_dirname ( file ), g_build_filename ( get_xdir (), ZOITECHAT_SOUND_DIR , NULL )))
2026-01-16 17:52:57 -07:00
{
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-25 16:13:47 -07:00
char * sounds_dir = g_build_filename ( get_xdir (), ZOITECHAT_SOUND_DIR , NULL );
2026-01-16 17:52:57 -07:00
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 ;
2026-02-05 01:59:15 -07:00
vbox1 = gtkutil_box_new ( GTK_ORIENTATION_VERTICAL , FALSE , 0 );
2026-01-16 17:52:57 -07:00
gtk_container_set_border_width ( GTK_CONTAINER ( vbox1 ), 6 );
gtk_widget_show ( vbox1 );
2026-02-05 01:59:15 -07:00
vbox2 = gtkutil_box_new ( GTK_ORIENTATION_VERTICAL , FALSE , 0 );
2026-01-16 17:52:57 -07:00
gtk_widget_show ( vbox2 );
2026-03-21 00:00:59 -06:00
gtk_box_pack_start ( GTK_BOX ( vbox1 ), vbox2 , TRUE , TRUE , 0 );
2026-01-16 17:52:57 -07:00
scrolledwindow1 = gtk_scrolled_window_new ( NULL , NULL );
gtk_widget_show ( scrolledwindow1 );
2026-03-21 00:00:59 -06:00
gtk_box_pack_start ( GTK_BOX ( vbox2 ), scrolledwindow1 , TRUE , TRUE , 0 );
2026-01-16 17:52:57 -07:00
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 );
2026-03-11 01:49:14 -06:00
gtk_tree_view_set_grid_lines ( GTK_TREE_VIEW ( sound_tree ), GTK_TREE_VIEW_GRID_LINES_HORIZONTAL );
2026-01-16 17:52:57 -07:00
2026-02-05 01:59:15 -07:00
table1 = gtkutil_grid_new ( 2 , 3 , FALSE );
2026-01-30 17:13:44 -07:00
gtk_widget_show ( table1 );
gtk_box_pack_start ( GTK_BOX ( vbox2 ), table1 , FALSE , TRUE , 8 );
gtk_grid_set_row_spacing ( GTK_GRID ( table1 ), 2 );
gtk_grid_set_column_spacing ( GTK_GRID ( table1 ), 4 );
2026-01-16 17:52:57 -07:00
sound_label = gtk_label_new_with_mnemonic ( _ ( "Sound file:" ));
gtk_widget_show ( sound_label );
2026-01-30 08:36:01 -07:00
setup_table_attach ( table1 , sound_label , 0 , 1 , 0 , 1 , FALSE , FALSE ,
SETUP_ALIGN_START , SETUP_ALIGN_CENTER , 0 , 0 );
2026-01-16 17:52:57 -07:00
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 );
2026-01-30 08:36:01 -07:00
setup_table_attach ( table1 , sndfile_entry , 0 , 1 , 1 , 2 , TRUE , FALSE ,
SETUP_ALIGN_FILL , SETUP_ALIGN_FILL , 0 , 0 );
2026-01-16 17:52:57 -07:00
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 );
2026-01-30 08:36:01 -07:00
setup_table_attach ( table1 , sound_browse , 1 , 2 , 1 , 2 , FALSE , FALSE ,
SETUP_ALIGN_FILL , SETUP_ALIGN_FILL , 0 , 0 );
2011-02-24 04:14:30 +01:00
2026-01-30 08:00:08 -07:00
sound_play = gtkutil_button_new_from_stock ( "gtk-media-play" , _ ( "_Play" ));
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 );
2026-01-30 08:36:01 -07:00
setup_table_attach ( table1 , sound_play , 2 , 3 , 1 , 2 , FALSE , FALSE ,
SETUP_ALIGN_FILL , SETUP_ALIGN_FILL , 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
}
2026-03-27 09:30:27 -06:00
static GtkWidget *
setup_page_from_settings ( const setting * settings )
{
return setup_create_page ( settings );
}
static GtkWidget *
setup_page_from_appearance ( const setting * settings )
{
( void ) settings ;
return setup_create_appearance_page ();
}
static GtkWidget *
setup_page_from_sound ( const setting * settings )
{
( void ) settings ;
return setup_create_sound_page ();
}
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 ];
2026-02-05 01:59:15 -07:00
vvbox = gtkutil_box_new ( GTK_ORIENTATION_VERTICAL , FALSE , 0 );
2026-01-16 17:52:57 -07:00
/* 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 );
2026-01-23 20:18:49 -07:00
gtk_widget_set_halign ( label , GTK_ALIGN_START );
gtk_widget_set_valign ( label , GTK_ALIGN_CENTER );
gtk_widget_set_margin_start ( label , 2 );
gtk_widget_set_margin_end ( label , 2 );
gtk_widget_set_margin_top ( label , 1 );
gtk_widget_set_margin_bottom ( label , 1 );
2026-01-16 17:52:57 -07:00
gtk_box_pack_start ( GTK_BOX ( vvbox ), label , FALSE , FALSE , 2 );
2026-03-21 00:00:59 -06:00
gtk_box_pack_start ( GTK_BOX ( vvbox ), tab , TRUE , TRUE , 0 );
2026-01-16 17:52:57 -07:00
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 );
2026-03-11 01:49:14 -06:00
gtk_container_add ( GTK_CONTAINER ( sw ), vvbox );
2026-01-16 17:52:57 -07:00
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 );
}
2026-03-27 09:30:27 -06:00
static void
setup_register_page ( const char * title , GtkWidget * book , setup_page_factory factory , const setting * settings )
{
GtkWidget * container ;
if ( setup_page_count >= SETUP_MAX_PAGES )
return ;
setup_page_factories [ setup_page_count ] = factory ;
setup_page_settings [ setup_page_count ] = settings ;
container = gtkutil_box_new ( GTK_ORIENTATION_VERTICAL , FALSE , 0 );
setup_page_containers [ setup_page_count ] = container ;
setup_add_page ( title , book , container );
setup_page_count ++ ;
}
static void
setup_ensure_page_created ( int page )
{
GList * children ;
GtkWidget * page_widget ;
GtkWidget * container ;
if ( page < 0 || page >= setup_page_count )
return ;
container = setup_page_containers [ page ];
children = gtk_container_get_children ( GTK_CONTAINER ( container ));
if ( children != NULL )
{
g_list_free ( children );
return ;
}
page_widget = setup_page_factories [ page ] ( setup_page_settings [ page ]);
gtk_container_add ( GTK_CONTAINER ( container ), page_widget );
gtk_widget_show_all ( container );
}
2026-01-16 17:52:57 -07:00
static const char * const cata_interface [] =
{
N_ ( "Appearance" ),
N_ ( "Input box" ),
N_ ( "User list" ),
N_ ( "Channel switcher" ),
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 ;
2026-03-08 10:10:59 -06:00
GtkWindow * win = GTK_WINDOW ( setup_window );
2011-02-24 04:14:30 +01:00
2026-03-08 10:10:59 -06:00
( void ) box ;
2026-01-16 17:52:57 -07:00
book = gtk_notebook_new ();
2011-02-24 04:14:30 +01:00
2026-03-27 09:30:27 -06:00
memset ( setup_page_factories , 0 , sizeof ( setup_page_factories ));
memset ( setup_page_settings , 0 , sizeof ( setup_page_settings ));
memset ( setup_page_containers , 0 , sizeof ( setup_page_containers ));
setup_page_count = 0 ;
setup_register_page ( cata_interface [ 0 ], book , setup_page_from_appearance , NULL );
setup_register_page ( cata_interface [ 1 ], book , setup_page_from_settings , inputbox_settings );
setup_register_page ( cata_interface [ 2 ], book , setup_page_from_settings , userlist_settings );
setup_register_page ( cata_interface [ 3 ], book , setup_page_from_settings , tabs_settings );
2011-02-28 18:59:32 +01:00
2026-03-27 09:30:27 -06:00
setup_register_page ( cata_chatting [ 0 ], book , setup_page_from_settings , 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 ())
{
2026-03-27 09:30:27 -06:00
setup_register_page ( cata_chatting [ 1 ], book , setup_page_from_settings , alert_settings_unityandnonotifications );
2026-01-16 17:52:57 -07:00
}
else if ( ! gtkutil_tray_icon_supported ( win ))
{
2026-03-27 09:30:27 -06:00
setup_register_page ( cata_chatting [ 1 ], book , setup_page_from_settings , alert_settings_unity );
2026-01-16 17:52:57 -07:00
}
else if ( ! notification_backend_supported ())
{
2026-03-27 09:30:27 -06:00
setup_register_page ( cata_chatting [ 1 ], book , setup_page_from_settings , alert_settings_nonotifications );
2026-01-16 17:52:57 -07:00
}
else
{
2026-03-27 09:30:27 -06:00
setup_register_page ( cata_chatting [ 1 ], book , setup_page_from_settings , alert_settings );
2026-01-16 17:52:57 -07:00
}
2011-02-28 18:59:32 +01:00
2026-03-27 09:30:27 -06:00
setup_register_page ( cata_chatting [ 2 ], book , setup_page_from_sound , NULL );
setup_register_page ( cata_chatting [ 3 ], book , setup_page_from_settings , logging_settings );
setup_register_page ( cata_chatting [ 4 ], book , setup_page_from_settings , advanced_settings );
2011-11-25 10:10:11 +01:00
2026-03-27 09:30:27 -06:00
setup_register_page ( cata_network [ 0 ], book , setup_page_from_settings , network_settings );
setup_register_page ( cata_network [ 1 ], book , setup_page_from_settings , filexfer_settings );
setup_register_page ( cata_network [ 2 ], book , setup_page_from_settings , 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 );
2026-02-13 18:45:13 -07:00
gtk_box_pack_start ( GTK_BOX ( box ), book , TRUE , TRUE , 0 );
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 )
{
2026-03-27 09:30:27 -06:00
setup_ensure_page_created ( page );
2026-01-16 17:52:57 -07:00
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 );
2026-03-17 10:30:54 -06:00
g_signal_connect ( G_OBJECT ( tree ), "cursor-changed" ,
2026-01-16 17:52:57 -07:00
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 );
2026-03-27 09:30:27 -06:00
setup_tree_cb ( GTK_TREE_VIEW ( tree ), book );
2026-01-16 17:52:57 -07:00
}
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 );
2026-03-30 10:33:43 -06:00
mg_apply_session_font_prefs ( gui );
2026-01-16 17:52:57 -07:00
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 ])
{
2026-05-20 15:22:06 -06:00
size_t 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
2026-03-02 19:42:48 -07:00
setup_apply_real ( const ThemeChangedEvent * event )
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-03-02 19:42:48 -07:00
if ( theme_changed_event_has_reason ( event , THEME_CHANGED_REASON_PIXMAP ))
2026-01-16 17:52:57 -07:00
{
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-03-02 19:42:48 -07:00
theme_manager_reload_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-03-02 19:42:48 -07:00
if ( theme_changed_event_has_reason ( event , THEME_CHANGED_REASON_USERLIST ))
2026-01-16 17:52:57 -07:00
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 ();
2026-03-23 14:46:23 -06:00
menu_update_quit_accel ();
2026-01-16 17:52:57 -07:00
tray_apply_setup ();
zoitechat_reinit_timers ();
2011-02-24 04:14:30 +01:00
2026-03-02 19:42:48 -07:00
if ( theme_changed_event_has_reason ( event , THEME_CHANGED_REASON_LAYOUT ))
2026-01-16 17:52:57 -07:00
menu_change_layout ();
2016-01-25 21:01:56 -05:00
2026-03-02 19:42:48 -07:00
if ( theme_changed_event_has_reason ( event , THEME_CHANGED_REASON_IDENTD ))
2026-01-16 17:52:57 -07:00
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-03-02 19:42:48 -07:00
int noapply = FALSE ;
ThemeChangedEvent event ;
struct zoitechatprefs old_prefs = prefs ;
int old_dark_mode = prefs . hex_gui_dark_mode ;
2026-07-16 08:48:33 -06:00
mg_live_prefs live_changes ;
2011-02-24 04:14:30 +01:00
2026-07-16 08:48:33 -06:00
memset ( & live_changes , 0 , sizeof ( live_changes ));
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-07-16 08:48:33 -06:00
/* server tabs are only created when a connection is opened, so
existing connections keep their current tabs until a restart;
the channel tree indentation is still re-applied below */
2026-01-16 17:52:57 -07:00
if ( DIFF ( hex_gui_tab_server ))
2026-07-16 08:48:33 -06:00
{
2026-01-16 17:52:57 -07:00
noapply = TRUE ;
2026-07-16 08:48:33 -06:00
live_changes . chanview = TRUE ;
}
if ( DIFF ( hex_gui_compact ))
{
live_changes . chanview = TRUE ;
live_changes . ulist_columns = TRUE ;
}
if ( DIFF ( hex_gui_input_icon ) || DIFF ( hex_gui_input_nick ))
live_changes . input_box = TRUE ;
if ( DIFF ( hex_gui_lagometer ) || DIFF ( hex_gui_throttlemeter ))
live_changes . meters = TRUE ;
if ( DIFF ( hex_gui_mode_buttons_inline ) || DIFF ( hex_gui_topicbar_multiline ))
live_changes . topic_bar = TRUE ;
if ( DIFF ( hex_gui_tab_icons ) || DIFF ( hex_gui_tab_closebuttons ) ||
DIFF ( hex_gui_tab_small ))
live_changes . chanview = TRUE ;
2026-01-16 17:52:57 -07:00
if ( DIFF ( hex_gui_tab_sort ))
2026-07-16 08:48:33 -06:00
live_changes . tab_resort = TRUE ;
2026-01-16 17:52:57 -07:00
if ( DIFF ( hex_gui_tab_trunc ))
2026-07-16 08:48:33 -06:00
live_changes . tab_trunc = TRUE ;
2026-01-16 17:52:57 -07:00
if ( DIFF ( hex_gui_ulist_count ))
2026-07-16 08:48:33 -06:00
live_changes . ulist_count = TRUE ;
2026-01-16 17:52:57 -07:00
if ( DIFF ( hex_gui_ulist_icons ))
2026-07-16 08:48:33 -06:00
live_changes . ulist_rows = TRUE ;
2026-01-16 17:52:57 -07:00
if ( DIFF ( hex_gui_ulist_show_hosts ))
2026-07-16 08:48:33 -06:00
{
live_changes . ulist_columns = TRUE ;
live_changes . ulist_rows = TRUE ; /* hostnames may be stale */
}
2026-01-16 17:52:57 -07:00
if ( DIFF ( hex_gui_ulist_sort ))
2026-07-16 08:48:33 -06:00
live_changes . ulist_sort = TRUE ;
/* compare against the pre-dialog value: the slider previews the
opacity live on the current window only, so OK still needs to
apply it to the other windows */
if ( pr -> hex_gui_transparency != setup_transparency_snapshot )
live_changes . transparency = TRUE ;
2026-01-16 17:52:57 -07:00
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 ));
2026-03-02 19:42:48 -07:00
event = theme_manager_on_preferences_changed ( & old_prefs , & prefs , old_dark_mode , & color_change );
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" );
}
2026-03-02 19:42:48 -07:00
theme_manager_dispatch_setup_apply ( & event );
2011-02-24 04:14:30 +01:00
2026-07-16 08:48:33 -06:00
mg_apply_live_prefs ( & live_changes );
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-03-16 22:45:30 -06:00
PreferencesPersistenceResult save_result ;
2026-03-17 11:01:40 -06:00
struct zoitechatprefs old_prefs ;
2026-03-16 22:45:30 -06:00
char buffer [ 192 ];
2026-03-17 11:01:40 -06:00
memcpy ( & old_prefs , & prefs , sizeof ( prefs ));
2026-01-16 17:52:57 -07:00
setup_apply ( & setup_prefs );
2026-03-21 03:01:03 -06:00
theme_preferences_stage_apply ();
2026-03-16 22:45:30 -06:00
save_result = preferences_persistence_save_all ();
if ( save_result . success )
2026-03-17 11:01:40 -06:00
{
theme_preferences_stage_commit ();
2026-07-16 08:48:33 -06:00
/* the previewed values were accepted, so the close handler
must not revert them */
setup_transparency_snapshot = prefs . hex_gui_transparency ;
2026-03-17 11:01:40 -06:00
gtk_widget_destroy ( win );
2026-03-16 22:45:30 -06:00
return ;
2026-03-17 11:01:40 -06:00
}
memcpy ( & prefs , & old_prefs , sizeof ( prefs ));
theme_preferences_stage_discard ();
2026-03-16 22:45:30 -06:00
if ( save_result . partial_failure )
{
fe_message ( _ ( "Preferences were partially saved. zoitechat.conf succeeded, colors.conf failed. Retry is possible." ), FE_MSG_ERROR );
return ;
}
g_snprintf ( buffer , sizeof ( buffer ), _ ( "Could not save preferences (%s). Retry is possible." ), save_result . failed_file ? save_result . failed_file : _ ( "unknown file" ));
fe_message ( buffer , FE_MSG_ERROR );
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 );
2026-03-08 10:10:59 -06:00
setup_window = win ;
2011-02-24 04:14:30 +01:00
2026-02-05 01:59:15 -07:00
vbox = gtkutil_box_new ( GTK_ORIENTATION_VERTICAL , FALSE , 5 );
2026-01-16 17:52:57 -07:00
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-02-05 01:59:15 -07:00
hbox = gtkutil_box_new ( GTK_ORIENTATION_HORIZONTAL , FALSE , 4 );
2026-02-13 18:45:13 -07:00
gtk_box_pack_start ( GTK_BOX ( vbox ), hbox , TRUE , TRUE , 0 );
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 */
2026-01-30 17:03:27 -07:00
hbbox = gtk_button_box_new ( GTK_ORIENTATION_HORIZONTAL );
gtk_button_box_set_layout ( GTK_BUTTON_BOX ( hbbox ), GTK_BUTTONBOX_END );
2026-01-16 17:52:57 -07:00
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-30 08:00:08 -07:00
cancel_button = wid = gtkutil_button_new_from_stock ( "gtk-cancel" , _ ( "_Cancel" ));
2026-01-16 17:52:57 -07:00
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-30 08:00:08 -07:00
wid = gtkutil_button_new_from_stock ( "gtk-ok" , _ ( "_OK" ));
2026-01-16 17:52:57 -07:00
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-07-16 08:48:33 -06:00
/* drop any pending transparency preview and undo the previewed
opacity when the dialog is cancelled; after OK the snapshot
was updated so this is a no-op */
if ( setup_trans_apply_tag )
{
g_source_remove ( setup_trans_apply_tag );
setup_trans_apply_tag = 0 ;
}
if ( prefs . hex_gui_transparency != setup_transparency_snapshot )
{
mg_live_prefs revert_changes ;
prefs . hex_gui_transparency = setup_transparency_snapshot ;
memset ( & revert_changes , 0 , sizeof ( revert_changes ));
revert_changes . transparency = TRUE ;
mg_apply_live_prefs ( & revert_changes );
}
2026-03-17 09:43:50 -06:00
theme_preferences_stage_discard ();
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 ;
2026-07-16 08:48:33 -06:00
setup_transparency_snapshot = prefs . hex_gui_transparency ;
2026-03-17 09:43:50 -06:00
theme_preferences_stage_begin ();
2026-01-16 17:52:57 -07:00
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
}