diff --git a/CHANGELOG.md b/CHANGELOG.md index 1aa220717d..2097c4bbaa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -168,6 +168,7 @@ Feature #7546: Start the game on Fredas Feature #7554: Controller binding for tab for menu navigation Feature #7568: Uninterruptable scripted music + Feature #7606: Launcher: allow Shift-select in Archives tab Feature #7608: Make the missing dependencies warning when loading a savegame more helpful Feature #7618: Show the player character's health in the save details Feature #7625: Add some missing console error outputs diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 114221ce92..70ebe29625 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -3,7 +3,9 @@ #include #include +#include #include +#include #include #include @@ -162,8 +164,8 @@ Launcher::DataFilesPage::DataFilesPage(const Files::ConfigurationManager& cfg, C connect(ui.directoryUpButton, &QPushButton::released, this, [this]() { this->moveDirectory(-1); }); connect(ui.directoryDownButton, &QPushButton::released, this, [this]() { this->moveDirectory(1); }); connect(ui.directoryRemoveButton, &QPushButton::released, this, [this]() { this->removeDirectory(); }); - connect(ui.archiveUpButton, &QPushButton::released, this, [this]() { this->moveArchive(-1); }); - connect(ui.archiveDownButton, &QPushButton::released, this, [this]() { this->moveArchive(1); }); + connect(ui.archiveUpButton, &QPushButton::released, this, [this]() { this->moveArchives(-1); }); + connect(ui.archiveDownButton, &QPushButton::released, this, [this]() { this->moveArchives(1); }); connect( ui.directoryListWidget->model(), &QAbstractItemModel::rowsMoved, this, [this]() { this->sortDirectories(); }); @@ -218,6 +220,18 @@ void Launcher::DataFilesPage::buildView() &DataFilesPage::readNavMeshToolStderr); connect(mNavMeshToolInvoker->getProcess(), qOverload(&QProcess::finished), this, &DataFilesPage::navMeshToolFinished); + + buildArchiveContextMenu(); +} + +void Launcher::DataFilesPage::buildArchiveContextMenu() +{ + connect(ui.archiveListWidget, &QListWidget::customContextMenuRequested, this, + &DataFilesPage::slotShowArchiveContextMenu); + + mArchiveContextMenu = new QMenu(ui.archiveListWidget); + mArchiveContextMenu->addAction(tr("&Check Selected"), this, SLOT(slotCheckMultiSelectedItems())); + mArchiveContextMenu->addAction(tr("&Uncheck Selected"), this, SLOT(slotUncheckMultiSelectedItems())); } bool Launcher::DataFilesPage::loadSettings() @@ -707,17 +721,71 @@ void Launcher::DataFilesPage::removeDirectory() refreshDataFilesView(); } -void Launcher::DataFilesPage::moveArchive(int step) +void Launcher::DataFilesPage::slotShowArchiveContextMenu(const QPoint& pos) +{ + QPoint globalPos = ui.archiveListWidget->viewport()->mapToGlobal(pos); + mArchiveContextMenu->exec(globalPos); +} + +void Launcher::DataFilesPage::setCheckStateForMultiSelectedItems(bool checked) +{ + Qt::CheckState checkState = checked ? Qt::Checked : Qt::Unchecked; + + for (QListWidgetItem* selectedItem : ui.archiveListWidget->selectedItems()) + { + selectedItem->setCheckState(checkState); + } +} + +void Launcher::DataFilesPage::slotUncheckMultiSelectedItems() +{ + setCheckStateForMultiSelectedItems(false); +} + +void Launcher::DataFilesPage::slotCheckMultiSelectedItems() +{ + setCheckStateForMultiSelectedItems(true); +} + +void Launcher::DataFilesPage::moveArchives(int step) { - int selectedRow = ui.archiveListWidget->currentRow(); + QList selectedItems = ui.archiveListWidget->selectedItems(); + QList> sortedItems; + + for (QListWidgetItem* selectedItem : selectedItems) + { + int selectedRow = ui.archiveListWidget->row(selectedItem); + sortedItems.append(qMakePair(selectedRow, selectedItem)); + } + + if (step > 0) + { + std::sort(sortedItems.begin(), sortedItems.end(), [](auto a, auto b) { return a.first > b.first; }); + } + else + { + std::sort(sortedItems.begin(), sortedItems.end(), [](auto a, auto b) { return a.first < b.first; }); + } + + for (auto i : sortedItems) + { + if (!moveArchive(i.second, step)) + break; + } +} + +bool Launcher::DataFilesPage::moveArchive(QListWidgetItem* listItem, int step) +{ + int selectedRow = ui.archiveListWidget->row(listItem); int newRow = selectedRow + step; if (selectedRow == -1 || newRow < 0 || newRow > ui.archiveListWidget->count() - 1) - return; + return false; - const auto* item = ui.archiveListWidget->takeItem(selectedRow); + const QListWidgetItem* item = ui.archiveListWidget->takeItem(selectedRow); addArchive(item->text(), item->checkState(), newRow); ui.archiveListWidget->setCurrentRow(newRow); + return true; } void Launcher::DataFilesPage::addArchive(const QString& name, Qt::CheckState selected, int row) diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp index dc3aeaef6f..e568137e8f 100644 --- a/apps/launcher/datafilespage.hpp +++ b/apps/launcher/datafilespage.hpp @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -39,6 +40,7 @@ namespace Launcher ContentSelectorView::ContentSelector* mSelector; Ui::DataFilesPage ui; + QMenu* mArchiveContextMenu; public: explicit DataFilesPage(const Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings, @@ -72,9 +74,13 @@ namespace Launcher void addSubdirectories(bool append); void sortDirectories(); void removeDirectory(); - void moveArchive(int step); + void moveArchives(int step); void moveDirectory(int step); + void slotShowArchiveContextMenu(const QPoint& pos); + void slotCheckMultiSelectedItems(); + void slotUncheckMultiSelectedItems(); + void on_newProfileAction_triggered(); void on_cloneProfileAction_triggered(); void on_deleteProfileAction_triggered(); @@ -120,7 +126,10 @@ namespace Launcher void addArchive(const QString& name, Qt::CheckState selected, int row = -1); void addArchivesFromDir(const QString& dir); + bool moveArchive(QListWidgetItem* listItem, int step); void buildView(); + void buildArchiveContextMenu(); + void setCheckStateForMultiSelectedItems(bool checked); void setProfile(int index, bool savePrevious); void setProfile(const QString& previous, const QString& current, bool savePrevious); void removeProfile(const QString& profile); diff --git a/apps/launcher/ui/datafilespage.ui b/apps/launcher/ui/datafilespage.ui index 249207123e..2b54307838 100644 --- a/apps/launcher/ui/datafilespage.ui +++ b/apps/launcher/ui/datafilespage.ui @@ -7,7 +7,7 @@ 0 0 573 - 384 + 557 @@ -29,6 +29,12 @@ + + + 0 + 0 + + <html><head/><body><p>note: content files that are not part of current Content List are <span style=" font-style:italic;font-weight: bold">highlighted</span></p></body></html> @@ -41,14 +47,111 @@ Data Directories - + QAbstractItemView::InternalMove - + + + + + + + 0 + 33 + + + + Scan directories for likely data directories and append them at the end of the list. + + + Append + + + + + + + + 0 + 33 + + + + Scan directories for likely data directories and insert them above the selected position + + + Insert Above + + + + + + + + 0 + 33 + + + + Move selected directory one position up + + + Move Up + + + + + + + + 0 + 33 + + + + Move selected directory one position down + + + Move Down + + + + + + + + 0 + 33 + + + + Remove selected directory + + + Remove + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + @@ -61,116 +164,6 @@ - - - - - 0 - 33 - - - - - 0 - 33 - - - - Scan directories for likely data directories and append them at the end of the list. - - - Append - - - - - - - - 0 - 33 - - - - - 0 - 33 - - - - Scan directories for likely data directories and insert them above the selected position - - - Insert Above - - - - - - - - 0 - 33 - - - - - 0 - 33 - - - - Move selected directory one position up - - - Move Up - - - - - - - - 0 - 33 - - - - - 0 - 33 - - - - Move selected directory one position down - - - Move Down - - - - - - - - 0 - 33 - - - - - 0 - 33 - - - - Remove selected directory - - - Remove - - - @@ -178,64 +171,90 @@ Archive Files - + + + Qt::CustomContextMenu + QAbstractItemView::InternalMove - - - - - - - 0 - 33 - - - - - 0 - 33 - + + Qt::CopyAction - - Move selected archive one position up - - - Move Up + + QAbstractItemView::ExtendedSelection - + + + + + + + 0 + 33 + + + + + 0 + 33 + + + + Move selected archive one position up + + + Move Up + + + + + + + + 0 + 33 + + + + + 0 + 33 + + + + Move selected archive one position down + + + Move Down + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + <html><head/><body><p>note: archives that are not part of current Content List are <span style=" font-style:italic;font-weight: bold">highlighted</span></p></body></html> - - - - - 0 - 33 - - - - - 0 - 33 - - - - Move selected archive one position down - - - Move Down - - -