diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/mainwindow.cpp | 48 | ||||
| -rw-r--r-- | src/mainwindow.h | 4 | ||||
| -rw-r--r-- | src/modlistcontextmenu.cpp | 37 | ||||
| -rw-r--r-- | src/modlistcontextmenu.h | 2 | ||||
| -rw-r--r-- | src/modlistviewactions.cpp | 171 | ||||
| -rw-r--r-- | src/modlistviewactions.h | 11 |
6 files changed, 216 insertions, 57 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 056eeef7..6942f83b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2365,32 +2365,6 @@ void MainWindow::renameMod_clicked() } } - -void MainWindow::restoreBackup_clicked(int modIndex) -{ - QRegExp backupRegEx("(.*)_backup[0-9]*$"); - ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex); - if (backupRegEx.indexIn(modInfo->name()) != -1) { - QString regName = backupRegEx.cap(1); - QDir modDir(QDir::fromNativeSeparators(m_OrganizerCore.settings().paths().mods())); - if (!modDir.exists(regName) || - (QMessageBox::question(this, tr("Overwrite?"), - tr("This will replace the existing mod \"%1\". Continue?").arg(regName), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)) { - if (modDir.exists(regName) && !shellDelete(QStringList(modDir.absoluteFilePath(regName)))) { - reportError(tr("failed to remove mod \"%1\"").arg(regName)); - } else { - QString destinationPath = QDir::fromNativeSeparators(m_OrganizerCore.settings().paths().mods()) + "/" + regName; - if (!modDir.rename(modInfo->absolutePath(), destinationPath)) { - reportError(tr("failed to rename \"%1\" to \"%2\"").arg(modInfo->absolutePath()).arg(destinationPath)); - } - m_OrganizerCore.refresh(); - ui->modList->updateModCount(); - } - } - } -} - void MainWindow::modlistChanged(const QModelIndex&, int) { m_OrganizerCore.currentProfile()->writeModlist(); @@ -2850,7 +2824,7 @@ void MainWindow::visitOnNexus_clicked(int modIndex) void MainWindow::visitWebPage_clicked(int index) { - QItemSelectionModel *selection = ui->modList->selectionModel(); + QItemSelectionModel* selection = ui->modList->selectionModel(); if (selection->hasSelection() && selection->selectedRows().count() > 1) { int count = selection->selectedRows().count(); if (count > 10) { @@ -3740,26 +3714,6 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos) // context menu for mod backups else if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) != flags.end()) { - menu.addAction(tr("Restore Backup"), [=]() { restoreBackup_clicked(modIndex); }); - menu.addAction(tr("Remove Backup..."), [=]() { removeMod_clicked(modIndex); }); - menu.addSeparator(); - if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_INVALID) != flags.end()) { - menu.addAction(tr("Ignore missing data"), [=]() { ignoreMissingData_clicked(modIndex); }); - } - if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_ALTERNATE_GAME) != flags.end()) { - menu.addAction(tr("Mark as converted/working"), [=]() { markConverted_clicked(modIndex); }); - } - menu.addSeparator(); - if (info->nexusId() > 0) { - menu.addAction(tr("Visit on Nexus"), [=]() { visitOnNexus_clicked(modIndex); }); - } - - const auto url = info->parseCustomURL(); - if (url.isValid()) { - menu.addAction(tr("Visit on %1").arg(url.host()), [=]() { visitWebPage_clicked(modIndex); }); - } - - menu.addAction(tr("Open in Explorer"), [=]() { ui->modList->actions().openExplorer({ contextIdx }); }); } // separator diff --git a/src/mainwindow.h b/src/mainwindow.h index 21c8f2aa..49ecee32 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -151,6 +151,8 @@ public slots: void directory_refreshed(); + void updatePluginCount(); + signals: /** @@ -347,7 +349,6 @@ private slots: // modlist context menu void installMod_clicked(); - void restoreBackup_clicked(int modIndex); void renameMod_clicked(); void removeMod_clicked(int modIndex); void setColor_clicked(int modIndex); @@ -498,7 +499,6 @@ private slots: void esplistSelectionsChanged(const QItemSelection ¤t); void resetActionIcons(); - void updatePluginCount(); private slots: // ui slots // actions diff --git a/src/modlistcontextmenu.cpp b/src/modlistcontextmenu.cpp index dda88735..df80f0d9 100644 --- a/src/modlistcontextmenu.cpp +++ b/src/modlistcontextmenu.cpp @@ -46,6 +46,7 @@ ModListContextMenu::ModListContextMenu(OrganizerCore& core, const QModelIndex& i , m_core(core) , m_index(index) , m_view(view) + , m_actions(view->actions()) { if (view->selectionModel()->hasSelection()) { m_selected = view->indexViewToModel(view->selectionModel()->selectedRows()); @@ -99,10 +100,10 @@ QMenu* ModListContextMenu::createSendToContextMenu() { QMenu* menu = new QMenu(m_view); menu->setTitle(tr("Send to... ")); - menu->addAction(tr("Top"), [=]() { m_view->actions().sendModsToTop(m_selected); }); - menu->addAction(tr("Bottom"), [=]() { m_view->actions().sendModsToBottom(m_selected); }); - menu->addAction(tr("Priority..."), [=]() { m_view->actions().sendModsToPriority(m_selected); }); - menu->addAction(tr("Separator..."), [=]() { m_view->actions().sendModsToSeparator(m_selected); }); + menu->addAction(tr("Top"), [=]() { m_actions.sendModsToTop(m_selected); }); + menu->addAction(tr("Bottom"), [=]() { m_actions.sendModsToBottom(m_selected); }); + menu->addAction(tr("Priority..."), [=]() { m_actions.sendModsToPriority(m_selected); }); + menu->addAction(tr("Separator..."), [=]() { m_actions.sendModsToSeparator(m_selected); }); return menu; } @@ -110,11 +111,11 @@ void ModListContextMenu::addOverwriteActions(ModInfo::Ptr mod) { if (QDir(mod->absolutePath()).count() > 2) { addAction(tr("Sync to Mods..."), [=]() { m_core.syncOverwrite(); }); - addAction(tr("Create Mod..."), [=]() { m_view->actions().createModFromOverwrite(); }); - addAction(tr("Move content to Mod..."), [=]() { m_view->actions().moveOverwriteContentToExistingMod(); }); - addAction(tr("Clear Overwrite..."), [=]() { m_view->actions().clearOverwrite(); }); + addAction(tr("Create Mod..."), [=]() { m_actions.createModFromOverwrite(); }); + addAction(tr("Move content to Mod..."), [=]() { m_actions.moveOverwriteContentToExistingMod(); }); + addAction(tr("Clear Overwrite..."), [=]() { m_actions.clearOverwrite(); }); } - addAction(tr("Open in Explorer"), [=]() { m_view->actions().openExplorer(m_selected); }); + addAction(tr("Open in Explorer"), [=]() { m_actions.openExplorer(m_selected); }); } void ModListContextMenu::addSeparatorActions(ModInfo::Ptr mod) @@ -131,7 +132,27 @@ void ModListContextMenu::addForeignActions(ModInfo::Ptr mod) void ModListContextMenu::addBackupActions(ModInfo::Ptr mod) { + auto flags = mod->getFlags(); + addAction(tr("Restore Backup"), [=]() { m_actions.restoreBackup(m_index); }); + addAction(tr("Remove Backup..."), [=]() { m_actions.removeMods(m_selected); }); + addSeparator(); + if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_INVALID) != flags.end()) { + addAction(tr("Ignore missing data"), [=]() { m_actions.ignoreMissingData(m_selected); }); + } + if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_ALTERNATE_GAME) != flags.end()) { + addAction(tr("Mark as converted/working"), [=]() { m_actions.markConverted(m_selected); }); + } + addSeparator(); + if (mod->nexusId() > 0) { + addAction(tr("Visit on Nexus"), [=]() { m_actions.visitOnNexus(m_selected); }); + } + + const auto url = mod->parseCustomURL(); + if (url.isValid()) { + addAction(tr("Visit on %1").arg(url.host()), [=]() { m_actions.visitWebPage(m_selected); }); + } + addAction(tr("Open in Explorer"), [=]() { m_actions.openExplorer(m_selected); }); } void ModListContextMenu::addRegularActions(ModInfo::Ptr mod) diff --git a/src/modlistcontextmenu.h b/src/modlistcontextmenu.h index 22318575..05e6b601 100644 --- a/src/modlistcontextmenu.h +++ b/src/modlistcontextmenu.h @@ -10,6 +10,7 @@ #include "modinfo.h" class ModListView; +class ModListViewActions; class OrganizerCore; class ModListGlobalContextMenu : public QMenu @@ -49,6 +50,7 @@ public: // TODO: Move this to private when all is done QModelIndex m_index; QModelIndexList m_selected; ModListView* m_view; + ModListViewActions& m_actions; // shortcut for m_view->actions() }; diff --git a/src/modlistviewactions.cpp b/src/modlistviewactions.cpp index a07fb27c..53c29a5d 100644 --- a/src/modlistviewactions.cpp +++ b/src/modlistviewactions.cpp @@ -4,6 +4,7 @@ #include <QGroupBox> #include <QInputDialog> #include <QLabel> +#include <QRegExp> #include <log.h> #include <report.h> @@ -505,6 +506,150 @@ void ModListViewActions::sendModsToSeparator(const QModelIndexList& index) const } } +void ModListViewActions::removeMods(const QModelIndexList& indices) const +{ + const int max_items = 20; + + try { + if (indices.size() > 1) { + QString mods; + QStringList modNames; + + int i = 0; + for (auto& idx : indices) { + QString name = idx.data().toString(); + if (!ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt())->isRegular()) { + continue; + } + + // adds an item for the mod name until `i` reaches `max_items`, which + // adds one "..." item; subsequent mods are not shown on the list but + // are still added to `modNames` below so they can be removed correctly + + if (i < max_items) { + mods += "<li>" + name + "</li>"; + } + else if (i == max_items) { + mods += "<li>...</li>"; + } + + modNames.append(ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt())->name()); + ++i; + } + if (QMessageBox::question(m_view, tr("Confirm"), + tr("Remove the following mods?<br><ul>%1</ul>").arg(mods), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + // use mod names instead of indexes because those become invalid during the removal + DownloadManager::startDisableDirWatcher(); + for (QString name : modNames) { + m_core.modList()->removeRowForce(ModInfo::getIndex(name), QModelIndex()); + } + DownloadManager::endDisableDirWatcher(); + } + } + else if (!indices.isEmpty()) { + m_core.modList()->removeRow(indices[0].data(ModList::IndexRole).toInt(), QModelIndex()); + } + m_view->updateModCount(); + m_main->updatePluginCount(); + } + catch (const std::exception& e) { + reportError(tr("failed to remove mod: %1").arg(e.what())); + } +} + +void ModListViewActions::ignoreMissingData(const QModelIndexList& indices) const +{ + for (auto& idx : indices) { + int row_idx = idx.data(ModList::IndexRole).toInt(); + ModInfo::Ptr info = ModInfo::getByIndex(row_idx); + info->markValidated(true); + m_core.modList()->notifyChange(row_idx); + } +} + +void ModListViewActions::markConverted(const QModelIndexList& indices) const +{ + for (auto& idx : indices) { + int row_idx = idx.data(ModList::IndexRole).toInt(); + ModInfo::Ptr info = ModInfo::getByIndex(row_idx); + info->markConverted(true); + m_core.modList()->notifyChange(row_idx); + } +} + +void ModListViewActions::visitOnNexus(const QModelIndexList& indices) const +{ + if (indices.size() > 1) { + if (indices.size() > 10) { + if (QMessageBox::question(m_view, tr("Opening Nexus Links"), + tr("You are trying to open %1 links to Nexus Mods. Are you sure you want to do this?").arg(indices.size()), + QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) { + return; + } + } + int row_idx; + ModInfo::Ptr info; + QString gameName; + + for (auto& idx : indices) { + row_idx = idx.data(ModList::IndexRole).toInt(); + info = ModInfo::getByIndex(row_idx); + int modID = info->nexusId(); + gameName = info->gameName(); + if (modID > 0) { + shell::Open(QUrl(NexusInterface::instance().getModURL(modID, gameName))); + } + else { + log::error("mod '{}' has no nexus id", info->name()); + } + } + } + else if (!indices.isEmpty()) { + int modID = indices[0].data(Qt::UserRole).toInt(); + QString gameName = indices[0].data(Qt::UserRole + 4).toString(); + if (modID > 0) { + shell::Open(QUrl(NexusInterface::instance().getModURL(modID, gameName))); + } + else { + MessageDialog::showMessage(tr("Nexus ID for this mod is unknown"), m_view); + } + } +} + +void ModListViewActions::visitWebPage(const QModelIndexList& indices) const +{ + if (indices.size() > 1) { + if (indices.size() > 10) { + if (QMessageBox::question(m_view, tr("Opening Web Pages"), + tr("You are trying to open %1 Web Pages. Are you sure you want to do this?").arg(indices.size()), + QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) { + return; + } + } + int row_idx; + ModInfo::Ptr info; + QString gameName; + for (auto& idx : indices) { + row_idx = idx.data(ModList::IndexRole).toInt(); + info = ModInfo::getByIndex(row_idx); + + const auto url = info->parseCustomURL(); + if (url.isValid()) { + shell::Open(url); + } + } + } + else if (!indices.isEmpty()) { + ModInfo::Ptr info = ModInfo::getByIndex(indices[0].data(ModList::IndexRole).toInt()); + + const auto url = info->parseCustomURL(); + if (url.isValid()) { + shell::Open(url); + } + } +} + void ModListViewActions::openExplorer(const QModelIndexList& index) const { for (auto& idx : index) { @@ -513,6 +658,32 @@ void ModListViewActions::openExplorer(const QModelIndexList& index) const } } +void ModListViewActions::restoreBackup(const QModelIndex& index) const +{ + QRegExp backupRegEx("(.*)_backup[0-9]*$"); + ModInfo::Ptr modInfo = ModInfo::getByIndex(index.data(ModList::IndexRole).toInt()); + if (backupRegEx.indexIn(modInfo->name()) != -1) { + QString regName = backupRegEx.cap(1); + QDir modDir(QDir::fromNativeSeparators(m_core.settings().paths().mods())); + if (!modDir.exists(regName) || + (QMessageBox::question(m_view, tr("Overwrite?"), + tr("This will replace the existing mod \"%1\". Continue?").arg(regName), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)) { + if (modDir.exists(regName) && !shellDelete(QStringList(modDir.absoluteFilePath(regName)))) { + reportError(tr("failed to remove mod \"%1\"").arg(regName)); + } + else { + QString destinationPath = QDir::fromNativeSeparators(m_core.settings().paths().mods()) + "/" + regName; + if (!modDir.rename(modInfo->absolutePath(), destinationPath)) { + reportError(tr("failed to rename \"%1\" to \"%2\"").arg(modInfo->absolutePath()).arg(destinationPath)); + } + m_core.refresh(); + m_view->updateModCount(); + } + } + } +} + void ModListViewActions::moveOverwriteContentsTo(const QString& absolutePath) const { ModInfo::Ptr overwriteInfo = ModInfo::getOverwrite(); diff --git a/src/modlistviewactions.h b/src/modlistviewactions.h index 10aa6c39..05994813 100644 --- a/src/modlistviewactions.h +++ b/src/modlistviewactions.h @@ -60,10 +60,21 @@ public: void sendModsToPriority(const QModelIndexList& index) const; void sendModsToSeparator(const QModelIndexList& index) const; + // actions for most type of mods + void removeMods(const QModelIndexList& indices) const; + void ignoreMissingData(const QModelIndexList& indices) const; + void markConverted(const QModelIndexList& indices) const; + void visitOnNexus(const QModelIndexList& indices) const; + void visitWebPage(const QModelIndexList& indices) const; + // open the Windows explorer for the specified mods // void openExplorer(const QModelIndexList& index) const; + // backup-specific actions + // + void restoreBackup(const QModelIndex& index) const; + // overwrite-specific actions // void createModFromOverwrite() const; |
