aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/aoapplication.cpp99
-rw-r--r--src/aobutton.cpp7
-rw-r--r--src/aocaseannouncerdialog.cpp85
-rw-r--r--src/aocharbutton.cpp4
-rw-r--r--src/aoevidencebutton.cpp4
-rw-r--r--src/aoimage.cpp9
-rw-r--r--src/aolayer.cpp18
-rw-r--r--src/aomusicplayer.cpp54
-rw-r--r--src/aooptionsdialog.cpp1449
-rw-r--r--src/charselect.cpp47
-rw-r--r--src/courtroom.cpp342
-rw-r--r--src/demoserver.cpp10
-rw-r--r--src/emotes.cpp3
-rw-r--r--src/evidence.cpp9
-rw-r--r--src/file_functions.cpp20
-rw-r--r--src/lobby.cpp832
-rw-r--r--src/main.cpp14
-rw-r--r--src/networkmanager.cpp13
-rw-r--r--src/options.cpp703
-rw-r--r--src/packet_distribution.cpp107
-rw-r--r--src/path_functions.cpp30
-rw-r--r--src/text_file_functions.cpp514
-rw-r--r--src/widgets/add_server_dialog.cpp96
-rw-r--r--src/widgets/aooptionsdialog.cpp648
-rw-r--r--src/widgets/direct_connect_dialog.cpp101
-rw-r--r--src/widgets/edit_server_dialog.cpp87
26 files changed, 2335 insertions, 2970 deletions
diff --git a/src/aoapplication.cpp b/src/aoapplication.cpp
index 856b8ada..24682bc2 100644
--- a/src/aoapplication.cpp
+++ b/src/aoapplication.cpp
@@ -1,12 +1,13 @@
#include "aoapplication.h"
+#include "bassmidi.h"
#include "courtroom.h"
#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);
}
@@ -51,8 +47,7 @@ void AOApplication::construct_lobby()
return;
}
- load_favorite_list();
- w_lobby = new Lobby(this);
+ w_lobby = new Lobby(this, net_manager);
lobby_constructed = true;
QRect geometry = QGuiApplication::primaryScreen()->geometry();
@@ -60,13 +55,12 @@ 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)
demo_server->deleteLater();
demo_server = new DemoServer(this);
-
w_lobby->show();
}
@@ -124,64 +118,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();
-}
-
-void AOApplication::save_favorite_list()
-{
- QSettings favorite_servers_ini(get_base_path() + "favorite_servers.ini", QSettings::IniFormat);
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- favorite_servers_ini.setIniCodec("UTF-8");
-#endif
-
- favorite_servers_ini.clear();
- // skip demo server entry, demo server entry is always at index 0
- for(int i = 1; i < favorite_list.size(); ++i) {
- auto fav_server = favorite_list.at(i);
- favorite_servers_ini.beginGroup(QString::number(i));
- favorite_servers_ini.setValue("name", fav_server.name);
- favorite_servers_ini.setValue("address", fav_server.ip);
- favorite_servers_ini.setValue("port", fav_server.port);
- favorite_servers_ini.setValue("desc", fav_server.desc);
-
- if (fav_server.socket_type == TCP) {
- favorite_servers_ini.setValue("protocol", "tcp");
- } else {
- favorite_servers_ini.setValue("protocol", "ws");
- }
- favorite_servers_ini.endGroup();
- }
- favorite_servers_ini.sync();
-}
-
-QString AOApplication::get_current_char()
-{
- if (courtroom_constructed)
- return w_courtroom->get_current_char();
- else
- return "";
-}
-
-void AOApplication::add_favorite_server(int p_server)
-{
- if (p_server < 0 || p_server >= server_list.size())
- return;
- favorite_list.append(server_list.at(p_server));
- save_favorite_list();
-}
-
-void AOApplication::remove_favorite_server(int p_server)
-{
- if (p_server < 0 || p_server >= favorite_list.size())
- return;
- favorite_list.removeAt(p_server);
- save_favorite_list();
-}
-
void AOApplication::server_disconnected()
{
if (courtroom_constructed) {
@@ -189,25 +125,26 @@ void AOApplication::server_disconnected()
construct_lobby();
destruct_courtroom();
}
+ Options::getInstance().setServerSubTheme(QString());
}
void AOApplication::loading_cancelled()
{
destruct_courtroom();
-
- w_lobby->hide_loading_overlay();
}
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);
+ }
-void AOApplication::call_announce_menu(Courtroom *court)
-{
- AOCaseAnnouncerDialog announcer(nullptr, this, court);
- announcer.exec();
+ if(lobby_constructed) {
+ }
+ l_dialog->exec();
+ delete l_dialog;
}
// Callback for when BASS device is lost
@@ -238,24 +175,26 @@ 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<int>(a), 48000, BASS_DEVICE_LATENCY, nullptr,
nullptr);
load_bass_plugins();
qInfo() << info.name << "was set as the default audio output device.";
+ BASS_SetConfigPtr(BASS_CONFIG_MIDI_DEFFONT, QString(get_base_path() + "soundfont.sf2").toStdString().c_str());
return;
}
}
BASS_Init(-1, 48000, BASS_DEVICE_LATENCY, nullptr, nullptr);
load_bass_plugins();
}
+ BASS_SetConfigPtr(BASS_CONFIG_MIDI_DEFFONT, QString(get_base_path() + "soundfont.sf2").toStdString().c_str());
}
#if (defined(_WIN32) || defined(_WIN64))
diff --git a/src/aobutton.cpp b/src/aobutton.cpp
index 6d25a05f..5ef2a066 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/aocaseannouncerdialog.cpp b/src/aocaseannouncerdialog.cpp
deleted file mode 100644
index 0c9ee0f3..00000000
--- a/src/aocaseannouncerdialog.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-#include "aocaseannouncerdialog.h"
-
-AOCaseAnnouncerDialog::AOCaseAnnouncerDialog(QWidget *parent,
- AOApplication *p_ao_app,
- Courtroom *p_court)
- : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint)
-{
- ao_app = p_ao_app;
- court = p_court;
-
- setWindowTitle(tr("Case Announcer"));
- resize(405, 235);
-
- ui_announcer_buttons = new QDialogButtonBox(this);
-
- QSizePolicy sizepolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
- sizepolicy.setHorizontalStretch(0);
- sizepolicy.setVerticalStretch(0);
- sizepolicy.setHeightForWidth(
- ui_announcer_buttons->sizePolicy().hasHeightForWidth());
- ui_announcer_buttons->setSizePolicy(sizepolicy);
- ui_announcer_buttons->setOrientation(Qt::Horizontal);
- ui_announcer_buttons->setStandardButtons(QDialogButtonBox::Ok |
- QDialogButtonBox::Cancel);
-
- connect(ui_announcer_buttons, &QDialogButtonBox::accepted, this,
- &AOCaseAnnouncerDialog::ok_pressed);
- connect(ui_announcer_buttons, &QDialogButtonBox::rejected, this,
- &AOCaseAnnouncerDialog::cancel_pressed);
-
- setUpdatesEnabled(false);
-
- ui_vbox_layout = new QVBoxLayout(this);
-
- ui_form_layout = new QFormLayout(this);
- ui_form_layout->setLabelAlignment(Qt::AlignLeading | Qt::AlignLeft |
- Qt::AlignVCenter);
- ui_form_layout->setFormAlignment(Qt::AlignLeading | Qt::AlignLeft |
- Qt::AlignTop);
- ui_form_layout->setContentsMargins(6, 6, 6, 6);
-
- ui_vbox_layout->addItem(ui_form_layout);
- ui_vbox_layout->addWidget(ui_announcer_buttons);
-
- ui_case_title_label = new QLabel(this);
- ui_case_title_label->setText(tr("Case title:"));
-
- ui_form_layout->setWidget(0, QFormLayout::LabelRole, ui_case_title_label);
-
- ui_case_title_textbox = new QLineEdit(this);
- ui_case_title_textbox->setMaxLength(50);
-
- ui_form_layout->setWidget(0, QFormLayout::FieldRole, ui_case_title_textbox);
-
- ui_defense_needed = new QCheckBox(this);
- ui_defense_needed->setText(tr("Defense needed"));
- ui_prosecutor_needed = new QCheckBox(this);
- ui_prosecutor_needed->setText(tr("Prosecution needed"));
- ui_judge_needed = new QCheckBox(this);
- ui_judge_needed->setText(tr("Judge needed"));
- ui_juror_needed = new QCheckBox(this);
- ui_juror_needed->setText(tr("Jurors needed"));
- ui_steno_needed = new QCheckBox(this);
- ui_steno_needed->setText(tr("Stenographer needed"));
-
- ui_form_layout->setWidget(1, QFormLayout::FieldRole, ui_defense_needed);
- ui_form_layout->setWidget(2, QFormLayout::FieldRole, ui_prosecutor_needed);
- ui_form_layout->setWidget(3, QFormLayout::FieldRole, ui_judge_needed);
- ui_form_layout->setWidget(4, QFormLayout::FieldRole, ui_juror_needed);
- ui_form_layout->setWidget(5, QFormLayout::FieldRole, ui_steno_needed);
-
- setUpdatesEnabled(true);
-}
-
-void AOCaseAnnouncerDialog::ok_pressed()
-{
- court->announce_case(
- ui_case_title_textbox->text(), ui_defense_needed->isChecked(),
- ui_prosecutor_needed->isChecked(), ui_judge_needed->isChecked(),
- ui_juror_needed->isChecked(), ui_steno_needed->isChecked());
-
- done(0);
-}
-
-void AOCaseAnnouncerDialog::cancel_pressed() { done(0); }
diff --git a/src/aocharbutton.cpp b/src/aocharbutton.cpp
index 19eff5fc..0c4ff129 100644
--- a/src/aocharbutton.cpp
+++ b/src/aocharbutton.cpp
@@ -78,7 +78,11 @@ void AOCharButton::set_image(QString p_character)
}
}
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+void AOCharButton::enterEvent(QEvent *e)
+#else
void AOCharButton::enterEvent(QEnterEvent *e)
+#endif
{
ui_selector->move(this->x() - 1, this->y() - 1);
ui_selector->raise();
diff --git a/src/aoevidencebutton.cpp b/src/aoevidencebutton.cpp
index ff690c20..d731682e 100644
--- a/src/aoevidencebutton.cpp
+++ b/src/aoevidencebutton.cpp
@@ -104,7 +104,11 @@ void AOEvidenceButton::dragEnterEvent(QMouseEvent *e)
}
*/
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+void AOEvidenceButton::enterEvent(QEvent *e)
+#else
void AOEvidenceButton::enterEvent(QEnterEvent *e)
+#endif
{
ui_selector->show();
diff --git a/src/aoimage.cpp b/src/aoimage.cpp
index c488a093..e737ffb3 100644
--- a/src/aoimage.cpp
+++ b/src/aoimage.cpp
@@ -1,6 +1,7 @@
#include "file_functions.h"
#include "aoimage.h"
+#include "options.h"
#include <QBitmap>
@@ -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 27ebe48c..f9b01d3b 100644
--- a/src/aolayer.cpp
+++ b/src/aolayer.cpp
@@ -2,6 +2,8 @@
#include "aoapplication.h"
#include "file_functions.h"
+#include "misc_functions.h"
+#include "options.h"
static QThreadPool *thread_pool;
@@ -233,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();
}
@@ -256,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();
}
@@ -264,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();
}
@@ -296,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;
}
@@ -335,11 +337,11 @@ void AOLayer::start_playback(QString p_image)
frame = 0;
continuous = false;
}
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
frame_loader = QtConcurrent::run(thread_pool, this, &AOLayer::populate_vectors);
-#else
+ #else
frame_loader = QtConcurrent::run(thread_pool, &AOLayer::populate_vectors, this);
-#endif
+ #endif
last_path = p_image;
while (movie_frames.size() <= frame) // if we haven't loaded the frame we need yet
frameAdded.wait(&mutex); // wait for the frame loader to add another frame, then check again
diff --git a/src/aomusicplayer.cpp b/src/aomusicplayer.cpp
index f29e0cf9..366335a4 100644
--- a/src/aomusicplayer.cpp
+++ b/src/aomusicplayer.cpp
@@ -1,4 +1,8 @@
#include "aomusicplayer.h"
+#include "options.h"
+
+#include "bass.h"
+#include "file_functions.h"
AOMusicPlayer::AOMusicPlayer(QWidget *parent, AOApplication *p_ao_app)
{
@@ -30,25 +34,15 @@ 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.");
}
-
- if (f_path.endsWith(".opus"))
- newstream = BASS_OPUS_StreamCreateURL(f_path.toStdString().c_str(), 0, streaming_flags, nullptr, 0);
- else if (f_path.endsWith(".mid"))
- newstream = BASS_MIDI_StreamCreateURL(f_path.toStdString().c_str(), 0, streaming_flags, nullptr, 0, 1);
- else
- newstream = BASS_StreamCreateURL(f_path.toStdString().c_str(), 0, streaming_flags, nullptr, 0);
-
- } else {
+ newstream = BASS_StreamCreateURL(f_path.toStdString().c_str(), 0, streaming_flags, nullptr, 0);
+ }
+ else {
f_path = ao_app->get_real_path(ao_app->get_music_path(p_song));
- if (f_path.endsWith(".opus"))
- newstream = BASS_OPUS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags);
- else if (f_path.endsWith(".mid"))
- newstream = BASS_MIDI_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags, 1);
- else if (f_path.endsWith(".mo3") || f_path.endsWith(".xm") || f_path.endsWith(".mod") || f_path.endsWith(".s3m") || f_path.endsWith(".it") || f_path.endsWith(".mtm") || f_path.endsWith(".umx") )
+ if (f_path.endsWith(".mo3") || f_path.endsWith(".xm") || f_path.endsWith(".mod") || f_path.endsWith(".s3m") || f_path.endsWith(".it") || f_path.endsWith(".mtm") || f_path.endsWith(".umx") )
newstream = BASS_MusicLoad(FALSE,f_path.utf16(), 0, 0, flags, 1);
else
newstream = BASS_StreamCreateFile(FALSE, f_path.utf16(), 0, 0, flags);
@@ -56,7 +50,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";
@@ -219,20 +213,18 @@ void AOMusicPlayer::set_looping(bool loop_song, int channel)
loop_sync[channel] = 0;
}
- if (loop_start[channel] >= 0) {
- if (loop_start[channel] < loop_end[channel])
- {
- //Loop when the endpoint is reached.
- loop_sync[channel] = BASS_ChannelSetSync(
- m_stream_list[channel], BASS_SYNC_POS | BASS_SYNC_MIXTIME,
- loop_end[channel], loopProc, &loop_start[channel]);
- }
- else
- {
- //Loop when the end of the file is reached.
- loop_sync[channel] = BASS_ChannelSetSync(
- m_stream_list[channel], BASS_SYNC_END | BASS_SYNC_MIXTIME,
- 0, loopProc, &loop_start[channel]);
- }
+ if (loop_start[channel] < loop_end[channel])
+ {
+ //Loop when the endpoint is reached.
+ loop_sync[channel] = BASS_ChannelSetSync(
+ m_stream_list[channel], BASS_SYNC_POS | BASS_SYNC_MIXTIME,
+ loop_end[channel], loopProc, &loop_start[channel]);
+ }
+ else
+ {
+ //Loop when the end of the file is reached.
+ loop_sync[channel] = BASS_ChannelSetSync(
+ m_stream_list[channel], BASS_SYNC_END | BASS_SYNC_MIXTIME,
+ 0, loopProc, &loop_start[channel]);
}
}
diff --git a/src/aooptionsdialog.cpp b/src/aooptionsdialog.cpp
deleted file mode 100644
index f8a8cfe3..00000000
--- a/src/aooptionsdialog.cpp
+++ /dev/null
@@ -1,1449 +0,0 @@
-#include "aooptionsdialog.h"
-#include "aoapplication.h"
-#include "courtroom.h"
-#include "lobby.h"
-#include "bass.h"
-#include "networkmanager.h"
-
-#include <QFileDialog>
-
-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<QString> 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<int>::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<QString>() +
- 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("<html><head/><body>Enter as many callwords as you would like. These "
- "are case insensitive. Make sure to leave every callword in its own "
- "line!<br>Do not leave a line with a space at the end -- you will be "
- "alerted everytime someone uses a space in their "
- "messages.</body></html>"));
-
- 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<QString>();
- 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<QString>());
- 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);
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- out.setCodec("UTF-8");
-#endif
- 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/charselect.cpp b/src/charselect.cpp
index a9770048..7a3ec1a1 100644
--- a/src/charselect.cpp
+++ b/src/charselect.cpp
@@ -98,8 +98,14 @@ void Courtroom::set_char_select()
set_size_and_pos(ui_char_taken, "char_taken");
set_size_and_pos(ui_char_buttons, "char_buttons");
+ // Silence emission. This causes the signal to be emitted TWICE during server join!
+ // Fuck this. Performance Sandwich.
+ ui_char_taken->blockSignals(true);
+ ui_char_passworded->blockSignals(true);
ui_char_taken->setChecked(true);
ui_char_passworded->setChecked(true);
+ ui_char_taken->blockSignals(false);
+ ui_char_passworded->blockSignals(false);
truncate_label_text(ui_char_taken, "char_taken");
truncate_label_text(ui_char_passworded, "char_passworded");
@@ -142,6 +148,18 @@ void Courtroom::set_char_select_page()
if (current_char_page > 0)
ui_char_select_left->show();
+ QPoint f_spacing =
+ ao_app->get_button_spacing("char_button_spacing", "courtroom_design.ini");
+
+ char_columns =
+ ((ui_char_buttons->width() - button_width) / (f_spacing.x() + button_width)) +
+ 1;
+ char_rows = ((ui_char_buttons->height() - button_height) /
+ (f_spacing.y() + button_height)) +
+ 1;
+
+ max_chars_on_page = char_columns * char_rows;
+
put_button_in_place(current_char_page * max_chars_on_page, chars_on_page);
}
@@ -233,25 +251,13 @@ void Courtroom::put_button_in_place(int starting, int chars_on_this_page)
QPoint f_spacing =
ao_app->get_button_spacing("char_button_spacing", "courtroom_design.ini");
- int x_spacing = f_spacing.x();
int x_mod_count = 0;
-
- int y_spacing = f_spacing.y();
int y_mod_count = 0;
- char_columns =
- ((ui_char_buttons->width() - button_width) / (x_spacing + button_width)) +
- 1;
- char_rows = ((ui_char_buttons->height() - button_height) /
- (y_spacing + button_height)) +
- 1;
-
- max_chars_on_page = char_columns * char_rows;
-
int startout = starting;
for (int n = starting; n < startout + chars_on_this_page; ++n) {
- int x_pos = (button_width + x_spacing) * x_mod_count;
- int y_pos = (button_height + y_spacing) * y_mod_count;
+ int x_pos = (button_width + f_spacing.x()) * x_mod_count;
+ int y_pos = (button_height + f_spacing.y()) * y_mod_count;
ui_char_button_list_filtered.at(n)->move(x_pos, y_pos);
ui_char_button_list_filtered.at(n)->show();
@@ -324,19 +330,6 @@ void Courtroom::character_loading_finished()
// still running, it is just loading the pictures of the characters.
if (ao_app->lobby_constructed) {
ao_app->generated_chars++;
- int total_loading_size = ao_app->char_list_size * 2 +
- ao_app->evidence_list_size +
- ao_app->music_list_size;
- int loading_value =
- int(((ao_app->loaded_chars + ao_app->generated_chars +
- ao_app->loaded_music + ao_app->loaded_evidence) /
- static_cast<double>(total_loading_size)) *
- 100);
- ao_app->w_lobby->set_loading_value(loading_value);
- ao_app->w_lobby->set_loading_text(
- tr("Generating chars:\n%1/%2").arg(
- QString::number(ao_app->generated_chars),
- QString::number(ao_app->char_list_size)));
}
}
ui_char_list->expandAll();
diff --git a/src/courtroom.cpp b/src/courtroom.cpp
index a08b5e13..65c5e1a3 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()
{
@@ -52,6 +53,7 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
ui_vp_background->setObjectName("ui_vp_background");
ui_vp_speedlines = new SplashLayer(ui_viewport, ao_app);
ui_vp_speedlines->setObjectName("ui_vp_speedlines");
+ ui_vp_speedlines->stretch = true;
ui_vp_player_char = new CharLayer(ui_viewport, ao_app);
ui_vp_player_char->setObjectName("ui_vp_player_char");
ui_vp_player_char->masked = false;
@@ -114,15 +116,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 +178,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 +202,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);
@@ -290,9 +292,6 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
ui_settings = new AOButton(this, ao_app);
ui_settings->setObjectName("ui_settings");
- ui_announce_casing = new AOButton(this, ao_app);
- ui_announce_casing->setObjectName("ui_announce_casing");
-
ui_switch_area_music = new AOButton(this, ao_app);
ui_switch_area_music->setObjectName("ui_switch_area_music");
@@ -315,14 +314,8 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
ui_additive->hide();
ui_additive->setObjectName("ui_additive");
- ui_casing = new QCheckBox(this);
- ui_casing->setChecked(ao_app->get_casing_enabled());
- 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 +358,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);
@@ -539,8 +532,6 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
&Courtroom::on_reload_theme_clicked);
connect(ui_call_mod, &AOButton::clicked, this, &Courtroom::on_call_mod_clicked);
connect(ui_settings, &AOButton::clicked, this, &Courtroom::on_settings_clicked);
- connect(ui_announce_casing, &AOButton::clicked, this,
- &Courtroom::on_announce_casing_clicked);
connect(ui_switch_area_music, &AOButton::clicked, this,
&Courtroom::on_switch_area_music_clicked);
@@ -548,7 +539,6 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
connect(ui_flip, &AOButton::clicked, this, &Courtroom::on_flip_clicked);
connect(ui_additive, &AOButton::clicked, this, &Courtroom::on_additive_clicked);
connect(ui_guard, &AOButton::clicked, this, &Courtroom::on_guard_clicked);
- connect(ui_casing, &AOButton::clicked, this, &Courtroom::on_casing_clicked);
connect(ui_showname_enable, &AOButton::clicked, this,
&Courtroom::on_showname_enable_clicked);
@@ -584,7 +574,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();
}
@@ -668,9 +658,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");
@@ -693,15 +680,6 @@ void Courtroom::set_widgets()
ui_ic_chat_name->setEnabled(false);
}
- if (ao_app->casing_alerts_supported) {
- ui_announce_casing->show();
- ui_casing->show();
- }
- else {
- ui_announce_casing->hide();
- ui_casing->hide();
- }
-
// We also show the non-server-dependent client additions.
// Once again, if the theme can't display it, set_move_and_pos will catch
// them.
@@ -748,20 +726,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();
}
@@ -1014,13 +992,6 @@ void Courtroom::set_widgets()
ui_settings->setToolTip(
tr("Allows you to change various aspects of the client."));
- set_size_and_pos(ui_announce_casing, "casing_button");
- ui_announce_casing->setText(tr("Casing"));
- ui_announce_casing->set_image("casing_button");
- ui_announce_casing->setToolTip(
- tr("An interface to help you announce a case (you have to be a CM first "
- "to be able to announce cases)"));
-
set_size_and_pos(ui_switch_area_music, "switch_area_music");
ui_switch_area_music->setText(tr("A/M"));
ui_switch_area_music->set_image("switch_area_music");
@@ -1061,10 +1032,6 @@ void Courtroom::set_widgets()
tr("Do not listen to mod calls when checked, preventing them from "
"playing sounds or focusing attention on the window."));
- set_size_and_pos(ui_casing, "casing");
- ui_casing->setToolTip(tr("Lets you receive case alerts when enabled.\n"
- "(You can set your preferences in the Settings!)"));
-
set_size_and_pos(ui_showname_enable, "showname_enable");
ui_showname_enable->setToolTip(
tr("Display customized shownames for all users when checked."));
@@ -1390,7 +1357,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
@@ -1412,9 +1379,7 @@ void Courtroom::set_background(QString p_background, bool display)
QString f_side = current_side;
if (current_side == "")
f_side = ao_app->get_char_side(current_char);
- set_scene(
- QString::number(ao_app->get_desk_mod(current_char, current_emote)),
- f_side);
+ set_scene(true, f_side);
}
}
@@ -1486,7 +1451,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 = "";
}
@@ -1496,7 +1461,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());
}
@@ -1602,11 +1567,6 @@ void Courtroom::enter_courtroom()
else
ui_additive->hide();
- if (ao_app->casing_alerts_supported)
- ui_casing->show();
- else
- ui_casing->hide();
-
list_music();
list_areas();
@@ -1775,6 +1735,7 @@ void Courtroom::list_areas()
void Courtroom::debug_message_handler(QtMsgType type, const QMessageLogContext &context,
const QString &msg)
{
+ Q_UNUSED(context);
const QMap<QtMsgType, QString> colors = {
{QtDebugMsg, "debug"},
{QtInfoMsg, "info"},
@@ -1814,7 +1775,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);
}
@@ -1841,7 +1802,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#
@@ -1875,22 +1836,21 @@ void Courtroom::on_chat_return_pressed()
else
f_side = current_side;
- QString f_desk_mod = "chat";
+ int f_desk_mod = DESK_SHOW;
if (ao_app->desk_mod_supported) {
- f_desk_mod =
- QString::number(ao_app->get_desk_mod(current_char, current_emote));
+ f_desk_mod = ao_app->get_desk_mod(current_char, current_emote);
if (!ao_app->expanded_desk_mods_supported) {
- if (f_desk_mod == "2" || f_desk_mod == "4")
- f_desk_mod = "0";
- else if (f_desk_mod == "3" || f_desk_mod == "5")
- f_desk_mod = "1";
+ if (f_desk_mod == DESK_PRE_ONLY_EX || f_desk_mod == DESK_PRE_ONLY)
+ f_desk_mod = DESK_HIDE;
+ else if (f_desk_mod == DESK_EMOTE_ONLY_EX || f_desk_mod == DESK_EMOTE_ONLY)
+ f_desk_mod = DESK_SHOW;
}
- if (f_desk_mod == "-1")
- f_desk_mod = "chat";
+ if (f_desk_mod == -1)
+ f_desk_mod = DESK_SHOW;
}
- packet_contents.append(f_desk_mod);
+ packet_contents.append(QString::number(f_desk_mod));
QString f_pre = ao_app->get_pre_emote(current_char, current_emote);
int f_emote_mod = ao_app->get_emote_mod(current_char, current_emote);
@@ -1945,7 +1905,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
@@ -1985,7 +1945,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);
@@ -2078,7 +2038,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(
@@ -2109,7 +2069,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);
@@ -2138,14 +2098,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);
}
@@ -2190,17 +2150,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;
@@ -2217,7 +2177,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
@@ -2242,7 +2202,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);
}
}
@@ -2265,7 +2225,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);
@@ -2501,19 +2461,17 @@ 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
else {
ui_vp_sticker->stop();
}
- // Initialize the correct pos (called SIDE here for some reason) with DESK_MOD to determine if we should hide the desk or not.
- set_scene(m_chatmessage[DESK_MOD], m_chatmessage[SIDE]);
// 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],
@@ -2672,7 +2630,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();
@@ -2685,7 +2643,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
@@ -2734,7 +2692,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];
@@ -2758,7 +2716,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(
@@ -2855,7 +2813,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);
@@ -2966,8 +2924,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
@@ -3297,7 +3255,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 &&
@@ -3512,20 +3470,20 @@ void Courtroom::play_preanim(bool immediate)
ui_vp_player_char->set_play_once(true);
ui_vp_player_char->load_image(f_preanim, f_char, preanim_duration, true);
- switch(m_chatmessage[DESK_MOD].toInt()) {
- case 4:
+ switch (m_chatmessage[DESK_MOD].toInt()) {
+ case DESK_EMOTE_ONLY_EX:
ui_vp_sideplayer_char->hide();
ui_vp_player_char->move_and_center(0, 0);
[[fallthrough]];
- case 2:
- set_scene("0", m_chatmessage[SIDE]);
+ case DESK_EMOTE_ONLY:
+ case DESK_HIDE:
+ set_scene(false, m_chatmessage[SIDE]);
break;
- case 5:
- case 3:
- set_scene("1", m_chatmessage[SIDE]);
- break;
- default:
- set_scene(m_chatmessage[DESK_MOD], m_chatmessage[SIDE]);
+
+ case DESK_PRE_ONLY_EX:
+ case DESK_PRE_ONLY:
+ case DESK_SHOW:
+ set_scene(true, m_chatmessage[SIDE]);
break;
}
@@ -3563,21 +3521,21 @@ void Courtroom::start_chat_ticking()
// handle expanded desk mods
switch(m_chatmessage[DESK_MOD].toInt()) {
- case 4:
+ case DESK_EMOTE_ONLY_EX:
set_self_offset(m_chatmessage[SELF_OFFSET]);
[[fallthrough]];
- case 2:
- set_scene("1", m_chatmessage[SIDE]);
+ case DESK_EMOTE_ONLY:
+ case DESK_SHOW:
+ set_scene(true, m_chatmessage[SIDE]);
break;
- case 5:
+
+ case DESK_PRE_ONLY_EX:
ui_vp_sideplayer_char->hide();
ui_vp_player_char->move_and_center(0, 0);
[[fallthrough]];
- case 3:
- set_scene("0", m_chatmessage[SIDE]);
- break;
- default:
- set_scene(m_chatmessage[DESK_MOD], m_chatmessage[SIDE]);
+ case DESK_PRE_ONLY:
+ case DESK_HIDE:
+ set_scene(false, m_chatmessage[SIDE]);
break;
}
@@ -3616,7 +3574,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 {
@@ -3624,7 +3582,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;
@@ -3633,7 +3591,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") {
@@ -3644,9 +3602,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;
@@ -3707,7 +3665,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);
}
@@ -3723,12 +3681,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();
@@ -3944,24 +3902,20 @@ 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");
}
-void Courtroom::set_scene(const QString f_desk_mod, const QString f_side)
+void Courtroom::set_scene(bool show_desk, const QString f_side)
{
ui_vp_background->load_image(ao_app->get_pos_path(f_side));
ui_vp_desk->load_image(ao_app->get_pos_path(f_side, true));
- if (f_desk_mod == "0" ||
- (f_desk_mod != "1" &&
- (f_side == "jud" || f_side == "hld" || f_side == "hlp"))) {
- ui_vp_desk->hide();
- }
- else {
+ if (show_desk)
ui_vp_desk->show();
- }
+ else
+ ui_vp_desk->hide();
}
void Courtroom::set_self_offset(const QString& p_list) {
@@ -4245,21 +4199,6 @@ void Courtroom::mod_called(QString p_ip)
}
}
-void Courtroom::case_called(QString msg, bool def, bool pro, bool jud, bool jur,
- bool steno)
-{
- Q_UNUSED(def);
- Q_UNUSED(pro);
- Q_UNUSED(jud);
- Q_UNUSED(jur);
- Q_UNUSED(steno);
- if (ui_casing->isChecked()) {
- ui_server_chatlog->append(msg);
- modcall_player->play(ao_app->get_court_sfx("case_call"));
- ao_app->alert(this);
- }
-}
-
void Courtroom::on_ooc_return_pressed()
{
QString ooc_message = ui_ooc_chat_message->text();
@@ -4281,9 +4220,9 @@ void Courtroom::on_ooc_return_pressed()
#else
QStringList command = ooc_message.split(" ", Qt::SkipEmptyParts);
#endif
- QDir casefolder("base/cases");
+ QDir casefolder(get_base_path()+"/cases");
if (!casefolder.exists()) {
- QDir::current().mkdir("base/" + casefolder.dirName());
+ QDir::current().mkdir(get_base_path() + casefolder.dirName());
append_server_chatmessage(
"CLIENT",
tr("You don't have a `base/cases/` folder! It was just made for you, "
@@ -4320,7 +4259,7 @@ void Courtroom::on_ooc_return_pressed()
return;
}
- QSettings casefile("base/cases/" + command[1] + ".ini",
+ QSettings casefile(get_base_path() + "/cases/" + command[1] + ".ini",
QSettings::IniFormat);
QString caseauth = casefile.value("author", "").value<QString>();
@@ -4381,9 +4320,9 @@ void Courtroom::on_ooc_return_pressed()
#else
QStringList command = ooc_message.split(" ", Qt::SkipEmptyParts);
#endif
- QDir casefolder("base/cases");
+ QDir casefolder(get_base_path() + "cases");
if (!casefolder.exists()) {
- QDir::current().mkdir("base/" + casefolder.dirName());
+ QDir(get_base_path()).mkdir(casefolder.dirName());
append_server_chatmessage(
"CLIENT",
tr("You don't have a `base/cases/` folder! It was just made for you, "
@@ -4417,7 +4356,7 @@ void Courtroom::on_ooc_return_pressed()
ui_ooc_chat_message->clear();
return;
}
- QSettings casefile("base/cases/" + command[1] + ".ini",
+ QSettings casefile(get_base_path() + "/cases/" + command[1] + ".ini",
QSettings::IniFormat);
casefile.setValue("author", ui_ooc_chat_name->text());
casefile.setValue("cmdoc", "");
@@ -4637,7 +4576,7 @@ void Courtroom::on_iniswap_dropdown_changed(int p_index)
}
QString p_path = ao_app->get_real_path(VPath("iniswaps.ini"));
if (!file_exists(p_path)) {
- p_path = ao_app->get_base_path() + "iniswaps.ini";
+ p_path = get_base_path() + "iniswaps.ini";
}
ao_app->write_to_file(swaplist.join("\n"), p_path);
ui_iniswap_dropdown->blockSignals(true);
@@ -4787,7 +4726,7 @@ void Courtroom::on_sfx_context_menu_requested(const QPoint &pos)
menu->addSeparator();
menu->addAction(QString("Open base sounds folder"), this,
[=] {
- QString p_path = ao_app->get_base_path() + "sounds/general/";
+ QString p_path = get_base_path() + "sounds/general/";
if (!dir_exists(p_path)) {
return;
}
@@ -4814,7 +4753,7 @@ void Courtroom::on_sfx_edit_requested()
}
if (!file_exists(p_path)) {
- p_path = ao_app->get_base_path() + "soundlist.ini";
+ p_path = get_base_path() + "soundlist.ini";
}
QDesktopServices::openUrl(QUrl::fromLocalFile(p_path));
}
@@ -5013,7 +4952,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);
@@ -5062,7 +5001,7 @@ void Courtroom::on_music_list_context_menu_requested(const QPoint &pos)
menu->addSeparator();
menu->addAction(QString("Open base music folder"), this,
[=] {
- QString p_path = ao_app->get_base_path() + "sounds/music/";
+ QString p_path = get_base_path() + "sounds/music/";
if (!dir_exists(p_path)) {
return;
}
@@ -5388,7 +5327,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;
}
@@ -5578,8 +5517,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()));
@@ -5648,11 +5585,6 @@ void Courtroom::on_call_mod_clicked()
void Courtroom::on_settings_clicked() { ao_app->call_settings_menu(); }
-void Courtroom::on_announce_casing_clicked()
-{
- ao_app->call_announce_menu(this);
-}
-
void Courtroom::on_pre_clicked() { ui_ic_chat_message->setFocus(); }
void Courtroom::on_flip_clicked() { ui_ic_chat_message->setFocus(); }
@@ -5707,7 +5639,7 @@ void Courtroom::on_evidence_context_menu_requested(const QPoint &pos)
QMenu *menu = new QMenu(this);
menu->addAction(QString("Open base evidence folder"), this,
[=] {
- QString p_path = ao_app->get_base_path() + "evidence/";
+ QString p_path = get_base_path() + "evidence/";
if (!dir_exists(p_path)) {
return;
}
@@ -5752,45 +5684,6 @@ qint64 Courtroom::pong()
return ping_timer.elapsed();
}
-void Courtroom::on_casing_clicked()
-{
- if (ao_app->casing_alerts_supported) {
- 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(
- 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()));
-
- ao_app->send_server_packet(new AOPacket("SETCASE", f_packet));
- }
- else
- ao_app->send_server_packet(new AOPacket("SETCASE", {"","0","0","0","0","0","0"}));
- }
-}
-
-void Courtroom::announce_case(QString title, bool def, bool pro, bool jud,
- bool jur, bool steno)
-{
- if (ao_app->casing_alerts_supported) {
- QStringList f_packet;
-
- f_packet.append(title);
- f_packet.append(QString::number(def));
- f_packet.append(QString::number(pro));
- f_packet.append(QString::number(jud));
- f_packet.append(QString::number(jur));
- f_packet.append(QString::number(steno));
-
- ao_app->send_server_packet(new AOPacket("CASEA", f_packet));
- }
-}
-
void Courtroom::start_clock(int id)
{
if (id >= 0 && id < max_clocks && ui_clock[id] != nullptr)
@@ -5920,6 +5813,11 @@ void Courtroom::truncate_label_text(QWidget *p_widget, QString p_identifier)
Courtroom::~Courtroom()
{
+ //save sound settings
+ Options::getInstance().setMusicVolume(ui_music_slider->value());
+ Options::getInstance().setSfxVolume(ui_sfx_slider->value());
+ Options::getInstance().setBlipVolume(ui_blip_slider->value());
+
delete music_player;
delete sfx_player;
delete objection_player;
diff --git a/src/demoserver.cpp b/src/demoserver.cpp
index bc7da1c1..16d2b46e 100644
--- a/src/demoserver.cpp
+++ b/src/demoserver.cpp
@@ -12,6 +12,11 @@ DemoServer::DemoServer(QObject *parent) : QObject(parent)
connect(timer, &QTimer::timeout, this, &DemoServer::playback);
}
+void DemoServer::set_demo_file(QString filepath)
+{
+ filename = filepath;
+}
+
void DemoServer::start_server()
{
if (server_started) return;
@@ -35,13 +40,12 @@ void DemoServer::destroy_connection()
void DemoServer::accept_connection()
{
- QString path = QFileDialog::getOpenFileName(nullptr, tr("Load Demo"), "logs/", tr("Demo Files (*.demo)"));
- if (path.isEmpty())
+ if (filename.isEmpty())
{
destroy_connection();
return;
}
- load_demo(path);
+ load_demo(filename);
if (demo_data.isEmpty())
{
diff --git a/src/emotes.cpp b/src/emotes.cpp
index 2a1d5066..899ae4e9 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 337e8303..752ca47d 100644
--- a/src/evidence.cpp
+++ b/src/evidence.cpp
@@ -1,4 +1,5 @@
#include "courtroom.h"
+#include "options.h"
void Courtroom::initialize_evidence()
{
@@ -400,7 +401,7 @@ void Courtroom::on_evidence_image_name_edited()
void Courtroom::on_evidence_image_button_clicked()
{
- QDir dir("base/evidence/");
+ QDir dir(get_base_path() + "/evidence/");
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::ExistingFile);
dialog.setNameFilter(tr("Images (*.png)"));
@@ -416,8 +417,8 @@ void Courtroom::on_evidence_image_button_clicked()
return;
QString filename = filenames.at(0);
- QStringList bases = ao_app->get_mount_paths();
- bases.prepend(ao_app->get_base_path());
+ QStringList bases = Options::getInstance().mountPaths();
+ bases.prepend(get_base_path());
for (const QString &base : bases) {
QDir baseDir(base);
if (filename.startsWith(baseDir.absolutePath() + "/")) {
@@ -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;
}
diff --git a/src/file_functions.cpp b/src/file_functions.cpp
index 95e9b5f4..92e598f8 100644
--- a/src/file_functions.cpp
+++ b/src/file_functions.cpp
@@ -26,3 +26,23 @@ bool exists(QString p_path)
return file.exists();
}
+
+QString get_base_path()
+{
+ QString base_path = "";
+#ifdef ANDROID
+ QString sdcard_storage = getenv("SECONDARY_STORAGE");
+ if (dir_exists(sdcard_storage + "/base/")) {
+ base_path = sdcard_storage + "/base/";
+ }
+ else {
+ QString external_storage = getenv("EXTERNAL_STORAGE");
+ base_path = external_storage + "/base/";
+ }
+#elif defined(__APPLE__)
+ base_path = QCoreApplication::applicationDirPath() + "/../../../base/";
+#else
+ base_path = QCoreApplication::applicationDirPath() + "/base/";
+#endif
+ return base_path;
+}
diff --git a/src/lobby.cpp b/src/lobby.cpp
index c4eecb4b..a705b262 100644
--- a/src/lobby.cpp
+++ b/src/lobby.cpp
@@ -1,422 +1,282 @@
#include "lobby.h"
#include "aoapplication.h"
-#include "aosfxplayer.h"
-#include "debug_functions.h"
#include "demoserver.h"
#include "networkmanager.h"
+#include "widgets/add_server_dialog.h"
+#include "widgets/direct_connect_dialog.h"
+#include "widgets/edit_server_dialog.h"
-#include <QAction>
#include <QImageReader>
-#include <QMenu>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QTreeWidget>
+
+#include <QUiLoader>
+
+#define FROM_UI(type, name) \
+ ; \
+ ui_##name = findChild<type *>(#name);
+
+#define COMBO_RELOAD() \
+ list_servers(); \
+ list_favorites(); \
+ list_demos(); \
+ get_motd(); \
+ check_for_updates(); \
+ reset_selection();
-Lobby::Lobby(AOApplication *p_ao_app) : QMainWindow()
+Lobby::Lobby(AOApplication *p_ao_app, NetworkManager *p_net_manager)
+ : QMainWindow()
{
ao_app = p_ao_app;
-
- this->setWindowTitle(tr("Attorney Online %1").arg(ao_app->applicationVersion()));
- this->setWindowIcon(QIcon(":/logo.png"));
- this->setWindowFlags( (this->windowFlags() | Qt::CustomizeWindowHint) & ~Qt::WindowMaximizeButtonHint);
-
- ui_background = new AOImage(this, ao_app);
- ui_background->setObjectName("ui_background");
- ui_public_servers = new AOButton(this, ao_app);
- ui_public_servers->setObjectName("ui_public_servers");
- ui_favorites = new AOButton(this, ao_app);
- ui_favorites->setObjectName("ui_favorites");
- ui_refresh = new AOButton(this, ao_app);
- ui_refresh->setObjectName("ui_refresh");
- ui_add_to_fav = new AOButton(this, ao_app);
- ui_add_to_fav->setObjectName("ui_add_to_fav");
- ui_remove_from_fav = new AOButton(this, ao_app);
- ui_remove_from_fav->setObjectName("ui_remove_from_fav");
- ui_remove_from_fav->hide();
- ui_connect = new AOButton(this, ao_app);
- ui_connect->setObjectName("ui_connect");
- ui_version = new QLabel(this);
- ui_version->setObjectName("ui_version");
- ui_about = new AOButton(this, ao_app);
- ui_about->setObjectName("ui_about");
- ui_settings = new AOButton(this, ao_app);
- ui_settings->setObjectName("ui_settings");
-
- ui_server_list = new QTreeWidget(this);
- ui_server_list->setHeaderLabels({"#", "Name"});
- ui_server_list->setTextElideMode(Qt::ElideNone);
- ui_server_list->header()->setMinimumSectionSize(24);
- ui_server_list->header()->setSectionsMovable(false);
- ui_server_list->setColumnWidth(0, 0);
- ui_server_list->setIndentation(0);
- ui_server_list->setObjectName("ui_server_list");
- ui_server_list->setContextMenuPolicy(Qt::CustomContextMenu);
-
- ui_server_search = new QLineEdit(this);
- ui_server_search->setFrame(false);
- ui_server_search->setPlaceholderText(tr("Search"));
- ui_server_search->setObjectName("ui_server_search");
-
- ui_player_count = new QLabel(this);
- ui_player_count->setObjectName("ui_player_count");
- ui_description = new AOTextArea(this);
- ui_description->setOpenExternalLinks(true);
- ui_description->setObjectName("ui_description");
- ui_chatbox = new AOTextArea(this);
- ui_chatbox->setOpenExternalLinks(true);
- ui_chatbox->setObjectName("ui_chatbox");
- ui_loading_background = new AOImage(this, ao_app);
- ui_loading_background->setObjectName("ui_loading_background");
- ui_loading_text = new QTextEdit(ui_loading_background);
- ui_loading_text->setObjectName("ui_loading_text");
- ui_progress_bar = new QProgressBar(ui_loading_background);
- ui_progress_bar->setMinimum(0);
- ui_progress_bar->setMaximum(100);
- ui_progress_bar->setObjectName("ui_progress_bar");
- ui_cancel = new AOButton(ui_loading_background, ao_app);
- ui_cancel->setObjectName("ui_cancel");
-
- connect(ui_public_servers, &AOButton::clicked, this,
- &Lobby::on_public_servers_clicked);
- connect(ui_favorites, &AOButton::clicked, this, &Lobby::on_favorites_clicked);
- connect(ui_refresh, &AOButton::pressed, this, &Lobby::on_refresh_pressed);
- connect(ui_refresh, &AOButton::released, this, &Lobby::on_refresh_released);
- connect(ui_add_to_fav, &AOButton::pressed, this,
- &Lobby::on_add_to_fav_pressed);
- connect(ui_add_to_fav, &AOButton::released, this,
- &Lobby::on_add_to_fav_released);
- connect(ui_remove_from_fav, &AOButton::pressed, this,
- &Lobby::on_remove_from_fav_pressed);
- connect(ui_remove_from_fav, &AOButton::released, this,
- &Lobby::on_remove_from_fav_released);
- connect(ui_connect, &AOButton::pressed, this, &Lobby::on_connect_pressed);
- connect(ui_connect, &AOButton::released, this, &Lobby::on_connect_released);
- connect(ui_about, &AOButton::clicked, this, &Lobby::on_about_clicked);
- connect(ui_settings, &AOButton::clicked, this, &Lobby::on_settings_clicked);
- connect(ui_server_list, &QTreeWidget::itemClicked, this,
- &Lobby::on_server_list_clicked);
- connect(ui_server_list, &QTreeWidget::itemDoubleClicked,
- this, &Lobby::on_server_list_doubleclicked);
- connect(ui_server_list, &QTreeWidget::customContextMenuRequested, this,
- &Lobby::on_server_list_context_menu_requested);
- connect(ui_server_search, &QLineEdit::textChanged, this,
- &Lobby::on_server_search_edited);
- connect(ui_cancel, &AOButton::clicked, ao_app, &AOApplication::loading_cancelled);
-
- ui_connect->setEnabled(false);
-
- list_servers();
- get_motd();
- check_for_updates();
-
- set_widgets();
+ net_manager = p_net_manager;
+
+ loadUI();
+ COMBO_RELOAD()
+}
+
+void Lobby::on_tab_changed(int index)
+{
+ switch (index) {
+ case SERVER:
+ current_page = SERVER;
+ ui_add_to_favorite_button->setVisible(true);
+ ui_remove_from_favorites_button->setVisible(false);
+ ui_add_server_button->setVisible(false);
+ ui_edit_favorite_button->setVisible(false);
+ ui_direct_connect_button->setVisible(true);
+ reset_selection();
+ break;
+ case FAVORITES:
+ current_page = FAVORITES;
+ ui_add_to_favorite_button->setVisible(false);
+ ui_remove_from_favorites_button->setVisible(true);
+ ui_add_server_button->setVisible(true);
+ ui_edit_favorite_button->setVisible(true);
+ ui_direct_connect_button->setVisible(false);
+ reset_selection();
+ break;
+ case DEMOS:
+ current_page = DEMOS;
+ ui_add_to_favorite_button->setVisible(false);
+ ui_add_server_button->setVisible(false);
+ ui_remove_from_favorites_button->setVisible(false);
+ ui_edit_favorite_button->setVisible(false);
+ ui_direct_connect_button->setVisible(false);
+ reset_selection();
+ break;
+ default:
+ break;
+ }
}
-// sets images, position and size
-void Lobby::set_widgets()
+int Lobby::get_selected_server()
{
- ao_app->reload_theme();
-
- QString filename = "lobby_design.ini";
-
- pos_size_type f_lobby = ao_app->get_element_dimensions("lobby", filename);
-
- if (f_lobby.width < 0 || f_lobby.height < 0) {
- qWarning() << "did not find lobby width or height in " << filename;
-
- #ifdef ANDROID
- if(QtAndroid::checkPermission("android.permission.READ_EXTERNAL_STORAGE")==QtAndroid::PermissionResult::Denied) {
- QtAndroid::requestPermissionsSync({"android.permission.READ_EXTERNAL_STORAGE","android.permission.WRITE_EXTERNAL_STORAGE"});
+ switch (ui_connections_tabview->currentIndex()) {
+ case SERVER:
+ if (auto item = ui_serverlist_tree->currentItem()) {
+ return item->text(0).toInt();
}
- #endif
-
- // Most common symptom of bad config files and missing assets.
- call_notice(
- tr("It doesn't look like your client is set up correctly.\n"
- "Did you download all resources correctly from tiny.cc/getao, "
- "including the large 'base' folder?"));
-
- this->setFixedSize(517, 666);
- }
- else {
- this->setFixedSize(f_lobby.width, f_lobby.height);
+ break;
+ case FAVORITES:
+ if (auto item = ui_favorites_tree->currentItem()) {
+ return item->text(0).toInt();
+ }
+ break;
+ default:
+ break;
}
-
- set_size_and_pos(ui_background, "lobby");
- ui_background->set_image("lobbybackground");
-
- set_size_and_pos(ui_public_servers, "public_servers");
- ui_public_servers->set_image("publicservers_selected");
-
- set_size_and_pos(ui_favorites, "favorites");
- ui_favorites->set_image("favorites");
-
- set_size_and_pos(ui_refresh, "refresh");
- ui_refresh->set_image("refresh");
-
- set_size_and_pos(ui_add_to_fav, "add_to_fav");
- ui_add_to_fav->set_image("addtofav");
-
- set_size_and_pos(ui_remove_from_fav, "remove_from_fav");
- ui_remove_from_fav->set_image("removefromfav");
-
- set_size_and_pos(ui_connect, "connect");
- ui_connect->set_image("connect");
-
- set_size_and_pos(ui_version, "version");
- ui_version->setText(tr("Version: %1").arg(ao_app->get_version_string()));
-
- set_size_and_pos(ui_about, "about");
- ui_about->set_image("about");
-
- set_size_and_pos(ui_settings, "settings");
- ui_settings->setText(tr("Settings"));
- ui_settings->set_image("lobby_settings");
- ui_settings->setToolTip(
- tr("Allows you to change various aspects of the client."));
-
- set_size_and_pos(ui_server_list, "server_list");
-
- set_size_and_pos(ui_server_search, "server_search");
-
- set_size_and_pos(ui_player_count, "player_count");
- ui_player_count->setText(tr("Offline"));
-
- set_size_and_pos(ui_description, "description");
- ui_description->setReadOnly(true);
-
- set_size_and_pos(ui_chatbox, "chatbox");
- ui_chatbox->setReadOnly(true);
-
- ui_loading_background->resize(this->width(), this->height());
- ui_loading_background->set_image("loadingbackground");
-
- set_size_and_pos(ui_loading_text, "loading_label");
- ui_loading_text->setFont(QFont("Arial", 20, QFont::Bold));
- ui_loading_text->setReadOnly(true);
- ui_loading_text->setAlignment(Qt::AlignCenter);
- ui_loading_text->setFrameStyle(QFrame::NoFrame);
- ui_loading_text->append(tr("Loading"));
-
- set_size_and_pos(ui_progress_bar, "progress_bar");
- set_size_and_pos(ui_cancel, "cancel");
- ui_cancel->setText(tr("Cancel"));
-
- ui_loading_background->hide();
-
- set_fonts();
- set_stylesheets();
+ return -1;
}
-void Lobby::set_size_and_pos(QWidget *p_widget, QString p_identifier)
-{
- QString filename = "lobby_design.ini";
+int Lobby::pageSelected() { return current_page; }
- pos_size_type design_ini_result =
- ao_app->get_element_dimensions(p_identifier, filename);
-
- if (design_ini_result.width < 0 || design_ini_result.height < 0) {
- qWarning() << "could not find" << p_identifier << "in" << filename;
- p_widget->hide();
- }
- else {
- p_widget->move(design_ini_result.x, design_ini_result.y);
- p_widget->resize(design_ini_result.width, design_ini_result.height);
- }
-}
-
-void Lobby::set_fonts()
+void Lobby::reset_selection()
{
- set_font(ui_version, "version");
- set_font(ui_player_count, "player_count");
- set_font(ui_description, "description");
- set_font(ui_chatbox, "chatbox");
- set_font(ui_loading_text, "loading_text");
- set_font(ui_server_list, "server_list");
-}
+ last_index = -1;
+ ui_server_player_count_lbl->setText(tr("Offline"));
+ ui_server_description_text->clear();
-void Lobby::set_stylesheet(QWidget *widget)
-{
- QString f_file = "lobby_stylesheets.css";
- QString style_sheet_string = ao_app->get_stylesheet(f_file);
- if (style_sheet_string != "")
- widget->setStyleSheet(style_sheet_string);
+ ui_edit_favorite_button->setEnabled(false);
+ ui_remove_from_favorites_button->setEnabled(false);
+ ui_connect_button->setEnabled(false);
}
-void Lobby::set_stylesheets()
+void Lobby::loadUI()
{
- set_stylesheet(this);
- this->setStyleSheet(
- "QFrame { background-color:transparent; } "
- "QAbstractItemView { background-color: transparent; color: black; } "
- "QLineEdit { background-color:transparent; }"
- + this->styleSheet()
- );
-}
+ this->setWindowTitle(
+ tr("Attorney Online %1").arg(ao_app->applicationVersion()));
+ this->setWindowIcon(QIcon(":/logo.png"));
+ this->setWindowFlags((this->windowFlags() | Qt::CustomizeWindowHint));
-void Lobby::set_font(QWidget *widget, QString p_identifier)
-{
- QString design_file = "lobby_fonts.ini";
- int f_weight = ao_app->get_font_size(p_identifier, design_file);
- QString class_name = widget->metaObject()->className();
- QString font_name =
- ao_app->get_design_element(p_identifier + "_font", design_file);
- QFont font(font_name, f_weight);
- bool use = ao_app->get_font_size("use_custom_fonts", design_file) == 1;
- if (use) {
- bool bold = ao_app->get_font_size(p_identifier + "_bold", design_file) ==
- 1; // is the font bold or not?
- font.setBold(bold);
- widget->setFont(font);
- QColor f_color = ao_app->get_color(p_identifier + "_color", design_file);
- bool center =
- ao_app->get_font_size(p_identifier + "_center", design_file) ==
- 1; // should it be centered?
- QString is_center = "";
- if (center)
- is_center = "qproperty-alignment: AlignCenter;";
- QString style_sheet_string =
- class_name + " { background-color: rgba(0, 0, 0, 0);\n" +
- "color: rgba(" + QString::number(f_color.red()) + ", " +
- QString::number(f_color.green()) + ", " +
- QString::number(f_color.blue()) + ", 255);\n" + is_center + "}";
- widget->setStyleSheet(style_sheet_string);
+ QUiLoader l_loader(this);
+ QFile l_uiFile(Options::getInstance().getUIAsset(DEFAULT_UI));
+ if (!l_uiFile.open(QFile::ReadOnly)) {
+ qCritical() << "Unable to open file " << l_uiFile.fileName();
+ return;
}
- return;
-}
-
-void Lobby::set_loading_text(QString p_text)
-{
- ui_loading_text->clear();
- ui_loading_text->setAlignment(Qt::AlignCenter);
- ui_loading_text->append(p_text);
-}
-QString Lobby::get_chatlog()
-{
- QString return_value = ui_chatbox->toPlainText();
+ l_loader.load(&l_uiFile, this);
- return return_value;
-}
+ FROM_UI(QLabel, game_version_lbl);
+ ui_game_version_lbl->setText(
+ tr("Version: %1").arg(ao_app->get_version_string()));
-int Lobby::get_selected_server()
-{
- if (auto item = ui_server_list->currentItem()) {
- return item->text(0).toInt();
- }
- return -1;
-}
+ FROM_UI(QPushButton, settings_button);
+ connect(ui_settings_button, &QPushButton::clicked, this,
+ &Lobby::onSettingsRequested);
-void Lobby::set_loading_value(int p_value)
-{
- ui_progress_bar->setValue(p_value);
-}
+ FROM_UI(QPushButton, about_button);
+ connect(ui_about_button, &QPushButton::clicked, this,
+ &Lobby::on_about_clicked);
-void Lobby::on_public_servers_clicked()
-{
- ui_public_servers->set_image("publicservers_selected");
- ui_favorites->set_image("favorites");
- ui_add_to_fav->show();
- ui_remove_from_fav->hide();
+ // Serverlist elements
+ FROM_UI(QTabWidget, connections_tabview);
+ ui_connections_tabview->tabBar()->setExpanding(true);
+ connect(ui_connections_tabview, &QTabWidget::currentChanged, this,
+ &Lobby::on_tab_changed);
- reset_selection();
+ FROM_UI(QTreeWidget, serverlist_tree);
+ FROM_UI(QLineEdit, serverlist_search);
+ connect(ui_serverlist_tree, &QTreeWidget::itemClicked, this,
+ &Lobby::on_server_list_clicked);
+ connect(ui_serverlist_tree, &QTreeWidget::itemDoubleClicked, this,
+ &Lobby::on_list_doubleclicked);
+ connect(ui_serverlist_search, &QLineEdit::textChanged, this,
+ &Lobby::on_server_search_edited);
- public_servers_selected = true;
+ FROM_UI(QTreeWidget, favorites_tree);
+ connect(ui_favorites_tree, &QTreeWidget::itemClicked, this,
+ &Lobby::on_favorite_tree_clicked);
+ connect(ui_favorites_tree, &QTreeWidget::itemDoubleClicked, this,
+ &Lobby::on_list_doubleclicked);
- list_servers();
-}
+ FROM_UI(QTreeWidget, demo_tree);
+ connect(ui_demo_tree, &QTreeWidget::itemClicked, this,
+ &Lobby::on_demo_clicked);
+ connect(ui_demo_tree, &QTreeWidget::itemDoubleClicked, this,
+ &Lobby::on_list_doubleclicked);
-void Lobby::on_favorites_clicked()
-{
- ui_public_servers->set_image("publicservers");
- ui_favorites->set_image("favorites_selected");
- ui_add_to_fav->hide();
- ui_remove_from_fav->show();
+ FROM_UI(QPushButton, refresh_button);
+ connect(ui_refresh_button, &QPushButton::released, this,
+ &Lobby::on_refresh_released);
- reset_selection();
+ FROM_UI(QPushButton, direct_connect_button);
+ connect(ui_direct_connect_button, &QPushButton::released, this,
+ &Lobby::on_direct_connect_released);
- ao_app->load_favorite_list();
+ FROM_UI(QPushButton, add_to_favorite_button)
+ connect(ui_add_to_favorite_button, &QPushButton::released, this,
+ &Lobby::on_add_to_fav_released);
- public_servers_selected = false;
+ FROM_UI(QPushButton, add_server_button)
+ ui_add_server_button->setVisible(false);
+ connect(ui_add_server_button, &QPushButton::released, this,
+ &Lobby::on_add_server_to_fave_released);
- list_favorites();
-}
+ FROM_UI(QPushButton, edit_favorite_button)
+ ui_edit_favorite_button->setVisible(false);
+ connect(ui_edit_favorite_button, &QPushButton::released, this,
+ &Lobby::on_edit_favorite_released)
-void Lobby::reset_selection()
-{
- last_index = -1;
- ui_server_list->clearSelection();
- ui_player_count->setText(tr("Offline"));
- ui_description->clear();
+ FROM_UI(QPushButton, remove_from_favorites_button)
+ ui_remove_from_favorites_button->setVisible(false);
+ connect(ui_remove_from_favorites_button, &QPushButton::released, this,
+ &Lobby::on_remove_from_fav_released);
- ui_connect->setEnabled(false);
+ FROM_UI(QLabel, server_player_count_lbl)
+ FROM_UI(QTextBrowser, server_description_text)
+ FROM_UI(QPushButton, connect_button);
+ connect(ui_connect_button, &QPushButton::released, net_manager,
+ &NetworkManager::join_to_server);
+ connect(ui_connect_button, &QPushButton::released, this, [=] {
+ ui_server_player_count_lbl->setText(tr("Joining Server..."));
+ });
+ connect(net_manager, &NetworkManager::server_connected, ui_connect_button,
+ &QPushButton::setEnabled);
+
+ FROM_UI(QTextBrowser, motd_text);
+ FROM_UI(QTextBrowser, game_changelog_text)
+ if (ui_game_changelog_text != nullptr) {
+ QString l_changelog_text = "No changelog found.";
+ QFile l_changelog(get_base_path() + "changelog.md");
+ if (!l_changelog.open(QFile::ReadOnly)) {
+ qDebug() << "Unable to locate changelog file. Does it even exist?";
+#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
+ ui_game_changelog_text->setMarkdown(l_changelog_text);
+#else
+ ui_game_changelog_text->setPlainText(
+ l_changelog_text); // imperfect solution, but implementing Markdown
+ // ourselves for this edge case is out of scope
+#endif
+ return;
+ }
+#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
+ ui_game_changelog_text->setMarkdown(l_changelog.readAll());
+#else
+ ui_game_changelog_text->setPlainText((l_changelog.readAll()));
+#endif
+ l_changelog.close();
+
+ QTabWidget *l_tabbar = findChild<QTabWidget *>("motd_changelog_tab");
+ if (l_tabbar != nullptr) {
+ l_tabbar->tabBar()->setExpanding(true);
+ }
+ }
}
-void Lobby::on_refresh_pressed() { ui_refresh->set_image("refresh_pressed"); }
-
void Lobby::on_refresh_released()
{
- ui_refresh->set_image("refresh");
-
- if (public_servers_selected) {
- ao_app->net_manager->get_server_list(std::bind(&Lobby::list_servers, this));
- get_motd();
- } else {
- ao_app->load_favorite_list();
- list_favorites();
- }
+ net_manager->get_server_list(std::bind(&Lobby::list_servers, this));
+ get_motd();
+ list_favorites();
}
-void Lobby::on_add_to_fav_pressed()
+void Lobby::on_direct_connect_released()
{
- ui_add_to_fav->set_image("addtofav_pressed");
+ DirectConnectDialog connect_dialog(net_manager);
+ connect_dialog.exec();
}
void Lobby::on_add_to_fav_released()
{
- ui_add_to_fav->set_image("addtofav");
- if (public_servers_selected) {
- int selection = get_selected_server();
- if (selection > -1) {
- ao_app->add_favorite_server(selection);
- }
+ int selection = get_selected_server();
+ if (selection > -1) {
+ Options::getInstance().addFavorite(ao_app->get_server_list().at(selection));
+ list_favorites();
}
}
-void Lobby::on_remove_from_fav_pressed()
+void Lobby::on_add_server_to_fave_released()
{
- ui_remove_from_fav->set_image("removefromfav_pressed");
+ AddServerDialog l_dialog;
+ l_dialog.exec();
+ list_favorites();
+ reset_selection();
}
-void Lobby::on_remove_from_fav_released()
+void Lobby::on_edit_favorite_released()
{
- ui_remove_from_fav->set_image("removefromfav");
- if (public_servers_selected) {
- return;
- }
+ EditServerDialog l_dialog(get_selected_server());
+ l_dialog.exec();
+ list_favorites();
+ reset_selection();
+}
+void Lobby::on_remove_from_fav_released()
+{
int selection = get_selected_server();
- if (selection > 0) {
- ao_app->remove_favorite_server(selection);
+ if (selection >= 0) {
+ Options::getInstance().removeFavorite(selection);
list_favorites();
}
}
-void Lobby::on_connect_pressed() { ui_connect->set_image("connect_pressed"); }
-
-void Lobby::on_connect_released()
-{
- ui_connect->set_image("connect");
-
- AOPacket *f_packet;
-
- f_packet = new AOPacket("askchaa");
-
- ao_app->send_server_packet(f_packet);
-}
-
void Lobby::on_about_clicked()
{
const bool hasApng = QImageReader::supportedImageFormats().contains("apng");
-
QString msg =
tr("<h2>Attorney Online %1</h2>"
"The courtroom drama simulator."
@@ -427,18 +287,20 @@ void Lobby::on_about_clicked()
"OmniTroid, stonedDiscord, longbyte1, gameboyprinter, Cerapter, "
"Crystalwarrior, Iamgoofball, in1tiate"
"<p><b>Client development:</b><br>"
- "Cents02, windrammer, skyedeving, TrickyLeifa, Salanto"
+ "Cents02, windrammer, skyedeving, TrickyLeifa, Salanto, lambdcalculus"
"<p><b>QA testing:</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>Translations:</b><br>"
- "k-emiko (Русский), Pyraq (Polski), scatterflower (日本語), vintprox (Русский), "
+ "k-emiko (Русский), Pyraq (Polski), scatterflower (日本語), vintprox "
+ "(Русский), "
"windrammer (Español, Português)"
"<p><b>Special thanks:</b><br>"
"Wiso, dyviacat (2.10 release); "
- "CrazyJC (2.8 release director) and MaximumVolty (2.8 release promotion); "
+ "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); "
@@ -452,100 +314,90 @@ void Lobby::on_about_clicked()
"<p>Running on Qt version %2 with the BASS audio engine.<br>"
"APNG plugin loaded: %3"
"<p>Built on %4")
- .arg(ao_app->get_version_string())
- .arg(QLatin1String(QT_VERSION_STR))
- .arg(hasApng ? tr("Yes") : tr("No"))
- .arg(QLatin1String(__DATE__));
+ .arg(ao_app->get_version_string())
+ .arg(QLatin1String(QT_VERSION_STR))
+ .arg(hasApng ? tr("Yes") : tr("No"))
+ .arg(QLatin1String(__DATE__));
QMessageBox::about(this, tr("About"), msg);
}
-void Lobby::on_settings_clicked() { ao_app->call_settings_menu(); }
-
// clicked on an item in the serverlist
void Lobby::on_server_list_clicked(QTreeWidgetItem *p_item, int column)
{
column = 0;
- if (p_item->text(column).toInt() != last_index || !public_servers_selected) {
- server_type f_server;
- int n_server = p_item->text(column).toInt();
- last_index = n_server;
+ server_type f_server;
+ int n_server = p_item->text(column).toInt();
- if (n_server < 0)
- return;
+ if (n_server == last_index) {
+ return;
+ }
+ last_index = n_server;
- if (public_servers_selected) {
- QVector<server_type> f_server_list = ao_app->get_server_list();
+ if (n_server < 0) return;
- if (n_server >= f_server_list.size())
- return;
+ QVector<server_type> f_server_list = ao_app->get_server_list();
- f_server = f_server_list.at(n_server);
- }
- else {
- if (n_server >= ao_app->get_favorite_list().size())
- return;
-
- f_server = ao_app->get_favorite_list().at(n_server);
- }
+ if (n_server >= f_server_list.size()) return;
- set_server_description(f_server.desc);
+ f_server = f_server_list.at(n_server);
- ui_description->moveCursor(QTextCursor::Start);
- ui_description->ensureCursorVisible();
+ set_server_description(f_server.desc);
- ui_player_count->setText(tr("Offline"));
+ ui_server_description_text->moveCursor(QTextCursor::Start);
+ ui_server_description_text->ensureCursorVisible();
+ ui_server_player_count_lbl->setText(tr("Connecting..."));
- ui_connect->setEnabled(false);
+ ui_connect_button->setEnabled(false);
- if (f_server.port == 99999 && f_server.ip == "127.0.0.1") {
- // Demo playback server selected
- ao_app->demo_server->start_server();
- server_type demo_server;
- demo_server.ip = "127.0.0.1";
- demo_server.port = ao_app->demo_server->port;
- ao_app->net_manager->connect_to_server(demo_server);
- }
- else ao_app->net_manager->connect_to_server(f_server);
- }
+ net_manager->connect_to_server(f_server);
}
// doubleclicked on an item in the serverlist so we'll connect right away
-void Lobby::on_server_list_doubleclicked(QTreeWidgetItem *p_item, int column)
+void Lobby::on_list_doubleclicked(QTreeWidgetItem *p_item, int column)
{
- doubleclicked = true;
- on_server_list_clicked(p_item, column);
- //on_connect_released();
+ Q_UNUSED(p_item)
+ Q_UNUSED(column)
+ ui_server_player_count_lbl->setText(tr("Joining Server..."));
+ net_manager->join_to_server();
}
-void Lobby::on_server_list_context_menu_requested(const QPoint &point)
+void Lobby::on_favorite_tree_clicked(QTreeWidgetItem *p_item, int column)
{
- if (public_servers_selected) {
- return;
- }
+ column = 0;
+ server_type f_server;
+ int n_server = p_item->text(column).toInt();
- auto *item = ui_server_list->itemAt(point);
- if (item == nullptr) {
- qInfo() << "no favorite server item; skipping context menu";
- return;
- }
- const int server_index = item->data(0, Qt::DisplayRole).toInt();
- if (server_index == 0) {
- qInfo() << "demo server has no context menu to display";
+ if (n_server == last_index) {
return;
}
+ last_index = n_server;
- auto *menu = new QMenu(this);
- menu->addAction(tr("Remove"), ao_app, [this,server_index](){
- ao_app->remove_favorite_server(server_index);
- list_favorites();
- });
- menu->popup(ui_server_list->mapToGlobal(point));
+ if (n_server < 0) return;
+
+ ui_add_server_button->setEnabled(true);
+ ui_edit_favorite_button->setEnabled(true);
+ ui_remove_from_favorites_button->setEnabled(true);
+
+ QVector<server_type> f_server_list = Options::getInstance().favorites();
+
+ if (n_server >= f_server_list.size()) return;
+
+ f_server = f_server_list.at(n_server);
+
+ set_server_description(f_server.desc);
+ ui_server_description_text->moveCursor(QTextCursor::Start);
+ ui_server_description_text->ensureCursorVisible();
+ ui_server_player_count_lbl->setText(tr("Connecting..."));
+
+ ui_connect_button->setEnabled(false);
+
+ net_manager->connect_to_server(f_server);
}
void Lobby::on_server_search_edited(QString p_text)
{
// Iterate through all QTreeWidgetItem items
- QTreeWidgetItemIterator it(ui_server_list);
+ QTreeWidgetItemIterator it(ui_serverlist_tree);
while (*it) {
(*it)->setHidden(p_text != "");
++it;
@@ -553,8 +405,9 @@ void Lobby::on_server_search_edited(QString p_text)
if (p_text != "") {
// Search in metadata
- QList<QTreeWidgetItem *> clist = ui_server_list->findItems(
- ui_server_search->text(), Qt::MatchContains | Qt::MatchRecursive, 1);
+ QList<QTreeWidgetItem *> clist = ui_serverlist_tree->findItems(
+ ui_serverlist_search->text(), Qt::MatchContains | Qt::MatchRecursive,
+ 1);
foreach (QTreeWidgetItem *item, clist) {
if (item->parent() != nullptr) // So the category shows up too
item->parent()->setHidden(false);
@@ -563,98 +416,137 @@ void Lobby::on_server_search_edited(QString p_text)
}
}
-void Lobby::list_servers()
+void Lobby::on_demo_clicked(QTreeWidgetItem *item, int column)
{
- if (!public_servers_selected) {
+ Q_UNUSED(column)
+
+ if (item == nullptr) {
return;
}
- ui_favorites->set_image("favorites");
- ui_public_servers->set_image("publicservers_selected");
- ui_server_list->setSortingEnabled(false);
- ui_server_list->clear();
+ QString l_filepath = (QApplication::applicationDirPath() + "/logs/%1/%2")
+ .arg(item->data(0, Qt::DisplayRole).toString(),
+ item->data(1, Qt::DisplayRole).toString());
+ ao_app->demo_server->start_server();
+ server_type demo_server;
+ demo_server.ip = "127.0.0.1";
+ demo_server.port = ao_app->demo_server->port;
+ ao_app->demo_server->set_demo_file(l_filepath);
+ net_manager->connect_to_server(demo_server);
+}
+
+void Lobby::onReloadThemeRequested()
+{
+ // This is destructive to the active widget data.
+ // Whatever, this is lobby. Nothing here is worth saving.
+ delete centralWidget();
+ loadUI();
+ COMBO_RELOAD()
+}
+
+void Lobby::onSettingsRequested()
+{
+ AOOptionsDialog options(nullptr, ao_app);
+ connect(&options, &AOOptionsDialog::reloadThemeRequest, this,
+ &Lobby::onReloadThemeRequested);
+ options.exec();
+}
+
+void Lobby::list_servers()
+{
+ ui_serverlist_tree->setSortingEnabled(false);
+ ui_serverlist_tree->clear();
- ui_server_search->setText("");
+ ui_serverlist_search->setText("");
int i = 0;
for (const server_type &i_server : qAsConst(ao_app->get_server_list())) {
- QTreeWidgetItem *treeItem = new QTreeWidgetItem(ui_server_list);
+ QTreeWidgetItem *treeItem = new QTreeWidgetItem(ui_serverlist_tree);
treeItem->setData(0, Qt::DisplayRole, i);
treeItem->setText(1, i_server.name);
i++;
}
- ui_server_list->setSortingEnabled(true);
- ui_server_list->sortItems(0, Qt::SortOrder::AscendingOrder);
+ ui_serverlist_tree->setSortingEnabled(true);
+ ui_serverlist_tree->sortItems(0, Qt::SortOrder::AscendingOrder);
+ ui_serverlist_tree->resizeColumnToContents(0);
}
void Lobby::list_favorites()
{
- if (public_servers_selected) {
- return;
- }
- ui_server_list->setSortingEnabled(false);
- ui_server_list->clear();
+ ui_favorites_tree->setSortingEnabled(false);
+ ui_favorites_tree->clear();
int i = 0;
- for (const server_type &i_server : qAsConst(ao_app->get_favorite_list())) {
- QTreeWidgetItem *treeItem = new QTreeWidgetItem(ui_server_list);
+ for (const server_type &i_server : Options::getInstance().favorites()) {
+ QTreeWidgetItem *treeItem = new QTreeWidgetItem(ui_favorites_tree);
treeItem->setData(0, Qt::DisplayRole, i);
treeItem->setText(1, i_server.name);
- // treeItem->setText(2, "-");
i++;
}
- ui_server_list->setSortingEnabled(true);
+ ui_favorites_tree->setSortingEnabled(true);
+ ui_favorites_tree->sortItems(0, Qt::SortOrder::AscendingOrder);
+ ui_favorites_tree->resizeColumnToContents(0);
}
-void Lobby::get_motd()
+void Lobby::list_demos()
{
- ao_app->net_manager->request_document(MSDocumentType::Motd,
- [this](QString document) {
- if (document.isEmpty()) {
- document = tr("Couldn't get the message of the day.");
+ ui_demo_tree->setSortingEnabled(false);
+ ui_demo_tree->clear();
+
+ QMultiMap<QString, QString> m_demo_entries = ao_app->load_demo_logs_list();
+ for (auto &l_key : m_demo_entries.uniqueKeys()) {
+ for (const QString &l_entry : m_demo_entries.values(l_key)) {
+ QTreeWidgetItem *treeItem = new QTreeWidgetItem(ui_demo_tree);
+ treeItem->setData(0, Qt::DisplayRole, l_key);
+ treeItem->setData(1, Qt::DisplayRole, l_entry);
}
- ui_chatbox->setHtml(document);
- });
+ }
+ ui_demo_tree->setSortingEnabled(true);
+ ui_demo_tree->sortItems(0, Qt::SortOrder::AscendingOrder);
+ ui_demo_tree->resizeColumnToContents(0);
}
-void Lobby::check_for_updates()
+void Lobby::get_motd()
{
- ao_app->net_manager->request_document(MSDocumentType::ClientVersion,
- [this](QString version) {
- const QString current_version = ao_app->get_version_string();
- if (!version.isEmpty() && version != current_version) {
- ui_version->setText(tr("Version: %1 (!)").arg(current_version));
- ui_version->setToolTip(tr("New version available: %1").arg(version));
+ net_manager->request_document(MSDocumentType::Motd, [this](QString document) {
+ if (document.isEmpty()) {
+ document = tr("Couldn't get the message of the day.");
}
+ ui_motd_text->setHtml(document);
});
}
-void Lobby::append_chatmessage(QString f_name, QString f_message)
-{
- ui_chatbox->append_chatmessage(
- f_name, f_message,
- ao_app->get_color("ooc_default_color", "courtroom_design.ini").name());
-}
-
-void Lobby::append_error(QString f_message)
+void Lobby::check_for_updates()
{
- ui_chatbox->append_error(f_message);
+ net_manager->request_document(
+ MSDocumentType::ClientVersion, [this](QString version) {
+ const QString current_version = ao_app->get_version_string();
+ if (!version.isEmpty() && version != current_version) {
+ ui_game_version_lbl->setText(
+ tr("Version: %1 (!)").arg(current_version));
+ ui_game_version_lbl->setToolTip(
+ tr("New version available: %1").arg(version));
+ }
+ });
}
void Lobby::set_player_count(int players_online, int max_players)
{
- QString f_string = tr("Online: %1/%2").arg(
- QString::number(players_online),
- QString::number(max_players));
- ui_player_count->setText(f_string);
+ QString f_string =
+ tr("Online: %1/%2")
+ .arg(QString::number(players_online), QString::number(max_players));
+ ui_server_player_count_lbl->setText(f_string);
}
-void Lobby::set_server_description(const QString& server_description)
+void Lobby::set_server_description(const QString &server_description)
{
- ui_description->clear();
- ui_description->append_linked(server_description);
+ ui_server_description_text->clear();
+ QString result =
+ server_description.toHtmlEscaped()
+ .replace("\n", "<br>")
+ .replace(QRegularExpression("\\b(https?://\\S+\\.\\S+)\\b"),
+ "<a href='\\1'>\\1</a>");
+ ui_server_description_text->insertHtml(result);
}
-void Lobby::enable_connect_button() { ui_connect->setEnabled(true); }
-
Lobby::~Lobby() {}
diff --git a/src/main.cpp b/src/main.cpp
index e8ffe67e..5b696fef 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -9,6 +9,7 @@
#include <QLibraryInfo>
#include <QPluginLoader>
#include <QTranslator>
+#include <QResource>
int main(int argc, char *argv[])
{
@@ -16,16 +17,21 @@ int main(int argc, char *argv[])
AOApplication main_app(argc, argv);
+ #ifdef ANDROID
+ if(QtAndroid::checkPermission("android.permission.READ_EXTERNAL_STORAGE")==QtAndroid::PermissionResult::Denied) {
+ QtAndroid::requestPermissionsSync({"android.permission.READ_EXTERNAL_STORAGE","android.permission.WRITE_EXTERNAL_STORAGE"});
+ }
+ #endif
+
AOApplication::addLibraryPath(AOApplication::applicationDirPath() + "/lib");
+ QResource::registerResource(main_app.get_asset("themes/" + Options::getInstance().theme() + ".rcc"));
QFontDatabase fontDatabase;
- QDirIterator it(main_app.get_base_path() + "fonts",
+ QDirIterator it(get_base_path() + "fonts",
QDirIterator::Subdirectories);
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 +41,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 6d01a30e..96e262a5 100644
--- a/src/networkmanager.cpp
+++ b/src/networkmanager.cpp
@@ -3,10 +3,12 @@
#include "datatypes.h"
#include "debug_functions.h"
#include "lobby.h"
+#include "options.h"
#include <QAbstractSocket>
#include <QJsonArray>
#include <QJsonDocument>
+#include <QJsonObject>
#include <QNetworkReply>
NetworkManager::NetworkManager(AOApplication *parent) : QObject(parent)
@@ -17,7 +19,7 @@ NetworkManager::NetworkManager(AOApplication *parent) : QObject(parent)
heartbeat_timer = new QTimer(this);
QString master_config =
- ao_app->configini->value("master", "").value<QString>();
+ 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 +83,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 +107,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();
@@ -192,6 +194,11 @@ void NetworkManager::connect_to_server(server_type p_server)
active_connection_type = p_server.socket_type;
}
+void NetworkManager::join_to_server()
+{
+ ship_server_packet(AOPacket("askchaa").to_string());
+}
+
void NetworkManager::disconnect_from_server()
{
if (!connected)
diff --git a/src/options.cpp b/src/options.cpp
new file mode 100644
index 00000000..4c32e963
--- /dev/null
+++ b/src/options.cpp
@@ -0,0 +1,703 @@
+#include "options.h"
+#include "file_functions.h"
+
+#include <QCoreApplication>
+#include <QDebug>
+#include <QFile>
+#include <QLocale>
+#include <QObject>
+#include <QRegularExpression>
+#include <QSize>
+
+void Options::migrateCallwords()
+{
+ // Bla bla, evil boilerplate.
+ QStringList l_callwords;
+
+ QFile l_file;
+ l_file.setFileName(get_base_path() + "callwords.ini");
+
+ if (!l_file.open(QIODevice::ReadOnly)) {
+ qWarning() << "Unable to migrate callwords : File not open.";
+ return;
+ }
+
+ QTextStream in(&l_file);
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ in.setCodec("UTF-8");
+#endif
+
+ while (!in.atEnd()) {
+ QString line = in.readLine();
+ l_callwords.append(line);
+ }
+ l_file.close();
+ l_file.remove();
+
+ setCallwords(l_callwords);
+}
+
+Options::Options()
+ : config(get_base_path() + "config.ini", QSettings::IniFormat, nullptr),
+ favorite(get_base_path() + "favorite_servers.ini", QSettings::IniFormat,
+ nullptr)
+{
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ config.setIniCodec("UTF-8");
+#endif
+ migrate();
+
+#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
+ favorite.setIniCodec("UTF-8");
+#endif
+}
+
+/*! 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(get_base_path() + "callwords.ini")) {
+ migrateCallwords();
+ }
+ if (config.contains("ooc_name")) {
+ if (username().isEmpty()) {
+ config.setValue("default_username", config.value("ooc_name"));
+ }
+ config.remove("ooc_name");
+ }
+
+ if (config.contains("casing_enabled")) {
+ config.remove("casing_enabled");
+ config.remove("casing_defence_enabled");
+ config.remove("casing_prosecution_enabled");
+ config.remove("casing_judge_enabled");
+ config.remove("casing_juror_enabled");
+ config.remove("casing_steno_enabled");
+ config.remove("casing_cm_enabled");
+ config.remove("casing_can_host_cases");
+ }
+}
+
+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<QString>();
+}
+
+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::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
+{
+ if (settingsSubTheme() == "server" && !m_server_subtheme.isEmpty()) {
+ return m_server_subtheme;
+ }
+ return settingsSubTheme();
+}
+
+QString Options::settingsSubTheme() const
+{
+ return config.value("subtheme", "server").toString();
+}
+
+void Options::setSettingsSubTheme(QString value)
+{
+ config.setValue("subtheme", value);
+}
+
+QString Options::serverSubTheme() const { return m_server_subtheme; }
+
+void Options::setServerSubTheme(QString value) { m_server_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<QStringList>();
+}
+
+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(); }
+
+QVector<server_type> Options::favorites()
+{
+ QVector<server_type> serverlist;
+
+ auto grouplist = favorite.childGroups();
+ { // remove all negative and non-numbers
+ auto filtered_grouplist = grouplist;
+ for (const QString &group : qAsConst(grouplist)) {
+ bool ok = false;
+ const int l_num = group.toInt(&ok);
+ if (ok && l_num >= 0) {
+ continue;
+ }
+ filtered_grouplist.append(group);
+ }
+ std::sort(filtered_grouplist.begin(), filtered_grouplist.end(),
+ [](const auto &a, const auto &b) -> bool {
+ return a.toInt() < b.toInt();
+ });
+ grouplist = std::move(filtered_grouplist);
+ }
+
+ for (const QString &group : qAsConst(grouplist)) {
+ server_type f_server;
+ favorite.beginGroup(group);
+ f_server.ip = favorite.value("address", "127.0.0.1").toString();
+ f_server.port = favorite.value("port", 27016).toInt();
+ f_server.name = favorite.value("name", "Missing Name").toString();
+ f_server.desc = favorite.value("desc", "No description").toString();
+ f_server.socket_type =
+ to_connection_type.value(favorite.value("protocol", "tcp").toString());
+ serverlist.append(std::move(f_server));
+ favorite.endGroup();
+ }
+
+ return serverlist;
+}
+
+void Options::setFavorites(QVector<server_type> value)
+{
+ favorite.clear();
+ for (int i = 0; i < value.size(); ++i) {
+ auto fav_server = value.at(i);
+ favorite.beginGroup(QString::number(i));
+ favorite.setValue("name", fav_server.name);
+ favorite.setValue("address", fav_server.ip);
+ favorite.setValue("port", fav_server.port);
+ favorite.setValue("desc", fav_server.desc);
+
+ if (fav_server.socket_type == TCP) {
+ favorite.setValue("protocol", "tcp");
+ }
+ else {
+ favorite.setValue("protocol", "ws");
+ }
+ favorite.endGroup();
+ }
+ favorite.sync();
+}
+
+void Options::removeFavorite(int index)
+{
+ QVector<server_type> l_favorites = favorites();
+ l_favorites.remove(index);
+ setFavorites(l_favorites);
+}
+
+void Options::addFavorite(server_type server)
+{
+ int index = favorites().size();
+ favorite.beginGroup(QString::number(index));
+ favorite.setValue("name", server.name);
+ favorite.setValue("address", server.ip);
+ favorite.setValue("port", server.port);
+ favorite.setValue("desc", server.desc);
+ if (server.socket_type == TCP) {
+ favorite.setValue("protocol", "tcp");
+ }
+ else {
+ favorite.setValue("protocol", "ws");
+ }
+ favorite.endGroup();
+ favorite.sync();
+}
+
+void Options::updateFavorite(server_type server, int index)
+{
+ favorite.beginGroup(QString::number(index));
+ favorite.setValue("name", server.name);
+ favorite.setValue("address", server.ip);
+ favorite.setValue("port", server.port);
+ favorite.setValue("desc", server.desc);
+ if (server.socket_type == TCP) {
+ favorite.setValue("protocol", "tcp");
+ }
+ else {
+ favorite.setValue("protocol", "ws");
+ }
+ favorite.endGroup();
+ favorite.sync();
+}
+
+QString Options::getUIAsset(QString f_asset_name)
+{
+ QStringList l_paths{":/base/themes/" + Options::getInstance().theme() + "/" +
+ f_asset_name};
+
+ if (subTheme() == "server") {
+ if (serverSubTheme().isEmpty()) {
+ l_paths.prepend(":/base/themes/" + theme() + "/" + serverSubTheme() +
+ "/" + f_asset_name);
+ }
+ }
+ else {
+ l_paths.prepend(":/base/themes/" + theme() + "/" + subTheme() + "/" +
+ f_asset_name);
+ }
+
+ for (const QString &l_path : qAsConst(l_paths)) {
+ if (QFile::exists(l_path)) {
+ return l_path;
+ }
+ }
+ qWarning() << "Unable to locate ui-asset" << f_asset_name << "in theme"
+ << theme() << "Defaulting to embeeded asset.";
+ return QString(":/resource/ui/" + f_asset_name);
+}
diff --git a/src/packet_distribution.cpp b/src/packet_distribution.cpp
index 9c05b65f..9bd4d8f6 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())
@@ -71,8 +72,7 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
client_id = f_contents.at(0).toInt();
server_software = f_contents.at(1);
- if (lobby_constructed)
- w_lobby->enable_connect_button();
+ net_manager->server_connected(true);
QStringList f_contents = {"AO2", get_version_string()};
send_server_packet(new AOPacket("ID", f_contents));
@@ -150,10 +150,6 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
w_lobby->set_server_description(f_contents.at(2));
}
- if (w_lobby->doubleclicked) {
- send_server_packet(new AOPacket("askchaa"));
- w_lobby->doubleclicked = false;
- }
log_to_demo = false;
}
else if (header == "SI") {
@@ -179,34 +175,39 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
courtroom_loaded = false;
int selected_server = w_lobby->get_selected_server();
-
QString server_address = "", server_name = "";
- if (w_lobby->public_servers_selected) {
- if (selected_server >= 0 && selected_server < server_list.size()) {
- auto info = server_list.at(selected_server);
- server_name = info.name;
- server_address =
- QString("%1:%2").arg(info.ip, QString::number(info.port));
- window_title = server_name;
- }
+ switch (w_lobby->pageSelected()) {
+ case 0:
+ if (selected_server >= 0 && selected_server < server_list.size()) {
+ auto info = server_list.at(selected_server);
+ server_name = info.name;
+ server_address =
+ QString("%1:%2").arg(info.ip, QString::number(info.port));
+ window_title = server_name;
+ }
+ break;
+ case 1:
+ {
+ QVector<server_type> favorite_list = Options::getInstance().favorites();
+ if (selected_server >= 0 && selected_server < favorite_list.size()) {
+ auto info = favorite_list.at(selected_server);
+ server_name = info.name;
+ server_address =
+ QString("%1:%2").arg(info.ip, QString::number(info.port));
+ window_title = server_name;
+ }
}
- else {
- if (selected_server >= 0 && selected_server < favorite_list.size()) {
- auto info = favorite_list.at(selected_server);
- server_name = info.name;
- server_address =
- QString("%1:%2").arg(info.ip, QString::number(info.port));
- window_title = server_name;
- }
+ break;
+ case 2:
+ window_title = "Local Demo Recording";
+ break;
+ default:
+ break;
}
if (courtroom_constructed)
w_courtroom->set_window_title(window_title);
- w_lobby->show_loading_overlay();
- w_lobby->set_loading_text(tr("Loading"));
- w_lobby->set_loading_value(0);
-
AOPacket *f_packet;
f_packet = new AOPacket("RC");
@@ -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(QRegularExpression("[\\\\/:*?\"<>|\']")) +
"/'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;
@@ -264,21 +265,6 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
f_char.taken = false;
w_courtroom->append_char(f_char);
-
- if (!courtroom_loaded) {
- ++loaded_chars;
- w_lobby->set_loading_text(tr("Loading chars:\n%1/%2")
- .arg(QString::number(loaded_chars))
- .arg(QString::number(char_list_size)));
-
- int total_loading_size =
- char_list_size * 2 + evidence_list_size + music_list_size;
- int loading_value = int(
- ((loaded_chars + generated_chars + loaded_music + loaded_evidence) /
- static_cast<double>(total_loading_size)) *
- 100);
- w_lobby->set_loading_value(loading_value);
- }
}
if (!courtroom_loaded)
@@ -295,11 +281,6 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
for (int n_element = 0; n_element < f_contents.size(); ++n_element) {
++loaded_music;
-
- w_lobby->set_loading_text(tr("Loading music:\n%1/%2")
- .arg(QString::number(loaded_music))
- .arg(QString::number(music_list_size)));
-
if (musics_time) {
w_courtroom->append_music(f_contents.at(n_element));
}
@@ -319,14 +300,6 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
areas++;
}
}
-
- int total_loading_size =
- char_list_size * 2 + evidence_list_size + music_list_size;
- int loading_value = int(
- ((loaded_chars + generated_chars + loaded_music + loaded_evidence) /
- static_cast<double>(total_loading_size)) *
- 100);
- w_lobby->set_loading_value(loading_value);
}
for (int area_n = 0; area_n < areas; area_n++) {
@@ -370,10 +343,6 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
if (!courtroom_constructed)
goto end;
- if (lobby_constructed)
- w_courtroom->append_server_chatmessage(tr("[Global log]"),
- w_lobby->get_chatlog(), "0");
-
w_courtroom->character_loading_finished();
w_courtroom->done_received();
@@ -534,13 +503,6 @@ void AOApplication::server_packet_received(AOPacket *p_packet)
if (courtroom_constructed && !f_contents.isEmpty())
w_courtroom->mod_called(f_contents.at(0));
}
- else if (header == "CASEA") {
- if (courtroom_constructed && f_contents.size() >= 6)
- w_courtroom->case_called(f_contents.at(0), f_contents.at(1) == "1",
- f_contents.at(2) == "1", f_contents.at(3) == "1",
- f_contents.at(4) == "1",
- f_contents.at(5) == "1");
- }
else if (header == "TI") { // Timer packet
if (!courtroom_constructed || f_contents.size() < 2)
goto end;
@@ -603,14 +565,15 @@ 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>();
- if (p_st.toLower() != "server")
+ if (Options::getInstance().settingsSubTheme().toLower() != "server")
// We don't. Simply acknowledge the subtheme sent by the server, but don't do anything else.
return;
// Reload theme request
- if (f_contents.size() > 1 && f_contents.at(1) == "1")
+ if (f_contents.size() > 1 && f_contents.at(1) == "1") {
+ Options::getInstance().setServerSubTheme(subtheme);
w_courtroom->on_reload_theme_clicked();
+ }
}
// Auth packet
else if (header == "AUTH") {
diff --git a/src/path_functions.cpp b/src/path_functions.cpp
index 2128ad93..df76383d 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 <QDir>
#include <QRegularExpression>
@@ -28,31 +29,10 @@ static bool is_power_2(unsigned int n) {
return r == 1;
}
-QString AOApplication::get_base_path()
-{
- QString base_path = "";
-#ifdef ANDROID
- QString sdcard_storage = getenv("SECONDARY_STORAGE");
- if (dir_exists(sdcard_storage + "/base/")) {
- base_path = sdcard_storage + "/base/";
- }
- else {
- QString external_storage = getenv("EXTERNAL_STORAGE");
- base_path = external_storage + "/base/";
- }
-#elif defined(__APPLE__)
- base_path = applicationDirPath() + "/../../../base/";
-#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 +260,9 @@ QString AOApplication::get_sfx(QString p_sfx, QString p_misc, QString p_characte
{
QVector<VPath> 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 +326,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 f3dc0cb9..8aba93fd 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<QString>();
- 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<QString>();
- 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", 1000).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<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_log_newline()
-{
- QString result = configini->value("log_newline", "false").value<QString>();
- 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<QString>();
- return result.startsWith("true");
-}
-
-QString AOApplication::get_log_timestamp_format()
-{
- QString result = configini->value("log_timestamp_format", "h:mm:ss AP").value<QString>();
- return result;
-}
-
-bool AOApplication::get_log_ic_actions()
-{
- QString result =
- configini->value("log_ic_actions", "true").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_showname_enabled_by_default()
-{
- QString result =
- configini->value("show_custom_shownames", "true").value<QString>();
- return result.startsWith("true");
-}
-
-QString AOApplication::get_default_username()
-{
- QString result = configini->value("default_username", "").value<QString>();
- if (result.isEmpty())
- return get_ooc_name();
- else
- return result;
-}
-
-QString AOApplication::get_default_showname()
-{
- QString result = configini->value("default_showname", "").value<QString>();
- return result;
-}
-
-QString AOApplication::get_audio_output_device()
-{
- QString result =
- configini->value("default_audio_device", "default").value<QString>();
- 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)
{
@@ -202,6 +61,7 @@ bool AOApplication::write_to_file(QString p_text, QString p_file, bool make_dir)
if (f_log.open(QIODevice::WriteOnly | QIODevice::Text |
QIODevice::Truncate)) {
QTextStream out(&f_log);
+
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
out.setCodec("UTF-8");
#endif
@@ -233,6 +93,7 @@ bool AOApplication::append_to_file(QString p_text, QString p_file,
QFile f_log(p_file);
if (f_log.open(QIODevice::WriteOnly | QIODevice::Append)) {
QTextStream out(&f_log);
+
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
out.setCodec("UTF-8");
#endif
@@ -245,101 +106,23 @@ bool AOApplication::append_to_file(QString p_text, QString p_file,
return false;
}
-QVector<server_type> AOApplication::read_favorite_servers()
+QMultiMap<QString, QString> AOApplication::load_demo_logs_list() const
{
- QVector<server_type> serverlist;
-
- // demo server is always at the top
- server_type demo_server;
- demo_server.ip = "127.0.0.1";
- demo_server.port = 99999;
- demo_server.name = tr("Demo playback");
- demo_server.desc = tr("Play back demos you have previously recorded");
- serverlist.append(demo_server);
-
- QString fav_servers_ini_path(get_base_path() + "favorite_servers.ini");
- if (!QFile::exists(fav_servers_ini_path)) {
- qWarning() << "failed to locate favorite_servers.ini, falling back to legacy serverlist.txt";
- serverlist += read_legacy_favorite_servers();
- }
- else {
- QSettings fav_servers_ini(fav_servers_ini_path, QSettings::IniFormat);
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- fav_servers_ini.setIniCodec("UTF-8");
-#endif
+ QString l_log_path = applicationDirPath() + "/logs/";
+ QDir l_log_folder(l_log_path);
+ l_log_folder.setFilter(QDir::NoDotAndDotDot | QDir::Dirs);
- auto grouplist = fav_servers_ini.childGroups();
- { // remove all negative and non-numbers
- auto filtered_grouplist = grouplist;
- for (const QString &group : qAsConst(grouplist)) {
- bool ok = false;
- const int l_num = group.toInt(&ok);
- if (ok && l_num >= 0) {
- continue;
- }
- filtered_grouplist.append(group);
- }
- std::sort(filtered_grouplist.begin(), filtered_grouplist.end(), [](const auto &a, const auto &b) -> bool {
- return a.toInt() < b.toInt();
- });
- grouplist = std::move(filtered_grouplist);
- }
+ QMultiMap<QString,QString> l_demo_logs;
+ for (const QString &l_demo_folder_name : l_log_folder.entryList()) {
+ QDir l_demo_folder(l_log_path + l_demo_folder_name);
+ l_demo_folder.setFilter(QDir::Files);
+ l_demo_folder.setNameFilters(QStringList() << "*.demo");
- for(const QString &group: qAsConst(grouplist)) {
- server_type f_server;
- fav_servers_ini.beginGroup(group);
- f_server.ip = fav_servers_ini.value("address", "127.0.0.1").toString();
- f_server.port = fav_servers_ini.value("port", 27016).toInt();
- f_server.name = fav_servers_ini.value("name", "Missing Name").toString();
- f_server.desc = fav_servers_ini.value("desc", "No description").toString();
- f_server.socket_type = to_connection_type.value(fav_servers_ini.value("protocol", "tcp").toString());
- serverlist.append(std::move(f_server));
- fav_servers_ini.endGroup();
- }
- }
-
- return serverlist;
-}
-
-QVector<server_type> AOApplication::read_legacy_favorite_servers()
-{
- QVector<server_type> serverlist;
-
- QFile serverlist_txt(get_base_path() + "serverlist.txt");
- if (!serverlist_txt.exists()) {
- qWarning() << "serverlist.txt does not exist";
- } else if (!serverlist_txt.open(QIODevice::ReadOnly)) {
- qWarning() << "failed to open serverlist.txt";
- } else {
- QTextStream stream(&serverlist_txt);
-#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
- stream.setCodec("UTF-8");
-#endif
-
- while (!stream.atEnd())
- {
- QStringList contents = stream.readLine().split(":");
-
- int item_count = contents.size();
- if (item_count < 3 || item_count > 4) {
- continue;
- }
-
- server_type server;
- server.ip = contents.at(0);
- server.port = contents.at(1).toInt();
- server.name = contents.at(2);
- if (item_count == 4) {
- server.socket_type = connection_type(contents.at(3).toInt());
- } else {
- server.socket_type = TCP;
- }
- serverlist.append(std::move(server));
+ for (QString l_demo_name : l_demo_folder.entryList()) {
+ l_demo_logs.insert(l_demo_folder_name, l_demo_name);
+ }
}
- serverlist_txt.close();
- }
-
- return serverlist;
+ return l_demo_logs;
}
QString AOApplication::read_design_ini(QString p_identifier,
@@ -368,7 +151,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;
@@ -377,7 +160,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);
@@ -423,7 +206,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 "";
@@ -432,7 +215,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;
@@ -440,7 +223,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())
@@ -460,7 +243,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))
@@ -480,7 +263,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))
@@ -514,7 +297,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();
@@ -557,14 +340,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 "";
@@ -615,10 +398,10 @@ QString AOApplication::read_char_ini(QString p_char, QString p_search_line,
{
QSettings settings(get_real_path(get_character_path(p_char, "char.ini")),
QSettings::IniFormat);
- settings.beginGroup(target_tag);
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
settings.setIniCodec("UTF-8");
#endif
+ settings.beginGroup(target_tag);
QString value = settings.value(p_search_line).value<QString>();
settings.endGroup();
return value;
@@ -629,6 +412,7 @@ void AOApplication::set_char_ini(QString p_char, QString value,
{
QSettings settings(get_real_path(get_character_path(p_char, "char.ini")),
QSettings::IniFormat);
+
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
settings.setIniCodec("UTF-8");
#endif
@@ -927,8 +711,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;
@@ -943,7 +727,6 @@ QStringList AOApplication::get_effects(QString p_char)
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
l_effects_ini.setIniCodec("UTF-8");
#endif
-
// port legacy effects
if (!l_effects_ini.contains("version/major") || l_effects_ini.value("version/major").toInt() < 2)
{
@@ -998,8 +781,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)
@@ -1014,8 +797,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) {
@@ -1060,230 +843,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<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_looping_sfx()
-{
- QString result = configini->value("looping_sfx", "true").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::objection_stop_music()
-{
- QString result =
- configini->value("objection_stop_music", "false").value<QString>();
- 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<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_desyncrhonized_logs_enabled()
-{
- QString result = configini->value("desync_logs", "true").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_discord_enabled()
-{
- QString result = configini->value("discord", "true").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_shake_enabled()
-{
- QString result = configini->value("shake", "true").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_effects_enabled()
-{
- QString result = configini->value("effects", "true").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_frame_network_enabled()
-{
- QString result = configini->value("framenetwork", "true").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_colorlog_enabled()
-{
- QString result = configini->value("colorlog", "true").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_stickysounds_enabled()
-{
- QString result = configini->value("stickysounds", "false").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_stickyeffects_enabled()
-{
- QString result = configini->value("stickyeffects", "false").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_stickypres_enabled()
-{
- QString result = configini->value("stickypres", "false").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_customchat_enabled()
-{
- QString result = configini->value("customchat", "true").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_sticker_enabled()
-{
- QString result = configini->value("sticker", "true").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_continuous_enabled()
-{
- QString result = configini->value("continuous_playback", "false").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::is_category_stop_enabled()
-{
- QString result = configini->value("category_stop", "false").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_casing_enabled()
-{
- QString result = configini->value("casing_enabled", "false").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_casing_defence_enabled()
-{
- QString result =
- configini->value("casing_defence_enabled", "false").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_casing_prosecution_enabled()
-{
- QString result =
- configini->value("casing_prosecution_enabled", "false").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_casing_judge_enabled()
-{
- QString result =
- configini->value("casing_judge_enabled", "false").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_casing_juror_enabled()
-{
- QString result =
- configini->value("casing_juror_enabled", "false").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_casing_steno_enabled()
-{
- QString result =
- configini->value("casing_steno_enabled", "false").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_casing_cm_enabled()
-{
- QString result =
- configini->value("casing_cm_enabled", "false").value<QString>();
- return result.startsWith("true");
-}
-
-QString AOApplication::get_casing_can_host_cases()
-{
- QString result =
- configini->value("casing_can_host_cases", "Turnabout Check Your Settings")
- .value<QString>();
- return result;
-}
-
-bool AOApplication::get_text_logging_enabled()
-{
- QString result =
- configini->value("automatic_logging_enabled", "true").value<QString>();
- return result.startsWith("true");
-}
-
-bool AOApplication::get_demo_logging_enabled()
-{
- QString result =
- configini->value("demo_logging_enabled", "true").value<QString>();
- return result.startsWith("true");
-}
-
-QString AOApplication::get_subtheme()
-{
- QString result =
- configini->value("subtheme", "server").value<QString>();
- // 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", "false").value<QString>();
- return result.startsWith("true");
-}
-
-QString AOApplication::get_default_scaling()
-{
- return configini->value("default_scaling", "fast").value<QString>();
-}
-
-QStringList AOApplication::get_mount_paths()
-{
- return configini->value("mount_paths").value<QStringList>();
-}
-
-bool AOApplication::get_player_count_optout()
-{
- return configini->value("player_count_optout", "false").value<QString>()
- .startsWith("true");
-}
-
-bool AOApplication::get_sfx_on_idle()
-{
- return configini->value("sfx_on_idle", "true").value<QString>()
- .startsWith("true");
-}
-
-bool AOApplication::get_evidence_double_click()
-{
- return configini->value("evidence_double_click", "false").value<QString>()
- .startsWith("true");
-}
diff --git a/src/widgets/add_server_dialog.cpp b/src/widgets/add_server_dialog.cpp
new file mode 100644
index 00000000..d590d77c
--- /dev/null
+++ b/src/widgets/add_server_dialog.cpp
@@ -0,0 +1,96 @@
+#include "widgets/add_server_dialog.h"
+#include "datatypes.h"
+#include "options.h"
+
+#include <QComboBox>
+#include <QDebug>
+#include <QDialogButtonBox>
+#include <QFile>
+#include <QLineEdit>
+#include <QLabel>
+#include <QPlainTextEdit>
+#include <QPushButton>
+#include <QSpinBox>
+#include <QUiLoader>
+#include <QVBoxLayout>
+
+#define FROM_UI(type, name) \
+ ; \
+ ui_##name = findChild<type *>(#name);
+
+AddServerDialog::AddServerDialog()
+{
+ QUiLoader l_loader(this);
+ QFile l_uiFile(Options::getInstance().getUIAsset(DEFAULT_UI));
+
+ if (!l_uiFile.open(QFile::ReadOnly)) {
+ qCritical() << "Unable to open file " << l_uiFile.fileName();
+ return;
+ }
+ ui_widget = l_loader.load(&l_uiFile, this);
+
+ auto l_layout = new QVBoxLayout(this);
+ l_layout->addWidget(ui_widget);
+
+ FROM_UI(QLineEdit, server_display_name_edit);
+ FROM_UI(QLineEdit, server_hostname_edit);
+ FROM_UI(QSpinBox, server_port_box);
+ FROM_UI(QComboBox, server_protocol_box);
+ FROM_UI(QPlainTextEdit, server_description_edit);
+ FROM_UI(QDialogButtonBox, server_dialog_button);
+ connect(ui_server_dialog_button, &QDialogButtonBox::accepted, this,
+ &::AddServerDialog::onSavePressed);
+ connect(ui_server_dialog_button, &QDialogButtonBox::rejected, this,
+ &AddServerDialog::onCancelPressed);
+
+ FROM_UI(QLabel, server_legacy_lbl);
+ FROM_UI(QLineEdit, server_legacy_edit);
+ FROM_UI(QPushButton, server_legacy_load_button);
+ connect(ui_server_legacy_load_button, &QPushButton::released, this,
+ &AddServerDialog::parseLegacyServerEntry);
+}
+
+void AddServerDialog::onSavePressed()
+{
+ server_type server;
+ server.name = ui_server_display_name_edit->text();
+ server.ip = ui_server_hostname_edit->text();
+ server.port = ui_server_port_box->value();
+ server.desc = ui_server_description_edit->toPlainText();
+ server.socket_type =
+ ui_server_protocol_box->currentIndex() == TCP_INDEX ? TCP : WEBSOCKETS;
+ Options::getInstance().addFavorite(server);
+ close();
+}
+
+void AddServerDialog::onCancelPressed()
+{
+ close();
+ deleteLater();
+}
+
+void AddServerDialog::parseLegacyServerEntry()
+{
+ QStringList l_legacy_entry = ui_server_legacy_edit->text().split(":");
+ server_type l_server_entry;
+ if (l_legacy_entry.isEmpty()) {
+ qDebug() << "Legacy entry empty.";
+ return;
+ }
+
+ int l_item_count = l_legacy_entry.size();
+
+ if (l_item_count >= 3) {
+ ui_server_hostname_edit->setText(l_legacy_entry.at(0));
+ ui_server_port_box->setValue(l_legacy_entry.at(1).toInt());
+ ui_server_display_name_edit->setText(l_legacy_entry.at(2));
+ if (l_item_count >= 4) {
+ if (l_legacy_entry.at(3) == "ws") {
+ ui_server_protocol_box->setCurrentIndex(1);
+ }
+ else {
+ ui_server_protocol_box->setCurrentIndex(0);
+ }
+ }
+ }
+}
diff --git a/src/widgets/aooptionsdialog.cpp b/src/widgets/aooptionsdialog.cpp
new file mode 100644
index 00000000..8b7befe9
--- /dev/null
+++ b/src/widgets/aooptionsdialog.cpp
@@ -0,0 +1,648 @@
+#include "widgets/aooptionsdialog.h"
+#include "QDesktopServices"
+#include "aoapplication.h"
+#include "bass.h"
+#include "file_functions.h"
+#include "networkmanager.h"
+#include "options.h"
+
+#include <QCheckBox>
+#include <QCollator>
+#include <QComboBox>
+#include <QDialogButtonBox>
+#include <QGroupBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPlainTextEdit>
+#include <QPushButton>
+#include <QResource>
+#include <QSpinBox>
+#include <QUiLoader>
+#include <QVBoxLayout>
+
+#define FROM_UI(type, name) \
+ ; \
+ ui_##name = findChild<type *>(#name);
+
+AOOptionsDialog::AOOptionsDialog(QDialog *parent, AOApplication *p_ao_app)
+ : QDialog(parent)
+{
+ ao_app = p_ao_app;
+ setupUI();
+}
+
+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 <typename T, typename V>
+void AOOptionsDialog::registerOption(const QString &widgetName,
+ V (Options::*getter)() const,
+ void (Options::*setter)(V))
+{
+ auto *widget = findChild<T *>(widgetName);
+ if (!widget) {
+ qWarning() << "could not find widget" << widgetName;
+ return;
+ }
+
+ OptionEntry entry;
+ entry.load = [=] {
+ setWidgetData<T, V>(widget, (Options::getInstance().*getter)());
+ };
+ entry.save = [=] {
+ (Options::getInstance().*setter)(widgetData<T, V>(widget));
+ };
+
+ optionEntries.append(entry);
+}
+
+void AOOptionsDialog::updateValues()
+{
+ QSet<QString> themes;
+ QStringList bases = Options::getInstance().mountPaths();
+ bases.push_front(get_base_path());
+
+ for (const QString &base : bases) {
+ QStringList l_themes =
+ QDir(base + "themes").entryList(QDir::Dirs | QDir::NoDotAndDotDot);
+
+ // Resorts list to match numeric sorting found in Windows.
+ QCollator l_sorting;
+ l_sorting.setNumericMode(true);
+ std::sort(l_themes.begin(), l_themes.end(), l_sorting);
+
+ for (const QString &l_theme : qAsConst(l_themes)) {
+ if (!themes.contains(l_theme)) {
+ ui_theme_combobox->addItem(l_theme);
+ themes.insert(l_theme);
+ }
+ }
+ }
+
+ QStringList l_subthemes =
+ QDir(ao_app->get_real_path(ao_app->get_theme_path("")))
+ .entryList(QDir::Dirs | QDir::NoDotAndDotDot);
+ for (const QString &l_subtheme : qAsConst(l_subthemes)) {
+ if (l_subtheme.toLower() != "server" && l_subtheme.toLower() != "default" &&
+ l_subtheme.toLower() != "effects" && l_subtheme.toLower() != "misc") {
+ ui_subtheme_combobox->addItem(l_subtheme);
+ }
+ }
+
+ 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);
+ });
+
+ for (const OptionEntry &entry : qAsConst(optionEntries)) {
+ entry.load();
+ }
+}
+
+void AOOptionsDialog::savePressed()
+{
+ bool l_reload_theme_required = (ui_theme_combobox->currentText() != Options::getInstance().theme());
+ for (const OptionEntry &entry : qAsConst(optionEntries)) {
+ entry.save();
+ }
+
+ if (l_reload_theme_required) {
+ emit reloadThemeRequest();
+ }
+ close();
+}
+
+void AOOptionsDialog::discardPressed() { 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().setSettingsSubTheme(ui_subtheme_combobox->currentText());
+ Options::getInstance().setAnimatedThemeEnabled(
+ ui_animated_theme_cb->isChecked());
+ emit reloadThemeRequest();
+ delete layout();
+ delete ui_settings_widget;
+ optionEntries.clear();
+ setupUI();
+}
+
+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");
+
+ QStringList l_subthemes = QDir(ao_app->get_real_path(ao_app->get_theme_path(
+ "", ui_theme_combobox->itemText(i))))
+ .entryList(QDir::Dirs | QDir::NoDotAndDotDot);
+
+ for (const QString &l_subthemes : qAsConst(l_subthemes)) {
+ if (l_subthemes.toLower() != "server" &&
+ l_subthemes.toLower() != "default" &&
+ l_subthemes.toLower() != "effects" && l_subthemes.toLower() != "misc") {
+ ui_subtheme_combobox->addItem(l_subthemes);
+ }
+ }
+
+ QString l_ressource_name = Options::getInstance().theme() + ".rcc";
+ QString l_resource =
+ ao_app->get_asset("themes/" + ui_theme_combobox->currentText() + ".rcc");
+ if (l_resource.isEmpty()) {
+ QResource::unregisterResource(
+ ao_app->get_asset("themes/" + l_ressource_name));
+ qDebug() << "Unable to locate ressource file" << l_ressource_name;
+ return;
+ }
+ QResource::registerResource(l_resource);
+}
+
+void AOOptionsDialog::setupUI()
+{
+ QUiLoader l_loader(this);
+ QFile l_uiFile(Options::getInstance().getUIAsset("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)
+ connect(ui_theme_combobox,
+ QOverload<int>::of(&QComboBox::currentIndexChanged), this,
+ &AOOptionsDialog::themeChanged);
+
+ registerOption<QComboBox, QString>("theme_combobox", &Options::theme,
+ &Options::setTheme);
+
+ FROM_UI(QComboBox, subtheme_combobox)
+ registerOption<QComboBox, QString>("subtheme_combobox", &Options::settingsSubTheme,
+ &Options::setSettingsSubTheme);
+
+ 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<QCheckBox, bool>("animated_theme_cb",
+ &Options::animatedThemeEnabled,
+ &Options::setAnimatedThemeEnabled);
+ registerOption<QSpinBox, int>("stay_time_spinbox", &Options::textStayTime,
+ &Options::setTextStayTime);
+ registerOption<QCheckBox, bool>("instant_objection_cb",
+ &Options::objectionSkipQueueEnabled,
+ &Options::setObjectionSkipQueueEnabled);
+ registerOption<QSpinBox, int>("text_crawl_spinbox", &Options::textCrawlSpeed,
+ &Options::setTextCrawlSpeed);
+ registerOption<QSpinBox, int>("chat_ratelimit_spinbox",
+ &Options::chatRateLimit,
+ &Options::setChatRateLimit);
+ registerOption<QLineEdit, QString>("username_textbox", &Options::username,
+ &Options::setUsername);
+ registerOption<QCheckBox, bool>("showname_cb",
+ &Options::customShownameEnabled,
+ &Options::setCustomShownameEnabled);
+ registerOption<QLineEdit, QString>("default_showname_textbox",
+ &Options::shownameOnJoin,
+ &Options::setShownameOnJoin);
+ registerOption<QLineEdit, QString>("ms_textbox",
+ &Options::alternativeMasterserver,
+ &Options::setAlternativeMasterserver);
+ registerOption<QCheckBox, bool>("discord_cb", &Options::discordEnabled,
+ &Options::setDiscordEnabled);
+ registerOption<QComboBox, QString>("language_combobox", &Options::language,
+ &Options::setLanguage);
+ registerOption<QComboBox, QString>("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<QCheckBox, bool>("shake_cb", &Options::shakeEnabled,
+ &Options::setShakeEnabled);
+ registerOption<QCheckBox, bool>("effects_cb", &Options::effectsEnabled,
+ &Options::setEffectsEnabled);
+ registerOption<QCheckBox, bool>("framenetwork_cb",
+ &Options::networkedFrameSfxEnabled,
+ &Options::setNetworkedFrameSfxEnabled);
+ registerOption<QCheckBox, bool>("colorlog_cb", &Options::colorLogEnabled,
+ &Options::setColorLogEnabled);
+ registerOption<QCheckBox, bool>(
+ "stickysounds_cb", &Options::clearSoundsDropdownOnPlayEnabled,
+ &Options::setClearSoundsDropdownOnPlayEnabled);
+ registerOption<QCheckBox, bool>(
+ "stickyeffects_cb", &Options::clearEffectsDropdownOnPlayEnabled,
+ &Options::setClearEffectsDropdownOnPlayEnabled);
+ registerOption<QCheckBox, bool>("stickypres_cb",
+ &Options::clearPreOnPlayEnabled,
+ &Options::setClearPreOnPlayEnabled);
+ registerOption<QCheckBox, bool>("customchat_cb",
+ &Options::customChatboxEnabled,
+ &Options::setCustomChatboxEnabled);
+ registerOption<QCheckBox, bool>("sticker_cb",
+ &Options::characterStickerEnabled,
+ &Options::setCharacterStickerEnabled);
+ registerOption<QCheckBox, bool>("continuous_cb",
+ &Options::continuousPlaybackEnabled,
+ &Options::setContinuousPlaybackEnabled);
+ registerOption<QCheckBox, bool>("category_stop_cb",
+ &Options::stopMusicOnCategoryEnabled,
+ &Options::setStopMusicOnCategoryEnabled);
+ registerOption<QCheckBox, bool>("sfx_on_idle_cb",
+ &Options::playSelectedSFXOnIdle,
+ &Options::setPlaySelectedSFXOnIdle);
+ registerOption<QCheckBox, bool>("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<QPlainTextEdit, QStringList>(
+ "callwords_textbox", &Options::callwords, &Options::setCallwords);
+
+ // Audio tab.
+ FROM_UI(QComboBox, audio_device_combobox)
+ populateAudioDevices();
+ registerOption<QComboBox, QString>("audio_device_combobox",
+ &Options::audioOutputDevice,
+ &Options::setAudioOutputDevice);
+
+ 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<QSpinBox, int>("suppress_audio_spinbox",
+ &::Options::defaultSuppressAudio,
+ &Options::setDefaultSupressedAudio);
+ registerOption<QSpinBox, int>("bliprate_spinbox", &::Options::blipRate,
+ &Options::setBlipRate);
+ registerOption<QCheckBox, bool>("blank_blips_cb", &Options::blankBlip,
+ &Options::setBlankBlip);
+ registerOption<QCheckBox, bool>("loopsfx_cb", &Options::loopingSfx,
+ &Options::setLoopingSfx);
+ registerOption<QCheckBox, bool>("objectmusic_cb",
+ &Options::objectionStopMusic,
+ &Options::setObjectionStopMusic);
+ registerOption<QCheckBox, bool>("disablestreams_cb",
+ &Options::streamingEnabled,
+ &Options::setStreamingEnabled);
+
+ // Asset tab
+ FROM_UI(QListWidget, mount_list)
+ auto *defaultMount =
+ new QListWidgetItem(tr("%1 (default)").arg(get_base_path()));
+ defaultMount->setFlags(Qt::ItemFlag::NoItemFlags);
+ ui_mount_list->addItem(defaultMount);
+ registerOption<QListWidget, QStringList>("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<QCheckBox, bool>("downwards_cb",
+ &Options::logDirectionDownwards,
+ &Options::setLogDirectionDownwards);
+ registerOption<QSpinBox, int>("length_spinbox", &Options::maxLogSize,
+ &Options::setMaxLogSize);
+ registerOption<QCheckBox, bool>("log_newline_cb", &Options::logNewline,
+ &Options::setLogNewline);
+ registerOption<QSpinBox, int>("log_margin_spinbox", &Options::logMargin,
+ &Options::setLogMargin);
+
+ FROM_UI(QCheckBox, log_timestamp_cb)
+ registerOption<QCheckBox, bool>("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<QComboBox, QString>("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<QCheckBox, bool>("log_ic_actions_cb", &Options::logIcActions,
+ &Options::setLogIcActions);
+ registerOption<QCheckBox, bool>("desync_logs_cb",
+ &Options::desynchronisedLogsEnabled,
+ &Options::setDesynchronisedLogsEnabled);
+ registerOption<QCheckBox, bool>("log_text_cb", &Options::logToTextFileEnabled,
+ &Options::setLogToTextFileEnabled);
+ registerOption<QCheckBox, bool>("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::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
diff --git a/src/widgets/direct_connect_dialog.cpp b/src/widgets/direct_connect_dialog.cpp
new file mode 100644
index 00000000..82eaa23a
--- /dev/null
+++ b/src/widgets/direct_connect_dialog.cpp
@@ -0,0 +1,101 @@
+#include "widgets/direct_connect_dialog.h"
+
+#include "networkmanager.h"
+#include "options.h"
+#include "debug_functions.h"
+
+#include <QComboBox>
+#include <QLabel>
+#include <QLineEdit>
+#include <QPushButton>
+#include <QSpinBox>
+#include <QUiLoader>
+#include <QVBoxLayout>
+#include <QRegularExpressionMatch>
+#include <QStringBuilder>
+#include <QUrl>
+
+#define FROM_UI(type, name) \
+ ; \
+ ui_##name = findChild<type *>(#name);
+
+DirectConnectDialog::DirectConnectDialog(NetworkManager *p_net_manager) :
+ net_manager(p_net_manager)
+{
+ QUiLoader l_loader(this);
+ QFile l_uiFile(Options::getInstance().getUIAsset(DEFAULT_UI));
+
+ if (!l_uiFile.open(QFile::ReadOnly)) {
+ qCritical() << "Unable to open file " << l_uiFile.fileName();
+ return;
+ }
+ ui_widget = l_loader.load(&l_uiFile, this);
+
+ auto l_layout = new QVBoxLayout(this);
+ l_layout->addWidget(ui_widget);
+
+ FROM_UI(QLineEdit, direct_hostname_edit)
+
+ FROM_UI(QLabel, direct_connection_status_lbl)
+
+ FROM_UI(QPushButton, direct_connect_button);
+ connect(ui_direct_connect_button, &QPushButton::pressed,
+ this, &DirectConnectDialog::onConnectPressed);
+ FROM_UI(QPushButton, direct_cancel_button);
+ connect(ui_direct_cancel_button, &QPushButton::pressed,
+ this, &DirectConnectDialog::close);
+
+ connect(net_manager, &NetworkManager::server_connected,
+ this, &DirectConnectDialog::onServerConnected);
+
+ connect(&connect_timeout, &QTimer::timeout, this,
+ &DirectConnectDialog::onConnectTimeout);
+ connect_timeout.setSingleShot(true);
+}
+
+void DirectConnectDialog::onConnectPressed()
+{
+ QString l_hostname = ui_direct_hostname_edit->text();
+ if (!SCHEME_PATTERN.match(l_hostname).hasMatch()) {
+ l_hostname = "tcp://" % l_hostname;
+ }
+ QUrl l_url(l_hostname);
+ if (!l_url.isValid()) {
+ call_error(tr("Invalid URL."));
+ return;
+ }
+ if (!to_connection_type.contains(l_url.scheme())) {
+ call_error(tr("Scheme not recognized. Must be either of the following: ") % QStringList::fromVector(to_connection_type.keys().toVector()).join(", "));
+ return;
+ }
+ if (l_url.port() == -1) {
+ call_error(tr("Invalid server port."));
+ return;
+ }
+ server_type l_server;
+ l_server.socket_type = to_connection_type[l_url.scheme()];
+ l_server.ip = l_url.host();
+ l_server.port = l_url.port();
+ l_server.name = "Direct Connection";
+
+ net_manager->connect_to_server(l_server);
+ ui_direct_connect_button->setEnabled(false);
+ ui_direct_connection_status_lbl->setText("Connecting...");
+ ui_direct_connection_status_lbl->setStyleSheet("color : rgb(0,64,156)");
+ connect_timeout.start(CONNECT_TIMEOUT);
+}
+
+void DirectConnectDialog::onServerConnected()
+{
+ net_manager->join_to_server();
+ ui_direct_connection_status_lbl->setText("Connected!");
+ ui_direct_connection_status_lbl->setStyleSheet("color: rgb(0,128,0)");
+ close();
+}
+
+void DirectConnectDialog::onConnectTimeout()
+{
+ ui_direct_connect_button->setEnabled(true);
+ ui_direct_connection_status_lbl->setText("Connection Timeout!");
+ ui_direct_connection_status_lbl->setStyleSheet("color: rgb(255,0,0)");
+}
diff --git a/src/widgets/edit_server_dialog.cpp b/src/widgets/edit_server_dialog.cpp
new file mode 100644
index 00000000..109e968f
--- /dev/null
+++ b/src/widgets/edit_server_dialog.cpp
@@ -0,0 +1,87 @@
+#include "widgets/edit_server_dialog.h"
+#include "datatypes.h"
+#include "options.h"
+
+#include <QComboBox>
+#include <QDebug>
+#include <QDialogButtonBox>
+#include <QFile>
+#include <QLineEdit>
+#include <QLabel>
+#include <QPlainTextEdit>
+#include <QPushButton>
+#include <QSpinBox>
+#include <QUiLoader>
+#include <QVBoxLayout>
+
+#define FROM_UI(type, name) \
+ ; \
+ ui_##name = findChild<type *>(#name);
+
+EditServerDialog::EditServerDialog(int index) :
+ index(index) // lol
+{
+ QUiLoader l_loader(this);
+ QFile l_uiFile(Options::getInstance().getUIAsset(DEFAULT_UI));
+
+ if (!l_uiFile.open(QFile::ReadOnly)) {
+ qCritical() << "Unable to open file " << l_uiFile.fileName();
+ return;
+ }
+ ui_widget = l_loader.load(&l_uiFile, this);
+
+ auto l_layout = new QVBoxLayout(this);
+ l_layout->addWidget(ui_widget);
+
+ FROM_UI(QLineEdit, server_display_name_edit);
+ FROM_UI(QLineEdit, server_hostname_edit);
+ FROM_UI(QSpinBox, server_port_box);
+ FROM_UI(QComboBox, server_protocol_box);
+ FROM_UI(QPlainTextEdit, server_description_edit);
+ FROM_UI(QDialogButtonBox, server_dialog_button);
+ connect(ui_server_dialog_button, &QDialogButtonBox::accepted, this,
+ &::EditServerDialog::onSavePressed);
+ connect(ui_server_dialog_button, &QDialogButtonBox::rejected, this,
+ &EditServerDialog::onCancelPressed);
+
+ // We don't need you.
+ FROM_UI(QLabel, server_legacy_lbl);
+ FROM_UI(QLineEdit, server_legacy_edit);
+ FROM_UI(QPushButton, server_legacy_load_button);
+
+ ui_server_legacy_lbl->setVisible(false);
+ ui_server_legacy_edit->setVisible(false);
+ ui_server_legacy_load_button->setVisible(false);
+
+ loadEntry();
+}
+
+void EditServerDialog::loadEntry()
+{
+ server_type server = Options::getInstance().favorites().at(index);
+ ui_server_display_name_edit->setText(server.name);
+ ui_server_hostname_edit->setText(server.ip);
+ ui_server_port_box->setValue(server.port);
+ ui_server_description_edit->setPlainText(server.desc);
+ ui_server_protocol_box->setCurrentIndex(server.socket_type);
+}
+
+void EditServerDialog::onSavePressed()
+{
+ server_type server;
+ server.name = ui_server_display_name_edit->text();
+ server.ip = ui_server_hostname_edit->text();
+ server.port = ui_server_port_box->value();
+ server.desc = ui_server_description_edit->toPlainText();
+ server.socket_type =
+ ui_server_protocol_box->currentIndex() == TCP_INDEX ? TCP : WEBSOCKETS;
+ Options::getInstance().updateFavorite(server, index);
+ close();
+ deleteLater();
+}
+
+void EditServerDialog::onCancelPressed()
+{
+ close();
+ deleteLater();
+}