From 58b6e0eb48b4d4b201613f1062796a9af68fe454 Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Wed, 20 Jan 2021 18:16:20 +0100 Subject: Increase robustness of mods priority in profile. --- src/modlistview.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/modlistview.cpp') diff --git a/src/modlistview.cpp b/src/modlistview.cpp index 9597b48e..aa920905 100644 --- a/src/modlistview.cpp +++ b/src/modlistview.cpp @@ -647,16 +647,15 @@ void ModListView::onExternalFolderDropped(const QUrl& url, int priority) bool ModListView::moveSelection(int key) { - auto [cindex, sourceRows] = selected(); + auto rows = selectionModel()->selectedRows(); + const QPersistentModelIndex current(key == Qt::Key_Up ? rows.first() : rows.last()); int offset = key == Qt::Key_Up ? -1 : 1; if (m_sortProxy->sortOrder() == Qt::DescendingOrder) { offset = -offset; } - m_core->modList()->shiftModsPriority(sourceRows, offset); - - auto current = indexModelToView(key == Qt::Key_Up ? sourceRows.first() : sourceRows.last()); + m_core->modList()->shiftModsPriority(indexViewToModel(rows), offset); selectionModel()->setCurrentIndex(current, QItemSelectionModel::NoUpdate); scrollTo(current); -- cgit v1.3.1 From d94b7c444d02e070875026d8c037fbd9700d2ca8 Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Thu, 21 Jan 2021 21:56:26 +0100 Subject: Move update of directory structure after mod priority change to organizer core. --- src/modlistview.cpp | 36 ------------------------------------ src/organizercore.cpp | 45 +++++++++++++++++++++++++++++++++++++++++++-- src/organizercore.h | 1 + 3 files changed, 44 insertions(+), 38 deletions(-) (limited to 'src/modlistview.cpp') diff --git a/src/modlistview.cpp b/src/modlistview.cpp index aa920905..a6bb4982 100644 --- a/src/modlistview.cpp +++ b/src/modlistview.cpp @@ -434,42 +434,6 @@ void ModListView::onModPrioritiesChanged(const QModelIndexList& indices) } } - for (unsigned int i = 0; i < m_core->currentProfile()->numMods(); ++i) { - int priority = m_core->currentProfile()->getModPriority(i); - if (m_core->currentProfile()->modEnabled(i)) { - ModInfo::Ptr modInfo = ModInfo::getByIndex(i); - // priorities in the directory structure are one higher because data is 0 - m_core->directoryStructure()->getOriginByName(MOBase::ToWString(modInfo->internalName())).setPriority(priority + 1); - } - } - m_core->refreshBSAList(); - m_core->currentProfile()->writeModlist(); - m_core->directoryStructure()->getFileRegister()->sortOrigins(); - - for (auto& idx : indices) { - ModInfo::Ptr modInfo = ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt()); - // clear caches on all mods conflicting with the moved mod - for (int i : modInfo->getModOverwrite()) { - ModInfo::getByIndex(i)->clearCaches(); - } - for (int i : modInfo->getModOverwritten()) { - ModInfo::getByIndex(i)->clearCaches(); - } - for (int i : modInfo->getModArchiveOverwrite()) { - ModInfo::getByIndex(i)->clearCaches(); - } - for (int i : modInfo->getModArchiveOverwritten()) { - ModInfo::getByIndex(i)->clearCaches(); - } - for (int i : modInfo->getModArchiveLooseOverwrite()) { - ModInfo::getByIndex(i)->clearCaches(); - } - for (int i : modInfo->getModArchiveLooseOverwritten()) { - ModInfo::getByIndex(i)->clearCaches(); - } - // update conflict check on the moved mod - modInfo->doConflictCheck(); - } setOverwriteMarkers(selectionModel()->selectedRows()); } diff --git a/src/organizercore.cpp b/src/organizercore.cpp index cf641886..df4cfe5e 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -119,6 +119,7 @@ OrganizerCore::OrganizerCore(Settings &settings) connect(&m_ModList, SIGNAL(removeOrigin(QString)), this, SLOT(removeOrigin(QString))); connect(&m_ModList, &ModList::modStatesChanged, [=] { currentProfile()->writeModlist(); }); + connect(&m_ModList, &ModList::modPrioritiesChanged, [this](auto&& indexes) { modPrioritiesChanged(indexes); }); connect(NexusInterface::instance().getAccessManager(), SIGNAL(validateSuccessful(bool)), this, SLOT(loginSuccessful(bool))); @@ -581,8 +582,8 @@ void OrganizerCore::setCurrentProfile(const QString &profileName) m_Settings.game().setSelectedProfileName(m_CurrentProfile->name()); - connect(m_CurrentProfile.get(), SIGNAL(modStatusChanged(uint)), this, SLOT(modStatusChanged(uint))); - connect(m_CurrentProfile.get(), SIGNAL(modStatusChanged(QList)), this, SLOT(modStatusChanged(QList))); + connect(m_CurrentProfile.get(), qOverload(&Profile::modStatusChanged), [this](auto&& index) { modStatusChanged(index); }); + connect(m_CurrentProfile.get(), qOverload>(&Profile::modStatusChanged), [this](auto&& indexes) { modStatusChanged(indexes); }); refreshDirectoryStructure(); m_CurrentProfile->debugDump(); @@ -1565,6 +1566,46 @@ void OrganizerCore::profileRefresh() refresh(); } +void OrganizerCore::modPrioritiesChanged(const QModelIndexList& indices) +{ + for (unsigned int i = 0; i < currentProfile()->numMods(); ++i) { + int priority = currentProfile()->getModPriority(i); + if (currentProfile()->modEnabled(i)) { + ModInfo::Ptr modInfo = ModInfo::getByIndex(i); + // priorities in the directory structure are one higher because data is 0 + directoryStructure()->getOriginByName(MOBase::ToWString(modInfo->internalName())).setPriority(priority + 1); + } + } + refreshBSAList(); + currentProfile()->writeModlist(); + directoryStructure()->getFileRegister()->sortOrigins(); + + for (auto& idx : indices) { + ModInfo::Ptr modInfo = ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt()); + // clear caches on all mods conflicting with the moved mod + for (int i : modInfo->getModOverwrite()) { + ModInfo::getByIndex(i)->clearCaches(); + } + for (int i : modInfo->getModOverwritten()) { + ModInfo::getByIndex(i)->clearCaches(); + } + for (int i : modInfo->getModArchiveOverwrite()) { + ModInfo::getByIndex(i)->clearCaches(); + } + for (int i : modInfo->getModArchiveOverwritten()) { + ModInfo::getByIndex(i)->clearCaches(); + } + for (int i : modInfo->getModArchiveLooseOverwrite()) { + ModInfo::getByIndex(i)->clearCaches(); + } + for (int i : modInfo->getModArchiveLooseOverwritten()) { + ModInfo::getByIndex(i)->clearCaches(); + } + // update conflict check on the moved mod + modInfo->doConflictCheck(); + } +} + void OrganizerCore::modStatusChanged(unsigned int index) { try { diff --git a/src/organizercore.h b/src/organizercore.h index 53686c8a..c00d0d42 100644 --- a/src/organizercore.h +++ b/src/organizercore.h @@ -362,6 +362,7 @@ public slots: ModInfo::Ptr installArchive(const QString& archivePath, int priority = -1, bool reinstallation = false, ModInfo::Ptr currentMod = nullptr, const QString& modName = QString()); + void modPrioritiesChanged(QModelIndexList const& indexes); void modStatusChanged(unsigned int index); void modStatusChanged(QList index); void requestDownload(const QUrl &url, QNetworkReply *reply); -- cgit v1.3.1 From ab820c1b0a5bb0f002ec5aba7954330acbdeb978 Mon Sep 17 00:00:00 2001 From: Mikaël Capelle Date: Sun, 24 Jan 2021 11:09:12 +0100 Subject: Fix enable/disable all message. --- src/modlistview.cpp | 105 ++++++++++++++++++----------------------- src/modlistview.h | 113 +++++++++++++++++++++++++++------------------ src/modlistviewactions.cpp | 8 +++- 3 files changed, 120 insertions(+), 106 deletions(-) (limited to 'src/modlistview.cpp') diff --git a/src/modlistview.cpp b/src/modlistview.cpp index a6bb4982..d7f90c9f 100644 --- a/src/modlistview.cpp +++ b/src/modlistview.cpp @@ -471,67 +471,52 @@ void ModListView::onModFilterActive(bool filterActive) } } -void ModListView::updateModCount() +ModListView::ModCounters ModListView::counters() const { - int activeCount = 0; - int visActiveCount = 0; - int backupCount = 0; - int visBackupCount = 0; - int foreignCount = 0; - int visForeignCount = 0; - int separatorCount = 0; - int visSeparatorCount = 0; - int regularCount = 0; - int visRegularCount = 0; - - QStringList allMods = m_core->modList()->allMods(); + ModCounters c; auto hasFlag = [](std::vector flags, ModInfo::EFlag filter) { return std::find(flags.begin(), flags.end(), filter) != flags.end(); }; - bool isEnabled; - bool isVisible; - for (QString mod : allMods) { - int modIndex = ModInfo::getIndex(mod); - ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex); - std::vector modFlags = modInfo->getFlags(); - isEnabled = m_core->currentProfile()->modEnabled(modIndex); - isVisible = m_sortProxy->filterMatchesMod(modInfo, isEnabled); - - for (auto flag : modFlags) { - switch (flag) { - case ModInfo::FLAG_BACKUP: backupCount++; - if (isVisible) - visBackupCount++; - break; - case ModInfo::FLAG_FOREIGN: foreignCount++; - if (isVisible) - visForeignCount++; - break; - case ModInfo::FLAG_SEPARATOR: separatorCount++; - if (isVisible) - visSeparatorCount++; - break; - } - } - if (!hasFlag(modFlags, ModInfo::FLAG_BACKUP) && - !hasFlag(modFlags, ModInfo::FLAG_FOREIGN) && - !hasFlag(modFlags, ModInfo::FLAG_SEPARATOR) && - !hasFlag(modFlags, ModInfo::FLAG_OVERWRITE)) { - if (isEnabled) { - activeCount++; - if (isVisible) - visActiveCount++; + for (unsigned int index = 0; index < ModInfo::getNumMods(); ++index) { + auto info = ModInfo::getByIndex(index); + const auto flags = info->getFlags(); + + const bool enabled = m_core->currentProfile()->modEnabled(index); + const bool visible = m_sortProxy->filterMatchesMod(info, enabled); + + if (info->isBackup()) { + c.backup++; + if (visible) c.visible.backup++; + } + else if (info->isForeign()) { + c.foreign++; + if (visible) c.visible.foreign++; + } + else if (info->isSeparator()) { + c.separator++; + if (visible) c.visible.separator++; + } + else if (!info->isOverwrite()) { + c.regular++; + if (visible) c.visible.regular++; + if (enabled) { + c.active++; + if (visible) c.visible.active++; } - if (isVisible) - visRegularCount++; - regularCount++; } } - ui.counter->display(visActiveCount); + return c; +} + +void ModListView::updateModCount() +{ + const auto c = counters(); + + ui.counter->display(c.visible.active); ui.counter->setToolTip(tr("" "" "" @@ -539,16 +524,16 @@ void ModListView::updateModCount() "" "" "
TypeAllVisible
Enabled mods: %1 / %2%3 / %4
Mod backups: %7%8
Separators: %9%10
") - .arg(activeCount) - .arg(regularCount) - .arg(visActiveCount) - .arg(visRegularCount) - .arg(foreignCount) - .arg(visForeignCount) - .arg(backupCount) - .arg(visBackupCount) - .arg(separatorCount) - .arg(visSeparatorCount) + .arg(c.active) + .arg(c.regular) + .arg(c.visible.active) + .arg(c.visible.regular) + .arg(c.foreign) + .arg(c.visible.foreign) + .arg(c.backup) + .arg(c.visible.backup) + .arg(c.separator) + .arg(c.visible.separator) ); } diff --git a/src/modlistview.h b/src/modlistview.h index adffd737..408bc900 100644 --- a/src/modlistview.h +++ b/src/modlistview.h @@ -131,9 +131,6 @@ public slots: protected: - friend class ModListContextMenu; - friend class ModListViewActions; - // map from/to the view indexes to the model // QModelIndex indexModelToView(const QModelIndex& index) const; @@ -183,14 +180,74 @@ protected slots: void commitData(QWidget* editor) override; -private: +private: // friend classes friend class ModConflictIconDelegate; - friend class ModFlagIconDelegate; friend class ModContentIconDelegate; + friend class ModFlagIconDelegate; + friend class ModListContextMenu; friend class ModListStyledItemDelegate; + friend class ModListViewActions; friend class ModListViewMarkingScrollBar; +private: // private structures + + struct ModListViewUi { + // the group by combo box + QComboBox* groupBy; + + // the mod counter + QLCDNumber* counter; + + // filters related + QLineEdit* filter; + QLabel* currentCategory; + QPushButton* clearFilters; + QComboBox* filterSeparators; + + // the plugin list (for highligths) + PluginListView* pluginList; + }; + + struct MarkerInfos { + // conflicts + std::set overwrite; + std::set overwritten; + std::set archiveOverwrite; + std::set archiveOverwritten; + std::set archiveLooseOverwrite; + std::set archiveLooseOverwritten; + + // selected plugins + std::set highlight; + }; + + struct ModCounters { + int active = 0; + int backup = 0; + int foreign = 0; + int separator = 0; + int regular = 0; + + struct { + int active = 0; + int backup = 0; + int foreign = 0; + int separator = 0; + int regular = 0; + } visible; + }; + + // index in the groupby combo + // + enum GroupBy { + NONE = 0, + CATEGORY = 1, + NEXUS_ID = 2 + }; + +private: // private functions + void onModPrioritiesChanged(const QModelIndexList& indices); void onModInstalled(const QString& modName); void onModFilterActive(bool filterActive); @@ -229,6 +286,10 @@ private: QList contentsIcons(const QModelIndex& index, bool* forceCompact = nullptr) const; QString contentsTooltip(const QModelIndex& index) const; + // compute the counters for mods according to the current filter + // + ModCounters counters() const; + // get/set the selected items on the view, this method return/take indices // from the mod list model, not the view, so it's safe to restore // @@ -244,33 +305,7 @@ private: // void updateGroupByProxy(); - // index in the groupby combo - // - enum GroupBy { - NONE = 0, - CATEGORY = 1, - NEXUS_ID = 2 - }; - -private: - - struct ModListViewUi - { - // the group by combo box - QComboBox* groupBy; - - // the mod counter - QLCDNumber* counter; - - // filters related - QLineEdit* filter; - QLabel* currentCategory; - QPushButton* clearFilters; - QComboBox* filterSeparators; - - // the plugin list (for highligths) - PluginListView* pluginList; - }; +public: // member variables OrganizerCore* m_core; std::unique_ptr m_filters; @@ -291,19 +326,7 @@ private: // losing them on model reset std::map> m_collapsed; - struct MarkerInfos { - // conflicts - std::set overwrite; - std::set overwritten; - std::set archiveOverwrite; - std::set archiveOverwritten; - std::set archiveLooseOverwrite; - std::set archiveLooseOverwritten; - - // selected plugins - std::set highlight; - } m_markers; - + MarkerInfos m_markers; ViewMarkingScrollBar* m_scrollbar; bool m_inDragMoveEvent = false; diff --git a/src/modlistviewactions.cpp b/src/modlistviewactions.cpp index 647aac0b..9d4be554 100644 --- a/src/modlistviewactions.cpp +++ b/src/modlistviewactions.cpp @@ -207,10 +207,16 @@ void ModListViewActions::createSeparator(const QModelIndex& index) const void ModListViewActions::setAllMatchingModsEnabled(bool enabled) const { + // number of mods to enable / disable + const auto counters = m_view->counters(); + const auto count = enabled ? + counters.visible.regular - counters.visible.active : counters.visible.active; + + // retrieve visible mods from the model view const auto allIndex = m_view->indexViewToModel(flatIndex(m_view->model())); const QString message = enabled ? tr("Really enable %1 mod(s)?") : tr("Really disable %1 mod(s)?"); - if (QMessageBox::question(m_parent, tr("Confirm"), message.arg(allIndex.size()), + if (QMessageBox::question(m_parent, tr("Confirm"), message.arg(count), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { m_core.modList()->setActive(allIndex, enabled); } -- cgit v1.3.1