diff options
Diffstat (limited to 'src/widgets')
| -rw-r--r-- | src/widgets/add_server_dialog.cpp | 96 | ||||
| -rw-r--r-- | src/widgets/aooptionsdialog.cpp | 648 | ||||
| -rw-r--r-- | src/widgets/direct_connect_dialog.cpp | 101 | ||||
| -rw-r--r-- | src/widgets/edit_server_dialog.cpp | 87 |
4 files changed, 932 insertions, 0 deletions
diff --git a/src/widgets/add_server_dialog.cpp b/src/widgets/add_server_dialog.cpp new file mode 100644 index 00000000..d590d77c --- /dev/null +++ b/src/widgets/add_server_dialog.cpp @@ -0,0 +1,96 @@ +#include "widgets/add_server_dialog.h" +#include "datatypes.h" +#include "options.h" + +#include <QComboBox> +#include <QDebug> +#include <QDialogButtonBox> +#include <QFile> +#include <QLineEdit> +#include <QLabel> +#include <QPlainTextEdit> +#include <QPushButton> +#include <QSpinBox> +#include <QUiLoader> +#include <QVBoxLayout> + +#define FROM_UI(type, name) \ + ; \ + ui_##name = findChild<type *>(#name); + +AddServerDialog::AddServerDialog() +{ + QUiLoader l_loader(this); + QFile l_uiFile(Options::getInstance().getUIAsset(DEFAULT_UI)); + + if (!l_uiFile.open(QFile::ReadOnly)) { + qCritical() << "Unable to open file " << l_uiFile.fileName(); + return; + } + ui_widget = l_loader.load(&l_uiFile, this); + + auto l_layout = new QVBoxLayout(this); + l_layout->addWidget(ui_widget); + + FROM_UI(QLineEdit, server_display_name_edit); + FROM_UI(QLineEdit, server_hostname_edit); + FROM_UI(QSpinBox, server_port_box); + FROM_UI(QComboBox, server_protocol_box); + FROM_UI(QPlainTextEdit, server_description_edit); + FROM_UI(QDialogButtonBox, server_dialog_button); + connect(ui_server_dialog_button, &QDialogButtonBox::accepted, this, + &::AddServerDialog::onSavePressed); + connect(ui_server_dialog_button, &QDialogButtonBox::rejected, this, + &AddServerDialog::onCancelPressed); + + FROM_UI(QLabel, server_legacy_lbl); + FROM_UI(QLineEdit, server_legacy_edit); + FROM_UI(QPushButton, server_legacy_load_button); + connect(ui_server_legacy_load_button, &QPushButton::released, this, + &AddServerDialog::parseLegacyServerEntry); +} + +void AddServerDialog::onSavePressed() +{ + server_type server; + server.name = ui_server_display_name_edit->text(); + server.ip = ui_server_hostname_edit->text(); + server.port = ui_server_port_box->value(); + server.desc = ui_server_description_edit->toPlainText(); + server.socket_type = + ui_server_protocol_box->currentIndex() == TCP_INDEX ? TCP : WEBSOCKETS; + Options::getInstance().addFavorite(server); + close(); +} + +void AddServerDialog::onCancelPressed() +{ + close(); + deleteLater(); +} + +void AddServerDialog::parseLegacyServerEntry() +{ + QStringList l_legacy_entry = ui_server_legacy_edit->text().split(":"); + server_type l_server_entry; + if (l_legacy_entry.isEmpty()) { + qDebug() << "Legacy entry empty."; + return; + } + + int l_item_count = l_legacy_entry.size(); + + if (l_item_count >= 3) { + ui_server_hostname_edit->setText(l_legacy_entry.at(0)); + ui_server_port_box->setValue(l_legacy_entry.at(1).toInt()); + ui_server_display_name_edit->setText(l_legacy_entry.at(2)); + if (l_item_count >= 4) { + if (l_legacy_entry.at(3) == "ws") { + ui_server_protocol_box->setCurrentIndex(1); + } + else { + ui_server_protocol_box->setCurrentIndex(0); + } + } + } +} diff --git a/src/widgets/aooptionsdialog.cpp b/src/widgets/aooptionsdialog.cpp new file mode 100644 index 00000000..8b7befe9 --- /dev/null +++ b/src/widgets/aooptionsdialog.cpp @@ -0,0 +1,648 @@ +#include "widgets/aooptionsdialog.h" +#include "QDesktopServices" +#include "aoapplication.h" +#include "bass.h" +#include "file_functions.h" +#include "networkmanager.h" +#include "options.h" + +#include <QCheckBox> +#include <QCollator> +#include <QComboBox> +#include <QDialogButtonBox> +#include <QGroupBox> +#include <QLabel> +#include <QLineEdit> +#include <QPlainTextEdit> +#include <QPushButton> +#include <QResource> +#include <QSpinBox> +#include <QUiLoader> +#include <QVBoxLayout> + +#define FROM_UI(type, name) \ + ; \ + ui_##name = findChild<type *>(#name); + +AOOptionsDialog::AOOptionsDialog(QDialog *parent, AOApplication *p_ao_app) + : QDialog(parent) +{ + ao_app = p_ao_app; + setupUI(); +} + +void AOOptionsDialog::populateAudioDevices() +{ + ui_audio_device_combobox->clear(); + if (needsDefaultAudioDevice()) { + ui_audio_device_combobox->addItem("default"); + } + + BASS_DEVICEINFO info; + for (int a = 0; BASS_GetDeviceInfo(a, &info); a++) { + ui_audio_device_combobox->addItem(info.name); + } +} + +template <> +void AOOptionsDialog::setWidgetData(QCheckBox *widget, const bool &value) +{ + widget->setChecked(value); +} + +template <> bool AOOptionsDialog::widgetData(QCheckBox *widget) const +{ + return widget->isChecked(); +} + +template <> +void AOOptionsDialog::setWidgetData(QLineEdit *widget, const QString &value) +{ + widget->setText(value); +} + +template <> QString AOOptionsDialog::widgetData(QLineEdit *widget) const +{ + return widget->text(); +} + +template <> +void AOOptionsDialog::setWidgetData(QLineEdit *widget, const uint16_t &value) +{ + widget->setText(QString::number(value)); +} + +template <> uint16_t AOOptionsDialog::widgetData(QLineEdit *widget) const +{ + return widget->text().toUShort(); +} + +template <> +void AOOptionsDialog::setWidgetData(QPlainTextEdit *widget, + const QStringList &value) +{ + widget->setPlainText(value.join('\n')); +} + +template <> +QStringList AOOptionsDialog::widgetData(QPlainTextEdit *widget) const +{ + return widget->toPlainText().trimmed().split('\n'); +} + +template <> +void AOOptionsDialog::setWidgetData(QSpinBox *widget, const int &value) +{ + widget->setValue(value); +} + +template <> int AOOptionsDialog::widgetData(QSpinBox *widget) const +{ + return widget->value(); +} + +template <> +void AOOptionsDialog::setWidgetData(QComboBox *widget, const QString &value) +{ + for (auto i = 0; i < widget->count(); i++) { + if (widget->itemText(i) == value) { + widget->setCurrentIndex(i); + return; + } + } + qWarning() << "value" << value << "not found for widget" + << widget->objectName(); +} + +template <> QString AOOptionsDialog::widgetData(QComboBox *widget) const +{ + return widget->currentText(); +} + +template <> +void AOOptionsDialog::setWidgetData(QGroupBox *widget, const bool &value) +{ + widget->setChecked(value); +} + +template <> bool AOOptionsDialog::widgetData(QGroupBox *widget) const +{ + return widget->isChecked(); +} + +template <> +void AOOptionsDialog::setWidgetData(QListWidget *widget, + const QStringList &value) +{ + widget->addItems(value); +} + +template <> QStringList AOOptionsDialog::widgetData(QListWidget *widget) const +{ + QStringList paths; + for (auto i = 1; i < widget->count(); i++) { + paths.append(widget->item(i)->text()); + } + return paths; +} + +template <typename T, typename V> +void AOOptionsDialog::registerOption(const QString &widgetName, + V (Options::*getter)() const, + void (Options::*setter)(V)) +{ + auto *widget = findChild<T *>(widgetName); + if (!widget) { + qWarning() << "could not find widget" << widgetName; + return; + } + + OptionEntry entry; + entry.load = [=] { + setWidgetData<T, V>(widget, (Options::getInstance().*getter)()); + }; + entry.save = [=] { + (Options::getInstance().*setter)(widgetData<T, V>(widget)); + }; + + optionEntries.append(entry); +} + +void AOOptionsDialog::updateValues() +{ + QSet<QString> themes; + QStringList bases = Options::getInstance().mountPaths(); + bases.push_front(get_base_path()); + + for (const QString &base : bases) { + QStringList l_themes = + QDir(base + "themes").entryList(QDir::Dirs | QDir::NoDotAndDotDot); + + // Resorts list to match numeric sorting found in Windows. + QCollator l_sorting; + l_sorting.setNumericMode(true); + std::sort(l_themes.begin(), l_themes.end(), l_sorting); + + for (const QString &l_theme : qAsConst(l_themes)) { + if (!themes.contains(l_theme)) { + ui_theme_combobox->addItem(l_theme); + themes.insert(l_theme); + } + } + } + + QStringList l_subthemes = + QDir(ao_app->get_real_path(ao_app->get_theme_path(""))) + .entryList(QDir::Dirs | QDir::NoDotAndDotDot); + for (const QString &l_subtheme : qAsConst(l_subthemes)) { + if (l_subtheme.toLower() != "server" && l_subtheme.toLower() != "default" && + l_subtheme.toLower() != "effects" && l_subtheme.toLower() != "misc") { + ui_subtheme_combobox->addItem(l_subtheme); + } + } + + ao_app->net_manager->request_document( + MSDocumentType::PrivacyPolicy, [this](QString document) { + if (document.isEmpty()) { + document = tr("Couldn't get the privacy policy."); + } + ui_privacy_policy->setHtml(document); + }); + + for (const OptionEntry &entry : qAsConst(optionEntries)) { + entry.load(); + } +} + +void AOOptionsDialog::savePressed() +{ + bool l_reload_theme_required = (ui_theme_combobox->currentText() != Options::getInstance().theme()); + for (const OptionEntry &entry : qAsConst(optionEntries)) { + entry.save(); + } + + if (l_reload_theme_required) { + emit reloadThemeRequest(); + } + close(); +} + +void AOOptionsDialog::discardPressed() { close(); } + +void AOOptionsDialog::buttonClicked(QAbstractButton *button) +{ + if (ui_settings_buttons->buttonRole(button) == QDialogButtonBox::ResetRole) { + if (QMessageBox::question( + this, "", "Restore default settings?\nThis can't be undone!", + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + // Destructive operation. + Options::getInstance().clearConfig(); + updateValues(); + } + } +} + +void AOOptionsDialog::onReloadThemeClicked() +{ + Options::getInstance().setTheme(ui_theme_combobox->currentText()); + Options::getInstance().setSettingsSubTheme(ui_subtheme_combobox->currentText()); + Options::getInstance().setAnimatedThemeEnabled( + ui_animated_theme_cb->isChecked()); + emit reloadThemeRequest(); + delete layout(); + delete ui_settings_widget; + optionEntries.clear(); + setupUI(); +} + +void AOOptionsDialog::themeChanged(int i) +{ + ui_subtheme_combobox->clear(); + // Fill the combobox with the names of the themes. + ui_subtheme_combobox->addItem("server"); + ui_subtheme_combobox->addItem("default"); + + QStringList l_subthemes = QDir(ao_app->get_real_path(ao_app->get_theme_path( + "", ui_theme_combobox->itemText(i)))) + .entryList(QDir::Dirs | QDir::NoDotAndDotDot); + + for (const QString &l_subthemes : qAsConst(l_subthemes)) { + if (l_subthemes.toLower() != "server" && + l_subthemes.toLower() != "default" && + l_subthemes.toLower() != "effects" && l_subthemes.toLower() != "misc") { + ui_subtheme_combobox->addItem(l_subthemes); + } + } + + QString l_ressource_name = Options::getInstance().theme() + ".rcc"; + QString l_resource = + ao_app->get_asset("themes/" + ui_theme_combobox->currentText() + ".rcc"); + if (l_resource.isEmpty()) { + QResource::unregisterResource( + ao_app->get_asset("themes/" + l_ressource_name)); + qDebug() << "Unable to locate ressource file" << l_ressource_name; + return; + } + QResource::registerResource(l_resource); +} + +void AOOptionsDialog::setupUI() +{ + QUiLoader l_loader(this); + QFile l_uiFile(Options::getInstance().getUIAsset("options_dialog.ui")); + if (!l_uiFile.open(QFile::ReadOnly)) { + qWarning() << "Unable to open file " << l_uiFile.fileName(); + return; + } + + ui_settings_widget = l_loader.load(&l_uiFile, this); + + auto l_layout = new QVBoxLayout(this); + l_layout->addWidget(ui_settings_widget); + + // General dialog element. + FROM_UI(QDialogButtonBox, settings_buttons); + + connect(ui_settings_buttons, &QDialogButtonBox::accepted, this, + &AOOptionsDialog::savePressed); + connect(ui_settings_buttons, &QDialogButtonBox::rejected, this, + &AOOptionsDialog::discardPressed); + connect(ui_settings_buttons, &QDialogButtonBox::clicked, this, + &AOOptionsDialog::buttonClicked); + + // Gameplay Tab + FROM_UI(QComboBox, theme_combobox) + connect(ui_theme_combobox, + QOverload<int>::of(&QComboBox::currentIndexChanged), this, + &AOOptionsDialog::themeChanged); + + registerOption<QComboBox, QString>("theme_combobox", &Options::theme, + &Options::setTheme); + + FROM_UI(QComboBox, subtheme_combobox) + registerOption<QComboBox, QString>("subtheme_combobox", &Options::settingsSubTheme, + &Options::setSettingsSubTheme); + + FROM_UI(QPushButton, theme_reload_button) + connect(ui_theme_reload_button, &QPushButton::clicked, this, + &::AOOptionsDialog::onReloadThemeClicked); + + FROM_UI(QPushButton, theme_folder_button) + connect(ui_theme_folder_button, &QPushButton::clicked, this, [=] { + QString p_path = ao_app->get_real_path(ao_app->get_theme_path( + "", ui_theme_combobox->itemText(ui_theme_combobox->currentIndex()))); + if (!dir_exists(p_path)) { + return; + } + QDesktopServices::openUrl(QUrl::fromLocalFile(p_path)); + }); + + FROM_UI(QCheckBox, animated_theme_cb) + FROM_UI(QSpinBox, stay_time_spinbox) + FROM_UI(QCheckBox, instant_objection_cb) + FROM_UI(QSpinBox, text_crawl_spinbox) + FROM_UI(QSpinBox, chat_ratelimit_spinbox) + FROM_UI(QLineEdit, username_textbox) + FROM_UI(QCheckBox, showname_cb) + FROM_UI(QLineEdit, default_showname_textbox) + FROM_UI(QLineEdit, ms_textbox) + FROM_UI(QCheckBox, discord_cb) + FROM_UI(QComboBox, language_combobox) + FROM_UI(QComboBox, scaling_combobox) + FROM_UI(QCheckBox, shake_cb) + FROM_UI(QCheckBox, effects_cb) + FROM_UI(QCheckBox, framenetwork_cb) + FROM_UI(QCheckBox, colorlog_cb) + FROM_UI(QCheckBox, stickysounds_cb) + FROM_UI(QCheckBox, stickyeffects_cb) + FROM_UI(QCheckBox, stickypres_cb) + FROM_UI(QCheckBox, customchat_cb) + FROM_UI(QCheckBox, sticker_cb) + FROM_UI(QCheckBox, continuous_cb) + FROM_UI(QCheckBox, category_stop_cb) + FROM_UI(QCheckBox, sfx_on_idle_cb) + FROM_UI(QCheckBox, evidence_double_click_cb) + + registerOption<QCheckBox, bool>("animated_theme_cb", + &Options::animatedThemeEnabled, + &Options::setAnimatedThemeEnabled); + registerOption<QSpinBox, int>("stay_time_spinbox", &Options::textStayTime, + &Options::setTextStayTime); + registerOption<QCheckBox, bool>("instant_objection_cb", + &Options::objectionSkipQueueEnabled, + &Options::setObjectionSkipQueueEnabled); + registerOption<QSpinBox, int>("text_crawl_spinbox", &Options::textCrawlSpeed, + &Options::setTextCrawlSpeed); + registerOption<QSpinBox, int>("chat_ratelimit_spinbox", + &Options::chatRateLimit, + &Options::setChatRateLimit); + registerOption<QLineEdit, QString>("username_textbox", &Options::username, + &Options::setUsername); + registerOption<QCheckBox, bool>("showname_cb", + &Options::customShownameEnabled, + &Options::setCustomShownameEnabled); + registerOption<QLineEdit, QString>("default_showname_textbox", + &Options::shownameOnJoin, + &Options::setShownameOnJoin); + registerOption<QLineEdit, QString>("ms_textbox", + &Options::alternativeMasterserver, + &Options::setAlternativeMasterserver); + registerOption<QCheckBox, bool>("discord_cb", &Options::discordEnabled, + &Options::setDiscordEnabled); + registerOption<QComboBox, QString>("language_combobox", &Options::language, + &Options::setLanguage); + registerOption<QComboBox, QString>("scaling_combobox", + &Options::defaultScalingMode, + &Options::setDefaultScalingMode); + + // Populate scaling dropdown. This is necessary as we need the user data + // embeeded into the entry. + ui_scaling_combobox->addItem(tr("Pixel"), "fast"); + ui_scaling_combobox->addItem(tr("Smooth"), "smooth"); + + registerOption<QCheckBox, bool>("shake_cb", &Options::shakeEnabled, + &Options::setShakeEnabled); + registerOption<QCheckBox, bool>("effects_cb", &Options::effectsEnabled, + &Options::setEffectsEnabled); + registerOption<QCheckBox, bool>("framenetwork_cb", + &Options::networkedFrameSfxEnabled, + &Options::setNetworkedFrameSfxEnabled); + registerOption<QCheckBox, bool>("colorlog_cb", &Options::colorLogEnabled, + &Options::setColorLogEnabled); + registerOption<QCheckBox, bool>( + "stickysounds_cb", &Options::clearSoundsDropdownOnPlayEnabled, + &Options::setClearSoundsDropdownOnPlayEnabled); + registerOption<QCheckBox, bool>( + "stickyeffects_cb", &Options::clearEffectsDropdownOnPlayEnabled, + &Options::setClearEffectsDropdownOnPlayEnabled); + registerOption<QCheckBox, bool>("stickypres_cb", + &Options::clearPreOnPlayEnabled, + &Options::setClearPreOnPlayEnabled); + registerOption<QCheckBox, bool>("customchat_cb", + &Options::customChatboxEnabled, + &Options::setCustomChatboxEnabled); + registerOption<QCheckBox, bool>("sticker_cb", + &Options::characterStickerEnabled, + &Options::setCharacterStickerEnabled); + registerOption<QCheckBox, bool>("continuous_cb", + &Options::continuousPlaybackEnabled, + &Options::setContinuousPlaybackEnabled); + registerOption<QCheckBox, bool>("category_stop_cb", + &Options::stopMusicOnCategoryEnabled, + &Options::setStopMusicOnCategoryEnabled); + registerOption<QCheckBox, bool>("sfx_on_idle_cb", + &Options::playSelectedSFXOnIdle, + &Options::setPlaySelectedSFXOnIdle); + registerOption<QCheckBox, bool>("evidence_double_click_cb", + &Options::evidenceDoubleClickEdit, + &Options::setEvidenceDoubleClickEdit); + + // Callwords tab. This could just be a QLineEdit, but no, we decided to allow + // people to put a billion entries in. + FROM_UI(QPlainTextEdit, callwords_textbox) + registerOption<QPlainTextEdit, QStringList>( + "callwords_textbox", &Options::callwords, &Options::setCallwords); + + // Audio tab. + FROM_UI(QComboBox, audio_device_combobox) + populateAudioDevices(); + registerOption<QComboBox, QString>("audio_device_combobox", + &Options::audioOutputDevice, + &Options::setAudioOutputDevice); + + FROM_UI(QSpinBox, suppress_audio_spinbox) + FROM_UI(QSpinBox, bliprate_spinbox) + FROM_UI(QCheckBox, blank_blips_cb) + FROM_UI(QCheckBox, loopsfx_cb) + FROM_UI(QCheckBox, objectmusic_cb) + FROM_UI(QCheckBox, disablestreams_cb) + + registerOption<QSpinBox, int>("suppress_audio_spinbox", + &::Options::defaultSuppressAudio, + &Options::setDefaultSupressedAudio); + registerOption<QSpinBox, int>("bliprate_spinbox", &::Options::blipRate, + &Options::setBlipRate); + registerOption<QCheckBox, bool>("blank_blips_cb", &Options::blankBlip, + &Options::setBlankBlip); + registerOption<QCheckBox, bool>("loopsfx_cb", &Options::loopingSfx, + &Options::setLoopingSfx); + registerOption<QCheckBox, bool>("objectmusic_cb", + &Options::objectionStopMusic, + &Options::setObjectionStopMusic); + registerOption<QCheckBox, bool>("disablestreams_cb", + &Options::streamingEnabled, + &Options::setStreamingEnabled); + + // Asset tab + FROM_UI(QListWidget, mount_list) + auto *defaultMount = + new QListWidgetItem(tr("%1 (default)").arg(get_base_path())); + defaultMount->setFlags(Qt::ItemFlag::NoItemFlags); + ui_mount_list->addItem(defaultMount); + registerOption<QListWidget, QStringList>("mount_list", &Options::mountPaths, + &Options::setMountPaths); + + FROM_UI(QPushButton, mount_add) + connect(ui_mount_add, &QPushButton::clicked, this, [this] { + QString path = QFileDialog::getExistingDirectory( + this, tr("Select a base folder"), QApplication::applicationDirPath(), + QFileDialog::ShowDirsOnly); + if (path.isEmpty()) { + return; + } + QDir dir(QApplication::applicationDirPath()); + QString relative = dir.relativeFilePath(path); + if (!relative.contains("../")) { + path = relative; + } + QListWidgetItem *dir_item = new QListWidgetItem(path); + ui_mount_list->addItem(dir_item); + ui_mount_list->setCurrentItem(dir_item); + + // quick hack to update buttons + emit ui_mount_list->itemSelectionChanged(); + }); + + FROM_UI(QPushButton, mount_remove) + connect(ui_mount_remove, &QPushButton::clicked, this, [this] { + auto selected = ui_mount_list->selectedItems(); + if (selected.isEmpty()) return; + delete selected[0]; + emit ui_mount_list->itemSelectionChanged(); + asset_cache_dirty = true; + }); + + FROM_UI(QPushButton, mount_up) + connect(ui_mount_up, &QPushButton::clicked, this, [this] { + auto selected = ui_mount_list->selectedItems(); + if (selected.isEmpty()) return; + auto *item = selected[0]; + int row = ui_mount_list->row(item); + ui_mount_list->takeItem(row); + int new_row = qMax(1, row - 1); + ui_mount_list->insertItem(new_row, item); + ui_mount_list->setCurrentRow(new_row); + asset_cache_dirty = true; + }); + + FROM_UI(QPushButton, mount_down) + connect(ui_mount_down, &QPushButton::clicked, this, [this] { + auto selected = ui_mount_list->selectedItems(); + if (selected.isEmpty()) return; + auto *item = selected[0]; + int row = ui_mount_list->row(item); + ui_mount_list->takeItem(row); + int new_row = qMin(ui_mount_list->count() + 1, row + 1); + ui_mount_list->insertItem(new_row, item); + ui_mount_list->setCurrentRow(new_row); + asset_cache_dirty = true; + }); + + FROM_UI(QPushButton, mount_clear_cache) + connect(ui_mount_clear_cache, &QPushButton::clicked, this, [this] { + asset_cache_dirty = true; + ui_mount_clear_cache->setEnabled(false); + }); + + connect(ui_mount_list, &QListWidget::itemSelectionChanged, this, [this] { + auto selected_items = ui_mount_list->selectedItems(); + bool row_selected = !ui_mount_list->selectedItems().isEmpty(); + ui_mount_remove->setEnabled(row_selected); + ui_mount_up->setEnabled(row_selected); + ui_mount_down->setEnabled(row_selected); + + if (!row_selected) return; + + int row = ui_mount_list->row(selected_items[0]); + if (row <= 1) ui_mount_up->setEnabled(false); + if (row >= ui_mount_list->count() - 1) ui_mount_down->setEnabled(false); + }); + + // Logging tab + FROM_UI(QCheckBox, downwards_cb) + FROM_UI(QSpinBox, length_spinbox) + FROM_UI(QCheckBox, log_newline_cb) + FROM_UI(QSpinBox, log_margin_spinbox) + FROM_UI(QLabel, log_timestamp_format_lbl) + FROM_UI(QComboBox, log_timestamp_format_combobox) + + registerOption<QCheckBox, bool>("downwards_cb", + &Options::logDirectionDownwards, + &Options::setLogDirectionDownwards); + registerOption<QSpinBox, int>("length_spinbox", &Options::maxLogSize, + &Options::setMaxLogSize); + registerOption<QCheckBox, bool>("log_newline_cb", &Options::logNewline, + &Options::setLogNewline); + registerOption<QSpinBox, int>("log_margin_spinbox", &Options::logMargin, + &Options::setLogMargin); + + FROM_UI(QCheckBox, log_timestamp_cb) + registerOption<QCheckBox, bool>("log_timestamp_cb", + &Options::logTimestampEnabled, + &Options::setLogTimestampEnabled); + connect(ui_log_timestamp_cb, &QCheckBox::stateChanged, this, + &::AOOptionsDialog::timestampCbChanged); + ui_log_timestamp_format_lbl->setText( + tr("Log timestamp format:\n") + + QDateTime::currentDateTime().toString( + Options::getInstance().logTimestampFormat())); + + FROM_UI(QComboBox, log_timestamp_format_combobox) + registerOption<QComboBox, QString>("log_timestamp_format_combobox", + &Options::logTimestampFormat, + &Options::setLogTimestampFormat); + connect(ui_log_timestamp_format_combobox, &QComboBox::currentTextChanged, + this, &::AOOptionsDialog::onTimestampFormatEdited); + + QString l_current_format = Options::getInstance().logTimestampFormat(); + + ui_log_timestamp_format_combobox->setCurrentText(l_current_format); + + if (!Options::getInstance().logTimestampEnabled()) { + ui_log_timestamp_format_combobox->setDisabled(true); + } + + FROM_UI(QCheckBox, log_ic_actions_cb) + FROM_UI(QCheckBox, desync_logs_cb) + FROM_UI(QCheckBox, log_text_cb) + + registerOption<QCheckBox, bool>("log_ic_actions_cb", &Options::logIcActions, + &Options::setLogIcActions); + registerOption<QCheckBox, bool>("desync_logs_cb", + &Options::desynchronisedLogsEnabled, + &Options::setDesynchronisedLogsEnabled); + registerOption<QCheckBox, bool>("log_text_cb", &Options::logToTextFileEnabled, + &Options::setLogToTextFileEnabled); + registerOption<QCheckBox, bool>("log_demo_cb", &Options::logToDemoFileEnabled, + &Options::setLogToDemoFileEnabled); + + // DSGVO/Privacy tab + + FROM_UI(QTextBrowser, privacy_policy) + ui_privacy_policy->setPlainText(tr("Getting privacy policy...")); + + updateValues(); +} + +void AOOptionsDialog::onTimestampFormatEdited() +{ + ui_log_timestamp_format_lbl->setText( + tr("Log timestamp format:\n") + + QDateTime::currentDateTime().toString( + ui_log_timestamp_format_combobox->currentText())); +} + +void AOOptionsDialog::timestampCbChanged(int state) +{ + ui_log_timestamp_format_combobox->setDisabled(state == 0); +} + +#if (defined(_WIN32) || defined(_WIN64)) +bool AOOptionsDialog::needsDefaultAudioDevice() { return true; } +#elif (defined(LINUX) || defined(__linux__)) +bool AOOptionsDialog::needsDefaultAudioDevice() { return false; } +#elif defined __APPLE__ +bool AOOptionsDialog::needsDefaultAudioDevice() { return true; } +#else +#error This operating system is not supported. +#endif diff --git a/src/widgets/direct_connect_dialog.cpp b/src/widgets/direct_connect_dialog.cpp new file mode 100644 index 00000000..82eaa23a --- /dev/null +++ b/src/widgets/direct_connect_dialog.cpp @@ -0,0 +1,101 @@ +#include "widgets/direct_connect_dialog.h" + +#include "networkmanager.h" +#include "options.h" +#include "debug_functions.h" + +#include <QComboBox> +#include <QLabel> +#include <QLineEdit> +#include <QPushButton> +#include <QSpinBox> +#include <QUiLoader> +#include <QVBoxLayout> +#include <QRegularExpressionMatch> +#include <QStringBuilder> +#include <QUrl> + +#define FROM_UI(type, name) \ + ; \ + ui_##name = findChild<type *>(#name); + +DirectConnectDialog::DirectConnectDialog(NetworkManager *p_net_manager) : + net_manager(p_net_manager) +{ + QUiLoader l_loader(this); + QFile l_uiFile(Options::getInstance().getUIAsset(DEFAULT_UI)); + + if (!l_uiFile.open(QFile::ReadOnly)) { + qCritical() << "Unable to open file " << l_uiFile.fileName(); + return; + } + ui_widget = l_loader.load(&l_uiFile, this); + + auto l_layout = new QVBoxLayout(this); + l_layout->addWidget(ui_widget); + + FROM_UI(QLineEdit, direct_hostname_edit) + + FROM_UI(QLabel, direct_connection_status_lbl) + + FROM_UI(QPushButton, direct_connect_button); + connect(ui_direct_connect_button, &QPushButton::pressed, + this, &DirectConnectDialog::onConnectPressed); + FROM_UI(QPushButton, direct_cancel_button); + connect(ui_direct_cancel_button, &QPushButton::pressed, + this, &DirectConnectDialog::close); + + connect(net_manager, &NetworkManager::server_connected, + this, &DirectConnectDialog::onServerConnected); + + connect(&connect_timeout, &QTimer::timeout, this, + &DirectConnectDialog::onConnectTimeout); + connect_timeout.setSingleShot(true); +} + +void DirectConnectDialog::onConnectPressed() +{ + QString l_hostname = ui_direct_hostname_edit->text(); + if (!SCHEME_PATTERN.match(l_hostname).hasMatch()) { + l_hostname = "tcp://" % l_hostname; + } + QUrl l_url(l_hostname); + if (!l_url.isValid()) { + call_error(tr("Invalid URL.")); + return; + } + if (!to_connection_type.contains(l_url.scheme())) { + call_error(tr("Scheme not recognized. Must be either of the following: ") % QStringList::fromVector(to_connection_type.keys().toVector()).join(", ")); + return; + } + if (l_url.port() == -1) { + call_error(tr("Invalid server port.")); + return; + } + server_type l_server; + l_server.socket_type = to_connection_type[l_url.scheme()]; + l_server.ip = l_url.host(); + l_server.port = l_url.port(); + l_server.name = "Direct Connection"; + + net_manager->connect_to_server(l_server); + ui_direct_connect_button->setEnabled(false); + ui_direct_connection_status_lbl->setText("Connecting..."); + ui_direct_connection_status_lbl->setStyleSheet("color : rgb(0,64,156)"); + connect_timeout.start(CONNECT_TIMEOUT); +} + +void DirectConnectDialog::onServerConnected() +{ + net_manager->join_to_server(); + ui_direct_connection_status_lbl->setText("Connected!"); + ui_direct_connection_status_lbl->setStyleSheet("color: rgb(0,128,0)"); + close(); +} + +void DirectConnectDialog::onConnectTimeout() +{ + ui_direct_connect_button->setEnabled(true); + ui_direct_connection_status_lbl->setText("Connection Timeout!"); + ui_direct_connection_status_lbl->setStyleSheet("color: rgb(255,0,0)"); +} diff --git a/src/widgets/edit_server_dialog.cpp b/src/widgets/edit_server_dialog.cpp new file mode 100644 index 00000000..109e968f --- /dev/null +++ b/src/widgets/edit_server_dialog.cpp @@ -0,0 +1,87 @@ +#include "widgets/edit_server_dialog.h" +#include "datatypes.h" +#include "options.h" + +#include <QComboBox> +#include <QDebug> +#include <QDialogButtonBox> +#include <QFile> +#include <QLineEdit> +#include <QLabel> +#include <QPlainTextEdit> +#include <QPushButton> +#include <QSpinBox> +#include <QUiLoader> +#include <QVBoxLayout> + +#define FROM_UI(type, name) \ + ; \ + ui_##name = findChild<type *>(#name); + +EditServerDialog::EditServerDialog(int index) : + index(index) // lol +{ + QUiLoader l_loader(this); + QFile l_uiFile(Options::getInstance().getUIAsset(DEFAULT_UI)); + + if (!l_uiFile.open(QFile::ReadOnly)) { + qCritical() << "Unable to open file " << l_uiFile.fileName(); + return; + } + ui_widget = l_loader.load(&l_uiFile, this); + + auto l_layout = new QVBoxLayout(this); + l_layout->addWidget(ui_widget); + + FROM_UI(QLineEdit, server_display_name_edit); + FROM_UI(QLineEdit, server_hostname_edit); + FROM_UI(QSpinBox, server_port_box); + FROM_UI(QComboBox, server_protocol_box); + FROM_UI(QPlainTextEdit, server_description_edit); + FROM_UI(QDialogButtonBox, server_dialog_button); + connect(ui_server_dialog_button, &QDialogButtonBox::accepted, this, + &::EditServerDialog::onSavePressed); + connect(ui_server_dialog_button, &QDialogButtonBox::rejected, this, + &EditServerDialog::onCancelPressed); + + // We don't need you. + FROM_UI(QLabel, server_legacy_lbl); + FROM_UI(QLineEdit, server_legacy_edit); + FROM_UI(QPushButton, server_legacy_load_button); + + ui_server_legacy_lbl->setVisible(false); + ui_server_legacy_edit->setVisible(false); + ui_server_legacy_load_button->setVisible(false); + + loadEntry(); +} + +void EditServerDialog::loadEntry() +{ + server_type server = Options::getInstance().favorites().at(index); + ui_server_display_name_edit->setText(server.name); + ui_server_hostname_edit->setText(server.ip); + ui_server_port_box->setValue(server.port); + ui_server_description_edit->setPlainText(server.desc); + ui_server_protocol_box->setCurrentIndex(server.socket_type); +} + +void EditServerDialog::onSavePressed() +{ + server_type server; + server.name = ui_server_display_name_edit->text(); + server.ip = ui_server_hostname_edit->text(); + server.port = ui_server_port_box->value(); + server.desc = ui_server_description_edit->toPlainText(); + server.socket_type = + ui_server_protocol_box->currentIndex() == TCP_INDEX ? TCP : WEBSOCKETS; + Options::getInstance().updateFavorite(server, index); + close(); + deleteLater(); +} + +void EditServerDialog::onCancelPressed() +{ + close(); + deleteLater(); +} |
