From a023657348051cbc7c8ea29e3b37f3e2e3fd16d8 Mon Sep 17 00:00:00 2001 From: oldmud0 Date: Sat, 29 May 2021 10:43:53 -0500 Subject: [PATCH 01/35] Partial: Add mount list to options dialog --- include/aoapplication.h | 1 - include/aooptionsdialog.h | 11 ++++++ src/aoapplication.cpp | 2 +- src/aooptionsdialog.cpp | 75 +++++++++++++++++++++++++++++++++++++++ src/path_functions.cpp | 2 -- 5 files changed, 87 insertions(+), 4 deletions(-) diff --git a/include/aoapplication.h b/include/aoapplication.h index 9fa8c75..b0a87b5 100644 --- a/include/aoapplication.h +++ b/include/aoapplication.h @@ -130,7 +130,6 @@ 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); diff --git a/include/aooptionsdialog.h b/include/aooptionsdialog.h index e88ce54..62ce2f7 100644 --- a/include/aooptionsdialog.h +++ b/include/aooptionsdialog.h @@ -23,6 +23,7 @@ #include #include +#include #include class Lobby; @@ -170,6 +171,16 @@ 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; + bool needs_default_audiodev(); void update_values(); diff --git a/src/aoapplication.cpp b/src/aoapplication.cpp index 00175e5..dd75b0a 100644 --- a/src/aoapplication.cpp +++ b/src/aoapplication.cpp @@ -18,7 +18,7 @@ AOApplication::AOApplication(int &argc, char **argv) : QApplication(argc, argv) discord = new AttorneyOnline::Discord(); QObject::connect(net_manager, SIGNAL(ms_connect_finished(bool, bool)), SLOT(ms_connect_finished(bool, bool))); - qApp->setStyleSheet("QFrame {background-color:transparent;} QAbstractItemView {background-color: transparent; color: black;}; QLineEdit {background-color:transparent;}"); + // qApp->setStyleSheet("QFrame {background-color:transparent;} QAbstractItemView {background-color: transparent; color: black;}; QLineEdit {background-color:transparent;}"); } AOApplication::~AOApplication() diff --git a/src/aooptionsdialog.cpp b/src/aooptionsdialog.cpp index 091528a..6f1b348 100644 --- a/src/aooptionsdialog.cpp +++ b/src/aooptionsdialog.cpp @@ -4,6 +4,8 @@ #include "lobby.h" #include "bass.h" +#include + AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) : QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint) { @@ -874,7 +876,75 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) ui_casing_layout->setWidget(row, QFormLayout::FieldRole, ui_log_cb); + // 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; + ui_mount_list->addItem(dir); + }); + + 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; + ui_mount_list->removeItemWidget(selected[0]); + }); + + 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; + ui_mount_list->setEditTriggers() + }); + + 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); + update_values(); + // When we're done, we should continue the updates! setUpdatesEnabled(true); } @@ -944,6 +1014,11 @@ void AOOptionsDialog::update_values() { ui_sfx_volume_spinbox->setValue(ao_app->get_default_sfx()); ui_blips_volume_spinbox->setValue(ao_app->get_default_blip()); ui_bliprate_spinbox->setValue(ao_app->read_blip_rate()); + + auto *defaultMount = new QListWidgetItem(tr("%1 (default)") + .arg(ao_app->get_base_path())); + defaultMount->setFlags(Qt::ItemFlag::NoItemFlags); + ui_mount_list->addItem(defaultMount); } void AOOptionsDialog::save_pressed() diff --git a/src/path_functions.cpp b/src/path_functions.cpp index 5107349..9700529 100644 --- a/src/path_functions.cpp +++ b/src/path_functions.cpp @@ -39,8 +39,6 @@ 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) { if (p_theme == "") From d27501313cae78b838c1e738ebfaeae4740a23b4 Mon Sep 17 00:00:00 2001 From: oldmud0 Date: Sat, 5 Jun 2021 14:58:40 -0500 Subject: [PATCH 02/35] Finish mounting feature To pull this one off, a new class called VPath was created that denotes "virtual" paths that can exist anywhere among the list of mount points. It is functionally identical to QString, except that implicit conversion between QString and VPath is not allowed. This makes it easy to spot errors in path resolution at compile time, since get_real_path must be called to resolve a VPath into an absolute path that can be passed into a Qt function as a QString. Other functions, such as the get_*_suffix functions, also return an absolute path QString for convenience. As for the rest of the functions that return a VPath, you will need to call get_real_path yourself. Finally, a path resolution cache was added to try to avoid blowing up what is already a massive lookup cost for assets. The cache is invalidated when the mount path list is changed. Currently, this cache isn't bounded. Might need to write an LRU cache if issues arise. --- include/aoapplication.h | 62 ++++++++++---- include/aolayer.h | 1 + include/aooptionsdialog.h | 3 + src/aoapplication.cpp | 1 + src/aobutton.cpp | 2 +- src/aoevidencebutton.cpp | 8 +- src/aoevidencedisplay.cpp | 3 +- src/aoimage.cpp | 17 ++-- src/aolayer.cpp | 2 +- src/aomusicplayer.cpp | 2 +- src/aooptionsdialog.cpp | 73 ++++++++++++++++- src/charselect.cpp | 4 +- src/courtroom.cpp | 44 +++++----- src/file_functions.cpp | 3 + src/path_functions.cpp | 159 +++++++++++++++++++----------------- src/text_file_functions.cpp | 80 ++++++++++-------- 16 files changed, 296 insertions(+), 168 deletions(-) diff --git a/include/aoapplication.h b/include/aoapplication.h index b0a87b5..0c61d7b 100644 --- a/include/aoapplication.h +++ b/include/aoapplication.h @@ -37,6 +37,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) +{ + return qHash(key.toQString(), seed); +} + class AOApplication : public QApplication { Q_OBJECT @@ -130,23 +149,25 @@ public: // implementation in path_functions.cpp QString get_base_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 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 pathlist); + QString get_image_path(QVector pathlist, bool static_image=false); + QString get_sfx_path(QVector 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); + void invalidate_lookup_cache(); ////// Functions for reading and writing files ////// // Implementations file_functions.cpp @@ -281,6 +302,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 @@ -304,6 +326,7 @@ public: QVector 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 @@ -332,19 +355,22 @@ public: // Returns the sfx with p_identifier from courtroom_sounds.ini in the current theme path QString get_court_sfx(QString p_identifier, QString p_misc=""); + // Find the correct suffix for a given file + QString get_suffix(VPath file_to_check, QStringList suffixes); + // 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, @@ -489,6 +515,9 @@ public: // Get if the theme is animated bool get_animated_theme(); + // Get a list of custom mount paths + QStringList get_mount_paths(); + // Currently defined subtheme QString subtheme; @@ -514,6 +543,7 @@ private: QVector server_list; QVector favorite_list; + QHash asset_lookup_cache; private slots: void ms_connect_finished(bool connected, bool will_retry); diff --git a/include/aolayer.h b/include/aolayer.h index 1984b77..90108af 100644 --- a/include/aolayer.h +++ b/include/aolayer.h @@ -9,6 +9,7 @@ #include class AOApplication; +class VPath; // "Brief" explanation of what the hell this is: // diff --git a/include/aooptionsdialog.h b/include/aooptionsdialog.h index 62ce2f7..3ea8ccc 100644 --- a/include/aooptionsdialog.h +++ b/include/aooptionsdialog.h @@ -180,6 +180,9 @@ private: QPushButton *ui_mount_remove; QPushButton *ui_mount_up; QPushButton *ui_mount_down; + QPushButton *ui_mount_clear_cache; + + bool asset_cache_dirty = false; bool needs_default_audiodev(); void update_values(); diff --git a/src/aoapplication.cpp b/src/aoapplication.cpp index dd75b0a..355db03 100644 --- a/src/aoapplication.cpp +++ b/src/aoapplication.cpp @@ -19,6 +19,7 @@ AOApplication::AOApplication(int &argc, char **argv) : QApplication(argc, argv) QObject::connect(net_manager, SIGNAL(ms_connect_finished(bool, bool)), SLOT(ms_connect_finished(bool, bool))); // qApp->setStyleSheet("QFrame {background-color:transparent;} QAbstractItemView {background-color: transparent; color: black;}; QLineEdit {background-color:transparent;}"); + asset_lookup_cache.reserve(2048); } AOApplication::~AOApplication() diff --git a/src/aobutton.cpp b/src/aobutton.cpp index 7f8c13f..fb9da7d 100644 --- a/src/aobutton.cpp +++ b/src/aobutton.cpp @@ -27,7 +27,7 @@ void AOButton::set_image(QString p_path, QString 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)) { + if (p_image.isEmpty()) { this->setIcon(QIcon()); this->setIconSize(this->size()); this->setStyleSheet(""); diff --git a/src/aoevidencebutton.cpp b/src/aoevidencebutton.cpp index aea903a..11fed59 100644 --- a/src/aoevidencebutton.cpp +++ b/src/aoevidencebutton.cpp @@ -32,7 +32,7 @@ AOEvidenceButton::AOEvidenceButton(QWidget *p_parent, AOApplication *p_ao_app, 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; diff --git a/src/aoevidencedisplay.cpp b/src/aoevidencedisplay.cpp index ba1c170..c635a02 100644 --- a/src/aoevidencedisplay.cpp +++ b/src/aoevidencedisplay.cpp @@ -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 e1bd8b8..fbf8c99 100644 --- a/src/aoimage.cpp +++ b/src/aoimage.cpp @@ -20,21 +20,16 @@ AOImage::AOImage(QWidget *parent, AOApplication *p_ao_app) : QLabel(parent) 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 (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, "", "", !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; movie->stop(); movie->setFileName(path); if (ao_app->get_animated_theme() && movie->frameCount() > 1) { diff --git a/src/aolayer.cpp b/src/aolayer.cpp index f0d5779..27e7a65 100644 --- a/src/aolayer.cpp +++ b/src/aolayer.cpp @@ -137,7 +137,7 @@ 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"); diff --git a/src/aomusicplayer.cpp b/src/aomusicplayer.cpp index 8a3142e..c4d8496 100644 --- a/src/aomusicplayer.cpp +++ b/src/aomusicplayer.cpp @@ -19,7 +19,7 @@ void AOMusicPlayer::play(QString p_song, int channel, bool loop, channel = channel % m_channelmax; if (channel < 0) // wtf? return; - 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; diff --git a/src/aooptionsdialog.cpp b/src/aooptionsdialog.cpp index 6f1b348..a035a74 100644 --- a/src/aooptionsdialog.cpp +++ b/src/aooptionsdialog.cpp @@ -14,7 +14,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); @@ -907,7 +907,12 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) QFileDialog::ShowDirsOnly); if (dir.isEmpty()) return; - ui_mount_list->addItem(dir); + 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); @@ -918,7 +923,9 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) auto selected = ui_mount_list->selectedItems(); if (selected.isEmpty()) return; - ui_mount_list->removeItemWidget(selected[0]); + delete selected[0]; + emit ui_mount_list->itemSelectionChanged(); + asset_cache_dirty = true; }); auto *mount_buttons_spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, @@ -934,7 +941,13 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) auto selected = ui_mount_list->selectedItems(); if (selected.isEmpty()) return; - ui_mount_list->setEditTriggers() + 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); @@ -942,6 +955,49 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) 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); + }); update_values(); @@ -1019,6 +1075,7 @@ void AOOptionsDialog::update_values() { .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()); } void AOOptionsDialog::save_pressed() @@ -1091,9 +1148,17 @@ void AOOptionsDialog::save_pressed() configini->setValue("casing_can_host_cases", ui_casing_cm_cases_textbox->text()); + QStringList mountPaths; + for (int i = 1; i < ui_mount_list->count(); i++) + mountPaths.append(ui_mount_list->item(i)->text()); + configini->setValue("mount_paths", mountPaths); + if (audioChanged) ao_app->initBASS(); + if (asset_cache_dirty) + ao_app->invalidate_lookup_cache(); + callwordsini->close(); // We most probably pressed "Restore defaults" at some point. Since we're saving our settings, remove the temporary file. diff --git a/src/charselect.cpp b/src/charselect.cpp index 510d8c0..08df96f 100644 --- a/src/charselect.cpp +++ b/src/charselect.cpp @@ -157,8 +157,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; diff --git a/src/courtroom.cpp b/src/courtroom.cpp index fe5f74d..4b9c72c 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -501,7 +501,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(); @@ -1384,11 +1384,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" @@ -1523,7 +1523,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); @@ -4333,8 +4333,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) { @@ -4390,7 +4391,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()) != @@ -4401,7 +4403,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)); @@ -4478,7 +4480,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 @@ -4491,10 +4494,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)); } @@ -4527,12 +4530,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); @@ -4566,9 +4568,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; } @@ -4578,7 +4580,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; diff --git a/src/file_functions.cpp b/src/file_functions.cpp index e64a46b..37cdc32 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(); diff --git a/src/path_functions.cpp b/src/path_functions.cpp index 9700529..b1a5e48 100644 --- a/src/path_functions.cpp +++ b/src/path_functions.cpp @@ -39,71 +39,58 @@ QString AOApplication::get_base_path() return base_path; } -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 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; - pathlist += p_element; // The path by itself + QVector pathlist; + pathlist += VPath(p_element); // The path by itself if (p_character != "") pathlist += get_character_path(p_character, p_element); // Character folder if (p_misc != "" && p_theme != "" && p_subtheme != "") @@ -125,52 +112,47 @@ 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 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 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; - } - } - return path; -} - -QString AOApplication::get_sfx_path(QStringList 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_image_suffix(p, static_image); + if (!path.isEmpty()) { + return path; } } - return path; + return QString(); } + +QString AOApplication::get_sfx_path(QVector pathlist) +{ + for (const VPath &p : pathlist) { + QString path = get_sfx_suffix(p); + if (!path.isEmpty()) { + 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); + for (const VPath &p : get_asset_paths(p_config, p_theme, p_subtheme, p_default_theme, p_misc)) { + path = get_real_path(p); + if (!path.isEmpty()) { + QSettings settings(path, QSettings::IniFormat); QVariant value = settings.value(p_identifier); if (value.type() == QVariant::StringList) { // qDebug() << "got" << p << "is a string list, returning" << value.toStringList().join(","); @@ -190,25 +172,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 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); @@ -238,3 +217,35 @@ 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(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); + const QString path = baseDir.absoluteFilePath(vpath.toQString()); + if (!path.startsWith(baseDir.absolutePath())) { + qWarning() << "invalid path" << path << "(path is outside vfs)"; + break; + } + if (exists(get_case_sensitive_path(path))) { + asset_lookup_cache.insert(vpath, path); + return path; + } + } + + // File or directory not found + return QString(); +} + +void AOApplication::invalidate_lookup_cache() { + asset_lookup_cache.clear(); +} diff --git a/src/text_file_functions.cpp b/src/text_file_functions.cpp index f6a5d6c..c92287f 100644 --- a/src/text_file_functions.cpp +++ b/src/text_file_functions.cpp @@ -124,6 +124,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; @@ -275,6 +280,12 @@ QVector AOApplication::read_serverlist_txt() return f_server_list; } +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) { @@ -440,12 +451,14 @@ QString AOApplication::get_chat_markup(QString p_identifier, QString p_chat) return value.toLatin1(); // Backwards ass compatibility - QStringList backwards_paths{get_theme_path("misc/" + p_chat + "/config.ini"), - get_base_path() + "misc/" + p_chat + - "/config.ini", - get_base_path() + "misc/default/config.ini", - get_theme_path("misc/default/config.ini")}; - for (const QString &p : backwards_paths) { + QVector backwards_paths { + get_theme_path("misc/" + p_chat + "/config.ini"), + VPath("misc/" + p_chat + "/config.ini"), + VPath("misc/default/config.ini"), + get_theme_path("misc/default/config.ini") + }; + + for (const VPath &p : backwards_paths) { QString value = read_design_ini(p_identifier, p); if (!value.isEmpty()) { return value.toLatin1(); @@ -482,36 +495,32 @@ QString AOApplication::get_court_sfx(QString p_identifier, QString p_misc) return ""; } -QString AOApplication::get_sfx_suffix(QString 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"; +QString AOApplication::get_suffix(VPath path_to_check, QStringList suffixes) { + for (const QString &suffix : suffixes) { + QString path = get_real_path(VPath(path_to_check.toQString() + suffix)); + if (!path.isEmpty()) + return path; + } + + return QString(); } -QString AOApplication::get_image_suffix(QString path_to_check, bool static_image) +QString AOApplication::get_sfx_suffix(VPath sound_to_check) { - if (file_exists(path_to_check)) - return path_to_check; + return get_suffix(sound_to_check, { "", ".opus", ".ogg", ".mp3", ".wav" }); +} + +QString AOApplication::get_image_suffix(VPath path_to_check, bool static_image) +{ + QStringList suffixes { "" }; // A better method would to actually use AOImageReader and see if these images have more than 1 frame. // However, that might not be performant. 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_suffix(path_to_check, suffixes); } // returns whatever is to the right of "search_line =" within target_tag and @@ -520,7 +529,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); QString value = settings.value(p_search_line).value(); @@ -531,7 +540,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); @@ -539,10 +548,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); if (!target_tag.isEmpty()) settings.beginGroup(target_tag); QStringList keys = settings.allKeys(); @@ -1084,3 +1093,8 @@ bool AOApplication::get_animated_theme() configini->value("animated_theme", "true").value(); return result.startsWith("true"); } + +QStringList AOApplication::get_mount_paths() +{ + return configini->value("mount_paths").value(); +} From 037d96a5d96bae6e341d8f7ca4f485d519cde02b Mon Sep 17 00:00:00 2001 From: oldmud0 Date: Sat, 5 Jun 2021 20:28:55 -0500 Subject: [PATCH 03/35] Use intuitive behavior for loading assets with ambiguous extensions --- include/aoapplication.h | 4 +--- src/aobutton.cpp | 9 ++------- src/debug_functions.cpp | 1 + src/path_functions.cpp | 33 +++++++++++++++++++++++++++++++++ src/text_file_functions.cpp | 17 +++-------------- 5 files changed, 40 insertions(+), 24 deletions(-) diff --git a/include/aoapplication.h b/include/aoapplication.h index 0c61d7b..24a09ec 100644 --- a/include/aoapplication.h +++ b/include/aoapplication.h @@ -167,6 +167,7 @@ public: 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 ////// @@ -355,9 +356,6 @@ public: // Returns the sfx with p_identifier from courtroom_sounds.ini in the current theme path QString get_court_sfx(QString p_identifier, QString p_misc=""); - // Find the correct suffix for a given file - QString get_suffix(VPath file_to_check, QStringList suffixes); - // Figure out if we can opus this or if we should fall back to wav QString get_sfx_suffix(VPath sound_to_check); diff --git a/src/aobutton.cpp b/src/aobutton.cpp index fb9da7d..242fe79 100644 --- a/src/aobutton.cpp +++ b/src/aobutton.cpp @@ -20,13 +20,8 @@ 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); + 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()); diff --git a/src/debug_functions.cpp b/src/debug_functions.cpp index 1613a7d..456aee8 100644 --- a/src/debug_functions.cpp +++ b/src/debug_functions.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/src/path_functions.cpp b/src/path_functions.cpp index b1a5e48..f79f7bf 100644 --- a/src/path_functions.cpp +++ b/src/path_functions.cpp @@ -246,6 +246,39 @@ QString AOApplication::get_real_path(const VPath &vpath) { 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(vpath); + if (!phys_path.isEmpty() && exists(phys_path)) { + 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); + const QString path = baseDir.absoluteFilePath(vpath.toQString() + suffix); + if (!path.startsWith(baseDir.absolutePath())) { + qWarning() << "invalid path" << path << "(path is outside vfs)"; + break; + } + if (exists(get_case_sensitive_path(path))) { + asset_lookup_cache.insert(vpath, path); + return path; + } + } + } + + // File or directory not found + return QString(); +} + void AOApplication::invalidate_lookup_cache() { asset_lookup_cache.clear(); } diff --git a/src/text_file_functions.cpp b/src/text_file_functions.cpp index c92287f..9c46341 100644 --- a/src/text_file_functions.cpp +++ b/src/text_file_functions.cpp @@ -495,32 +495,21 @@ QString AOApplication::get_court_sfx(QString p_identifier, QString p_misc) return ""; } -QString AOApplication::get_suffix(VPath path_to_check, QStringList suffixes) { - for (const QString &suffix : suffixes) { - QString path = get_real_path(VPath(path_to_check.toQString() + suffix)); - if (!path.isEmpty()) - return path; - } - - return QString(); -} - QString AOApplication::get_sfx_suffix(VPath sound_to_check) { - return get_suffix(sound_to_check, { "", ".opus", ".ogg", ".mp3", ".wav" }); + return get_real_suffixed_path(sound_to_check, + { "", ".opus", ".ogg", ".mp3", ".wav" }); } QString AOApplication::get_image_suffix(VPath path_to_check, bool static_image) { QStringList suffixes { "" }; - // A better method would to actually use AOImageReader and see if these images have more than 1 frame. - // However, that might not be performant. if (!static_image) { suffixes.append({ ".webp", ".apng", ".gif" }); } suffixes.append(".png"); - return get_suffix(path_to_check, suffixes); + return get_real_suffixed_path(path_to_check, suffixes); } // returns whatever is to the right of "search_line =" within target_tag and From 7a1c3f385e5fc7f0fdcde60543d32795ea64e0fc Mon Sep 17 00:00:00 2001 From: oldmud0 Date: Sat, 5 Jun 2021 22:27:56 -0500 Subject: [PATCH 04/35] Greatly improve case-insensitive lookup speed By using hash tables, the algorithmic complexity of the case-insensitive lookup has been reduced from O(n * k) to amortized O(k), where n is the number of files in each level and k is the number of directory levels that need to be traversed. This massively improves performance on Linux when loading characters, especially when there are many missing characters, since it is no longer necessary to scan the entire character folder repeatedly. --- src/path_functions.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/path_functions.cpp b/src/path_functions.cpp index f79f7bf..dd65204 100644 --- a/src/path_functions.cpp +++ b/src/path_functions.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #ifdef BASE_OVERRIDE #include "base_override.h" @@ -195,6 +196,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? @@ -204,12 +206,22 @@ QString AOApplication::get_case_sensitive_path(QString p_file) // 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); + static QHash listing_cache; + static QHash listing_exist_cache; - if (result != -1) - return file_parent_dir + "/" + files.at(result); + if (!listing_exist_cache.contains(qHash(file_parent_dir))) { + QStringList files = QDir(file_parent_dir).entryList(); + for (const QString &file : files) { + listing_cache.insert(qHash(file_parent_dir % QChar('/') % file.toLower()), file); + } + listing_exist_cache.insert(qHash(file_parent_dir), true); + } + QString found_file = listing_cache.value(qHash(file_parent_dir % QChar('/') % file_basename.toLower())); + + 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; From 387233e9e3603eb7d346eb351f0c70c84a956a10 Mon Sep 17 00:00:00 2001 From: oldmud0 Date: Sun, 6 Jun 2021 22:41:40 -0500 Subject: [PATCH 05/35] Don't store key in asset lookup cache --- include/aoapplication.h | 4 ++-- src/path_functions.cpp | 14 ++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/include/aoapplication.h b/include/aoapplication.h index 24a09ec..e800bb5 100644 --- a/include/aoapplication.h +++ b/include/aoapplication.h @@ -51,7 +51,7 @@ public: } }; -inline uint qHash(const VPath &key, uint seed) +inline uint qHash(const VPath &key, uint seed = qGlobalQHashSeed()) { return qHash(key.toQString(), seed); } @@ -541,7 +541,7 @@ private: QVector server_list; QVector favorite_list; - QHash asset_lookup_cache; + QHash asset_lookup_cache; private slots: void ms_connect_finished(bool connected, bool will_retry); diff --git a/src/path_functions.cpp b/src/path_functions.cpp index dd65204..66b0a5b 100644 --- a/src/path_functions.cpp +++ b/src/path_functions.cpp @@ -204,9 +204,6 @@ 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); - static QHash listing_cache; static QHash listing_exist_cache; @@ -217,7 +214,8 @@ QString AOApplication::get_case_sensitive_path(QString p_file) } listing_exist_cache.insert(qHash(file_parent_dir), true); } - QString found_file = listing_cache.value(qHash(file_parent_dir % QChar('/') % file_basename.toLower())); + QString found_file = listing_cache.value( + qHash(file_parent_dir % QChar('/') % file_basename.toLower())); if (!found_file.isEmpty()) { return file_parent_dir + "/" + found_file; @@ -232,7 +230,7 @@ QString AOApplication::get_case_sensitive_path(QString p_file) QString AOApplication::get_real_path(const VPath &vpath) { // Try cache first - QString phys_path = asset_lookup_cache.value(vpath); + QString phys_path = asset_lookup_cache.value(qHash(vpath)); if (!phys_path.isEmpty() && exists(phys_path)) { return phys_path; } @@ -249,7 +247,7 @@ QString AOApplication::get_real_path(const VPath &vpath) { break; } if (exists(get_case_sensitive_path(path))) { - asset_lookup_cache.insert(vpath, path); + asset_lookup_cache.insert(qHash(vpath), path); return path; } } @@ -263,7 +261,7 @@ QString AOApplication::get_real_path(const VPath &vpath) { QString AOApplication::get_real_suffixed_path(const VPath &vpath, const QStringList &suffixes) { // Try cache first - QString phys_path = asset_lookup_cache.value(vpath); + QString phys_path = asset_lookup_cache.value(qHash(vpath)); if (!phys_path.isEmpty() && exists(phys_path)) { return phys_path; } @@ -281,7 +279,7 @@ QString AOApplication::get_real_suffixed_path(const VPath &vpath, break; } if (exists(get_case_sensitive_path(path))) { - asset_lookup_cache.insert(vpath, path); + asset_lookup_cache.insert(qHash(vpath), path); return path; } } From 2ef7b206e24d9af112c8b466c006aa98e072e235 Mon Sep 17 00:00:00 2001 From: oldmud0 Date: Sun, 6 Jun 2021 22:42:16 -0500 Subject: [PATCH 06/35] Scan themes in all mount paths --- src/aooptionsdialog.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/aooptionsdialog.cpp b/src/aooptionsdialog.cpp index a035a74..6b42590 100644 --- a/src/aooptionsdialog.cpp +++ b/src/aooptionsdialog.cpp @@ -75,12 +75,19 @@ 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 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, From e576a8b23d1dec48553ef4a2de3bf5c7c6925633 Mon Sep 17 00:00:00 2001 From: oldmud0 Date: Sun, 6 Jun 2021 23:27:30 -0500 Subject: [PATCH 07/35] Fix bug with case-sensitive vpath lookup --- src/path_functions.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/path_functions.cpp b/src/path_functions.cpp index 4dc1c62..b15cc90 100644 --- a/src/path_functions.cpp +++ b/src/path_functions.cpp @@ -242,12 +242,13 @@ QString AOApplication::get_real_path(const VPath &vpath) { for (const QString &base : bases) { QDir baseDir(base); - const QString path = baseDir.absoluteFilePath(vpath.toQString()); + QString path = baseDir.absoluteFilePath(vpath.toQString()); if (!path.startsWith(baseDir.absolutePath())) { qWarning() << "invalid path" << path << "(path is outside vfs)"; break; } - if (exists(get_case_sensitive_path(path))) { + path = get_case_sensitive_path(path); + if (exists(path)) { asset_lookup_cache.insert(qHash(vpath), path); return path; } @@ -274,12 +275,13 @@ QString AOApplication::get_real_suffixed_path(const VPath &vpath, for (const QString &base : bases) { for (const QString &suffix : suffixes) { QDir baseDir(base); - const QString path = baseDir.absoluteFilePath(vpath.toQString() + suffix); + QString path = baseDir.absoluteFilePath(vpath.toQString() + suffix); if (!path.startsWith(baseDir.absolutePath())) { qWarning() << "invalid path" << path << "(path is outside vfs)"; break; } - if (exists(get_case_sensitive_path(path))) { + path = get_case_sensitive_path(path); + if (exists(path)) { asset_lookup_cache.insert(qHash(vpath), path); return path; } From dcce1750525d0cca21ebaa7a65c1abc2ff36123c Mon Sep 17 00:00:00 2001 From: oldmud0 Date: Sun, 6 Jun 2021 23:31:48 -0500 Subject: [PATCH 08/35] Fix clazy-range-loop-detach warning --- src/path_functions.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/path_functions.cpp b/src/path_functions.cpp index b15cc90..3f19715 100644 --- a/src/path_functions.cpp +++ b/src/path_functions.cpp @@ -150,7 +150,8 @@ QString AOApplication::get_config_value(QString p_identifier, QString p_config, { QString path; // qDebug() << "got request for" << p_identifier << "in" << p_config; - for (const VPath &p : get_asset_paths(p_config, p_theme, p_subtheme, p_default_theme, p_misc)) { + 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); From 2cb7ca7895e72f603ac2283da656377217d281c6 Mon Sep 17 00:00:00 2001 From: oldmud0 Date: Tue, 8 Jun 2021 22:50:32 -0500 Subject: [PATCH 09/35] Move global stylesheet to lobby and courtroom This way, it will not affect the options dialog. --- src/aoapplication.cpp | 2 +- src/courtroom.cpp | 6 ++++++ src/lobby.cpp | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/aoapplication.cpp b/src/aoapplication.cpp index 355db03..1ae90f8 100644 --- a/src/aoapplication.cpp +++ b/src/aoapplication.cpp @@ -18,7 +18,7 @@ AOApplication::AOApplication(int &argc, char **argv) : QApplication(argc, argv) discord = new AttorneyOnline::Discord(); QObject::connect(net_manager, SIGNAL(ms_connect_finished(bool, bool)), SLOT(ms_connect_finished(bool, bool))); - // qApp->setStyleSheet("QFrame {background-color:transparent;} QAbstractItemView {background-color: transparent; color: black;}; QLineEdit {background-color:transparent;}"); + asset_lookup_cache.reserve(2048); } diff --git a/src/courtroom.cpp b/src/courtroom.cpp index d1f8d3a..d12ede5 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -1222,6 +1222,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) diff --git a/src/lobby.cpp b/src/lobby.cpp index 5cdb94a..31895d1 100644 --- a/src/lobby.cpp +++ b/src/lobby.cpp @@ -235,6 +235,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) From 2f50cd55281cfa963ea2d6fb566b1eee675c643f Mon Sep 17 00:00:00 2001 From: oldmud0 Date: Tue, 8 Jun 2021 23:11:28 -0500 Subject: [PATCH 10/35] Clear case sensitive cache as well on vpath cache flush --- include/aoapplication.h | 2 ++ src/path_functions.cpp | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/include/aoapplication.h b/include/aoapplication.h index b0ab972..90364db 100644 --- a/include/aoapplication.h +++ b/include/aoapplication.h @@ -554,6 +554,8 @@ private: QVector server_list; QVector favorite_list; QHash asset_lookup_cache; + QHash dir_listing_cache; + QSet dir_listing_exist_cache; private slots: void ms_connect_finished(bool connected, bool will_retry); diff --git a/src/path_functions.cpp b/src/path_functions.cpp index 3f19715..2f5aaec 100644 --- a/src/path_functions.cpp +++ b/src/path_functions.cpp @@ -206,17 +206,15 @@ 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 - static QHash listing_cache; - static QHash listing_exist_cache; - if (!listing_exist_cache.contains(qHash(file_parent_dir))) { + if (!dir_listing_exist_cache.contains(qHash(file_parent_dir))) { QStringList files = QDir(file_parent_dir).entryList(); for (const QString &file : files) { - listing_cache.insert(qHash(file_parent_dir % QChar('/') % file.toLower()), file); + dir_listing_cache.insert(qHash(file_parent_dir % QChar('/') % file.toLower()), file); } - listing_exist_cache.insert(qHash(file_parent_dir), true); + dir_listing_exist_cache.insert(qHash(file_parent_dir)); } - QString found_file = listing_cache.value( + QString found_file = dir_listing_cache.value( qHash(file_parent_dir % QChar('/') % file_basename.toLower())); if (!found_file.isEmpty()) { @@ -295,4 +293,6 @@ QString AOApplication::get_real_suffixed_path(const VPath &vpath, void AOApplication::invalidate_lookup_cache() { asset_lookup_cache.clear(); + dir_listing_cache.clear(); + dir_listing_exist_cache.clear(); } From 097bc3d4f7c5664ac54cd16b289660b03c7fdceb Mon Sep 17 00:00:00 2001 From: in1tiate Date: Wed, 9 Jun 2021 14:50:47 -0500 Subject: [PATCH 11/35] stupidly simple fix --- include/lobby.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/lobby.h b/include/lobby.h index 0f066ab..0f1610f 100644 --- a/include/lobby.h +++ b/include/lobby.h @@ -84,7 +84,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); From 65f812cf7331acb5d5d1f1dfbac4bc99fd0aed04 Mon Sep 17 00:00:00 2001 From: Rose Witchaven <32779090+in1tiate@users.noreply.github.com> Date: Wed, 16 Jun 2021 23:58:39 -0500 Subject: [PATCH 12/35] Extend /pair command to work with character names as well as IDs (#562) --- src/courtroom.cpp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 18c6f01..7b4d4f0 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -4029,10 +4029,28 @@ void Courtroom::on_ooc_return_pressed() } } else { - append_server_chatmessage("CLIENT", - tr("Are you sure you typed that well? The char " - "ID could not be recognised."), - "1"); + int whom = 0; + bool matched = false; + for (char_type chara : char_list) { + if (chara.name.toLower() == ooc_message.toLower()) { + matched = true; + break; + } + whom++; + } + if (matched) { + 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 { + append_server_chatmessage("CLIENT", + tr("Are you sure you typed that well? The char " + "ID/name could not be recognised."), + "1"); + } } return; } From 5190490a07f929aef3ee0198f5bce251ff28dbea Mon Sep 17 00:00:00 2001 From: Rose Witchaven <32779090+in1tiate@users.noreply.github.com> Date: Fri, 18 Jun 2021 23:58:46 -0500 Subject: [PATCH 13/35] Set BASS_CONFIG_DEV_DEFAULT to 1 to enable automatic reinitialization of the default device when it is lost (#564) fixes #561 --- src/aoapplication.cpp | 2 ++ src/aoblipplayer.cpp | 6 ------ src/aosfxplayer.cpp | 6 ------ 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/aoapplication.cpp b/src/aoapplication.cpp index 7485759..e71f4c8 100644 --- a/src/aoapplication.cpp +++ b/src/aoapplication.cpp @@ -194,6 +194,7 @@ 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) { @@ -213,6 +214,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 6607d46..307a0bd 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/aosfxplayer.cpp b/src/aosfxplayer.cpp index 000b6a7..fcdeb94 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); From 2d3cab82c896b86b1e107b8e1773572ac0fec6d3 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Thu, 22 Jul 2021 12:26:57 -0500 Subject: [PATCH 14/35] Fix custom objections not playing sounds --- src/path_functions.cpp | 5 ++++- src/text_file_functions.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/path_functions.cpp b/src/path_functions.cpp index 2f5aaec..61df1c6 100644 --- a/src/path_functions.cpp +++ b/src/path_functions.cpp @@ -264,7 +264,10 @@ QString AOApplication::get_real_suffixed_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; + 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 diff --git a/src/text_file_functions.cpp b/src/text_file_functions.cpp index fbe8279..d9b341b 100644 --- a/src/text_file_functions.cpp +++ b/src/text_file_functions.cpp @@ -506,7 +506,7 @@ QString AOApplication::get_court_sfx(QString p_identifier, QString p_misc) QString AOApplication::get_sfx_suffix(VPath sound_to_check) { return get_real_suffixed_path(sound_to_check, - { "", ".opus", ".ogg", ".mp3", ".wav" }); + {".opus", ".ogg", ".mp3", ".wav" }); } QString AOApplication::get_image_suffix(VPath path_to_check, bool static_image) From 15f0ee38383fef3c140752345b4aa57628ad2e53 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Thu, 29 Jul 2021 08:54:34 -0500 Subject: [PATCH 15/35] swap out custom UNUSED macro for Q_UNUSED --- include/aoapplication.h | 2 -- src/aoapplication.cpp | 8 ++++---- src/aomusicplayer.cpp | 4 ++-- src/charselect.cpp | 2 +- src/courtroom.cpp | 4 ++-- 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/include/aoapplication.h b/include/aoapplication.h index 90364db..718029a 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" diff --git a/src/aoapplication.cpp b/src/aoapplication.cpp index e71f4c8..74dc6ed 100644 --- a/src/aoapplication.cpp +++ b/src/aoapplication.cpp @@ -198,10 +198,10 @@ void AOApplication::call_announce_menu(Courtroom *court) 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(); } diff --git a/src/aomusicplayer.cpp b/src/aomusicplayer.cpp index b0f3fa3..d0d9563 100644 --- a/src/aomusicplayer.cpp +++ b/src/aomusicplayer.cpp @@ -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(user)); BASS_ChannelLock(channel, true); BASS_ChannelSetPosition(channel, loop_start, BASS_POS_BYTE); diff --git a/src/charselect.cpp b/src/charselect.cpp index 472938d..4d5edbc 100644 --- a/src/charselect.cpp +++ b/src/charselect.cpp @@ -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); diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 7b4d4f0..25f256a 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -4584,7 +4584,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 = ""; @@ -4964,7 +4964,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; From ce94cd2d1e75738b53f7ab990a49e75a01b80394 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Wed, 11 Aug 2021 09:20:00 -0500 Subject: [PATCH 16/35] preload next frame before ticking over --- include/aolayer.h | 4 ++++ src/aolayer.cpp | 22 ++++++++++++++-------- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/include/aolayer.h b/include/aolayer.h index 7a8e2fd..4b95ddb 100644 --- a/include/aolayer.h +++ b/include/aolayer.h @@ -7,6 +7,7 @@ #include #include #include +#include class AOApplication; class VPath; @@ -139,6 +140,9 @@ protected: // Center the QLabel in the viewport based on the dimensions of f_pixmap void center_pixmap(QPixmap f_pixmap); + // Populate the frame and delay vectors. Done asynchronously. + void load_next_frame(); + signals: void done(); diff --git a/src/aolayer.cpp b/src/aolayer.cpp index 3791d66..7ec42b9 100644 --- a/src/aolayer.cpp +++ b/src/aolayer.cpp @@ -532,7 +532,11 @@ void CharLayer::movie_ticker() void AOLayer::movie_ticker() { ++frame; - if (frame >= max_frames) { + QFuture future; + if (frame >= movie_frames.size() && frame < max_frames) { // need to load the image + future = QtConcurrent::run(this, &AOLayer::load_next_frame); + } + else if (frame >= max_frames) { if (play_once) { if (cull_image) this->stop(); @@ -544,19 +548,21 @@ 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()); - } - #ifdef DEBUG_MOVIE qDebug() << frame << movie_delays[frame] << "actual time taken from last frame:" << actual_time.restart(); #endif - + future.waitForFinished(); // don't set the frame before we definitely have it in memory this->set_frame(movie_frames[frame]); ticker->setInterval(this->get_frame_delay(movie_delays[frame])); + if (frame + 1 >= movie_frames.size() && frame + 1 < max_frames) { // load the next frame before we tick again + future = QtConcurrent::run(this, &AOLayer::load_next_frame); + } +} + +void AOLayer::load_next_frame() { + movie_frames.append(this->get_pixmap(m_reader.read())); + movie_delays.append(m_reader.nextImageDelay()); } void CharLayer::preanim_done() From 51698ca6ac57361ca3a5d9aa7d3b3a67374f8b49 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Wed, 11 Aug 2021 09:28:59 -0500 Subject: [PATCH 17/35] debug_movie fixes --- Attorney_Online.pro | 2 ++ src/aolayer.cpp | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Attorney_Online.pro b/Attorney_Online.pro index 2a5c1e1..2498232 100644 --- a/Attorney_Online.pro +++ b/Attorney_Online.pro @@ -19,6 +19,8 @@ QMAKE_LFLAGS += -Wl,-rpath,"'\$$ORIGIN/lib'" # Uncomment for verbose network logging # DEFINES += DEBUG_NETWORK +DEFINES += DEBUG_MOVIE + # Uncomment for building with debug symbols # CONFIG += debug diff --git a/src/aolayer.cpp b/src/aolayer.cpp index 7ec42b9..075338b 100644 --- a/src/aolayer.cpp +++ b/src/aolayer.cpp @@ -344,7 +344,7 @@ void AOLayer::start_playback(QString p_image) if (duration > 0 && cull_image == true) shfx_timer->start(duration); #ifdef DEBUG_MOVIE - qDebug() << max_frames << "Setting image to " << image_path + qDebug() << max_frames << "Setting image to " << p_image << "Time taken to process image:" << actual_time.elapsed(); actual_time.restart(); @@ -548,11 +548,11 @@ void AOLayer::movie_ticker() else frame = 0; } + future.waitForFinished(); // don't set the frame before we definitely have it in memory #ifdef DEBUG_MOVIE qDebug() << frame << movie_delays[frame] << "actual time taken from last frame:" << actual_time.restart(); #endif - future.waitForFinished(); // don't set the frame before we definitely have it in memory this->set_frame(movie_frames[frame]); ticker->setInterval(this->get_frame_delay(movie_delays[frame])); if (frame + 1 >= movie_frames.size() && frame + 1 < max_frames) { // load the next frame before we tick again From d84194871e50d86ba36d01029192ecf0b7665127 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Wed, 11 Aug 2021 09:38:05 -0500 Subject: [PATCH 18/35] comment out debug_movie --- Attorney_Online.pro | 3 ++- src/aolayer.cpp | 5 +---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Attorney_Online.pro b/Attorney_Online.pro index 2498232..abca0fb 100644 --- a/Attorney_Online.pro +++ b/Attorney_Online.pro @@ -19,7 +19,8 @@ QMAKE_LFLAGS += -Wl,-rpath,"'\$$ORIGIN/lib'" # Uncomment for verbose network logging # DEFINES += DEBUG_NETWORK -DEFINES += DEBUG_MOVIE +# Uncomment for verbose animation logging +# DEFINES += DEBUG_MOVIE # Uncomment for building with debug symbols # CONFIG += debug diff --git a/src/aolayer.cpp b/src/aolayer.cpp index 075338b..25873fe 100644 --- a/src/aolayer.cpp +++ b/src/aolayer.cpp @@ -320,10 +320,7 @@ void AOLayer::start_playback(QString p_image) 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); + load_next_frame(); } } last_path = p_image; From 42760bc3f86e1d38acbf6c3c9f675dbf6acc37c8 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Wed, 11 Aug 2021 09:40:11 -0500 Subject: [PATCH 19/35] more accurate comment --- include/aolayer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/aolayer.h b/include/aolayer.h index 4b95ddb..1216b32 100644 --- a/include/aolayer.h +++ b/include/aolayer.h @@ -140,7 +140,7 @@ protected: // Center the QLabel in the viewport based on the dimensions of f_pixmap void center_pixmap(QPixmap f_pixmap); - // Populate the frame and delay vectors. Done asynchronously. + // Populates the frame and delay vectors with the next frame's data. void load_next_frame(); signals: From 2a18c1cdec54a324c6ba9834d6e6b05cc46f2535 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Wed, 11 Aug 2021 20:14:35 -0500 Subject: [PATCH 20/35] wait for thread to finish before starting new one --- include/aolayer.h | 3 +++ src/aolayer.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/include/aolayer.h b/include/aolayer.h index 1216b32..ffbd6da 100644 --- a/include/aolayer.h +++ b/include/aolayer.h @@ -143,6 +143,9 @@ protected: // Populates the frame and delay vectors with the next frame's data. void load_next_frame(); + // used in load_next_frame + QFuture future; + signals: void done(); diff --git a/src/aolayer.cpp b/src/aolayer.cpp index 25873fe..9952494 100644 --- a/src/aolayer.cpp +++ b/src/aolayer.cpp @@ -529,8 +529,8 @@ void CharLayer::movie_ticker() void AOLayer::movie_ticker() { ++frame; - QFuture future; if (frame >= movie_frames.size() && frame < max_frames) { // need to load the image + future.waitForFinished(); // Do Not want this to be running twice future = QtConcurrent::run(this, &AOLayer::load_next_frame); } else if (frame >= max_frames) { From 3bcf01bb21c60c05d52bf53828bf8361b3234a2b Mon Sep 17 00:00:00 2001 From: in1tiate Date: Fri, 13 Aug 2021 03:23:12 -0500 Subject: [PATCH 21/35] asynchronously load animations for bigly performant gainz --- include/aolayer.h | 17 +++++++--- src/aolayer.cpp | 83 ++++++++++++++++++++++++----------------------- 2 files changed, 55 insertions(+), 45 deletions(-) diff --git a/include/aolayer.h b/include/aolayer.h index ffbd6da..b890715 100644 --- a/include/aolayer.h +++ b/include/aolayer.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include class AOApplication; class VPath; @@ -140,11 +142,17 @@ protected: // Center the QLabel in the viewport based on the dimensions of f_pixmap void center_pixmap(QPixmap f_pixmap); - // Populates the frame and delay vectors with the next frame's data. - void load_next_frame(); +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 frame_loader; + QMutex mutex; + QWaitCondition frameAdded; - // used in load_next_frame - QFuture future; signals: void done(); @@ -243,4 +251,5 @@ public: StickerLayer(QWidget *p_parent, AOApplication *p_ao_app); void load_image(QString p_charname); }; + #endif // AOLAYER_H diff --git a/src/aolayer.cpp b/src/aolayer.cpp index 9952494..eb7853c 100644 --- a/src/aolayer.cpp +++ b/src/aolayer.cpp @@ -269,6 +269,9 @@ void CharLayer::start_playback(QString p_image) void AOLayer::start_playback(QString p_image) { + 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 +279,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,7 +299,7 @@ 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) @@ -309,39 +312,22 @@ void AOLayer::start_playback(QString p_image) 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; - load_next_frame(); - } - } + 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) + frameAdded.wait(&mutex); + 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 " << p_image + qDebug() << "[AOLayer::start_playback] Max frames:" << max_frames << "Setting image to " << p_image << "Time taken to process image:" << actual_time.elapsed(); actual_time.restart(); @@ -372,8 +358,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; } @@ -451,7 +441,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); @@ -472,14 +462,14 @@ void CharLayer::play_frame_effect(int p_frame) if (effect == "shake") { 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(); #ifdef DEBUG_MOVIE - qDebug() << "Attempting to play flash on frame" << frame; + qDebug() << "[CharLayer::play_frame_effect] Attempting to play flash on frame" << frame; #endif } @@ -487,7 +477,7 @@ void CharLayer::play_frame_effect(int p_frame) QString sfx = effect.section("^", 1); 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 } } @@ -529,11 +519,12 @@ void CharLayer::movie_ticker() void AOLayer::movie_ticker() { ++frame; - if (frame >= movie_frames.size() && frame < max_frames) { // need to load the image - future.waitForFinished(); // Do Not want this to be running twice - future = QtConcurrent::run(this, &AOLayer::load_next_frame); + mutex.lock(); + while (frame >= movie_frames.size() && frame < max_frames) { // oops! our frame isn't ready yet + frameAdded.wait(&mutex); } - else if (frame >= max_frames) { + mutex.unlock(); + if (frame >= max_frames) { if (play_once) { if (cull_image) this->stop(); @@ -545,21 +536,31 @@ void AOLayer::movie_ticker() else frame = 0; } - future.waitForFinished(); // don't set the frame before we definitely have it in memory #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])); - if (frame + 1 >= movie_frames.size() && frame + 1 < max_frames) { // load the next frame before we tick again - future = QtConcurrent::run(this, &AOLayer::load_next_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() From 8b82f5d592a9f76b1edbaa1efdf09366e41b266c Mon Sep 17 00:00:00 2001 From: Rosemary Witchaven <32779090+in1tiate@users.noreply.github.com> Date: Tue, 24 Aug 2021 19:37:13 -0500 Subject: [PATCH 22/35] Fix an infinite hang when loading the pair character, fix strange undesired behavior of the pair character (#586) * sanity check if the frame we're waiting on isnt nonexistent * consolidate conditionals --- src/aolayer.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/aolayer.cpp b/src/aolayer.cpp index eb7853c..30ff652 100644 --- a/src/aolayer.cpp +++ b/src/aolayer.cpp @@ -304,11 +304,12 @@ void AOLayer::start_playback(QString p_image) 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; } @@ -519,11 +520,6 @@ void CharLayer::movie_ticker() void AOLayer::movie_ticker() { ++frame; - mutex.lock(); - while (frame >= movie_frames.size() && frame < max_frames) { // oops! our frame isn't ready yet - frameAdded.wait(&mutex); - } - mutex.unlock(); if (frame >= max_frames) { if (play_once) { if (cull_image) @@ -536,6 +532,11 @@ void AOLayer::movie_ticker() else frame = 0; } + mutex.lock(); + while (frame >= movie_frames.size() && frame < max_frames) { // oops! our frame isn't ready yet + frameAdded.wait(&mutex); + } + mutex.unlock(); #ifdef DEBUG_MOVIE qDebug() << "[AOLayer::movie_ticker] Frame:" << frame << "Delay:" << movie_delays[frame] << "Actual time taken from last frame:" << actual_time.restart(); From 7ce4dd6f618b64341c9d9520dfc98ede5a7500a7 Mon Sep 17 00:00:00 2001 From: Rosemary Witchaven <32779090+in1tiate@users.noreply.github.com> Date: Mon, 30 Aug 2021 21:23:11 -0500 Subject: [PATCH 23/35] Use event filters instead of subclassing QLineEdit and QPlainTextEdit (#587) * replace aolineedit and aotextedit with event filters * use a button to make evidence editable instead of double click --- include/CMakeLists.txt | 3 +- include/aolineedit.h | 26 ---------------- include/aotextedit.h | 21 ------------- include/courtroom.h | 19 +++++++----- include/eventfilters.h | 36 +++++++++++++++++++++++ src/CMakeLists.txt | 2 -- src/aolayer.cpp | 12 ++++---- src/aolineedit.cpp | 22 -------------- src/aotextedit.cpp | 17 ----------- src/courtroom.cpp | 6 ++-- src/evidence.cpp | 67 +++++++++++++++++++++++++----------------- 11 files changed, 98 insertions(+), 133 deletions(-) delete mode 100644 include/aolineedit.h delete mode 100644 include/aotextedit.h create mode 100644 include/eventfilters.h delete mode 100644 src/aolineedit.cpp delete mode 100644 src/aotextedit.cpp diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 18cf23b..e74a49b 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/aolineedit.h b/include/aolineedit.h deleted file mode 100644 index 5dce3aa..0000000 --- a/include/aolineedit.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef AOLINEEDIT_H -#define AOLINEEDIT_H - -#include -#include - -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/aotextedit.h b/include/aotextedit.h deleted file mode 100644 index 8d876f1..0000000 --- a/include/aotextedit.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef AOTEXTEDIT_H -#define AOTEXTEDIT_H - -#include - -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 e814514..09ec486 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 #include @@ -648,7 +647,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 +730,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 ui_evidence_list; AOButton *ui_evidence_left; @@ -738,7 +739,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 +748,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 +877,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 +933,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 0000000..7847608 --- /dev/null +++ b/include/eventfilters.h @@ -0,0 +1,36 @@ +#ifndef EVENTFILTERS_H +#define EVENTFILTERS_H + +#include +#include + +class AOLineEditFilter : public QObject +{ + Q_OBJECT +public: + bool preserve_selection = false; + +protected: + bool eventFilter(QObject *obj, QEvent *event) override { + QLineEdit *lineEdit = qobject_cast(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/src/CMakeLists.txt b/src/CMakeLists.txt index b04db8b..32e924a 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/aolayer.cpp b/src/aolayer.cpp index 30ff652..201c724 100644 --- a/src/aolayer.cpp +++ b/src/aolayer.cpp @@ -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 @@ -461,14 +461,14 @@ 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() << "[CharLayer::play_frame_effect] Attempting to play shake on frame" << frame; #endif } if (effect == "flash") { - flash(); + emit flash(); #ifdef DEBUG_MOVIE qDebug() << "[CharLayer::play_frame_effect] Attempting to play flash on frame" << frame; #endif @@ -476,7 +476,7 @@ void CharLayer::play_frame_effect(int p_frame) if (effect.startsWith("sfx^")) { QString sfx = effect.section("^", 1); - play_sfx(sfx); + emit play_sfx(sfx); #ifdef DEBUG_MOVIE qDebug() << "[CharLayer::play_frame_effect] Attempting to play sfx" << sfx << "on frame" << frame; #endif @@ -576,7 +576,7 @@ void AOLayer::preanim_done() { ticker->stop(); preanim_timer->stop(); - done(); + emit done(); } void AOLayer::shfx_timer_done() @@ -586,5 +586,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 d80fa01..0000000 --- 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/aotextedit.cpp b/src/aotextedit.cpp deleted file mode 100644 index 22d9a62..0000000 --- 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/courtroom.cpp b/src/courtroom.cpp index 25f256a..389dd74 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -164,10 +164,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); diff --git a/src/evidence.cpp b/src/evidence.cpp index 2cc1d75..d34ba4f 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,16 +61,18 @@ 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"); + 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, 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, @@ -85,8 +92,6 @@ void Courtroom::initialize_evidence() 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, @@ -100,6 +105,7 @@ void Courtroom::initialize_evidence() SLOT(on_evidence_edited())); connect(ui_evidence_description, SIGNAL(textChanged()), this, SLOT(on_evidence_edited())); + connect(ui_evidence_edit, SIGNAL(clicked()), this, SLOT(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"); @@ -368,26 +377,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); @@ -469,14 +462,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 +591,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 +675,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 +715,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(); } From 74d01e81fbcb9e423cd18ee90eacddbb47f01b14 Mon Sep 17 00:00:00 2001 From: Salanto <62221668+Salanto@users.noreply.github.com> Date: Fri, 3 Sep 2021 01:25:28 +0200 Subject: [PATCH 24/35] Fix VPath lookup ignoring possibility of remote files (#588) * Fix VPath lookup ignoring possibility of remote files * Use more formal URL check Co-authored-by: oldmud0 --- src/path_functions.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/path_functions.cpp b/src/path_functions.cpp index 61df1c6..6fd06e7 100644 --- a/src/path_functions.cpp +++ b/src/path_functions.cpp @@ -253,6 +253,12 @@ QString AOApplication::get_real_path(const VPath &vpath) { } } + // 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(); } From 97b1757da9956dc701a81cb319282ab141819b40 Mon Sep 17 00:00:00 2001 From: Salanto <62221668+Salanto@users.noreply.github.com> Date: Wed, 8 Sep 2021 22:13:22 +0200 Subject: [PATCH 25/35] Remove /pair as a client-side command Who was using this anyway? --- src/courtroom.cpp | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 389dd74..9d0ead7 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -4010,52 +4010,6 @@ void Courtroom::on_ooc_return_pressed() "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 { - int whom = 0; - bool matched = false; - for (char_type chara : char_list) { - if (chara.name.toLower() == ooc_message.toLower()) { - matched = true; - break; - } - whom++; - } - if (matched) { - 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 { - append_server_chatmessage("CLIENT", - tr("Are you sure you typed that well? The char " - "ID/name could not be recognised."), - "1"); - } - } - return; - } else if (ooc_message.startsWith("/offset")) { ui_ooc_chat_message->clear(); ooc_message.remove(0, 8); From b2a4a41fd707633a03ecdef8a484c0f16f13779e Mon Sep 17 00:00:00 2001 From: Rosemary Witchaven <32779090+in1tiate@users.noreply.github.com> Date: Sat, 18 Sep 2021 09:33:00 -0500 Subject: [PATCH 26/35] Fix background positions with no desk inheriting the previous position's desk (#598) * kill bglayer if file not exist * kill ALL layers if file not found --- src/aolayer.cpp | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/aolayer.cpp b/src/aolayer.cpp index 201c724..cf34999 100644 --- a/src/aolayer.cpp +++ b/src/aolayer.cpp @@ -145,7 +145,8 @@ void BackgroundLayer::load_image(QString p_filename) #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 - QVector pathlist { + QVector pathlist { // cursed character path resolution vector ao_app->get_character_path( p_charname, prefix + current_emote), // Default path ao_app->get_character_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,10 @@ 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 @@ -315,8 +321,8 @@ void AOLayer::start_playback(QString p_image) } frame_loader = QtConcurrent::run(this, &AOLayer::populate_vectors); last_path = p_image; - while (movie_frames.size() <= frame) - frameAdded.wait(&mutex); + 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]); if (max_frames <= 1) { @@ -534,7 +540,7 @@ void AOLayer::movie_ticker() } mutex.lock(); while (frame >= movie_frames.size() && frame < max_frames) { // oops! our frame isn't ready yet - frameAdded.wait(&mutex); + frameAdded.wait(&mutex); // wait for a new frame to be added, then check again } mutex.unlock(); #ifdef DEBUG_MOVIE From c163aab671b9590910039a7031ed4f02ff989ed8 Mon Sep 17 00:00:00 2001 From: Rosemary Witchaven <32779090+in1tiate@users.noreply.github.com> Date: Wed, 22 Sep 2021 18:59:59 -0500 Subject: [PATCH 27/35] Allow user to configure log timestamp format (#590) * user configurable timestamp format * fix label making the entire settings window move jankily * add a dropdown for sane timestamp formats * streamline adding options to log timestamp format --- include/aoapplication.h | 3 +++ include/aooptionsdialog.h | 4 ++++ include/courtroom.h | 3 +++ src/aooptionsdialog.cpp | 32 +++++++++++++++++++++++++++++++- src/courtroom.cpp | 7 +++++-- src/text_file_functions.cpp | 6 ++++++ 6 files changed, 52 insertions(+), 3 deletions(-) diff --git a/include/aoapplication.h b/include/aoapplication.h index 718029a..0c5359a 100644 --- a/include/aoapplication.h +++ b/include/aoapplication.h @@ -285,6 +285,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(); diff --git a/include/aooptionsdialog.h b/include/aooptionsdialog.h index 4568b1e..77d19a4 100644 --- a/include/aooptionsdialog.h +++ b/include/aooptionsdialog.h @@ -62,6 +62,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; @@ -197,6 +199,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/courtroom.h b/include/courtroom.h index 09ec486..4bc8624 100644 --- a/include/courtroom.h +++ b/include/courtroom.h @@ -416,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; diff --git a/src/aooptionsdialog.cpp b/src/aooptionsdialog.cpp index 5f3dbf0..aa1d634 100644 --- a/src/aooptionsdialog.cpp +++ b/src/aooptionsdialog.cpp @@ -216,8 +216,33 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) ui_log_timestamp_cb = new QCheckBox(ui_form_layout_widget); + connect(ui_log_timestamp_cb, SIGNAL(stateChanged(int)), this, SLOT(timestamp_cb_changed(int))); + 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, SIGNAL(currentTextChanged(QString)), this, SLOT(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:")); @@ -230,7 +255,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:")); @@ -1072,6 +1096,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()); @@ -1133,6 +1158,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()); @@ -1260,6 +1286,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/courtroom.cpp b/src/courtroom.cpp index 9d0ead7..12b97e5 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); @@ -708,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(); @@ -3127,7 +3130,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"; } diff --git a/src/text_file_functions.cpp b/src/text_file_functions.cpp index d9b341b..aedf3b8 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(); + return result; +} + bool AOApplication::get_log_ic_actions() { QString result = From 273ae6453503627165af6dcc4393c07fcfb440c3 Mon Sep 17 00:00:00 2001 From: Rosemary Witchaven <32779090+in1tiate@users.noreply.github.com> Date: Sat, 9 Oct 2021 10:29:15 -0500 Subject: [PATCH 28/35] Add missing check for anim_state 5 (#601) --- src/courtroom.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 12b97e5..fc2e2f9 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -3286,7 +3286,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()) { From 3c3b88f05c798639f96713e425fb71af60132ce8 Mon Sep 17 00:00:00 2001 From: Rosemary Witchaven <32779090+in1tiate@users.noreply.github.com> Date: Sun, 10 Oct 2021 17:59:07 -0500 Subject: [PATCH 29/35] Fix paired character only playing animations once (#603) --- src/courtroom.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index fc2e2f9..7081c71 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -2451,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); } From 2a923ac86f3bdb41881c3a2d8f21e8ab4c07fa47 Mon Sep 17 00:00:00 2001 From: Salanto <62221668+Salanto@users.noreply.github.com> Date: Tue, 12 Oct 2021 00:53:44 +0200 Subject: [PATCH 30/35] Purge most clientside-OOC commands (#599) Remove OOC-Client commands that are already replaced by UI elements that are easily accessible. Debatable if /save_case and /load_case should stay as they seem unused by most users/servers. * Maintain backwards compatability with older servers. Co-authored-by: oldmud0 --- src/courtroom.cpp | 135 +++++----------------------------------------- 1 file changed, 13 insertions(+), 122 deletions(-) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index 7081c71..dfb58aa 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -151,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); @@ -772,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); @@ -1672,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) { @@ -2268,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) { @@ -2336,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( @@ -3447,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)); @@ -3752,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); } @@ -3999,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); } @@ -4007,120 +4009,9 @@ 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("/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")) { - QStringList command = ooc_message.split(" ", QString::SkipEmptyParts); + if (ooc_message.startsWith("/load_case")) { + QStringList command = ooc_message.split(" ", Qt::SkipEmptyParts); QDir casefolder("base/cases"); if (!casefolder.exists()) { @@ -4218,7 +4109,7 @@ void Courtroom::on_ooc_return_pressed() return; } else if (ooc_message.startsWith("/save_case")) { - QStringList command = ooc_message.split(" ", QString::SkipEmptyParts); + QStringList command = ooc_message.split(" ", Qt::SkipEmptyParts); QDir casefolder("base/cases"); if (!casefolder.exists()) { From 1f985c65c7324e3ca16b6a86006c2da0a88b2ecc Mon Sep 17 00:00:00 2001 From: Salanto <62221668+Salanto@users.noreply.github.com> Date: Tue, 12 Oct 2021 07:27:06 +0200 Subject: [PATCH 31/35] Resolve compile error due to enum first introdcued in Qt 5.14 Could Linux distros please update their Qt version? Thanks. --- src/courtroom.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/courtroom.cpp b/src/courtroom.cpp index dfb58aa..2f09d85 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -4011,8 +4011,11 @@ void Courtroom::on_ooc_return_pressed() } 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()); @@ -4109,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()); From 101a5e506f77eb0a7282a4b5865fe498c954b049 Mon Sep 17 00:00:00 2001 From: in1tiate Date: Mon, 15 Nov 2021 16:48:46 -0600 Subject: [PATCH 32/35] Fix all files being allowed past the suffix check for images --- src/text_file_functions.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/text_file_functions.cpp b/src/text_file_functions.cpp index aedf3b8..d873b3c 100644 --- a/src/text_file_functions.cpp +++ b/src/text_file_functions.cpp @@ -517,7 +517,7 @@ QString AOApplication::get_sfx_suffix(VPath sound_to_check) QString AOApplication::get_image_suffix(VPath path_to_check, bool static_image) { - QStringList suffixes { "" }; + QStringList suffixes {}; if (!static_image) { suffixes.append({ ".webp", ".apng", ".gif" }); } From 658a1ae624e4757a580543dfab149d868ec7636c Mon Sep 17 00:00:00 2001 From: in1tiate Date: Mon, 15 Nov 2021 17:03:36 -0600 Subject: [PATCH 33/35] Add an explicit check for empty string to dir_exists --- src/file_functions.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/file_functions.cpp b/src/file_functions.cpp index 37cdc32..95e9b5f 100644 --- a/src/file_functions.cpp +++ b/src/file_functions.cpp @@ -12,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(); From bc49b3e976e4df01e983a9c9daea28287b9bee75 Mon Sep 17 00:00:00 2001 From: Salanto <62221668+Salanto@users.noreply.github.com> Date: Sat, 11 Dec 2021 00:28:00 +0100 Subject: [PATCH 34/35] Update slots/signals to Qt5 connection style and eliminate some clazy warnings --- src/aoapplication.cpp | 4 +- src/aocaseannouncerdialog.cpp | 8 +- src/aoemotebutton.cpp | 4 +- src/aoevidencebutton.cpp | 10 +- src/aoevidencedisplay.cpp | 2 +- src/aolayer.cpp | 6 +- src/aooptionsdialog.cpp | 24 +-- src/charselect.cpp | 38 ++--- src/chatlogpiece.cpp | 4 +- src/courtroom.cpp | 286 +++++++++++++++++----------------- src/demoserver.cpp | 4 +- src/emotes.cpp | 18 +-- src/evidence.cpp | 88 ++++++----- src/lobby.cpp | 54 +++---- src/networkmanager.cpp | 45 +++--- src/scrolltext.cpp | 2 +- 16 files changed, 300 insertions(+), 297 deletions(-) diff --git a/src/aoapplication.cpp b/src/aoapplication.cpp index 74dc6ed..4a5ed52 100644 --- a/src/aoapplication.cpp +++ b/src/aoapplication.cpp @@ -16,8 +16,8 @@ AOApplication::AOApplication(int &argc, char **argv) : QApplication(argc, argv) net_manager = new NetworkManager(this); discord = new AttorneyOnline::Discord(); - QObject::connect(net_manager, SIGNAL(ms_connect_finished(bool, bool)), - SLOT(ms_connect_finished(bool, bool))); + connect(net_manager, &NetworkManager::ms_connect_finished, + this, &AOApplication::ms_connect_finished); asset_lookup_cache.reserve(2048); } diff --git a/src/aocaseannouncerdialog.cpp b/src/aocaseannouncerdialog.cpp index aea6405..0c9ee0f 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 3260a94..638d49d 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 ae67b82..800c8b4 100644 --- a/src/aoevidencebutton.cpp +++ b/src/aoevidencebutton.cpp @@ -27,7 +27,7 @@ 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) @@ -80,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); } /* @@ -108,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); @@ -118,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 c635a02..0d3eae7 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, diff --git a/src/aolayer.cpp b/src/aolayer.cpp index cf34999..dd1fe76 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) diff --git a/src/aooptionsdialog.cpp b/src/aooptionsdialog.cpp index aa1d634..1b9342c 100644 --- a/src/aooptionsdialog.cpp +++ b/src/aooptionsdialog.cpp @@ -29,12 +29,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); @@ -90,8 +90,8 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) } } - QObject::connect(ui_theme_combobox, SIGNAL(currentIndexChanged(int)), this, - SLOT(theme_changed(int))); + connect(ui_theme_combobox, QOverload::of(&QComboBox::currentIndexChanged), this, + &AOOptionsDialog::theme_changed); ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_theme_combobox); row += 1; @@ -124,8 +124,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); @@ -216,7 +216,7 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) ui_log_timestamp_cb = new QCheckBox(ui_form_layout_widget); - connect(ui_log_timestamp_cb, SIGNAL(stateChanged(int)), this, SLOT(timestamp_cb_changed(int))); + connect(ui_log_timestamp_cb, &QCheckBox::stateChanged, this, &AOOptionsDialog::timestamp_cb_changed); ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_log_timestamp_cb); @@ -238,7 +238,7 @@ AOOptionsDialog::AOOptionsDialog(QWidget *parent, AOApplication *p_ao_app) ui_gameplay_form->setWidget(row, QFormLayout::FieldRole, ui_log_timestamp_format_combobox); - connect(ui_log_timestamp_format_combobox, SIGNAL(currentTextChanged(QString)), this, SLOT(on_timestamp_format_edited())); + 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); diff --git a/src/charselect.cpp b/src/charselect.cpp index 4d5edbc..8928f44 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); @@ -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 05a924c..f4cb225 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 2f09d85..e00d200 100644 --- a/src/courtroom.cpp +++ b/src/courtroom.cpp @@ -399,154 +399,154 @@ Courtroom::Courtroom(AOApplication *p_ao_app) : QMainWindow() construct_char_select(); - connect(keepalive_timer, SIGNAL(timeout()), this, SLOT(ping_server())); + connect(keepalive_timer, &QTimer::timeout, this, &Courtroom::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(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, SIGNAL(timeout()), this, - SLOT(start_chat_ticking())); + connect(text_delay_timer, &QTimer::timeout, this, + &Courtroom::start_chat_ticking); - connect(text_queue_timer, SIGNAL(timeout()), this, - SLOT(chatmessage_dequeue())); + connect(text_queue_timer, &QTimer::timeout, this, + &Courtroom::chatmessage_dequeue); - connect(sfx_delay_timer, SIGNAL(timeout()), this, SLOT(play_sfx())); + connect(sfx_delay_timer, &QTimer::timeout, this, &Courtroom::play_sfx); - connect(chat_tick_timer, SIGNAL(timeout()), this, SLOT(chat_tick())); + connect(chat_tick_timer, &QTimer::timeout, this, &Courtroom::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_pos_dropdown, QOverload::of(&QComboBox::currentIndexChanged), this, + QOverload::of(&Courtroom::on_pos_dropdown_changed)); + connect(ui_pos_dropdown, &QComboBox::editTextChanged, this, + QOverload::of(&Courtroom::on_pos_dropdown_changed)); + connect(ui_pos_remove, &AOButton::clicked, this, &Courtroom::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_iniswap_dropdown, QOverload::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, 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_sfx_dropdown, QOverload::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, 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_effects_dropdown, QOverload::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, 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_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, SIGNAL(returnPressed()), this, - SLOT(on_chat_return_pressed())); + connect(ui_ic_chat_message, &QLineEdit::returnPressed, this, + &Courtroom::on_chat_return_pressed); - connect(ui_ooc_chat_message, SIGNAL(returnPressed()), this, - SLOT(on_ooc_return_pressed())); + connect(ui_ooc_chat_message, &QLineEdit::returnPressed, this, + &Courtroom::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_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, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)), this, - SLOT(on_area_list_double_clicked(QTreeWidgetItem *, int))); + connect(ui_area_list, &QTreeWidget::itemDoubleClicked, this, + &Courtroom::on_area_list_double_clicked); - 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(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 &))); + &AOButton::customContextMenuRequested, this, + &Courtroom::show_custom_objection_menu); - connect(ui_realization, SIGNAL(clicked()), this, - SLOT(on_realization_clicked())); - connect(ui_screenshake, SIGNAL(clicked()), this, - SLOT(on_screenshake_clicked())); + connect(ui_realization, &AOButton::clicked, this, + &Courtroom::on_realization_clicked); + connect(ui_screenshake, &AOButton::clicked, this, + &Courtroom::on_screenshake_clicked); - connect(ui_mute, SIGNAL(clicked()), this, SLOT(on_mute_clicked())); + connect(ui_mute, &AOButton::clicked, this, &Courtroom::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_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, SIGNAL(currentIndexChanged(int)), this, - SLOT(on_text_color_changed(int))); + connect(ui_text_color, QOverload::of(&QComboBox::currentIndexChanged), this, + &Courtroom::on_text_color_changed); - 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_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, SIGNAL(clicked()), this, - SLOT(on_ooc_toggle_clicked())); + connect(ui_ooc_toggle, &AOButton::clicked, this, + &Courtroom::on_ooc_toggle_clicked); - connect(ui_music_search, SIGNAL(textChanged(QString)), this, - SLOT(on_music_search_edited(QString))); + connect(ui_music_search, &QLineEdit::textChanged, this, + &Courtroom::on_music_search_edited); - 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_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, 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_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, 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_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, SIGNAL(clicked()), this, - SLOT(on_showname_enable_clicked())); + connect(ui_showname_enable, &AOButton::clicked, this, + &Courtroom::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_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::of(&QSpinBox::valueChanged), this, + &Courtroom::on_pair_offset_changed); + connect(ui_pair_vert_offset_spinbox, QOverload::of(&QSpinBox::valueChanged), this, + &Courtroom::on_pair_vert_offset_changed); + connect(ui_pair_order_dropdown, QOverload::of(&QComboBox::currentIndexChanged), this, + &Courtroom::on_pair_order_dropdown_changed); - connect(ui_evidence_button, SIGNAL(clicked()), this, - SLOT(on_evidence_button_clicked())); + connect(ui_evidence_button, &AOButton::clicked, this, + &Courtroom::on_evidence_button_clicked); set_widgets(); @@ -586,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); } @@ -601,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); } } @@ -1337,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( @@ -1345,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); } @@ -1762,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); } } @@ -2201,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) { @@ -2763,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 @@ -2783,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"); @@ -3887,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; @@ -4421,7 +4421,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) @@ -4666,7 +4666,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(); @@ -4703,32 +4703,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)); } @@ -4793,7 +4793,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 diff --git a/src/demoserver.cpp b/src/demoserver.cpp index ee0fcf2..db5e1bc 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 8272007..541a6e2 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::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 d34ba4f..fc305d2 100644 --- a/src/evidence.cpp +++ b/src/evidence.cpp @@ -71,41 +71,41 @@ void Courtroom::initialize_evidence() ui_evidence_edit->setToolTip(tr("Edit this piece of evidence.")); ui_evidence_edit->setObjectName("ui_evidence_edit"); - connect(ui_evidence_name, SIGNAL(returnPressed()), this, - SLOT(on_evidence_name_edited())); - 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_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, 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_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_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, 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())); - connect(ui_evidence_edit, SIGNAL(clicked()), this, SLOT(on_evidence_edit_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(); } @@ -236,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; @@ -290,7 +290,11 @@ void Courtroom::set_evidence_list(QVector &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); @@ -318,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(); } @@ -438,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); diff --git a/src/lobby.cpp b/src/lobby.cpp index 31895d1..08fcaae 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); @@ -517,7 +517,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); @@ -533,7 +533,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); @@ -557,9 +557,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 5e29e21..8a90b7c 100644 --- a/src/networkmanager.cpp +++ b/src/networkmanager.cpp @@ -13,15 +13,15 @@ NetworkManager::NetworkManager(AOApplication *parent) : QObject(parent) ms_reconnect_timer = new QTimer(this); ms_reconnect_timer->setSingleShot(true); - QObject::connect(ms_reconnect_timer, SIGNAL(timeout()), this, - SLOT(retry_ms_connect())); + connect(ms_reconnect_timer, &QTimer::timeout, this, + &NetworkManager::retry_ms_connect); - QObject::connect(ms_socket, SIGNAL(readyRead()), this, - SLOT(handle_ms_packet())); - QObject::connect(server_socket, SIGNAL(readyRead()), this, - SLOT(handle_server_packet())); - QObject::connect(server_socket, SIGNAL(disconnected()), ao_app, - SLOT(server_disconnected())); + connect(ms_socket, &QTcpSocket::readyRead, this, + &NetworkManager::handle_ms_packet); + 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(); @@ -45,11 +45,11 @@ void NetworkManager::connect_to_master() void NetworkManager::connect_to_master_nosrv() { - QObject::connect(ms_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, - SLOT(on_ms_socket_error(QAbstractSocket::SocketError))); + connect(ms_socket, &QTcpSocket::errorOccurred, this, + &NetworkManager::on_ms_socket_error); - QObject::connect(ms_socket, SIGNAL(connected()), this, - SLOT(on_ms_nosrv_connect_success())); + connect(ms_socket, &QTcpSocket::connected, this, + &NetworkManager::on_ms_nosrv_connect_success); ms_socket->connectToHost(ms_nosrv_hostname, ms_port); } @@ -110,7 +110,7 @@ void NetworkManager::perform_srv_lookup() #ifdef MS_FAILOVER_SUPPORTED ms_dns = new QDnsLookup(QDnsLookup::SRV, ms_srv_hostname, this); - connect(ms_dns, SIGNAL(finished()), this, SLOT(on_srv_lookup())); + connect(ms_dns, &QDnsLookup::finished, this, &NetworkManager::on_srv_lookup); ms_dns->lookup(); #endif } @@ -155,9 +155,9 @@ void NetworkManager::on_srv_lookup() if (connected) { // Connect a one-shot signal in case the master server disconnects // randomly - QObject::connect( - ms_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, - SLOT(on_ms_socket_error(QAbstractSocket::SocketError))); + connect( + ms_socket, &QTcpSocket::errorOccurred, this, + &NetworkManager::on_ms_socket_error); break; } else { @@ -179,11 +179,11 @@ void NetworkManager::on_ms_nosrv_connect_success() { emit ms_connect_finished(true, false); - QObject::disconnect(ms_socket, SIGNAL(connected()), this, - SLOT(on_ms_nosrv_connect_success())); + disconnect(ms_socket, &QTcpSocket::connected, this, + &NetworkManager::on_ms_nosrv_connect_success); - QObject::connect(ms_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, - SLOT(on_ms_socket_error(QAbstractSocket::SocketError))); + connect(ms_socket, &QTcpSocket::errorOccurred, this, + &NetworkManager::on_ms_socket_error); } void NetworkManager::on_ms_socket_error(QAbstractSocket::SocketError error) @@ -193,9 +193,8 @@ void NetworkManager::on_ms_socket_error(QAbstractSocket::SocketError error) // Disconnect the one-shot signal - this way, failover connect attempts // don't trigger a full retry - QObject::disconnect(ms_socket, SIGNAL(error(QAbstractSocket::SocketError)), - this, - SLOT(on_ms_socket_error(QAbstractSocket::SocketError))); + disconnect(ms_socket, &QTcpSocket::errorOccurred, this, + &NetworkManager::on_ms_socket_error); emit ms_connect_finished(false, true); diff --git a/src/scrolltext.cpp b/src/scrolltext.cpp index d5da6ce..b526a8a 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); } From 641cca65044e41e49e5a871f0d60138b61c1bab3 Mon Sep 17 00:00:00 2001 From: Salanto <62221668+Salanto@users.noreply.github.com> Date: Wed, 15 Dec 2021 03:32:05 +0100 Subject: [PATCH 35/35] Add compiler flags to ensure correct signal is used in older versions (#617) --- src/networkmanager.cpp | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/src/networkmanager.cpp b/src/networkmanager.cpp index 8a90b7c..08d0124 100644 --- a/src/networkmanager.cpp +++ b/src/networkmanager.cpp @@ -45,11 +45,17 @@ void NetworkManager::connect_to_master() void NetworkManager::connect_to_master_nosrv() { - connect(ms_socket, &QTcpSocket::errorOccurred, this, - &NetworkManager::on_ms_socket_error); +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + connect(ms_socket, QOverload::of(&QAbstractSocket::error), + this, &NetworkManager::on_ms_socket_error); +#else + connect(ms_socket, &QTcpSocket::errorOccurred, + this, &NetworkManager::on_ms_socket_error); +#endif + + connect(ms_socket, &QTcpSocket::connected, + this, &NetworkManager::on_ms_nosrv_connect_success); - connect(ms_socket, &QTcpSocket::connected, this, - &NetworkManager::on_ms_nosrv_connect_success); ms_socket->connectToHost(ms_nosrv_hostname, ms_port); } @@ -155,9 +161,13 @@ void NetworkManager::on_srv_lookup() if (connected) { // Connect a one-shot signal in case the master server disconnects // randomly - connect( - ms_socket, &QTcpSocket::errorOccurred, this, - &NetworkManager::on_ms_socket_error); +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + connect(ms_socket, QOverload::of(&QAbstractSocket::error), + this, &NetworkManager::on_ms_socket_error); +#else + connect(ms_socket, &QTcpSocket::errorOccurred, + this, &NetworkManager::on_ms_socket_error); +#endif break; } else { @@ -182,8 +192,13 @@ void NetworkManager::on_ms_nosrv_connect_success() disconnect(ms_socket, &QTcpSocket::connected, this, &NetworkManager::on_ms_nosrv_connect_success); - connect(ms_socket, &QTcpSocket::errorOccurred, this, - &NetworkManager::on_ms_socket_error); +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + connect(ms_socket, QOverload::of(&QAbstractSocket::error), + this, &NetworkManager::on_ms_socket_error); +#else + connect(ms_socket, &QTcpSocket::errorOccurred, + this, &NetworkManager::on_ms_socket_error); +#endif } void NetworkManager::on_ms_socket_error(QAbstractSocket::SocketError error) @@ -193,8 +208,13 @@ void NetworkManager::on_ms_socket_error(QAbstractSocket::SocketError error) // Disconnect the one-shot signal - this way, failover connect attempts // don't trigger a full retry - disconnect(ms_socket, &QTcpSocket::errorOccurred, this, - &NetworkManager::on_ms_socket_error); +#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0) + disconnect(ms_socket, QOverload::of(&QAbstractSocket::error), + this, &NetworkManager::on_ms_socket_error); +#else + disconnect(ms_socket, &QTcpSocket::errorOccurred, + this, &NetworkManager::on_ms_socket_error); +#endif emit ms_connect_finished(false, true);