diff options
Diffstat (limited to 'launcher/ui')
23 files changed, 610 insertions, 132 deletions
diff --git a/launcher/ui/MainWindow.cpp b/launcher/ui/MainWindow.cpp index 7140831b..9375039b 100644 --- a/launcher/ui/MainWindow.cpp +++ b/launcher/ui/MainWindow.cpp @@ -266,6 +266,8 @@ public: TranslatedAction actionNoAccountsAdded; TranslatedAction actionNoDefaultAccount; + TranslatedAction actionLockToolbars; + QVector<TranslatedToolButton *> all_toolbuttons; QWidget *centralWidget = nullptr; @@ -432,6 +434,12 @@ public: actionManageAccounts->setCheckable(false); actionManageAccounts->setIcon(APPLICATION->getThemedIcon("accounts")); all_actions.append(&actionManageAccounts); + + actionLockToolbars = TranslatedAction(MainWindow); + actionLockToolbars->setObjectName(QStringLiteral("actionLockToolbars")); + actionLockToolbars.setTextId(QT_TRANSLATE_NOOP("MainWindow", "Lock Toolbars")); + actionLockToolbars->setCheckable(true); + all_actions.append(&actionLockToolbars); } void createMainToolbar(QMainWindow *MainWindow) @@ -439,7 +447,6 @@ public: mainToolBar = TranslatedToolbar(MainWindow); mainToolBar->setVisible(menuBar->isNativeMenuBar() || !APPLICATION->settings()->get("MenuBarInsteadOfToolBar").toBool()); mainToolBar->setObjectName(QStringLiteral("mainToolBar")); - mainToolBar->setMovable(true); mainToolBar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea); mainToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); mainToolBar->setFloatable(false); @@ -540,6 +547,8 @@ public: viewMenu->addAction(actionCAT); viewMenu->addSeparator(); + viewMenu->addAction(actionLockToolbars); + menuBar->addMenu(foldersMenu); profileMenu = menuBar->addMenu(tr("&Accounts")); @@ -620,7 +629,6 @@ public: { newsToolBar = TranslatedToolbar(MainWindow); newsToolBar->setObjectName(QStringLiteral("newsToolBar")); - newsToolBar->setMovable(true); newsToolBar->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea); newsToolBar->setIconSize(QSize(16, 16)); newsToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); @@ -755,7 +763,6 @@ public: instanceToolBar->setObjectName(QStringLiteral("instanceToolBar")); // disabled until we have an instance selected instanceToolBar->setEnabled(false); - instanceToolBar->setMovable(true); // Qt doesn't like vertical moving toolbars, so we have to force them... // See https://github.com/PolyMC/PolyMC/issues/493 connect(instanceToolBar, &QToolBar::orientationChanged, [=](Qt::Orientation){ instanceToolBar->setOrientation(Qt::Vertical); }); @@ -937,6 +944,14 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new MainWindow connect(ui->actionCAT.operator->(), SIGNAL(toggled(bool)), SLOT(onCatToggled(bool))); setCatBackground(cat_enable); } + + // Lock toolbars + { + bool toolbarsLocked = APPLICATION->settings()->get("ToolbarsLocked").toBool(); + ui->actionLockToolbars->setChecked(toolbarsLocked); + connect(ui->actionLockToolbars, &QAction::toggled, this, &MainWindow::lockToolbars); + lockToolbars(toolbarsLocked); + } // start instance when double-clicked connect(view, &InstanceView::activated, this, &MainWindow::instanceActivated); @@ -1092,8 +1107,19 @@ QMenu * MainWindow::createPopupMenu() { QMenu* filteredMenu = QMainWindow::createPopupMenu(); filteredMenu->removeAction( ui->mainToolBar->toggleViewAction() ); + + filteredMenu->addAction(ui->actionLockToolbars); + return filteredMenu; } +void MainWindow::lockToolbars(bool state) +{ + ui->mainToolBar->setMovable(!state); + ui->instanceToolBar->setMovable(!state); + ui->newsToolBar->setMovable(!state); + APPLICATION->settings()->set("ToolbarsLocked", state); +} + void MainWindow::konamiTriggered() { @@ -1583,8 +1609,8 @@ void MainWindow::setCatBackground(bool enabled) QString cat = APPLICATION->settings()->get("BackgroundCat").toString(); if (non_stupid_abs(now.daysTo(xmas)) <= 4) { cat += "-xmas"; - } else if (cat == "kitteh" && non_stupid_abs(now.daysTo(halloween)) <= 4) { - cat += "-ween"; + } else if (non_stupid_abs(now.daysTo(halloween)) <= 4) { + cat += "-spooky"; } else if (non_stupid_abs(now.daysTo(birthday)) <= 12) { cat += "-bday"; } @@ -1644,7 +1670,7 @@ void MainWindow::on_actionCopyInstance_triggered() if (!copyInstDlg.exec()) return; - auto copyTask = new InstanceCopyTask(m_selectedInstance, copyInstDlg.shouldCopySaves(), copyInstDlg.shouldKeepPlaytime()); + auto copyTask = new InstanceCopyTask(m_selectedInstance, copyInstDlg.getChosenOptions()); copyTask->setName(copyInstDlg.instName()); copyTask->setGroup(copyInstDlg.instGroup()); copyTask->setIcon(copyInstDlg.iconKey()); @@ -1919,6 +1945,7 @@ void MainWindow::on_actionReportBug_triggered() void MainWindow::on_actionClearMetadata_triggered() { APPLICATION->metacache()->evictAll(); + APPLICATION->metacache()->SaveNow(); } #ifdef Q_OS_MAC diff --git a/launcher/ui/MainWindow.h b/launcher/ui/MainWindow.h index c9ab8bfb..6aeeccca 100644 --- a/launcher/ui/MainWindow.h +++ b/launcher/ui/MainWindow.h @@ -207,6 +207,8 @@ private slots: void globalSettingsClosed(); + void lockToolbars(bool); + #ifndef Q_OS_MAC void keyReleaseEvent(QKeyEvent *event) override; #endif diff --git a/launcher/ui/dialogs/BlockedModsDialog.cpp b/launcher/ui/dialogs/BlockedModsDialog.cpp index fe87b517..2cf94250 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.cpp +++ b/launcher/ui/dialogs/BlockedModsDialog.cpp @@ -1,28 +1,186 @@ #include "BlockedModsDialog.h" -#include "ui_BlockedModsDialog.h" -#include <QPushButton> -#include <QDialogButtonBox> #include <QDesktopServices> +#include <QDialogButtonBox> +#include <QPushButton> +#include "Application.h" +#include "ui_BlockedModsDialog.h" +#include <QDebug> +#include <QStandardPaths> -BlockedModsDialog::BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, const QString &body, const QList<QUrl> &urls) : - QDialog(parent), ui(new Ui::BlockedModsDialog), urls(urls) { +BlockedModsDialog::BlockedModsDialog(QWidget* parent, const QString& title, const QString& text, QList<BlockedMod>& mods) + : QDialog(parent), ui(new Ui::BlockedModsDialog), mods(mods) +{ ui->setupUi(this); auto openAllButton = ui->buttonBox->addButton(tr("Open All"), QDialogButtonBox::ActionRole); connect(openAllButton, &QPushButton::clicked, this, &BlockedModsDialog::openAll); + connect(&watcher, &QFileSystemWatcher::directoryChanged, this, &BlockedModsDialog::directoryChanged); + + hashing_task = shared_qobject_ptr<ConcurrentTask>(new ConcurrentTask(this, "MakeHashesTask", 10)); + + qDebug() << "Mods List: " << mods; + + setupWatch(); + scanPaths(); + this->setWindowTitle(title); ui->label->setText(text); - ui->textBrowser->setText(body); + ui->labelModsFound->setText(tr("Please download the missing mods.")); + update(); } -BlockedModsDialog::~BlockedModsDialog() { +BlockedModsDialog::~BlockedModsDialog() +{ delete ui; } -void BlockedModsDialog::openAll() { - for(auto &url : urls) { - QDesktopServices::openUrl(url); +void BlockedModsDialog::openAll() +{ + for (auto& mod : mods) { + QDesktopServices::openUrl(mod.websiteUrl); + } +} + +/// @brief update UI with current status of the blocked mod detection +void BlockedModsDialog::update() +{ + QString text; + QString span; + + for (auto& mod : mods) { + if (mod.matched) { + // ✔ -> html for HEAVY CHECK MARK : ✔ + span = QString(tr("<span style=\"color:green\"> ✔ Found at %1 </span>")).arg(mod.localPath); + } else { + // ✘ -> html for HEAVY BALLOT X : ✘ + span = QString(tr("<span style=\"color:red\"> ✘ Not Found </span>")); + } + text += QString(tr("%1: <a href='%2'>%2</a> <p>Hash: %3 %4</p> <br/>")).arg(mod.name, mod.websiteUrl, mod.hash, span); } + + ui->textBrowser->setText(text); + + if (allModsMatched()) { + ui->labelModsFound->setText(tr("All mods found ✔")); + } else { + ui->labelModsFound->setText(tr("Please download the missing mods.")); + } +} + +/// @brief Signal fired when a watched direcotry has changed +/// @param path the path to the changed directory +void BlockedModsDialog::directoryChanged(QString path) +{ + qDebug() << "Directory changed: " << path; + scanPath(path); +} + +/// @brief add the user downloads folder and the global mods folder to the filesystem watcher +void BlockedModsDialog::setupWatch() +{ + const QString downloadsFolder = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); + const QString modsFolder = APPLICATION->settings()->get("CentralModsDir").toString(); + watcher.addPath(downloadsFolder); + watcher.addPath(modsFolder); +} + +/// @brief scan all watched folder +void BlockedModsDialog::scanPaths() +{ + for (auto& dir : watcher.directories()) { + scanPath(dir); + } +} + +/// @brief Scan the directory at path, skip paths that do not contain a file name +/// of a blocked mod we are looking for +/// @param path the directory to scan +void BlockedModsDialog::scanPath(QString path) +{ + QDir scan_dir(path); + QDirIterator scan_it(path, QDir::Filter::Files | QDir::Filter::Hidden, QDirIterator::NoIteratorFlags); + while (scan_it.hasNext()) { + QString file = scan_it.next(); + + if (!checkValidPath(file)) { + continue; + } + + auto hash_task = Hashing::createBlockedModHasher(file, ModPlatform::Provider::FLAME, "sha1"); + + qDebug() << "Creating Hash task for path: " << file; + + connect(hash_task.get(), &Task::succeeded, [this, hash_task, file] { checkMatchHash(hash_task->getResult(), file); }); + connect(hash_task.get(), &Task::failed, [file] { qDebug() << "Failed to hash path: " << file; }); + + hashing_task->addTask(hash_task); + } + + hashing_task->start(); +} + +/// @brief check if the computed hash for the provided path matches a blocked +/// mod we are looking for +/// @param hash the computed hash for the provided path +/// @param path the path to the local file being compared +void BlockedModsDialog::checkMatchHash(QString hash, QString path) +{ + bool match = false; + + qDebug() << "Checking for match on hash: " << hash << "| From path:" << path; + + for (auto& mod : mods) { + if (mod.matched) { + continue; + } + if (mod.hash.compare(hash, Qt::CaseInsensitive) == 0) { + mod.matched = true; + mod.localPath = path; + match = true; + + qDebug() << "Hash match found:" << mod.name << hash << "| From path:" << path; + + break; + } + } + + if (match) { + update(); + } +} + +/// @brief Check if the name of the file at path matches the name of a blocked mod we are searching for +/// @param path the path to check +/// @return boolean: did the path match the name of a blocked mod? +bool BlockedModsDialog::checkValidPath(QString path) +{ + QFileInfo file = QFileInfo(path); + QString filename = file.fileName(); + + for (auto& mod : mods) { + if (mod.name.compare(filename, Qt::CaseInsensitive) == 0) { + qDebug() << "Name match found:" << mod.name << "| From path:" << path; + return true; + } + } + + return false; +} + +bool BlockedModsDialog::allModsMatched() +{ + return std::all_of(mods.begin(), mods.end(), [](auto const& mod) { return mod.matched; }); +} + +/// qDebug print support for the BlockedMod struct +QDebug operator<<(QDebug debug, const BlockedMod& m) +{ + QDebugStateSaver saver(debug); + + debug.nospace() << "{ name: " << m.name << ", websiteUrl: " << m.websiteUrl << ", hash: " << m.hash << ", matched: " << m.matched + << ", localPath: " << m.localPath << "}"; + + return debug; } diff --git a/launcher/ui/dialogs/BlockedModsDialog.h b/launcher/ui/dialogs/BlockedModsDialog.h index 5f5bd61b..0a5c90db 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.h +++ b/launcher/ui/dialogs/BlockedModsDialog.h @@ -1,7 +1,23 @@ #pragma once #include <QDialog> +#include <QString> +#include <QList> +#include <QFileSystemWatcher> + +#include "modplatform/helpers/HashUtils.h" + +#include "tasks/ConcurrentTask.h" + +struct BlockedMod { + QString name; + QString websiteUrl; + QString hash; + bool matched; + QString localPath; + +}; QT_BEGIN_NAMESPACE namespace Ui { class BlockedModsDialog; } @@ -11,12 +27,27 @@ class BlockedModsDialog : public QDialog { Q_OBJECT public: - BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, const QString &body, const QList<QUrl> &urls); + BlockedModsDialog(QWidget *parent, const QString &title, const QString &text, QList<BlockedMod> &mods); ~BlockedModsDialog() override; + private: Ui::BlockedModsDialog *ui; - const QList<QUrl> &urls; + QList<BlockedMod> &mods; + QFileSystemWatcher watcher; + shared_qobject_ptr<ConcurrentTask> hashing_task; + void openAll(); + void update(); + void directoryChanged(QString path); + void setupWatch(); + void scanPaths(); + void scanPath(QString path); + void checkMatchHash(QString hash, QString path); + + bool checkValidPath(QString path); + bool allModsMatched(); }; + +QDebug operator<<(QDebug debug, const BlockedMod &m); diff --git a/launcher/ui/dialogs/BlockedModsDialog.ui b/launcher/ui/dialogs/BlockedModsDialog.ui index f4ae95b6..371549cf 100644 --- a/launcher/ui/dialogs/BlockedModsDialog.ui +++ b/launcher/ui/dialogs/BlockedModsDialog.ui @@ -13,8 +13,8 @@ <property name="windowTitle"> <string notr="true">BlockedModsDialog</string> </property> - <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> <widget class="QLabel" name="label"> <property name="text"> <string notr="true"/> @@ -24,17 +24,7 @@ </property> </widget> </item> - <item row="2" column="0"> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - <item row="1" column="0"> + <item> <widget class="QTextBrowser" name="textBrowser"> <property name="acceptRichText"> <bool>true</bool> @@ -44,6 +34,27 @@ </property> </widget> </item> + <item> + <layout class="QHBoxLayout" name="bottomBoxH"> + <item> + <widget class="QLabel" name="labelModsFound"> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </item> </layout> </widget> <resources/> diff --git a/launcher/ui/dialogs/CopyInstanceDialog.cpp b/launcher/ui/dialogs/CopyInstanceDialog.cpp index 9ec341bc..3f5122f6 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.cpp +++ b/launcher/ui/dialogs/CopyInstanceDialog.cpp @@ -44,7 +44,6 @@ #include "BaseVersion.h" #include "icons/IconList.h" -#include "tasks/Task.h" #include "BaseInstance.h" #include "InstanceList.h" @@ -78,8 +77,14 @@ CopyInstanceDialog::CopyInstanceDialog(InstancePtr original, QWidget *parent) } ui->groupBox->setCurrentIndex(index); ui->groupBox->lineEdit()->setPlaceholderText(tr("No group")); - ui->copySavesCheckbox->setChecked(m_copySaves); - ui->keepPlaytimeCheckbox->setChecked(m_keepPlaytime); + ui->copySavesCheckbox->setChecked(m_selectedOptions.isCopySavesEnabled()); + ui->keepPlaytimeCheckbox->setChecked(m_selectedOptions.isKeepPlaytimeEnabled()); + ui->copyGameOptionsCheckbox->setChecked(m_selectedOptions.isCopyGameOptionsEnabled()); + ui->copyResPacksCheckbox->setChecked(m_selectedOptions.isCopyResourcePacksEnabled()); + ui->copyShaderPacksCheckbox->setChecked(m_selectedOptions.isCopyShaderPacksEnabled()); + ui->copyServersCheckbox->setChecked(m_selectedOptions.isCopyServersEnabled()); + ui->copyModsCheckbox->setChecked(m_selectedOptions.isCopyModsEnabled()); + ui->copyScreenshotsCheckbox->setChecked(m_selectedOptions.isCopyScreenshotsEnabled()); } CopyInstanceDialog::~CopyInstanceDialog() @@ -117,6 +122,31 @@ QString CopyInstanceDialog::instGroup() const return ui->groupBox->currentText(); } +const InstanceCopyPrefs& CopyInstanceDialog::getChosenOptions() const +{ + return m_selectedOptions; +} + +void CopyInstanceDialog::checkAllCheckboxes(const bool& b) +{ + ui->keepPlaytimeCheckbox->setChecked(b); + ui->copySavesCheckbox->setChecked(b); + ui->copyGameOptionsCheckbox->setChecked(b); + ui->copyResPacksCheckbox->setChecked(b); + ui->copyShaderPacksCheckbox->setChecked(b); + ui->copyServersCheckbox->setChecked(b); + ui->copyModsCheckbox->setChecked(b); + ui->copyScreenshotsCheckbox->setChecked(b); +} + +// Check the "Select all" checkbox if all options are already selected: +void CopyInstanceDialog::updateSelectAllCheckbox() +{ + ui->selectAllCheckbox->blockSignals(true); + ui->selectAllCheckbox->setChecked(m_selectedOptions.allTrue()); + ui->selectAllCheckbox->blockSignals(false); +} + void CopyInstanceDialog::on_iconButton_clicked() { IconPickerDialog dlg(this); @@ -129,42 +159,64 @@ void CopyInstanceDialog::on_iconButton_clicked() } } + void CopyInstanceDialog::on_instNameTextBox_textChanged(const QString &arg1) { updateDialogState(); } -bool CopyInstanceDialog::shouldCopySaves() const +void CopyInstanceDialog::on_selectAllCheckbox_stateChanged(int state) { - return m_copySaves; + bool checked; + checked = (state == Qt::Checked); + checkAllCheckboxes(checked); } void CopyInstanceDialog::on_copySavesCheckbox_stateChanged(int state) { - if(state == Qt::Unchecked) - { - m_copySaves = false; - } - else if(state == Qt::Checked) - { - m_copySaves = true; - } + m_selectedOptions.enableCopySaves(state == Qt::Checked); + updateSelectAllCheckbox(); } -bool CopyInstanceDialog::shouldKeepPlaytime() const + +void CopyInstanceDialog::on_keepPlaytimeCheckbox_stateChanged(int state) { - return m_keepPlaytime; + m_selectedOptions.enableKeepPlaytime(state == Qt::Checked); + updateSelectAllCheckbox(); } +void CopyInstanceDialog::on_copyGameOptionsCheckbox_stateChanged(int state) +{ + m_selectedOptions.enableCopyGameOptions(state == Qt::Checked); + updateSelectAllCheckbox(); +} -void CopyInstanceDialog::on_keepPlaytimeCheckbox_stateChanged(int state) +void CopyInstanceDialog::on_copyResPacksCheckbox_stateChanged(int state) { - if(state == Qt::Unchecked) - { - m_keepPlaytime = false; - } - else if(state == Qt::Checked) - { - m_keepPlaytime = true; - } + m_selectedOptions.enableCopyResourcePacks(state == Qt::Checked); + updateSelectAllCheckbox(); +} + +void CopyInstanceDialog::on_copyShaderPacksCheckbox_stateChanged(int state) +{ + m_selectedOptions.enableCopyShaderPacks(state == Qt::Checked); + updateSelectAllCheckbox(); +} + +void CopyInstanceDialog::on_copyServersCheckbox_stateChanged(int state) +{ + m_selectedOptions.enableCopyServers(state == Qt::Checked); + updateSelectAllCheckbox(); +} + +void CopyInstanceDialog::on_copyModsCheckbox_stateChanged(int state) +{ + m_selectedOptions.enableCopyMods(state == Qt::Checked); + updateSelectAllCheckbox(); +} + +void CopyInstanceDialog::on_copyScreenshotsCheckbox_stateChanged(int state) +{ + m_selectedOptions.enableCopyScreenshots(state == Qt::Checked); + updateSelectAllCheckbox(); } diff --git a/launcher/ui/dialogs/CopyInstanceDialog.h b/launcher/ui/dialogs/CopyInstanceDialog.h index bf3cd920..884501d1 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.h +++ b/launcher/ui/dialogs/CopyInstanceDialog.h @@ -17,7 +17,7 @@ #include <QDialog> #include "BaseVersion.h" -#include <BaseInstance.h> +#include "InstanceCopyPrefs.h" class BaseInstance; @@ -39,20 +39,29 @@ public: QString instName() const; QString instGroup() const; QString iconKey() const; - bool shouldCopySaves() const; - bool shouldKeepPlaytime() const; + const InstanceCopyPrefs& getChosenOptions() const; private slots: void on_iconButton_clicked(); void on_instNameTextBox_textChanged(const QString &arg1); + // Checkboxes + void on_selectAllCheckbox_stateChanged(int state); void on_copySavesCheckbox_stateChanged(int state); void on_keepPlaytimeCheckbox_stateChanged(int state); + void on_copyGameOptionsCheckbox_stateChanged(int state); + void on_copyResPacksCheckbox_stateChanged(int state); + void on_copyShaderPacksCheckbox_stateChanged(int state); + void on_copyServersCheckbox_stateChanged(int state); + void on_copyModsCheckbox_stateChanged(int state); + void on_copyScreenshotsCheckbox_stateChanged(int state); private: + void checkAllCheckboxes(const bool& b); + void updateSelectAllCheckbox(); + /* data */ Ui::CopyInstanceDialog *ui; QString InstIconKey; InstancePtr m_original; - bool m_copySaves = true; - bool m_keepPlaytime = true; + InstanceCopyPrefs m_selectedOptions; }; diff --git a/launcher/ui/dialogs/CopyInstanceDialog.ui b/launcher/ui/dialogs/CopyInstanceDialog.ui index f4b191e2..b7828fe3 100644 --- a/launcher/ui/dialogs/CopyInstanceDialog.ui +++ b/launcher/ui/dialogs/CopyInstanceDialog.ui @@ -9,8 +9,8 @@ <rect> <x>0</x> <y>0</y> - <width>345</width> - <height>323</height> + <width>341</width> + <height>399</height> </rect> </property> <property name="windowTitle"> @@ -33,7 +33,7 @@ </property> <property name="sizeHint" stdset="0"> <size> - <width>40</width> + <width>60</width> <height>20</height> </size> </property> @@ -60,7 +60,7 @@ </property> <property name="sizeHint" stdset="0"> <size> - <width>40</width> + <width>60</width> <height>20</height> </size> </property> @@ -83,7 +83,10 @@ </widget> </item> <item> - <layout class="QGridLayout" name="gridLayout"> + <layout class="QGridLayout" name="groupDropdownLayout"> + <property name="verticalSpacing"> + <number>6</number> + </property> <item row="0" column="0"> <widget class="QLabel" name="labelVersion_3"> <property name="text"> @@ -110,18 +113,96 @@ </layout> </item> <item> - <widget class="QCheckBox" name="copySavesCheckbox"> - <property name="text"> - <string>Copy saves</string> - </property> - </widget> + <layout class="QHBoxLayout" name="selectAllButtonLayout"> + <item> + <widget class="QCheckBox" name="selectAllCheckbox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="layoutDirection"> + <enum>Qt::LeftToRight</enum> + </property> + <property name="text"> + <string>Select all</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> </item> <item> - <widget class="QCheckBox" name="keepPlaytimeCheckbox"> - <property name="text"> - <string>Keep play time</string> - </property> - </widget> + <layout class="QGridLayout" name="copyOptionsLayout"> + <item row="6" column="1"> + <widget class="QCheckBox" name="copyModsCheckbox"> + <property name="toolTip"> + <string>Disabling this will still keep the mod loader (ex: Fabric, Quilt, etc.) but erase the mods folder and their configs.</string> + </property> + <property name="text"> + <string>Copy mods</string> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QCheckBox" name="copyGameOptionsCheckbox"> + <property name="toolTip"> + <string>Copy the in-game options like FOV, max framerate, etc.</string> + </property> + <property name="text"> + <string>Copy game options</string> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QCheckBox" name="copySavesCheckbox"> + <property name="text"> + <string>Copy saves</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QCheckBox" name="copyShaderPacksCheckbox"> + <property name="text"> + <string>Copy shader packs</string> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QCheckBox" name="copyServersCheckbox"> + <property name="text"> + <string>Copy servers</string> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QCheckBox" name="copyResPacksCheckbox"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="text"> + <string>Copy resource packs</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QCheckBox" name="keepPlaytimeCheckbox"> + <property name="text"> + <string>Keep play time</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QCheckBox" name="copyScreenshotsCheckbox"> + <property name="text"> + <string>Copy screenshots</string> + </property> + </widget> + </item> + </layout> </item> <item> <widget class="QDialogButtonBox" name="buttonBox"> @@ -139,8 +220,6 @@ <tabstop>iconButton</tabstop> <tabstop>instNameTextBox</tabstop> <tabstop>groupBox</tabstop> - <tabstop>copySavesCheckbox</tabstop> - <tabstop>keepPlaytimeCheckbox</tabstop> </tabstops> <resources> <include location="../../graphics.qrc"/> @@ -153,8 +232,8 @@ <slot>accept()</slot> <hints> <hint type="sourcelabel"> - <x>248</x> - <y>254</y> + <x>254</x> + <y>316</y> </hint> <hint type="destinationlabel"> <x>157</x> @@ -169,8 +248,8 @@ <slot>reject()</slot> <hints> <hint type="sourcelabel"> - <x>316</x> - <y>260</y> + <x>322</x> + <y>316</y> </hint> <hint type="destinationlabel"> <x>286</x> diff --git a/launcher/ui/dialogs/ExportInstanceDialog.cpp b/launcher/ui/dialogs/Expo |
