From 792a402782f979c2fe5747d30b8faffb054a4c26 Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Mon, 18 Jan 2021 20:05:13 +0100 Subject: Modify 'Install mod... ' in context menu to install above current mod. --- src/modlistcontextmenu.cpp | 5 ++++- src/modlistviewactions.cpp | 16 +++++++++++++--- src/modlistviewactions.h | 5 +++-- src/organizercore.cpp | 3 ++- src/organizercore.h | 2 +- src/organizerproxy.cpp | 2 +- 6 files changed, 24 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/modlistcontextmenu.cpp b/src/modlistcontextmenu.cpp index f4aea109..66516ed5 100644 --- a/src/modlistcontextmenu.cpp +++ b/src/modlistcontextmenu.cpp @@ -24,12 +24,14 @@ void ModListGlobalContextMenu::populate(OrganizerCore& core, ModListView* view, { clear(); - addAction(tr("Install Mod..."), [=]() { view->actions().installMod(); }); auto modIndex = index.data(ModList::IndexRole); if (modIndex.isValid() && view->sortColumn() == ModList::COL_PRIORITY) { auto info = ModInfo::getByIndex(modIndex.toInt()); if (!info->isBackup()) { + + addAction(tr("Install mod above..."), [=]() { view->actions().installMod("", index); }); + QString text = tr("Create empty mod above"); if (info->isSeparator()) { text = tr("Create empty mod inside"); @@ -42,6 +44,7 @@ void ModListGlobalContextMenu::populate(OrganizerCore& core, ModListView* view, } } else { + addAction(tr("Install mod..."), [=]() { view->actions().installMod(); }); addAction(tr("Create empty mod"), [=]() { view->actions().createEmptyMod(); }); addAction(tr("Create separator"), [=]() { view->actions().createSeparator(); }); } diff --git a/src/modlistviewactions.cpp b/src/modlistviewactions.cpp index 5af79b3b..fe0bfc38 100644 --- a/src/modlistviewactions.cpp +++ b/src/modlistviewactions.cpp @@ -50,8 +50,18 @@ ModListViewActions::ModListViewActions( } -void ModListViewActions::installMod(const QString& archivePath) const +void ModListViewActions::installMod(const QString& archivePath, const QModelIndex& index) const { + int newPriority = -1; + if (index.isValid() && m_view->sortColumn() == ModList::COL_PRIORITY) { + newPriority = m_core.currentProfile()->getModPriority(index.data(ModList::IndexRole).toInt()); + + // descending order, we need to fix the priority + if (m_view->sortOrder() == Qt::DescendingOrder) { + newPriority++; + } + } + try { QString path = archivePath; if (path.isEmpty()) { @@ -68,7 +78,7 @@ void ModListViewActions::installMod(const QString& archivePath) const return; } else { - m_core.installMod(path, false, nullptr, QString()); + m_core.installMod(path, newPriority, false, nullptr, QString()); } } catch (const std::exception& e) { @@ -864,7 +874,7 @@ void ModListViewActions::reinstallMod(const QModelIndex& index) const fullInstallationFile = m_core.downloadManager()->getOutputDirectory() + "/" + installationFile; } if (QFile::exists(fullInstallationFile)) { - m_core.installMod(fullInstallationFile, true, modInfo, modInfo->name()); + m_core.installMod(fullInstallationFile, -1, true, modInfo, modInfo->name()); } else { QMessageBox::information(m_parent, tr("Failed"), tr("Installation file no longer exists")); diff --git a/src/modlistviewactions.h b/src/modlistviewactions.h index 3c225fbc..069bb1e6 100644 --- a/src/modlistviewactions.h +++ b/src/modlistviewactions.h @@ -31,9 +31,10 @@ public: PluginListView* pluginView, QObject* nxmReceiver); - // install the mod from the given archive + // install the mod from the given archive before "above" the mod with + // the given index // - void installMod(const QString& archivePath = "") const; + void installMod(const QString& archivePath = "", const QModelIndex& index = QModelIndex()) const; // create an empty mod/a separator before the given mod or at // the end of the list if the index is invalid diff --git a/src/organizercore.cpp b/src/organizercore.cpp index e95aa565..8766ebb9 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -733,11 +733,12 @@ QString OrganizerCore::pluginDataPath() } MOBase::IModInterface *OrganizerCore::installMod(const QString & archivePath, + int priority, bool reinstallation, ModInfo::Ptr currentMod, const QString &initModName) { - return installArchive(archivePath, -1, reinstallation, currentMod, initModName).get(); + return installArchive(archivePath, reinstallation ? -1 : priority, reinstallation, currentMod, initModName).get(); } ModInfo::Ptr OrganizerCore::installDownload(int index, int priority) diff --git a/src/organizercore.h b/src/organizercore.h index 8add5542..72359a90 100644 --- a/src/organizercore.h +++ b/src/organizercore.h @@ -318,7 +318,7 @@ public: QVariant persistent(const QString &pluginName, const QString &key, const QVariant &def) const; void setPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync); static QString pluginDataPath(); - virtual MOBase::IModInterface *installMod(const QString &fileName, bool reinstallation, ModInfo::Ptr currentMod, const QString &initModName); + virtual MOBase::IModInterface *installMod(const QString &fileName, int priority, bool reinstallation, ModInfo::Ptr currentMod, const QString &initModName); QString resolvePath(const QString &fileName) const; QStringList listDirectories(const QString &directoryName) const; QStringList findFiles(const QString &path, const std::function &filter) const; diff --git a/src/organizerproxy.cpp b/src/organizerproxy.cpp index acfb8404..f9943623 100644 --- a/src/organizerproxy.cpp +++ b/src/organizerproxy.cpp @@ -228,7 +228,7 @@ void OrganizerProxy::refresh(bool saveChanges) IModInterface *OrganizerProxy::installMod(const QString &fileName, const QString &nameSuggestion) { - return m_Proxied->installMod(fileName, false, nullptr, nameSuggestion); + return m_Proxied->installMod(fileName, -1, false, nullptr, nameSuggestion); } QString OrganizerProxy::resolvePath(const QString &fileName) const -- cgit v1.3.1 From 5bc8256dc8a861451213288187c0eaf0713be494 Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Mon, 18 Jan 2021 20:23:41 +0100 Subject: Make installMod behave similarly to createEmptyMod for the new mod priority. --- src/modlistcontextmenu.cpp | 13 ++++--- src/modlistviewactions.cpp | 85 ++++++++++++++++++++++------------------------ src/modlistviewactions.h | 5 +++ 3 files changed, 54 insertions(+), 49 deletions(-) (limited to 'src') diff --git a/src/modlistcontextmenu.cpp b/src/modlistcontextmenu.cpp index 66516ed5..c7cbb033 100644 --- a/src/modlistcontextmenu.cpp +++ b/src/modlistcontextmenu.cpp @@ -30,16 +30,19 @@ void ModListGlobalContextMenu::populate(OrganizerCore& core, ModListView* view, auto info = ModInfo::getByIndex(modIndex.toInt()); if (!info->isBackup()) { - addAction(tr("Install mod above..."), [=]() { view->actions().installMod("", index); }); - QString text = tr("Create empty mod above"); + QString installText = tr("Install mod above... "); + QString createText = tr("Create empty mod above"); if (info->isSeparator()) { - text = tr("Create empty mod inside"); + installText = tr("Install mod inside... "); + createText = tr("Create empty mod inside"); } else if (view->sortOrder() == Qt::DescendingOrder) { - text = tr("Create empty mod below"); + installText = tr("Install mod below... "); + createText = tr("Create empty mod below"); } - addAction(text, [=]() { view->actions().createEmptyMod(index); }); + addAction(installText, [=]() { view->actions().installMod("", index); }); + addAction(createText, [=]() { view->actions().createEmptyMod(index); }); addAction(tr("Create separator above"), [=]() { view->actions().createSeparator(index); }); } } diff --git a/src/modlistviewactions.cpp b/src/modlistviewactions.cpp index fe0bfc38..0042d9c0 100644 --- a/src/modlistviewactions.cpp +++ b/src/modlistviewactions.cpp @@ -50,18 +50,51 @@ ModListViewActions::ModListViewActions( } -void ModListViewActions::installMod(const QString& archivePath, const QModelIndex& index) const +int ModListViewActions::findInstallPriority(const QModelIndex& index) const { int newPriority = -1; - if (index.isValid() && m_view->sortColumn() == ModList::COL_PRIORITY) { - newPriority = m_core.currentProfile()->getModPriority(index.data(ModList::IndexRole).toInt()); + if (index.isValid() && index.data(ModList::IndexRole).isValid() + && m_view->sortColumn() == ModList::COL_PRIORITY) { + auto mIndex = index.data(ModList::IndexRole).toInt(); + auto info = ModInfo::getByIndex(mIndex); + newPriority = m_core.currentProfile()->getModPriority(mIndex); + if (info->isSeparator()) { - // descending order, we need to fix the priority - if (m_view->sortOrder() == Qt::DescendingOrder) { - newPriority++; + auto isSeparator = [](const auto& p) { + return ModInfo::getByIndex(p.second)->isSeparator(); + }; + + auto& ibp = m_core.currentProfile()->getAllIndexesByPriority(); + + // start right after/before the current priority and look for the next + // separator + if (m_view->sortOrder() == Qt::AscendingOrder) { + auto it = std::find_if(ibp.find(newPriority + 1), ibp.end(), isSeparator); + if (it != ibp.end()) { + newPriority = it->first; + } + else { + newPriority = -1; + } + } + else { + auto it = std::find_if(std::reverse_iterator{ ibp.find(newPriority - 1) }, ibp.rend(), isSeparator); + if (it != ibp.rend()) { + newPriority = it->first + 1; + } + else { + // create "before" priority 0, i.e. at the end in descending priority. + newPriority = 0; + } + } } } + return newPriority; +} + +void ModListViewActions::installMod(const QString& archivePath, const QModelIndex& index) const +{ try { QString path = archivePath; if (path.isEmpty()) { @@ -78,7 +111,7 @@ void ModListViewActions::installMod(const QString& archivePath, const QModelInde return; } else { - m_core.installMod(path, newPriority, false, nullptr, QString()); + m_core.installMod(path, findInstallPriority(index), false, nullptr, QString()); } } catch (const std::exception& e) { @@ -107,43 +140,6 @@ void ModListViewActions::createEmptyMod(const QModelIndex& index) const return; } - int newPriority = -1; - if (index.isValid() && index.data(ModList::IndexRole).isValid() - && m_view->sortColumn() == ModList::COL_PRIORITY) { - auto mIndex = index.data(ModList::IndexRole).toInt(); - auto info = ModInfo::getByIndex(mIndex); - newPriority = m_core.currentProfile()->getModPriority(mIndex); - if (info->isSeparator()) { - - auto isSeparator = [](const auto& p) { - return ModInfo::getByIndex(p.second)->isSeparator(); - }; - - auto& ibp = m_core.currentProfile()->getAllIndexesByPriority(); - - // start right after/before the current priority and look for the next - // separator - if (m_view->sortOrder() == Qt::AscendingOrder) { - auto it = std::find_if(ibp.find(newPriority + 1), ibp.end(), isSeparator); - if (it != ibp.end()) { - newPriority = it->first; - } - else { - newPriority = -1; - } - } - else { - auto it = std::find_if(std::reverse_iterator{ ibp.find(newPriority - 1) }, ibp.rend(), isSeparator); - if (it != ibp.rend()) { - newPriority = it->first + 1; - } - else { - // create "before" priority 0, i.e. at the end in descending priority. - newPriority = 0; - } - } - } - } if (m_core.createMod(name) == nullptr) { return; @@ -151,6 +147,7 @@ void ModListViewActions::createEmptyMod(const QModelIndex& index) const m_core.refresh(); + const int newPriority = findInstallPriority(index); const auto mIndex = ModInfo::getIndex(name); if (newPriority >= 0) { m_core.modList()->changeModPriority(mIndex, newPriority); diff --git a/src/modlistviewactions.h b/src/modlistviewactions.h index 069bb1e6..429c37b6 100644 --- a/src/modlistviewactions.h +++ b/src/modlistviewactions.h @@ -134,6 +134,11 @@ signals: private: + // find the priority where to install or create a mod for the + // given index (e.g. above, below, inside separator or at the end) + // + int findInstallPriority(const QModelIndex& current) const; + // move the contents of the overwrite to the given path // void moveOverwriteContentsTo(const QString& absolutePath) const; -- cgit v1.3.1 From c3f73fe8edb3edce863967093b8b91e2002e33b8 Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Mon, 18 Jan 2021 20:25:02 +0100 Subject: Comment and remove extra blank lines. --- src/modlistcontextmenu.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/modlistcontextmenu.cpp b/src/modlistcontextmenu.cpp index c7cbb033..2d9577c5 100644 --- a/src/modlistcontextmenu.cpp +++ b/src/modlistcontextmenu.cpp @@ -24,13 +24,13 @@ void ModListGlobalContextMenu::populate(OrganizerCore& core, ModListView* view, { clear(); - auto modIndex = index.data(ModList::IndexRole); if (modIndex.isValid() && view->sortColumn() == ModList::COL_PRIORITY) { auto info = ModInfo::getByIndex(modIndex.toInt()); if (!info->isBackup()) { - + // the mod are not created/installed at the same position depending + // on the clicked mod and the sort order QString installText = tr("Install mod above... "); QString createText = tr("Create empty mod above"); if (info->isSeparator()) { @@ -41,6 +41,7 @@ void ModListGlobalContextMenu::populate(OrganizerCore& core, ModListView* view, installText = tr("Install mod below... "); createText = tr("Create empty mod below"); } + addAction(installText, [=]() { view->actions().installMod("", index); }); addAction(createText, [=]() { view->actions().createEmptyMod(index); }); addAction(tr("Create separator above"), [=]() { view->actions().createSeparator(index); }); -- cgit v1.3.1 From 3c0201a79909a878e6ae572b28bc7fc9588ff1c2 Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Mon, 18 Jan 2021 20:43:27 +0100 Subject: Update documentation for installMod / createEmptyMod. --- src/modlistviewactions.h | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/modlistviewactions.h b/src/modlistviewactions.h index 429c37b6..fef88375 100644 --- a/src/modlistviewactions.h +++ b/src/modlistviewactions.h @@ -31,14 +31,20 @@ public: PluginListView* pluginView, QObject* nxmReceiver); - // install the mod from the given archive before "above" the mod with - // the given index + // install mod, create an empty mod or a separator with at priority based on the + // index and the current sorting of the view + // - if the list is not sorted by priority or the index is invalid, use the + // highest priority + // - otherwise + // - create separators above the given index (the priority is not the + // same depending on the current sorting) + // - create/install mods above or below other mods depending on the sort order, or + // at the end of the separator if index corresponds to the separator + // + // if the archivePath is empty for installMod, ask the user for the archive + // to install // void installMod(const QString& archivePath = "", const QModelIndex& index = QModelIndex()) const; - - // create an empty mod/a separator before the given mod or at - // the end of the list if the index is invalid - // void createEmptyMod(const QModelIndex& index = QModelIndex()) const; void createSeparator(const QModelIndex& index = QModelIndex()) const; -- cgit v1.3.1