summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikaël Capelle <capelle.mikael@gmail.com>2020-12-31 00:55:49 +0100
committerMikaël Capelle <capelle.mikael@gmail.com>2021-01-02 15:38:17 +0100
commit4ee929b68a5ba3f622fd6cecf37f61b983eb0874 (patch)
tree1f535c794b3e3f0e6f1e50c5bae1ee32f993ab67
parent7f0c9b8d8278f14754b375967267ff67d6fdb6ee (diff)
Move the backup context menu.
-rw-r--r--src/mainwindow.cpp48
-rw-r--r--src/mainwindow.h4
-rw-r--r--src/modlistcontextmenu.cpp37
-rw-r--r--src/modlistcontextmenu.h2
-rw-r--r--src/modlistviewactions.cpp171
-rw-r--r--src/modlistviewactions.h11
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 &current);
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;