aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Attorney_Online.pro3
-rw-r--r--include/CMakeLists.txt3
-rw-r--r--include/aoapplication.h68
-rw-r--r--include/aolayer.h17
-rw-r--r--include/aolineedit.h26
-rw-r--r--include/aooptionsdialog.h18
-rw-r--r--include/aotextedit.h21
-rw-r--r--include/courtroom.h22
-rw-r--r--include/eventfilters.h36
-rw-r--r--include/lobby.h2
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/aoapplication.cpp12
-rw-r--r--src/aoblipplayer.cpp6
-rw-r--r--src/aobutton.cpp11
-rw-r--r--src/aocaseannouncerdialog.cpp8
-rw-r--r--src/aoemotebutton.cpp4
-rw-r--r--src/aoevidencebutton.cpp18
-rw-r--r--src/aoevidencedisplay.cpp5
-rw-r--r--src/aoimage.cpp17
-rw-r--r--src/aolayer.cpp139
-rw-r--r--src/aolineedit.cpp22
-rw-r--r--src/aomusicplayer.cpp6
-rw-r--r--src/aooptionsdialog.cpp216
-rw-r--r--src/aosfxplayer.cpp6
-rw-r--r--src/aotextedit.cpp17
-rw-r--r--src/charselect.cpp44
-rw-r--r--src/chatlogpiece.cpp4
-rw-r--r--src/courtroom.cpp581
-rw-r--r--src/debug_functions.cpp1
-rw-r--r--src/demoserver.cpp4
-rw-r--r--src/emotes.cpp18
-rw-r--r--src/evidence.cpp157
-rw-r--r--src/file_functions.cpp6
-rw-r--r--src/lobby.cpp60
-rw-r--r--src/networkmanager.cpp8
-rw-r--r--src/path_functions.cpp220
-rw-r--r--src/scrolltext.cpp2
-rw-r--r--src/text_file_functions.cpp77
38 files changed, 1033 insertions, 854 deletions
diff --git a/Attorney_Online.pro b/Attorney_Online.pro
index 2a5c1e14..abca0fb0 100644
--- a/Attorney_Online.pro
+++ b/Attorney_Online.pro
@@ -19,6 +19,9 @@ QMAKE_LFLAGS += -Wl,-rpath,"'\$$ORIGIN/lib'"
# Uncomment for verbose network logging
# DEFINES += DEBUG_NETWORK
+# Uncomment for verbose animation logging
+# DEFINES += DEBUG_MOVIE
+
# Uncomment for building with debug symbols
# CONFIG += debug
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index 18cf23ba..e74a49bf 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -10,13 +10,11 @@ aoevidencebutton.h
aoevidencedisplay.h
aoimage.h
aolayer.h
-aolineedit.h
aomusicplayer.h
aooptionsdialog.h
aopacket.h
aosfxplayer.h
aotextarea.h
-aotextedit.h
bass.h
bassopus.h
chatlogpiece.h
@@ -28,6 +26,7 @@ discord-rpc.h
discord_register.h
discord_rich_presence.h
discord_rpc.h
+eventfilters.h
file_functions.h
hardware_functions.h
lobby.h
diff --git a/include/aoapplication.h b/include/aoapplication.h
index 1cdcbc54..d8d3c9a1 100644
--- a/include/aoapplication.h
+++ b/include/aoapplication.h
@@ -1,8 +1,6 @@
#ifndef AOAPPLICATION_H
#define AOAPPLICATION_H
-#define UNUSED(x) (void)(x)
-
#include "aopacket.h"
#include "datatypes.h"
#include "demoserver.h"
@@ -37,6 +35,25 @@ class NetworkManager;
class Lobby;
class Courtroom;
+class VPath : QString {
+ using QString::QString;
+
+public:
+ explicit VPath(const QString &str) : QString(str) {}
+ inline QString const &toQString() const { return *this; }
+ inline bool operator==(const VPath &str) const {
+ return this->toQString() == str.toQString();
+ }
+ inline VPath operator+(const VPath &str) const {
+ return VPath(this->toQString() + str.toQString());
+ }
+};
+
+inline uint qHash(const VPath &key, uint seed = qGlobalQHashSeed())
+{
+ return qHash(key.toQString(), seed);
+}
+
class AOApplication : public QApplication {
Q_OBJECT
@@ -129,24 +146,26 @@ public:
// implementation in path_functions.cpp
QString get_base_path();
- QString get_data_path();
- QString get_theme_path(QString p_file, QString p_theme="");
- QString get_character_path(QString p_char, QString p_file);
- QString get_misc_path(QString p_misc, QString p_file);
- QString get_sounds_path(QString p_file);
- QString get_music_path(QString p_song);
- QString get_background_path(QString p_file);
- QString get_default_background_path(QString p_file);
- QString get_evidence_path(QString p_file);
- QStringList get_asset_paths(QString p_element, QString p_theme="", QString p_subtheme="", QString p_default_theme="", QString p_misc="", QString p_character="", QString p_placeholder="");
- QString get_asset_path(QStringList pathlist);
- QString get_image_path(QStringList pathlist, bool static_image=false);
- QString get_sfx_path(QStringList pathlist);
+ VPath get_theme_path(QString p_file, QString p_theme="");
+ VPath get_character_path(QString p_char, QString p_file);
+ VPath get_misc_path(QString p_misc, QString p_file);
+ VPath get_sounds_path(QString p_file);
+ VPath get_music_path(QString p_song);
+ VPath get_background_path(QString p_file);
+ VPath get_default_background_path(QString p_file);
+ VPath get_evidence_path(QString p_file);
+ QVector<VPath> get_asset_paths(QString p_element, QString p_theme="", QString p_subtheme="", QString p_default_theme="", QString p_misc="", QString p_character="", QString p_placeholder="");
+ QString get_asset_path(QVector<VPath> pathlist);
+ QString get_image_path(QVector<VPath> pathlist, bool static_image=false);
+ QString get_sfx_path(QVector<VPath> pathlist);
QString get_config_value(QString p_identifier, QString p_config, QString p_theme="", QString p_subtheme="", QString p_default_theme="", QString p_misc="");
QString get_asset(QString p_element, QString p_theme="", QString p_subtheme="", QString p_default_theme="", QString p_misc="", QString p_character="", QString p_placeholder="");
- QString get_image(QString p_element, QString p_theme="", QString p_subtheme="", QString p_default_theme="", QString p_misc="", QString p_character="", QString p_placeholder="");
+ QString get_image(QString p_element, QString p_theme="", QString p_subtheme="", QString p_default_theme="", QString p_misc="", QString p_character="", QString p_placeholder="", bool static_image=false);
QString get_sfx(QString p_sfx, QString p_misc="", QString p_character="");
QString get_case_sensitive_path(QString p_file);
+ QString get_real_path(const VPath &vpath);
+ QString get_real_suffixed_path(const VPath &vpath, const QStringList &suffixes);
+ void invalidate_lookup_cache();
////// Functions for reading and writing files //////
// Implementations file_functions.cpp
@@ -265,6 +284,9 @@ public:
// Returns whether the log should have a timestamp.
bool get_log_timestamp();
+ // Returns the format string for the log timestamp
+ QString get_log_timestamp_format();
+
// Returns whether to log IC actions.
bool get_log_ic_actions();
@@ -284,6 +306,7 @@ public:
QStringList get_call_words();
// returns all of the file's lines in a QStringList
+ QStringList get_list_file(VPath path);
QStringList get_list_file(QString p_file);
// Process a file and return its text as a QString
@@ -307,6 +330,7 @@ public:
QVector<server_type> read_serverlist_txt();
// Returns the value of p_identifier in the design.ini file in p_design_path
+ QString read_design_ini(QString p_identifier, VPath p_design_path);
QString read_design_ini(QString p_identifier, QString p_design_path);
// Returns the coordinates of widget with p_identifier from p_file
@@ -336,18 +360,18 @@ public:
QString get_court_sfx(QString p_identifier, QString p_misc="");
// Figure out if we can opus this or if we should fall back to wav
- QString get_sfx_suffix(QString sound_to_check);
+ QString get_sfx_suffix(VPath sound_to_check);
// Can we use APNG for this? If not, WEBP? If not, GIF? If not, fall back to
// PNG.
- QString get_image_suffix(QString path_to_check, bool static_image=false);
+ QString get_image_suffix(VPath path_to_check, bool static_image=false);
// Returns the value of p_search_line within target_tag and terminator_tag
QString read_char_ini(QString p_char, QString p_search_line,
QString target_tag);
// Returns a QStringList of all key=value definitions on a given tag.
- QStringList read_ini_tags(QString p_file, QString target_tag = "");
+ QStringList read_ini_tags(VPath p_file, QString target_tag = "");
// Sets the char.ini p_search_line key under tag target_tag to value.
void set_char_ini(QString p_char, QString value, QString p_search_line,
@@ -491,6 +515,9 @@ public:
// Get the default scaling method
QString get_default_scaling();
+ // Get a list of custom mount paths
+ QStringList get_mount_paths();
+
// Get whether to opt out of player count metrics sent to the master server
bool get_player_count_optout();
@@ -529,6 +556,9 @@ private:
QVector<server_type> server_list;
QVector<server_type> favorite_list;
+ QHash<uint, QString> asset_lookup_cache;
+ QHash<uint, QString> dir_listing_cache;
+ QSet<uint> dir_listing_exist_cache;
public slots:
void server_disconnected();
diff --git a/include/aolayer.h b/include/aolayer.h
index f3ecebfb..b8907152 100644
--- a/include/aolayer.h
+++ b/include/aolayer.h
@@ -7,8 +7,12 @@
#include <QLabel>
#include <QTimer>
#include <QBitmap>
+#include <QtConcurrent/QtConcurrentRun>
+#include <QMutex>
+#include <QWaitCondition>
class AOApplication;
+class VPath;
// "Brief" explanation of what the hell this is:
//
@@ -138,6 +142,18 @@ protected:
// Center the QLabel in the viewport based on the dimensions of f_pixmap
void center_pixmap(QPixmap f_pixmap);
+private:
+ // Populates the frame and delay vectors.
+ void populate_vectors();
+
+ // used in populate_vectors
+ void load_next_frame();
+ bool exit_loop; //awful solution but i'm not fucking using QThread
+ QFuture<void> frame_loader;
+ QMutex mutex;
+ QWaitCondition frameAdded;
+
+
signals:
void done();
@@ -235,4 +251,5 @@ public:
StickerLayer(QWidget *p_parent, AOApplication *p_ao_app);
void load_image(QString p_charname);
};
+
#endif // AOLAYER_H
diff --git a/include/aolineedit.h b/include/aolineedit.h
deleted file mode 100644
index 5dce3aaa..00000000
--- a/include/aolineedit.h
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef AOLINEEDIT_H
-#define AOLINEEDIT_H
-
-#include <QLineEdit>
-#include <QMouseEvent>
-
-class AOLineEdit : public QLineEdit {
- Q_OBJECT
-
-public:
- AOLineEdit(QWidget *parent);
-
- void preserve_selection(bool toggle) { p_selection = toggle; }
-
-private:
- bool p_selection = false;
-
-protected:
- void mouseDoubleClickEvent(QMouseEvent *e);
- void focusOutEvent(QFocusEvent *ev);
-
-signals:
- void double_clicked();
-};
-
-#endif // AOLINEEDIT_H
diff --git a/include/aooptionsdialog.h b/include/aooptionsdialog.h
index d8ef49f5..84a96484 100644
--- a/include/aooptionsdialog.h
+++ b/include/aooptionsdialog.h
@@ -23,6 +23,7 @@
#include <QtWidgets/QWidget>
#include <QDirIterator>
+#include <QListWidget>
#include <QTextBrowser>
#include <QTextStream>
@@ -62,6 +63,8 @@ private:
QSpinBox *ui_log_margin_spinbox;
QLabel *ui_log_timestamp_lbl;
QCheckBox *ui_log_timestamp_cb;
+ QLabel *ui_log_timestamp_format_lbl;
+ QComboBox *ui_log_timestamp_format_combobox;
QLabel *ui_stay_time_lbl;
QSpinBox *ui_stay_time_spinbox;
QLabel *ui_desync_logs_lbl;
@@ -175,12 +178,25 @@ private:
QLabel *ui_log_lbl;
QCheckBox *ui_log_cb;
+ QWidget *ui_assets_tab;
+ QVBoxLayout *ui_assets_tab_layout;
+ QGridLayout *ui_mount_buttons_layout;
+ QLabel *ui_asset_lbl;
+ QListWidget *ui_mount_list;
+ QPushButton *ui_mount_add;
+ QPushButton *ui_mount_remove;
+ QPushButton *ui_mount_up;
+ QPushButton *ui_mount_down;
+ QPushButton *ui_mount_clear_cache;
+
QWidget *ui_privacy_tab;
QVBoxLayout *ui_privacy_layout;
QCheckBox *ui_privacy_optout_cb;
QFrame *ui_privacy_separator;
QTextBrowser *ui_privacy_policy;
+ bool asset_cache_dirty = false;
+
bool needs_default_audiodev();
void update_values();
@@ -190,6 +206,8 @@ public slots:
void save_pressed();
void discard_pressed();
void button_clicked(QAbstractButton *button);
+ void on_timestamp_format_edited();
+ void timestamp_cb_changed(int state);
void on_reload_theme_clicked();
void theme_changed(int i);
};
diff --git a/include/aotextedit.h b/include/aotextedit.h
deleted file mode 100644
index 8d876f17..00000000
--- a/include/aotextedit.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef AOTEXTEDIT_H
-#define AOTEXTEDIT_H
-
-#include <QPlainTextEdit>
-
-class AOTextEdit : public QPlainTextEdit {
- Q_OBJECT
-public:
- AOTextEdit(QWidget *parent);
-
-protected:
- void mouseDoubleClickEvent(QMouseEvent *e);
-
-signals:
- void double_clicked();
-
-private slots:
- void on_enter_pressed();
-};
-
-#endif // AOTEXTEDIT_H
diff --git a/include/courtroom.h b/include/courtroom.h
index e8145140..4bc86242 100644
--- a/include/courtroom.h
+++ b/include/courtroom.h
@@ -11,13 +11,11 @@
#include "aoevidencedisplay.h"
#include "aoimage.h"
#include "aolayer.h"
-#include "aolineedit.h"
#include "aomusicplayer.h"
#include "aooptionsdialog.h"
#include "aopacket.h"
#include "aosfxplayer.h"
#include "aotextarea.h"
-#include "aotextedit.h"
#include "chatlogpiece.h"
#include "datatypes.h"
#include "debug_functions.h"
@@ -25,6 +23,7 @@
#include "hardware_functions.h"
#include "lobby.h"
#include "scrolltext.h"
+#include "eventfilters.h"
#include <QCheckBox>
#include <QCloseEvent>
@@ -417,6 +416,9 @@ private:
// True, if the log should have a timestamp.
bool log_timestamp = false;
+ // format string for aforementioned log timestamp
+ QString log_timestamp_format;
+
// How long in miliseconds should the objection wait before appearing.
int objection_threshold = 1500;
@@ -648,7 +650,8 @@ private:
QComboBox *ui_pair_order_dropdown;
- AOLineEdit *ui_ic_chat_message;
+ QLineEdit *ui_ic_chat_message;
+ AOLineEditFilter *ui_ic_chat_message_filter;
QLineEdit *ui_ic_chat_name;
QLineEdit *ui_ooc_chat_message;
@@ -730,7 +733,8 @@ private:
AOButton *ui_evidence_button;
AOImage *ui_evidence;
- AOLineEdit *ui_evidence_name;
+ QLineEdit *ui_evidence_name;
+ AOLineEditFilter *ui_evidence_name_filter;
QWidget *ui_evidence_buttons;
QVector<AOEvidenceButton *> ui_evidence_list;
AOButton *ui_evidence_left;
@@ -738,7 +742,8 @@ private:
AOButton *ui_evidence_present;
AOImage *ui_evidence_overlay;
AOButton *ui_evidence_delete;
- AOLineEdit *ui_evidence_image_name;
+ QLineEdit *ui_evidence_image_name;
+ AOLineEditFilter *ui_evidence_image_name_filter;
AOButton *ui_evidence_image_button;
AOButton *ui_evidence_x;
AOButton *ui_evidence_ok;
@@ -746,7 +751,9 @@ private:
AOButton *ui_evidence_transfer;
AOButton *ui_evidence_save;
AOButton *ui_evidence_load;
- AOTextEdit *ui_evidence_description;
+ AOButton *ui_evidence_edit;
+ QPlainTextEdit *ui_evidence_description;
+
AOImage *ui_char_select_background;
@@ -873,6 +880,7 @@ private slots:
void on_evidence_image_button_clicked();
void on_evidence_clicked(int p_id);
void on_evidence_double_clicked(int p_id);
+ void on_evidence_edit_clicked();
void on_evidence_hover(int p_id, bool p_state);
@@ -928,8 +936,6 @@ private slots:
void on_showname_enable_clicked();
- void on_evidence_name_double_clicked();
- void on_evidence_image_name_double_clicked();
void on_evidence_button_clicked();
void on_evidence_delete_clicked();
diff --git a/include/eventfilters.h b/include/eventfilters.h
new file mode 100644
index 00000000..7847608d
--- /dev/null
+++ b/include/eventfilters.h
@@ -0,0 +1,36 @@
+#ifndef EVENTFILTERS_H
+#define EVENTFILTERS_H
+
+#include <QEvent>
+#include <QLineEdit>
+
+class AOLineEditFilter : public QObject
+{
+ Q_OBJECT
+public:
+ bool preserve_selection = false;
+
+protected:
+ bool eventFilter(QObject *obj, QEvent *event) override {
+ QLineEdit *lineEdit = qobject_cast<QLineEdit *>(obj);
+ if (event->type() == QEvent::FocusOut && lineEdit != nullptr && preserve_selection) { // lost focus
+ int start = lineEdit->selectionStart();
+ #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
+ int len = lineEdit->selectionLength();
+ #else
+ int len = lineEdit->selectedText().length();
+ #endif
+ if (start != -1 && len != -1) {
+ lineEdit->setSelection(start, len);\
+ return true;
+ }
+ }
+ return false;
+ }
+signals:
+ void double_clicked();
+};
+
+
+
+#endif // EVENTFILTERS_H
diff --git a/include/lobby.h b/include/lobby.h
index 1d2cbc6c..80832491 100644
--- a/include/lobby.h
+++ b/include/lobby.h
@@ -86,7 +86,7 @@ private:
QProgressBar *ui_progress_bar;
AOButton *ui_cancel;
- int last_index;
+ int last_index = -1;
void set_size_and_pos(QWidget *p_widget, QString p_identifier);
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index b04db8b3..32e924a7 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -10,13 +10,11 @@ aoevidencebutton.cpp
aoevidencedisplay.cpp
aoimage.cpp
aolayer.cpp
-aolineedit.cpp
aomusicplayer.cpp
aooptionsdialog.cpp
aopacket.cpp
aosfxplayer.cpp
aotextarea.cpp
-aotextedit.cpp
charselect.cpp
chatlogpiece.cpp
courtroom.cpp
diff --git a/src/aoapplication.cpp b/src/aoapplication.cpp
index a8701562..f516be38 100644
--- a/src/aoapplication.cpp
+++ b/src/aoapplication.cpp
@@ -17,6 +17,8 @@ AOApplication::AOApplication(int &argc, char **argv) : QApplication(argc, argv)
net_manager = new NetworkManager(this);
discord = new AttorneyOnline::Discord();
qApp->setStyleSheet("QFrame {background-color:transparent;} QAbstractItemView {background-color: transparent; color: black;}; QLineEdit {background-color:transparent;}");
+
+ asset_lookup_cache.reserve(2048);
}
AOApplication::~AOApplication()
@@ -164,13 +166,14 @@ void AOApplication::call_announce_menu(Courtroom *court)
}
// Callback for when BASS device is lost
+// Only actually used for music syncs
void CALLBACK AOApplication::BASSreset(HSTREAM handle, DWORD channel,
DWORD data, void *user)
{
- UNUSED(handle);
- UNUSED(channel);
- UNUSED(data);
- UNUSED(user);
+ Q_UNUSED(handle);
+ Q_UNUSED(channel);
+ Q_UNUSED(data);
+ Q_UNUSED(user);
doBASSreset();
}
@@ -183,6 +186,7 @@ void AOApplication::doBASSreset()
void AOApplication::initBASS()
{
+ BASS_SetConfig(BASS_CONFIG_DEV_DEFAULT, 1);
BASS_Free();
// Change the default audio output device to be the one the user has given
// in his config.ini file for now.
diff --git a/src/aoblipplayer.cpp b/src/aoblipplayer.cpp
index 6607d463..307a0bdd 100644
--- a/src/aoblipplayer.cpp
+++ b/src/aoblipplayer.cpp
@@ -34,12 +34,6 @@ void AOBlipPlayer::blip_tick()
HSTREAM f_stream = m_stream_list[f_cycle];
BASS_ChannelSetDevice(f_stream, BASS_GetDevice());
- int f_bass_error = BASS_ErrorGetCode();
- if (f_bass_error == BASS_ERROR_DEVICE) {
- ao_app->doBASSreset();
- BASS_ChannelSetDevice(f_stream, BASS_GetDevice());
- }
-
BASS_ChannelPlay(f_stream, false);
}
diff --git a/src/aobutton.cpp b/src/aobutton.cpp
index 7f8c13fe..242fe79a 100644
--- a/src/aobutton.cpp
+++ b/src/aobutton.cpp
@@ -20,14 +20,9 @@ void AOButton::set_image(QString p_path, QString p_misc)
{
movie->stop();
QString p_image;
- // Check if the user wants animated themes
- if (ao_app->get_animated_theme())
- // We want an animated image
- p_image = ao_app->get_image(p_path, ao_app->current_theme, ao_app->get_subtheme(), ao_app->default_theme, p_misc);
- else
- // Grab a static variant of the image
- p_image = ao_app->get_image_path(ao_app->get_asset_paths(p_path, ao_app->current_theme, ao_app->get_subtheme(), ao_app->default_theme, p_misc), true);
- if (!file_exists(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());
+ if (p_image.isEmpty()) {
this->setIcon(QIcon());
this->setIconSize(this->size());
this->setStyleSheet("");
diff --git a/src/aocaseannouncerdialog.cpp b/src/aocaseannouncerdialog.cpp
index aea6405d..0c9ee0f3 100644
--- a/src/aocaseannouncerdialog.cpp
+++ b/src/aocaseannouncerdialog.cpp
@@ -23,10 +23,10 @@ AOCaseAnnouncerDialog::AOCaseAnnouncerDialog(QWidget *parent,
ui_announcer_buttons->setStandardButtons(QDialogButtonBox::Ok |
QDialogButtonBox::Cancel);
- QObject::connect(ui_announcer_buttons, SIGNAL(accepted()), this,
- SLOT(ok_pressed()));
- QObject::connect(ui_announcer_buttons, SIGNAL(rejected()), this,
- SLOT(cancel_pressed()));
+ connect(ui_announcer_buttons, &QDialogButtonBox::accepted, this,
+ &AOCaseAnnouncerDialog::ok_pressed);
+ connect(ui_announcer_buttons, &QDialogButtonBox::rejected, this,
+ &AOCaseAnnouncerDialog::cancel_pressed);
setUpdatesEnabled(false);
diff --git a/src/aoemotebutton.cpp b/src/aoemotebutton.cpp
index 3260a944..638d49da 100644
--- a/src/aoemotebutton.cpp
+++ b/src/aoemotebutton.cpp
@@ -11,7 +11,7 @@ AOEmoteButton::AOEmoteButton(QWidget *p_parent, AOApplication *p_ao_app,
this->move(p_x, p_y);
this->resize(p_w, p_h);
- connect(this, SIGNAL(clicked()), this, SLOT(on_clicked()));
+ connect(this, &AOEmoteButton::clicked, this, &AOEmoteButton::on_clicked);
}
void AOEmoteButton::set_image(QString p_image, QString p_emote_comment)
@@ -67,4 +67,4 @@ void AOEmoteButton::set_char_image(QString p_char, int p_emote, QString suffix)
this->set_image(image_path, ao_app->get_emote_comment(p_char, p_emote));
}
-void AOEmoteButton::on_clicked() { emote_clicked(m_id); }
+void AOEmoteButton::on_clicked() { emit emote_clicked(m_id); }
diff --git a/src/aoevidencebutton.cpp b/src/aoevidencebutton.cpp
index fee7327a..800c8b43 100644
--- a/src/aoevidencebutton.cpp
+++ b/src/aoevidencebutton.cpp
@@ -27,12 +27,12 @@ AOEvidenceButton::AOEvidenceButton(QWidget *p_parent, AOApplication *p_ao_app,
this->resize(p_w, p_h);
// this->setAcceptDrops(true);
- connect(this, SIGNAL(clicked()), this, SLOT(on_clicked()));
+ connect(this, &AOEvidenceButton::clicked, this, &AOEvidenceButton::on_clicked);
}
void AOEvidenceButton::set_image(QString p_image)
{
- QString image_path = ao_app->get_evidence_path(p_image);
+ QString image_path = ao_app->get_real_path(ao_app->get_evidence_path(p_image));
if (file_exists(p_image)) {
this->setText("");
this->setStyleSheet(
@@ -57,8 +57,10 @@ void AOEvidenceButton::set_image(QString p_image)
void AOEvidenceButton::set_theme_image(QString p_image)
{
- QString theme_image_path = ao_app->get_theme_path(p_image);
- QString default_image_path = ao_app->get_theme_path(p_image, ao_app->default_theme);
+ QString theme_image_path = ao_app->get_real_path(
+ ao_app->get_theme_path(p_image));
+ QString default_image_path = ao_app->get_real_path(
+ ao_app->get_theme_path(p_image, ao_app->default_theme));
QString final_image_path;
@@ -78,12 +80,12 @@ void AOEvidenceButton::set_selected(bool p_selected)
ui_selected->hide();
}
-void AOEvidenceButton::on_clicked() { evidence_clicked(m_id); }
+void AOEvidenceButton::on_clicked() { emit evidence_clicked(m_id); }
void AOEvidenceButton::mouseDoubleClickEvent(QMouseEvent *e)
{
QPushButton::mouseDoubleClickEvent(e);
- evidence_double_clicked(m_id);
+ emit evidence_double_clicked(m_id);
}
/*
@@ -106,7 +108,7 @@ void AOEvidenceButton::enterEvent(QEvent *e)
{
ui_selector->show();
- on_hover(m_id, true);
+ emit on_hover(m_id, true);
setFlat(false);
QPushButton::enterEvent(e);
@@ -116,6 +118,6 @@ void AOEvidenceButton::leaveEvent(QEvent *e)
{
ui_selector->hide();
- on_hover(m_id, false);
+ emit on_hover(m_id, false);
QPushButton::leaveEvent(e);
}
diff --git a/src/aoevidencedisplay.cpp b/src/aoevidencedisplay.cpp
index ba1c170d..0d3eae73 100644
--- a/src/aoevidencedisplay.cpp
+++ b/src/aoevidencedisplay.cpp
@@ -13,7 +13,7 @@ AOEvidenceDisplay::AOEvidenceDisplay(QWidget *p_parent, AOApplication *p_ao_app)
evidence_movie = new InterfaceLayer(this, ao_app);
- connect(evidence_movie, SIGNAL(done()), this, SLOT(show_done()));
+ connect(evidence_movie, &InterfaceLayer::done, this, &AOEvidenceDisplay::show_done);
}
void AOEvidenceDisplay::show_evidence(QString p_evidence_image,
@@ -35,7 +35,8 @@ void AOEvidenceDisplay::show_evidence(QString p_evidence_image,
gif_name = "evidence_appear_right";
}
- QString f_evidence_path = ao_app->get_evidence_path(p_evidence_image);
+ QString f_evidence_path = ao_app->get_real_path(
+ ao_app->get_evidence_path(p_evidence_image));
QPixmap f_pixmap(f_evidence_path);
pos_size_type icon_dimensions =
diff --git a/src/aoimage.cpp b/src/aoimage.cpp
index 656528e3..82e17b98 100644
--- a/src/aoimage.cpp
+++ b/src/aoimage.cpp
@@ -24,21 +24,16 @@ AOImage::AOImage(QWidget *parent, AOApplication *p_ao_app, bool make_static) : Q
AOImage::~AOImage() {}
-bool AOImage::set_image(QString p_path, QString p_misc)
+bool AOImage::set_image(QString p_image, QString p_misc)
{
- // Check if the user wants animated themes
- if (!is_static && ao_app->get_animated_theme())
- // We want an animated image
- p_path = ao_app->get_image(p_path, ao_app->current_theme, ao_app->get_subtheme(), ao_app->default_theme, p_misc);
- else
- // Grab a static variant of the image
- p_path = ao_app->get_image_path(ao_app->get_asset_paths(p_path, ao_app->current_theme, ao_app->get_subtheme(), ao_app->default_theme, p_misc), true);
+ p_image = ao_app->get_image(p_image, ao_app->current_theme, ao_app->get_subtheme(),
+ ao_app->default_theme, p_misc, "", "", is_static || !ao_app->get_animated_theme());
- if (!file_exists(p_path)) {
- qDebug() << "Warning: Image" << p_path << "not found! Can't set!";
+ if (!file_exists(p_image)) {
+ qDebug() << "Warning: Image" << p_image << "not found! Can't set!";
return false;
}
- path = p_path;
+ path = p_image;
if (!is_static) {
movie->stop();
movie->setFileName(path);
diff --git a/src/aolayer.cpp b/src/aolayer.cpp
index 2c6c9117..dd1fe76c 100644
--- a/src/aolayer.cpp
+++ b/src/aolayer.cpp
@@ -12,16 +12,16 @@ AOLayer::AOLayer(QWidget *p_parent, AOApplication *p_ao_app) : QLabel(p_parent)
shfx_timer = new QTimer(this);
shfx_timer->setTimerType(Qt::PreciseTimer);
shfx_timer->setSingleShot(true);
- connect(shfx_timer, SIGNAL(timeout()), this, SLOT(shfx_timer_done()));
+ connect(shfx_timer, &QTimer::timeout, this, &AOLayer::shfx_timer_done);
ticker = new QTimer(this);
ticker->setTimerType(Qt::PreciseTimer);
ticker->setSingleShot(false);
- connect(ticker, SIGNAL(timeout()), this, SLOT(movie_ticker()));
+ connect(ticker, &QTimer::timeout, this, &AOLayer::movie_ticker);
preanim_timer = new QTimer(this);
preanim_timer->setSingleShot(true);
- connect(preanim_timer, SIGNAL(timeout()), this, SLOT(preanim_done()));
+ connect(preanim_timer, &QTimer::timeout, this, &AOLayer::preanim_done);
}
BackgroundLayer::BackgroundLayer(QWidget *p_parent, AOApplication *p_ao_app)
@@ -52,7 +52,7 @@ StickerLayer::StickerLayer(QWidget *p_parent, AOApplication *p_ao_app)
QString AOLayer::find_image(QStringList p_list)
{
QString image_path;
- for (QString path : p_list) {
+ for (const QString &path : p_list) {
#ifdef DEBUG_MOVIE
qDebug() << "checking path " << path;
#endif
@@ -138,14 +138,15 @@ void BackgroundLayer::load_image(QString p_filename)
{
play_once = false;
cull_image = false;
- QString design_path = ao_app->get_background_path("design.ini");
+ VPath design_path = ao_app->get_background_path("design.ini");
transform_mode =
ao_app->get_scaling(ao_app->read_design_ini("scaling", design_path));
stretch = ao_app->read_design_ini("stretch", design_path).startsWith("true");
#ifdef DEBUG_MOVIE
qDebug() << "[BackgroundLayer] BG loaded: " << p_filename;
#endif
- start_playback(ao_app->get_image_suffix(ao_app->get_background_path(p_filename)));
+ QString final_path = ao_app->get_image_suffix(ao_app->get_background_path(p_filename));
+ start_playback(final_path);
play();
}
@@ -179,15 +180,16 @@ void CharLayer::load_image(QString p_filename, QString p_charname,
last_emote = current_emote;
last_prefix = prefix;
is_preanim = p_is_preanim;
- if ((p_filename.left(3) == "(a)") || (p_filename.left(3) == "(b)")) {
- prefix = p_filename.left(3);
+ if ((p_filename.left(3) == "(a)") || (p_filename.left(3) == "(b)")) { // if we are playing an idle or talking animation
+ prefix = p_filename.left(3); // separate the prefix from the emote name
current_emote = p_filename.mid(3, -1);
}
- else if ((duration > 0) || (p_filename.left(3) == "(c)")) {
- if (p_filename.left(3) == "(c)") {
- prefix = "(c)";
+ else if ((duration > 0) || (p_filename.left(3) == "(c)")) { // else if we are playing a preanim or postanim
+ if (p_filename.left(3) == "(c)") { // if we are playing a postanim
+ prefix = "(c)"; // separate the prefix from the emote name
current_emote = p_filename.mid(3, -1);
}
+ // pre/postanim specific flags
is_preanim = true;
play_once = true;
preanim_timer->start(duration);
@@ -197,7 +199,7 @@ void CharLayer::load_image(QString p_filename, QString p_charname,
<< current_emote << " from character: " << p_charname
<< " continuous: " << continuous;
#endif
- QStringList pathlist = {
+ QVector<VPath> pathlist { // cursed character path resolution vector
ao_app->get_character_path(
p_charname, prefix + current_emote), // Default path
ao_app->get_character_path(
@@ -207,7 +209,7 @@ void CharLayer::load_image(QString p_filename, QString p_charname,
ao_app->get_character_path(
p_charname,
current_emote), // Just use the non-prefixed image, animated or not
- current_emote, // The path by itself after the above fail
+ VPath(current_emote), // The path by itself after the above fail
ao_app->get_theme_path("placeholder"), // Theme placeholder path
ao_app->get_theme_path(
"placeholder", ao_app->default_theme)}; // Default theme placeholder path
@@ -232,7 +234,7 @@ void EffectLayer::load_image(QString p_filename, bool p_looping)
play_once = true;
continuous = false;
force_continuous = true;
- start_playback(p_filename); // handled in its own file before we see it
+ start_playback(p_filename); // path resolution is handled by the caller for EffectLayer objects
play();
}
@@ -269,6 +271,13 @@ void CharLayer::start_playback(QString p_image)
void AOLayer::start_playback(QString p_image)
{
+ if (p_image == "") {// image wasn't found by the path resolution function
+ this->kill();
+ return;
+ }
+ QMutexLocker locker(&mutex);
+ if (frame_loader.isRunning())
+ exit_loop = true; // tell the loader to stop, we have a new image to load
this->show();
if (!ao_app->is_continuous_enabled()) {
@@ -276,7 +285,7 @@ void AOLayer::start_playback(QString p_image)
force_continuous = true;
}
- if ((last_path == p_image) && (!force_continuous))
+ if (((last_path == p_image) && (!force_continuous)) || p_image == "")
return;
#ifdef DEBUG_MOVIE
@@ -296,55 +305,36 @@ void AOLayer::start_playback(QString p_image)
stretch = stretch_override.startsWith("true");
#ifdef DEBUG_MOVIE
- qDebug() << "stretch:" << stretch << "filename:" << p_image;
+ qDebug() << "[AOLayer::start_playback] Stretch:" << stretch << "Filename:" << p_image;
#endif
m_reader.setFileName(p_image);
if (m_reader.loopCount() == 0)
play_once = true;
- if (!continuous)
- frame = 0;
last_max_frames = max_frames;
max_frames = m_reader.imageCount();
- if (((continuous) && (max_frames != last_max_frames)) || max_frames == 0) {
+ if (!continuous
+ || ((continuous) && (max_frames != last_max_frames))
+ || max_frames == 0
+ || frame >= max_frames) {
frame = 0;
continuous = false;
}
- // CANTFIX: this causes a hitch
- // The correct way of doing this would be to use QImageReader::jumpToImage()
- // and populate missing data in the movie ticker when it's needed. This is
- // unfortunately completely impossible, because QImageReader::jumpToImage() is
- // not implemented in any image format AO2 is equipped to use. Instead, the
- // default behavior is used - that is, absolutely nothing.
- // This is why continuous playback can be toggled off.
- if (continuous) {
- for (int i = frame; i--;) {
- if (i <= -1)
- break;
- QPixmap l_pixmap = this->get_pixmap(m_reader.read());
- int l_delay = m_reader.nextImageDelay();
- movie_frames.append(l_pixmap);
- movie_delays.append(l_delay);
- }
- }
+ frame_loader = QtConcurrent::run(this, &AOLayer::populate_vectors);
last_path = p_image;
- QPixmap f_pixmap = this->get_pixmap(m_reader.read());
- int f_delay = m_reader.nextImageDelay();
+ 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
+ this->set_frame(movie_frames[frame]);
- this->set_frame(f_pixmap);
- if (max_frames > 1) {
- movie_frames.append(f_pixmap);
- movie_delays.append(f_delay);
- }
- else if (max_frames <= 1) {
+ if (max_frames <= 1) {
duration = static_duration;
#ifdef DEBUG_MOVIE
- qDebug() << "max_frames is <= 1, using static duration";
+ qDebug() << "[AOLayer::start_playback] max_frames is <= 1, using static duration";
#endif
}
if (duration > 0 && cull_image == true)
shfx_timer->start(duration);
#ifdef DEBUG_MOVIE
- qDebug() << max_frames << "Setting image to " << image_path
+ qDebug() << "[AOLayer::start_playback] Max frames:" << max_frames << "Setting image to " << p_image
<< "Time taken to process image:" << actual_time.elapsed();
actual_time.restart();
@@ -375,8 +365,12 @@ void AOLayer::play()
else
this->freeze();
}
- else
+ else {
+ while (movie_delays.size() <= frame) {
+ frameAdded.wait(&mutex);
+ }
ticker->start(this->get_frame_delay(movie_delays[frame]));
+ }
}
void AOLayer::set_play_once(bool p_play_once) { play_once = p_play_once; }
@@ -454,7 +448,7 @@ void CharLayer::load_network_effects()
// data, let's yank it in.
effect += f_data;
#ifdef DEBUG_MOVIE
- qDebug() << effect << f_data << "frame" << f_frame << "for"
+ qDebug() << "[CharLayer::load_network_effects]" << effect << f_data << "frame" << f_frame << "for"
<< m_emote;
#endif
movie_effects[f_frame].append(effect);
@@ -473,24 +467,24 @@ void CharLayer::play_frame_effect(int p_frame)
if (p_frame < max_frames) {
foreach (QString effect, movie_effects[p_frame]) {
if (effect == "shake") {
- shake();
+ emit shake();
#ifdef DEBUG_MOVIE
- qDebug() << "Attempting to play shake on frame" << frame;
+ qDebug() << "[CharLayer::play_frame_effect] Attempting to play shake on frame" << frame;
#endif
}
if (effect == "flash") {
- flash();
+ emit flash();
#ifdef DEBUG_MOVIE
- qDebug() << "Attempting to play flash on frame" << frame;
+ qDebug() << "[CharLayer::play_frame_effect] Attempting to play flash on frame" << frame;
#endif
}
if (effect.startsWith("sfx^")) {
QString sfx = effect.section("^", 1);
- play_sfx(sfx);
+ emit play_sfx(sfx);
#ifdef DEBUG_MOVIE
- qDebug() << "Attempting to play sfx" << sfx << "on frame" << frame;
+ qDebug() << "[CharLayer::play_frame_effect] Attempting to play sfx" << sfx << "on frame" << frame;
#endif
}
}
@@ -544,21 +538,38 @@ void AOLayer::movie_ticker()
else
frame = 0;
}
- // qint64 difference = elapsed - movie_delays[frame];
- if (frame >= movie_frames.size()) {
- movie_frames.append(this->get_pixmap(m_reader.read()));
- movie_delays.append(m_reader.nextImageDelay());
+ mutex.lock();
+ while (frame >= movie_frames.size() && frame < max_frames) { // oops! our frame isn't ready yet
+ frameAdded.wait(&mutex); // wait for a new frame to be added, then check again
}
-
+ mutex.unlock();
#ifdef DEBUG_MOVIE
- qDebug() << frame << movie_delays[frame]
- << "actual time taken from last frame:" << actual_time.restart();
+ qDebug() << "[AOLayer::movie_ticker] Frame:" << frame << "Delay:" << movie_delays[frame]
+ << "Actual time taken from last frame:" << actual_time.restart();
#endif
-
this->set_frame(movie_frames[frame]);
ticker->setInterval(this->get_frame_delay(movie_delays[frame]));
}
+void AOLayer::populate_vectors() {
+ while (movie_frames.size() < max_frames && !exit_loop) {
+ load_next_frame();
+#ifdef DEBUG_MOVIE
+ qDebug() << "[AOLayer::populate_vectors] Loaded frame" << movie_frames.size();
+#endif
+ }
+ exit_loop = false;
+}
+
+void AOLayer::load_next_frame() {
+ //QMutexLocker locker(&mutex);
+ mutex.lock();
+ movie_frames.append(this->get_pixmap(m_reader.read()));
+ movie_delays.append(m_reader.nextImageDelay());
+ mutex.unlock();
+ frameAdded.wakeAll();
+}
+
void CharLayer::preanim_done()
{
if (is_preanim)
@@ -571,7 +582,7 @@ void AOLayer::preanim_done()
{
ticker->stop();
preanim_timer->stop();
- done();
+ emit done();
}
void AOLayer::shfx_timer_done()
@@ -581,5 +592,5 @@ void AOLayer::shfx_timer_done()
qDebug() << "shfx timer signaled done";
#endif
// signal connected to courtroom object, let it figure out what to do
- done();
+ emit done();
}
diff --git a/src/aolineedit.cpp b/src/aolineedit.cpp
deleted file mode 100644
index d80fa014..00000000
--- a/src/aolineedit.cpp
+++ /dev/null
@@ -1,22 +0,0 @@
-#include "aolineedit.h"
-
-AOLineEdit::AOLineEdit(QWidget *parent) : QLineEdit(parent) {}
-
-void AOLineEdit::mouseDoubleClickEvent(QMouseEvent *e)
-{
- QLineEdit::mouseDoubleClickEvent(e);
-
- double_clicked();
-}
-void AOLineEdit::focusOutEvent(QFocusEvent *ev)
-{
- int start = selectionStart();
-#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
- int len = selectionLength();
-#else
- int len = selectedText().length();
-#endif
- QLineEdit::focusOutEvent(ev);
- if (p_selection && start != -1 && len != -1)
- this->setSelection(start, len);
-}
diff --git a/src/aomusicplayer.cpp b/src/aomusicplayer.cpp
index e8bd690c..d0d95635 100644
--- a/src/aomusicplayer.cpp
+++ b/src/aomusicplayer.cpp
@@ -19,7 +19,7 @@ int AOMusicPlayer::play(QString p_song, int channel, bool loop,
channel = channel % m_channelmax;
if (channel < 0) // wtf?
return BASS_ERROR_NOCHAN;
- QString f_path = ao_app->get_music_path(p_song);
+ QString f_path = ao_app->get_real_path(ao_app->get_music_path(p_song));
unsigned int flags = BASS_STREAM_PRESCAN | BASS_STREAM_AUTOFREE |
BASS_UNICODE | BASS_ASYNCFILE;
@@ -150,8 +150,8 @@ void AOMusicPlayer::set_volume(int p_value, int channel)
void CALLBACK loopProc(HSYNC handle, DWORD channel, DWORD data, void *user)
{
- UNUSED(handle);
- UNUSED(data);
+ Q_UNUSED(handle);
+ Q_UNUSED(data);
QWORD loop_start = *(static_cast<unsigned *>(user));
BASS_ChannelLock(channel, true);
BASS_ChannelSetPosition(channel, loop_start, BASS_POS_BYTE);
diff --git a/src/aooptionsdialog.cpp b/src/aooptionsdialog.cpp
index 03c73346..54a11e13 100644
--- a/src/aooptionsdialog.cpp
+++ b/src/aooptionsdialog.cpp
@@ -5,6 +5,8 @@
#include "bass.h"
#include "networkmanager.h"
+#include <QFileDialog>
+
AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app)
: QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint)
{
@@ -13,7 +15,7 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app)
// Setting up the basics.
setWindowFlag(Qt::WindowCloseButtonHint);
setWindowTitle(tr("Settings"));
- resize(400, 408);
+ resize(450, 408);
ui_settings_buttons = new QDialogButtonBox(this);
@@ -28,12 +30,12 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app)
QDialogButtonBox::Save |
QDialogButtonBox::RestoreDefaults);
- QObject::connect(ui_settings_buttons, SIGNAL(accepted()), this,
- SLOT(save_pressed()));
- QObject::connect(ui_settings_buttons, SIGNAL(rejected()), this,
- SLOT(discard_pressed()));
- QObject::connect(ui_settings_buttons, SIGNAL(clicked(QAbstractButton*)), this,
- SLOT(button_clicked(QAbstractButton*)));
+ 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);
@@ -74,16 +76,23 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app)
ui_theme_combobox = new QComboBox(ui_form_layout_widget);
// Fill the combobox with the names of the themes.
- QDirIterator it(ao_app->get_base_path() + "themes", QDir::Dirs,
- QDirIterator::NoIteratorFlags);
- while (it.hasNext()) {
- QString actualname = QDir(it.next()).dirName();
- if (actualname != "." && actualname != "..")
- ui_theme_combobox->addItem(actualname);
+ 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);
+ }
+ }
}
- QObject::connect(ui_theme_combobox, SIGNAL(currentIndexChanged(int)), this,
- SLOT(theme_changed(int)));
+ 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;
@@ -116,8 +125,8 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app)
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);
- QObject::connect(ui_theme_reload_button, SIGNAL(clicked()), this,
- SLOT(on_reload_theme_clicked()));
+ connect(ui_theme_reload_button, &QPushButton::clicked, this,
+ &AOOptionsDialog::on_reload_theme_clicked);
row += 1;
ui_animated_theme_lbl = new QLabel(ui_form_layout_widget);
@@ -208,9 +217,34 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app)
ui_log_timestamp_cb = new QCheckBox(ui_form_layout_widget);
+ connect(ui_log_timestamp_cb, &QCheckBox::stateChanged, this, &AOOptionsDialog::timestamp_cb_changed);
+
ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_log_timestamp_cb);
row += 1;
+ ui_log_timestamp_format_lbl = new QLabel(ui_form_layout_widget);
+ ui_log_timestamp_format_lbl->setText(tr("Log timestamp format:\n") + QDateTime::currentDateTime().toString(ao_app->get_log_timestamp_format()));
+ ui_gameplay_form->setWidget(row, QFormLayout::LabelRole, ui_log_timestamp_format_lbl);
+
+ ui_log_timestamp_format_combobox = new QComboBox(ui_form_layout_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_gameplay_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_layout_widget);
ui_log_ic_actions_lbl->setText(tr("Log IC actions:"));
ui_log_ic_actions_lbl->setToolTip(
@@ -222,7 +256,6 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app)
ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_log_ic_actions_cb);
-
row += 1;
ui_stay_time_lbl = new QLabel(ui_form_layout_widget);
ui_stay_time_lbl->setText(tr("Text Stay Time:"));
@@ -903,7 +936,130 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app)
ui_casing_layout->setWidget(row, QFormLayout::FieldRole, ui_log_cb);
- // privacy policy.
+ // 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 will be searched in the order provided."));
+ 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 dir = QFileDialog::getExistingDirectory(this, tr("Select a base folder"),
+ QApplication::applicationDirPath(),
+ QFileDialog::ShowDirsOnly);
+ if (dir.isEmpty())
+ return;
+ QListWidgetItem *dir_item = new QListWidgetItem(dir);
+ 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, [=] {
+ 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, [=] {
+ 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, [=] {
+ 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, [=] {
+ asset_cache_dirty = true;
+ ui_mount_clear_cache->setEnabled(false);
+ });
+
+ connect(ui_mount_list, &QListWidget::itemSelectionChanged, 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);
+ });
+
+ // Privacy tab
ui_privacy_tab = new QWidget(this);
ui_settings_tabs->addTab(ui_privacy_tab, tr("Privacy"));
@@ -965,6 +1121,7 @@ void AOOptionsDialog::update_values() {
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());
@@ -1002,6 +1159,13 @@ void AOOptionsDialog::update_values() {
ui_blips_volume_spinbox->setValue(ao_app->get_default_blip());
ui_bliprate_spinbox->setValue(ao_app->read_blip_rate());
ui_default_showname_textbox->setText(ao_app->get_default_showname());
+
+ auto *defaultMount = new QListWidgetItem(tr("%1 (default)")
+ .arg(ao_app->get_base_path()));
+ defaultMount->setFlags(Qt::ItemFlag::NoItemFlags);
+ 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) {
@@ -1028,6 +1192,7 @@ void AOOptionsDialog::save_pressed()
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());
@@ -1083,9 +1248,16 @@ void AOOptionsDialog::save_pressed()
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 (asset_cache_dirty)
+ ao_app->invalidate_lookup_cache();
+
if (audioChanged)
ao_app->initBASS();
@@ -1147,6 +1319,10 @@ void AOOptionsDialog::theme_changed(int i) {
}
+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__))
diff --git a/src/aosfxplayer.cpp b/src/aosfxplayer.cpp
index 000b6a7e..fcdeb949 100644
--- a/src/aosfxplayer.cpp
+++ b/src/aosfxplayer.cpp
@@ -47,12 +47,6 @@ void AOSfxPlayer::play(QString p_sfx, QString p_character, QString p_misc)
set_volume_internal(m_volume);
BASS_ChannelSetDevice(m_stream_list[m_channel], BASS_GetDevice());
- int f_bass_error = BASS_ErrorGetCode();
- if (f_bass_error == BASS_ERROR_DEVICE) {
- ao_app->doBASSreset();
- BASS_ChannelSetDevice(m_stream_list[m_channel], BASS_GetDevice());
- }
-
BASS_ChannelPlay(m_stream_list[m_channel], false);
BASS_ChannelSetSync(m_stream_list[m_channel], BASS_SYNC_DEV_FAIL, 0,
ao_app->BASSreset, 0);
diff --git a/src/aotextedit.cpp b/src/aotextedit.cpp
deleted file mode 100644
index 22d9a62e..00000000
--- a/src/aotextedit.cpp
+++ /dev/null
@@ -1,17 +0,0 @@
-#include "aotextedit.h"
-
-AOTextEdit::AOTextEdit(QWidget *parent) : QPlainTextEdit(parent)
-{
- this->setReadOnly(true);
-
- // connect(this, SIGNAL(returnPressed()), this, SLOT(on_enter_pressed()));
-}
-
-void AOTextEdit::mouseDoubleClickEvent(QMouseEvent *e)
-{
- QPlainTextEdit::mouseDoubleClickEvent(e);
-
- this->setReadOnly(false);
-}
-
-void AOTextEdit::on_enter_pressed() { this->setReadOnly(true); }
diff --git a/src/charselect.cpp b/src/charselect.cpp
index 53269b54..8928f446 100644
--- a/src/charselect.cpp
+++ b/src/charselect.cpp
@@ -52,25 +52,25 @@ void Courtroom::construct_char_select()
ui_char_taken->setText(tr("Taken"));
ui_char_taken->setObjectName("ui_char_taken");
- connect(ui_char_list, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
- this, SLOT(on_char_list_double_clicked(QTreeWidgetItem *, int)));
+ connect(ui_char_list, &QTreeWidget::itemDoubleClicked,
+ this, &Courtroom::on_char_list_double_clicked);
- connect(ui_back_to_lobby, SIGNAL(clicked()), this,
- SLOT(on_back_to_lobby_clicked()));
+ connect(ui_back_to_lobby, &AOButton::clicked, this,
+ &Courtroom::on_back_to_lobby_clicked);
- connect(ui_char_select_left, SIGNAL(clicked()), this,
- SLOT(on_char_select_left_clicked()));
- connect(ui_char_select_right, SIGNAL(clicked()), this,
- SLOT(on_char_select_right_clicked()));
+ connect(ui_char_select_left, &AOButton::clicked, this,
+ &Courtroom::on_char_select_left_clicked);
+ connect(ui_char_select_right, &AOButton::clicked, this,
+ &Courtroom::on_char_select_right_clicked);
- connect(ui_spectator, SIGNAL(clicked()), this, SLOT(on_spectator_clicked()));
+ connect(ui_spectator, &AOButton::clicked, this, &Courtroom::on_spectator_clicked);
- connect(ui_char_search, SIGNAL(textEdited(const QString &)), this,
- SLOT(on_char_search_changed()));
- connect(ui_char_passworded, SIGNAL(stateChanged(int)), this,
- SLOT(on_char_passworded_clicked()));
- connect(ui_char_taken, SIGNAL(stateChanged(int)), this,
- SLOT(on_char_taken_clicked()));
+ connect(ui_char_search, &QLineEdit::textEdited,this,
+ &Courtroom::on_char_search_changed);
+ connect(ui_char_passworded, &QCheckBox::stateChanged, this,
+ &Courtroom::on_char_passworded_clicked);
+ connect(ui_char_taken, &QCheckBox::stateChanged, this,
+ &Courtroom::on_char_taken_clicked);
}
@@ -116,7 +116,7 @@ void Courtroom::set_char_select_page()
ui_char_select_left->hide();
ui_char_select_right->hide();
- for (AOCharButton *i_button : ui_char_button_list) {
+ for (AOCharButton *i_button : qAsConst(ui_char_button_list)) {
i_button->reset();
i_button->hide();
i_button->move(0, 0);
@@ -147,7 +147,7 @@ void Courtroom::set_char_select_page()
void Courtroom::on_char_list_double_clicked(QTreeWidgetItem *p_item, int column)
{
- UNUSED(column);
+ Q_UNUSED(column);
int cid = p_item->text(1).toInt();
if (cid == -1 && !p_item->isExpanded()) {
p_item->setExpanded(true);
@@ -164,8 +164,8 @@ void Courtroom::char_clicked(int n_char)
{
if (n_char != -1)
{
- QString char_ini_path =
- ao_app->get_character_path(char_list.at(n_char).name, "char.ini");
+ QString char_ini_path = ao_app->get_real_path(
+ ao_app->get_character_path(char_list.at(n_char).name, "char.ini"));
qDebug() << "char_ini_path" << char_ini_path;
@@ -298,9 +298,9 @@ void Courtroom::character_loading_finished()
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))
- .arg(QString::number(ao_app->char_list_size)));
+ 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/chatlogpiece.cpp b/src/chatlogpiece.cpp
index 05a924ca..f4cb2259 100644
--- a/src/chatlogpiece.cpp
+++ b/src/chatlogpiece.cpp
@@ -7,7 +7,7 @@ chatlogpiece::chatlogpiece()
message = tr("UNKNOWN");
color = 0;
action = "";
- datetime = QDateTime::currentDateTime().toUTC();
+ datetime = QDateTime::currentDateTimeUtc();
}
chatlogpiece::chatlogpiece(QString p_name, QString p_showname,
@@ -18,7 +18,7 @@ chatlogpiece::chatlogpiece(QString p_name, QString p_showname,
message = p_message;
action = p_action;
color = p_color;
- datetime = QDateTime::currentDateTime().toUTC();
+ datetime = QDateTime::currentDateTimeUtc();
}
chatlogpiece::chatlogpiece(QString p_name, QString p_showname,
diff --git a/src/courtroom.cpp b/src/courtroom.cpp
index f551c9e5..e5495266 100644
--- a/src/courtroom.cpp
+++ b/src/courtroom.cpp
@@ -109,6 +109,7 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
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();
ui_ms_chatlog = new AOTextArea(this);
ui_ms_chatlog->setReadOnly(true);
@@ -150,7 +151,7 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
ui_music_name->setText(tr("None"));
ui_music_name->setAttribute(Qt::WA_TransparentForMouseEvents);
ui_music_name->setObjectName("ui_music_name");
-
+
for (int i = 0; i < max_clocks; i++) {
ui_clock[i] = new AOClockLabel(this);
ui_clock[i]->setAttribute(Qt::WA_TransparentForMouseEvents);
@@ -164,10 +165,12 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
ui_ic_chat_name->setText(p_ao_app->get_default_showname());
ui_ic_chat_name->setObjectName("ui_ic_chat_name");
- ui_ic_chat_message = new AOLineEdit(this);
+ ui_ic_chat_message = new QLineEdit(this);
ui_ic_chat_message->setFrame(false);
ui_ic_chat_message->setPlaceholderText(tr("Message"));
- ui_ic_chat_message->preserve_selection(true);
+ ui_ic_chat_message_filter = new AOLineEditFilter();
+ ui_ic_chat_message_filter->preserve_selection = true;
+ ui_ic_chat_message->installEventFilter(ui_ic_chat_message_filter);
ui_ic_chat_message->setObjectName("ui_ic_chat_message");
ui_vp_sticker = new StickerLayer(ui_viewport, ao_app);
@@ -396,154 +399,154 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow()
construct_char_select();
- connect(keepalive_timer, SIGNAL(timeout()), this, SLOT(ping_server()));
-
- connect(ui_vp_objection, SIGNAL(done()), this, SLOT(objection_done()));
- connect(ui_vp_effect, SIGNAL(done()), this, SLOT(effect_done()));
- connect(ui_vp_wtce, SIGNAL(done()), this, SLOT(effect_done()));
- connect(ui_vp_player_char, SIGNAL(done()), this, SLOT(preanim_done()));
- connect(ui_vp_player_char, SIGNAL(shake()), this, SLOT(do_screenshake()));
- connect(ui_vp_player_char, SIGNAL(flash()), this, SLOT(do_flash()));
- connect(ui_vp_player_char, SIGNAL(play_sfx(QString)), this,
- SLOT(play_char_sfx(QString)));
-
- connect(text_delay_timer, SIGNAL(timeout()), this,
- SLOT(start_chat_ticking()));
-
- connect(text_queue_timer, SIGNAL(timeout()), this,
- SLOT(chatmessage_dequeue()));
-
- connect(sfx_delay_timer, SIGNAL(timeout()), this, SLOT(play_sfx()));
-
- connect(chat_tick_timer, SIGNAL(timeout()), this, SLOT(chat_tick()));
-
- connect(ui_pos_dropdown, SIGNAL(currentIndexChanged(int)), this,
- SLOT(on_pos_dropdown_changed(int)));
- connect(ui_pos_dropdown, SIGNAL(editTextChanged(QString)), this,
- SLOT(on_pos_dropdown_changed(QString)));
- connect(ui_pos_remove, SIGNAL(clicked()), this, SLOT(on_pos_remove_clicked()));
-
- connect(ui_iniswap_dropdown, SIGNAL(currentIndexChanged(int)), this,
- SLOT(on_iniswap_dropdown_changed(int)));
- connect(ui_iniswap_dropdown, SIGNAL(customContextMenuRequested(QPoint)), this,
- SLOT(on_iniswap_context_menu_requested(QPoint)));
- connect(ui_iniswap_remove, SIGNAL(clicked()), this,
- SLOT(on_iniswap_remove_clicked()));
-
- connect(ui_sfx_dropdown, SIGNAL(currentIndexChanged(int)), this,
- SLOT(on_sfx_dropdown_changed(int)));
- connect(ui_sfx_dropdown, SIGNAL(editTextChanged(QString)), this,
- SLOT(on_sfx_dropdown_custom(QString)));
- connect(ui_sfx_dropdown, SIGNAL(customContextMenuRequested(QPoint)), this,
- SLOT(on_sfx_context_menu_requested(QPoint)));
- connect(ui_sfx_remove, SIGNAL(clicked()), this,
- SLOT(on_sfx_remove_clicked()));
-
- connect(ui_effects_dropdown, SIGNAL(currentIndexChanged(int)), this,
- SLOT(on_effects_dropdown_changed(int)));
- connect(ui_effects_dropdown, SIGNAL(customContextMenuRequested(QPoint)), this,
- SLOT(on_effects_context_menu_requested(QPoint)));
-
- connect(ui_music_search, SIGNAL(returnPressed()), this,
- SLOT(on_music_search_return_pressed()));
- connect(ui_mute_list, SIGNAL(clicked(QModelIndex)), this,
- SLOT(on_mute_list_clicked(QModelIndex)));
-
- connect(ui_ic_chat_message, SIGNAL(returnPressed()), this,
- SLOT(on_chat_return_pressed()));
-
- connect(ui_ooc_chat_message, SIGNAL(returnPressed()), this,
- SLOT(on_ooc_return_pressed()));
-
- connect(ui_music_list, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
- this, SLOT(on_music_list_double_clicked(QTreeWidgetItem *, int)));
- connect(ui_music_list, SIGNAL(customContextMenuRequested(QPoint)), this,
- SLOT(on_music_list_context_menu_requested(QPoint)));
-
- connect(ui_area_list, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this,
- SLOT(on_area_list_double_clicked(QTreeWidgetItem *, int)));
-
- connect(ui_hold_it, SIGNAL(clicked()), this, SLOT(on_hold_it_clicked()));
- connect(ui_objection, SIGNAL(clicked()), this, SLOT(on_objection_clicked()));
- connect(ui_take_that, SIGNAL(clicked()), this, SLOT(on_take_that_clicked()));
- connect(ui_custom_objection, SIGNAL(clicked()), this,
- SLOT(on_custom_objection_clicked()));
+ connect(keepalive_timer, &QTimer::timeout, this, &Courtroom::ping_server);
+
+ connect(ui_vp_objection, &SplashLayer::done, this, &Courtroom::objection_done);
+ connect(ui_vp_effect, &EffectLayer::done, this, &Courtroom::effect_done);
+ connect(ui_vp_wtce, &SplashLayer::done, this, &Courtroom::effect_done);
+ connect(ui_vp_player_char, &CharLayer::done, this, &Courtroom::preanim_done);
+ connect(ui_vp_player_char, &CharLayer::shake, this, &Courtroom::do_screenshake);
+ connect(ui_vp_player_char, &CharLayer::flash, this, &Courtroom::do_flash);
+ connect(ui_vp_player_char, &CharLayer::play_sfx, this,
+ &Courtroom::play_char_sfx);
+
+ connect(text_delay_timer, &QTimer::timeout, this,
+ &Courtroom::start_chat_ticking);
+
+ connect(text_queue_timer, &QTimer::timeout, this,
+ &Courtroom::chatmessage_dequeue);
+
+ connect(sfx_delay_timer, &QTimer::timeout, this, &Courtroom::play_sfx);
+
+ connect(chat_tick_timer, &QTimer::timeout, this, &Courtroom::chat_tick);
+
+ connect(ui_pos_dropdown, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
+ QOverload<int>::of(&Courtroom::on_pos_dropdown_changed));
+ connect(ui_pos_dropdown, &QComboBox::editTextChanged, this,
+ QOverload<QString>::of(&Courtroom::on_pos_dropdown_changed));
+ connect(ui_pos_remove, &AOButton::clicked, this, &Courtroom::on_pos_remove_clicked);
+
+ connect(ui_iniswap_dropdown, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
+ &Courtroom::on_iniswap_dropdown_changed);
+ connect(ui_iniswap_dropdown, &QComboBox::customContextMenuRequested, this,
+ &Courtroom::on_iniswap_context_menu_requested);
+ connect(ui_iniswap_remove, &AOButton::clicked, this,
+ &Courtroom::on_iniswap_remove_clicked);
+
+ connect(ui_sfx_dropdown, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
+ &Courtroom::on_sfx_dropdown_changed);
+ connect(ui_sfx_dropdown, &QComboBox::editTextChanged, this,
+ &Courtroom::on_sfx_dropdown_custom);
+ connect(ui_sfx_dropdown, &QComboBox::customContextMenuRequested, this,
+ &Courtroom::on_sfx_context_menu_requested);
+ connect(ui_sfx_remove, &AOButton::clicked, this,
+ &Courtroom::on_sfx_remove_clicked);
+
+ connect(ui_effects_dropdown, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
+ &Courtroom::on_effects_dropdown_changed);
+ connect(ui_effects_dropdown, &QComboBox::customContextMenuRequested, this,
+ &Courtroom::on_effects_context_menu_requested);
+
+ connect(ui_music_search, &QLineEdit::returnPressed, this,
+ &Courtroom::on_music_search_return_pressed);
+ connect(ui_mute_list, &QListWidget::clicked, this,
+ &Courtroom::on_mute_list_clicked);
+
+ connect(ui_ic_chat_message, &QLineEdit::returnPressed, this,
+ &Courtroom::on_chat_return_pressed);
+
+ connect(ui_ooc_chat_message, &QLineEdit::returnPressed, this,
+ &Courtroom::on_ooc_return_pressed);
+
+ connect(ui_music_list, &QTreeWidget::itemDoubleClicked,
+ this, &Courtroom::on_music_list_double_clicked);
+ connect(ui_music_list, &QTreeWidget::customContextMenuRequested, this,
+ &Courtroom::on_music_list_context_menu_requested);
+
+ connect(ui_area_list, &QTreeWidget::itemDoubleClicked, this,
+ &Courtroom::on_area_list_double_clicked);
+
+ connect(ui_hold_it, &AOButton::clicked, this, &Courtroom::on_hold_it_clicked);
+ connect(ui_objection, &AOButton::clicked, this, &Courtroom::on_objection_clicked);
+ connect(ui_take_that, &AOButton::clicked, this, &Courtroom::on_take_that_clicked);
+ connect(ui_custom_objection, &AOButton::clicked, this,
+ &Courtroom::on_custom_objection_clicked);
connect(ui_custom_objection,
- SIGNAL(customContextMenuRequested(const QPoint &)), this,
- SLOT(show_custom_objection_menu(const QPoint &)));
-
- connect(ui_realization, SIGNAL(clicked()), this,
- SLOT(on_realization_clicked()));
- connect(ui_screenshake, SIGNAL(clicked()), this,
- SLOT(on_screenshake_clicked()));
-
- connect(ui_mute, SIGNAL(clicked()), this, SLOT(on_mute_clicked()));
-
- connect(ui_defense_minus, SIGNAL(clicked()), this,
- SLOT(on_defense_minus_clicked()));
- connect(ui_defense_plus, SIGNAL(clicked()), this,
- SLOT(on_defense_plus_clicked()));
- connect(ui_prosecution_minus, SIGNAL(clicked()), this,
- SLOT(on_prosecution_minus_clicked()));
- connect(ui_prosecution_plus, SIGNAL(clicked()), this,
- SLOT(on_prosecution_plus_clicked()));
-
- connect(ui_text_color, SIGNAL(currentIndexChanged(int)), this,
- SLOT(on_text_color_changed(int)));
-
- connect(ui_music_slider, SIGNAL(valueChanged(int)), this,
- SLOT(on_music_slider_moved(int)));
- connect(ui_sfx_slider, SIGNAL(valueChanged(int)), this,
- SLOT(on_sfx_slider_moved(int)));
- connect(ui_blip_slider, SIGNAL(valueChanged(int)), this,
- SLOT(on_blip_slider_moved(int)));
-
- connect(ui_ooc_toggle, SIGNAL(clicked()), this,
- SLOT(on_ooc_toggle_clicked()));
-
- connect(ui_music_search, SIGNAL(textChanged(QString)), this,
- SLOT(on_music_search_edited(QString)));
-
- connect(ui_witness_testimony, SIGNAL(clicked()), this,
- SLOT(on_witness_testimony_clicked()));
- connect(ui_cross_examination, SIGNAL(clicked()), this,
- SLOT(on_cross_examination_clicked()));
- connect(ui_guilty, SIGNAL(clicked()), this, SLOT(on_guilty_clicked()));
- connect(ui_not_guilty, SIGNAL(clicked()), this,
- SLOT(on_not_guilty_clicked()));
-
- connect(ui_change_character, SIGNAL(clicked()), this,
- SLOT(on_change_character_clicked()));
- connect(ui_reload_theme, SIGNAL(clicked()), this,
- SLOT(on_reload_theme_clicked()));
- connect(ui_call_mod, SIGNAL(clicked()), this, SLOT(on_call_mod_clicked()));
- connect(ui_settings, SIGNAL(clicked()), this, SLOT(on_settings_clicked()));
- connect(ui_announce_casing, SIGNAL(clicked()), this,
- SLOT(on_announce_casing_clicked()));
- connect(ui_switch_area_music, SIGNAL(clicked()), this,
- SLOT(on_switch_area_music_clicked()));
-
- connect(ui_pre, SIGNAL(clicked()), this, SLOT(on_pre_clicked()));
- connect(ui_flip, SIGNAL(clicked()), this, SLOT(on_flip_clicked()));
- connect(ui_additive, SIGNAL(clicked()), this, SLOT(on_additive_clicked()));
- connect(ui_guard, SIGNAL(clicked()), this, SLOT(on_guard_clicked()));
- connect(ui_casing, SIGNAL(clicked()), this, SLOT(on_casing_clicked()));
-
- connect(ui_showname_enable, SIGNAL(clicked()), this,
- SLOT(on_showname_enable_clicked()));
-
- connect(ui_pair_button, SIGNAL(clicked()), this, SLOT(on_pair_clicked()));
- connect(ui_pair_list, SIGNAL(clicked(QModelIndex)), this,
- SLOT(on_pair_list_clicked(QModelIndex)));
- connect(ui_pair_offset_spinbox, SIGNAL(valueChanged(int)), this,
- SLOT(on_pair_offset_changed(int)));
- connect(ui_pair_vert_offset_spinbox, SIGNAL(valueChanged(int)), this,
- SLOT(on_pair_vert_offset_changed(int)));
- connect(ui_pair_order_dropdown, SIGNAL(currentIndexChanged(int)), this,
- SLOT(on_pair_order_dropdown_changed(int)));
-
- connect(ui_evidence_button, SIGNAL(clicked()), this,
- SLOT(on_evidence_button_clicked()));
+ &AOButton::customContextMenuRequested, this,
+ &Courtroom::show_custom_objection_menu);
+
+ connect(ui_realization, &AOButton::clicked, this,
+ &Courtroom::on_realization_clicked);
+ connect(ui_screenshake, &AOButton::clicked, this,
+ &Courtroom::on_screenshake_clicked);
+
+ connect(ui_mute, &AOButton::clicked, this, &Courtroom::on_mute_clicked);
+
+ connect(ui_defense_minus, &AOButton::clicked, this,
+ &Courtroom::on_defense_minus_clicked);
+ connect(ui_defense_plus, &AOButton::clicked, this,
+ &Courtroom::on_defense_plus_clicked);
+ connect(ui_prosecution_minus, &AOButton::clicked, this,
+ &Courtroom::on_prosecution_minus_clicked);
+ connect(ui_prosecution_plus, &AOButton::clicked, this,
+ &Courtroom::on_prosecution_plus_clicked);
+
+ connect(ui_text_color, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
+ &Courtroom::on_text_color_changed);
+
+ connect(ui_music_slider, &QSlider::valueChanged, this,
+ &Courtroom::on_music_slider_moved);
+ connect(ui_sfx_slider, &QSlider::valueChanged, this,
+ &Courtroom::on_sfx_slider_moved);
+ connect(ui_blip_slider, &QSlider::valueChanged, this,
+ &Courtroom::on_blip_slider_moved);
+
+ connect(ui_ooc_toggle, &AOButton::clicked, this,
+ &Courtroom::on_ooc_toggle_clicked);
+
+ connect(ui_music_search, &QLineEdit::textChanged, this,
+ &Courtroom::on_music_search_edited);
+
+ connect(ui_witness_testimony, &AOButton::clicked, this,
+ &Courtroom::on_witness_testimony_clicked);
+ connect(ui_cross_examination, &AOButton::clicked, this,
+ &Courtroom::on_cross_examination_clicked);
+ connect(ui_guilty, &AOButton::clicked, this, &Courtroom::on_guilty_clicked);
+ connect(ui_not_guilty, &AOButton::clicked, this,
+ &Courtroom::on_not_guilty_clicked);
+
+ connect(ui_change_character, &AOButton::clicked, this,
+ &Courtroom::on_change_character_clicked);
+ connect(ui_reload_theme, &AOButton::clicked, this,
+ &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);
+
+ connect(ui_pre, &AOButton::clicked, this, &Courtroom::on_pre_clicked);
+ 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);
+
+ connect(ui_pair_button, &AOButton::clicked, this, &Courtroom::on_pair_clicked);
+ connect(ui_pair_list, &QListWidget::clicked, this,
+ &Courtroom::on_pair_list_clicked);
+ connect(ui_pair_offset_spinbox, QOverload<int>::of(&QSpinBox::valueChanged), this,
+ &Courtroom::on_pair_offset_changed);
+ connect(ui_pair_vert_offset_spinbox, QOverload<int>::of(&QSpinBox::valueChanged), this,
+ &Courtroom::on_pair_vert_offset_changed);
+ connect(ui_pair_order_dropdown, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
+ &Courtroom::on_pair_order_dropdown_changed);
+
+ connect(ui_evidence_button, &AOButton::clicked, this,
+ &Courtroom::on_evidence_button_clicked);
set_widgets();
@@ -583,12 +586,12 @@ void Courtroom::set_mute_list()
QStringList sorted_mute_list;
- for (char_type i_char : char_list)
+ for (const char_type &i_char : qAsConst(char_list))
sorted_mute_list.append(i_char.name);
sorted_mute_list.sort();
- for (QString i_name : sorted_mute_list) {
+ for (const QString &i_name : sorted_mute_list) {
// mute_map.insert(i_name, false);
ui_mute_list->addItem(i_name);
}
@@ -598,12 +601,12 @@ void Courtroom::set_pair_list()
{
QStringList sorted_pair_list;
- for (char_type i_char : char_list)
+ for (const char_type &i_char : qAsConst(char_list))
sorted_pair_list.append(i_char.name);
sorted_pair_list.sort();
- for (QString i_name : sorted_pair_list) {
+ for (const QString &i_name : sorted_pair_list) {
ui_pair_list->addItem(i_name);
}
}
@@ -612,7 +615,7 @@ 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_theme_path(filename, ao_app->current_theme), QSettings::IniFormat);
+ 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();
@@ -706,12 +709,14 @@ void Courtroom::set_widgets()
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 != 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();
if (regenerate)
regenerate_ic_chatlog();
@@ -767,7 +772,7 @@ void Courtroom::set_widgets()
ui_music_list->resetIndentation();
else
ui_music_list->setIndentation(music_list_indentation.toInt());
-
+
QString music_list_animated = ao_app->get_design_element("music_list_animated", "courtroom_design.ini");
if (music_list_animated == "1")
ui_music_list->setAnimated(true);
@@ -1222,6 +1227,12 @@ void Courtroom::set_stylesheet(QWidget *widget)
void Courtroom::set_stylesheets()
{
set_stylesheet(this);
+ this->setStyleSheet(
+ "QFrame { background-color:transparent; } "
+ "QAbstractItemView { background-color: transparent; color: black; } "
+ "QLineEdit { background-color:transparent; }"
+ + this->styleSheet()
+ );
}
void Courtroom::set_window_title(QString p_title)
@@ -1326,7 +1337,7 @@ void Courtroom::set_background(QString p_background, bool display)
// Populate the dropdown list with all pos that exist on this bg
QStringList pos_list = {};
- for (QString key : default_pos.keys()) {
+ for (const QString &key : default_pos) {
if (file_exists(ao_app->get_image_suffix(
ao_app->get_background_path(default_pos[key]))) || // if we have 2.8-style positions, e.g. def.png, wit.webp, hld.apng
file_exists(
@@ -1334,7 +1345,7 @@ void Courtroom::set_background(QString p_background, bool display)
pos_list.append(default_pos[key]);
}
}
- for (QString pos : ao_app->read_design_ini("positions", ao_app->get_background_path("design.ini")).split(",")) {
+ for (const QString &pos : ao_app->read_design_ini("positions", ao_app->get_background_path("design.ini")).split(",")) {
if (file_exists(ao_app->get_image_suffix(ao_app->get_background_path(pos)))) {
pos_list.append(pos);
}
@@ -1492,11 +1503,11 @@ void Courtroom::update_character(int p_cid)
custom_obj_menu->setDefaultAction(action);
objection_custom = "";
}
- if (dir_exists(
- ao_app->get_character_path(current_char, "custom_objections"))) {
- ui_custom_objection->show();
- QDir directory(
+ QString custom_objection_dir = ao_app->get_real_path(
ao_app->get_character_path(current_char, "custom_objections"));
+ if (dir_exists(custom_objection_dir)) {
+ ui_custom_objection->show();
+ QDir directory(custom_objection_dir);
QStringList custom_obj = directory.entryList(QStringList() << "*.png"
<< "*.gif"
<< "*.apng"
@@ -1631,7 +1642,7 @@ void Courtroom::list_music()
treeItem->setText(0, i_song_listname);
treeItem->setText(1, i_song);
- QString song_path = ao_app->get_music_path(i_song);
+ QString song_path = ao_app->get_real_path(ao_app->get_music_path(i_song));
if (file_exists(song_path))
treeItem->setBackground(0, found_brush);
@@ -1661,7 +1672,7 @@ void Courtroom::list_areas()
int n_listed_areas = 0;
for (int n_area = 0; n_area < area_list.size(); ++n_area) {
- QString i_area = "";
+ QString i_area = "";
i_area.append(area_list.at(n_area));
if (ao_app->arup_enabled) {
@@ -1751,7 +1762,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_auto_logging_enabled() && !ao_app->log_filename.isEmpty()) {
- QString full = "[OOC][" + QDateTime::currentDateTime().toUTC().toString() + "] " + p_name + ": " + p_message;
+ QString full = "[OOC][" + QDateTime::currentDateTimeUtc().toString() + "] " + p_name + ": " + p_message;
ao_app->append_to_file(full, ao_app->log_filename, true);
}
}
@@ -2190,7 +2201,7 @@ void Courtroom::log_chatmessage(QString f_message, int f_char_id, QString f_show
objection_mod = f_objection_mod.toInt();
}
- QString f_custom_theme = ao_app->get_chat(f_char);
+ //QString f_custom_theme = ao_app->get_chat(f_char);
if (objection_mod <= 4 && objection_mod >= 1) {
QString shout_message;
switch (objection_mod) {
@@ -2257,7 +2268,7 @@ void Courtroom::log_chatmessage(QString f_message, int f_char_id, QString f_show
if ((f_log_mode != IO_ONLY) && // if we're not in I/O only mode,
f_message.isEmpty() && // our current message is a blankpost,
!ic_chatlog_history.isEmpty() && // the chat log isn't empty,
- last_ic_message == f_displayname + ":" && // the chat log's last message is a blank post, and
+ last_ic_message == f_displayname + ":" && // the chat log's last message is a blank post, and
last_ic_message.mid(0, last_ic_message.lastIndexOf(":")) == f_displayname) // the blankpost's showname is the same as ours
return; // Skip adding message
switch (f_log_mode) {
@@ -2325,7 +2336,7 @@ bool Courtroom::handle_objection()
"custom", m_chatmessage[CHAR_NAME],
ao_app->get_chat(m_chatmessage[CHAR_NAME]));
}
- break;
+ break;
m_chatmessage[EMOTE_MOD] = 1;
}
ui_vp_objection->load_image(
@@ -2440,6 +2451,7 @@ void Courtroom::display_pair_character(QString other_charid, QString other_offse
// Play the other pair character's idle animation
QString filename = "(a)" + m_chatmessage[OTHER_EMOTE];
+ ui_vp_sideplayer_char->set_play_once(false);
ui_vp_sideplayer_char->load_image(filename, m_chatmessage[OTHER_NAME],
0, false);
}
@@ -2751,7 +2763,7 @@ void Courtroom::handle_callwords()
// Obtain the current call words (Really? It does File I/O on every single message???)
QStringList call_words = ao_app->get_call_words();
// Loop through each word in the call words list
- for (QString word : call_words) {
+ for (const QString &word : qAsConst(call_words)) {
// If our message contains that specific call word
if (f_message.contains(word, Qt::CaseInsensitive)) {
// Play the call word sfx on the modcall_player sound container
@@ -2771,7 +2783,7 @@ void Courtroom::display_evidence_image()
if (f_evi_id > 0 && f_evi_id <= local_evidence_list.size()) {
// shifted by 1 because 0 is no evidence per legacy standards
QString f_image = local_evidence_list.at(f_evi_id - 1).image;
- QString f_evi_name = local_evidence_list.at(f_evi_id - 1).name;
+ //QString f_evi_name = local_evidence_list.at(f_evi_id - 1).name;
// def jud and hlp should display the evidence icon on the RIGHT side
bool is_left_side = !(side == "def" || side == "hlp" ||
side == "jud" || side == "jur");
@@ -3119,7 +3131,7 @@ void Courtroom::append_ic_text(QString p_text, QString p_name, QString p_action,
if (log_timestamp) {
if (timestamp.isValid()) {
ui_ic_chatlog->textCursor().insertText(
- "[" + timestamp.toString("h:mm:ss AP") + "] ", normal);
+ "[" + timestamp.toString(log_timestamp_format) + "] ", normal);
} else {
qDebug() << "could not insert invalid timestamp";
}
@@ -3275,7 +3287,7 @@ void Courtroom::play_preanim(bool immediate)
void Courtroom::preanim_done()
{
// Currently, someone's talking over us mid-preanim...
- if (anim_state != 1 && anim_state != 4)
+ if (anim_state != 1 && anim_state != 4 && anim_state != 5)
return;
anim_state = 1;
switch(m_chatmessage[DESK_MOD].toInt()) {
@@ -3435,7 +3447,7 @@ void Courtroom::chat_tick()
}
ui_vp_chat_arrow->transform_mode = ao_app->get_misc_scaling(f_custom_theme);
ui_vp_chat_arrow->load_image("chat_arrow", f_custom_theme); // Chat stopped being processed, indicate that.
- QString f_message_filtered = filter_ic_text(f_message, true, -1, m_chatmessage[TEXT_COLOR].toInt());
+ QString f_message_filtered = filter_ic_text(f_message, true, -1, m_chatmessage[TEXT_COLOR].toInt());
for (int c = 0; c < max_colors; ++c) {
additive_previous = additive_previous.replace("$c" + QString::number(c), char_color_rgb_list.at(c).name(QColor::HexRgb));
f_message_filtered = f_message_filtered.replace("$c" + QString::number(c), char_color_rgb_list.at(c).name(QColor::HexRgb));
@@ -3740,7 +3752,7 @@ void Courtroom::set_self_offset(QString p_list) {
int self_offset_v;
if (self_offsets.length() <= 1)
self_offset_v = 0;
- else
+ else
self_offset_v = self_offsets[1].toInt();
ui_vp_player_char->move(ui_viewport->width() * self_offset / 100, ui_viewport->height() * self_offset_v / 100);
}
@@ -3875,7 +3887,7 @@ void Courtroom::handle_song(QStringList *p_contents)
void Courtroom::handle_wtce(QString p_wtce, int variant)
{
- QString sfx_file = "courtroom_sounds.ini";
+ //QString sfx_file = "courtroom_sounds.ini";
QString bg_misc = ao_app->read_design_ini("misc", ao_app->get_background_path("design.ini"));
QString sfx_name;
QString filename;
@@ -3987,7 +3999,9 @@ void Courtroom::on_ooc_return_pressed()
{
QString ooc_message = ui_ooc_chat_message->text();
- if (ooc_message.startsWith("/pos")) {
+ //We ignore it when the server is compatible with 2.8
+ //Using an arbitrary 2.8 feature flag certainly won't cause issues someday.
+ if (ooc_message.startsWith("/pos") & !ao_app->effects_enabled) {
if (ooc_message == "/pos jud") {
toggle_judge_buttons(true);
}
@@ -3995,149 +4009,13 @@ void Courtroom::on_ooc_return_pressed()
toggle_judge_buttons(false);
}
}
- else if (ooc_message.startsWith("/settings")) {
- ui_ooc_chat_message->clear();
- ao_app->call_settings_menu();
- append_server_chatmessage("CLIENT", tr("You opened the settings menu."),
- "1");
- return;
- }
- else if (ooc_message.startsWith("/pair")) {
- ui_ooc_chat_message->clear();
- ooc_message.remove(0, 6);
- bool ok;
- int whom = ooc_message.toInt(&ok);
- if (ok) {
- if (whom > -1) {
- other_charid = whom;
- QString msg = tr("You will now pair up with %1 if they also choose "
- "your character in return.")
- .arg(char_list.at(whom).name);
- append_server_chatmessage("CLIENT", msg, "1");
- }
- else {
- other_charid = -1;
- append_server_chatmessage(
- "CLIENT", tr("You are no longer paired with anyone."), "1");
- }
- }
- else {
- append_server_chatmessage("CLIENT",
- tr("Are you sure you typed that well? The char "
- "ID could not be recognised."),
- "1");
- }
- return;
- }
- else if (ooc_message.startsWith("/offset")) {
- ui_ooc_chat_message->clear();
- ooc_message.remove(0, 8);
-
- bool ok;
- int off = ooc_message.toInt(&ok);
- if (ok) {
- if (off >= -100 && off <= 100) {
- char_offset = off;
- QString msg =
- tr("You have set your offset to %1%%.").arg(QString::number(off));
- append_server_chatmessage("CLIENT", msg, "1");
- }
- else {
- append_server_chatmessage(
- "CLIENT", tr("Your offset must be between -100% and 100%!"), "1");
- }
- }
- else {
- append_server_chatmessage("CLIENT",
- tr("That offset does not look like one."), "1");
- }
- return;
- }
- else if (ooc_message.startsWith("/voffset")) {
- ui_ooc_chat_message->clear();
- ooc_message.remove(0, 8);
-
- bool ok;
- int off = ooc_message.toInt(&ok);
- if (ok) {
- if (off >= -100 && off <= 100) {
- char_vert_offset = off;
- QString msg = tr("You have set your vertical offset to %1%%.")
- .arg(QString::number(off));
- append_server_chatmessage("CLIENT", msg, "1");
- }
- else {
- append_server_chatmessage(
- "CLIENT",
- tr("Your vertical offset must be between -100% and 100%!"), "1");
- }
- }
- else {
- append_server_chatmessage(
- "CLIENT", tr("That vertical offset does not look like one."), "1");
- }
- return;
- }
- else if (ooc_message.startsWith("/switch_am")) {
- append_server_chatmessage(
- "CLIENT", tr("You switched your music and area list."), "1");
- on_switch_area_music_clicked();
- ui_ooc_chat_message->clear();
- return;
- }
- else if (ooc_message.startsWith("/enable_blocks")) {
- append_server_chatmessage("CLIENT",
- tr("You have forcefully enabled features that "
- "the server may not support. You may not be "
- "able to talk IC, or worse, because of this."),
- "1");
- ao_app->cccc_ic_support_enabled = true;
- ao_app->arup_enabled = true;
- ao_app->modcall_reason_enabled = true;
- on_reload_theme_clicked();
- ui_ooc_chat_message->clear();
- return;
- }
- else if (ooc_message.startsWith("/non_int_pre")) {
- if (ui_immediate->isChecked())
- append_server_chatmessage(
- "CLIENT", tr("Your pre-animations interrupt again."), "1");
- else
- append_server_chatmessage(
- "CLIENT", tr("Your pre-animations will not interrupt text."), "1");
- ui_immediate->setChecked(!ui_immediate->isChecked());
- ui_ooc_chat_message->clear();
- return;
- }
- else if (ooc_message.startsWith("/save_chatlog")) {
- QFile file("chatlog.txt");
-
- if (!file.open(QIODevice::WriteOnly | QIODevice::Text |
- QIODevice::Truncate)) {
- append_server_chatmessage(
- "CLIENT", tr("Couldn't open chatlog.txt to write into."), "1");
- ui_ooc_chat_message->clear();
- return;
- }
-
- QTextStream out(&file);
- out.setCodec("UTF-8");
-
- foreach (chatlogpiece item, ic_chatlog_history) {
- out << item.get_full() << '\n';
- }
-
- file.close();
-
- append_server_chatmessage("CLIENT", tr("The IC chatlog has been saved."),
- "1");
- ui_ooc_chat_message->clear();
- return;
- }
- else if (ooc_message.startsWith("/load_case")) {
+ if (ooc_message.startsWith("/load_case")) {
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
QStringList command = ooc_message.split(" ", QString::SkipEmptyParts);
-
+#else
+ QStringList command = ooc_message.split(" ", Qt::SkipEmptyParts);
+#endif
QDir casefolder("base/cases");
if (!casefolder.exists()) {
QDir::current().mkdir("base/" + casefolder.dirName());
@@ -4234,8 +4112,11 @@ void Courtroom::on_ooc_return_pressed()
return;
}
else if (ooc_message.startsWith("/save_case")) {
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
QStringList command = ooc_message.split(" ", QString::SkipEmptyParts);
-
+#else
+ QStringList command = ooc_message.split(" ", Qt::SkipEmptyParts);
+#endif
QDir casefolder("base/cases");
if (!casefolder.exists()) {
QDir::current().mkdir("base/" + casefolder.dirName());
@@ -4429,8 +4310,9 @@ void Courtroom::set_iniswap_dropdown()
ui_iniswap_remove->hide();
return;
}
- QStringList iniswaps = ao_app->get_list_file(
- ao_app->get_character_path(char_list.at(m_cid).name, "iniswaps.ini")) + ao_app->get_list_file(ao_app->get_base_path() + "iniswaps.ini");
+ QStringList iniswaps =
+ ao_app->get_list_file(ao_app->get_character_path(char_list.at(m_cid).name, "iniswaps.ini")) +
+ ao_app->get_list_file(ao_app->get_base_path() + "iniswaps.ini");
iniswaps.removeDuplicates();
iniswaps.prepend(char_list.at(m_cid).name);
if (iniswaps.size() <= 0) {
@@ -4486,7 +4368,8 @@ void Courtroom::on_iniswap_context_menu_requested(const QPoint &pos)
menu->setAttribute(Qt::WA_DeleteOnClose);
menu->addSeparator();
- if (file_exists(ao_app->get_character_path(current_char, "char.ini")))
+ if (file_exists(ao_app->get_real_path(
+ ao_app->get_character_path(current_char, "char.ini"))))
menu->addAction(QString("Edit " + current_char + "/char.ini"), this,
SLOT(on_iniswap_edit_requested()));
if (ui_iniswap_dropdown->itemText(ui_iniswap_dropdown->currentIndex()) !=
@@ -4497,7 +4380,7 @@ void Courtroom::on_iniswap_context_menu_requested(const QPoint &pos)
}
void Courtroom::on_iniswap_edit_requested()
{
- QString p_path = ao_app->get_character_path(current_char, "char.ini");
+ QString p_path = ao_app->get_real_path(ao_app->get_character_path(current_char, "char.ini"));
if (!file_exists(p_path))
return;
QDesktopServices::openUrl(QUrl::fromLocalFile(p_path));
@@ -4536,7 +4419,7 @@ void Courtroom::set_sfx_dropdown()
ao_app->get_base_path() + "soundlist.ini");
QStringList display_sounds;
- for (QString sound : sound_list) {
+ for (const QString &sound : qAsConst(sound_list)) {
QStringList unpacked = sound.split("=");
QString display = unpacked[0].trimmed();
if (unpacked.size() > 1)
@@ -4556,7 +4439,7 @@ void Courtroom::set_sfx_dropdown()
void Courtroom::on_sfx_dropdown_changed(int p_index)
{
- UNUSED(p_index);
+ Q_UNUSED(p_index);
ui_ic_chat_message->setFocus();
ui_sfx_remove->hide();
custom_sfx = "";
@@ -4574,7 +4457,8 @@ void Courtroom::on_sfx_context_menu_requested(const QPoint &pos)
menu->setAttribute(Qt::WA_DeleteOnClose);
menu->addSeparator();
- if (file_exists(ao_app->get_character_path(current_char, "soundlist.ini")))
+ if (file_exists(ao_app->get_real_path(
+ ao_app->get_character_path(current_char, "soundlist.ini"))))
menu->addAction(QString("Edit " + current_char + "/soundlist.ini"), this,
SLOT(on_sfx_edit_requested()));
else
@@ -4587,10 +4471,10 @@ void Courtroom::on_sfx_context_menu_requested(const QPoint &pos)
void Courtroom::on_sfx_edit_requested()
{
- QString p_path = ao_app->get_character_path(current_char, "soundlist.ini");
+ QString p_path = ao_app->get_real_path(ao_app->get_character_path(current_char, "soundlist.ini"));
if (!file_exists(p_path)) {
p_path = ao_app->get_base_path() + "soundlist.ini";
- }
+ }
QDesktopServices::openUrl(QUrl::fromLocalFile(p_path));
}
@@ -4623,12 +4507,11 @@ void Courtroom::set_effects_dropdown()
// ICON-MAKING HELL
QString p_effect = ao_app->read_char_ini(current_char, "effects", "Options");
- QString custom_path =
- ao_app->get_base_path() + "misc/" + p_effect + "/icons/";
- QString theme_path = ao_app->get_theme_path("effects/icons/");
- QString default_path = ao_app->get_theme_path("effects/icons/", "default");
+ VPath custom_path("misc/" + p_effect + "/icons/");
+ VPath theme_path = ao_app->get_theme_path("effects/icons/");
+ VPath default_path = ao_app->get_theme_path("effects/icons/", "default");
for (int i = 0; i < ui_effects_dropdown->count(); ++i) {
- QString entry = ui_effects_dropdown->itemText(i);
+ VPath entry = VPath(ui_effects_dropdown->itemText(i));
QString iconpath = ao_app->get_image_suffix(custom_path + entry);
if (!file_exists(iconpath)) {
iconpath = ao_app->get_image_suffix(theme_path + entry);
@@ -4662,9 +4545,9 @@ void Courtroom::on_effects_context_menu_requested(const QPoint &pos)
}
void Courtroom::on_effects_edit_requested()
{
- QString p_path = ao_app->get_theme_path("effects/");
+ QString p_path = ao_app->get_real_path(ao_app->get_theme_path("effects/"));
if (!dir_exists(p_path)) {
- p_path = ao_app->get_theme_path("effects/", "default");
+ p_path = ao_app->get_real_path(ao_app->get_theme_path("effects/", "default"));
if (!dir_exists(p_path)) {
return;
}
@@ -4674,7 +4557,7 @@ void Courtroom::on_effects_edit_requested()
void Courtroom::on_character_effects_edit_requested()
{
QString p_effect = ao_app->read_char_ini(current_char, "effects", "Options");
- QString p_path = ao_app->get_base_path() + "misc/" + p_effect + "/";
+ QString p_path = ao_app->get_real_path(VPath("misc/" + p_effect + "/"));
if (!dir_exists(p_path))
return;
@@ -4781,7 +4664,7 @@ void Courtroom::on_pair_list_clicked(QModelIndex p_index)
// Redo the character list.
QStringList sorted_pair_list;
- for (char_type i_char : char_list)
+ for (const char_type &i_char : qAsConst(char_list))
sorted_pair_list.append(i_char.name);
sorted_pair_list.sort();
@@ -4818,32 +4701,32 @@ void Courtroom::on_music_list_context_menu_requested(const QPoint &pos)
{
QMenu *menu = new QMenu(this);
menu->setAttribute(Qt::WA_DeleteOnClose);
- menu->addAction(QString(tr("Stop Current Song")), this, SLOT(music_stop()));
- menu->addAction(QString(tr("Play Random Song")), this, SLOT(music_random()));
+ menu->addAction(QString(tr("Stop Current Song")), this, &Courtroom::music_stop);
+ menu->addAction(QString(tr("Play Random Song")), this, &Courtroom::music_random);
menu->addSeparator();
menu->addAction(QString(tr("Expand All Categories")), this,
- SLOT(music_list_expand_all()));
+ &Courtroom::music_list_expand_all);
menu->addAction(QString(tr("Collapse All Categories")), this,
- SLOT(music_list_collapse_all()));
+ &Courtroom::music_list_collapse_all);
menu->addSeparator();
menu->addAction(new QAction(tr("Fade Out Previous"), this));
menu->actions().back()->setCheckable(true);
menu->actions().back()->setChecked(music_flags & FADE_OUT);
- connect(menu->actions().back(), SIGNAL(toggled(bool)), this,
- SLOT(music_fade_out(bool)));
+ connect(menu->actions().back(), &QAction::toggled, this,
+ &Courtroom::music_fade_out);
menu->addAction(new QAction(tr("Fade In"), this));
menu->actions().back()->setCheckable(true);
menu->actions().back()->setChecked(music_flags & FADE_IN);
- connect(menu->actions().back(), SIGNAL(toggled(bool)), this,
- SLOT(music_fade_in(bool)));
+ connect(menu->actions().back(), &QAction::toggled, this,
+ &Courtroom::music_fade_in);
menu->addAction(new QAction(tr("Synchronize"), this));
menu->actions().back()->setCheckable(true);
menu->actions().back()->setChecked(music_flags & SYNC_POS);
- connect(menu->actions().back(), SIGNAL(toggled(bool)), this,
- SLOT(music_synchronize(bool)));
+ connect(menu->actions().back(), &QAction::toggled, this,
+ &Courtroom::music_synchronize);
menu->popup(ui_music_list->mapToGlobal(pos));
}
@@ -4908,7 +4791,7 @@ void Courtroom::music_stop(bool no_effects)
// If the fake song is not present in the music list
if (!music_list.contains(fake_song)) {
// Loop through our music list
- for (QString song : music_list) {
+ for (const QString &song : qAsConst(music_list)) {
// Pick first song that does not contain a file extension
if (!song.contains('.')) {
// Use it as a fake song as the server we're working with must recognize song categories
@@ -4936,7 +4819,7 @@ void Courtroom::music_stop(bool no_effects)
void Courtroom::on_area_list_double_clicked(QTreeWidgetItem *p_item, int column)
{
column = 0; // The metadata
- UNUSED(column); // so gcc shuts up
+ Q_UNUSED(column); // so gcc shuts up
QString p_area = p_item->text(0);
QStringList packet_contents;
diff --git a/src/debug_functions.cpp b/src/debug_functions.cpp
index 1613a7d1..456aee8a 100644
--- a/src/debug_functions.cpp
+++ b/src/debug_functions.cpp
@@ -1,4 +1,5 @@
#include <QCoreApplication>
+#include <QElapsedTimer>
#include <QMessageBox>
#include <QTimer>
#include <functional>
diff --git a/src/demoserver.cpp b/src/demoserver.cpp
index ee0fcf25..db5e1bc5 100644
--- a/src/demoserver.cpp
+++ b/src/demoserver.cpp
@@ -97,7 +97,7 @@ void DemoServer::recv_data()
QStringList packet_list =
in_data.split("%", QString::SplitBehavior(QString::SkipEmptyParts));
- for (QString packet : packet_list) {
+ for (const QString &packet : packet_list) {
AOPacket ao_packet(packet);
handle_packet(ao_packet);
}
@@ -297,7 +297,7 @@ void DemoServer::load_demo(QString filename)
QTextStream out(&demo_file);
out.setCodec("UTF-8");
out << p_demo_data.dequeue();
- for (QString line : p_demo_data) {
+ for (const QString &line : qAsConst(p_demo_data)) {
out << "\n" << line;
}
demo_file.flush();
diff --git a/src/emotes.cpp b/src/emotes.cpp
index 82720076..541a6e20 100644
--- a/src/emotes.cpp
+++ b/src/emotes.cpp
@@ -15,13 +15,13 @@ void Courtroom::initialize_emotes()
ui_emote_dropdown = new QComboBox(this);
ui_emote_dropdown->setObjectName("ui_emote_dropdown");
- connect(ui_emote_left, SIGNAL(clicked()), this,
- SLOT(on_emote_left_clicked()));
- connect(ui_emote_right, SIGNAL(clicked()), this,
- SLOT(on_emote_right_clicked()));
+ connect(ui_emote_left, &AOButton::clicked, this,
+ &Courtroom::on_emote_left_clicked);
+ connect(ui_emote_right, &AOButton::clicked, this,
+ &Courtroom::on_emote_right_clicked);
- connect(ui_emote_dropdown, SIGNAL(activated(int)), this,
- SLOT(on_emote_dropdown_changed(int)));
+ connect(ui_emote_dropdown, QOverload<int>::of(&QComboBox::activated), this,
+ &Courtroom::on_emote_dropdown_changed);
}
void Courtroom::refresh_emotes()
@@ -74,8 +74,8 @@ void Courtroom::refresh_emotes()
f_emote->set_id(n);
- connect(f_emote, SIGNAL(emote_clicked(int)), this,
- SLOT(on_emote_clicked(int)));
+ connect(f_emote, &AOEmoteButton::emote_clicked, this,
+ &Courtroom::on_emote_clicked);
++x_mod_count;
@@ -96,7 +96,7 @@ void Courtroom::set_emote_page()
ui_emote_left->hide();
ui_emote_right->hide();
- for (AOEmoteButton *i_button : ui_emote_list) {
+ for (AOEmoteButton *i_button : qAsConst(ui_emote_list)) {
i_button->hide();
}
diff --git a/src/evidence.cpp b/src/evidence.cpp
index 2cc1d75a..fc305d23 100644
--- a/src/evidence.cpp
+++ b/src/evidence.cpp
@@ -6,7 +6,9 @@ void Courtroom::initialize_evidence()
ui_evidence->setObjectName("ui_evidence");
// ui_evidence_name = new QLabel(ui_evidence);
- ui_evidence_name = new AOLineEdit(ui_evidence);
+ ui_evidence_name = new QLineEdit(ui_evidence);
+ ui_evidence_name_filter = new AOLineEditFilter();
+ ui_evidence_name->installEventFilter(ui_evidence_name_filter);
ui_evidence_name->setAlignment(Qt::AlignCenter);
ui_evidence_name->setFrame(false);
ui_evidence_name->setObjectName("ui_evidence_name");
@@ -41,11 +43,14 @@ void Courtroom::initialize_evidence()
ui_evidence_delete = new AOButton(ui_evidence_overlay, ao_app);
ui_evidence_delete->setToolTip(tr("Destroy this piece of evidence"));
ui_evidence_delete->setObjectName("ui_evidence_delete");
- ui_evidence_image_name = new AOLineEdit(ui_evidence_overlay);
+ ui_evidence_image_name = new QLineEdit(ui_evidence_overlay);
+ ui_evidence_image_name_filter = new AOLineEditFilter();
+ ui_evidence_image_name->installEventFilter(ui_evidence_image_name_filter);
ui_evidence_image_name->setObjectName("ui_evidence_image_name");
ui_evidence_image_button = new AOButton(ui_evidence_overlay, ao_app);
ui_evidence_image_button->setText(tr("Choose.."));
ui_evidence_image_button->setObjectName("ui_evidence_image_button");
+ ui_evidence_image_button->setDisabled(true);
ui_evidence_x = new AOButton(ui_evidence_overlay, ao_app);
ui_evidence_x->setToolTip(
tr("Close the evidence display/editing overlay.\n"
@@ -56,50 +61,51 @@ void Courtroom::initialize_evidence()
"evidence and send them to server."));
ui_evidence_ok->setObjectName("ui_evidence_ok");
- ui_evidence_description = new AOTextEdit(ui_evidence_overlay);
+ ui_evidence_description = new QPlainTextEdit(ui_evidence_overlay);
ui_evidence_description->setFrameStyle(QFrame::NoFrame);
ui_evidence_description->setToolTip(
- tr("Double-click to edit. Press [X] to update your changes."));
+ tr("Click the pencil icon to edit. Press [X] to update your changes."));
ui_evidence_description->setObjectName("ui_evidence_description");
- connect(ui_evidence_name, SIGNAL(returnPressed()), this,
- SLOT(on_evidence_name_edited()));
- connect(ui_evidence_name, SIGNAL(double_clicked()), this,
- SLOT(on_evidence_name_double_clicked()));
- connect(ui_evidence_left, SIGNAL(clicked()), this,
- SLOT(on_evidence_left_clicked()));
- connect(ui_evidence_right, SIGNAL(clicked()), this,
- SLOT(on_evidence_right_clicked()));
- connect(ui_evidence_present, SIGNAL(clicked()), this,
- SLOT(on_evidence_present_clicked()));
- connect(ui_evidence_switch, SIGNAL(clicked()), this,
- SLOT(on_evidence_switch_clicked()));
- connect(ui_evidence_transfer, SIGNAL(clicked()), this,
- SLOT(on_evidence_transfer_clicked()));
- connect(ui_evidence_save, SIGNAL(clicked()), this,
- SLOT(on_evidence_save_clicked()));
- connect(ui_evidence_load, SIGNAL(clicked()), this,
- SLOT(on_evidence_load_clicked()));
-
- connect(ui_evidence_delete, SIGNAL(clicked()), this,
- SLOT(on_evidence_delete_clicked()));
- connect(ui_evidence_image_name, SIGNAL(returnPressed()), this,
- SLOT(on_evidence_image_name_edited()));
- connect(ui_evidence_image_name, SIGNAL(double_clicked()), this,
- SLOT(on_evidence_image_name_double_clicked()));
- connect(ui_evidence_image_button, SIGNAL(clicked()), this,
- SLOT(on_evidence_image_button_clicked()));
- connect(ui_evidence_x, SIGNAL(clicked()), this,
- SLOT(on_evidence_x_clicked()));
- connect(ui_evidence_ok, SIGNAL(clicked()), this,
- SLOT(on_evidence_ok_clicked()));
-
- connect(ui_evidence_name, SIGNAL(textChanged(QString)), this,
- SLOT(on_evidence_edited()));
- connect(ui_evidence_image_name, SIGNAL(textChanged(QString)), this,
- SLOT(on_evidence_edited()));
- connect(ui_evidence_description, SIGNAL(textChanged()), this,
- SLOT(on_evidence_edited()));
+ ui_evidence_edit = new AOButton(ui_evidence_overlay, ao_app);
+ ui_evidence_edit->setToolTip(tr("Edit this piece of evidence."));
+ ui_evidence_edit->setObjectName("ui_evidence_edit");
+
+ connect(ui_evidence_name, &QLineEdit::returnPressed, this,
+ &Courtroom::on_evidence_name_edited);
+ connect(ui_evidence_left, &AOButton::clicked, this,
+ &Courtroom::on_evidence_left_clicked);
+ connect(ui_evidence_right, &AOButton::clicked, this,
+ &Courtroom::on_evidence_right_clicked);
+ connect(ui_evidence_present, &AOButton::clicked, this,
+ &Courtroom::on_evidence_present_clicked);
+ connect(ui_evidence_switch, &AOButton::clicked, this,
+ &Courtroom::on_evidence_switch_clicked);
+ connect(ui_evidence_transfer, &AOButton::clicked, this,
+ &Courtroom::on_evidence_transfer_clicked);
+ connect(ui_evidence_save, &AOButton::clicked, this,
+ &Courtroom::on_evidence_save_clicked);
+ connect(ui_evidence_load, &AOButton::clicked, this,
+ &Courtroom::on_evidence_load_clicked);
+
+ connect(ui_evidence_delete, &AOButton::clicked, this,
+ &Courtroom::on_evidence_delete_clicked);
+ connect(ui_evidence_image_name, &QLineEdit::returnPressed, this,
+ &Courtroom::on_evidence_image_name_edited);
+ connect(ui_evidence_image_button, &AOButton::clicked, this,
+ &Courtroom::on_evidence_image_button_clicked);
+ connect(ui_evidence_x, &AOButton::clicked, this,
+ &Courtroom::on_evidence_x_clicked);
+ connect(ui_evidence_ok, &AOButton::clicked, this,
+ &Courtroom::on_evidence_ok_clicked);
+
+ connect(ui_evidence_name, &QLineEdit::textChanged, this,
+ &Courtroom::on_evidence_edited);
+ connect(ui_evidence_image_name, &QLineEdit::textChanged, this,
+ &Courtroom::on_evidence_image_name_edited);
+ connect(ui_evidence_description, &QPlainTextEdit::textChanged, this,
+ &Courtroom::on_evidence_edited);
+ connect(ui_evidence_edit, &AOButton::clicked, this, &Courtroom::on_evidence_edit_clicked);
ui_evidence->hide();
}
@@ -156,6 +162,9 @@ void Courtroom::refresh_evidence()
set_size_and_pos(ui_evidence_ok, "evidence_ok");
ui_evidence_ok->set_image("evidence_ok");
+ set_size_and_pos(ui_evidence_edit, "evidence_edit");
+ ui_evidence_edit->set_image("evidence_edit");
+
set_size_and_pos(ui_evidence_switch, "evidence_switch");
if (current_evidence_global) {
ui_evidence_switch->set_image("evidence_global");
@@ -227,12 +236,12 @@ void Courtroom::refresh_evidence()
f_evidence->set_id(n);
- connect(f_evidence, SIGNAL(evidence_clicked(int)), this,
- SLOT(on_evidence_clicked(int)));
- connect(f_evidence, SIGNAL(evidence_double_clicked(int)), this,
- SLOT(on_evidence_double_clicked(int)));
- connect(f_evidence, SIGNAL(on_hover(int, bool)), this,
- SLOT(on_evidence_hover(int, bool)));
+ connect(f_evidence, &AOEvidenceButton::evidence_clicked, this,
+ &Courtroom::on_evidence_clicked);
+ connect(f_evidence, &AOEvidenceButton::evidence_double_clicked, this,
+ &Courtroom::on_evidence_double_clicked);
+ connect(f_evidence, &AOEvidenceButton::on_hover, this,
+ &Courtroom::on_evidence_hover);
++x_mod_count;
@@ -281,7 +290,11 @@ void Courtroom::set_evidence_list(QVector<evi_type> &p_evi_list)
msgBox->setDetailedText(tr(
"Name: %1\n"
"Image: %2\n"
- "Description:\n%3").arg(local_evidence_list.at(current_evidence).name).arg(local_evidence_list.at(current_evidence).image).arg(local_evidence_list.at(current_evidence).description));
+ "Description:\n%3").arg(
+ local_evidence_list.at(current_evidence).name,
+ local_evidence_list.at(current_evidence).image,
+ local_evidence_list.at(current_evidence).description)
+ );
msgBox->setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgBox->setDefaultButton(QMessageBox::LastButton);
// msgBox->setWindowModality(Qt::NonModal);
@@ -309,7 +322,7 @@ void Courtroom::set_evidence_page()
ui_evidence_left->hide();
ui_evidence_right->hide();
- for (AOEvidenceButton *i_button : ui_evidence_list) {
+ for (AOEvidenceButton *i_button : qAsConst(ui_evidence_list)) {
i_button->hide();
}
@@ -368,26 +381,10 @@ void Courtroom::set_evidence_page()
void Courtroom::on_evidence_name_edited()
{
- ui_evidence_name->setReadOnly(true);
if (current_evidence >= local_evidence_list.size())
return;
}
-void Courtroom::on_evidence_name_double_clicked()
-{
- if (ui_evidence_overlay->isVisible()) {
- ui_evidence_name->setReadOnly(false);
- }
- else {
- ui_evidence_name->setReadOnly(true);
- }
-}
-
-void Courtroom::on_evidence_image_name_double_clicked()
-{
- ui_evidence_image_name->setReadOnly(false);
-}
-
void Courtroom::on_evidence_image_name_edited()
{
ui_evidence_image_name->setReadOnly(true);
@@ -445,7 +442,7 @@ void Courtroom::on_evidence_clicked(int p_id)
ui_evidence_name->setText(local_evidence_list.at(f_real_id).name);
- for (AOEvidenceButton *i_button : ui_evidence_list)
+ for (AOEvidenceButton *i_button : qAsConst(ui_evidence_list))
i_button->set_selected(false);
ui_evidence_list.at(p_id)->set_selected(true);
@@ -469,14 +466,14 @@ void Courtroom::on_evidence_double_clicked(int p_id)
ui_evidence_description->clear();
ui_evidence_description->appendPlainText(f_evi.description);
ui_evidence_description->setReadOnly(true);
- ui_evidence_description->setToolTip(tr("Double-click to edit..."));
+ ui_evidence_description->setToolTip(tr("Click the pencil to edit..."));
ui_evidence_name->setText(f_evi.name);
ui_evidence_name->setReadOnly(true);
- ui_evidence_name->setToolTip(tr("Double-click to edit..."));
+ ui_evidence_name->setToolTip(tr("Click the pencil to edit..."));
ui_evidence_image_name->setText(f_evi.image);
ui_evidence_image_name->setReadOnly(true);
- ui_evidence_image_name->setToolTip(tr("Double-click to edit..."));
+ ui_evidence_image_name->setToolTip(tr("Click the pencil to edit..."));
ui_evidence_overlay->show();
ui_evidence_ok->hide();
@@ -598,6 +595,8 @@ void Courtroom::on_evidence_ok_clicked()
ui_evidence_name->setReadOnly(true);
ui_evidence_description->setReadOnly(true);
ui_evidence_image_name->setReadOnly(true);
+ ui_evidence_edit->show();
+ ui_evidence_image_button->setDisabled(true);
if (current_evidence < local_evidence_list.size()) {
evi_type f_evi = local_evidence_list.at(current_evidence);
if (current_evidence_global) {
@@ -680,6 +679,22 @@ void Courtroom::on_evidence_transfer_clicked()
msgBox->exec();
}
+void Courtroom::on_evidence_edit_clicked()
+{
+ if (!ui_evidence_overlay->isVisible())
+ return;
+ if (!ui_evidence_edit->isHidden()) {
+ ui_evidence_name->setReadOnly(false);
+ ui_evidence_image_name->setReadOnly(false);
+ ui_evidence_description->setReadOnly(false);
+ ui_evidence_image_button->setDisabled(false);
+ ui_evidence_edit->hide();
+ }
+ else {
+ return;
+ }
+}
+
void Courtroom::on_evidence_edited()
{
if (current_evidence >=
@@ -704,6 +719,8 @@ void Courtroom::evidence_close()
ui_evidence_name->setToolTip("");
ui_evidence_image_name->setReadOnly(true);
ui_evidence_image_name->setToolTip("");
+ ui_evidence_edit->show();
+ ui_evidence_image_button->setDisabled(true);
ui_evidence_overlay->hide();
ui_ic_chat_message->setFocus();
}
diff --git a/src/file_functions.cpp b/src/file_functions.cpp
index e64a46bf..95e9b5f4 100644
--- a/src/file_functions.cpp
+++ b/src/file_functions.cpp
@@ -2,6 +2,9 @@
bool file_exists(QString file_path)
{
+ if (file_path.isEmpty())
+ return false;
+
QFileInfo check_file(file_path);
return check_file.exists() && check_file.isFile();
@@ -9,6 +12,9 @@ bool file_exists(QString file_path)
bool dir_exists(QString dir_path)
{
+ if (dir_path == "")
+ return false;
+
QDir check_dir(dir_path);
return check_dir.exists();
diff --git a/src/lobby.cpp b/src/lobby.cpp
index 5c3ff116..39b63e55 100644
--- a/src/lobby.cpp
+++ b/src/lobby.cpp
@@ -75,28 +75,28 @@ Lobby::Lobby(AOApplication *p_ao_app) : QMainWindow()
ui_cancel = new AOButton(ui_loading_background, ao_app);
ui_cancel->setObjectName("ui_cancel");
- connect(ui_public_servers, SIGNAL(clicked()), this,
- SLOT(on_public_servers_clicked()));
- connect(ui_favorites, SIGNAL(clicked()), this, SLOT(on_favorites_clicked()));
- connect(ui_refresh, SIGNAL(pressed()), this, SLOT(on_refresh_pressed()));
- connect(ui_refresh, SIGNAL(released()), this, SLOT(on_refresh_released()));
- connect(ui_add_to_fav, SIGNAL(pressed()), this,
- SLOT(on_add_to_fav_pressed()));
- connect(ui_add_to_fav, SIGNAL(released()), this,
- SLOT(on_add_to_fav_released()));
- connect(ui_connect, SIGNAL(pressed()), this, SLOT(on_connect_pressed()));
- connect(ui_connect, SIGNAL(released()), this, SLOT(on_connect_released()));
- connect(ui_about, SIGNAL(clicked()), this, SLOT(on_about_clicked()));
- connect(ui_settings, SIGNAL(clicked()), this, SLOT(on_settings_clicked()));
- connect(ui_server_list, SIGNAL(itemClicked(QTreeWidgetItem *, int)), this,
- SLOT(on_server_list_clicked(QTreeWidgetItem *, int)));
- connect(ui_server_list, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
- this, SLOT(on_server_list_doubleclicked(QTreeWidgetItem *, int)));
- connect(ui_server_search, SIGNAL(textChanged(QString)), this,
- SLOT(on_server_search_edited(QString)));
- connect(ui_chatmessage, SIGNAL(returnPressed()), this,
- SLOT(on_chatfield_return_pressed()));
- connect(ui_cancel, SIGNAL(clicked()), ao_app, SLOT(loading_cancelled()));
+ 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_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_search, &QLineEdit::textChanged, this,
+ &Lobby::on_server_search_edited);
+ connect(ui_chatmessage, &QLineEdit::returnPressed, this,
+ &Lobby::on_chatfield_return_pressed);
+ connect(ui_cancel, &AOButton::clicked, ao_app, &AOApplication::loading_cancelled);
ui_connect->setEnabled(false);
@@ -237,6 +237,12 @@ void Lobby::set_stylesheet(QWidget *widget)
void Lobby::set_stylesheets()
{
set_stylesheet(this);
+ this->setStyleSheet(
+ "QFrame { background-color:transparent; } "
+ "QAbstractItemView { background-color: transparent; color: black; } "
+ "QLineEdit { background-color:transparent; }"
+ + this->styleSheet()
+ );
}
void Lobby::set_font(QWidget *widget, QString p_identifier)
@@ -510,7 +516,7 @@ void Lobby::list_servers()
ui_server_search->setText("");
int i = 0;
- for (server_type i_server : ao_app->get_server_list()) {
+ for (const server_type &i_server : qAsConst(ao_app->get_server_list())) {
QTreeWidgetItem *treeItem = new QTreeWidgetItem(ui_server_list);
treeItem->setData(0, Qt::DisplayRole, i);
treeItem->setText(1, i_server.name);
@@ -526,7 +532,7 @@ void Lobby::list_favorites()
ui_server_list->clear();
int i = 0;
- for (server_type i_server : ao_app->get_favorite_list()) {
+ for (const server_type &i_server : qAsConst(ao_app->get_favorite_list())) {
QTreeWidgetItem *treeItem = new QTreeWidgetItem(ui_server_list);
treeItem->setData(0, Qt::DisplayRole, i);
treeItem->setText(1, i_server.name);
@@ -573,9 +579,9 @@ void Lobby::append_error(QString f_message)
void Lobby::set_player_count(int players_online, int max_players)
{
- QString f_string = tr("Online: %1/%2")
- .arg(QString::number(players_online))
- .arg(QString::number(max_players));
+ QString f_string = tr("Online: %1/%2").arg(
+ QString::number(players_online),
+ QString::number(max_players));
ui_player_count->setText(f_string);
}
diff --git a/src/networkmanager.cpp b/src/networkmanager.cpp
index 89a9bff4..c1e8480f 100644
--- a/src/networkmanager.cpp
+++ b/src/networkmanager.cpp
@@ -16,10 +16,10 @@ NetworkManager::NetworkManager(AOApplication *parent) : QObject(parent)
http = new QNetworkAccessManager(this);
heartbeat_timer = new QTimer(this);
- connect(server_socket, SIGNAL(readyRead()), this,
- SLOT(handle_server_packet()));
- connect(server_socket, SIGNAL(disconnected()), ao_app,
- SLOT(server_disconnected()));
+ connect(server_socket, &QTcpSocket::readyRead, this,
+ &NetworkManager::handle_server_packet);
+ connect(server_socket, &QTcpSocket::disconnected, ao_app,
+ &AOApplication::server_disconnected);
QString master_config =
ao_app->configini->value("master", "").value<QString>();
diff --git a/src/path_functions.cpp b/src/path_functions.cpp
index dbf1cc40..6fd06e79 100644
--- a/src/path_functions.cpp
+++ b/src/path_functions.cpp
@@ -5,6 +5,7 @@
#include <QDir>
#include <QRegExp>
#include <QStandardPaths>
+#include <QStringBuilder>
#ifdef BASE_OVERRIDE
#include "base_override.h"
@@ -39,72 +40,57 @@ QString AOApplication::get_base_path()
return base_path;
}
-QString AOApplication::get_data_path() { return get_base_path() + "data/"; }
-
-QString AOApplication::get_theme_path(QString p_file, QString p_theme)
+VPath AOApplication::get_theme_path(QString p_file, QString p_theme)
{
if (p_theme == "")
p_theme = current_theme;
- QString path = get_base_path() + "themes/" + p_theme + "/" + p_file;
- return get_case_sensitive_path(path);
+ return VPath("themes/" + p_theme + "/" + p_file);
}
-QString AOApplication::get_character_path(QString p_char, QString p_file)
+VPath AOApplication::get_character_path(QString p_char, QString p_file)
{
- QString path = get_base_path() + "characters/" + p_char + "/" + p_file;
- return get_case_sensitive_path(path);
+ return VPath("characters/" + p_char + "/" + p_file);
}
-QString AOApplication::get_misc_path(QString p_misc, QString p_file)
+VPath AOApplication::get_misc_path(QString p_misc, QString p_file)
{
- QString path = get_base_path() + "misc/" + p_misc + "/" + p_file;
-#ifndef CASE_SENSITIVE_FILESYSTEM
- return path;
-#else
- return get_case_sensitive_path(path);
-#endif
+ return VPath("misc/" + p_misc + "/" + p_file);
}
-QString AOApplication::get_sounds_path(QString p_file)
+VPath AOApplication::get_sounds_path(QString p_file)
{
- QString path = get_base_path() + "sounds/general/" + p_file;
- return get_case_sensitive_path(path);
+ return VPath("sounds/general/" + p_file);
}
-QString AOApplication::get_music_path(QString p_song)
+VPath AOApplication::get_music_path(QString p_song)
{
if (p_song.startsWith("http")) {
- return p_song; // url
+ return VPath(p_song); // url
}
- QString path = get_base_path() + "sounds/music/" + p_song;
- return get_case_sensitive_path(path);
+ return VPath("sounds/music/" + p_song);
}
-QString AOApplication::get_background_path(QString p_file)
+VPath AOApplication::get_background_path(QString p_file)
{
- QString path = get_base_path() + "background/" +
- w_courtroom->get_current_background() + "/" + p_file;
if (courtroom_constructed) {
- return get_case_sensitive_path(path);
+ return VPath("background/" + w_courtroom->get_current_background() + "/" + p_file);
}
return get_default_background_path(p_file);
}
-QString AOApplication::get_default_background_path(QString p_file)
+VPath AOApplication::get_default_background_path(QString p_file)
{
- QString path = get_base_path() + "background/default/" + p_file;
- return get_case_sensitive_path(path);
+ return VPath("background/default/" + p_file);
}
-QString AOApplication::get_evidence_path(QString p_file)
+VPath AOApplication::get_evidence_path(QString p_file)
{
- QString path = get_base_path() + "evidence/" + p_file;
- return get_case_sensitive_path(path);
+ return VPath("evidence/" + p_file);
}
-QStringList AOApplication::get_asset_paths(QString p_element, QString p_theme, QString p_subtheme, QString p_default_theme, QString p_misc, QString p_character, QString p_placeholder)
+QVector<VPath> AOApplication::get_asset_paths(QString p_element, QString p_theme, QString p_subtheme, QString p_default_theme, QString p_misc, QString p_character, QString p_placeholder)
{
- QStringList pathlist;
+ QVector<VPath> pathlist;
if (p_character != "")
pathlist += get_character_path(p_character, p_element); // Character folder
if (p_misc != "" && p_theme != "" && p_subtheme != "")
@@ -119,7 +105,7 @@ QStringList AOApplication::get_asset_paths(QString p_element, QString p_theme, Q
pathlist += get_theme_path(p_element, p_theme); // Theme path
if (p_default_theme != "")
pathlist += get_theme_path(p_element, p_default_theme); // Default theme path
- pathlist += p_element; // The path by itself
+ pathlist += VPath(p_element); // The path by itself
if (p_placeholder != "" && p_theme != "")
pathlist += get_theme_path(p_placeholder, p_theme); // Placeholder path
if (p_placeholder != "" && p_default_theme != "")
@@ -127,52 +113,48 @@ QStringList AOApplication::get_asset_paths(QString p_element, QString p_theme, Q
return pathlist;
}
-QString AOApplication::get_asset_path(QStringList pathlist)
+QString AOApplication::get_asset_path(QVector<VPath> pathlist)
{
- QString path;
- for (QString p : pathlist) {
- p = get_case_sensitive_path(p);
- if (file_exists(p)) {
- path = p;
- break;
+ for (const VPath &p : pathlist) {
+ QString path = get_real_path(p);
+ if (!path.isEmpty()) {
+ return path;
}
}
- return path;
+ return QString();
}
-QString AOApplication::get_image_path(QStringList pathlist, bool static_image)
+QString AOApplication::get_image_path(QVector<VPath> pathlist, bool static_image)
{
- QString path;
- for (QString p : pathlist) {
- p = get_case_sensitive_path(get_image_suffix(p, static_image));
- if (file_exists(p)) {
- path = p;
- break;
- }
+ for (const VPath &p : pathlist) {
+ QString path = get_image_suffix(p, static_image);
+ if (!path.isEmpty()) {
+ return path;
+ }
}
- return path;
+ return QString();
}
-QString AOApplication::get_sfx_path(QStringList pathlist)
+QString AOApplication::get_sfx_path(QVector<VPath> pathlist)
{
- QString path;
- for (QString p : pathlist) {
- p = get_case_sensitive_path(get_sfx_suffix(p));
- if (file_exists(p)) {
- path = p;
- break;
+ for (const VPath &p : pathlist) {
+ QString path = get_sfx_suffix(p);
+ if (!path.isEmpty()) {
+ return path;
}
}
- return path;
+ return QString();
}
+
QString AOApplication::get_config_value(QString p_identifier, QString p_config, QString p_theme, QString p_subtheme, QString p_default_theme, QString p_misc)
{
QString path;
// qDebug() << "got request for" << p_identifier << "in" << p_config;
- for (QString p : get_asset_paths(p_config, p_theme, p_subtheme, p_default_theme, p_misc)) {
- p = get_case_sensitive_path(p);
- if (file_exists(p)) {
- QSettings settings(p, QSettings::IniFormat);
+ const auto paths = get_asset_paths(p_config, p_theme, p_subtheme, p_default_theme, p_misc);
+ for (const VPath &p : paths) {
+ path = get_real_path(p);
+ if (!path.isEmpty()) {
+ QSettings settings(path, QSettings::IniFormat);
settings.setIniCodec("UTF-8");
QVariant value = settings.value(p_identifier);
if (value.type() == QVariant::StringList) {
@@ -193,25 +175,22 @@ QString AOApplication::get_asset(QString p_element, QString p_theme, QString p_s
return get_asset_path(get_asset_paths(p_element, p_theme, p_subtheme, p_default_theme, p_misc, p_character, p_placeholder));
}
-QString AOApplication::get_image(QString p_element, QString p_theme, QString p_subtheme, QString p_default_theme, QString p_misc, QString p_character, QString p_placeholder)
+QString AOApplication::get_image(QString p_element, QString p_theme, QString p_subtheme, QString p_default_theme, QString p_misc, QString p_character, QString p_placeholder,
+ bool static_image)
{
- return get_image_path(get_asset_paths(p_element, p_theme, p_subtheme, p_default_theme, p_misc, p_character, p_placeholder));
+ return get_image_path(get_asset_paths(p_element, p_theme, p_subtheme, p_default_theme, p_misc, p_character, p_placeholder), static_image);
}
QString AOApplication::get_sfx(QString p_sfx, QString p_misc, QString p_character)
{
- QStringList pathlist = get_asset_paths(p_sfx, current_theme, get_subtheme(), default_theme, p_misc, p_character);
+ QVector<VPath> pathlist = get_asset_paths(p_sfx, current_theme, get_subtheme(), default_theme, p_misc, p_character);
pathlist += get_sounds_path(p_sfx); // Sounds folder path
return get_sfx_path(pathlist);
}
QString AOApplication::get_case_sensitive_path(QString p_file)
{
- // no path traversal above base folder
- if (!(p_file.startsWith(get_base_path())))
- return get_base_path() + p_file;
-
- #ifdef CASE_SENSITIVE_FILESYSTEM
+#ifdef CASE_SENSITIVE_FILESYSTEM
// first, check to see if it's actually there (also serves as base case for
// recursion)
QFileInfo file(p_file);
@@ -219,6 +198,7 @@ QString AOApplication::get_case_sensitive_path(QString p_file)
if (exists(p_file))
return p_file;
+
QString file_parent_dir = get_case_sensitive_path(file.absolutePath());
// second, does it exist in the new parent dir?
@@ -226,14 +206,20 @@ QString AOApplication::get_case_sensitive_path(QString p_file)
return file_parent_dir + "/" + file_basename;
// last resort, dirlist parent dir and find case insensitive match
- QRegExp file_rx =
- QRegExp(file_basename, Qt::CaseInsensitive, QRegExp::FixedString);
- QStringList files = QDir(file_parent_dir).entryList();
- int result = files.indexOf(file_rx);
+ if (!dir_listing_exist_cache.contains(qHash(file_parent_dir))) {
+ QStringList files = QDir(file_parent_dir).entryList();
+ for (const QString &file : files) {
+ dir_listing_cache.insert(qHash(file_parent_dir % QChar('/') % file.toLower()), file);
+ }
+ dir_listing_exist_cache.insert(qHash(file_parent_dir));
+ }
+ QString found_file = dir_listing_cache.value(
+ qHash(file_parent_dir % QChar('/') % file_basename.toLower()));
- if (result != -1)
- return file_parent_dir + "/" + files.at(result);
+ if (!found_file.isEmpty()) {
+ return file_parent_dir + "/" + found_file;
+ }
// if nothing is found, let the caller handle the missing file
return file_parent_dir + "/" + file_basename;
@@ -241,3 +227,81 @@ QString AOApplication::get_case_sensitive_path(QString p_file)
return p_file;
#endif
}
+
+QString AOApplication::get_real_path(const VPath &vpath) {
+ // Try cache first
+ QString phys_path = asset_lookup_cache.value(qHash(vpath));
+ if (!phys_path.isEmpty() && exists(phys_path)) {
+ return phys_path;
+ }
+
+ // Cache miss; try all known mount paths
+ QStringList bases = get_mount_paths();
+ bases.push_front(get_base_path());
+
+ for (const QString &base : bases) {
+ QDir baseDir(base);
+ QString path = baseDir.absoluteFilePath(vpath.toQString());
+ if (!path.startsWith(baseDir.absolutePath())) {
+ qWarning() << "invalid path" << path << "(path is outside vfs)";
+ break;
+ }
+ path = get_case_sensitive_path(path);
+ if (exists(path)) {
+ asset_lookup_cache.insert(qHash(vpath), path);
+ return path;
+ }
+ }
+
+ // Not found in mount paths; check if the file is remote
+ QString remotePath = vpath.toQString();
+ if (remotePath.startsWith("http:") || remotePath.startsWith("https:")) {
+ return remotePath;
+ }
+
+ // File or directory not found
+ return QString();
+}
+
+// Special case of get_real_path where multiple suffixes need to be tried
+// on each mount path.
+QString AOApplication::get_real_suffixed_path(const VPath &vpath,
+ const QStringList &suffixes) {
+ // Try cache first
+ QString phys_path = asset_lookup_cache.value(qHash(vpath));
+ if (!phys_path.isEmpty() && exists(phys_path)) {
+ for (const QString &suffix : suffixes) { // make sure cached asset is the right type
+ if (phys_path.endsWith(suffix, Qt::CaseInsensitive))
+ return phys_path;
+ }
+ }
+
+ // Cache miss; try each suffix on all known mount paths
+ QStringList bases = get_mount_paths();
+ bases.push_front(get_base_path());
+
+ for (const QString &base : bases) {
+ for (const QString &suffix : suffixes) {
+ QDir baseDir(base);
+ QString path = baseDir.absoluteFilePath(vpath.toQString() + suffix);
+ if (!path.startsWith(baseDir.absolutePath())) {
+ qWarning() << "invalid path" << path << "(path is outside vfs)";
+ break;
+ }
+ path = get_case_sensitive_path(path);
+ if (exists(path)) {
+ asset_lookup_cache.insert(qHash(vpath), path);
+ return path;
+ }
+ }
+ }
+
+ // File or directory not found
+ return QString();
+}
+
+void AOApplication::invalidate_lookup_cache() {
+ asset_lookup_cache.clear();
+ dir_listing_cache.clear();
+ dir_listing_exist_cache.clear();
+}
diff --git a/src/scrolltext.cpp b/src/scrolltext.cpp
index d5da6ce5..b526a8ab 100644
--- a/src/scrolltext.cpp
+++ b/src/scrolltext.cpp
@@ -9,7 +9,7 @@ ScrollText::ScrollText(QWidget *parent) : QWidget(parent), scrollPos(0)
setSeparator(" --- ");
- connect(&timer, SIGNAL(timeout()), this, SLOT(timer_timeout()));
+ connect(&timer, &QTimer::timeout, this, &ScrollText::timer_timeout);
timer.setInterval(50);
}
diff --git a/src/text_file_functions.cpp b/src/text_file_functions.cpp
index d0bebbb1..07a93935 100644
--- a/src/text_file_functions.cpp
+++ b/src/text_file_functions.cpp
@@ -89,6 +89,12 @@ bool AOApplication::get_log_timestamp()
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 =
@@ -130,6 +136,11 @@ QStringList AOApplication::get_call_words()
return get_list_file(get_base_path() + "callwords.ini");
}
+QStringList AOApplication::get_list_file(VPath path)
+{
+ return get_list_file(get_real_path(path));
+}
+
QStringList AOApplication::get_list_file(QString p_file)
{
QStringList return_value;
@@ -280,6 +291,12 @@ QVector<server_type> AOApplication::read_serverlist_txt()
}
QString AOApplication::read_design_ini(QString p_identifier,
+ VPath p_design_path)
+{
+ return read_design_ini(p_identifier, get_real_path(p_design_path));
+}
+
+QString AOApplication::read_design_ini(QString p_identifier,
QString p_design_path)
{
QSettings settings(p_design_path, QSettings::IniFormat);
@@ -448,12 +465,14 @@ QString AOApplication::get_chat_markup(QString p_identifier, QString p_chat)
return value.toUtf8();
// Backwards ass compatibility
- QStringList backwards_paths{get_theme_path("misc/" + p_chat + "/config.ini"),
- get_base_path() + "misc/" + p_chat +
- "/config.ini",
- get_theme_path("misc/default/config.ini"),
- get_base_path() + "misc/default/config.ini"};
- for (const QString &p : backwards_paths) {
+ QVector<VPath> backwards_paths {
+ get_theme_path("misc/" + p_chat + "/config.ini"),
+ VPath("misc/" + p_chat + "/config.ini"),
+ get_theme_path("misc/default/config.ini"),
+ VPath("misc/default/config.ini")
+ };
+
+ for (const VPath &p : backwards_paths) {
QString value = read_design_ini(p_identifier, p);
if (!value.isEmpty()) {
return value.toUtf8();
@@ -490,36 +509,21 @@ QString AOApplication::get_court_sfx(QString p_identifier, QString p_misc)
return "";
}
-QString AOApplication::get_sfx_suffix(QString sound_to_check)
+QString AOApplication::get_sfx_suffix(VPath sound_to_check)
{
- if (file_exists(sound_to_check))
- return sound_to_check;
- if (file_exists(sound_to_check + ".opus"))
- return sound_to_check + ".opus";
- if (file_exists(sound_to_check + ".ogg"))
- return sound_to_check + ".ogg";
- if (file_exists(sound_to_check + ".mp3"))
- return sound_to_check + ".mp3";
- if (file_exists(sound_to_check + ".mp4"))
- return sound_to_check + ".mp4";
- return sound_to_check + ".wav";
+ return get_real_suffixed_path(sound_to_check,
+ {".opus", ".ogg", ".mp3", ".wav" });
}
-QString AOApplication::get_image_suffix(QString path_to_check, bool static_image)
+QString AOApplication::get_image_suffix(VPath path_to_check, bool static_image)
{
- if (file_exists(path_to_check))
- return path_to_check;
- // A better method would to actually use AOImageReader and see if these images have more than 1 frame.
- // However, that might not be performant.
+ QStringList suffixes {};
if (!static_image) {
- if (file_exists(path_to_check + ".webp"))
- return path_to_check + ".webp";
- if (file_exists(path_to_check + ".apng"))
- return path_to_check + ".apng";
- if (file_exists(path_to_check + ".gif"))
- return path_to_check + ".gif";
+ suffixes.append({ ".webp", ".apng", ".gif" });
}
- return path_to_check + ".png";
+ suffixes.append(".png");
+
+ return get_real_suffixed_path(path_to_check, suffixes);
}
// returns whatever is to the right of "search_line =" within target_tag and
@@ -528,7 +532,7 @@ QString AOApplication::get_image_suffix(QString path_to_check, bool static_image
QString AOApplication::read_char_ini(QString p_char, QString p_search_line,
QString target_tag)
{
- QSettings settings(get_character_path(p_char, "char.ini"),
+ QSettings settings(get_real_path(get_character_path(p_char, "char.ini")),
QSettings::IniFormat);
settings.beginGroup(target_tag);
settings.setIniCodec("UTF-8");
@@ -540,7 +544,7 @@ QString AOApplication::read_char_ini(QString p_char, QString p_search_line,
void AOApplication::set_char_ini(QString p_char, QString value,
QString p_search_line, QString target_tag)
{
- QSettings settings(get_character_path(p_char, "char.ini"),
+ QSettings settings(get_real_path(get_character_path(p_char, "char.ini")),
QSettings::IniFormat);
settings.beginGroup(target_tag);
settings.setValue(p_search_line, value);
@@ -548,10 +552,10 @@ void AOApplication::set_char_ini(QString p_char, QString value,
}
// returns all the values of target_tag
-QStringList AOApplication::read_ini_tags(QString p_path, QString target_tag)
+QStringList AOApplication::read_ini_tags(VPath p_path, QString target_tag)
{
QStringList r_values;
- QSettings settings(p_path, QSettings::IniFormat);
+ QSettings settings(get_real_path(p_path), QSettings::IniFormat);
settings.setIniCodec("UTF-8");
if (!target_tag.isEmpty())
settings.beginGroup(target_tag);
@@ -1096,6 +1100,11 @@ 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>()