diff --git a/Attorney_Online.pro b/Attorney_Online.pro
index a7815d030..1bb32c1b1 100644
--- a/Attorney_Online.pro
+++ b/Attorney_Online.pro
@@ -1,4 +1,4 @@
-QT += core gui widgets network websockets
+QT += core gui widgets network websockets uitools
TARGET = Attorney_Online
TEMPLATE = app
@@ -10,8 +10,10 @@ DESTDIR = $$PWD/bin
OBJECTS_DIR = $$PWD/build
MOC_DIR = $$PWD/build
-SOURCES += $$files($$PWD/src/*.cpp)
-HEADERS += $$files($$PWD/include/*.h)
+SOURCES += $$files($$PWD/src/*.cpp, true)
+HEADERS += $$files($$PWD/include/*.h, true)
+
+FORMS += $$files($$PWD/resource/ui/*.ui)
LIBS += -L$$PWD/lib
QMAKE_LFLAGS += -Wl,-rpath,"'\$$ORIGIN/lib'"
@@ -57,7 +59,8 @@ TRANSLATIONS = resource/translations/ao_en.ts \
resource/translations/ao_es.ts \
resource/translations/ao_pt.ts \
resource/translations/ao_pl.ts \
- resource/translations/ao_it.ts
+ resource/translations/ao_it.ts \
+ ressource/ui/
win32:RC_ICONS = resource/logo_ao2.ico
macx:ICON = resource/logo_ao2.icns
diff --git a/README.md b/README.md
index 2f5341d33..251bcf864 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# Attorney Online
+![CI build](https://github.com/AttorneyOnline/AO2-Client/actions/workflows/build.yml/badge.svg?event=push) ![license](https://img.shields.io/github/license/AttorneyOnline/AO2-Client?color=blue) ![contributors](https://img.shields.io/github/contributors/AttorneyOnline/AO2-Client)
+
[Attorney Online](https://aceattorneyonline.com) is an online version of the world-renowned courtroom drama simulator that allows you to create and play out cases in an off-the-cuff format.
**[Refer to the docs](https://github.com/AttorneyOnline/docs/blob/master/docs/index.md) for more information.**
diff --git a/include/aoapplication.h b/include/aoapplication.h
index 4f2c585ae..f8f88872e 100644
--- a/include/aoapplication.h
+++ b/include/aoapplication.h
@@ -1,6 +1,7 @@
#ifndef AOAPPLICATION_H
#define AOAPPLICATION_H
+#include "widgets/aooptionsdialog.h"
#include "aopacket.h"
#include "datatypes.h"
#include "demoserver.h"
@@ -35,6 +36,7 @@
class NetworkManager;
class Lobby;
class Courtroom;
+class Options;
class VPath : QString {
using QString::QString;
@@ -142,9 +144,6 @@ class AOApplication : public QApplication {
void set_server_list(QVector &servers) { server_list = servers; }
QVector &get_server_list() { return server_list; }
- // reads the theme from config.ini and sets it accordingly
- void reload_theme();
-
// Returns the character the player has currently selected
QString get_current_char();
@@ -174,147 +173,6 @@ class AOApplication : public QApplication {
////// Functions for reading and writing files //////
// Implementations file_functions.cpp
- // Instead of reinventing the wheel, we'll use a QSettings class.
- QSettings *configini;
-
- // Reads the theme from config.ini and loads it into the current_theme
- // variable
- QString read_theme();
-
- // Returns the value of ooc_name in config.ini
- QString get_ooc_name();
-
- // Returns the blip rate from config.ini (once per X symbols)
- int read_blip_rate();
-
- // Returns true if blank blips is enabled in config.ini and false otherwise
- bool get_blank_blip();
-
- // Returns true if looping sound effects are enabled in the config.ini
- bool get_looping_sfx();
-
- // Returns true if stop music on objection is enabled in the config.ini
- bool objection_stop_music();
-
- // Returns true if streaming is enabled in the config.ini
- bool is_streaming_disabled();
-
- // Returns the value of default_music in config.ini
- int get_default_music();
-
- // Returns the value of default_sfx in config.ini
- int get_default_sfx();
-
- // Returns the value of default_blip in config.ini
- int get_default_blip();
-
- // Returns the value of suppress_audio in config.ini
- int get_default_suppress_audio();
-
- // Returns the value if objections interrupt and skip the message queue
- // from the config.ini.
- bool is_instant_objection_enabled();
-
- // returns if log will show messages as-received, while viewport will parse according to the queue (Text Stay Time)
- // from the config.ini
- bool is_desyncrhonized_logs_enabled();
-
- // Returns the value of whether Discord should be enabled on startup
- // from the config.ini.
- bool is_discord_enabled();
-
- // Returns the value of whether shaking should be enabled.
- // from the config.ini.
- bool is_shake_enabled();
-
- // Returns the value of whether effects should be enabled.
- // from the config.ini.
- bool is_effects_enabled();
-
- // Returns the value of whether frame-specific effects defined in char.ini
- // should be sent/received over the network. from the config.ini.
- bool is_frame_network_enabled();
-
- // Returns the value of whether colored ic log should be a thing.
- // from the config.ini.
- bool is_colorlog_enabled();
-
- // Returns the value of whether sticky sounds should be a thing.
- // from the config.ini.
- bool is_stickysounds_enabled();
-
- // Returns the value of whether sticky effects should be a thing.
- // from the config.ini.
- bool is_stickyeffects_enabled();
-
- // Returns the value of whether sticky preanims should be a thing.
- // from the config.ini.
- bool is_stickypres_enabled();
-
- // Returns the value of whether custom chatboxes should be a thing.
- // from the config.ini.
- // I am increasingly maddened by the lack of dynamic auto-generation system
- // for settings.
- bool is_customchat_enabled();
-
- // Returns the value of characer sticker (avatar) setting
- bool is_sticker_enabled();
-
- // Returns the value of whether continuous playback should be used
- // from the config.ini.
- bool is_continuous_enabled();
-
- // Returns the value of whether stopping music by double clicking category should be used
- // from the config.ini.
- bool is_category_stop_enabled();
-
- // Returns the value of the maximum amount of lines the IC chatlog
- // may contain, from config.ini.
- int get_max_log_size();
-
- // Current wait time between messages for the queue system
- int stay_time();
-
- // Returns the letter display speed during text crawl in in-character messages
- int get_text_crawl();
-
- // Returns Minimum amount of time (in miliseconds) that must pass before the next Enter key press will send your IC message. (new behaviour)
- int get_chat_ratelimit();
-
- // Returns whether the log should go upwards (new behaviour)
- // or downwards (vanilla behaviour).
- bool get_log_goes_downwards();
-
- // Returns whether the log should separate name from text via newline or :
- bool get_log_newline();
-
- // Get spacing between IC log entries.
- int get_log_margin();
-
- // Returns whether the log should have a timestamp.
- bool get_log_timestamp();
-
- // Returns the format string for the log timestamp
- QString get_log_timestamp_format();
-
- // Returns whether to log IC actions.
- bool get_log_ic_actions();
-
- // Returns the username the user may have set in config.ini.
- QString get_default_username();
-
- // Returns the audio device used for the client.
- QString get_audio_output_device();
-
- // Returns whether the user would like to have custom shownames on by default.
- bool get_showname_enabled_by_default();
-
- //Returns the showname the user may have set in config.ini.
- QString get_default_showname();
-
- // Returns the list of words in callwords.ini
- QStringList get_call_words();
-
// returns all of the file's lines in a QStringList
QStringList get_list_file(VPath path);
QStringList get_list_file(QString p_file);
@@ -506,62 +364,11 @@ class AOApplication : public QApplication {
// These are all casing-related settings.
// ======
- // Returns if the user has casing alerts enabled.
- bool get_casing_enabled();
-
- // Returns if the user wants to get alerts for the defence role.
- bool get_casing_defence_enabled();
-
- // Same for prosecution.
- bool get_casing_prosecution_enabled();
-
- // Same for judge.
- bool get_casing_judge_enabled();
-
- // Same for juror.
- bool get_casing_juror_enabled();
-
- // Same for steno.
- bool get_casing_steno_enabled();
-
- // Same for CM.
- bool get_casing_cm_enabled();
-
- // Get the message for the CM for casing alerts.
- QString get_casing_can_host_cases();
-
- // Get if text file logging is enabled
- bool get_text_logging_enabled();
-
- // Get if demo logging is enabled
- bool get_demo_logging_enabled();
-
- // Get the subtheme from settings
- QString get_subtheme();
-
- // Get if the theme is animated
- bool get_animated_theme();
-
- // Get the default scaling method
- QString get_default_scaling();
-
- // Get a list of custom mount paths
- QStringList get_mount_paths();
-
- // Get whether to opt out of player count metrics sent to the master server
- bool get_player_count_optout();
-
- // Get if sfx can be sent to play on idle
- bool get_sfx_on_idle();
-
- // Whether opening evidence requires a single or double click
- bool get_evidence_double_click();
-
// Currently defined subtheme
QString subtheme;
- QString default_theme = "default";
- QString current_theme = default_theme;
+ //Default is always default.
+ const QString default_theme = "default";
// The file name of the log file in base/logs.
QString log_filename;
diff --git a/include/aooptionsdialog.h b/include/aooptionsdialog.h
deleted file mode 100644
index be305d216..000000000
--- a/include/aooptionsdialog.h
+++ /dev/null
@@ -1,273 +0,0 @@
-#ifndef AOOPTIONSDIALOG_H
-#define AOOPTIONSDIALOG_H
-
-#include "aoapplication.h"
-#include "bass.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-class Lobby;
-class Courtroom;
-
-class AOOptionsDialog : public QDialog {
- Q_OBJECT
-public:
- explicit AOOptionsDialog(QWidget *parent = nullptr,
- AOApplication *p_ao_app = nullptr);
-
-private:
- AOApplication *ao_app;
-
- QVBoxLayout *ui_vertical_layout;
- QTabWidget *ui_settings_tabs;
-
- QWidget *ui_gameplay_tab;
- QWidget *ui_form_layout_widget;
- QFormLayout *ui_gameplay_form;
-
- QLabel *ui_theme_label;
- QComboBox *ui_theme_combobox;
- QLabel *ui_subtheme_label;
- QComboBox *ui_subtheme_combobox;
- QPushButton *ui_theme_reload_button;
- QPushButton *ui_theme_folder_button;
- QLabel *ui_evidence_double_click_lbl;
- QCheckBox *ui_evidence_double_click_cb;
- QLabel *ui_animated_theme_lbl;
- QCheckBox *ui_animated_theme_cb;
- QFrame *ui_theme_log_divider;
- QLabel *ui_stay_time_lbl;
- QSpinBox *ui_stay_time_spinbox;
- QLabel *ui_instant_objection_lbl;
- QCheckBox *ui_instant_objection_cb;
- QLabel *ui_text_crawl_lbl;
- QSpinBox *ui_text_crawl_spinbox;
- QLabel *ui_chat_ratelimit_lbl;
- QSpinBox *ui_chat_ratelimit_spinbox;
- QFrame *ui_log_names_divider;
- QLineEdit *ui_username_textbox;
- QLabel *ui_username_lbl;
- QLabel *ui_showname_lbl;
- QCheckBox *ui_showname_cb;
- QLabel *ui_default_showname_lbl;
- QLineEdit *ui_default_showname_textbox;
- QFrame *ui_net_divider;
- QLabel *ui_ms_lbl;
- QLineEdit *ui_ms_textbox;
- QLabel *ui_discord_lbl;
- QCheckBox *ui_discord_cb;
- QLabel *ui_language_label;
- QComboBox *ui_language_combobox;
- QLabel *ui_scaling_label;
- QComboBox *ui_scaling_combobox;
-
- QLabel *ui_shake_lbl;
- QCheckBox *ui_shake_cb;
- QLabel *ui_effects_lbl;
- QCheckBox *ui_effects_cb;
- QLabel *ui_framenetwork_lbl;
- QCheckBox *ui_framenetwork_cb;
-
- QLabel *ui_colorlog_lbl;
- QCheckBox *ui_colorlog_cb;
-
- QLabel *ui_stickysounds_lbl;
- QCheckBox *ui_stickysounds_cb;
-
- QLabel *ui_stickyeffects_lbl;
- QCheckBox *ui_stickyeffects_cb;
-
- QLabel *ui_stickypres_lbl;
- QCheckBox *ui_stickypres_cb;
-
- QLabel *ui_customchat_lbl;
- QCheckBox *ui_customchat_cb;
-
- QLabel *ui_sticker_lbl;
- QCheckBox *ui_sticker_cb;
-
- QLabel *ui_continuous_lbl;
- QCheckBox *ui_continuous_cb;
-
- QLabel *ui_category_stop_lbl;
- QCheckBox *ui_category_stop_cb;
-
- QLabel *ui_sfx_on_idle_lbl;
- QCheckBox *ui_sfx_on_idle_cb;
-
- QWidget *ui_callwords_tab;
- QWidget *ui_callwords_widget;
- QVBoxLayout *ui_callwords_layout;
- QPlainTextEdit *ui_callwords_textbox;
- QLabel *ui_callwords_explain_lbl;
- QCheckBox *ui_callwords_char_textbox;
-
- QWidget *ui_audio_tab;
- QWidget *ui_audio_widget;
- QFormLayout *ui_audio_layout;
- QLabel *ui_audio_device_lbl;
- QComboBox *ui_audio_device_combobox;
- QFrame *ui_audio_volume_divider;
- QSpinBox *ui_music_volume_spinbox;
- QLabel *ui_music_volume_lbl;
- QSpinBox *ui_sfx_volume_spinbox;
- QSpinBox *ui_blips_volume_spinbox;
- QSpinBox *ui_suppress_audio_spinbox;
- QLabel *ui_sfx_volume_lbl;
- QLabel *ui_blips_volume_lbl;
- QLabel *ui_suppress_audio_lbl;
- QFrame *ui_volume_blip_divider;
- QSpinBox *ui_bliprate_spinbox;
- QLabel *ui_bliprate_lbl;
- QCheckBox *ui_blank_blips_cb;
- QLabel *ui_blank_blips_lbl;
- QLabel *ui_loopsfx_lbl;
- QCheckBox *ui_loopsfx_cb;
- QLabel *ui_objectmusic_lbl;
- QCheckBox *ui_objectmusic_cb;
- QLabel *ui_disablestreams_lbl;
- QCheckBox *ui_disablestreams_cb;
- QDialogButtonBox *ui_settings_buttons;
-
- QWidget *ui_casing_tab;
- QWidget *ui_casing_widget;
- QFormLayout *ui_casing_layout;
- QLabel *ui_casing_supported_lbl;
- QLabel *ui_casing_enabled_lbl;
- QCheckBox *ui_casing_enabled_cb;
- QLabel *ui_casing_def_lbl;
- QCheckBox *ui_casing_def_cb;
- QLabel *ui_casing_pro_lbl;
- QCheckBox *ui_casing_pro_cb;
- QLabel *ui_casing_jud_lbl;
- QCheckBox *ui_casing_jud_cb;
- QLabel *ui_casing_jur_lbl;
- QCheckBox *ui_casing_jur_cb;
- QLabel *ui_casing_steno_lbl;
- QCheckBox *ui_casing_steno_cb;
- QLabel *ui_casing_cm_lbl;
- QCheckBox *ui_casing_cm_cb;
- QLabel *ui_casing_cm_cases_lbl;
- QLineEdit *ui_casing_cm_cases_textbox;
-
- QWidget *ui_assets_tab;
- QVBoxLayout *ui_assets_tab_layout;
- QGridLayout *ui_mount_buttons_layout;
- QLabel *ui_asset_lbl;
- QListWidget *ui_mount_list;
- QPushButton *ui_mount_add;
- QPushButton *ui_mount_remove;
- QPushButton *ui_mount_up;
- QPushButton *ui_mount_down;
- QPushButton *ui_mount_clear_cache;
-
- QWidget *ui_logging_tab;
- QWidget *ui_form_logging_widget;
- QFormLayout *ui_logging_form;
-
- /**
- * Option for log direction. Supported options are downwards and wrong way.
- */
- QLabel *ui_downwards_lbl;
- QCheckBox *ui_downwards_cb;
-
- /**
- * Option for log length. Controls how many IC-log entries are kept before it autowraps.
- */
- QLabel *ui_length_lbl;
- QSpinBox *ui_length_spinbox;
-
- /**
- * Option for log newline. Controls if the IC-log contains newlines or as one consecutive string.
- */
- QLabel *ui_log_newline_lbl;
- QCheckBox *ui_log_newline_cb;
-
- /**
- * Option for log margin. Controls how many pixels are between each log entry.
- */
- QLabel *ui_log_margin_lbl;
- QSpinBox *ui_log_margin_spinbox;
-
- /**
- * Option for timestamp format. A checkmark to enable the timestamp dropdown.
- * Why does this exist? Are we Dorico now?
- */
- QLabel *ui_log_timestamp_lbl;
- QCheckBox *ui_log_timestamp_cb;
-
- /**
- * Option for timestamp format. Dropdown to select the preferred format.
- */
- QLabel *ui_log_timestamp_format_lbl;
- QComboBox *ui_log_timestamp_format_combobox;
-
- /**
- * Option for desynched IC-log and viewport. Controls if entires are appended to the IC-log before displayed in the viewport.
- */
- QLabel *ui_desync_logs_lbl;
- QCheckBox *ui_desync_logs_cb;
-
- /**
- * Option for logging IC-actions. Will add shouts, evidence or music changes to the IC-log.
- */
- QLabel *ui_log_ic_actions_lbl;
- QCheckBox *ui_log_ic_actions_cb;
-
- /**
- * Option to enable logging. If enabled client will save all messages to the log folder.
- */
- QLabel *ui_log_text_lbl;
- QCheckBox *ui_log_text_cb;
-
- /**
- * Option to enable demo logging. If enabled, client will save a demo file for replay trough the demo server.
- */
- QLabel *ui_log_demo_lbl;
- QCheckBox *ui_log_demo_cb;
-
- QWidget *ui_privacy_tab;
- QVBoxLayout *ui_privacy_layout;
- QCheckBox *ui_privacy_optout_cb;
- QFrame *ui_privacy_separator;
- QTextBrowser *ui_privacy_policy;
-
- bool asset_cache_dirty = false;
-
- bool needs_default_audiodev();
- void update_values();
-
-signals:
-
-public slots:
- void save_pressed();
- void discard_pressed();
- void button_clicked(QAbstractButton *button);
- void on_timestamp_format_edited();
- void timestamp_cb_changed(int state);
- void on_reload_theme_clicked();
- void theme_changed(int i);
-};
-
-#endif // AOOPTIONSDIALOG_H
diff --git a/include/courtroom.h b/include/courtroom.h
index 45c040fbd..5c68f78ee 100644
--- a/include/courtroom.h
+++ b/include/courtroom.h
@@ -12,7 +12,7 @@
#include "aoimage.h"
#include "aolayer.h"
#include "aomusicplayer.h"
-#include "aooptionsdialog.h"
+#include "widgets/aooptionsdialog.h"
#include "aopacket.h"
#include "aosfxplayer.h"
#include "aotextarea.h"
diff --git a/include/options.h b/include/options.h
new file mode 100644
index 000000000..fe37dc6cc
--- /dev/null
+++ b/include/options.h
@@ -0,0 +1,296 @@
+#ifndef OPTIONS_H
+#define OPTIONS_H
+
+
+#include
+#include
+
+class Options {
+private:
+ /**
+ * @brief QSettings object for config.ini
+ */
+ QSettings config;
+
+ void migrateCallwords();
+
+ /**
+ * @brief Constructor for options class.
+ */
+ Options();
+
+public:
+ Options(Options const &) = delete;
+ void operator=(Options const &) = delete;
+
+ static Options &getInstance()
+ {
+ static Options instance;
+ return instance;
+ }
+
+ /**
+ * @brief Migrates old configuration files to the most recent format.
+ */
+ void migrate();
+
+ // Reads the theme from config.ini and loads it into the currenttheme
+ // variable
+ QString theme() const;
+ void setTheme(QString value);
+
+ // Returns the value of oocname in config.ini
+ QString oocName() const;
+ void setOocName(QString value);
+
+ // Returns the blip rate from config.ini (once per X symbols)
+ int blipRate() const;
+ void setBlipRate(int value);
+
+ // Returns true if blank blips is enabled in config.ini and false otherwise
+ bool blankBlip() const;
+ void setBlankBlip(bool value);
+
+ // Returns true if looping sound effects are enabled in the config.ini
+ bool loopingSfx() const;
+ void setLoopingSfx(bool value);
+
+ // Returns true if stop music on objection is enabled in the config.ini
+ bool objectionStopMusic() const;
+ void setObjectionStopMusic(bool value);
+
+ // Returns true if streaming is enabled in the config.ini
+ bool streamingEnabled() const;
+ void setStreamingEnabled(bool value);
+
+ // Returns the value of defaultmusic in config.ini
+ int musicVolume() const;
+ void setMusicVolume(int value);
+
+ // Returns the value of defaultsfx in config.ini
+ int sfxVolume() const;
+ void setSfxVolume(int value);
+
+ // Returns the value of defaultblip in config.ini
+ int blipVolume() const;
+ void setBlipVolume(int value);
+
+ // Returns the value of suppressaudio in config.ini
+ int defaultSuppressAudio() const;
+ void setDefaultSupressedAudio(int value);
+
+ // Returns the value if objections interrupt and skip the message queue
+ // from the config.ini.
+ bool objectionSkipQueueEnabled() const;
+ void setObjectionSkipQueueEnabled(bool value);
+
+ // returns if log will show messages as-received, while viewport will parse
+ // according to the queue (Text Stay Time) from the config.ini
+ bool desynchronisedLogsEnabled() const;
+ void setDesynchronisedLogsEnabled(bool value);
+
+ // Returns the value of whether Discord should be enabled on startup
+ // from the config.ini.
+ bool discordEnabled() const;
+ void setDiscordEnabled(bool value);
+
+ // Returns the value of whether shaking should be enabled.
+ // from the config.ini.
+ bool shakeEnabled() const;
+ void setShakeEnabled(bool value);
+
+ // Returns the value of whether effects should be Enabled.
+ // from the config.ini.
+ bool effectsEnabled() const;
+ void setEffectsEnabled(bool value);
+
+ // Returns the value of whether frame-specific effects defined in char.ini
+ // should be sent/received over the network. from the config.ini.
+ bool networkedFrameSfxEnabled() const;
+ void setNetworkedFrameSfxEnabled(bool value);
+
+ // Returns the value of whether colored ic log should be a thing.
+ // from the config.ini.
+ bool colorLogEnabled() const;
+ void setColorLogEnabled(bool value);
+
+ // Returns the value of whether sticky sounds should be a thing.
+ // from the config.ini.
+ bool clearSoundsDropdownOnPlayEnabled() const;
+ void setClearSoundsDropdownOnPlayEnabled(bool value);
+
+ // Returns the value of whether sticky effects should be a thing.
+ // from the config.ini.
+ bool clearEffectsDropdownOnPlayEnabled() const;
+ void setClearEffectsDropdownOnPlayEnabled(bool value);
+
+ // Returns the value of whether sticky preanims should be a thing.
+ // from the config.ini.
+ bool clearPreOnPlayEnabled() const;
+ void setClearPreOnPlayEnabled(bool value);
+
+ // Returns the value of whether custom chatboxes should be a thing.
+ // from the config.ini.
+ // I am increasingly maddened by the lack of dynamic auto-generation system
+ // for settings.
+ bool customChatboxEnabled() const;
+ void setCustomChatboxEnabled(bool value);
+
+ // Returns the value of characer sticker (avatar) setting
+ bool characterStickerEnabled() const;
+ void setCharacterStickerEnabled(bool value);
+
+ // Returns the value of whether continuous playback should be used
+ // from the config.ini.
+ bool continuousPlaybackEnabled() const;
+ void setContinuousPlaybackEnabled(bool value);
+
+ // Returns the value of whether stopping music by double clicking category
+ // should be used from the config.ini.
+ bool stopMusicOnCategoryEnabled() const;
+ void setStopMusicOnCategoryEnabled(bool value);
+
+ // Returns the value of the maximum amount of lines the IC chatlog
+ // may contain, from config.ini.
+ int maxLogSize() const;
+ void setMaxLogSize(int value);
+
+ // Current wait time between messages for the queue system
+ int textStayTime() const;
+ void setTextStayTime(int value);
+
+ // Returns the letter display speed during text crawl in in-character messages
+ int textCrawlSpeed() const;
+ void setTextCrawlSpeed(int value);
+
+ // Returns Minimum amount of time (in miliseconds) that must pass before the
+ // next Enter key press will send your IC message. (new behaviour)
+ int chatRateLimit() const;
+ void setChatRateLimit(int value);
+
+ // Returns whether the log should go upwards (new behaviour)
+ // or downwards (vanilla behaviour).
+ bool logDirectionDownwards() const;
+ void setLogDirectionDownwards(bool value);
+
+ // Returns whether the log should separate name from text via newline or :
+ bool logNewline() const;
+ void setLogNewline(bool value);
+
+ // Get spacing between IC log entries.
+ int logMargin() const;
+ void setLogMargin(int value);
+
+ // Returns whether the log should have a timestamp.
+ bool logTimestampEnabled() const;
+ void setLogTimestampEnabled(bool value);
+
+ // Returns the format string for the log timestamp
+ QString logTimestampFormat() const;
+ void setLogTimestampFormat(QString value);
+
+ // Returns whether to log IC actions.
+ bool logIcActions() const;
+ void setLogIcActions(bool value);
+
+ // Returns the username the user may have set in config.ini.
+ QString username() const;
+ void setUsername(QString value);
+
+ // Returns the audio device used for the client.
+ QString audioOutputDevice() const;
+ void setAudioOutputDevice(QString value);
+
+ // Returns whether the user would like to have custom shownames on by default.
+ bool customShownameEnabled() const;
+ void setCustomShownameEnabled(bool value);
+
+ // Returns the showname the user may have set in config.ini.
+ QString shownameOnJoin() const;
+ void setShownameOnJoin(QString value);
+
+ // Returns if the user has casing alerts Enabled.
+ bool casingAlertEnabled() const;
+ void setCasingAlertEnabled(bool value);
+
+ // Returns if the user wants to get alerts for the defence role.
+ bool casingDefenceEnabled() const;
+ void setcasingDefenceEnabled(bool value);
+
+ // Same for prosecution.
+ bool casingProsecutionEnabled() const;
+ void setCasingProseuctionEnabled(bool value);
+
+ // Same for judge.
+ bool casingJudgeEnabled() const;
+ void setCasingJudgeEnabled(bool value);
+
+ // Same for juror.
+ bool casingJurorEnabled() const;
+ void setCasingJurorEnabled(bool value);
+
+ // Same for steno.
+ bool casingStenoEnabled() const;
+ void setCasingStenoEnabled(bool value);
+
+ // Same for CM.
+ bool casingCmEnabled() const;
+ void setCasingCmEnabled(bool value);
+
+ // Get the message for the CM for casing alerts.
+ QString casingCanHostCases() const;
+ void setCasingCanHostCases(QString value);
+
+ // Get if text file logging is Enabled
+ bool logToTextFileEnabled() const;
+ void setLogToTextFileEnabled(bool value);
+
+ // Get if demo logging is Enabled
+ bool logToDemoFileEnabled() const;
+ void setLogToDemoFileEnabled(bool value);
+
+ // Get the subtheme from settings
+ QString subTheme() const;
+ void setSubTheme(QString value);
+
+ // Get if the theme is animated
+ bool animatedThemeEnabled() const;
+ void setAnimatedThemeEnabled(bool value);
+
+ // Get the default scaling method
+ QString defaultScalingMode() const;
+ void setDefaultScalingMode(QString value);
+
+ // Get a list of custom mount paths
+ QStringList mountPaths() const;
+ void setMountPaths(QStringList value);
+
+ // Get whether to opt out of player count metrics sent to the master server
+ bool playerCountOptout() const;
+ void setPlayerCountOptout(bool value);
+
+ // Get if sfx can be sent to play on idle
+ bool playSelectedSFXOnIdle() const;
+ void setPlaySelectedSFXOnIdle(bool value);
+
+ // Whether opening evidence requires a single or double click
+ bool evidenceDoubleClickEdit() const;
+ void setEvidenceDoubleClickEdit(bool value);
+
+ // Supplies an alternative masterserver URL
+ QString alternativeMasterserver() const;
+ void setAlternativeMasterserver(QString value);
+
+ // Language the client loads on start.
+ QString language() const;
+ void setLanguage(QString value);
+
+ // Callwords notify the user when the word/words are used in a game message.
+ QStringList callwords() const;
+ void setCallwords(QStringList value);
+
+ // Clears the configuration file. Essentially restoring it to default.
+ void clearConfig();
+};
+
+#endif // OPTIONS_H
diff --git a/include/widgets/aooptionsdialog.h b/include/widgets/aooptionsdialog.h
new file mode 100644
index 000000000..21fc322b6
--- /dev/null
+++ b/include/widgets/aooptionsdialog.h
@@ -0,0 +1,175 @@
+#ifndef AOOPTIONSDIALOG_H
+#define AOOPTIONSDIALOG_H
+
+#include "options.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+class AOApplication;
+
+struct OptionEntry {
+ std::function load;
+ std::function save;
+};
+
+class AOOptionsDialog : public QDialog {
+ Q_OBJECT
+public:
+ explicit AOOptionsDialog(QDialog *parent = nullptr,
+ AOApplication *p_ao_app = nullptr);
+
+private:
+ AOApplication *ao_app;
+
+ // Dialog interaction buttons. Save/Discard/Restore Defaults
+ QDialogButtonBox *ui_settings_buttons;
+
+ // The gameplay tab
+ QWidget *ui_settings_widget;
+ QComboBox *ui_theme_combobox;
+ QComboBox *ui_subtheme_combobox;
+ QPushButton *ui_theme_reload_button;
+ QPushButton *ui_theme_folder_button;
+ QCheckBox *ui_evidence_double_click_cb;
+ QCheckBox *ui_animated_theme_cb;
+ QSpinBox *ui_stay_time_spinbox;
+ QCheckBox *ui_instant_objection_cb;
+ QSpinBox *ui_text_crawl_spinbox;
+ QSpinBox *ui_chat_ratelimit_spinbox;
+ QFrame *ui_log_names_divider;
+ QLineEdit *ui_username_textbox;
+ QCheckBox *ui_showname_cb;
+ QLineEdit *ui_default_showname_textbox;
+ QFrame *ui_net_divider;
+ QLineEdit *ui_ms_textbox;
+ QCheckBox *ui_discord_cb;
+ QLabel *ui_language_label;
+ QComboBox *ui_language_combobox;
+ QLabel *ui_scaling_label;
+ QComboBox *ui_scaling_combobox;
+ QCheckBox *ui_shake_cb;
+ QCheckBox *ui_effects_cb;
+ QCheckBox *ui_framenetwork_cb;
+ QCheckBox *ui_colorlog_cb;
+ QCheckBox *ui_stickysounds_cb;
+ QCheckBox *ui_stickyeffects_cb;
+ QCheckBox *ui_stickypres_cb;
+ QCheckBox *ui_customchat_cb;
+ QCheckBox *ui_sticker_cb;
+ QCheckBox *ui_continuous_cb;
+ QCheckBox *ui_category_stop_cb;
+ QCheckBox *ui_sfx_on_idle_cb;
+
+ // The callwords tab
+ QPlainTextEdit *ui_callwords_textbox;
+ QCheckBox *ui_callwords_char_textbox;
+
+ // The audio tab
+ QWidget *ui_audio_tab;
+ QWidget *ui_audio_widget;
+ QFormLayout *ui_audio_layout;
+ QComboBox *ui_audio_device_combobox;
+ QSpinBox *ui_music_volume_spinbox;
+ QSpinBox *ui_sfx_volume_spinbox;
+ QSpinBox *ui_blips_volume_spinbox;
+ QSpinBox *ui_suppress_audio_spinbox;
+ QFrame *ui_volume_blip_divider;
+ QSpinBox *ui_bliprate_spinbox;
+ QCheckBox *ui_blank_blips_cb;
+ QCheckBox *ui_loopsfx_cb;
+ QCheckBox *ui_objectmusic_cb;
+ QCheckBox *ui_disablestreams_cb;
+
+ // The casing tab
+ QGroupBox *ui_casing_enabled_box;
+ QCheckBox *ui_casing_def_cb;
+ QCheckBox *ui_casing_pro_cb;
+ QCheckBox *ui_casing_jud_cb;
+ QCheckBox *ui_casing_jur_cb;
+ QCheckBox *ui_casing_steno_cb;
+ QCheckBox *ui_casing_cm_cb;
+ QLineEdit *ui_casing_cm_cases_textbox;
+
+ // The asset tab
+ QListWidget *ui_mount_list;
+ QPushButton *ui_mount_add;
+ QPushButton *ui_mount_remove;
+ QPushButton *ui_mount_up;
+ QPushButton *ui_mount_down;
+ QPushButton *ui_mount_clear_cache;
+
+ // The logging tab
+ QCheckBox *ui_downwards_cb;
+ QSpinBox *ui_length_spinbox;
+ QCheckBox *ui_log_newline_cb;
+ QSpinBox *ui_log_margin_spinbox;
+ QLabel *ui_log_timestamp_format_lbl;
+ QCheckBox *ui_log_timestamp_cb;
+ QComboBox *ui_log_timestamp_format_combobox;
+ QCheckBox *ui_desync_logs_cb;
+ QCheckBox *ui_log_ic_actions_cb;
+ QCheckBox *ui_log_text_cb;
+ QCheckBox *ui_log_demo_cb;
+
+ /**
+ * Allows the AO2 master server hoster to go broke.
+ */
+ QWidget *ui_privacy_tab;
+ QVBoxLayout *ui_privacy_layout;
+ QCheckBox *ui_privacy_optout_cb;
+ QFrame *ui_privacy_separator;
+ QTextBrowser *ui_privacy_policy;
+
+ bool asset_cache_dirty = false;
+
+ bool needsDefaultAudioDevice();
+ void populateAudioDevices();
+ void updateValues();
+
+ QVector optionEntries;
+
+ template
+ void setWidgetData(T *widget, const V &value);
+
+ template V widgetData(T *widget) const;
+
+ template
+ void registerOption(const QString &widgetName, V (Options::*getter)() const,
+ void (Options::*setter)(V));
+
+signals:
+ void reloadThemeRequest();
+
+private slots:
+ void savePressed();
+ void discardPressed();
+ void buttonClicked(QAbstractButton *button);
+ void onTimestampFormatEdited();
+ void timestampCbChanged(int state);
+ void onReloadThemeClicked();
+ void themeChanged(int i);
+};
+
+#endif // AOOPTIONSDIALOG_H
diff --git a/resource/translations/ao_de.qm b/resource/translations/ao_de.qm
index 0b914aa15..0c5e8fd90 100644
Binary files a/resource/translations/ao_de.qm and b/resource/translations/ao_de.qm differ
diff --git a/resource/translations/ao_de.ts b/resource/translations/ao_de.ts
index caf9c6ace..0e2cba946 100644
--- a/resource/translations/ao_de.ts
+++ b/resource/translations/ao_de.ts
@@ -4,127 +4,69 @@
AOApplication
-
+
Vom Server getrennt.
-
- Fehler bei der Verbindung zum Master Server. Erneuter Versuch in %1 Sekunden.
-
-
-
- Fehler bei der Verbindung zum Master Server. Erneuter Versuch in %n Sekunden.
-
-
-
- Es gab einen Fehler beim Verbinden zum Master Server.
-Wir verwenden mehrere Master Server um Ausfälle zu verhindern, jedoch hat der Client alle Möglichkeiten einen zu finden erschöpft.
-Bitte prüfe deine Internetverbindung und Firewall, und versuche es erneut.
-
-
-
- Version zu alt! Deine Version: %1
-Bitte besuche aceattorneyonline.com für ein Update.
-
-
-
- Du wurdest von AO befreit.
-Schönen Urlaub.
-
-
-
- Attorney Online
-
-
-
+
Laden
-
- Lade Beweisstücke:
-%1/%2
-
-
-
+
Lade Musik:
%1/%2
-
+
Lade Charaktere:
%1/%2
-
+
Attorney Online %1
-
+
-
+ [Globaler Log]
-
+
Du wurdest von diesem Server geschmissen.
Grund: %1
-
+
Du wurdest von diesem Server verbannt.
Grund: %1
-
+
Du bist von diesem Server verbannt.
Grund: %1
-
- Du wurdest von diesem Server geschmissen.
-Grund:
-
-
-
- Du wurdest von diesem Server verbannt.
-Grund:
-
-
-
- Du wurdest rausgeschmissen.
-
-
-
- Du wurdest verbannt.
-
-
-
+
-
+ Demo Wiedergabe
-
+
-
+ Spielt Demo Dateien welche vorher aufgenommen wurden
@@ -164,2112 +106,1824 @@ Grund:
Stenograph benötigt
-
-
- Zeuge benötigt
-
AOOptionsDialog
-
-
- Einstellungen
+
+
+
+ Log Zeitstempel Format:
+
-
-
- Spiel
+
+
+ Pixel
-
-
- Theme:
+
+
+ Glatt
-
-
- Setzt das Theme. Wenn das neue Theme auch das Aussehen der Lobby verändert, must du diese neu laden um die Änderungen zu sehen.
+
+
+ Datenschutz-Bestimmungen konnten nicht abgerufen werden.
-
- Setzt den Standardwerd für den eigenen Anzeigenamen.
+
+
+ Wähle ein base Ordner
-
- Standardlautstärke für die Musik.
+
+
+ Lade Datenschutz-Bestimmungen...
-
- Standardlautstärke für Soundeffekte.
+
+
+ %1 (Standard)
+
+
+ Courtroom
-
- Log
+
+
+ Passwort
-
- Farbiges Log:
+
+
+ Zuschauer
-
- Aktiviert farbigen Text im Log.
+
+
+
+ Suche
-
- Nur in-Zeilen Farben:
+
+
+ Gesperrt
-
- Nur die in-Zeilen Farben wie <>,|| etc. werden gezeigt.
+
+
+ Benutzt
-
- Log spiegeln:
+
+
+
+ Charakter (char.ini) nicht gefunden für %1
-
- Das Log spiegelt die Nachrichten. Bedeutet dass wenn jemand unterbrochen wird, kann man nicht sehen was derjenige sagen wollte. Für ein realistischeres Spielerlebnis.
+
+
+ Generiere Charaktere:
+%1/%2
-
-
- Verlauf geht nach unten:
+
+
+ Anzeigename
-
-
- Wenn angehakt werden neue Nachrichten unten erscheinen (wie beim OOC). Das traditionelle (AO1) Verhalten wäre nicht angehakt.
+
+
+ Name
-
-
- Länge:
+
+
+ Vor
-
- Die Menge an Nachrichten die aufgehoben werden bevor alte gelöscht werden. 0 bedeutet unendlich.
+
+
+ Spiegeln
-
-
- Absätze protokollieren:
+
+
+ Wache
-
-
- Wenn Nachrichten mehrere Zeilen enthalten wird dies mitprotokolliert.
+
+
+
+ Fall
-
-
- Protokollabstand:
+
+
+ Anzeigenamen
-
-
- Setzt den Abstand zwischen den Zeilen im Protokoll. Standard: 0.
+
+
+ Keine Unterbrechung
-
-
- Zeitstempel:
+
+
+ Musik
-
-
- Das Protokoll enthält vor dem Namen einen Zeitstempel in UTC.
+
+
+ Sfx
-
-
- Aktionen protokollieren:
+
+
+ Blips
-
-
- Protokolliert Charakteraktionen wie Zwischenrufe und Beweisstücke.
+
+
+
+ Server
-
-
- Standzeit:
+
+
+ Charakter ändern
-
- Minimale Zeit (in Milisekunden) die eine Nachricht auf dem Bildschirm bleibt bevor die nächste gezeigt wird. 0 deaktiviert dies.
+
+
+ Aussehen neu laden
-
-
- Protokoll desynchronisieren:
+
+
+ Moderator rufen
-
-
- Wenn angehakt werden die Nachrichten sofort im Protokoll angezeigt, ansonsten wartet es auf den Chat.
+
+
+ Einstellungen
-
-
- Zwischenrufe sofort:
+
+
+ A/M
-
-
- Wenn die Standzeit länger als 0 ist überspringen Zwischenrufe die Warteschleife.
+
+
+ Voranimation
-
-
- Standard Benutzername:
+
+
+ Zurück zur Lobby
-
-
- Dein OOC Name wird automatisch auf dies gesetzt.
+
+
+ Du hast nun den "Modcall deaktivieren" Knopf.
-
-
- Eigener Anzeigename:
+
+
+ Du wurdest verbannt.
-
-
- Standardwert für die Anzeigename Box, welche den In-Charakter Namen bestimmt.
+
+
+
+ Keine
-
- Rückfall MS:
+
+
+ Nachricht als Charakter
-
- Wenn dereingebaute Master Server fehlschlägt, wird das Spiel diesen hier verwenden.
+
+
+ Nachricht out-of-character
-
-
- Discord:
+
+
+ Hinzufügend
-
-
- Erlaubt anderen auf Discord zu sehen auf welchem Server du spielst, welchen Charakter du spielst und wie lange.
+
+
+ Vorne
-
- Schütteln/Geistesblitz erlauben:
+
+
+ Hinten
-
- Erlaubt schütteln des Bildschirms und weiße Blitze. Deaktiviere dies falls du Bedenken wegen Photosensitivität hast.
+
+
+ Log geht nach unten
-
-
- Sprache:
+
+
+ Log geht nach oben
-
-
- Setzte die Sprache falls du nicht die Systemsprache verwenden möchtest.
+
+
+ Wähle einen Charakter mit dem du gepaart sein möchtest.
-
- Langsamerer Text:
+
+
+ Ändere die Reihenfolge in der die Charaktere erscheinen.
-
- Setzt den Text auf die gleiche Geschwindigkeit wie in den AA Spielen.
+
+
+ Zeigt die Liste der paarbaren Charaktere.
-
- Blip Pausen bei Satzzeichen:
+
+
+ Ohje, du bist stumm!
-
- Aktivieren damit die Blips bei Satzzeichen langsamer werden.
+
+
+ Setzt den Ausdruck für die nächste Nachricht.
-
-
- Untertheme:
+
+
+ Setzt die Position des Charakters.
-
-
- Setzt ein 'Untertheme', das alles aus dem aktuellen Theme ersetzt. Lass es auf 'Server' um den Server entscheiden zu lassen. 'Standard' um es so zu lassen.
+
+
+ Ändert den Hoizontalen Abstand relativ zur Mitte.
-
-
- Aussehen neu laden
+
+
+ Ändert den vertikalen Abstand relativ zur Mitte.
-
-
- Aktualisiert das Design und alle UI Elemente.
+
+
+ Setzt den Zusatzhintergrund deines Charakters zurück.
-
-
- Animiertes Theme:
+
+
+ Setz einen 'iniswap', oder einen anderen Charakterordner von deinem aktuellen Charakter.
+Bearbeiten durch tippen und Enter drücken, [X] zum entfernen. Das wird in base/iniswaps.ini gespeichert.
-
-
- Aktiviert animierte Theme Elemente.
+
+
+ Entfernt den aktuellen iniswap von der Liste und stellt den originalen Ordner wieder her.
-
-
- Die menge an Zeilen die das IC Log behält bevor ältere Nachrichten gelöscht werden. 0 bedeutet unendlich.
+
+
+ Wähle einen Soundeffekt der bei der nächsten 'Preanim' gespielt wird. Lasse dies auf Standard um den emote-Sound zu verwenden.
+Bearbeiten durch tippen und Enter drücken, [X] zum entfernen. Das wird in base/characters/<charname>/soundlist.ini gespeichert.
-
-
-
-
+
+
+ Entfernt den aktuell ausgewählten Soundeffekt.
-
-
- Minimale Zeit (in Milisekunden) die eine IC Nachricht auf dem Bildschirm bleibt bevore die nächste kommt, wie eine Art 'Warteschlange'. 0 deaktiviert das.
+
+
+ Wähle einen Effekt für die nächste Nachricht.
+Die Effekte sind definiert in theme/effects/effects.ini. Dein Charakter kann eigene Effekte in der
+char.ini [Options] Kategorie, effects = 'miscname' haben welcher dann misc/<miscname>/effects.ini liest.
-
-
- Kriechender Text:
+
+
+ Moment mal!
-
-
- Zeit (in Milisekunden) für jeden Buchstaben.
+
+
+
+
+ Wenn dies an ist, wird die Nächste Nachricht ein Zuruf!
-
-
- Chat Rate Limit:
+
+
+ Einspruch!
-
-
- Minimale Zeit (in Milisekunden) die verstreichen müssen bevore der nächste Enter Druck die Nachricht versendet.
+
+
+ Nimm das!
-
-
-
+
+
+ Wechselt zwischen Serverchat und AO2 Chat.
-
-
-
+
+
+
+
+
+ Dies zeigt die Animation im Spielfeld sobald es angeklickt wird.
-
-
-
+
+
+ Schuldig!
-
-
-
+
+
+ Zeige die Charakterauswahl und ändere deinen Charakter.
-
-
- - aktuelle Einstellung behalten
-
-
-
-
-
+
+
+ Aktualisiert das Design und alle UI Elemente.
-
-
-
+
+
+ Fordere einen Moderator an.
-
-
-
+
+
+ Lässt dich verschiedene Dinge des Clients anpassen.
-
-
-
+
+
+ Ein Menü um einen Fall anzukündigen (du musst dafür erst CM sein)
-
-
- Schütteln erlauben:
+
+
+ Wechsel zwischen Areal- und Musikliste
-
-
- Erlaubt schütteln des Bildschirms. Deaktiviere dies falls du Bedenken wegen Photosensitivität hast.
+
+
+ Zeigt eine Animation vor dem Sprechen.
-
-
- Effekte erlauben:
+
+
+ Starte sofort zu sprechen, ohne auf das Ende der Voranimation zu warten.
-
-
- Erlaubt Bildeffekte. Deaktiviere dies falls du Bedenken wegen Photosensitivität hast.
+
+
+ Spiegelt die Emotes deines Charakters.
-
-
- Netzwerk Frame-Effekte:
+
+
+ Füge Text zu deiner letzten Nachricht hinzu.
-
-
- Sendet schüttel, Blitze und Geräusche aus der char.ini Datei über das Netzwerk. Funkioniert nur wenn der Server dies unterstützt.
+
+
+ Ignoriere Modcalls und spiel keinen Ton ab.
-
-
- Farben im IC Log:
+
+
+ Lässt dich Fallalarme erhalten.
+(Du kannst dies in den Einstellungen anpassen!)
-
-
- Verwendet Farbe im IC Log so wie im Bild.
+
+
+ Zeigt selbst einstellbare Namen für alle.
-
-
- Klebende Geräuschauswahl:
+
+
+ Eigener Zwischenruf!
-
-
- Aktiviere dies damit die Geräuschauswahl nicht zurückspringt nachdem es abgespielt wurde.
+
+
+ Dies zeigt des Charakters eigenen Zwischenruf.
+Um einen zu haben muss im Charakterordner eine custom.[webp/apng/gif/png] und ein custom.[wav/ogg/opus] Soundeffekt sein
-
-
- Klebende Effekt:
+
+
+ Spiele den Realisierung Sound und Animation mit der nächsten Nachricht.
-
-
- Aktiviere dies damit die Effektauswahl nicht zurückspringt nachdem er abgespielt wurde.
+
+
+ Schüttelt den Bildschirm bei der nächsten Nachricht.
-
-
- Klebende Voranimation:
+
+
+ Zeigt die Charakterliste um einen stumm zu schalten.
-
-
- Aktiviere dies damit das Kontrollkästchen für die Voranimation nicht zurückspringt nachdem sie abgespielt wurde.
+
+
+
+ Erhöhe die Gesundheit.
-
-
- Eigene Chatboxen:
+
+
+
+ Verringere die Gesundheit.
-
-
- Charaktere können ihre eigenen Chatboxen verwenden.
+
+
+ Ändert die Textfarbe.
+Du kannst auch nur einen Teil der Nachricht auswählen und dessen Farbe ändern!
-
-
- Sticker:
+
+
+ Zurück zur Serverliste.
-
-
- An zeigt 'Sticker' an, kleine Bilder wie Avatare.
+
+
+ Werde ein Zuschauer. Es ist dir nicht möglich mit dem Spielfeld zu interagieren.
-
-
- Durchgehendes Abspielen:
+
+
+
+
+
+ CLIENT
-
-
- Spielt Animationen wieder dort ab wo sie aufgehört haben. Ausschalten kann bei Lag helfen.
+
+
+ Login erfolgreich.
-
-
- Musik durch eine Kategorie stoppen:
+
+
+ Du wurdest ausgeloggt.
-
-
- Stoppt die Musik wenn eine Kategorie doppelt geklickt wird. Wenn dies deaktiviert ist, benutze die Rechte Maustaste und das Kontextmenü um die Musik anzuhalten.
+
+
+ MOMENT MAL!
-
-
-
+
+
+ EINSPRUCH!
-
-
-
+
+
+ NIMM DAS!
-
-
-
+
+
+ SPEZIALRUF!
-
-
-
+
+
+
+
+
+
+ Zwischenruf
-
-
- Alarmwörter
+
+
+
+
+
+ hat Beweis präsentiert
-
-
- <html><head/><body>Gib so viele Alarmwörter ein wie du möchtest. Groß/Kleinschreibung ist egal. Für jede Wort nur eine Zeile!<br>Bitte keine leere Zeile am Ende -- du bekommst sonst bei jeder Nachricht einen Alarm.</body></html>
+
+
+
+
+ hat die Musik angehalten
-
-
- Audio
+
+
+ [LADEN] %1
-
-
- Audiogerät:
+
+
+ Debug
-
-
- Setzt das Audiogerät für all Geräusche.
+
+
+
+ spielte ein Lied
-
-
- Musik:
+
+
+ Du hattest keinen 'base/cases' Ordner! Ich hab ihn nun angelegt aber bedenke das er leer sein wird.
-
-
- Setzt die Musiklautstärke.
+
+
+ Du musst einen Dateinamen angeben (ohne .ini). Stelle sicher das er im 'base/cases' Ordner ist und das er korrekt formatiert ist.
+Verfügbare Fälle: %1
-
-
- SFX:
+
+
+ Fall von %1.
-
-
- Setzt die Lautstärke der Soundeffekte wie Einsprüche und die Geräusche der Charaktere.
+
+
+ Gehe zu %1 für das CM Dokument.
-
-
- Blips:
+
+
+
+ UNBEKANNT
-
-
- Setzt die Lautstärke der Blips, das ist das Geräusch das die Charaktere beim Reden machen.
+
+
+ Dein Fall "%1" wurde geladen!
-
-
- Bliprate:
+
+
+ Zu viele Argumente! Du brauchst nur den Dateinamen, ohne Erweiterung.
-
-
- Setzt die Pause zwischen einzelnen Blips.
+
+
+ Du hattest keinen 'base/cases' Ordner! Ich hab ihn nun angelegt aber bedenke das er leer sein wird.
-
-
-
+
+
+ Du musst einen Dateinamen (ohne Erweiterung) angebenn, sowie den Gebietsstatus!
-
-
-
+
+
+ Zu viele Argumente! Du brauchst nur den Dateinamen, ohne Erweiterung sowie den Gebietsstatus!
-
-
-
+
+
+ Erfolgreich gespeichert!
-
- Spiele ein blip einmal für all X Buchstaben.
+
+
+ Lied stoppen
-
-
- Leere Blips:
+
+
+ Zufälliges Lied
-
-
- Wenn angehakt wird das Spiel auch bei einem Leerzeichen einen Blip machen.
+
+
+ Alle Kategorien erweitern
-
-
- Wiederholende Soundeffekte:
+
+
+ Alle Kategorien verstecken
-
-
- Wenn aktiviert, werden wiederholende Soundeffekte bei den Voranimationen erlaubt.
+
+
+ Vorheriges ausblenden
-
-
- Stoppe Musik bei Einspruch:
+
+
+ Einblenden
-
-
- Hält die Musik für alle an wenn du 'Einspruch' benutzt.
+
+
+ Synchronisieren
-
-
-
+
+
+ Standard
-
-
-
+
+
+ Grund:
-
-
-
+
+
+ Moderator rufen
-
-
-
+
+
+
+ Fehler
-
-
-
+
+
+ Du musst einen Grund angeben.
-
-
-
+
+
+ Die Nachricht ist zu lang.
-
-
-
+
+
+ Wähle..
-
-
-
+
+
+ Präsentiere dieses Beweisstück allen in der nächsten Nachricht
-
-
-
+
+
+ Speichere Beweise in einer .ini Datei.
-
-
-
+
+
+ Lade Beweise aus einer .ini Datei.
-
-
-
+
+
+ Zerstöre dieses Beweisstück
-
-
-
-
-
-
- Hält die Musik an wenn jemand "Einspruch" ruft, wie im echten Spiel.
-
-
-
- Autmatisches Protokollieren:
-
-
-
- Schreibt die Protokolle automatisch in den /logs Ordner.
-
-
-
- Hält die Musik an wenn jemand "Einspruch" ruft, wie im echten Spiel.
-
-
-
-
- Fälle
+
+
+ Schließe das Beweisfenster.
+Du wirst gefragt wenn es ungespeicherte Änderungen gibt.
-
-
- Dieser Server unterstützt Fallalarme.
+
+
+ Speichert alle Änderungen an diesem Beweisstück und schickt sie zum Server.
-
-
- Dieser Server unterstützt Fallalarme nicht.
+
+
+ Klick zum editieren. Drücke [X] zum speichern deiner Änderungen.
-
-
- Eigentlich selbsterklärend.
+
+
+ Zeigt die Beweisliste.
-
-
- Fälle:
+
+
+ Wechselt zum eigenen Inventar.
-
-
- Wenn angehakt wirst du benachrichtigt wenn ein Fall angekündigt wird.
+
+
+ Wechselt zum globalen Inventar.
-
-
- Verteidigung:
+
+
+
+ Übertrage Beweisstück zum eigenen Inventar.
-
-
- Wenn angehakt wirst du benachrichtigt wenn ein Verteidiger benötigt wird.
+
+
+
+ Übertrage Beweisstück zum globalen Inventar.
-
-
- Kläger:
+
+
+ Das Beweisstück das du bearbeitet hast hat sich verändert.
-
-
- Wenn angehakt wirst du benachrichtigt wenn ein Kläger benötigt wird.
+
+
+ Möchtest du deine Änderungen behalten?
-
-
- Richter:
+
+
+ Name: %1
+Bild: %2
+Beschreibung:
+%3
-
-
- Wenn angehakt wirst du benachrichtigt wenn ein Richter benötigt wird.
+
+
+ Bilder (*.png)
-
-
- Jury:
+
+
+
+
+ Klicken zum bearbeiten...
-
-
- Wenn angehakt wirst du benachrichtigt wenn eine Jury benötigt wird.
+
+
+ Neues Beweisstück...
-
-
- Stenograph:
+
+
+ Beweise wurden verändert.
-
-
- Wenn angehakt wirst du benachrichtigt wenn ein Stenograph benötigt wird.
+
+
+ Möchtest du deine Änderungen speichen?
-
-
- CM:
+
+
+ Beweise sind global. Klicken um zu eigenen zu wechseln.
-
-
- Wenn angehakt wirst du als potentielle CM angezeigt.
+
+
+ Beweise sind die eigenen. Klicken um zu global zu wechseln.
-
- Zeuge:
+
+
+ "%1" wurde übertragen.
-
- Wenn angehakt wirst du als potentielle Zeuge angezeigt.
+
+
+ Inventar speichen
-
-
- Fallleitung:
+
+
+
+ Ini Dateien (*.ini)
-
-
- Wenn du CM bist, gib ein welche Fälle du spielen möchtest.
+
+
+ Inventar öffnen
- Courtroom
-
-
-
- Passwort
-
-
-
-
- Zuschauer
-
-
-
-
-
- Suche
-
-
-
-
- Gesperrt
-
-
-
-
- Benutzt
-
-
-
-
-
-
-
-
-
- Generiere Charaktere:
-%1/%2
-
-
-
- Generiere Charaktere:
-
-
-
-
- Konnte %1 nicht finden
-
-
-
-
- Anzeigename
-
-
-
-
- Nachricht
-
-
-
- OOC Nachricht
-
-
-
-
- Name
-
-
-
-
- Vor
-
+ DemoServer
-
-
- Spiegeln
+
+
+
+ Demo laden
-
-
- Wache
+
+
+
+ Demos (*.demo)
-
- Deaktiviere Moderatorenrufe
+
+
+
+ Demo geladen. Sende /play oder > in OOC um Wiedergabe zu beginnen.
-
-
-
- Fall
+
+
+ Wiedergabe fortsetzen.
-
-
- Anzeigenamen
+
+
+ Wiedergabe pausieren.
-
-
- Keine Unterbrechung
+
+
+ Setze max_wait zu
-
- Weiß
+
+
+
+ millisekunden.
-
- Grün
+
+
+ Kein valider Integer!
-
- Rot
+
+
+ Aktueller max_wait ist
-
- Orange
+
+
+ Demo Datei neugeladen. Sende /play or > in OOC um die Wiedergabe zu beginnen.
-
- Blau
+
+
+ min_wait ist veraltet. Benutze die Client Einstellung Standzeit!
-
- Gelb
+
+
+ Setze Debug Modus zu %1
-
-
- Musik
+
+
+ Gültige Werte sind 1 oder 0!
-
-
- Sfx
+
+
+
-
-
- Blips
+
+
+ Verfügbate Kommandos:
+load, reload, play, pause, max_wait, debug, help
-
- Verlaufsgrenze
+
+
+ Ende der Demo Datei erreicht. Sende /play oder > um die Wiedergabe neuzustarten oder /load um eine neue Datei zu öffnen.
+
+
+ Lobby
-
-
-
- Server
+
+
+ Attorney Online %1
-
-
- Charakter ändern
+
+
+ Suche
-
-
- Aussehen neu laden
+
+
+ Dein Client ist nicht korrekt eingerichtet.
+Hast du ALLES von tiny.cc/getao heruntergeladen und entpackt, auch den großen 'base' Ordner?
-
-
- Moderator rufen
+
+
+ Version: %1
-
+
Einstellungen
-
-
- A/M
-
-
-
-
- Voranimation
-
-
-
-
- Zurück zur Lobby
-
-
-
-
- Du hast nun den "Modcall deaktivieren" Knopf.
-
-
-
-
- Du wurdest verbannt.
-
-
-
- Zu viele Argumente zum Speichern! Bitte gib nur den Dateinamen ohne Erweiterung und den Saalstatus an.
-
-
-
- %1 hat ein Lied gespielt: %2
-
-
-
- Regenbogen
-
-
-
- Pink
-
-
-
- Cyan
-
-
-
- % Abstand
-
-
-
- Dir wurde der Wache Knopf gegeben.
-
-
-
- Dies bewirkt nichts, aber egal.
-
-
-
- Dies bewirkt nichts, aber egal.
-
-
-
- Du hast die Einstellungen geöffnet.
-
-
-
- Du wirst nun mit
-
-
-
- gepaart, wenn der andere dies auch tut.
-
-
-
-
-
- Keine
-
-
-
-
- Hinzufügend
-
-
-
-
- % Horizontaler Abstand
-
-
-
-
- % Vertikaler Abstand
-
-
-
-
- Vorne
-
-
-
-
- Hinten
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Wähle einen Charakter mit dem du gepaart sein möchtest.
-
-
-
- Ändere den Abstand des Charakters zur Mitte.
-
-
-
-
- Ändere die Reihenfolge in der die Charaktere erscheinen.
-
-
-
-
- Zeigt die Liste der paarbaren Charaktere.
-
-
-
-
- Ohje, du bist stumm!
-
-
-
-
- Setzt den Ausdruck für die nächste Nachricht.
-
-
-
-
- Setzt die Position des Charakters.
-
-
-
- Setz einen 'iniswap', oder einen anderen Charakterordner von deinem aktuellen Charakter.
-Bearbeiten durch tippen und Enter drücken, [X] zum entfernen. Das wird in base/characters/<charname>/iniswaps.ini gespeichert.
-
-
-
-
- Ändert den Hoizontalen Abstand relativ zur Mitte.
-
-
-
-
- Ändert den vertikalen Abstand relativ zur Mitte.
-
-
-
-
- Setzt den Zusatzhintergrund deines Charakters zurück.
-
-
-
-
- Setz einen 'iniswap', oder einen anderen Charakterordner von deinem aktuellen Charakter.
-Bearbeiten durch tippen und Enter drücken, [X] zum entfernen. Das wird in base/iniswaps.ini gespeichert.
-
-
-
-
- Entfernt den aktuellen iniswap von der Liste und stellt den originalen Ordner wieder her.
-
-
-
-
- Wähle einen Soundeffekt der bei der nächsten 'Preanim' gespielt wird. Lasse dies auf Standard um den emote-Sound zu verwenden.
-Bearbeiten durch tippen und Enter drücken, [X] zum entfernen. Das wird in base/characters/<charname>/soundlist.ini gespeichert.
-
-
-
-
- Entfernt den aktuell ausgewählten Soundeffekt.
-
-
-
-
- Wähle einen Effekt für die nächste Nachricht.
-Die Effekte sind definiert in theme/effects/effects.ini. Dein Charakter kann eigene Effekte in der
-char.ini [Options] Kategorie, effects = 'miscname' haben welcher dann misc/<miscname>/effects.ini liest.
-
-
-
-
- Moment mal!
-
-
-
-
-
-
- Wenn dies an ist, wird die Nächste Nachricht ein Zuruf!
-
-
-
-
- Einspruch!
-
-
-
-
- Nimm das!
-
-
-
-
- Wechselt zwischen Serverchat und AO2 Chat.
-
-
-
-
-
-
-
- Dies zeigt die Animation im Spielfeld sobald es angeklickt wird.
-
-
-
-
- Schuldig!
-
-
-
-
- Zeige die Charakterauswahl und ändere deinen Charakter.
-
-
-
-
- Aktualisiert das Design und alle UI Elemente.
-
-
-
-
- Fordere einen Moderator an.
-
-
-
+
- Lässt dich verschiedene Dinge des Clients anpassen.
-
-
-
-
- Ein Menü um einen Fall anzukündigen (du musst dafür erst CM sein)
-
-
-
-
- Wechsel zwischen Areal- und Musikliste
-
-
-
-
- Zeigt eine Animation vor dem Sprechen.
-
-
-
-
- Starte sofort zu sprechen, ohne auf das Ende der Voranimation zu warten.
+ Erlaubt es verschiedene Aspekte des Clients zu ändern.
-
-
- Spiegelt die Emotes deines Charakters.
+
+
+ Laden
-
-
- Füge Text zu deiner letzten Nachricht hinzu.
+
+
+ Abbrechen
-
-
- Ignoriere Modcalls und spiel keinen Ton ab.
+
+
+
-
-
- Lässt dich Fallalarme erhalten.
-(Du kannst dies in den Einstellungen anpassen!)
+
+
+ Entfernen
-
-
- Zeigt selbst einstellbare Namen für alle.
+
+
+ Fehler beim abrufen der Nachricht des Tages.
-
-
- Eigener Zwischenruf!
+
+
+ Version: %1 (!)
-
-
- Dies zeigt des Charakters eigenen Zwischenruf.
-Um einen zu haben muss im Charakterordner eine custom.[webp/apng/gif/png] und ein custom.[wav/ogg/opus] Soundeffekt sein
+
+
+ Neue Version verfügbar:%1
-
-
- Spiele den Realisierung Sound und Animation mit der nächsten Nachricht.
+
+
+ Ja
-
-
- Schüttelt den Bildschirm bei der nächsten Nachricht.
+
+
+ Nein
-
-
- Zeigt die Charakterliste um einen stumm zu schalten.
+
+
+ Über
-
-
-
- Erhöhe die Gesundheit.
+
+
+ Online: %1/%2
-
-
-
- Verringere die Gesundheit.
+
+
+
+
+ Offline
+
+
+ NetworkManager
-
-
- Ändert die Textfarbe.
-Du kannst auch nur einen Teil der Nachricht auswählen und dessen Farbe ändern!
+
+
+ Keine Beschreibung erhalten.
+
+
+ QDialogButtonBox
-
-
- Zurück zur Serverliste.
+
+
+
+ OK
+
+
+ QObject
-
-
- Werde ein Zuschauer. Es ist dir nicht möglich mit dem Spielfeld zu interagieren.
+
+
+ [FEHLT] Streaming deaktiviert.
-
-
-
-
-
-
- CLIENT
+
+
+
+ Keine
-
-
-
+
+
+ [FEHLT] %1
-
-
-
+
+
+ [STREAM] %1
+
+
+ chatlogpiece
-
-
- MOMENT MAL!
+
+
+
+
+ UNBEKANNT
+
+
+ debug_functions
-
-
- EINSPRUCH!
+
+
+ Fehler: %1
-
-
- NIMM DAS!
+
+
+ Fehler
-
-
- SPEZIALRUF!
+
+
+ Hinweis
+
+
+ optionsdialogue
-
-
-
-
-
- Zwischenruf
+
+
+ Einstellungen
-
-
-
-
- hat Beweis präsentiert
+
+
+ Spiel
-
-
-
-
- hat die Musik angehalten
+
+
+ Stoppt die Musik wenn eine Kategorie doppelt geklickt wird. Wenn dies deaktiviert ist, benutze die Rechte Maustaste und das Kontextmenü um die Musik anzuhalten.
-
-
-
+
+
+ Musik durch eine Kategorie stoppen:
-
-
+
+
-
- [STREAM] %1
+
+
+ Skalierung:
-
- [FEHLT] %1
+
+
+ Charaktere können ihre eigenen Chatboxen verwenden.
-
-
-
- spielte ein Lied
+
+
+ Eigene Chatboxen:
-
- Du paarst dich nun mit %1 wenn diese deinen Charakter auch gewählt haben.
+
+
+ Erlaubt Bildeffekte. Deaktiviere dies falls du Bedenken wegen Photosensitivität hast.
-
- Du bist nicht mehr gepaart.
+
+
+ Effekte erlauben:
-
- Hast du dich vertippt? Die ID konnte nicht erkannt werden.
+
+
+ Öffnet den Ordner des aktuell ausgewählten Theme.
-
- Dein Abstand ist auf %1%% gesetzt.
+
+
+ Öffne Theme Ordner
-
- Dein Abstand ist auf
+
+
+ Überschreibt die Standard URL für den Abruf von Server Informationen.
-
- Der Abstand muss zwischen -100% und 100% liegen!
+
+
+ Alternative Serverliste:
-
- Das sieht nicht wie ein Abstand aus.
+
+
+ Zwischenrufe sofort:
-
- Du hast deinen vertikalen Abstand auf %1%% gesetzt.
+
+
+
+
+ ms
-
- Dein vertikaler Abstand muss zwischen -100% und 100% sein!
+
+
+
-
- Das sieht nicht wie ein Abstand aus.
+
+
+ Theme:
-
- Du hast zwischen Musik- und Gebitsliste umgeschaltet.
+
+
+
-
- Du hast Funktionen erzwungen die der Server eventuell nicht unterstützt. Möglicherweise wirst du nicht mehr sprechen können.
+
+
+
-
- Deine Voranimation unterbrechen nun Text.
+
+
+
-
- Deine Voranimation unterbrechen Text nicht.
+
+
+
-
- Konnte chatlog.txt nicht öffnen.
+
+
+
-
- Der IC Verlauf wurde gespeichert.
+
+
+
-
-
- Du hattest keinen 'base/cases' Ordner! Ich hab ihn nun angelegt aber bedenke das er leer sein wird.
+
+
+
-
-
- Du musst einen Dateinamen angeben (ohne .ini). Stelle sicher das er im 'base/cases' Ordner ist und das er korrekt formatiert ist.
-Verfügbare Fälle: %1
+
+
+
-
-
- Fall von %1.
+
+
+
-
-
- Gehe zu %1 für das CM Dokument.
+
+
+ Sendet schüttel, Blitze und Geräusche aus der char.ini Datei über das Netzwerk. Funkioniert nur wenn der Server dies unterstützt.
-
-
-
-
-
- UNBEKANNT
+
+
+ Netzwerk Frame-Effekte:
-
-
- Dein Fall "%1" wurde geladen!
+
+
+ Chat Rate Limit:
-
- Du musst einen Dateinamen angeben (ohne .ini). Stelle sicher das er im 'base/cases' Ordner ist und das er korrekt formatiert ist.
-Verfügbare Fälle:
+
+
+ Aktiviert animierte Theme Elemente.
-
-
- Zu viele Argumente! Du brauchst nur den Dateinamen, ohne Erweiterung.
+
+
+ Animiertes Theme:
-
- Fall von
+
+
+ Zeit (in Milisekunden) für jeden Buchstaben.
-
- Gehe zu
+
+
+ Kriechender Text:
-
- für das CM Dokument.
+
+
+ Aktualisiert das Design und alle UI Elemente.
-
- Dein Fall "
+
+
+ Aussehen neu laden
-
- " wurde geladen!
+
+
+ Dein Anzeigename wird automatisch gesetzt wenn du einem Server beitritts.
-
-
- Du hattest keinen 'base/cases' Ordner! Ich hab ihn nun angelegt aber bedenke das er leer sein wird.
+
+
+ Standard Anzeigename:
-
-
- Du musst einen Dateinamen (ohne Erweiterung) angebenn, sowie den Gebietsstatus!
+
+
+ An zeigt 'Sticker' an, kleine Bilder wie Avatare.
-
-
- Zu viele Argumente! Du brauchst nur den Dateinamen, ohne Erweiterung sowie den Gebietsstatus!
+
+
+ Sticker:
-
-
- Erfolgreich gespeichert!
+
+
+ Aktiviere dies damit das Kontrollkästchen für die Voranimation nicht zurückspringt nachdem sie abgespielt wurde.
-
- Master
+
+
+ Klebende Voranimation:
-
-
- Lied stoppen
+
+
+ Standardwert für die Anzeigename Box, welche den In-Charakter Namen bestimmt.
-
-
- Zufälliges Lied
+
+
+ Eigener Anzeigename:
-
-
- Alle Kategorien erweitern
+
+
+ Aktiviere dies damit die Effektauswahl nicht zurückspringt nachdem er abgespielt wurde.
-
-
- Alle Kategorien verstecken
+
+
+ Klebende Effekt:
-
-
- Vorheriges ausblenden
+
+
+ Minimale Zeit (in Milisekunden) die eine IC Nachricht auf dem Bildschirm bleibt bevore die nächste kommt, wie eine Art 'Warteschlange'. 0 deaktiviert das.
-
-
- Einblenden
+
+
+ Standzeit:
-
-
- Synchronisieren
+
+
+ Setzte die Sprache falls du nicht die Systemsprache verwenden möchtest.
-
-
- Standard
+
+
+ Sprache:
-
-
- Grund:
+
+
+
-
-
- Moderator rufen
+
+
+ SFX immer senden:
-
-
-
- Fehler
+
+
+ Aktiviere dies damit die Geräuschauswahl nicht zurückspringt nachdem es abgespielt wurde.
-
-
- Du musst einen Grund angeben.
+
+
+ Klebende Geräuschauswahl:
-
-
- Die Nachricht ist zu lang.
+
+
+ Dein OOC Name wird automatisch auf dies gesetzt.
-
-
- Wähle..
+
+
+ Standard Benutzername:
-
- Wähle...
+
+
+ Erlaubt schütteln des Bildschirms. Deaktiviere dies falls du Bedenken wegen Photosensitivität hast.
-
-
- Präsentiere dieses Beweisstück allen in der nächsten Nachricht
+
+
+ Schütteln erlauben:
-
-
- Speichere Beweise in einer .ini Datei.
+
+
+ Erlaubt anderen auf Discord zu sehen auf welchem Server du spielst, welchen Charakter du spielst und wie lange.
-
-
- Lade Beweise aus einer .ini Datei.
+
+
+ Discord:
-
-
- Zerstöre dieses Beweisstück
+
+
+ Verwendet Farbe im IC Log so wie im Bild.
-
-
- Schließe das Beweisfenster.
-Du wirst gefragt wenn es ungespeicherte Änderungen gibt.
+
+
+ Farben im IC Log:
-
-
- Speichert alle Änderungen an diesem Beweisstück und schickt sie zum Server.
+
+
+
-
- Doppelklick zum bearbeiten. Klicke [X] um die Änderungen zu übernehmen.
+
+
+ Untertheme:
-
-
+
+
-
-
- Zeigt die Beweisliste.
+
+
+ Doppelklick für Beweise:
-
-
- Wechselt zum eigenen Inventar.
+
+
+ Spielt Animationen wieder dort ab wo sie aufgehört haben. Ausschalten kann bei Lag helfen.
-
-
- Wechselt zum globalen Inventar.
+
+
+ Durchgehendes Abspielen:
-
-
-
- Übertrage Beweisstück zum eigenen Inventar.
+
+
+ Alarmwörter
-
-
-
- Übertrage Beweisstück zum globalen Inventar.
+
+
+
-
-
- Das Beweisstück das du bearbeitet hast hat sich verändert.
+
+
+ Audio
-
-
- Möchtest du deine Änderungen behalten?
+
+
+ Audiogerät:
-
-
- Name: %1
-Bild: %2
-Beschreibung:
-%3
+
+
+ Setzt die Musiklautstärke.
-
-
- Bilder (*.png)
+
+
+ Musik:
-
-
-
-
+
+
+
+
+
-
- Doppelklick zum bearbeiten...
+
+
+ Setzt die Lautstärke der Soundeffekte wie Einsprüche und die Geräusche der Charaktere.
-
-
- Neues Beweisstück...
+
+
+ SFX:
-
-
- Beweise wurden verändert.
+
+
+ Setzt die Lautstärke der Blips, das ist das Geräusch das die Charaktere beim Reden machen.
-
-
- Möchtest du deine Änderungen speichen?
+
+
+ Blips:
-
-
- Beweise sind global. Klicken um zu eigenen zu wechseln.
+
+
+
-
-
- Beweise sind die eigenen. Klicken um zu global zu wechseln.
+
+
+
-
-
- "%1" wurde übertragen.
+
+
+ Setzt die Pause zwischen einzelnen Blips.
-
-
- Inventar speichen
+
+
+ Bliprate:
-
-
-
- Ini Dateien (*.ini)
+
+
+
-
-
- Inventar öffnen
+
+
+ Wenn angehakt wird das Spiel auch bei einem Leerzeichen einen Blip machen.
-
-
- DemoServer
-
-
-
- Demo laden
+
+
+ Leere Blips:
-
-
-
- Demos (*.demo)
+
+
+ Wenn aktiviert, werden wiederholende Soundeffekte bei den Voranimationen erlaubt.
-
-
-
-
+
+
+ Wiederholende Soundeffekte:
-
-
+
+
-
-
-
+
+
+ Stoppe Musik bei Einspruch:
-
-
+
+
-
-
-
+
+
-
-
+
+
+
-
-
-
+
+
+ Eigentlich selbsterklärend.
-
-
-
+
+
+ Dieser Server unterstützt Fallalarme nicht.
-
-
-
+
+
+ Wenn angehakt wirst du benachrichtigt wenn ein Fall angekündigt wird.
-
-
-
+
+
+ Wenn angehakt wirst du benachrichtigt wenn ein Verteidiger benötigt wird.
-
-
+
+
-
-
-
+
+
+ Wenn angehakt wirst du benachrichtigt wenn eine Jury benötigt wird.
-
-
+
+
-
-
-
+
+
+ Wenn angehakt wirst du benachrichtigt wenn ein Stenograph benötigt wird.
-
-
- Discord
-
- Einspruch!
+
+
+
-
- In Lobby
+
+
+ Wenn angehakt wirst du als potentielle CM angezeigt.
-
- Untätig
+
+
+
-
- In einem Server
+
+
+ Wenn du CM bist, gib ein welche Fälle du spielen möchtest.
-
- Spielt als %1
+
+
+ Fallleitung:
-
- Zuschauend
+
+
+ Wenn angehakt wirst du benachrichtigt wenn ein Kläger benötigt wird.
-
-
- Lobby
-
- Attorney Online
+
+
+
-
-
- Attorney Online %1
+
+
+ Wenn angehakt wirst du benachrichtigt wenn ein Richter benötigt wird.
-
-
- Suche
+
+
+
-
- Name
+
+
+
-
-
- Dein Client ist nicht korrekt eingerichtet.
-Hast du ALLES von tiny.cc/getao heruntergeladen und entpackt, auch den großen 'base' Ordner?
+
+
+
-
-
- Version: %1
+
+
+
-
-
- Einstellungen
+
+
+
-
-
- Erlaubt es verschiedene Aspekte des Clients zu ändern.
+
+
+
-
-
- Laden
+
+
+
-
-
- Abbrechen
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
+ Wenn angehakt werden neue Nachrichten unten erscheinen (wie beim OOC). Das traditionelle (AO1) Verhalten wäre nicht angehakt.
+
+
+
+
+ Verlauf geht nach unten:
+
+
+
+
+ Die menge an Zeilen die das IC Log behält bevor ältere Nachrichten gelöscht werden. 0 bedeutet unendlich.
+
+
+
+
+ Länge:
+
+
+
+
-
-
+
+
-
- <h2>Attorney Online %1</h2>Der Gerichtsdrama Simulator<p><b>Quelltext:</b> <a href='https://github.com/AttorneyOnline/AO2-Client'>https://github.com/AttorneyOnline/AO2-Client</a><p><b>Leitende Entwicklung:</b><br>OmniTroid, stonedDiscord, longbyte1, gameboyprinter, Cerapter, Crystalwarrior, Iamgoofball<p><b>Cliententwicklung:</b><br>Cents02, in1tiate, raidensnake, windrammer<p><b>Qualitätssicherung:</b><br>CaseyCazy, CedricDewitt, Chewable Tablets, CrazyJC, Fantos, Fury McFlurry, Geck, Gin-Gi, Jamania, Minx, Pandae, Robotic Overlord, Shadowlions (aka Shali), Sierra, SomeGuy, Veritas, Wiso<p><b>Danksagungen:</b><br>CrazyJC (2.8 release director) and MaximumVolty (2.8 release promotion); Remy, Hibiki, court-records.net (sprites); Qubrick (webAO); Rue (website); Draxirch (UI design); Lewdton and Argoneus (tsuserver); Fiercy, Noevain, Cronnicossy, und FanatSors (AO1); Serverbetreiber, Gamemaster, Fallersteller, Inhaltsersteller und die ganze AO2 Community!<p>Das Attorney Online networked visual novel Projekt ist copyright (c) 2016-2020 Attorney Online Entwickler. Unter Open-Source Lizenz. Alle anderen Inhalte sind Eigentum ihrer Besitzer.<p>Läuft auf Qt version %2 mit der BASS Audio Engine.<br>APNG plugin geladen: %3<p>Built on %4
+
+
+ Absätze protokollieren:
-
-
- Ja
+
+
+
-
-
- Nein
+
+
+ Protokollabstand:
-
- <h2>Attorney Online %1</h2>Der Gerichtsdrama Simulator<p><b>Quelltext:</b> <a href='https://github.com/AttorneyOnline/AO2-Client'>https://github.com/AttorneyOnline/AO2-Client</a><p><b>Leitende Entwicklung:</b><br>OmniTroid, stonedDiscord, longbyte1, gameboyprinter, Cerapter<p><b>Version 2.8 Entwicklung:</b><br>Crystalwarrior, Iamgoofball<p><b>2.8 Qualitätskontrolle:</b><br>WillDean, Captain N, Mr M, Riel, Seimmet, Fury McFlurry,CedricDewitt, Chewable Tablets, Fantos, Futugaze,Geck, Minx, Pandae, Sierra, CrazyJC, CaseyMayCazy,GreenBowers, Robotic Overlord, Veritas, Gin-Gi<p><b>Danksagungen:</b><br>Remy, Iamgoofball, Hibiki, Qubrick (webAO), Ruekasu (UI design), Draxirch (UI design), Unishred, Argoneus (tsuserver), Fiercy, Noevain, Cronnicossy, die AO2 Community, Serverbetreiber, Gamemaster, Fallersteller, Inhaltersteller und Spieler!
+
+
+
-
-
- Über
+
+
+ Das Protokoll enthält vor dem Namen einen Zeitstempel in UTC.
-
- <h2>Attorney Online %1</h2>Der Gerichtsdrama Simulator<p><b>Quelltext:</b> <a href='https://github.com/AttorneyOnline/AO2-Client'>https://github.com/AttorneyOnline/AO2-Client</a><p><b>Leitende Entwicklung:</b><br>OmniTroid, stonedDiscord, longbyte1, gameboyprinter, Cerapter, Cents02<p><b>Danksagungen:</b><br>Remy, Iamgoofball, Hibiki, Qubrick (webAO), Ruekasu (UI design), Draxirch (UI design), Unishred, Argoneus (tsuserver), Fiercy, Noevain, Cronnicossy, Raidensnake
+
+
+ Zeitstempel:
-
- <h2>Attorney Online %1</h2>Der Gerichtsdrama Simulator<p><b>Quelltext:</b> <a href='https://github.com/AttorneyOnline/AO2-Client'>https://github.com/AttorneyOnline/AO2-Client</a><p><b>Leitende Entwicklung:</b><br>OmniTroid, stonedDiscord, longbyte1, gameboyprinter, Cerapter<p><b>Danksagungen:</b><br>Remy, Iamgoofball, Hibiki, Qubrick (webAO), Ruekasu (UI design), Draxirch (UI design), Unishred, Argoneus (tsuserver), Fiercy, Noevain, Cronnicossy
+
+
+
-
-
- Online: %1/%2
+
+
+
-
- Attorney Online 2 wurde gemacht mit Qt 5.11.
-
-Leitende Entwicklung:
-longbyte1
-OmniTroid
-stonedDiscord
-
-Unterstützende Entwicklung:
-Fiercy
-
-UI Design:
-Ruekasu
-Draxirch
-
-Speziellen Dank:
-Unishred
-Argoneus
-Noevain
-Cronnicossy
-
-
-
-
-
- Offline
+
+
+
-
-
- NetworkManager
-
-
+
+
-
-
- QDialogButtonBox
-
-
-
+
+
-
-
- QObject
-
-
- Keine
+
+
+ Protokolliert Charakteraktionen wie Zwischenrufe und Beweisstücke.
-
-
- [FEHLT] %1
+
+
+ Aktionen protokollieren:
-
-
- [STREAM] %1
+
+
+ Wenn angehakt werden die Nachrichten sofort im Protokoll angezeigt, ansonsten wartet es auf den Chat.
-
-
- chatlogpiece
-
-
-
-
- UNBEKANNT
+
+
+ Protokoll desynchronisieren:
-
- hat ein Lied gespielt:
+
+
+
-
-
- debug_functions
-
-
- Fehler: %1
+
+
+
-
-
- Fehler
+
+
+
-
-
- Hinweis
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resource/ui/options_dialog.ui b/resource/ui/options_dialog.ui
new file mode 100644
index 000000000..d63643248
--- /dev/null
+++ b/resource/ui/options_dialog.ui
@@ -0,0 +1,1302 @@
+
+
+ optionsdialogue
+
+
+
+ 0
+ 0
+ 450
+ 415
+
+
+
+ Qt::NoContextMenu
+
+
+ Settings
+
+
+ -
+
+
+ Qt::NoFocus
+
+
+ 0
+
+
+
+ Gameplay
+
+
+
-
+
+
+ true
+
+
+
+
+ 0
+ 0
+ 389
+ 701
+
+
+
+
-
+
+
+
+
+
+
+ -
+
+
+ Stop music when double-clicking a category. If this is disabled, use the right-click context menu to stop music.
+
+
+ Stop Music w/ Category:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+ Sets the default scaling method, if there is not one already defined specifically for the character.
+
+
+ Scaling:
+
+
+
+ -
+
+
+ Turn this on to allow characters to define their own custom chat box designs.
+
+
+ Custom Chatboxes:
+
+
+
+ -
+
+
+ Allows screen effects. Disable this if you have concerns or issues with photosensitivity and/or seizures.
+
+
+ Allow Effects:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ Open the theme folder of the currently selected theme.
+
+
+ Open Theme Folder
+
+
+
+ -
+
+
+ Overrides the base URL to retrieve server information from.
+
+
+ Alternate Server List:
+
+
+
+ -
+
+
+ Instant Objection:
+
+
+
+ -
+
+
+ ms
+
+
+ 500
+
+
+
+ -
+
+
+ Sets the theme used in-game. If the new theme changes the lobby's look as well, you'll need to reload the Lobby for the changes to take effect, such as by joining a server and leaving it.
+
+
+ Theme:
+
+
+
+ -
+
+
-
+
+ en
+
+
+ -
+
+ de
+
+
+ -
+
+ es
+
+
+ -
+
+ pt
+
+
+ -
+
+ pl
+
+
+ -
+
+ jp
+
+
+ -
+
+ ru
+
+
+
+
+ -
+
+
+ -
+
+
+ Send screen-shaking, flashes and sounds as defined in the char.ini over the network. Only works for servers that support this functionality.
+
+
+ Network Frame Effects:
+
+
+
+ -
+
+
+ Chat Rate Limit:
+
+
+ Qt::AutoText
+
+
+
+ -
+
+
+ ms
+
+
+ 5000
+
+
+
+ -
+
+
+ If ticked, themes will be allowed to have animated elements.
+
+
+ Animated Theme:
+
+
+
+ -
+
+
+ Amount of time (in miliseconds) spent on each letter when the in-character text is being displayed.
+
+
+ Text crawl:
+
+
+
+ -
+
+
+ Refresh the theme and update all of the ui elements to match.
+
+
+ Reload Theme
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ Your showname will be automatically set to this value when you join a server.
+
+
+ Default showname:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+ Turn this on to allow characters to define their own stickers (unique images that show up over the chatbox - like avatars or shownames).
+
+
+ Stickers:
+
+
+
+ -
+
+
+ Turn this on to prevent preanimation checkbox from clearing after playing the emote.
+
+
+ Sticky Preanims:
+
+
+
+ -
+
+
+ ms
+
+
+ 10000
+
+
+
+ -
+
+
+ Gives the default value for the in-game 'Custom shownames' tickbox, which in turn determines whether the client should display custom in-character names.
+
+
+ Custom shownames:
+
+
+
+ -
+
+
+ Turn this on to prevent the effects dropdown from clearing the effect after playing it.
+
+
+ Sticky Effects:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ Minimum amount of time (in miliseconds) an IC message must stay on screen before the next IC message is shown, acting as a 'queue'. Set to 0 to disable this behavior.
+
+
+ Text Stay Time:
+
+
+
+ -
+
+
+ Sets the language if you don't want to use your system language.
+
+
+ Language:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ If the SFX dropdown has an SFX selected, send the custom SFX alongside the message even if Preanim is OFF.
+
+
+ Always Send SFX:
+
+
+
+ -
+
+
+ Turn this on to prevent the sound dropdown from clearing the sound after playing it.
+
+
+ Sticky Sounds:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ Your OOC name will be automatically set to this value when you join a server.
+
+
+ Default username:
+
+
+
+ -
+
+
+ Allows screenshaking. Disable this if you have concerns or issues with photosensitivity and/or seizures.
+
+
+ Allow Screenshake:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ Allows others on Discord to see what server you are in, what character are you playing, and how long you have been playing for.
+
+
+ Discord:
+
+
+
+ -
+
+
+ Use the markup colors in the server IC chatlog.
+
+
+ Colors in IC Log:
+
+
+
+ -
+
+
+ Sets a 'subtheme', which will stack on top of the current theme and replace anything it can. Keep it at 'server' to let the server decide. Keep it at 'default' to keep it unchanging.
+
+
+ Subtheme:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ -
+
+
+ QFrame::HLine
+
+
+ QFrame::Sunken
+
+
+
+ -
+
+
+ QFrame::HLine
+
+
+ QFrame::Sunken
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ If ticked, Evidence needs a double-click to view rather than a single click.
+
+
+ Evidence Double Click:
+
+
+
+ -
+
+
+ QFrame::HLine
+
+
+ QFrame::Sunken
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ Whether or not to resume playing animations from where they left off. Turning off might reduce lag.
+
+
+ Continuous Playback:
+
+
+
+ -
+
+
+ 30
+
+
+
+
+
+
+
+
+
+
+
+ Callwords
+
+
+ -
+
+
+ -
+
+
+ <html><head/><body><p>Enter as many callwords as you would like. These are case insensitive. Make sure to leave every callword in its own line!<br/><br/>Do not leave a line with a space at the end -- you will be alerted everytime someone uses a space in their messages.</p></body></html>
+
+
+ true
+
+
+
+
+
+
+
+ Audio
+
+
+ -
+
+
+ Audio device:
+
+
+
+ -
+
+
+ -
+
+
+ Sets the music's default volume.
+
+
+ Music:
+
+
+
+ -
+
+
+ %
+
+
+ 100
+
+
+
+ -
+
+
+ Sets the SFX's default volume. Interjections and actual sound effects count as 'SFX'.
+
+
+ SFX:
+
+
+
+ -
+
+
+ %
+
+
+ 100
+
+
+
+ -
+
+
+ Sets the volume of the blips, the talking sound effects.
+
+
+ Blips:
+
+
+
+ -
+
+
+ %
+
+
+ 100
+
+
+
+ -
+
+
+ How much of the volume to suppress when client is not in focus.
+
+
+ Suppress Audio:
+
+
+
+ -
+
+
+ %
+
+
+ 100
+
+
+
+ -
+
+
+ Sets the delay between playing the blip sounds.
+
+
+ Blip rate:
+
+
+
+ -
+
+
+ Play a blip sound \"once per every X symbols\", where X is the blip rate. 0 plays a blip sound only once.
+
+
+
+ -
+
+
+ If true, the game will play a blip sound even when a space is 'being said'.
+
+
+ Blank blips:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ If true, the game will allow looping sound effects to play on preanimations.
+
+
+ Enable Looping SFX:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ If true, AO2 will ask the server to stop music when you use 'Objection!'
+
+
+ Kill Music On Objection:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ If true, AO2 will not play any streamed audio and show that streaming is disabled.
+
+
+ Music Streaming enabled:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ QFrame::HLine
+
+
+ QFrame::Sunken
+
+
+
+ -
+
+
+ QFrame::HLine
+
+
+ QFrame::Sunken
+
+
+
+
+
+
+
+ Casing
+
+
+ -
+
+
+ If checked, you will get alerts about case announcements.
+
+
+ Casing
+
+
+ true
+
+
+ false
+
+
+
-
+
+
+ If checked, you will get alerts about case announcements if a defense spot is open.
+
+
+ Defense
+
+
+
+ -
+
+
+ If checked, you will get alerts about case announcements if a juror spot is open.
+
+
+ Juror
+
+
+
+ -
+
+
+ If checked, you will get alerts about case announcements if a stenographer spot is open.
+
+
+ Stenographer
+
+
+
+ -
+
+
+ If checked, you will appear amongst the potential CMs on the server.
+
+
+ Case Master
+
+
+
+ -
+
+
-
+
+
+ If you're a CM, enter what cases you are willing to host.
+
+
+ Hosting cases:
+
+
+
+ -
+
+
+
+
+ -
+
+
+ If checked, you will get alerts about case announcements if a prosecutor spot is open.
+
+
+ Prosecution
+
+
+
+ -
+
+
+ If checked, you will get alerts about case announcements if the judge spot is open.
+
+
+ Judge
+
+
+
+
+
+
+ -
+
+
+ Qt::Vertical
+
+
+
+ 20
+ 338
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+ Assets
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ <html><head/><body><p>Add or remove base folders for use by assets.</p><p><br/>Base folders on the bottom are prioritized over those above them.</p></body></html>
+
+
+ true
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+
+ -
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 40
+ 16777215
+
+
+
+ ↓
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Remove
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+ QSizePolicy::Expanding
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 40
+ 16777215
+
+
+
+ ↑
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Add...
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Clears the lookup cache for assets.
+Use this when you have added an asset that takes precedence over another existing asset.
+
+
+ Clear Cache
+
+
+
+
+
+
+
+
+
+ Logging
+
+
+ -
+
+
+ If ticked, new messages will appear at the bottom (like the OOC chatlog). The traditional (AO1) behaviour is equivalent to this being unticked.
+
+
+ Log goes downwards:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ The amount of message lines the IC chatlog will keep before deleting older message lines. A value of 0 or below counts as 'infinite'.
+
+
+ Log length:
+
+
+
+ -
+
+
+ entries
+
+
+ 10000
+
+
+
+ -
+
+
+ If ticked, new messages will appear separated, with the message coming on the next line after the name.
+When unticked, it displays it as 'name: message'.
+
+
+ Log newline:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ The distance in pixels between each entry in the IC log.
+Default: 0.
+
+
+ Log margin:
+
+
+
+ -
+
+
+ px
+
+
+ 1000
+
+
+
+ -
+
+
+ If ticked, log will contain a timestamp in UTC before the name.
+
+
+ Log timestamp:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ Log timestamp format:
+
+
+
+
+ -
+
+
+ true
+
+
-
+
+ h:mm:ss AP
+
+
+ -
+
+ hh:mm:ss
+
+
+ -
+
+ h:mm AP
+
+
+ -
+
+ hh:mm
+
+
+
+
+ -
+
+
+ If ticked, log will show IC actions such as shouting and presenting evidence.
+
+
+ Log IC actions:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ If ticked, log will show messages as-received, while viewport will parse according to the queue (Text Stay Time).
+
+
+ Desynchronize IC Logs:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ Text logs of gameplay will be automatically written in the /logs folder.
+
+
+ Log to Text Files:
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ Gameplay will be automatically recorded as demos in the /logs folder.
+
+
+ Log to Demo Files:
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+ Privacy
+
+
+ -
+
+
+ Do not include me in public player counts
+
+
+
+ -
+
+
+ QFrame::HLine
+
+
+ QFrame::Sunken
+
+
+
+ -
+
+
+
+
+
+
+ -
+
+
+ QDialogButtonBox::Cancel|QDialogButtonBox::RestoreDefaults|QDialogButtonBox::Save
+
+
+
+
+
+
+
+
diff --git a/resources.qrc b/resources.qrc
index cca23ef6c..793a66bd8 100644
--- a/resources.qrc
+++ b/resources.qrc
@@ -9,5 +9,6 @@
resource/translations/ao_pl.qm
resource/translations/ao_pt.qm
resource/translations/ao_ru.qm
+ resource/ui/options_dialog.ui
diff --git a/src/aoapplication.cpp b/src/aoapplication.cpp
index 11889f722..0fc8b1c18 100644
--- a/src/aoapplication.cpp
+++ b/src/aoapplication.cpp
@@ -4,9 +4,10 @@
#include "debug_functions.h"
#include "lobby.h"
#include "networkmanager.h"
+#include "options.h"
#include "aocaseannouncerdialog.h"
-#include "aooptionsdialog.h"
+#include "widgets/aooptionsdialog.h"
static QtMessageHandler original_message_handler;
static AOApplication *message_handler_context;
@@ -19,10 +20,6 @@ void message_handler(QtMsgType type, const QMessageLogContext &context,
AOApplication::AOApplication(int &argc, char **argv) : QApplication(argc, argv)
{
- // Create the QSettings class that points to the config.ini.
- configini =
- new QSettings(get_base_path() + "config.ini", QSettings::IniFormat);
-
net_manager = new NetworkManager(this);
discord = new AttorneyOnline::Discord();
@@ -40,7 +37,6 @@ AOApplication::~AOApplication()
destruct_lobby();
destruct_courtroom();
delete discord;
- delete configini;
qInstallMessageHandler(original_message_handler);
}
@@ -60,7 +56,7 @@ void AOApplication::construct_lobby()
int y = (geometry.height() - w_lobby->height()) / 2;
w_lobby->move(x, y);
- if (is_discord_enabled())
+ if (Options::getInstance().discordEnabled())
discord->state_lobby();
if (demo_server)
@@ -124,8 +120,6 @@ QString AOApplication::get_version_string()
QString::number(MINOR_VERSION);
}
-void AOApplication::reload_theme() { current_theme = read_theme(); }
-
void AOApplication::load_favorite_list()
{
favorite_list = read_favorite_servers();
@@ -198,8 +192,18 @@ void AOApplication::loading_cancelled()
void AOApplication::call_settings_menu()
{
- AOOptionsDialog settings(nullptr, this);
- settings.exec();
+ AOOptionsDialog* l_dialog = new AOOptionsDialog(nullptr, this);
+ if (courtroom_constructed) {
+ connect(l_dialog, &AOOptionsDialog::reloadThemeRequest,
+ w_courtroom, &Courtroom::on_reload_theme_clicked);
+ }
+
+ if(lobby_constructed) {
+ connect(l_dialog, &AOOptionsDialog::reloadThemeRequest,
+ w_lobby, &Lobby::set_widgets);
+ }
+ l_dialog->exec();
+ delete l_dialog;
}
void AOApplication::call_announce_menu(Courtroom *court)
@@ -236,13 +240,13 @@ void AOApplication::initBASS()
unsigned int a = 0;
BASS_DEVICEINFO info;
- if (get_audio_output_device() == "default") {
+ if (Options::getInstance().audioOutputDevice() == "default") {
BASS_Init(-1, 48000, BASS_DEVICE_LATENCY, nullptr, nullptr);
load_bass_plugins();
}
else {
for (a = 0; BASS_GetDeviceInfo(a, &info); a++) {
- if (get_audio_output_device() == info.name) {
+ if (Options::getInstance().audioOutputDevice() == info.name) {
BASS_SetDevice(a);
BASS_Init(static_cast(a), 48000, BASS_DEVICE_LATENCY, nullptr,
nullptr);
diff --git a/src/aobutton.cpp b/src/aobutton.cpp
index 6d25a05f6..5ef2a066c 100644
--- a/src/aobutton.cpp
+++ b/src/aobutton.cpp
@@ -2,6 +2,7 @@
#include "debug_functions.h"
#include "file_functions.h"
+#include "options.h"
AOButton::AOButton(QWidget *parent, AOApplication *p_ao_app)
: QPushButton(parent)
@@ -20,8 +21,8 @@ void AOButton::set_image(QString p_path, QString p_misc)
{
movie->stop();
QString p_image;
- p_image = ao_app->get_image(p_path, ao_app->current_theme, ao_app->get_subtheme(),
- ao_app->default_theme, p_misc, "", "", !ao_app->get_animated_theme());
+ p_image = ao_app->get_image(p_path, Options::getInstance().theme(), Options::getInstance().subTheme(),
+ ao_app->default_theme, p_misc, "", "", !Options::getInstance().animatedThemeEnabled());
if (p_image.isEmpty()) {
this->setIcon(QIcon());
this->setIconSize(this->size());
@@ -33,7 +34,7 @@ void AOButton::set_image(QString p_path, QString p_misc)
movie->setFileName(p_image);
// We double-check if the user wants animated themes, so even if an animated image slipped through,
// we still set it static
- if (ao_app->get_animated_theme() && movie->frameCount() > 1) {
+ if (Options::getInstance().animatedThemeEnabled() && movie->frameCount() > 1) {
movie->start();
}
else {
diff --git a/src/aoimage.cpp b/src/aoimage.cpp
index c488a0938..e737ffb3e 100644
--- a/src/aoimage.cpp
+++ b/src/aoimage.cpp
@@ -1,6 +1,7 @@
#include "file_functions.h"
#include "aoimage.h"
+#include "options.h"
#include
@@ -28,9 +29,9 @@ AOImage::~AOImage() {}
bool AOImage::set_image(QString p_image, QString p_misc)
{
- QString p_image_resolved = ao_app->get_image(p_image, ao_app->current_theme, ao_app->get_subtheme(),
+ QString p_image_resolved = ao_app->get_image(p_image, Options::getInstance().theme(), Options::getInstance().subTheme(),
ao_app->default_theme, p_misc, "", "",
- is_static || !ao_app->get_animated_theme());
+ is_static || !Options::getInstance().animatedThemeEnabled());
if (!file_exists(p_image_resolved)) {
qWarning() << "could not find image" << p_image;
@@ -41,11 +42,11 @@ bool AOImage::set_image(QString p_image, QString p_misc)
if (!is_static) {
movie->stop();
movie->setFileName(path);
- if (ao_app->get_animated_theme() && movie->frameCount() > 1) {
+ if (Options::getInstance().animatedThemeEnabled() && movie->frameCount() > 1) {
movie->start();
}
}
- if (is_static || !ao_app->get_animated_theme() || movie->frameCount() <= 1) {
+ if (is_static || !Options::getInstance().animatedThemeEnabled() || movie->frameCount() <= 1) {
QPixmap f_pixmap(path);
f_pixmap =
diff --git a/src/aolayer.cpp b/src/aolayer.cpp
index badf6351b..71dd6c8da 100644
--- a/src/aolayer.cpp
+++ b/src/aolayer.cpp
@@ -3,6 +3,7 @@
#include "aoapplication.h"
#include "file_functions.h"
#include "misc_functions.h"
+#include "options.h"
static QThreadPool *thread_pool;
@@ -234,7 +235,7 @@ void SplashLayer::load_image(QString p_filename, QString p_charname,
QString p_miscname)
{
transform_mode = ao_app->get_misc_scaling(p_miscname);
- QString final_image = ao_app->get_image(p_filename, ao_app->current_theme, ao_app->get_subtheme(), ao_app->default_theme, p_miscname, p_charname, "placeholder");
+ QString final_image = ao_app->get_image(p_filename, Options::getInstance().theme(), Options::getInstance().subTheme(), ao_app->default_theme, p_miscname, p_charname, "placeholder");
start_playback(final_image);
play();
}
@@ -257,7 +258,7 @@ void InterfaceLayer::load_image(QString p_filename, QString p_miscname)
{
last_path = "";
stretch = true;
- QString final_image = ao_app->get_image(p_filename, ao_app->current_theme, ao_app->get_subtheme(), ao_app->default_theme, p_miscname);
+ QString final_image = ao_app->get_image(p_filename, Options::getInstance().theme(), Options::getInstance().subTheme(), ao_app->default_theme, p_miscname);
start_playback(final_image);
play();
}
@@ -265,10 +266,10 @@ void InterfaceLayer::load_image(QString p_filename, QString p_miscname)
void StickerLayer::load_image(QString p_charname)
{
QString p_miscname;
- if (ao_app->is_customchat_enabled())
+ if (Options::getInstance().customChatboxEnabled())
p_miscname = ao_app->get_chat(p_charname);
transform_mode = ao_app->get_misc_scaling(p_miscname);
- QString final_image = ao_app->get_image("sticker/" + p_charname, ao_app->current_theme, ao_app->get_subtheme(), ao_app->default_theme, p_miscname);
+ QString final_image = ao_app->get_image("sticker/" + p_charname, Options::getInstance().theme(), Options::getInstance().subTheme(), ao_app->default_theme, p_miscname);
start_playback(final_image);
play();
}
@@ -297,7 +298,7 @@ void AOLayer::start_playback(QString p_image)
QMutexLocker locker(&mutex);
this->show();
- if (!ao_app->is_continuous_enabled()) {
+ if (!Options::getInstance().continuousPlaybackEnabled()) {
continuous = false;
force_continuous = true;
}
diff --git a/src/aomusicplayer.cpp b/src/aomusicplayer.cpp
index f29e0cf99..c7090e67c 100644
--- a/src/aomusicplayer.cpp
+++ b/src/aomusicplayer.cpp
@@ -1,4 +1,5 @@
#include "aomusicplayer.h"
+#include "options.h"
AOMusicPlayer::AOMusicPlayer(QWidget *parent, AOApplication *p_ao_app)
{
@@ -30,7 +31,7 @@ QString AOMusicPlayer::play(QString p_song, int channel, bool loop,
DWORD newstream;
if (f_path.startsWith("http")) {
- if (ao_app->is_streaming_disabled()) {
+ if (!Options::getInstance().streamingEnabled()) {
BASS_ChannelStop(m_stream_list[channel]);
return QObject::tr("[MISSING] Streaming disabled.");
}
@@ -56,7 +57,7 @@ QString AOMusicPlayer::play(QString p_song, int channel, bool loop,
int error_code = BASS_ErrorGetCode();
- if (ao_app->get_audio_output_device() != "default")
+ if (Options::getInstance().audioOutputDevice() != "default")
BASS_ChannelSetDevice(m_stream_list[channel], BASS_GetDevice());
QString d_path = f_path + ".txt";
diff --git a/src/aooptionsdialog.cpp b/src/aooptionsdialog.cpp
deleted file mode 100644
index e25b46538..000000000
--- a/src/aooptionsdialog.cpp
+++ /dev/null
@@ -1,1447 +0,0 @@
-#include "aooptionsdialog.h"
-#include "aoapplication.h"
-#include "courtroom.h"
-#include "lobby.h"
-#include "bass.h"
-#include "networkmanager.h"
-
-#include
-
-AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app)
- : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint)
-{
- ao_app = p_ao_app;
-
- // Setting up the basics.
- setWindowFlag(Qt::WindowCloseButtonHint);
- setWindowTitle(tr("Settings"));
- resize(450, 408);
-
- ui_settings_buttons = new QDialogButtonBox(this);
-
- QSizePolicy sizePolicy1(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
- sizePolicy1.setHorizontalStretch(0);
- sizePolicy1.setVerticalStretch(0);
- sizePolicy1.setHeightForWidth(
- ui_settings_buttons->sizePolicy().hasHeightForWidth());
- ui_settings_buttons->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Maximum));
- ui_settings_buttons->setOrientation(Qt::Horizontal);
- ui_settings_buttons->setStandardButtons(QDialogButtonBox::Cancel |
- QDialogButtonBox::Save |
- QDialogButtonBox::RestoreDefaults);
-
- connect(ui_settings_buttons, &QDialogButtonBox::accepted, this,
- &AOOptionsDialog::save_pressed);
- connect(ui_settings_buttons, &QDialogButtonBox::rejected, this,
- &AOOptionsDialog::discard_pressed);
- connect(ui_settings_buttons, &QDialogButtonBox::clicked, this,
- &AOOptionsDialog::button_clicked);
-
- // We'll stop updates so that the window won't flicker while it's being made.
- setUpdatesEnabled(false);
-
- // First of all, we want a tabbed dialog, so let's add some layout.
- ui_vertical_layout = new QVBoxLayout(this);
- ui_settings_tabs = new QTabWidget(this);
-
- ui_vertical_layout->addWidget(ui_settings_tabs);
- ui_vertical_layout->addWidget(ui_settings_buttons);
-
- // Let's add the tabs one by one.
- // First, we'll start with 'Gameplay'.
- ui_gameplay_tab = new QWidget(this);
- ui_gameplay_tab->setSizePolicy(sizePolicy1);
- ui_settings_tabs->addTab(ui_gameplay_tab, tr("Gameplay"));
- ui_form_layout_widget = new QWidget(ui_gameplay_tab);
- ui_form_layout_widget->setSizePolicy(sizePolicy1);
-
- ui_gameplay_form = new QFormLayout(ui_form_layout_widget);
- ui_gameplay_form->setLabelAlignment(Qt::AlignLeading | Qt::AlignLeft |
- Qt::AlignVCenter);
- ui_gameplay_form->setFormAlignment(Qt::AlignLeading | Qt::AlignLeft |
- Qt::AlignTop);
- ui_gameplay_form->setContentsMargins(0, 0, 0, 0);
- ui_gameplay_form->setSpacing(4);
-
- int row = 0;
-
- ui_theme_label = new QLabel(ui_form_layout_widget);
- ui_theme_label->setText(tr("Theme:"));
- ui_theme_label->setToolTip(
- tr("Sets the theme used in-game. If the new theme changes "
- "the lobby's look as well, you'll need to reload the "
- "lobby for the changes to take effect, such as by joining "
- "a server and leaving it."));
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_theme_label);
- ui_theme_combobox = new QComboBox(ui_form_layout_widget);
-
- // Fill the combobox with the names of the themes.
- QSet themes;
- QStringList bases = ao_app->get_mount_paths();
- bases.push_front(ao_app->get_base_path());
- for (const QString &base : bases) {
- QDirIterator it(base + "/themes", QDir::Dirs | QDir::NoDotAndDotDot,
- QDirIterator::NoIteratorFlags);
- while (it.hasNext()) {
- QString actualname = QDir(it.next()).dirName();
- if (!themes.contains(actualname)) {
- ui_theme_combobox->addItem(actualname);
- themes.insert(actualname);
- }
- }
- }
-
- connect(ui_theme_combobox, QOverload::of(&QComboBox::currentIndexChanged), this,
- &AOOptionsDialog::theme_changed);
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_theme_combobox);
-
- row += 1;
-
- ui_subtheme_label = new QLabel(ui_form_layout_widget);
- ui_subtheme_label->setText(tr("Subtheme:"));
- ui_subtheme_label->setToolTip(
- tr("Sets a 'subtheme', which will stack on top of the current theme and replace anything it can."
- "Keep it at 'server' to let the server decide. Keep it at 'default' to keep it unchanging."));
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_subtheme_label);
- ui_subtheme_combobox = new QComboBox(ui_form_layout_widget);
-
- // Fill the combobox with the names of the themes.
- ui_subtheme_combobox->addItem("server");
- ui_subtheme_combobox->addItem("default");
- QDirIterator it2(ao_app->get_real_path(ao_app->get_theme_path("")), QDir::Dirs,
- QDirIterator::NoIteratorFlags);
- while (it2.hasNext()) {
- QString actualname = QDir(it2.next()).dirName();
- if (actualname != "." && actualname != ".." && actualname.toLower() != "server" && actualname.toLower() != "default" && actualname.toLower() != "effects" && actualname.toLower() != "misc") {
- ui_subtheme_combobox->addItem(actualname);
- }
- }
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_subtheme_combobox);
-
- row += 1;
- ui_theme_reload_button = new QPushButton(ui_form_layout_widget);
- ui_theme_reload_button->setText(tr("Reload Theme"));
- ui_theme_reload_button->setToolTip(
- tr("Refresh the theme and update all of the ui elements to match."));
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_theme_reload_button);
- connect(ui_theme_reload_button, &QPushButton::clicked, this,
- &AOOptionsDialog::on_reload_theme_clicked);
-
- row += 1;
- ui_theme_folder_button = new QPushButton(ui_form_layout_widget);
- ui_theme_folder_button->setText(tr("Open Theme Folder"));
- ui_theme_folder_button->setToolTip(
- tr("Open the theme folder of the currently selected theme."));
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_theme_folder_button);
- connect(ui_theme_folder_button, &QPushButton::clicked, this,
- [=] {
- QString p_path = ao_app->get_real_path(ao_app->get_theme_path("", ui_theme_combobox->itemText(ui_theme_combobox->currentIndex())));
- if (!dir_exists(p_path)) {
- return;
- }
- QDesktopServices::openUrl(QUrl::fromLocalFile(p_path));
- }
- );
-
- row += 1;
- ui_animated_theme_lbl = new QLabel(ui_form_layout_widget);
- ui_animated_theme_lbl->setText(tr("Animated Theme:"));
- ui_animated_theme_lbl->setToolTip(
- tr("If ticked, themes will be allowed to have animated elements."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_animated_theme_lbl);
-
- ui_animated_theme_cb = new QCheckBox(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_animated_theme_cb);
-
- row += 1;
- ui_theme_log_divider = new QFrame(ui_form_layout_widget);
- ui_theme_log_divider->setMidLineWidth(0);
- ui_theme_log_divider->setFrameShape(QFrame::HLine);
- ui_theme_log_divider->setFrameShadow(QFrame::Sunken);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole,
- ui_theme_log_divider);
-
- row += 1;
- ui_stay_time_lbl = new QLabel(ui_form_layout_widget);
- ui_stay_time_lbl->setText(tr("Text Stay Time:"));
- ui_stay_time_lbl->setToolTip(tr(
- "Minimum amount of time (in miliseconds) an IC message must stay on screen before "
- "the next IC message is shown, acting as a 'queue'. Set to 0 to disable this behavior."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_stay_time_lbl);
-
- ui_stay_time_spinbox = new QSpinBox(ui_form_layout_widget);
- ui_stay_time_spinbox->setSuffix(" ms");
- ui_stay_time_spinbox->setMaximum(10000);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_stay_time_spinbox);
-
- row += 1;
- ui_instant_objection_lbl = new QLabel(ui_form_layout_widget);
- ui_instant_objection_lbl->setText(tr("Instant Objection:"));
- ui_instant_objection_lbl->setToolTip(
- tr("If Text Stay Time is more than 0, instant objection will skip queued messages instead of waiting to catch up."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_instant_objection_lbl);
-
- ui_instant_objection_cb = new QCheckBox(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_instant_objection_cb);
-
- row += 1;
- ui_text_crawl_lbl = new QLabel(ui_form_layout_widget);
- ui_text_crawl_lbl->setText(tr("Text crawl:"));
- ui_text_crawl_lbl->setToolTip(tr(
- "Amount of time (in miliseconds) spent on each letter when the in-character text is being displayed."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_text_crawl_lbl);
-
- ui_text_crawl_spinbox = new QSpinBox(ui_form_layout_widget);
- ui_text_crawl_spinbox->setSuffix(" ms");
- ui_text_crawl_spinbox->setMaximum(500);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_text_crawl_spinbox);
-
- row += 1;
- ui_chat_ratelimit_lbl = new QLabel(ui_form_layout_widget);
- ui_chat_ratelimit_lbl->setText(tr("Chat Rate Limit:"));
- ui_chat_ratelimit_lbl->setToolTip(tr(
- "Minimum amount of time (in miliseconds) that must pass before the next Enter key press will send your IC message."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_chat_ratelimit_lbl);
-
- ui_chat_ratelimit_spinbox = new QSpinBox(ui_form_layout_widget);
- ui_chat_ratelimit_spinbox->setSuffix(" ms");
- ui_chat_ratelimit_spinbox->setMaximum(5000);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_chat_ratelimit_spinbox);
-
- row += 1;
- ui_log_names_divider = new QFrame(ui_form_layout_widget);
- ui_log_names_divider->setFrameShape(QFrame::HLine);
- ui_log_names_divider->setFrameShadow(QFrame::Sunken);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole,
- ui_log_names_divider);
-
- row += 1;
- ui_username_lbl = new QLabel(ui_form_layout_widget);
- ui_username_lbl->setText(tr("Default username:"));
- ui_username_lbl->setToolTip(
- tr("Your OOC name will be automatically set to this value "
- "when you join a server."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_username_lbl);
-
- ui_username_textbox = new QLineEdit(ui_form_layout_widget);
- ui_username_textbox->setMaxLength(30);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_username_textbox);
-
- row += 1;
- ui_showname_lbl = new QLabel(ui_form_layout_widget);
- ui_showname_lbl->setText(tr("Custom shownames:"));
- ui_showname_lbl->setToolTip(
- tr("Gives the default value for the in-game 'Custom shownames' "
- "tickbox, which in turn determines whether the client should "
- "display custom in-character names."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_showname_lbl);
-
- ui_showname_cb = new QCheckBox(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_showname_cb);
-
- row +=1;
- ui_default_showname_lbl = new QLabel(ui_form_layout_widget);
- ui_default_showname_lbl->setText(tr("Default showname:"));
- ui_default_showname_lbl->setToolTip(
- tr("Your showname will be automatically set to this value "
- "when you join a server."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_default_showname_lbl);
-
- ui_default_showname_textbox = new QLineEdit(ui_form_layout_widget);
- ui_default_showname_textbox->setMaxLength(30);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_default_showname_textbox);
-
- row += 1;
- ui_net_divider = new QFrame(ui_form_layout_widget);
- ui_net_divider->setFrameShape(QFrame::HLine);
- ui_net_divider->setFrameShadow(QFrame::Sunken);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_net_divider);
-
- row += 1;
- ui_ms_lbl = new QLabel(ui_form_layout_widget);
- ui_ms_lbl->setText(tr("Alternate Server List:"));
- ui_ms_lbl->setToolTip(
- tr("Overrides the base URL to retrieve server information from."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_ms_lbl);
-
- ui_ms_textbox = new QLineEdit(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_ms_textbox);
-
- row += 1;
- ui_discord_lbl = new QLabel(ui_form_layout_widget);
- ui_discord_lbl->setText(tr("Discord:"));
- ui_discord_lbl->setToolTip(
- tr("Allows others on Discord to see what server you are in, "
- "what character are you playing, and how long you have "
- "been playing for."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_discord_lbl);
-
- ui_discord_cb = new QCheckBox(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_discord_cb);
-
- row += 1;
- ui_language_label = new QLabel(ui_form_layout_widget);
- ui_language_label->setText(tr("Language:"));
- ui_language_label->setToolTip(
- tr("Sets the language if you don't want to use your system language."));
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_language_label);
-
- ui_language_combobox = new QComboBox(ui_form_layout_widget);
- ui_language_combobox->addItem(
- ao_app->configini->value("language", " ").value() +
- tr(" - Keep current setting"));
- ui_language_combobox->addItem(" - Default");
- ui_language_combobox->addItem("en - English");
- ui_language_combobox->addItem("de - Deutsch");
- ui_language_combobox->addItem("es - Español");
- ui_language_combobox->addItem("pt - Português");
- ui_language_combobox->addItem("pl - Polskie");
- ui_language_combobox->addItem("jp - 日本語");
- ui_language_combobox->addItem("ru - Русский");
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole,
- ui_language_combobox);
-
- row += 1;
- ui_scaling_label = new QLabel(ui_form_layout_widget);
- ui_scaling_label->setText(tr("Scaling:"));
- ui_scaling_label->setToolTip(
- tr("Sets the default scaling method, if there is not one already defined "
- "specifically for the character."));
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_scaling_label);
-
- ui_scaling_combobox = new QComboBox(ui_form_layout_widget);
- // Corresponds with Qt::TransformationMode enum. Please don't change the order.
- ui_scaling_combobox->addItem(tr("Pixel"), "fast");
- ui_scaling_combobox->addItem(tr("Smooth"), "smooth");
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_scaling_combobox);
-
- row += 1;
- ui_shake_lbl = new QLabel(ui_form_layout_widget);
- ui_shake_lbl->setText(tr("Allow Screenshake:"));
- ui_shake_lbl->setToolTip(
- tr("Allows screenshaking. Disable this if you have concerns or issues "
- "with photosensitivity and/or seizures."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_shake_lbl);
-
- ui_shake_cb = new QCheckBox(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_shake_cb);
-
- row += 1;
- ui_effects_lbl = new QLabel(ui_form_layout_widget);
- ui_effects_lbl->setText(tr("Allow Effects:"));
- ui_effects_lbl->setToolTip(
- tr("Allows screen effects. Disable this if you have concerns or issues "
- "with photosensitivity and/or seizures."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_effects_lbl);
-
- ui_effects_cb = new QCheckBox(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_effects_cb);
-
- row += 1;
- ui_framenetwork_lbl = new QLabel(ui_form_layout_widget);
- ui_framenetwork_lbl->setText(tr("Network Frame Effects:"));
- ui_framenetwork_lbl->setToolTip(tr(
- "Send screen-shaking, flashes and sounds as defined in the char.ini over "
- "the network. Only works for servers that support this functionality."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_framenetwork_lbl);
-
- ui_framenetwork_cb = new QCheckBox(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_framenetwork_cb);
-
- row += 1;
- ui_colorlog_lbl = new QLabel(ui_form_layout_widget);
- ui_colorlog_lbl->setText(tr("Colors in IC Log:"));
- ui_colorlog_lbl->setToolTip(
- tr("Use the markup colors in the server IC chatlog."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_colorlog_lbl);
-
- ui_colorlog_cb = new QCheckBox(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_colorlog_cb);
-
- row += 1;
- ui_stickysounds_lbl = new QLabel(ui_form_layout_widget);
- ui_stickysounds_lbl->setText(tr("Sticky Sounds:"));
- ui_stickysounds_lbl->setToolTip(
- tr("Turn this on to prevent the sound dropdown from clearing the sound "
- "after playing it."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_stickysounds_lbl);
-
- ui_stickysounds_cb = new QCheckBox(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_stickysounds_cb);
-
- row += 1;
- ui_stickyeffects_lbl = new QLabel(ui_form_layout_widget);
- ui_stickyeffects_lbl->setText(tr("Sticky Effects:"));
- ui_stickyeffects_lbl->setToolTip(
- tr("Turn this on to prevent the effects dropdown from clearing the "
- "effect after playing it."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole,
- ui_stickyeffects_lbl);
-
- ui_stickyeffects_cb = new QCheckBox(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_stickyeffects_cb);
-
- row += 1;
- ui_stickypres_lbl = new QLabel(ui_form_layout_widget);
- ui_stickypres_lbl->setText(tr("Sticky Preanims:"));
- ui_stickypres_lbl->setToolTip(
- tr("Turn this on to prevent preanimation checkbox from clearing after "
- "playing the emote."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_stickypres_lbl);
-
- ui_stickypres_cb = new QCheckBox(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_stickypres_cb);
-
- row += 1;
- ui_customchat_lbl = new QLabel(ui_form_layout_widget);
- ui_customchat_lbl->setText(tr("Custom Chatboxes:"));
- ui_customchat_lbl->setToolTip(
- tr("Turn this on to allow characters to define their own "
- "custom chat box designs."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_customchat_lbl);
-
- ui_customchat_cb = new QCheckBox(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_customchat_cb);
-
- row += 1;
- ui_sticker_lbl = new QLabel(ui_form_layout_widget);
- ui_sticker_lbl->setText(tr("Stickers:"));
- ui_sticker_lbl->setToolTip(
- tr("Turn this on to allow characters to define their own "
- "stickers (unique images that show up over the chatbox - like avatars or shownames)."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_sticker_lbl);
-
- ui_sticker_cb = new QCheckBox(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_sticker_cb);
-
- row += 1;
- ui_continuous_lbl = new QLabel(ui_form_layout_widget);
- ui_continuous_lbl->setText(tr("Continuous Playback:"));
- ui_continuous_lbl->setToolTip(
- tr("Whether or not to resume playing animations from where they left off. Turning off might reduce lag."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_continuous_lbl);
-
- ui_continuous_cb = new QCheckBox(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_continuous_cb);
-
- row += 1;
- ui_category_stop_lbl = new QLabel(ui_form_layout_widget);
- ui_category_stop_lbl->setText(tr("Stop Music w/ Category:"));
- ui_category_stop_lbl->setToolTip(
- tr("Stop music when double-clicking a category. If this is disabled, use the right-click context menu to stop music."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_category_stop_lbl);
-
- ui_category_stop_cb = new QCheckBox(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_category_stop_cb);
-
- row += 1;
-
- ui_sfx_on_idle_lbl = new QLabel(ui_form_layout_widget);
- ui_sfx_on_idle_lbl->setText(tr("Always Send SFX:"));
- ui_sfx_on_idle_lbl->setToolTip(
- tr("If the SFX dropdown has an SFX selected, send the custom SFX alongside the message even if Preanim is OFF."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_sfx_on_idle_lbl);
-
- ui_sfx_on_idle_cb = new QCheckBox(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_sfx_on_idle_cb);
-
- row += 1;
-
- ui_evidence_double_click_lbl = new QLabel(ui_form_layout_widget);
- ui_evidence_double_click_lbl->setText(tr("Evidence Double Click:"));
- ui_evidence_double_click_lbl->setToolTip(
- tr("If ticked, Evidence needs a double-click to view rather than a single click."));
-
- ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_evidence_double_click_lbl);
-
- ui_evidence_double_click_cb = new QCheckBox(ui_form_layout_widget);
-
- ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_evidence_double_click_cb);
-
- // Finish gameplay tab
- QScrollArea *scroll = new QScrollArea(this);
- scroll->setWidget(ui_form_layout_widget);
- ui_gameplay_tab->setLayout(new QVBoxLayout);
- ui_gameplay_tab->layout()->addWidget(scroll);
- ui_gameplay_tab->show();
-
- // Here we start the callwords tab.
- ui_callwords_tab = new QWidget(this);
- ui_settings_tabs->addTab(ui_callwords_tab, tr("Callwords"));
-
- ui_callwords_widget = new QWidget(ui_callwords_tab);
- ui_callwords_widget->setGeometry(QRect(10, 10, 361, 211));
-
- ui_callwords_layout = new QVBoxLayout(ui_callwords_widget);
- ui_callwords_layout->setContentsMargins(0, 0, 0, 0);
-
- ui_callwords_textbox = new QPlainTextEdit(ui_callwords_widget);
- QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- sizePolicy.setHorizontalStretch(0);
- sizePolicy.setVerticalStretch(0);
- sizePolicy.setHeightForWidth(
- ui_callwords_textbox->sizePolicy().hasHeightForWidth());
- ui_callwords_textbox->setSizePolicy(sizePolicy);
-
- ui_callwords_layout->addWidget(ui_callwords_textbox);
-
- ui_callwords_explain_lbl = new QLabel(ui_callwords_widget);
- ui_callwords_explain_lbl->setWordWrap(true);
- ui_callwords_explain_lbl->setText(
- tr("Enter as many callwords as you would like. These "
- "are case insensitive. Make sure to leave every callword in its own "
- "line!
Do not leave a line with a space at the end -- you will be "
- "alerted everytime someone uses a space in their "
- "messages."));
-
- ui_callwords_layout->addWidget(ui_callwords_explain_lbl);
-
- // The audio tab.
- ui_audio_tab = new QWidget(this);
- ui_settings_tabs->addTab(ui_audio_tab, tr("Audio"));
-
- ui_audio_widget = new QWidget(ui_audio_tab);
- ui_audio_widget->setGeometry(QRect(10, 10, 361, 211));
-
- ui_audio_layout = new QFormLayout(ui_audio_widget);
- ui_audio_layout->setLabelAlignment(Qt::AlignLeading | Qt::AlignLeft |
- Qt::AlignVCenter);
- ui_audio_layout->setFormAlignment(Qt::AlignLeading | Qt::AlignLeft |
- Qt::AlignTop);
- ui_audio_layout->setContentsMargins(0, 0, 0, 0);
- row = 0;
-
- ui_audio_device_lbl = new QLabel(ui_audio_widget);
- ui_audio_device_lbl->setText(tr("Audio device:"));
- ui_audio_device_lbl->setToolTip(tr("Sets the audio device for all sounds."));
-
- ui_audio_layout->setWidget(row, QFormLayout::LabelRole, ui_audio_device_lbl);
-
- ui_audio_device_combobox = new QComboBox(ui_audio_widget);
-
- // Let's fill out the combobox with the available audio devices. Or don't if
- // there is no audio
- int a = 0;
- if (needs_default_audiodev()) {
-
- ui_audio_device_combobox->addItem("default"); //TODO translate this without breaking the default audio device
- }
- BASS_DEVICEINFO info;
- for (a = 0; BASS_GetDeviceInfo(a, &info); a++) {
- ui_audio_device_combobox->addItem(info.name);
- if (ao_app->get_audio_output_device() == info.name)
- ui_audio_device_combobox->setCurrentIndex(
- ui_audio_device_combobox->count() - 1);
- }
- ui_audio_layout->setWidget(row, QFormLayout::FieldRole,
- ui_audio_device_combobox);
-
- row += 1;
- ui_audio_volume_divider = new QFrame(ui_audio_widget);
- ui_audio_volume_divider->setFrameShape(QFrame::HLine);
- ui_audio_volume_divider->setFrameShadow(QFrame::Sunken);
-
- ui_audio_layout->setWidget(row, QFormLayout::FieldRole,
- ui_audio_volume_divider);
-
- row += 1;
- ui_music_volume_lbl = new QLabel(ui_audio_widget);
- ui_music_volume_lbl->setText(tr("Music:"));
- ui_music_volume_lbl->setToolTip(tr("Sets the music's default volume."));
-
- ui_audio_layout->setWidget(row, QFormLayout::LabelRole, ui_music_volume_lbl);
-
- ui_music_volume_spinbox = new QSpinBox(ui_audio_widget);
- ui_music_volume_spinbox->setMaximum(100);
- ui_music_volume_spinbox->setSuffix("%");
-
- ui_audio_layout->setWidget(row, QFormLayout::FieldRole,
- ui_music_volume_spinbox);
-
- row += 1;
- ui_sfx_volume_lbl = new QLabel(ui_audio_widget);
- ui_sfx_volume_lbl->setText(tr("SFX:"));
- ui_sfx_volume_lbl->setToolTip(
- tr("Sets the SFX's default volume. "
- "Interjections and actual sound effects count as 'SFX'."));
- ui_audio_layout->setWidget(row, QFormLayout::LabelRole, ui_sfx_volume_lbl);
-
- ui_sfx_volume_spinbox = new QSpinBox(ui_audio_widget);
- ui_sfx_volume_spinbox->setMaximum(100);
- ui_sfx_volume_spinbox->setSuffix("%");
-
- ui_audio_layout->setWidget(row, QFormLayout::FieldRole,
- ui_sfx_volume_spinbox);
-
- row += 1;
- ui_blips_volume_lbl = new QLabel(ui_audio_widget);
- ui_blips_volume_lbl->setText(tr("Blips:"));
- ui_blips_volume_lbl->setToolTip(
- tr("Sets the volume of the blips, the talking sound effects."));
-
- ui_audio_layout->setWidget(row, QFormLayout::LabelRole, ui_blips_volume_lbl);
-
- ui_blips_volume_spinbox = new QSpinBox(ui_audio_widget);
- ui_blips_volume_spinbox->setMaximum(100);
- ui_blips_volume_spinbox->setSuffix("%");
-
- ui_audio_layout->setWidget(row, QFormLayout::FieldRole,
- ui_blips_volume_spinbox);
-
- row += 1;
- ui_suppress_audio_lbl = new QLabel(ui_audio_widget);
- ui_suppress_audio_lbl->setText(tr("Suppress Audio:"));
- ui_suppress_audio_lbl->setToolTip(
- tr("How much of the volume to suppress when client is not in focus."));
-
- ui_audio_layout->setWidget(row, QFormLayout::LabelRole, ui_suppress_audio_lbl);
-
- ui_suppress_audio_spinbox = new QSpinBox(ui_audio_widget);
- ui_suppress_audio_spinbox->setMaximum(100);
- ui_suppress_audio_spinbox->setSuffix("%");
-
- ui_audio_layout->setWidget(row, QFormLayout::FieldRole,
- ui_suppress_audio_spinbox);
-
- row += 1;
- ui_volume_blip_divider = new QFrame(ui_audio_widget);
- ui_volume_blip_divider->setFrameShape(QFrame::HLine);
- ui_volume_blip_divider->setFrameShadow(QFrame::Sunken);
-
- ui_audio_layout->setWidget(row, QFormLayout::FieldRole,
- ui_volume_blip_divider);
-
- row += 1;
- ui_bliprate_lbl = new QLabel(ui_audio_widget);
- ui_bliprate_lbl->setText(tr("Blip rate:"));
- ui_bliprate_lbl->setToolTip(
- tr("Sets the delay between playing the blip sounds."));
-
- ui_audio_layout->setWidget(row, QFormLayout::LabelRole, ui_bliprate_lbl);
-
- ui_bliprate_spinbox = new QSpinBox(ui_audio_widget);
- ui_bliprate_spinbox->setMinimum(0);
- ui_bliprate_spinbox->setToolTip(
- tr("Play a blip sound \"once per every X symbols\", where "
- "X is the blip rate. 0 plays a blip sound only once."));
-
- ui_audio_layout->setWidget(row, QFormLayout::FieldRole, ui_bliprate_spinbox);
-
- row += 1;
- ui_blank_blips_lbl = new QLabel(ui_audio_widget);
- ui_blank_blips_lbl->setText(tr("Blank blips:"));
- ui_blank_blips_lbl->setToolTip(
- tr("If true, the game will play a blip sound even "
- "when a space is 'being said'."));
-
- ui_audio_layout->setWidget(row, QFormLayout::LabelRole, ui_blank_blips_lbl);
-
- ui_blank_blips_cb = new QCheckBox(ui_audio_widget);
-
- ui_audio_layout->setWidget(row, QFormLayout::FieldRole, ui_blank_blips_cb);
-
- row += 1;
- ui_loopsfx_lbl = new QLabel(ui_audio_widget);
- ui_loopsfx_lbl->setText(tr("Enable Looping SFX:"));
- ui_loopsfx_lbl->setToolTip(tr("If true, the game will allow looping sound "
- "effects to play on preanimations."));
-
- ui_audio_layout->setWidget(row, QFormLayout::LabelRole, ui_loopsfx_lbl);
-
- ui_loopsfx_cb = new QCheckBox(ui_audio_widget);
-
- ui_audio_layout->setWidget(row, QFormLayout::FieldRole, ui_loopsfx_cb);
-
- row += 1;
- ui_objectmusic_lbl = new QLabel(ui_audio_widget);
- ui_objectmusic_lbl->setText(tr("Kill Music On Objection:"));
- ui_objectmusic_lbl->setToolTip(
- tr("If true, AO2 will ask the server to stop music when you use 'Objection!' "));
-
- ui_audio_layout->setWidget(row, QFormLayout::LabelRole, ui_objectmusic_lbl);
-
- ui_objectmusic_cb = new QCheckBox(ui_audio_widget);
-
- ui_audio_layout->setWidget(row, QFormLayout::FieldRole, ui_objectmusic_cb);
-
- row += 1;
- ui_disablestreams_lbl = new QLabel(ui_audio_widget);
- ui_disablestreams_lbl->setText(tr("Disable Music Streaming:"));
- ui_disablestreams_lbl->setToolTip(
- tr("If true, AO2 will not play any streamed audio and show that streaming is disabled."));
- ui_audio_layout->setWidget(row, QFormLayout::LabelRole, ui_disablestreams_lbl);
-
- ui_disablestreams_cb = new QCheckBox(ui_audio_widget);
- ui_audio_layout->setWidget(row, QFormLayout::FieldRole, ui_disablestreams_cb);
-
- // The casing tab!
- ui_casing_tab = new QWidget(this);
- ui_settings_tabs->addTab(ui_casing_tab, tr("Casing"));
-
- ui_casing_widget = new QWidget(ui_casing_tab);
- ui_casing_widget->setGeometry(QRect(10, 10, 361, 211));
-
- ui_casing_layout = new QFormLayout(ui_casing_widget);
- ui_casing_layout->setLabelAlignment(Qt::AlignLeading | Qt::AlignLeft |
- Qt::AlignVCenter);
- ui_casing_layout->setFormAlignment(Qt::AlignLeading | Qt::AlignLeft |
- Qt::AlignTop);
- ui_casing_layout->setContentsMargins(0, 0, 0, 0);
- row = 0;
-
- // -- SERVER SUPPORTS CASING
-
- ui_casing_supported_lbl = new QLabel(ui_casing_widget);
- if (ao_app->casing_alerts_supported)
- ui_casing_supported_lbl->setText(tr("This server supports case alerts."));
- else
- ui_casing_supported_lbl->setText(
- tr("This server does not support case alerts."));
- ui_casing_supported_lbl->setToolTip(tr("Pretty self-explanatory."));
-
- ui_casing_layout->setWidget(row, QFormLayout::FieldRole,
- ui_casing_supported_lbl);
-
- // -- CASE ANNOUNCEMENTS
-
- row += 1;
- ui_casing_enabled_lbl = new QLabel(ui_casing_widget);
- ui_casing_enabled_lbl->setText(tr("Casing:"));
- ui_casing_enabled_lbl->setToolTip(
- tr("If checked, you will get alerts about case "
- "announcements."));
-
- ui_casing_layout->setWidget(row, QFormLayout::LabelRole,
- ui_casing_enabled_lbl);
-
- ui_casing_enabled_cb = new QCheckBox(ui_casing_widget);
-
- ui_casing_layout->setWidget(row, QFormLayout::FieldRole,
- ui_casing_enabled_cb);
-
- // -- DEFENSE ANNOUNCEMENTS
-
- row += 1;
- ui_casing_def_lbl = new QLabel(ui_casing_widget);
- ui_casing_def_lbl->setText(tr("Defense:"));
- ui_casing_def_lbl->setToolTip(tr("If checked, you will get alerts about case "
- "announcements if a defense spot is open."));
-
- ui_casing_layout->setWidget(row, QFormLayout::LabelRole, ui_casing_def_lbl);
-
- ui_casing_def_cb = new QCheckBox(ui_casing_widget);
-
- ui_casing_layout->setWidget(row, QFormLayout::FieldRole, ui_casing_def_cb);
-
- // -- PROSECUTOR ANNOUNCEMENTS
-
- row += 1;
- ui_casing_pro_lbl = new QLabel(ui_casing_widget);
- ui_casing_pro_lbl->setText(tr("Prosecution:"));
- ui_casing_pro_lbl->setToolTip(
- tr("If checked, you will get alerts about case "
- "announcements if a prosecutor spot is open."));
-
- ui_casing_layout->setWidget(row, QFormLayout::LabelRole, ui_casing_pro_lbl);
-
- ui_casing_pro_cb = new QCheckBox(ui_casing_widget);
-
- ui_casing_layout->setWidget(row, QFormLayout::FieldRole, ui_casing_pro_cb);
-
- // -- JUDGE ANNOUNCEMENTS
-
- row += 1;
- ui_casing_jud_lbl = new QLabel(ui_casing_widget);
- ui_casing_jud_lbl->setText(tr("Judge:"));
- ui_casing_jud_lbl->setToolTip(tr("If checked, you will get alerts about case "
- "announcements if the judge spot is open."));
-
- ui_casing_layout->setWidget(row, QFormLayout::LabelRole, ui_casing_jud_lbl);
-
- ui_casing_jud_cb = new QCheckBox(ui_casing_widget);
-
- ui_casing_layout->setWidget(row, QFormLayout::FieldRole, ui_casing_jud_cb);
-
- // -- JUROR ANNOUNCEMENTS
-
- row += 1;
- ui_casing_jur_lbl = new QLabel(ui_casing_widget);
- ui_casing_jur_lbl->setText(tr("Juror:"));
- ui_casing_jur_lbl->setToolTip(tr("If checked, you will get alerts about case "
- "announcements if a juror spot is open."));
-
- ui_casing_layout->setWidget(row, QFormLayout::LabelRole, ui_casing_jur_lbl);
-
- ui_casing_jur_cb = new QCheckBox(ui_casing_widget);
-
- ui_casing_layout->setWidget(row, QFormLayout::FieldRole, ui_casing_jur_cb);
-
- // -- STENO ANNOUNCEMENTS
-
- row += 1;
- ui_casing_steno_lbl = new QLabel(ui_casing_widget);
- ui_casing_steno_lbl->setText(tr("Stenographer:"));
- ui_casing_steno_lbl->setToolTip(
- tr("If checked, you will get alerts about case "
- "announcements if a stenographer spot is open."));
-
- ui_casing_layout->setWidget(row, QFormLayout::LabelRole, ui_casing_steno_lbl);
-
- ui_casing_steno_cb = new QCheckBox(ui_casing_widget);
-
- ui_casing_layout->setWidget(row, QFormLayout::FieldRole, ui_casing_steno_cb);
-
- // -- CM ANNOUNCEMENTS
-
- row += 1;
- ui_casing_cm_lbl = new QLabel(ui_casing_widget);
- ui_casing_cm_lbl->setText(tr("CM:"));
- ui_casing_cm_lbl->setToolTip(
- tr("If checked, you will appear amongst the potential "
- "CMs on the server."));
-
- ui_casing_layout->setWidget(row, QFormLayout::LabelRole, ui_casing_cm_lbl);
-
- ui_casing_cm_cb = new QCheckBox(ui_casing_widget);
-
- ui_casing_layout->setWidget(row, QFormLayout::FieldRole, ui_casing_cm_cb);
-
- // -- CM CASES ANNOUNCEMENTS
-
- row += 1;
- ui_casing_cm_cases_lbl = new QLabel(ui_casing_widget);
- ui_casing_cm_cases_lbl->setText(tr("Hosting cases:"));
- ui_casing_cm_cases_lbl->setToolTip(
- tr("If you're a CM, enter what cases you are "
- "willing to host."));
-
- ui_casing_layout->setWidget(row, QFormLayout::LabelRole,
- ui_casing_cm_cases_lbl);
-
- ui_casing_cm_cases_textbox = new QLineEdit(ui_casing_widget);
-
- ui_casing_layout->setWidget(row, QFormLayout::FieldRole,
- ui_casing_cm_cases_textbox);
-
- // Assets tab
- ui_assets_tab = new QWidget(this);
- ui_assets_tab_layout = new QVBoxLayout(ui_assets_tab);
- ui_assets_tab->setLayout(ui_assets_tab_layout);
- ui_settings_tabs->addTab(ui_assets_tab, tr("Assets"));
-
- ui_asset_lbl = new QLabel(ui_assets_tab);
- ui_asset_lbl->setText(
- tr("Add or remove base folders for use by assets. "
- "Base folders on the bottom are prioritized over those above them."));
- ui_asset_lbl->setWordWrap(true);
- ui_assets_tab_layout->addWidget(ui_asset_lbl);
-
- ui_mount_list = new QListWidget(ui_assets_tab);
- ui_assets_tab_layout->addWidget(ui_mount_list);
-
- ui_mount_buttons_layout = new QGridLayout(ui_assets_tab);
- ui_assets_tab_layout->addLayout(ui_mount_buttons_layout);
-
- QSizePolicy stretch_btns(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
- stretch_btns.setHorizontalStretch(4);
-
- ui_mount_add = new QPushButton(tr("Add…"), ui_assets_tab);
- ui_mount_add->setSizePolicy(stretch_btns);
- ui_mount_buttons_layout->addWidget(ui_mount_add, 0, 0, 1, 1);
- connect(ui_mount_add, &QPushButton::clicked, this, [this] {
- QString path = QFileDialog::getExistingDirectory(this, tr("Select a base folder"),
- QApplication::applicationDirPath(),
- QFileDialog::ShowDirsOnly);
- if (path.isEmpty()) {
- return;
- }
- QDir dir(QApplication::applicationDirPath());
- QString relative = dir.relativeFilePath(path);
- if (!relative.contains("../")) {
- path = relative;
- }
- QListWidgetItem *dir_item = new QListWidgetItem(path);
- ui_mount_list->addItem(dir_item);
- ui_mount_list->setCurrentItem(dir_item);
-
- // quick hack to update buttons
- emit ui_mount_list->itemSelectionChanged();
- });
-
- ui_mount_remove = new QPushButton(tr("Remove"), ui_assets_tab);
- ui_mount_remove->setSizePolicy(stretch_btns);
- ui_mount_remove->setEnabled(false);
- ui_mount_buttons_layout->addWidget(ui_mount_remove, 0, 1, 1, 1);
- connect(ui_mount_remove, &QPushButton::clicked, this, [this] {
- auto selected = ui_mount_list->selectedItems();
- if (selected.isEmpty())
- return;
- delete selected[0];
- emit ui_mount_list->itemSelectionChanged();
- asset_cache_dirty = true;
- });
-
- auto *mount_buttons_spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding,
- QSizePolicy::Minimum);
- ui_mount_buttons_layout->addItem(mount_buttons_spacer, 0, 2, 1, 1);
-
- ui_mount_up = new QPushButton(tr("↑"), ui_assets_tab);
- ui_mount_up->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
- ui_mount_up->setMaximumWidth(40);
- ui_mount_up->setEnabled(false);
- ui_mount_buttons_layout->addWidget(ui_mount_up, 0, 3, 1, 1);
- connect(ui_mount_up, &QPushButton::clicked, this, [this] {
- auto selected = ui_mount_list->selectedItems();
- if (selected.isEmpty())
- return;
- auto *item = selected[0];
- int row = ui_mount_list->row(item);
- ui_mount_list->takeItem(row);
- int new_row = qMax(1, row - 1);
- ui_mount_list->insertItem(new_row, item);
- ui_mount_list->setCurrentRow(new_row);
- asset_cache_dirty = true;
- });
-
- ui_mount_down = new QPushButton(tr("↓"), ui_assets_tab);
- ui_mount_down->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
- ui_mount_down->setMaximumWidth(40);
- ui_mount_down->setEnabled(false);
- ui_mount_buttons_layout->addWidget(ui_mount_down, 0, 4, 1, 1);
- connect(ui_mount_down, &QPushButton::clicked, this, [this] {
- auto selected = ui_mount_list->selectedItems();
- if (selected.isEmpty())
- return;
- auto *item = selected[0];
- int row = ui_mount_list->row(item);
- ui_mount_list->takeItem(row);
- int new_row = qMin(ui_mount_list->count() + 1, row + 1);
- ui_mount_list->insertItem(new_row, item);
- ui_mount_list->setCurrentRow(new_row);
- asset_cache_dirty = true;
- });
-
- auto *mount_buttons_spacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding,
- QSizePolicy::Minimum);
- ui_mount_buttons_layout->addItem(mount_buttons_spacer_2, 0, 5, 1, 1);
-
- ui_mount_clear_cache = new QPushButton(tr("Clear Cache"), ui_assets_tab);
- ui_mount_clear_cache->setToolTip(tr("Clears the lookup cache for assets. "
- "Use this when you have added an asset that takes precedence over another "
- "existing asset."));
- ui_mount_buttons_layout->addWidget(ui_mount_clear_cache, 0, 6, 1, 1);
- connect(ui_mount_clear_cache, &QPushButton::clicked, this, [this] {
- asset_cache_dirty = true;
- ui_mount_clear_cache->setEnabled(false);
- });
-
- connect(ui_mount_list, &QListWidget::itemSelectionChanged, this, [this] {
- auto selected_items = ui_mount_list->selectedItems();
- bool row_selected = !ui_mount_list->selectedItems().isEmpty();
- ui_mount_remove->setEnabled(row_selected);
- ui_mount_up->setEnabled(row_selected);
- ui_mount_down->setEnabled(row_selected);
-
- if (!row_selected)
- return;
-
- int row = ui_mount_list->row(selected_items[0]);
- if (row <= 1)
- ui_mount_up->setEnabled(false);
- if (row >= ui_mount_list->count() - 1)
- ui_mount_down->setEnabled(false);
- });
-
- // Logging tab
- ui_logging_tab = new QWidget(this);
- ui_settings_tabs->addTab(ui_logging_tab, tr("Logging"));
- ui_form_logging_widget = new QWidget(this);
-
- ui_logging_form = new QFormLayout(ui_form_logging_widget);
- ui_logging_form->setLabelAlignment(Qt::AlignLeading | Qt::AlignLeft |
- Qt::AlignVCenter);
- ui_logging_form->setFormAlignment(Qt::AlignLeading | Qt::AlignLeft |
- Qt::AlignTop);
- ui_logging_form->setContentsMargins(5, 5, 0, 0);
- ui_logging_form->setSpacing(4);
- row = 0;
-
- ui_downwards_lbl = new QLabel(ui_form_logging_widget);
- ui_downwards_lbl->setText(tr("Log goes downwards:"));
- ui_downwards_lbl->setToolTip(
- tr("If ticked, new messages will appear at "
- "the bottom (like the OOC chatlog). The traditional "
- "(AO1) behaviour is equivalent to this being unticked."));
-
- ui_logging_form->setWidget(row, QFormLayout::LabelRole, ui_downwards_lbl);
-
- ui_downwards_cb = new QCheckBox(ui_form_logging_widget);
-
- ui_logging_form->setWidget(row, QFormLayout::FieldRole, ui_downwards_cb);
-
- row += 1;
- ui_length_lbl = new QLabel(ui_form_logging_widget);
- ui_length_lbl->setText(tr("Log length:"));
- ui_length_lbl->setToolTip(tr(
- "The amount of message lines the IC chatlog will keep before "
- "deleting older message lines. A value of 0 or below counts as 'infinite'."));
-
- ui_logging_form->setWidget(row, QFormLayout::LabelRole, ui_length_lbl);
-
- ui_length_spinbox = new QSpinBox(ui_form_logging_widget);
- ui_length_spinbox->setSuffix(" lines");
- ui_length_spinbox->setMaximum(10000);
-
- ui_logging_form->setWidget(row, QFormLayout::FieldRole, ui_length_spinbox);
-
- row += 1;
- ui_log_newline_lbl = new QLabel(ui_form_logging_widget);
- ui_log_newline_lbl->setText(tr("Log newline:"));
- ui_log_newline_lbl->setToolTip(
- tr("If ticked, new messages will appear separated, "
- "with the message coming on the next line after the name. "
- "When unticked, it displays it as 'name: message'."));
-
- ui_logging_form->setWidget(row, QFormLayout::LabelRole, ui_log_newline_lbl);
-
- ui_log_newline_cb = new QCheckBox(ui_form_logging_widget);
-
- ui_logging_form->setWidget(row, QFormLayout::FieldRole, ui_log_newline_cb);
-
- row += 1;
- ui_log_margin_lbl = new QLabel(ui_form_logging_widget);
- ui_log_margin_lbl->setText(tr("Log margin:"));
- ui_log_margin_lbl->setToolTip(tr(
- "The distance in pixels between each entry in the IC log. "
- "Default: 0."));
-
- ui_logging_form->setWidget(row, QFormLayout::LabelRole, ui_log_margin_lbl);
-
- ui_log_margin_spinbox = new QSpinBox(ui_form_logging_widget);
- ui_log_margin_spinbox->setSuffix(" px");
- ui_log_margin_spinbox->setMaximum(1000);
-
- ui_logging_form->setWidget(row, QFormLayout::FieldRole, ui_log_margin_spinbox);
-
- row += 1;
- ui_log_timestamp_lbl = new QLabel(ui_form_logging_widget);
- ui_log_timestamp_lbl->setText(tr("Log timestamp:"));
- ui_log_timestamp_lbl->setToolTip(
- tr("If ticked, log will contain a timestamp in UTC before the name."));
-
- ui_logging_form->setWidget(row, QFormLayout::LabelRole, ui_log_timestamp_lbl);
-
- ui_log_timestamp_cb = new QCheckBox(ui_form_logging_widget);
-
- connect(ui_log_timestamp_cb, &QCheckBox::stateChanged, this, &AOOptionsDialog::timestamp_cb_changed);
-
- ui_logging_form->setWidget(row, QFormLayout::FieldRole, ui_log_timestamp_cb);
-
- row += 1;
- ui_log_timestamp_format_lbl = new QLabel(ui_form_logging_widget);
- ui_log_timestamp_format_lbl->setText(tr("Log timestamp format:\n") + QDateTime::currentDateTime().toString(ao_app->get_log_timestamp_format()));
- ui_logging_form->setWidget(row, QFormLayout::LabelRole, ui_log_timestamp_format_lbl);
-
- ui_log_timestamp_format_combobox = new QComboBox(ui_form_logging_widget);
- ui_log_timestamp_format_combobox->setEditable(true);
-
- QString l_current_format = ao_app->get_log_timestamp_format();
-
- ui_log_timestamp_format_combobox->setCurrentText(l_current_format);
- ui_log_timestamp_format_combobox->addItem("h:mm:ss AP"); // 2:13:09 PM
- ui_log_timestamp_format_combobox->addItem("hh:mm:ss"); // 14:13:09
- ui_log_timestamp_format_combobox->addItem("h:mm AP"); // 2:13 PM
- ui_log_timestamp_format_combobox->addItem("hh:mm"); // 14:13
-
- ui_logging_form->setWidget(row, QFormLayout::FieldRole, ui_log_timestamp_format_combobox);
-
- connect(ui_log_timestamp_format_combobox, &QComboBox::currentTextChanged, this, &AOOptionsDialog::on_timestamp_format_edited);
-
- if(!ao_app->get_log_timestamp()) {
- ui_log_timestamp_format_combobox->setDisabled(true);
- }
- row += 1;
- ui_log_ic_actions_lbl = new QLabel(ui_form_logging_widget);
- ui_log_ic_actions_lbl->setText(tr("Log IC actions:"));
- ui_log_ic_actions_lbl->setToolTip(
- tr("If ticked, log will show IC actions such as shouting and presenting evidence."));
-
- ui_logging_form->setWidget(row, QFormLayout::LabelRole, ui_log_ic_actions_lbl);
-
- ui_log_ic_actions_cb = new QCheckBox(ui_form_logging_widget);
-
- ui_logging_form->setWidget(row, QFormLayout::FieldRole, ui_log_ic_actions_cb);
-
- row += 1;
- ui_desync_logs_lbl = new QLabel(ui_form_logging_widget);
- ui_desync_logs_lbl->setText(tr("Desynchronize IC Logs:"));
- ui_desync_logs_lbl->setToolTip(
- tr("If ticked, log will show messages as-received, while viewport will parse according to the queue (Text Stay Time)."));
-
- ui_logging_form->setWidget(row, QFormLayout::LabelRole, ui_desync_logs_lbl);
-
- ui_desync_logs_cb = new QCheckBox(ui_form_logging_widget);
-
- ui_logging_form->setWidget(row, QFormLayout::FieldRole, ui_desync_logs_cb);
-
- //Check whether mass logging is enabled
- row += 1;
- ui_log_text_lbl = new QLabel(ui_form_logging_widget);
- ui_log_text_lbl->setText(tr("Log to Text Files:"));
- ui_log_text_lbl->setToolTip(
- tr("Text logs of gameplay will be automatically written in the /logs folder."));
- ui_logging_form->setWidget(row, QFormLayout::LabelRole, ui_log_text_lbl);
-
- ui_log_text_cb = new QCheckBox(ui_form_logging_widget);
- ui_logging_form->setWidget(row, QFormLayout::FieldRole, ui_log_text_cb);
-
- row += 1;
- ui_log_demo_lbl = new QLabel(ui_form_logging_widget);
- ui_log_demo_lbl->setText(tr("Log to Demo Files:"));
- ui_log_demo_lbl->setToolTip(
- tr("Gameplay will be automatically recorded as demos in the /logs folder."));
- ui_logging_form->setWidget(row, QFormLayout::LabelRole, ui_log_demo_lbl);
-
- ui_log_demo_cb = new QCheckBox(ui_form_logging_widget);
- ui_logging_form->setWidget(row, QFormLayout::FieldRole, ui_log_demo_cb);
-
- // Finish logging tab
- QScrollArea *log_scroll = new QScrollArea(this);
- log_scroll->setWidget(ui_form_logging_widget);
- ui_logging_tab->setLayout(new QVBoxLayout);
- ui_logging_tab->layout()->addWidget(log_scroll);
-
- // Privacy tab
- ui_privacy_tab = new QWidget(this);
- ui_settings_tabs->addTab(ui_privacy_tab, tr("Privacy"));
-
- ui_privacy_layout = new QVBoxLayout(ui_privacy_tab);
-
- ui_privacy_optout_cb = new QCheckBox(ui_privacy_tab);
- ui_privacy_optout_cb->setText(tr("Do not include me in public player counts"));
- ui_privacy_layout->addWidget(ui_privacy_optout_cb);
-
- ui_privacy_separator = new QFrame(ui_privacy_tab);
- ui_privacy_separator->setObjectName(QString::fromUtf8("line"));
- ui_privacy_separator->setFrameShape(QFrame::HLine);
- ui_privacy_separator->setFrameShadow(QFrame::Sunken);
- ui_privacy_layout->addWidget(ui_privacy_separator);
-
- ui_privacy_policy = new QTextBrowser(ui_privacy_tab);
- QSizePolicy privacySizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- sizePolicy.setHorizontalStretch(0);
- sizePolicy.setVerticalStretch(0);
- ui_privacy_policy->setSizePolicy(privacySizePolicy);
- ui_privacy_policy->setPlainText(tr("Getting privacy policy..."));
- ui_privacy_layout->addWidget(ui_privacy_policy);
-
- update_values();
-
- // When we're done, we should continue the updates!
- setUpdatesEnabled(true);
-}
-
-void AOOptionsDialog::update_values() {
- for (int i = 0; i < ui_theme_combobox->count(); ++i) {
- if (ui_theme_combobox->itemText(i) == ao_app->read_theme())
- {
- ui_theme_combobox->setCurrentIndex(i);
- break;
- }
- }
- QString subtheme =
- ao_app->configini->value("subtheme").value();
- for (int i = 0; i < ui_subtheme_combobox->count(); ++i) {
- if (ui_subtheme_combobox->itemText(i) == subtheme)
- {
- ui_subtheme_combobox->setCurrentIndex(i);
- break;
- }
- }
- Qt::TransformationMode scaling = ao_app->get_scaling(ao_app->get_default_scaling());
- ui_scaling_combobox->setCurrentIndex(scaling);
-
- // Let's fill the callwords text edit with the already present callwords.
- ui_callwords_textbox->document()->clear();
- foreach (QString callword, ao_app->get_call_words()) {
- ui_callwords_textbox->appendPlainText(callword);
- }
- ui_animated_theme_cb->setChecked(ao_app->get_animated_theme());
- ui_ms_textbox->setText(ao_app->configini->value("master", "").value());
- ui_casing_cm_cases_textbox->setText(ao_app->get_casing_can_host_cases());
- ui_username_textbox->setText(ao_app->get_default_username());
- ui_downwards_cb->setChecked(ao_app->get_log_goes_downwards());
- ui_log_newline_cb->setChecked(ao_app->get_log_newline());
- ui_log_timestamp_cb->setChecked(ao_app->get_log_timestamp());
- ui_log_timestamp_format_combobox->setCurrentText(ao_app->get_log_timestamp_format());
- ui_log_ic_actions_cb->setChecked(ao_app->get_log_ic_actions());
- ui_desync_logs_cb->setChecked(ao_app->is_desyncrhonized_logs_enabled());
- ui_instant_objection_cb->setChecked(ao_app->is_instant_objection_enabled());
- ui_showname_cb->setChecked(ao_app->get_showname_enabled_by_default());
- ui_discord_cb->setChecked(ao_app->is_discord_enabled());
- ui_shake_cb->setChecked(ao_app->is_shake_enabled());
- ui_effects_cb->setChecked(ao_app->is_effects_enabled());
- ui_framenetwork_cb->setChecked(ao_app->is_frame_network_enabled());
- ui_colorlog_cb->setChecked(ao_app->is_colorlog_enabled());
- ui_stickysounds_cb->setChecked(ao_app->is_stickysounds_enabled());
- ui_stickyeffects_cb->setChecked(ao_app->is_stickyeffects_enabled());
- ui_stickypres_cb->setChecked(ao_app->is_stickypres_enabled());
- ui_customchat_cb->setChecked(ao_app->is_customchat_enabled());
- ui_sticker_cb->setChecked(ao_app->is_sticker_enabled());
- ui_continuous_cb->setChecked(ao_app->is_continuous_enabled());
- ui_category_stop_cb->setChecked(ao_app->is_category_stop_enabled());
- ui_sfx_on_idle_cb->setChecked(ao_app->get_sfx_on_idle());
- ui_blank_blips_cb->setChecked(ao_app->get_blank_blip());
- ui_loopsfx_cb->setChecked(ao_app->get_looping_sfx());
- ui_objectmusic_cb->setChecked(ao_app->objection_stop_music());
- ui_disablestreams_cb->setChecked(ao_app->is_streaming_disabled());
- ui_casing_enabled_cb->setChecked(ao_app->get_casing_enabled());
- ui_casing_def_cb->setChecked(ao_app->get_casing_defence_enabled());
- ui_casing_pro_cb->setChecked(ao_app->get_casing_prosecution_enabled());
- ui_casing_jud_cb->setChecked(ao_app->get_casing_judge_enabled());
- ui_casing_jur_cb->setChecked(ao_app->get_casing_juror_enabled());
- ui_casing_steno_cb->setChecked(ao_app->get_casing_steno_enabled());
- ui_casing_cm_cb->setChecked(ao_app->get_casing_cm_enabled());
- ui_log_text_cb->setChecked(ao_app->get_text_logging_enabled());
- ui_log_demo_cb->setChecked(ao_app->get_demo_logging_enabled());
- ui_length_spinbox->setValue(ao_app->get_max_log_size());
- ui_log_margin_spinbox->setValue(ao_app->get_log_margin());
- ui_stay_time_spinbox->setValue(ao_app->stay_time());
- ui_text_crawl_spinbox->setValue(ao_app->get_text_crawl());
- ui_chat_ratelimit_spinbox->setValue(ao_app->get_chat_ratelimit());
- ui_music_volume_spinbox->setValue(ao_app->get_default_music());
- ui_sfx_volume_spinbox->setValue(ao_app->get_default_sfx());
- ui_blips_volume_spinbox->setValue(ao_app->get_default_blip());
- ui_suppress_audio_spinbox->setValue(ao_app->get_default_suppress_audio());
- ui_bliprate_spinbox->setValue(ao_app->read_blip_rate());
- ui_default_showname_textbox->setText(ao_app->get_default_showname());
- ui_evidence_double_click_cb->setChecked(ao_app->get_evidence_double_click());
-
- auto *defaultMount = new QListWidgetItem(tr("%1 (default)")
- .arg(ao_app->get_base_path()));
- defaultMount->setFlags(Qt::ItemFlag::NoItemFlags);
-
- //Clear the list to prevent duplication of default entries.
- ui_mount_list->clear();
- ui_mount_list->addItem(defaultMount);
- ui_mount_list->addItems(ao_app->get_mount_paths());
-
- ui_privacy_optout_cb->setChecked(ao_app->get_player_count_optout());
-
- ao_app->net_manager->request_document(MSDocumentType::PrivacyPolicy, [this](QString document) {
- if (document.isEmpty()) {
- document = tr("Couldn't get the privacy policy.");
- }
- ui_privacy_policy->setHtml(document);
- });
-}
-
-void AOOptionsDialog::save_pressed()
-{
- // Save everything into the config.ini.
- QSettings *configini = ao_app->configini;
-
- const bool audioChanged = ui_audio_device_combobox->currentText() !=
- ao_app->get_audio_output_device();
-
- configini->setValue("theme", ui_theme_combobox->currentText());
- configini->setValue("subtheme", ui_subtheme_combobox->currentText());
- configini->setValue("animated_theme", ui_animated_theme_cb->isChecked());
- configini->setValue("log_goes_downwards", ui_downwards_cb->isChecked());
- configini->setValue("log_maximum", ui_length_spinbox->value());
- configini->setValue("log_newline", ui_log_newline_cb->isChecked());
- configini->setValue("log_margin", ui_log_margin_spinbox->value());
- configini->setValue("log_timestamp", ui_log_timestamp_cb->isChecked());
- configini->setValue("log_timestamp_format", ui_log_timestamp_format_combobox->currentText());
- configini->setValue("log_ic_actions", ui_log_ic_actions_cb->isChecked());
- configini->setValue("desync_logs", ui_desync_logs_cb->isChecked());
- configini->setValue("stay_time", ui_stay_time_spinbox->value());
- configini->setValue("instant_objection", ui_instant_objection_cb->isChecked());
- configini->setValue("text_crawl", ui_text_crawl_spinbox->value());
- configini->setValue("chat_ratelimit", ui_chat_ratelimit_spinbox->value());
- configini->setValue("default_username", ui_username_textbox->text());
- configini->setValue("show_custom_shownames", ui_showname_cb->isChecked());
- configini->setValue("default_showname", ui_default_showname_textbox->text());
- configini->setValue("master", ui_ms_textbox->text());
- configini->setValue("discord", ui_discord_cb->isChecked());
- configini->setValue("language", ui_language_combobox->currentText().left(2));
- configini->setValue("default_scaling", ui_scaling_combobox->currentData());
- configini->setValue("shake", ui_shake_cb->isChecked());
- configini->setValue("effects", ui_effects_cb->isChecked());
- configini->setValue("framenetwork", ui_framenetwork_cb->isChecked());
- configini->setValue("colorlog", ui_colorlog_cb->isChecked());
- configini->setValue("stickysounds", ui_stickysounds_cb->isChecked());
- configini->setValue("stickyeffects", ui_stickyeffects_cb->isChecked());
- configini->setValue("stickypres", ui_stickypres_cb->isChecked());
- configini->setValue("customchat", ui_customchat_cb->isChecked());
- configini->setValue("sticker", ui_sticker_cb->isChecked());
- configini->setValue("automatic_logging_enabled", ui_log_text_cb->isChecked());
- configini->setValue("demo_logging_enabled", ui_log_demo_cb->isChecked());
- configini->setValue("continuous_playback", ui_continuous_cb->isChecked());
- configini->setValue("category_stop", ui_category_stop_cb->isChecked());
- configini->setValue("sfx_on_idle", ui_sfx_on_idle_cb->isChecked());
- configini->setValue("evidence_double_click", ui_evidence_double_click_cb->isChecked());
- QFile *callwordsini = new QFile(ao_app->get_base_path() + "callwords.ini");
-
- if (callwordsini->open(QIODevice::WriteOnly | QIODevice::Truncate |
- QIODevice::Text)) {
- QTextStream out(callwordsini);
- out.setCodec("UTF-8");
- out << ui_callwords_textbox->toPlainText();
- callwordsini->close();
- }
-
- configini->setValue("default_audio_device",
- ui_audio_device_combobox->currentText());
- configini->setValue("default_music", ui_music_volume_spinbox->value());
- configini->setValue("default_sfx", ui_sfx_volume_spinbox->value());
- configini->setValue("default_blip", ui_blips_volume_spinbox->value());
- configini->setValue("suppress_audio", ui_suppress_audio_spinbox->value());
- configini->setValue("blip_rate", ui_bliprate_spinbox->value());
- configini->setValue("blank_blip", ui_blank_blips_cb->isChecked());
- configini->setValue("looping_sfx", ui_loopsfx_cb->isChecked());
- configini->setValue("objection_stop_music", ui_objectmusic_cb->isChecked());
- configini->setValue("streaming_disabled", ui_disablestreams_cb->isChecked());
-
- configini->setValue("casing_enabled", ui_casing_enabled_cb->isChecked());
- configini->setValue("casing_defence_enabled", ui_casing_def_cb->isChecked());
- configini->setValue("casing_prosecution_enabled",
- ui_casing_pro_cb->isChecked());
- configini->setValue("casing_judge_enabled", ui_casing_jud_cb->isChecked());
- configini->setValue("casing_juror_enabled", ui_casing_jur_cb->isChecked());
- configini->setValue("casing_steno_enabled", ui_casing_steno_cb->isChecked());
- configini->setValue("casing_cm_enabled", ui_casing_cm_cb->isChecked());
- configini->setValue("casing_can_host_cases",
- ui_casing_cm_cases_textbox->text());
- configini->setValue("player_count_optout", ui_privacy_optout_cb->isChecked());
-
- QStringList mountPaths;
- for (int i = 1; i < ui_mount_list->count(); i++)
- mountPaths.append(ui_mount_list->item(i)->text());
- configini->setValue("mount_paths", mountPaths);
-
- if (audioChanged)
- ao_app->initBASS();
-
- if (asset_cache_dirty)
- ao_app->invalidate_lookup_cache();
-
- // We most probably pressed "Restore defaults" at some point. Since we're saving our settings, remove the temporary file.
- if (QFile::exists(ao_app->get_base_path() + "config.temp"))
- QFile::remove(ao_app->get_base_path() + "config.temp");
- done(0);
-}
-
-void AOOptionsDialog::discard_pressed() {
- // The .temp file exists, meaning we are trying to undo the user clicking on "Restore defaults" and bring back the old settings.
- if (QFile::exists(ao_app->get_base_path() + "config.temp")) {
- // Delete the QSettings object so it does not interfere with the file
- delete ao_app->configini;
- // Remove the current config.ini
- QFile::remove(ao_app->get_base_path() + "config.ini");
- // Rename .temp to .ini
- QFile::rename(ao_app->get_base_path() + "config.temp", ao_app->get_base_path() + "config.ini");
- // Recreate the QSettings object from the ini file, restoring the settings before the Options Dialog was opened..
- ao_app->configini =
- new QSettings(ao_app->get_base_path() + "config.ini", QSettings::IniFormat);
- }
- done(0);
-}
-
-void AOOptionsDialog::button_clicked(QAbstractButton *button) {
- if (ui_settings_buttons->buttonRole(button) == QDialogButtonBox::ResetRole) {
- // Store the current settings as a .temp file
- QFile::rename(ao_app->get_base_path() + "config.ini", ao_app->get_base_path() + "config.temp");
- // Load up the default settings
- ao_app->configini->clear();
- // Update the values on the settings ui
- update_values();
- }
-}
-
-void AOOptionsDialog::on_reload_theme_clicked() {
- ao_app->configini->setValue("theme", ui_theme_combobox->currentText());
- ao_app->configini->setValue("subtheme", ui_subtheme_combobox->currentText());
- ao_app->configini->setValue("animated_theme", ui_animated_theme_cb->isChecked());
- if (ao_app->courtroom_constructed)
- ao_app->w_courtroom->on_reload_theme_clicked();
- if (ao_app->lobby_constructed)
- ao_app->w_lobby->set_widgets();
-}
-
-void AOOptionsDialog::theme_changed(int i) {
- ui_subtheme_combobox->clear();
- // Fill the combobox with the names of the themes.
- ui_subtheme_combobox->addItem("server");
- ui_subtheme_combobox->addItem("default");
- QDirIterator it(ao_app->get_real_path(ao_app->get_theme_path("", ui_theme_combobox->itemText(i))), QDir::Dirs,
- QDirIterator::NoIteratorFlags);
- while (it.hasNext()) {
- QString actualname = QDir(it.next()).dirName();
- if (actualname != "." && actualname != ".." && actualname.toLower() != "server" && actualname.toLower() != "default" && actualname.toLower() != "effects" && actualname.toLower() != "misc")
- ui_subtheme_combobox->addItem(actualname);
- }
-
-}
-
-void AOOptionsDialog::on_timestamp_format_edited() { ui_log_timestamp_format_lbl->setText(tr("Log timestamp format:\n") + QDateTime::currentDateTime().toString(ui_log_timestamp_format_combobox->currentText())); }
-
-void AOOptionsDialog::timestamp_cb_changed(int state) { ui_log_timestamp_format_combobox->setDisabled(state == 0); }
-
-#if (defined(_WIN32) || defined(_WIN64))
-bool AOOptionsDialog::needs_default_audiodev() { return true; }
-#elif (defined(LINUX) || defined(__linux__))
-bool AOOptionsDialog::needs_default_audiodev() { return false; }
-#elif defined __APPLE__
-bool AOOptionsDialog::needs_default_audiodev() { return true; }
-#else
-#error This operating system is not supported.
-#endif
diff --git a/src/courtroom.cpp b/src/courtroom.cpp
index efea86d50..aa940719c 100644
--- a/src/courtroom.cpp
+++ b/src/courtroom.cpp
@@ -1,4 +1,5 @@
#include "courtroom.h"
+#include "options.h"
Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
{
@@ -114,15 +115,15 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
ui_ic_chatlog->setReadOnly(true);
ui_ic_chatlog->setObjectName("ui_ic_chatlog");
- log_maximum_blocks = ao_app->get_max_log_size();
- log_goes_downwards = ao_app->get_log_goes_downwards();
- log_colors = ao_app->is_colorlog_enabled();
- log_newline = ao_app->get_log_newline();
- log_margin = ao_app->get_log_margin();
- log_timestamp = ao_app->get_log_timestamp();
- log_timestamp_format = ao_app->get_log_timestamp_format();
+ log_maximum_blocks = Options::getInstance().maxLogSize();
+ log_goes_downwards = Options::getInstance().logDirectionDownwards();
+ log_colors = Options::getInstance().colorLogEnabled();
+ log_newline = Options::getInstance().logNewline();
+ log_margin = Options::getInstance().logMargin();
+ log_timestamp = Options::getInstance().logTimestampEnabled();
+ log_timestamp_format = Options::getInstance().logTimestampFormat();
- ui_debug_log = new AOTextArea(this, ao_app->get_max_log_size());
+ ui_debug_log = new AOTextArea(this, Options::getInstance().maxLogSize());
ui_debug_log->setReadOnly(true);
ui_debug_log->setOpenExternalLinks(true);
ui_debug_log->hide();
@@ -176,7 +177,7 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
ui_ic_chat_name = new QLineEdit(this);
ui_ic_chat_name->setFrame(false);
ui_ic_chat_name->setPlaceholderText(tr("Showname"));
- ui_ic_chat_name->setText(p_ao_app->get_default_showname());
+ ui_ic_chat_name->setText(Options::getInstance().shownameOnJoin());
ui_ic_chat_name->setObjectName("ui_ic_chat_name");
ui_ic_chat_message = new QLineEdit(this);
@@ -200,7 +201,7 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
ui_ooc_chat_name->setFrame(false);
ui_ooc_chat_name->setPlaceholderText(tr("Name"));
ui_ooc_chat_name->setMaxLength(30);
- ui_ooc_chat_name->setText(p_ao_app->get_default_username());
+ ui_ooc_chat_name->setText(Options::getInstance().username());
ui_ooc_chat_name->setObjectName("ui_ooc_chat_name");
// ui_area_password = new QLineEdit(this);
@@ -316,13 +317,13 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
ui_additive->setObjectName("ui_additive");
ui_casing = new QCheckBox(this);
- ui_casing->setChecked(ao_app->get_casing_enabled());
+ ui_casing->setChecked(Options::getInstance().casingAlertEnabled());
ui_casing->setText(tr("Casing"));
ui_casing->hide();
ui_casing->setObjectName("ui_casing");
ui_showname_enable = new QCheckBox(this);
- ui_showname_enable->setChecked(ao_app->get_showname_enabled_by_default());
+ ui_showname_enable->setChecked(Options::getInstance().customShownameEnabled());
ui_showname_enable->setText(tr("Shownames"));
ui_showname_enable->setObjectName("ui_showname_enable");
@@ -365,17 +366,17 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
ui_music_slider = new QSlider(Qt::Horizontal, this);
ui_music_slider->setRange(0, 100);
- ui_music_slider->setValue(ao_app->get_default_music());
+ ui_music_slider->setValue(Options::getInstance().musicVolume());
ui_music_slider->setObjectName("ui_music_slider");
ui_sfx_slider = new QSlider(Qt::Horizontal, this);
ui_sfx_slider->setRange(0, 100);
- ui_sfx_slider->setValue(ao_app->get_default_sfx());
+ ui_sfx_slider->setValue(Options::getInstance().sfxVolume());
ui_sfx_slider->setObjectName("ui_sfx_slider");
ui_blip_slider = new QSlider(Qt::Horizontal, this);
ui_blip_slider->setRange(0, 100);
- ui_blip_slider->setValue(ao_app->get_default_blip());
+ ui_blip_slider->setValue(Options::getInstance().blipVolume());
ui_blip_slider->setObjectName("ui_blip_slider");
ui_mute_list = new QListWidget(this);
@@ -409,6 +410,10 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
initialize_emotes();
initialize_evidence();
+ // TODO : Properly handle widget creation order.
+ // Good enough for 2.10
+ ui_pair_list->raise();
+
construct_char_select();
connect(keepalive_timer, &QTimer::timeout, this, &Courtroom::ping_server);
@@ -580,7 +585,7 @@ void Courtroom::on_application_state_changed(Qt::ApplicationState state)
suppress_audio = 0;
if (state != Qt::ApplicationActive) {
// Suppressed audio setting
- suppress_audio = ao_app->get_default_suppress_audio();
+ suppress_audio = Options::getInstance().defaultSuppressAudio();
}
update_audio_volume();
}
@@ -664,9 +669,6 @@ void Courtroom::set_pair_list()
void Courtroom::set_widgets()
{
QString filename = "courtroom_design.ini";
- // Update the default theme from the courtroom_design.ini, if it's not defined it will be 'default'.
- QSettings settings(ao_app->get_real_path(ao_app->get_theme_path(filename, ao_app->current_theme)), QSettings::IniFormat);
- ao_app->default_theme = settings.value("default_theme", "default").toString();
set_fonts();
set_size_and_pos(ui_viewport, "viewport");
@@ -744,20 +746,20 @@ void Courtroom::set_widgets()
ui_vp_objection->move_and_center(ui_viewport->x(), ui_viewport->y());
ui_vp_objection->combo_resize(ui_viewport->width(), ui_viewport->height());
- log_maximum_blocks = ao_app->get_max_log_size();
-
- bool regenerate = log_goes_downwards != ao_app->get_log_goes_downwards() ||
- log_colors != ao_app->is_colorlog_enabled() ||
- log_newline != ao_app->get_log_newline() ||
- log_margin != ao_app->get_log_margin() ||
- log_timestamp != ao_app->get_log_timestamp() ||
- log_timestamp_format != ao_app->get_log_timestamp_format();
- log_goes_downwards = ao_app->get_log_goes_downwards();
- log_colors = ao_app->is_colorlog_enabled();
- log_newline = ao_app->get_log_newline();
- log_margin = ao_app->get_log_margin();
- log_timestamp = ao_app->get_log_timestamp();
- log_timestamp_format = ao_app->get_log_timestamp_format();
+ log_maximum_blocks = Options::getInstance().maxLogSize();
+
+ bool regenerate = log_goes_downwards != Options::getInstance().logDirectionDownwards() ||
+ log_colors != Options::getInstance().colorLogEnabled() ||
+ log_newline != Options::getInstance().logNewline() ||
+ log_margin != Options::getInstance().logMargin() ||
+ log_timestamp != Options::getInstance().logTimestampEnabled() ||
+ log_timestamp_format != Options::getInstance().logTimestampFormat();
+ log_goes_downwards = Options::getInstance().logDirectionDownwards();
+ log_colors = Options::getInstance().colorLogEnabled();
+ log_newline = Options::getInstance().logNewline();
+ log_margin = Options::getInstance().logMargin();
+ log_timestamp = Options::getInstance().logTimestampEnabled();
+ log_timestamp_format = Options::getInstance().logTimestampFormat();
if (regenerate) {
regenerate_ic_chatlog();
}
@@ -1386,7 +1388,7 @@ void Courtroom::set_background(QString p_background, bool display)
ui_vp_message->hide();
ui_vp_chatbox->setVisible(chatbox_always_show);
// Show it if chatbox always shows
- if (ao_app->is_sticker_enabled() && chatbox_always_show) {
+ if (Options::getInstance().characterStickerEnabled() && chatbox_always_show) {
ui_vp_sticker->load_image(m_chatmessage[CHAR_NAME]);
}
// Hide the face sticker
@@ -1487,7 +1489,7 @@ void Courtroom::update_character(int p_cid, QString char_name, bool reset_emote)
QString f_char;
if (m_cid == -1) {
- if (ao_app->is_discord_enabled())
+ if (Options::getInstance().discordEnabled())
ao_app->discord->state_spectate();
f_char = "";
}
@@ -1497,7 +1499,7 @@ void Courtroom::update_character(int p_cid, QString char_name, bool reset_emote)
f_char = char_list.at(m_cid).name;
}
- if (ao_app->is_discord_enabled())
+ if (Options::getInstance().discordEnabled())
ao_app->discord->state_character(f_char.toStdString());
}
@@ -1590,9 +1592,6 @@ void Courtroom::update_character(int p_cid, QString char_name, bool reset_emote)
void Courtroom::enter_courtroom()
{
- current_evidence_page = 0;
- current_evidence = 0;
-
set_evidence_page();
if (ao_app->flipping_supported)
@@ -1817,7 +1816,7 @@ void Courtroom::append_server_chatmessage(QString p_name, QString p_message,
ui_server_chatlog->append_chatmessage(p_name, p_message, color);
- if (ao_app->get_text_logging_enabled() && !ao_app->log_filename.isEmpty()) {
+ if (Options::getInstance().logToTextFileEnabled() && !ao_app->log_filename.isEmpty()) {
QString full = "[OOC][" + QDateTime::currentDateTimeUtc().toString() + "] " + p_name + ": " + p_message;
ao_app->append_to_file(full, ao_app->log_filename, true);
}
@@ -1844,7 +1843,7 @@ void Courtroom::on_chat_return_pressed()
return;
ui_ic_chat_message->blockSignals(true);
- QTimer::singleShot(ao_app->get_chat_ratelimit(), this,
+ QTimer::singleShot(Options::getInstance().chatRateLimit(), this,
[this] { ui_ic_chat_message->blockSignals(false); });
// MS#
// deskmod#
@@ -1948,7 +1947,7 @@ void Courtroom::on_chat_return_pressed()
f_sfx = get_char_sfx();
// We have a custom sfx but we're on idle emotes.
// Turn them into pre so the sound plays if client setting sfx_on_idle is enabled.
- if (ao_app->get_sfx_on_idle() && (f_emote_mod == IDLE || f_emote_mod == ZOOM)) {
+ if (Options::getInstance().playSelectedSFXOnIdle() && (f_emote_mod == IDLE || f_emote_mod == ZOOM)) {
// We turn idle into preanim, but make it not send a pre animation
f_pre = "";
// Set sfx delay to 0 so the sfx plays immediately
@@ -1988,7 +1987,7 @@ void Courtroom::on_chat_return_pressed()
f_obj_state = QString::number(objection_state);
// We're doing an Objection (custom objections not yet supported)
- if (objection_state == 2 && ao_app->objection_stop_music())
+ if (objection_state == 2 && Options::getInstance().objectionStopMusic())
music_stop(true);
packet_contents.append(f_obj_state);
@@ -2081,7 +2080,7 @@ void Courtroom::on_chat_return_pressed()
QString packet;
foreach (QString f_emote, emotes_to_check) {
packet += f_emote;
- if (ao_app->is_frame_network_enabled()) {
+ if (Options::getInstance().networkedFrameSfxEnabled()) {
QString sfx_frames =
ao_app
->read_ini_tags(
@@ -2112,7 +2111,7 @@ void Courtroom::on_chat_return_pressed()
}
packet_contents.append(effect + "|" + p_effect_folder + "|" + fx_sound);
- if (!ao_app->is_stickyeffects_enabled() && !ao_app->get_effect_property(effect, current_char, p_effect_folder, "sticky").startsWith("true")) {
+ if (!Options::getInstance().clearEffectsDropdownOnPlayEnabled() && !ao_app->get_effect_property(effect, current_char, p_effect_folder, "sticky").startsWith("true")) {
ui_effects_dropdown->blockSignals(true);
ui_effects_dropdown->setCurrentIndex(0);
ui_effects_dropdown->blockSignals(false);
@@ -2141,14 +2140,14 @@ void Courtroom::reset_ui()
ui_evidence_present->set_image("present");
// If sticky sounds is disabled and we either have SFX on Idle enabled, or our Preanim checkbox is checked
- if (!ao_app->is_stickysounds_enabled() && (ao_app->get_sfx_on_idle() || ui_pre->isChecked())) {
+ if (!Options::getInstance().clearSoundsDropdownOnPlayEnabled() && (Options::getInstance().playSelectedSFXOnIdle() || ui_pre->isChecked())) {
// Reset the SFX Dropdown to "Default"
ui_sfx_dropdown->setCurrentIndex(0);
ui_sfx_remove->hide();
custom_sfx = "";
}
// If sticky preanims is disabled
- if (!ao_app->is_stickypres_enabled())
+ if (!Options::getInstance().clearPreOnPlayEnabled())
// Turn off our Preanim checkbox
ui_pre->setChecked(false);
}
@@ -2193,17 +2192,17 @@ void Courtroom::chatmessage_enqueue(QStringList p_contents)
reset_ui();
}
// If we determine we sent this message, or we have desync enabled
- if (sender || ao_app->is_desyncrhonized_logs_enabled()) {
+ if (sender || Options::getInstance().desynchronisedLogsEnabled()) {
// Initialize operation "message queue ghost"
log_chatmessage(p_contents[MESSAGE], p_contents[CHAR_ID].toInt(),
p_contents[SHOWNAME], p_contents[CHAR_NAME],
p_contents[OBJECTION_MOD], p_contents[EVIDENCE_ID].toInt(),
- p_contents[TEXT_COLOR].toInt(), QUEUED, sender || ao_app->is_desyncrhonized_logs_enabled());
+ p_contents[TEXT_COLOR].toInt(), QUEUED, sender || Options::getInstance().desynchronisedLogsEnabled());
}
bool is_objection = false;
// If the user wants to clear queue on objection
- if (ao_app->is_instant_objection_enabled())
+ if (Options::getInstance().objectionSkipQueueEnabled())
{
int objection_mod = p_contents[OBJECTION_MOD].split("&")[0].toInt();
is_objection = objection_mod >= 1 && objection_mod <= 5;
@@ -2220,7 +2219,7 @@ void Courtroom::chatmessage_enqueue(QStringList p_contents)
chatmessage_queue.enqueue(p_contents);
// Our settings disabled queue, or no message is being parsed right now and we're not waiting on one
- bool start_queue = ao_app->stay_time() <= 0 || (text_state >= 2 && !text_queue_timer->isActive());
+ bool start_queue = Options::getInstance().textStayTime() <= 0 || (text_state >= 2 && !text_queue_timer->isActive());
// Objections also immediately play the message
if (start_queue || is_objection)
chatmessage_dequeue(); // Process the message instantly
@@ -2245,7 +2244,7 @@ void Courtroom::skip_chatmessage_queue()
while (!chatmessage_queue.isEmpty()) {
QStringList p_contents = chatmessage_queue.dequeue();
// if the char ID matches our client's char ID (most likely, this is our message coming back to us)
- bool sender = ao_app->is_desyncrhonized_logs_enabled() || p_contents[CHAR_ID].toInt() == m_cid;
+ bool sender = Options::getInstance().desynchronisedLogsEnabled() || p_contents[CHAR_ID].toInt() == m_cid;
log_chatmessage(p_contents[MESSAGE], p_contents[CHAR_ID].toInt(), p_contents[SHOWNAME], p_contents[CHAR_NAME], p_contents[OBJECTION_MOD], p_contents[EVIDENCE_ID].toInt(), p_contents[TEXT_COLOR].toInt(), DISPLAY_ONLY, sender);
}
}
@@ -2268,7 +2267,7 @@ void Courtroom::unpack_chatmessage(QStringList p_contents)
}
// if the char ID matches our client's char ID (most likely, this is our message coming back to us)
- bool sender = ao_app->is_desyncrhonized_logs_enabled() || m_chatmessage[CHAR_ID].toInt() == m_cid;
+ bool sender = Options::getInstance().desynchronisedLogsEnabled() || m_chatmessage[CHAR_ID].toInt() == m_cid;
// We have logs displaying as soon as we reach the message in our queue, which is a less confusing but also less accurate experience for the user.
log_chatmessage(m_chatmessage[MESSAGE], m_chatmessage[CHAR_ID].toInt(), m_chatmessage[SHOWNAME], m_chatmessage[CHAR_NAME], m_chatmessage[OBJECTION_MOD], m_chatmessage[EVIDENCE_ID].toInt(), m_chatmessage[TEXT_COLOR].toInt(), DISPLAY_ONLY, sender);
@@ -2504,7 +2503,7 @@ void Courtroom::display_character()
ui_vp_message->hide();
ui_vp_chatbox->setVisible(chatbox_always_show);
// Show it if chatbox always shows
- if (ao_app->is_sticker_enabled() && chatbox_always_show) {
+ if (Options::getInstance().characterStickerEnabled() && chatbox_always_show) {
ui_vp_sticker->load_image(m_chatmessage[CHAR_NAME]);
}
// Hide the face sticker
@@ -2516,7 +2515,7 @@ void Courtroom::display_character()
// Arrange the netstrings of the frame SFX for the character to know about
if (!m_chatmessage[FRAME_SFX].isEmpty() &&
- ao_app->is_frame_network_enabled()) {
+ Options::getInstance().networkedFrameSfxEnabled()) {
// ORDER IS IMPORTANT!!
QStringList netstrings = {m_chatmessage[FRAME_SCREENSHAKE],
m_chatmessage[FRAME_REALIZATION],
@@ -2675,7 +2674,7 @@ void Courtroom::handle_ic_message()
}
// if we have instant objections disabled, and queue is not empty, check if next message after this is an objection.
- if (!ao_app->is_instant_objection_enabled() && chatmessage_queue.size() > 0)
+ if (!Options::getInstance().objectionSkipQueueEnabled() && chatmessage_queue.size() > 0)
{
QStringList p_contents = chatmessage_queue.head();
int objection_mod = p_contents[OBJECTION_MOD].split("&")[0].toInt();
@@ -2688,7 +2687,7 @@ void Courtroom::handle_ic_message()
void Courtroom::do_screenshake()
{
- if (!ao_app->is_shake_enabled())
+ if (!Options::getInstance().shakeEnabled())
return;
// This way, the animation is reset in such a way that last played screenshake
@@ -2737,7 +2736,7 @@ void Courtroom::do_screenshake()
void Courtroom::do_flash()
{
- if (!ao_app->is_effects_enabled())
+ if (!Options::getInstance().effectsEnabled())
return;
QString f_char = m_chatmessage[CHAR_NAME];
@@ -2761,7 +2760,7 @@ void Courtroom::do_effect(QString fx_path, QString fx_sound, QString p_char,
}
// Only check if effects are disabled after playing the sound if it exists
- if (!ao_app->is_effects_enabled()) {
+ if (!Options::getInstance().effectsEnabled()) {
return;
}
ui_vp_effect->transform_mode = ao_app->get_scaling(
@@ -2858,7 +2857,7 @@ void Courtroom::initialize_chatbox()
ui_vp_showname->setText(m_chatmessage[SHOWNAME]);
}
QString customchar;
- if (ao_app->is_customchat_enabled())
+ if (Options::getInstance().customChatboxEnabled())
customchar = m_chatmessage[CHAR_NAME];
QString p_misc = ao_app->get_chat(customchar);
@@ -2969,8 +2968,8 @@ void Courtroom::handle_callwords()
{
// Quickly check through the message for the word_call (callwords) sfx
QString f_message = m_chatmessage[MESSAGE];
- // Obtain the current call words (Really? It does File I/O on every single message???)
- QStringList call_words = ao_app->get_call_words();
+ //No more file IO on every message.
+ QStringList call_words = Options::getInstance().callwords();
// Loop through each word in the call words list
for (const QString &word : qAsConst(call_words)) {
// If our message contains that specific call word
@@ -3300,7 +3299,7 @@ void Courtroom::log_ic_text(QString p_name, QString p_showname,
{
chatlogpiece log_entry(p_name, p_showname, p_message, p_action, p_color, p_selfname);
ic_chatlog_history.append(log_entry);
- if (ao_app->get_text_logging_enabled() && !ao_app->log_filename.isEmpty())
+ if (Options::getInstance().logToTextFileEnabled() && !ao_app->log_filename.isEmpty())
ao_app->append_to_file(log_entry.get_full(), ao_app->log_filename, true);
while (ic_chatlog_history.size() > log_maximum_blocks &&
@@ -3619,7 +3618,7 @@ void Courtroom::start_chat_ticking()
ui_vp_chatbox->setVisible(chatbox_always_show);
ui_vp_message->hide();
// Show it if chatbox always shows
- if (ao_app->is_sticker_enabled() && chatbox_always_show)
+ if (Options::getInstance().characterStickerEnabled() && chatbox_always_show)
ui_vp_sticker->load_image(m_chatmessage[CHAR_NAME]);
// Hide the face sticker
else {
@@ -3627,7 +3626,7 @@ void Courtroom::start_chat_ticking()
}
}
// If we're not already waiting on the next message, start the timer. We could be overriden if there's an objection planned.
- int delay = ao_app->stay_time();
+ int delay = Options::getInstance().textStayTime();
if (delay > 0 && !text_queue_timer->isActive())
text_queue_timer->start(delay);
return;
@@ -3636,7 +3635,7 @@ void Courtroom::start_chat_ticking()
ui_vp_chatbox->show();
ui_vp_message->show();
- if (ao_app->is_sticker_enabled())
+ if (Options::getInstance().characterStickerEnabled())
ui_vp_sticker->load_image(m_chatmessage[CHAR_NAME]);
if (m_chatmessage[ADDITIVE] != "1") {
@@ -3647,9 +3646,9 @@ void Courtroom::start_chat_ticking()
tick_pos = 0;
blip_ticker = 0;
- text_crawl = ao_app->get_text_crawl();
- blip_rate = ao_app->read_blip_rate();
- blank_blip = ao_app->get_blank_blip();
+ text_crawl = Options::getInstance().textCrawlSpeed();
+ blip_rate = Options::getInstance().blipRate();
+ blank_blip = Options::getInstance().blankBlip();
// At the start of every new message, we set the text speed to the default.
current_display_speed = 3;
@@ -3710,7 +3709,7 @@ void Courtroom::chat_tick()
anim_state = 3;
QString f_char;
QString f_custom_theme;
- if (ao_app->is_customchat_enabled()) {
+ if (Options::getInstance().customChatboxEnabled()) {
f_char = m_chatmessage[CHAR_NAME];
f_custom_theme = ao_app->get_chat(f_char);
}
@@ -3726,12 +3725,12 @@ void Courtroom::chat_tick()
// If we're not already waiting on the next message, start the timer. We could be overriden if there's an objection planned.
- int delay = ao_app->stay_time();
+ int delay = Options::getInstance().textStayTime();
if (delay > 0 && !text_queue_timer->isActive())
text_queue_timer->start(delay);
// if we have instant objections disabled, and queue is not empty, check if next message after this is an objection.
- if (!ao_app->is_instant_objection_enabled() && chatmessage_queue.size() > 0)
+ if (!Options::getInstance().objectionSkipQueueEnabled() && chatmessage_queue.size() > 0)
{
QStringList p_contents = chatmessage_queue.head();
int objection_mod = p_contents[OBJECTION_MOD].split("&")[0].toInt();
@@ -3947,7 +3946,7 @@ void Courtroom::play_sfx()
return;
sfx_player->play(sfx_name);
- if (ao_app->get_looping_sfx())
+ if (Options::getInstance().loopingSfx())
sfx_player->set_looping(
ao_app->get_sfx_looping(current_char, current_emote) == "1");
}
@@ -3976,10 +3975,9 @@ void Courtroom::set_self_offset(const QString& p_list) {
}
else {
self_offset_v = self_offsets[1].toInt();
- ui_vp_player_char->move_and_center(ui_viewport->width() * self_offset / 100, ui_viewport->height() * self_offset_v / 100);
- const int percent = 100;
- ui_vp_player_char->move(ui_viewport->width() * self_offset / percent, ui_viewport->height() * self_offset_v / percent);
}
+ ui_vp_player_char->move_and_center(ui_viewport->width() * self_offset / 100,
+ ui_viewport->height() * self_offset_v / 100);
}
void Courtroom::set_ip_list(QString p_list)
@@ -5012,7 +5010,7 @@ void Courtroom::on_music_list_double_clicked(QTreeWidgetItem *p_item,
{
if (is_muted)
return;
- if (!ao_app->is_category_stop_enabled() && p_item->parent() == nullptr)
+ if (!Options::getInstance().stopMusicOnCategoryEnabled() && p_item->parent() == nullptr)
return;
column = 1; // Column 1 is always the metadata (which we want)
QString p_song = p_item->text(column);
@@ -5387,7 +5385,7 @@ void Courtroom::on_text_color_context_menu_requested(const QPoint &pos)
menu->addAction(QString("Open currently used chat_config.ini"), this,
[=] {
- QString p_path = ao_app->get_asset("chat_config.ini", ao_app->current_theme, ao_app->get_subtheme(), ao_app->default_theme, ao_app->get_chat(current_char));
+ QString p_path = ao_app->get_asset("chat_config.ini", Options::getInstance().theme(), Options::getInstance().subTheme(), ao_app->default_theme, ao_app->get_chat(current_char));
if (!file_exists(p_path)) {
return;
}
@@ -5577,8 +5575,6 @@ void Courtroom::on_change_character_clicked()
void Courtroom::on_reload_theme_clicked()
{
- ao_app->reload_theme();
-
set_courtroom_size();
set_widgets();
update_character(m_cid, ui_iniswap_dropdown->itemText(ui_iniswap_dropdown->currentIndex()));
@@ -5757,14 +5753,14 @@ void Courtroom::on_casing_clicked()
if (ui_casing->isChecked()) {
QStringList f_packet;
- f_packet.append(ao_app->get_casing_can_host_cases());
- f_packet.append(QString::number(ao_app->get_casing_cm_enabled()));
- f_packet.append(QString::number(ao_app->get_casing_defence_enabled()));
+ f_packet.append(Options::getInstance().casingCanHostCases());
+ f_packet.append(QString::number(Options::getInstance().casingCmEnabled()));
+ f_packet.append(QString::number(Options::getInstance().casingDefenceEnabled()));
f_packet.append(
- QString::number(ao_app->get_casing_prosecution_enabled()));
- f_packet.append(QString::number(ao_app->get_casing_judge_enabled()));
- f_packet.append(QString::number(ao_app->get_casing_juror_enabled()));
- f_packet.append(QString::number(ao_app->get_casing_steno_enabled()));
+ QString::number(Options::getInstance().casingProsecutionEnabled()));
+ f_packet.append(QString::number(Options::getInstance().casingJudgeEnabled()));
+ f_packet.append(QString::number(Options::getInstance().casingJurorEnabled()));
+ f_packet.append(QString::number(Options::getInstance().casingStenoEnabled()));
ao_app->send_server_packet(new AOPacket("SETCASE", f_packet));
}
diff --git a/src/emotes.cpp b/src/emotes.cpp
index 2a1d5066f..899ae4e94 100644
--- a/src/emotes.cpp
+++ b/src/emotes.cpp
@@ -1,6 +1,7 @@
#include "courtroom.h"
#include "aoemotebutton.h"
+#include "options.h"
void Courtroom::initialize_emotes()
{
@@ -200,7 +201,7 @@ void Courtroom::select_emote(int p_id)
if (old_emote == current_emote) {
ui_pre->setChecked(!ui_pre->isChecked());
}
- else if (!ao_app->is_stickypres_enabled()) {
+ else if (!Options::getInstance().clearPreOnPlayEnabled()) {
if (emote_mod == PREANIM || emote_mod == PREANIM_ZOOM) {
ui_pre->setChecked(true);
}
diff --git a/src/evidence.cpp b/src/evidence.cpp
index ab3a6a382..f8b25571c 100644
--- a/src/evidence.cpp
+++ b/src/evidence.cpp
@@ -1,4 +1,5 @@
#include "courtroom.h"
+#include "options.h"
void Courtroom::initialize_evidence()
{
@@ -416,7 +417,7 @@ void Courtroom::on_evidence_image_button_clicked()
return;
QString filename = filenames.at(0);
- QStringList bases = ao_app->get_mount_paths();
+ QStringList bases = Options::getInstance().mountPaths();
bases.prepend(ao_app->get_base_path());
for (const QString &base : bases) {
QDir baseDir(base);
@@ -453,7 +454,7 @@ void Courtroom::on_evidence_clicked(int p_id)
else if (f_real_id > local_evidence_list.size())
return;
- if (!ao_app->get_evidence_double_click()){
+ if (!Options::getInstance().evidenceDoubleClickEdit()){
on_evidence_double_clicked(p_id);
return;
}
@@ -487,7 +488,11 @@ void Courtroom::on_evidence_double_clicked(int p_id)
for (AOEvidenceButton *i_button : qAsConst(ui_evidence_list))
i_button->set_selected(false);
- ui_evidence_list.at(p_id)->set_selected(true);
+ // We have to check if the ID is on the currently displayed page.
+ // This is because SOMEONE allowed the switching of pages while evidence is still being edited.
+ if (p_id < ui_evidence_list.count()) {
+ ui_evidence_list.at(p_id)->set_selected(true);
+ }
current_evidence = f_real_id;
evi_type f_evi = local_evidence_list.at(f_real_id);
diff --git a/src/lobby.cpp b/src/lobby.cpp
index c4eecb4bf..29f8ecd82 100644
--- a/src/lobby.cpp
+++ b/src/lobby.cpp
@@ -113,8 +113,6 @@ Lobby::Lobby(AOApplication *p_ao_app) : QMainWindow()
// sets images, position and size
void Lobby::set_widgets()
{
- ao_app->reload_theme();
-
QString filename = "lobby_design.ini";
pos_size_type f_lobby = ao_app->get_element_dimensions("lobby", filename);
diff --git a/src/main.cpp b/src/main.cpp
index e8ffe67ec..9ec52f27c 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -24,8 +24,6 @@ int main(int argc, char *argv[])
while (it.hasNext())
fontDatabase.addApplicationFont(it.next());
- QSettings *configini = main_app.configini;
-
QPluginLoader apngPlugin("qapng");
if (!apngPlugin.load())
qCritical() << "QApng plugin could not be loaded";
@@ -35,7 +33,7 @@ int main(int argc, char *argv[])
qCritical() << "QWebp plugin could not be loaded";
QString p_language =
- configini->value("language", QLocale::system().name()).toString();
+ Options::getInstance().language();
if (p_language == " " || p_language == "")
p_language = QLocale::system().name();
diff --git a/src/networkmanager.cpp b/src/networkmanager.cpp
index 158b36b0a..e9abfe072 100644
--- a/src/networkmanager.cpp
+++ b/src/networkmanager.cpp
@@ -3,6 +3,7 @@
#include "datatypes.h"
#include "debug_functions.h"
#include "lobby.h"
+#include "options.h"
#include
#include
@@ -17,7 +18,7 @@ NetworkManager::NetworkManager(AOApplication *parent) : QObject(parent)
heartbeat_timer = new QTimer(this);
QString master_config =
- ao_app->configini->value("master", "").value();
+ Options::getInstance().alternativeMasterserver();
if (!master_config.isEmpty() && QUrl(master_config).scheme().startsWith("http")) {
qInfo() << "using alternate master server" << master_config;
ms_baseurl = master_config;
@@ -81,7 +82,7 @@ void NetworkManager::send_heartbeat()
// within a 5 minute window, so that the the number of people playing within
// that time period can be counted and an accurate player count be displayed.
// What do I care about your personal information, I really don't want it.
- if (ao_app->get_player_count_optout())
+ if (Options::getInstance().playerCountOptout())
return;
QNetworkRequest req(QUrl(ms_baseurl + "/playing"));
@@ -105,7 +106,7 @@ void NetworkManager::request_document(MSDocumentType document_type,
req.setRawHeader("User-Agent", get_user_agent().toUtf8());
QString language =
- ao_app->configini->value("language").toString();
+ Options::getInstance().language();
if (language.trimmed().isEmpty())
language = QLocale::system().name();
diff --git a/src/options.cpp b/src/options.cpp
new file mode 100644
index 000000000..7efaf9f6a
--- /dev/null
+++ b/src/options.cpp
@@ -0,0 +1,620 @@
+#include "options.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+void Options::migrateCallwords()
+{
+ // Bla bla, evil boilerplate.
+ QStringList l_callwords;
+
+ QFile l_file;
+ l_file.setFileName(QCoreApplication::applicationDirPath() +
+ "/base/callwords.ini");
+
+ if (!l_file.open(QIODevice::ReadOnly)) {
+ qWarning() << "Unable to migrate callwords : File not open.";
+ }
+
+ QTextStream in(&l_file);
+ in.setCodec("UTF-8");
+
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ l_callwords.append(line);
+ }
+ l_file.close();
+ l_file.remove();
+
+ setCallwords(l_callwords);
+}
+
+Options::Options()
+ : config(QCoreApplication::applicationDirPath() + "/base/config.ini",
+ QSettings::IniFormat)
+{
+ config.setIniCodec("UTF-8");
+ migrate();
+}
+
+/*! Migrate old configuration keys/values to a relevant format. */
+void Options::migrate()
+{
+ if (config.contains("show_custom_shownames")) {
+ config.remove("show_custom_shownames");
+ }
+ if (QFile::exists(QCoreApplication::applicationDirPath() +
+ "/base/callwords.ini")) {
+ migrateCallwords();
+ }
+ if (config.contains("ooc_name")) {
+ if (username().isEmpty()) {
+ config.setValue("default_username", config.value("ooc_name"));
+ }
+ config.remove("ooc_name");
+ }
+}
+
+QString Options::theme() const
+{
+ return config.value("theme", "default").toString();
+}
+
+void Options::setTheme(QString value) { config.setValue("theme", value); }
+
+int Options::blipRate() const { return config.value("blip_rate", 2).toInt(); }
+
+void Options::setBlipRate(int value) { config.setValue("blip_rate", value); }
+
+int Options::musicVolume() const
+{
+ return config.value("default_music", 50).toInt();
+}
+
+void Options::setMusicVolume(int value)
+{
+ config.setValue("default_music", value);
+}
+
+int Options::sfxVolume() const
+{
+ return config.value("default_sfx", 50).toInt();
+}
+
+void Options::setSfxVolume(int value) { config.setValue("default_sfx", value); }
+
+int Options::blipVolume() const
+{
+ return config.value("default_blip", 50).toInt();
+}
+
+void Options::setBlipVolume(int value)
+{
+ config.setValue("default_blip", value);
+}
+
+int Options::defaultSuppressAudio() const
+{
+ return config.value("suppress_audio", 50).toInt();
+}
+
+void Options::setDefaultSupressedAudio(int value)
+{
+ config.setValue("suppress_audio", value);
+}
+
+int Options::maxLogSize() const
+{
+ return config.value("log_maximum", 200).toInt();
+}
+
+void Options::setMaxLogSize(int value)
+{
+ config.setValue("log_maximum", value);
+}
+
+int Options::textStayTime() const
+{
+ return config.value("stay_time", 200).toInt();
+}
+
+void Options::setTextStayTime(int value)
+{
+ config.setValue("stay_time", value);
+}
+
+int Options::textCrawlSpeed() const
+{
+ return config.value("text_crawl", 40).toInt();
+}
+
+void Options::setTextCrawlSpeed(int value)
+{
+ config.setValue("text_crawl", value);
+}
+
+int Options::chatRateLimit() const
+{
+ return config.value("chat_ratelimit", 300).toInt();
+}
+
+void Options::setChatRateLimit(int value)
+{
+ config.setValue("chat_ratelimit", value);
+}
+
+bool Options::logDirectionDownwards() const
+{
+ return config.value("log_goes_downwards", true).toBool();
+}
+
+void Options::setLogDirectionDownwards(bool value)
+{
+ config.setValue("log_goes_downwards", value);
+}
+
+bool Options::logNewline() const
+{
+ return config.value("log_newline", false).toBool();
+}
+
+void Options::setLogNewline(bool value)
+{
+ config.setValue("log_newline", value);
+}
+
+int Options::logMargin() const { return config.value("log_margin", 0).toInt(); }
+
+void Options::setLogMargin(int value) { config.setValue("log_margin", value); }
+
+bool Options::logTimestampEnabled() const
+{
+ return config.value("log_timestamp", false).toBool();
+}
+
+void Options::setLogTimestampEnabled(bool value)
+{
+ config.setValue("log_timestamp", value);
+}
+
+QString Options::logTimestampFormat() const
+{
+ return config.value("log_timestamp_format", "h:mm:ss AP").toString();
+}
+
+void Options::setLogTimestampFormat(QString value)
+{
+ config.setValue("log_timestamp_format", value);
+}
+
+bool Options::logIcActions() const
+{
+ return config.value("log_ic_actions", true).toBool();
+}
+
+void Options::setLogIcActions(bool value)
+{
+ config.setValue("log_ic_actions", value);
+}
+
+bool Options::customShownameEnabled() const
+{
+ return config.value("show_custom_shownames", true).toBool();
+}
+
+void Options::setCustomShownameEnabled(bool value)
+{
+ config.setValue("show_custom_shownames", value);
+}
+
+QString Options::username() const
+{
+ return config.value("default_username", "").value();
+}
+
+void Options::setUsername(QString value)
+{
+ config.setValue("default_username", value);
+}
+
+QString Options::shownameOnJoin() const
+{
+ return config.value("default_showname", "").toString();
+}
+
+void Options::setShownameOnJoin(QString value)
+{
+ config.setValue("default_showname", value);
+}
+
+QString Options::audioOutputDevice() const
+{
+ return config.value("default_audio_device", "default").toString();
+}
+
+void Options::setAudioOutputDevice(QString value)
+{
+ config.setValue("default_audio_device", value);
+}
+
+bool Options::blankBlip() const
+{
+ return config.value("blank_blip", false).toBool();
+}
+
+void Options::setBlankBlip(bool value) { config.setValue("blank_blip", value); }
+
+bool Options::loopingSfx() const
+{
+ return config.value("looping_sfx", true).toBool();
+}
+
+void Options::setLoopingSfx(bool value)
+{
+ config.setValue("looping_sfx", value);
+}
+
+bool Options::objectionStopMusic() const
+{
+ return config.value("objection_stop_music", false).toBool();
+}
+
+void Options::setObjectionStopMusic(bool value)
+{
+ config.setValue("objection_stop_music", value);
+}
+
+bool Options::streamingEnabled() const
+{
+ return config.value("streaming_enabled", true).toBool();
+}
+
+void Options::setStreamingEnabled(bool value)
+{
+ config.setValue("streaming_enabled", value);
+}
+
+bool Options::objectionSkipQueueEnabled() const
+{
+ return config.value("instant_objection", true).toBool();
+}
+
+void Options::setObjectionSkipQueueEnabled(bool value)
+{
+ config.setValue("instant_objection", value);
+}
+
+bool Options::desynchronisedLogsEnabled() const
+{
+ return config.value("desync_logs", false).toBool();
+}
+
+void Options::setDesynchronisedLogsEnabled(bool value)
+{
+ config.setValue("desync_logs", value);
+}
+
+bool Options::discordEnabled() const
+{
+ return config.value("discord", true).toBool();
+}
+
+void Options::setDiscordEnabled(bool value)
+{
+ config.setValue("discord", value);
+}
+
+bool Options::shakeEnabled() const
+{
+ return config.value("shake", true).toBool();
+}
+
+void Options::setShakeEnabled(bool value) { config.setValue("shake", value); }
+
+bool Options::effectsEnabled() const
+{
+ return config.value("effects", true).toBool();
+}
+
+void Options::setEffectsEnabled(bool value)
+{
+ config.setValue("effects", value);
+}
+
+bool Options::networkedFrameSfxEnabled() const
+{
+ return config.value("framenetwork", true).toBool();
+}
+
+void Options::setNetworkedFrameSfxEnabled(bool value)
+{
+ config.setValue("framenetwork", value);
+}
+
+bool Options::colorLogEnabled() const
+{
+ return config.value("colorlog", true).toBool();
+}
+
+void Options::setColorLogEnabled(bool value)
+{
+ config.setValue("colorlog", value);
+}
+
+bool Options::clearSoundsDropdownOnPlayEnabled() const
+{
+ return config.value("stickysounds", true).toBool();
+}
+
+void Options::setClearSoundsDropdownOnPlayEnabled(bool value)
+{
+ config.setValue("stickysounds", value);
+}
+
+bool Options::clearEffectsDropdownOnPlayEnabled() const
+{
+ return config.value("stickyeffects", true).toBool();
+}
+
+void Options::setClearEffectsDropdownOnPlayEnabled(bool value)
+{
+ config.setValue("stickyeffects", value);
+}
+
+bool Options::clearPreOnPlayEnabled() const
+{
+ return config.value("stickypres", true).toBool();
+}
+
+void Options::setClearPreOnPlayEnabled(bool value)
+{
+ config.setValue("stickypres", value);
+}
+
+bool Options::customChatboxEnabled() const
+{
+ return config.value("customchat", true).toBool();
+}
+
+void Options::setCustomChatboxEnabled(bool value)
+{
+ config.setValue("customchat", value);
+}
+
+bool Options::characterStickerEnabled() const
+{
+ return config.value("sticker", true).toBool();
+}
+
+void Options::setCharacterStickerEnabled(bool value)
+{
+ config.setValue("sticker", value);
+}
+
+bool Options::continuousPlaybackEnabled() const
+{
+ return config.value("continuous_playback", true).toBool();
+}
+
+void Options::setContinuousPlaybackEnabled(bool value)
+{
+ config.setValue("continuous_playback", value);
+}
+
+bool Options::stopMusicOnCategoryEnabled() const
+{
+ return config.value("category_stop", true).toBool();
+}
+
+void Options::setStopMusicOnCategoryEnabled(bool value)
+{
+ config.setValue("category_stop", value);
+}
+
+bool Options::casingAlertEnabled() const
+{
+ return config.value("casing_enabled", false).toBool();
+}
+
+void Options::setCasingAlertEnabled(bool value)
+{
+ config.setValue("casing_enabled", value);
+}
+
+bool Options::casingDefenceEnabled() const
+{
+ return config.value("casing_defence_enabled", false).toBool();
+}
+
+void Options::setcasingDefenceEnabled(bool value)
+{
+ config.setValue("casing_defence_enabled", value);
+}
+
+bool Options::casingProsecutionEnabled() const
+{
+ return config.value("casing_prosecution_enabled", false).toBool();
+}
+
+void Options::setCasingProseuctionEnabled(bool value)
+{
+ config.setValue("casing_prosecution_enabled", value);
+}
+
+bool Options::casingJudgeEnabled() const
+{
+ return config.value("casing_judge_enabled", false).toBool();
+}
+
+void Options::setCasingJudgeEnabled(bool value)
+{
+ config.setValue("casing_judge_enabled", value);
+}
+
+bool Options::casingJurorEnabled() const
+{
+ return config.value("casing_juror_enabled", false).toBool();
+}
+
+void Options::setCasingJurorEnabled(bool value)
+{
+ config.setValue("casing_juror_enabled", value);
+}
+
+bool Options::casingStenoEnabled() const
+{
+ return config.value("casing_steno_enabled", false).toBool();
+}
+
+void Options::setCasingStenoEnabled(bool value)
+{
+ config.setValue("casing_steno_enabled", value);
+}
+
+bool Options::casingCmEnabled() const
+{
+ return config.value("casing_cm_enabled", false).toBool();
+}
+
+void Options::setCasingCmEnabled(bool value)
+{
+ config.setValue("casing_cm_enabled", value);
+}
+
+QString Options::casingCanHostCases() const
+{
+ return config.value("casing_can_host_cases", "Turnabout Check Your Settings")
+ .toString();
+}
+
+void Options::setCasingCanHostCases(QString value)
+{
+ config.setValue("casing_can_host_cases", value);
+}
+
+bool Options::logToTextFileEnabled() const
+{
+ return config.value("automatic_logging_enabled", true).toBool();
+}
+
+void Options::setLogToTextFileEnabled(bool value)
+{
+ config.setValue("automatic_logging_enabled", value);
+}
+
+bool Options::logToDemoFileEnabled() const
+{
+ return config.value("demo_logging_enabled", true).toBool();
+}
+
+void Options::setLogToDemoFileEnabled(bool value)
+{
+ config.setValue("demo_logging_enabled", value);
+}
+
+QString Options::subTheme() const
+{
+ return config.value("subtheme", "server").toString();
+}
+
+void Options::setSubTheme(QString value) { config.setValue("subtheme", value); }
+
+bool Options::animatedThemeEnabled() const
+{
+ return config.value("animated_theme", true).toBool();
+}
+
+void Options::setAnimatedThemeEnabled(bool value)
+{
+ config.setValue("animated_theme", value);
+}
+
+QString Options::defaultScalingMode() const
+{
+ return config.value("default_scaling", "fast").toString();
+}
+
+void Options::setDefaultScalingMode(QString value)
+{
+ config.setValue("default_scaling", value);
+}
+
+QStringList Options::mountPaths() const
+{
+ return config.value("mount_paths").value();
+}
+
+void Options::setMountPaths(QStringList value)
+{
+ config.setValue("mount_paths", value);
+}
+
+bool Options::playerCountOptout() const
+{
+ return config.value("player_count_optout", false).toBool();
+}
+
+void Options::setPlayerCountOptout(bool value)
+{
+ config.setValue("player_count_optout", value);
+}
+
+bool Options::playSelectedSFXOnIdle() const
+{
+ return config.value("sfx_on_idle", false).toBool();
+}
+
+void Options::setPlaySelectedSFXOnIdle(bool value)
+{
+ config.setValue("sfx_on_idle", value);
+}
+
+bool Options::evidenceDoubleClickEdit() const
+{
+ return config.value("evidence_double_click", true).toBool();
+}
+
+void Options::setEvidenceDoubleClickEdit(bool value)
+{
+ config.setValue("evidence_double_click", value);
+}
+
+QString Options::alternativeMasterserver() const
+{
+ return config.value("master", "").toString();
+}
+
+void Options::setAlternativeMasterserver(QString value)
+{
+ config.setValue("master", value);
+}
+
+QString Options::language() const
+{
+ return config.value("language", QLocale::system().name()).toString();
+}
+
+void Options::setLanguage(QString value) { config.setValue("language", value); }
+
+QStringList Options::callwords() const
+{
+ QStringList l_callwords =
+ config.value("callwords", QStringList{}).toStringList();
+
+ // Please someone explain to me how tf I am supposed to create an empty
+ // QStringList using QSetting defaults.
+ if (l_callwords.size() == 1 && l_callwords.at(0).isEmpty())
+ l_callwords.clear();
+ return l_callwords;
+}
+
+void Options::setCallwords(QStringList value)
+{
+ config.setValue("callwords", value);
+}
+
+void Options::clearConfig() { config.clear(); }
diff --git a/src/packet_distribution.cpp b/src/packet_distribution.cpp
index 4784faf58..c325928df 100644
--- a/src/packet_distribution.cpp
+++ b/src/packet_distribution.cpp
@@ -5,10 +5,11 @@
#include "hardware_functions.h"
#include "lobby.h"
#include "networkmanager.h"
+#include "options.h"
void AOApplication::append_to_demofile(QString packet_string)
{
- if (get_demo_logging_enabled() && !log_filename.isEmpty())
+ if (Options::getInstance().logToDemoFileEnabled() && !log_filename.isEmpty())
{
QString path = log_filename.left(log_filename.size()).replace(".log", ".demo");
if (!demo_timer.isValid())
@@ -214,7 +215,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
// Remove any characters not accepted in folder names for the server_name
// here
- if (AOApplication::get_demo_logging_enabled() && server_name != "Demo playback") {
+ if (Options::getInstance().logToDemoFileEnabled() && server_name != "Demo playback") {
this->log_filename = QDateTime::currentDateTime().toUTC().toString(
"'logs/" + server_name.remove(QRegExp("[\\\\/:*?\"<>|\']")) +
"/'yyyy-MM-dd hh-mm-ss t'.log'");
@@ -228,7 +229,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
QCryptographicHash hash(QCryptographicHash::Algorithm::Sha256);
hash.addData(server_address.toUtf8());
- if (is_discord_enabled())
+ if (Options::getInstance().discordEnabled())
discord->state_server(server_name.toStdString(),
hash.result().toBase64().toStdString());
log_to_demo = false;
@@ -601,7 +602,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
subtheme = f_contents.at(0);
// Check if we have subthemes set to "server"
- QString p_st = configini->value("subtheme").value();
+ QString p_st = Options::getInstance().subTheme();
if (p_st.toLower() != "server")
// We don't. Simply acknowledge the subtheme sent by the server, but don't do anything else.
return;
diff --git a/src/path_functions.cpp b/src/path_functions.cpp
index 45920d50b..6144ec897 100644
--- a/src/path_functions.cpp
+++ b/src/path_functions.cpp
@@ -1,6 +1,7 @@
#include "aoapplication.h"
#include "courtroom.h"
#include "file_functions.h"
+#include "options.h"
#include
#include
@@ -45,14 +46,13 @@ QString AOApplication::get_base_path()
#else
base_path = applicationDirPath() + "/base/";
#endif
-
return base_path;
}
VPath AOApplication::get_theme_path(QString p_file, QString p_theme)
{
if (p_theme == "")
- p_theme = current_theme;
+ p_theme = Options::getInstance().theme();
return VPath("themes/" + p_theme + "/" + p_file);
}
@@ -280,9 +280,9 @@ QString AOApplication::get_sfx(QString p_sfx, QString p_misc, QString p_characte
{
QVector pathlist;
// Sounds subfolder is prioritized for organization sake
- pathlist += get_asset_paths("sounds/" + p_sfx, current_theme, get_subtheme(), default_theme, p_misc, p_character);
+ pathlist += get_asset_paths("sounds/" + p_sfx, Options::getInstance().theme(), Options::getInstance().subTheme(), default_theme, p_misc, p_character);
// If sound subfolder not found, search just for SFX
- pathlist += get_asset_paths(p_sfx, current_theme, get_subtheme(), default_theme, p_misc, p_character);
+ pathlist += get_asset_paths(p_sfx, Options::getInstance().theme(), Options::getInstance().subTheme(), default_theme, p_misc, p_character);
// If SFX not found, search base/sounds/general/ folder
pathlist += get_sounds_path(p_sfx);
QString ret = get_sfx_path(pathlist);
@@ -346,7 +346,7 @@ QString AOApplication::get_real_path(const VPath &vpath,
}
// Cache miss; try all known mount paths
- QStringList bases = get_mount_paths();
+ QStringList bases = Options::getInstance().mountPaths();
bases.prepend(get_base_path());
// base
// content 1
diff --git a/src/text_file_functions.cpp b/src/text_file_functions.cpp
index d9c816206..543fa6173 100644
--- a/src/text_file_functions.cpp
+++ b/src/text_file_functions.cpp
@@ -1,147 +1,6 @@
#include "text_file_functions.h"
#include "aoutils.h"
-
-QString AOApplication::read_theme()
-{
- QString result = configini->value("theme", "default").value();
- return result;
-}
-
-int AOApplication::read_blip_rate()
-{
- int result = configini->value("blip_rate", 2).toInt();
-
- if (result < 0)
- return 0;
-
- return result;
-}
-
-QString AOApplication::get_ooc_name()
-{
- QString result = configini->value("ooc_name").value();
- return result;
-}
-
-int AOApplication::get_default_music()
-{
- int result = configini->value("default_music", 50).toInt();
- return result;
-}
-
-int AOApplication::get_default_sfx()
-{
- int result = configini->value("default_sfx", 50).toInt();
- return result;
-}
-
-int AOApplication::get_default_blip()
-{
- int result = configini->value("default_blip", 50).toInt();
- return result;
-}
-
-int AOApplication::get_default_suppress_audio()
-{
- int result = configini->value("suppress_audio", 50).toInt();
- return result;
-}
-
-int AOApplication::get_max_log_size()
-{
- int result = configini->value("log_maximum", 200).toInt();
- return result;
-}
-
-int AOApplication::stay_time()
-{
- int result = configini->value("stay_time", 200).toInt();
- return result;
-}
-
-int AOApplication::get_text_crawl()
-{
- int result = configini->value("text_crawl", 40).toInt();
- return result;
-}
-
-int AOApplication::get_chat_ratelimit()
-{
- int result = configini->value("chat_ratelimit", 300).toInt();
- return result;
-}
-
-bool AOApplication::get_log_goes_downwards()
-{
- QString result =
- configini->value("log_goes_downwards", "true").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_log_newline()
-{
- QString result = configini->value("log_newline", "false").value();
- return result.startsWith("true");
-}
-
-int AOApplication::get_log_margin()
-{
- int result = configini->value("log_margin", 0).toInt();
- return result;
-}
-
-bool AOApplication::get_log_timestamp()
-{
- QString result = configini->value("log_timestamp", "false").value();
- return result.startsWith("true");
-}
-
-QString AOApplication::get_log_timestamp_format()
-{
- QString result = configini->value("log_timestamp_format", "h:mm:ss AP").value();
- return result;
-}
-
-bool AOApplication::get_log_ic_actions()
-{
- QString result =
- configini->value("log_ic_actions", "true").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_showname_enabled_by_default()
-{
- QString result =
- configini->value("show_custom_shownames", "true").value();
- return result.startsWith("true");
-}
-
-QString AOApplication::get_default_username()
-{
- QString result = configini->value("default_username", "").value();
- if (result.isEmpty())
- return get_ooc_name();
- else
- return result;
-}
-
-QString AOApplication::get_default_showname()
-{
- QString result = configini->value("default_showname", "").value();
- return result;
-}
-
-QString AOApplication::get_audio_output_device()
-{
- QString result =
- configini->value("default_audio_device", "default").value();
- return result;
-}
-
-QStringList AOApplication::get_call_words()
-{
- return get_list_file(get_base_path() + "callwords.ini");
-}
+#include "options.h"
QStringList AOApplication::get_list_file(VPath path)
{
@@ -360,7 +219,7 @@ QString AOApplication::read_design_ini(QString p_identifier,
Qt::TransformationMode AOApplication::get_scaling(QString p_scaling)
{
if (p_scaling.isEmpty())
- p_scaling = get_default_scaling();
+ p_scaling = Options::getInstance().defaultScalingMode();
if (p_scaling == "smooth")
return Qt::SmoothTransformation;
@@ -369,7 +228,7 @@ Qt::TransformationMode AOApplication::get_scaling(QString p_scaling)
QPoint AOApplication::get_button_spacing(QString p_identifier, QString p_file)
{
- QString value = get_config_value(p_identifier, p_file, current_theme, get_subtheme(), default_theme);
+ QString value = get_config_value(p_identifier, p_file, Options::getInstance().theme(), Options::getInstance().subTheme(), default_theme);
QPoint return_value;
return_value.setX(0);
@@ -415,7 +274,7 @@ pos_size_type AOApplication::get_element_dimensions(QString p_identifier,
QString AOApplication::get_design_element(QString p_identifier, QString p_file,
QString p_misc)
{
- QString value = get_config_value(p_identifier, p_file, current_theme, get_subtheme(), default_theme, p_misc);
+ QString value = get_config_value(p_identifier, p_file, Options::getInstance().theme(), Options::getInstance().subTheme(), default_theme, p_misc);
if (!value.isEmpty())
return value;
return "";
@@ -424,7 +283,7 @@ QString AOApplication::get_design_element(QString p_identifier, QString p_file,
// tfw this function is only used for lobby and nowhere else
int AOApplication::get_font_size(QString p_identifier, QString p_file)
{
- QString value = get_config_value(p_identifier, p_file, current_theme, get_subtheme(), default_theme);
+ QString value = get_config_value(p_identifier, p_file, Options::getInstance().theme(), Options::getInstance().subTheme(), default_theme);
if (!value.isEmpty())
return value.toInt();
return 10;
@@ -432,7 +291,7 @@ int AOApplication::get_font_size(QString p_identifier, QString p_file)
QColor AOApplication::get_color(QString p_identifier, QString p_file)
{
- QString value = get_config_value(p_identifier, p_file, current_theme, get_subtheme(), default_theme);
+ QString value = get_config_value(p_identifier, p_file, Options::getInstance().theme(), Options::getInstance().subTheme(), default_theme);
QColor return_color(0, 0, 0);
if (value.isEmpty())
@@ -452,7 +311,7 @@ QColor AOApplication::get_color(QString p_identifier, QString p_file)
QString AOApplication::get_stylesheet(QString p_file)
{
- QString path = get_asset(p_file, current_theme, get_subtheme(), default_theme);
+ QString path = get_asset(p_file, Options::getInstance().theme(), Options::getInstance().subTheme(), default_theme);
QFile design_ini;
design_ini.setFileName(path);
if (!design_ini.open(QIODevice::ReadOnly))
@@ -472,7 +331,7 @@ QString AOApplication::get_stylesheet(QString p_file)
QString AOApplication::get_tagged_stylesheet(QString target_tag, QString p_file)
{
- QString path = get_asset(p_file, current_theme, get_subtheme(), default_theme);
+ QString path = get_asset(p_file, Options::getInstance().theme(), Options::getInstance().subTheme(), default_theme);
QFile design_ini;
design_ini.setFileName(path);
if (!design_ini.open(QIODevice::ReadOnly))
@@ -506,7 +365,7 @@ QString AOApplication::get_tagged_stylesheet(QString target_tag, QString p_file)
QString AOApplication::get_chat_markup(QString p_identifier, QString p_chat)
{
// New Chadly method
- QString value = get_config_value(p_identifier, "chat_config.ini", current_theme, get_subtheme(), default_theme, p_chat);
+ QString value = get_config_value(p_identifier, "chat_config.ini", Options::getInstance().theme(), Options::getInstance().subTheme(), default_theme, p_chat);
if (!value.isEmpty())
return value.toUtf8();
@@ -549,14 +408,14 @@ QColor AOApplication::get_chat_color(QString p_identifier, QString p_chat)
QString AOApplication::get_penalty_value(QString p_identifier)
{
- return get_config_value(p_identifier, "penalty/penalty.ini", current_theme,
- get_subtheme(), default_theme, "");
+ return get_config_value(p_identifier, "penalty/penalty.ini", Options::getInstance().theme(),
+ Options::getInstance().subTheme(), default_theme, "");
}
QString AOApplication::get_court_sfx(QString p_identifier, QString p_misc)
{
- QString value = get_config_value(p_identifier, "courtroom_sounds.ini", current_theme, get_subtheme(), default_theme, p_misc);
+ QString value = get_config_value(p_identifier, "courtroom_sounds.ini", Options::getInstance().theme(), Options::getInstance().subTheme(), default_theme, p_misc);
if (!value.isEmpty())
return value.toUtf8();
return "";
@@ -913,8 +772,8 @@ int AOApplication::get_text_delay(QString p_char, QString p_emote)
QStringList AOApplication::get_effects(QString p_char)
{
const QStringList l_filepath_list{
- get_asset("effects/effects.ini", current_theme, get_subtheme(), default_theme, ""),
- get_asset("effects.ini", current_theme, get_subtheme(), default_theme, read_char_ini(p_char, "effects", "Options")),
+ get_asset("effects/effects.ini", Options::getInstance().theme(), Options::getInstance().subTheme(), default_theme, ""),
+ get_asset("effects.ini", Options::getInstance().theme(), Options::getInstance().subTheme(), default_theme, read_char_ini(p_char, "effects", "Options")),
};
QStringList l_effect_name_list;
@@ -982,8 +841,8 @@ QString AOApplication::get_effect(QString effect, QString p_char,
p_folder = read_char_ini(p_char, "effects", "Options");
QStringList paths {
- get_image("effects/" + effect, current_theme, get_subtheme(), default_theme, ""),
- get_image(effect, current_theme, get_subtheme(), default_theme, p_folder)
+ get_image("effects/" + effect, Options::getInstance().theme(), Options::getInstance().subTheme(), default_theme, ""),
+ get_image(effect, Options::getInstance().theme(), Options::getInstance().subTheme(), default_theme, p_folder)
};
for (const auto &p : paths)
@@ -998,8 +857,8 @@ QString AOApplication::get_effect_property(QString fx_name, QString p_char,
if (p_folder == "")
p_folder = read_char_ini(p_char, "effects", "Options");
- const auto paths = get_asset_paths("effects/effects.ini", current_theme, get_subtheme(), default_theme, "");
- const auto misc_paths = get_asset_paths("effects.ini", current_theme, get_subtheme(), default_theme, p_folder);
+ const auto paths = get_asset_paths("effects/effects.ini", Options::getInstance().theme(), Options::getInstance().subTheme(), default_theme, "");
+ const auto misc_paths = get_asset_paths("effects.ini", Options::getInstance().theme(), Options::getInstance().subTheme(), default_theme, p_folder);
QString path;
QString f_result;
for (const VPath &p : paths + misc_paths) {
@@ -1042,230 +901,3 @@ bool AOApplication::get_pos_is_judge(const QString &p_pos)
}
return positions.contains(p_pos.trimmed());
}
-
-bool AOApplication::get_blank_blip()
-{
- QString result = configini->value("blank_blip", "false").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_looping_sfx()
-{
- QString result = configini->value("looping_sfx", "true").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::objection_stop_music()
-{
- QString result =
- configini->value("objection_stop_music", "false").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_streaming_disabled()
-{
- return configini->value("streaming_disabled", false).toBool();
-}
-
-bool AOApplication::is_instant_objection_enabled()
-{
- QString result = configini->value("instant_objection", "true").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_desyncrhonized_logs_enabled()
-{
- QString result = configini->value("desync_logs", "false").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_discord_enabled()
-{
- QString result = configini->value("discord", "true").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_shake_enabled()
-{
- QString result = configini->value("shake", "true").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_effects_enabled()
-{
- QString result = configini->value("effects", "true").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_frame_network_enabled()
-{
- QString result = configini->value("framenetwork", "true").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_colorlog_enabled()
-{
- QString result = configini->value("colorlog", "true").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_stickysounds_enabled()
-{
- QString result = configini->value("stickysounds", "false").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_stickyeffects_enabled()
-{
- QString result = configini->value("stickyeffects", "false").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_stickypres_enabled()
-{
- QString result = configini->value("stickypres", "false").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_customchat_enabled()
-{
- QString result = configini->value("customchat", "true").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_sticker_enabled()
-{
- QString result = configini->value("sticker", "true").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_continuous_enabled()
-{
- QString result = configini->value("continuous_playback", "true").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_category_stop_enabled()
-{
- QString result = configini->value("category_stop", "true").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_casing_enabled()
-{
- QString result = configini->value("casing_enabled", "false").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_casing_defence_enabled()
-{
- QString result =
- configini->value("casing_defence_enabled", "false").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_casing_prosecution_enabled()
-{
- QString result =
- configini->value("casing_prosecution_enabled", "false").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_casing_judge_enabled()
-{
- QString result =
- configini->value("casing_judge_enabled", "false").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_casing_juror_enabled()
-{
- QString result =
- configini->value("casing_juror_enabled", "false").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_casing_steno_enabled()
-{
- QString result =
- configini->value("casing_steno_enabled", "false").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_casing_cm_enabled()
-{
- QString result =
- configini->value("casing_cm_enabled", "false").value();
- return result.startsWith("true");
-}
-
-QString AOApplication::get_casing_can_host_cases()
-{
- QString result =
- configini->value("casing_can_host_cases", "Turnabout Check Your Settings")
- .value();
- return result;
-}
-
-bool AOApplication::get_text_logging_enabled()
-{
- QString result =
- configini->value("automatic_logging_enabled", "true").value();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_demo_logging_enabled()
-{
- QString result =
- configini->value("demo_logging_enabled", "true").value();
- return result.startsWith("true");
-}
-
-QString AOApplication::get_subtheme()
-{
- QString result =
- configini->value("subtheme", "server").value();
- // Server means we want the server to decide for us
- if (result == "server")
- // 'subtheme' variable is affected by the server
- result = subtheme;
- // Default means we don't want any subthemes
- else if (result == "default")
- result = "";
- return result;
-}
-
-bool AOApplication::get_animated_theme()
-{
- QString result =
- configini->value("animated_theme", "true").value();
- return result.startsWith("true");
-}
-
-QString AOApplication::get_default_scaling()
-{
- return configini->value("default_scaling", "fast").value();
-}
-
-QStringList AOApplication::get_mount_paths()
-{
- return configini->value("mount_paths").value();
-}
-
-bool AOApplication::get_player_count_optout()
-{
- return configini->value("player_count_optout", "false").value()
- .startsWith("true");
-}
-
-bool AOApplication::get_sfx_on_idle()
-{
- return configini->value("sfx_on_idle", "false").value()
- .startsWith("true");
-}
-
-bool AOApplication::get_evidence_double_click()
-{
- return configini->value("evidence_double_click", "true").value()
- .startsWith("true");
-}
diff --git a/src/widgets/aooptionsdialog.cpp b/src/widgets/aooptionsdialog.cpp
new file mode 100644
index 000000000..e9fbcaf39
--- /dev/null
+++ b/src/widgets/aooptionsdialog.cpp
@@ -0,0 +1,651 @@
+#include "widgets/aooptionsdialog.h"
+#include "aoapplication.h"
+#include "bass.h"
+#include "file_functions.h"
+#include "QDesktopServices"
+#include "networkmanager.h"
+#include "options.h"
+
+#include
+
+#define FROM_UI(type, name) \
+ ; \
+ ui_##name = findChild(#name);
+
+AOOptionsDialog::AOOptionsDialog(QDialog *parent, AOApplication *p_ao_app)
+ : QDialog(parent)
+{
+ ao_app = p_ao_app;
+
+ QUiLoader l_loader(this);
+ QFile l_uiFile(":/resource/ui/options_dialog.ui");
+ if (!l_uiFile.open(QFile::ReadOnly)) {
+ qWarning() << "Unable to open file " << l_uiFile.fileName();
+ return;
+ }
+
+ ui_settings_widget = l_loader.load(&l_uiFile, this);
+
+ auto l_layout = new QVBoxLayout(this);
+ l_layout->addWidget(ui_settings_widget);
+
+ // General dialog element.
+ FROM_UI(QDialogButtonBox, settings_buttons);
+
+ connect(ui_settings_buttons, &QDialogButtonBox::accepted, this,
+ &AOOptionsDialog::savePressed);
+ connect(ui_settings_buttons, &QDialogButtonBox::rejected, this,
+ &AOOptionsDialog::discardPressed);
+ connect(ui_settings_buttons, &QDialogButtonBox::clicked, this,
+ &AOOptionsDialog::buttonClicked);
+
+ // Gameplay Tab
+ FROM_UI(QComboBox, theme_combobox)
+ registerOption("theme_combobox", &Options::theme,
+ &Options::setTheme);
+
+ FROM_UI(QComboBox, subtheme_combobox)
+ connect(ui_theme_combobox,
+ QOverload::of(&QComboBox::currentIndexChanged), this,
+ &AOOptionsDialog::themeChanged);
+ registerOption("subtheme_combobox", &Options::subTheme,
+ &Options::setSubTheme);
+
+ FROM_UI(QPushButton, theme_reload_button)
+ connect(ui_theme_reload_button, &QPushButton::clicked, this,
+ &::AOOptionsDialog::onReloadThemeClicked);
+
+ FROM_UI(QPushButton, theme_folder_button)
+ connect(ui_theme_folder_button, &QPushButton::clicked, this, [=] {
+ QString p_path = ao_app->get_real_path(ao_app->get_theme_path(
+ "", ui_theme_combobox->itemText(ui_theme_combobox->currentIndex())));
+ if (!dir_exists(p_path)) {
+ return;
+ }
+ QDesktopServices::openUrl(QUrl::fromLocalFile(p_path));
+ });
+
+ FROM_UI(QCheckBox, animated_theme_cb)
+ FROM_UI(QSpinBox, stay_time_spinbox)
+ FROM_UI(QCheckBox, instant_objection_cb)
+ FROM_UI(QSpinBox, text_crawl_spinbox)
+ FROM_UI(QSpinBox, chat_ratelimit_spinbox)
+ FROM_UI(QLineEdit, username_textbox)
+ FROM_UI(QCheckBox, showname_cb)
+ FROM_UI(QLineEdit, default_showname_textbox)
+ FROM_UI(QLineEdit, ms_textbox)
+ FROM_UI(QCheckBox, discord_cb)
+ FROM_UI(QComboBox, language_combobox)
+ FROM_UI(QComboBox, scaling_combobox)
+ FROM_UI(QCheckBox, shake_cb)
+ FROM_UI(QCheckBox, effects_cb)
+ FROM_UI(QCheckBox, framenetwork_cb)
+ FROM_UI(QCheckBox, colorlog_cb)
+ FROM_UI(QCheckBox, stickysounds_cb)
+ FROM_UI(QCheckBox, stickyeffects_cb)
+ FROM_UI(QCheckBox, stickypres_cb)
+ FROM_UI(QCheckBox, customchat_cb)
+ FROM_UI(QCheckBox, sticker_cb)
+ FROM_UI(QCheckBox, continuous_cb)
+ FROM_UI(QCheckBox, category_stop_cb)
+ FROM_UI(QCheckBox, sfx_on_idle_cb)
+ FROM_UI(QCheckBox, evidence_double_click_cb)
+
+ registerOption("animated_theme_cb",
+ &Options::animatedThemeEnabled,
+ &Options::setAnimatedThemeEnabled);
+ registerOption("stay_time_spinbox", &Options::textStayTime,
+ &Options::setTextStayTime);
+ registerOption("instant_objection_cb",
+ &Options::objectionSkipQueueEnabled,
+ &Options::setObjectionSkipQueueEnabled);
+ registerOption("text_crawl_spinbox", &Options::textCrawlSpeed,
+ &Options::setTextCrawlSpeed);
+ registerOption("chat_ratelimit_spinbox",
+ &Options::chatRateLimit,
+ &Options::setChatRateLimit);
+ registerOption("username_textbox", &Options::username,
+ &Options::setUsername);
+ registerOption("showname_cb",
+ &Options::customShownameEnabled,
+ &Options::setCustomShownameEnabled);
+ registerOption("default_showname_textbox",
+ &Options::shownameOnJoin,
+ &Options::setShownameOnJoin);
+ registerOption("ms_textbox",
+ &Options::alternativeMasterserver,
+ &Options::setAlternativeMasterserver);
+ registerOption("discord_cb", &Options::discordEnabled,
+ &Options::setDiscordEnabled);
+ registerOption("language_combobox", &Options::language,
+ &Options::setLanguage);
+ registerOption("scaling_combobox",
+ &Options::defaultScalingMode,
+ &Options::setDefaultScalingMode);
+
+ // Populate scaling dropdown. This is necessary as we need the user data
+ // embeeded into the entry.
+ ui_scaling_combobox->addItem(tr("Pixel"), "fast");
+ ui_scaling_combobox->addItem(tr("Smooth"), "smooth");
+
+ registerOption("shake_cb", &Options::shakeEnabled,
+ &Options::setShakeEnabled);
+ registerOption("effects_cb", &Options::effectsEnabled,
+ &Options::setEffectsEnabled);
+ registerOption("framenetwork_cb",
+ &Options::networkedFrameSfxEnabled,
+ &Options::setNetworkedFrameSfxEnabled);
+ registerOption("colorlog_cb", &Options::colorLogEnabled,
+ &Options::setColorLogEnabled);
+ registerOption(
+ "stickysounds_cb", &Options::clearSoundsDropdownOnPlayEnabled,
+ &Options::setClearSoundsDropdownOnPlayEnabled);
+ registerOption(
+ "stickyeffects_cb", &Options::clearEffectsDropdownOnPlayEnabled,
+ &Options::setClearEffectsDropdownOnPlayEnabled);
+ registerOption("stickypres_cb",
+ &Options::clearPreOnPlayEnabled,
+ &Options::setClearPreOnPlayEnabled);
+ registerOption("customchat_cb",
+ &Options::customChatboxEnabled,
+ &Options::setCustomChatboxEnabled);
+ registerOption("sticker_cb",
+ &Options::characterStickerEnabled,
+ &Options::setCharacterStickerEnabled);
+ registerOption("continuous_cb",
+ &Options::continuousPlaybackEnabled,
+ &Options::setContinuousPlaybackEnabled);
+ registerOption("category_stop_cb",
+ &Options::stopMusicOnCategoryEnabled,
+ &Options::setStopMusicOnCategoryEnabled);
+ registerOption("sfx_on_idle_cb",
+ &Options::playSelectedSFXOnIdle,
+ &Options::setPlaySelectedSFXOnIdle);
+ registerOption("evidence_double_click_cb",
+ &Options::evidenceDoubleClickEdit,
+ &Options::setEvidenceDoubleClickEdit);
+
+ // Callwords tab. This could just be a QLineEdit, but no, we decided to allow
+ // people to put a billion entries in.
+ FROM_UI(QPlainTextEdit, callwords_textbox)
+ registerOption(
+ "callwords_textbox", &Options::callwords, &Options::setCallwords);
+
+ // Audio tab.
+ FROM_UI(QComboBox, audio_device_combobox)
+ populateAudioDevices();
+ registerOption("audio_device_combobox",
+ &Options::audioOutputDevice,
+ &Options::setAudioOutputDevice);
+
+ FROM_UI(QSpinBox, music_volume_spinbox)
+ FROM_UI(QSpinBox, sfx_volume_spinbox)
+ FROM_UI(QSpinBox, blips_volume_spinbox)
+ FROM_UI(QSpinBox, suppress_audio_spinbox)
+ FROM_UI(QSpinBox, bliprate_spinbox)
+ FROM_UI(QCheckBox, blank_blips_cb)
+ FROM_UI(QCheckBox, loopsfx_cb)
+ FROM_UI(QCheckBox, objectmusic_cb)
+ FROM_UI(QCheckBox, disablestreams_cb)
+
+ registerOption("music_volume_spinbox", &Options::musicVolume,
+ &Options::setMusicVolume);
+ registerOption("sfx_volume_spinbox", &Options::sfxVolume,
+ &Options::setSfxVolume);
+ registerOption("blips_volume_spinbox", &::Options::blipVolume,
+ &Options::setBlipVolume);
+ registerOption("suppress_audio_spinbox",
+ &::Options::defaultSuppressAudio,
+ &Options::setDefaultSupressedAudio);
+ registerOption("bliprate_spinbox", &::Options::blipRate,
+ &Options::setBlipRate);
+ registerOption("blank_blips_cb", &Options::blankBlip,
+ &Options::setBlankBlip);
+ registerOption("loopsfx_cb", &Options::loopingSfx,
+ &Options::setLoopingSfx);
+ registerOption("objectmusic_cb",
+ &Options::objectionStopMusic,
+ &Options::setObjectionStopMusic);
+ registerOption("disablestreams_cb",
+ &Options::streamingEnabled,
+ &Options::setStreamingEnabled);
+
+ // Casing tab.
+ FROM_UI(QGroupBox, casing_enabled_box)
+ FROM_UI(QCheckBox, casing_def_cb)
+ FROM_UI(QCheckBox, casing_pro_cb)
+ FROM_UI(QCheckBox, casing_jud_cb)
+ FROM_UI(QCheckBox, casing_jur_cb)
+ FROM_UI(QCheckBox, casing_steno_cb)
+ FROM_UI(QCheckBox, casing_cm_cb)
+ FROM_UI(QLineEdit, casing_cm_cases_textbox)
+
+ registerOption("casing_enabled_box",
+ &Options::casingAlertEnabled,
+ &Options::setCasingAlertEnabled);
+ registerOption("casing_def_cb",
+ &Options::casingDefenceEnabled,
+ &Options::setcasingDefenceEnabled);
+ registerOption("casing_pro_cb",
+ &Options::casingProsecutionEnabled,
+ &::Options::setCasingProseuctionEnabled);
+ registerOption("casing_jud_cb", &Options::casingJudgeEnabled,
+ &::Options::setCasingJudgeEnabled);
+ registerOption("casing_jur_cb", &Options::casingJurorEnabled,
+ &Options::setCasingJurorEnabled);
+ registerOption("casing_steno_cb",
+ &Options::casingStenoEnabled,
+ &Options::setCasingStenoEnabled);
+ registerOption("casing_cm_cb", &Options::casingCmEnabled,
+ &Options::setCasingCmEnabled);
+ registerOption("casing_cm_cases_textbox",
+ &Options::casingCanHostCases,
+ &Options::setCasingCanHostCases);
+
+ // Asset tab
+ FROM_UI(QListWidget, mount_list)
+ auto *defaultMount =
+ new QListWidgetItem(tr("%1 (default)").arg(ao_app->get_base_path()));
+ defaultMount->setFlags(Qt::ItemFlag::NoItemFlags);
+ ui_mount_list->addItem(defaultMount);
+ registerOption("mount_list", &Options::mountPaths,
+ &Options::setMountPaths);
+
+ FROM_UI(QPushButton, mount_add)
+ connect(ui_mount_add, &QPushButton::clicked, this, [this] {
+ QString path = QFileDialog::getExistingDirectory(
+ this, tr("Select a base folder"), QApplication::applicationDirPath(),
+ QFileDialog::ShowDirsOnly);
+ if (path.isEmpty()) {
+ return;
+ }
+ QDir dir(QApplication::applicationDirPath());
+ QString relative = dir.relativeFilePath(path);
+ if (!relative.contains("../")) {
+ path = relative;
+ }
+ QListWidgetItem *dir_item = new QListWidgetItem(path);
+ ui_mount_list->addItem(dir_item);
+ ui_mount_list->setCurrentItem(dir_item);
+
+ // quick hack to update buttons
+ emit ui_mount_list->itemSelectionChanged();
+ });
+
+ FROM_UI(QPushButton, mount_remove)
+ connect(ui_mount_remove, &QPushButton::clicked, this, [this] {
+ auto selected = ui_mount_list->selectedItems();
+ if (selected.isEmpty()) return;
+ delete selected[0];
+ emit ui_mount_list->itemSelectionChanged();
+ asset_cache_dirty = true;
+ });
+
+ FROM_UI(QPushButton, mount_up)
+ connect(ui_mount_up, &QPushButton::clicked, this, [this] {
+ auto selected = ui_mount_list->selectedItems();
+ if (selected.isEmpty()) return;
+ auto *item = selected[0];
+ int row = ui_mount_list->row(item);
+ ui_mount_list->takeItem(row);
+ int new_row = qMax(1, row - 1);
+ ui_mount_list->insertItem(new_row, item);
+ ui_mount_list->setCurrentRow(new_row);
+ asset_cache_dirty = true;
+ });
+
+ FROM_UI(QPushButton, mount_down)
+ connect(ui_mount_down, &QPushButton::clicked, this, [this] {
+ auto selected = ui_mount_list->selectedItems();
+ if (selected.isEmpty()) return;
+ auto *item = selected[0];
+ int row = ui_mount_list->row(item);
+ ui_mount_list->takeItem(row);
+ int new_row = qMin(ui_mount_list->count() + 1, row + 1);
+ ui_mount_list->insertItem(new_row, item);
+ ui_mount_list->setCurrentRow(new_row);
+ asset_cache_dirty = true;
+ });
+
+ FROM_UI(QPushButton, mount_clear_cache)
+ connect(ui_mount_clear_cache, &QPushButton::clicked, this, [this] {
+ asset_cache_dirty = true;
+ ui_mount_clear_cache->setEnabled(false);
+ });
+
+ connect(ui_mount_list, &QListWidget::itemSelectionChanged, this, [this] {
+ auto selected_items = ui_mount_list->selectedItems();
+ bool row_selected = !ui_mount_list->selectedItems().isEmpty();
+ ui_mount_remove->setEnabled(row_selected);
+ ui_mount_up->setEnabled(row_selected);
+ ui_mount_down->setEnabled(row_selected);
+
+ if (!row_selected) return;
+
+ int row = ui_mount_list->row(selected_items[0]);
+ if (row <= 1) ui_mount_up->setEnabled(false);
+ if (row >= ui_mount_list->count() - 1) ui_mount_down->setEnabled(false);
+ });
+
+ // Logging tab
+ FROM_UI(QCheckBox, downwards_cb)
+ FROM_UI(QSpinBox, length_spinbox)
+ FROM_UI(QCheckBox, log_newline_cb)
+ FROM_UI(QSpinBox, log_margin_spinbox)
+ FROM_UI(QLabel, log_timestamp_format_lbl)
+ FROM_UI(QComboBox, log_timestamp_format_combobox)
+
+ registerOption("downwards_cb",
+ &Options::logDirectionDownwards,
+ &Options::setLogDirectionDownwards);
+ registerOption("length_spinbox", &Options::maxLogSize,
+ &Options::setMaxLogSize);
+ registerOption("log_newline_cb", &Options::logNewline,
+ &Options::setLogNewline);
+ registerOption("log_margin_spinbox", &Options::logMargin,
+ &Options::setLogMargin);
+
+ FROM_UI(QCheckBox, log_timestamp_cb)
+ registerOption("log_timestamp_cb",
+ &Options::logTimestampEnabled,
+ &Options::setLogTimestampEnabled);
+ connect(ui_log_timestamp_cb, &QCheckBox::stateChanged, this,
+ &::AOOptionsDialog::timestampCbChanged);
+ ui_log_timestamp_format_lbl->setText(
+ tr("Log timestamp format:\n") +
+ QDateTime::currentDateTime().toString(
+ Options::getInstance().logTimestampFormat()));
+
+ FROM_UI(QComboBox, log_timestamp_format_combobox)
+ registerOption("log_timestamp_format_combobox",
+ &Options::logTimestampFormat,
+ &Options::setLogTimestampFormat);
+ connect(ui_log_timestamp_format_combobox, &QComboBox::currentTextChanged,
+ this, &::AOOptionsDialog::onTimestampFormatEdited);
+
+ QString l_current_format = Options::getInstance().logTimestampFormat();
+
+ ui_log_timestamp_format_combobox->setCurrentText(l_current_format);
+
+ if (!Options::getInstance().logTimestampEnabled()) {
+ ui_log_timestamp_format_combobox->setDisabled(true);
+ }
+
+ FROM_UI(QCheckBox, log_ic_actions_cb)
+ FROM_UI(QCheckBox, desync_logs_cb)
+ FROM_UI(QCheckBox, log_text_cb)
+
+ registerOption("log_ic_actions_cb", &Options::logIcActions,
+ &Options::setLogIcActions);
+ registerOption("desync_logs_cb",
+ &Options::desynchronisedLogsEnabled,
+ &Options::setDesynchronisedLogsEnabled);
+ registerOption("log_text_cb", &Options::logToTextFileEnabled,
+ &Options::setLogToTextFileEnabled);
+ registerOption("log_demo_cb", &Options::logToDemoFileEnabled,
+ &Options::setLogToDemoFileEnabled);
+
+ // DSGVO/Privacy tab
+
+ FROM_UI(QTextBrowser, privacy_policy)
+ ui_privacy_policy->setPlainText(tr("Getting privacy policy..."));
+
+ updateValues();
+}
+
+void AOOptionsDialog::populateAudioDevices()
+{
+ ui_audio_device_combobox->clear();
+ if (needsDefaultAudioDevice()) {
+ ui_audio_device_combobox->addItem("default");
+ }
+
+ BASS_DEVICEINFO info;
+ for (int a = 0; BASS_GetDeviceInfo(a, &info); a++) {
+ ui_audio_device_combobox->addItem(info.name);
+ }
+}
+
+template <>
+void AOOptionsDialog::setWidgetData(QCheckBox *widget, const bool &value)
+{
+ widget->setChecked(value);
+}
+
+template <> bool AOOptionsDialog::widgetData(QCheckBox *widget) const
+{
+ return widget->isChecked();
+}
+
+template <>
+void AOOptionsDialog::setWidgetData(QLineEdit *widget, const QString &value)
+{
+ widget->setText(value);
+}
+
+template <> QString AOOptionsDialog::widgetData(QLineEdit *widget) const
+{
+ return widget->text();
+}
+
+template <>
+void AOOptionsDialog::setWidgetData(QLineEdit *widget, const uint16_t &value)
+{
+ widget->setText(QString::number(value));
+}
+
+template <> uint16_t AOOptionsDialog::widgetData(QLineEdit *widget) const
+{
+ return widget->text().toUShort();
+}
+
+template <>
+void AOOptionsDialog::setWidgetData(QPlainTextEdit *widget,
+ const QStringList &value)
+{
+ widget->setPlainText(value.join('\n'));
+}
+
+template <>
+QStringList AOOptionsDialog::widgetData(QPlainTextEdit *widget) const
+{
+ return widget->toPlainText().trimmed().split('\n');
+}
+
+template <>
+void AOOptionsDialog::setWidgetData(QSpinBox *widget, const int &value)
+{
+ widget->setValue(value);
+}
+
+template <> int AOOptionsDialog::widgetData(QSpinBox *widget) const
+{
+ return widget->value();
+}
+
+template <>
+void AOOptionsDialog::setWidgetData(QComboBox *widget, const QString &value)
+{
+ for (auto i = 0; i < widget->count(); i++) {
+ if (widget->itemText(i) == value) {
+ widget->setCurrentIndex(i);
+ return;
+ }
+ }
+ qWarning() << "value" << value << "not found for widget"
+ << widget->objectName();
+}
+
+template <> QString AOOptionsDialog::widgetData(QComboBox *widget) const
+{
+ return widget->currentText();
+}
+
+template <>
+void AOOptionsDialog::setWidgetData(QGroupBox *widget, const bool &value)
+{
+ widget->setChecked(value);
+}
+
+template <> bool AOOptionsDialog::widgetData(QGroupBox *widget) const
+{
+ return widget->isChecked();
+}
+
+template <>
+void AOOptionsDialog::setWidgetData(QListWidget *widget,
+ const QStringList &value)
+{
+ widget->addItems(value);
+}
+
+template <> QStringList AOOptionsDialog::widgetData(QListWidget *widget) const
+{
+ QStringList paths;
+ for (auto i = 1; i < widget->count(); i++) {
+ paths.append(widget->item(i)->text());
+ }
+ return paths;
+}
+
+template
+void AOOptionsDialog::registerOption(const QString &widgetName,
+ V (Options::*getter)() const,
+ void (Options::*setter)(V))
+{
+ auto *widget = findChild(widgetName);
+ if (!widget) {
+ qWarning() << "could not find widget" << widgetName;
+ return;
+ }
+
+ OptionEntry entry;
+ entry.load = [=] {
+ setWidgetData(widget, (Options::getInstance().*getter)());
+ };
+ entry.save = [=] {
+ (Options::getInstance().*setter)(widgetData(widget));
+ };
+
+ optionEntries.append(entry);
+}
+
+void AOOptionsDialog::updateValues()
+{
+ for (const OptionEntry &entry : qAsConst(optionEntries))
+ entry.load();
+
+ QSet themes;
+ QStringList bases = Options::getInstance().mountPaths();
+ bases.push_front(ao_app->get_base_path());
+ for (const QString &base : bases) {
+ QDirIterator it(base + "/themes", QDir::Dirs | QDir::NoDotAndDotDot,
+ QDirIterator::NoIteratorFlags);
+ while (it.hasNext()) {
+ QString actualname = QDir(it.next()).dirName();
+ if (!themes.contains(actualname)) {
+ ui_theme_combobox->addItem(actualname);
+ themes.insert(actualname);
+ }
+ }
+ }
+ int l_theme_index =
+ ui_theme_combobox->findText(Options::getInstance().theme());
+ if (l_theme_index != -1) // Data found
+ ui_theme_combobox->setCurrentIndex(l_theme_index);
+
+ QDirIterator it2(ao_app->get_real_path(ao_app->get_theme_path("")),
+ QDir::Dirs, QDirIterator::NoIteratorFlags);
+ while (it2.hasNext()) {
+ QString actualname = QDir(it2.next()).dirName();
+ if (actualname != "." && actualname != ".." &&
+ actualname.toLower() != "server" && actualname.toLower() != "default" &&
+ actualname.toLower() != "effects" && actualname.toLower() != "misc") {
+ ui_subtheme_combobox->addItem(actualname);
+ }
+ }
+ int l_subTheme_index =
+ ui_subtheme_combobox->findText(Options::getInstance().subTheme());
+ if (l_theme_index != -1) // Data found
+ ui_subtheme_combobox->setCurrentIndex(l_subTheme_index);
+
+ ao_app->net_manager->request_document(
+ MSDocumentType::PrivacyPolicy, [this](QString document) {
+ if (document.isEmpty()) {
+ document = tr("Couldn't get the privacy policy.");
+ }
+ ui_privacy_policy->setHtml(document);
+ });
+}
+
+void AOOptionsDialog::savePressed()
+{
+ for (const OptionEntry &entry : qAsConst(optionEntries))
+ entry.save();
+ this->close();
+}
+
+void AOOptionsDialog::discardPressed() { this->close(); }
+
+void AOOptionsDialog::buttonClicked(QAbstractButton *button)
+{
+ if (ui_settings_buttons->buttonRole(button) == QDialogButtonBox::ResetRole) {
+ if (QMessageBox::question(
+ this, "", "Restore default settings?\nThis can't be undone!",
+ QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
+ // Destructive operation.
+ Options::getInstance().clearConfig();
+ updateValues();
+ }
+ }
+}
+
+void AOOptionsDialog::onReloadThemeClicked()
+{
+ Options::getInstance().setTheme(ui_theme_combobox->currentText());
+ Options::getInstance().setSubTheme(ui_subtheme_combobox->currentText());
+ Options::getInstance().setAnimatedThemeEnabled(
+ ui_animated_theme_cb->isChecked());
+ emit reloadThemeRequest();
+}
+
+void AOOptionsDialog::themeChanged(int i)
+{
+ ui_subtheme_combobox->clear();
+ // Fill the combobox with the names of the themes.
+ ui_subtheme_combobox->addItem("server");
+ ui_subtheme_combobox->addItem("default");
+ QDirIterator it(ao_app->get_real_path(ao_app->get_theme_path(
+ "", ui_theme_combobox->itemText(i))),
+ QDir::Dirs, QDirIterator::NoIteratorFlags);
+ while (it.hasNext()) {
+ QString actualname = QDir(it.next()).dirName();
+ if (actualname != "." && actualname != ".." &&
+ actualname.toLower() != "server" && actualname.toLower() != "default" &&
+ actualname.toLower() != "effects" && actualname.toLower() != "misc")
+ ui_subtheme_combobox->addItem(actualname);
+ }
+}
+
+void AOOptionsDialog::onTimestampFormatEdited()
+{
+ ui_log_timestamp_format_lbl->setText(
+ tr("Log timestamp format:\n") +
+ QDateTime::currentDateTime().toString(
+ ui_log_timestamp_format_combobox->currentText()));
+}
+
+void AOOptionsDialog::timestampCbChanged(int state)
+{
+ ui_log_timestamp_format_combobox->setDisabled(state == 0);
+}
+
+#if (defined(_WIN32) || defined(_WIN64))
+bool AOOptionsDialog::needsDefaultAudioDevice() { return true; }
+#elif (defined(LINUX) || defined(__linux__))
+bool AOOptionsDialog::needsDefaultAudioDevice() { return false; }
+#elif defined __APPLE__
+bool AOOptionsDialog::needsDefaultAudioDevice() { return true; }
+#else
+#error This operating system is not supported.
+#endif