From 8eb59316f9140a621bc4cf0d06d7b5b898b50972 Mon Sep 17 00:00:00 2001 From: Mikaƫl Capelle Date: Wed, 30 Dec 2020 14:39:57 +0100 Subject: Do not invalidate the sort proxy when not required (keep selection). --- src/mainwindow.cpp | 22 +++++++----- src/modlist.cpp | 31 ++++++---------- src/modlist.h | 13 +++++-- src/modlistsortproxy.cpp | 6 ++-- src/modlistview.cpp | 92 ++++++++++++++++++------------------------------ src/modlistview.h | 8 ++--- 6 files changed, 73 insertions(+), 99 deletions(-) (limited to 'src') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index df227aab..e01f984a 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -3833,15 +3833,17 @@ void MainWindow::ignoreUpdate(int modIndex) QItemSelectionModel *selection = ui->modList->selectionModel(); if (selection->hasSelection() && selection->selectedRows().count() > 1) { for (QModelIndex idx : selection->selectedRows()) { - ModInfo::Ptr info = ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt()); + auto index = idx.data(ModList::IndexRole).toInt(); + ModInfo::Ptr info = ModInfo::getByIndex(index); info->ignoreUpdate(true); + m_OrganizerCore.modList()->notifyChange(index); } } else { ModInfo::Ptr info = ModInfo::getByIndex(modIndex); info->ignoreUpdate(true); + m_OrganizerCore.modList()->notifyChange(modIndex); } - ui->modList->invalidate(); } void MainWindow::checkModUpdates_clicked(int modIndex) @@ -3867,13 +3869,14 @@ void MainWindow::unignoreUpdate(int modIndex) for (QModelIndex idx : selection->selectedRows()) { ModInfo::Ptr info = ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt()); info->ignoreUpdate(false); + m_OrganizerCore.modList()->notifyChange(idx.data(ModList::IndexRole).toInt()); } } else { ModInfo::Ptr info = ModInfo::getByIndex(modIndex); info->ignoreUpdate(false); + m_OrganizerCore.modList()->notifyChange(modIndex); } - ui->modList->invalidate(); } void MainWindow::addPrimaryCategoryCandidates(QMenu *primaryCategoryMenu, @@ -4970,7 +4973,6 @@ void MainWindow::nxmUpdateInfoAvailable(QString gameName, QVariant userData, QVa return std::make_pair(gameNameReal, ModInfo::filteredMods(gameNameReal, resultList, userData.toBool(), true)); }); watcher->setFuture(future); - ui->modList->invalidate(); } void MainWindow::finishUpdateInfo() @@ -4989,6 +4991,7 @@ void MainWindow::finishUpdateInfo() if (mod->canBeUpdated()) { organizedGames.insert(std::make_pair(mod->gameName().toLower(), mod->nexusId())); } + m_OrganizerCore.modList()->notifyChange(ModInfo::getIndex(mod->name())); } if (!finalMods.empty() && organizedGames.empty()) @@ -5073,7 +5076,7 @@ void MainWindow::nxmUpdatesAvailable(QString gameName, int modID, QVariant userD if (foundUpdate) { // Just get the standard data updates for endorsements and descriptions mod->setLastNexusUpdate(QDateTime::currentDateTimeUtc()); - ui->modList->invalidate(); + m_OrganizerCore.modList()->notifyChange(ModInfo::getIndex(mod->name())); } else { // Scrape mod data here so we can use the mod version if no file update was located requiresInfo = true; @@ -5087,7 +5090,6 @@ void MainWindow::nxmUpdatesAvailable(QString gameName, int modID, QVariant userD void MainWindow::nxmModInfoAvailable(QString gameName, int modID, QVariant userData, QVariant resultData, int requestID) { QVariantMap result = resultData.toMap(); - bool foundUpdate = false; QString gameNameReal; for (IPluginGame *game : m_PluginContainer.plugins()) { if (game->gameNexusName() == gameName) { @@ -5097,6 +5099,7 @@ void MainWindow::nxmModInfoAvailable(QString gameName, int modID, QVariant userD } std::vector modsList = ModInfo::getByModID(gameNameReal, modID); for (auto mod : modsList) { + bool foundUpdate = false; QDateTime now = QDateTime::currentDateTimeUtc(); QDateTime updateTarget = mod->getExpires(); if (now >= updateTarget) { @@ -5123,9 +5126,10 @@ void MainWindow::nxmModInfoAvailable(QString gameName, int modID, QVariant userD mod->setLastNexusQuery(QDateTime::currentDateTimeUtc()); mod->setNexusLastModified(QDateTime::fromSecsSinceEpoch(result["updated_timestamp"].toInt(), Qt::UTC)); mod->saveMeta(); - } - if (foundUpdate) { - ui->modList->invalidate(); + + if (foundUpdate) { + m_OrganizerCore.modList()->notifyChange(ModInfo::getIndex(mod->name())); + } } } diff --git a/src/modlist.cpp b/src/modlist.cpp index a192390d..608a26b4 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -1510,7 +1510,7 @@ QModelIndex ModList::indexToProxy(QAbstractItemModel* proxyModel, const QModelIn return QModelIndex(); } -void ModList::moveMods(const QModelIndexList& indices, int offset) +void ModList::shiftMods(const QModelIndexList& indices, int offset) { // retrieve the mod index and sort them by priority to avoid issue // when moving them @@ -1574,28 +1574,17 @@ bool ModList::toggleState(const QModelIndexList& indices) return true; } -//note: caller needs to make sure sort proxy is updated -void ModList::enableSelected(const QItemSelectionModel *selectionModel) +void ModList::setActive(const QModelIndexList& indices, bool active) { - if (selectionModel->hasSelection()) { - QList modsToEnable; - for (auto row : selectionModel->selectedRows(COL_PRIORITY)) { - int modID = m_Profile->modIndexByPriority(row.data().toInt()); - modsToEnable.append(modID); - } - m_Profile->setModsEnabled(modsToEnable, QList()); + QList mods; + for (auto& index : indices) { + mods.append(index.data(IndexRole).toInt()); } -} -//note: caller needs to make sure sort proxy is updated -void ModList::disableSelected(const QItemSelectionModel *selectionModel) -{ - if (selectionModel->hasSelection()) { - QList modsToDisable; - for (auto row : selectionModel->selectedRows(COL_PRIORITY)) { - int modID = m_Profile->modIndexByPriority(row.data().toInt()); - modsToDisable.append(modID); - } - m_Profile->setModsEnabled(QList(), modsToDisable); + if (active) { + m_Profile->setModsEnabled(mods, {}); + } + else { + m_Profile->setModsEnabled({}, mods); } } diff --git a/src/modlist.h b/src/modlist.h index 778f1fee..913d2ea8 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -218,10 +218,17 @@ public: // implementation of virtual functions of QAbstractItemModel public slots: void onDragEnter(const QMimeData* data); - void enableSelected(const QItemSelectionModel *selectionModel); - void disableSelected(const QItemSelectionModel *selectionModel); - void moveMods(const QModelIndexList& indices, int offset); + // enable/disable mods at the given indices. + // + void setActive(const QModelIndexList& indices, bool active); + + // shift the priority of mods at the given indices by the given offset + // + void shiftMods(const QModelIndexList& indices, int offset); + + // toggle the active state of mods at the given indices + // bool toggleState(const QModelIndexList& indices); signals: diff --git a/src/modlistsortproxy.cpp b/src/modlistsortproxy.cpp index ed752d7a..93f97895 100644 --- a/src/modlistsortproxy.cpp +++ b/src/modlistsortproxy.cpp @@ -69,7 +69,7 @@ void ModListSortProxy::setCriteria(const std::vector& criteria) if (changed || isForUpdates) { m_Criteria = criteria; updateFilterActive(); - invalidate(); + invalidateFilter(); } } @@ -236,7 +236,7 @@ void ModListSortProxy::updateFilter(const QString& filter) { m_Filter = filter; updateFilterActive(); - invalidate(); + invalidateFilter(); } bool ModListSortProxy::hasConflictFlag(const std::vector &flags) const @@ -555,7 +555,7 @@ void ModListSortProxy::setOptions( if (m_FilterMode != mode || separators != m_FilterSeparators) { m_FilterMode = mode; m_FilterSeparators = separators; - this->invalidate(); + invalidateFilter(); } } diff --git a/src/modlistview.cpp b/src/modlistview.cpp index 74f4b566..c4641934 100644 --- a/src/modlistview.cpp +++ b/src/modlistview.cpp @@ -171,64 +171,28 @@ int ModListView::prevMod(int modIndex) const return -1; } -void ModListView::invalidate() -{ - if (m_sortProxy) { - m_sortProxy->invalidate(); - } -} - void ModListView::enableAllVisible() { - Profile* profile = m_core->currentProfile(); - - QList modsToEnable; - for (auto& index : allIndex(model())) { - modsToEnable.append(index.data(ModList::IndexRole).toInt()); - } - profile->setModsEnabled(modsToEnable, {}); - invalidate(); + m_core->modList()->setActive(indexViewToModel(allIndex(model())), true); } void ModListView::disableAllVisible() { - MOBase::log::debug("disableAllVisible: {}", model()->rowCount()); - Profile* profile = m_core->currentProfile(); - - QList modsToDisable; - for (auto& index : allIndex(model())) { - modsToDisable.append(index.data(ModList::IndexRole).toInt()); - } - profile->setModsEnabled({}, modsToDisable); - invalidate(); + m_core->modList()->setActive(indexViewToModel(allIndex(model())), false); } void ModListView::enableSelected() { - Profile* profile = m_core->currentProfile(); if (selectionModel()->hasSelection()) { - QList modsToEnable; - for (auto row : selectionModel()->selectedRows(ModList::COL_PRIORITY)) { - int modID = profile->modIndexByPriority(row.data().toInt()); - modsToEnable.append(modID); - } - profile->setModsEnabled(modsToEnable, {}); + m_core->modList()->setActive(indexViewToModel(selectionModel()->selectedRows()), true); } - invalidate(); } void ModListView::disableSelected() { - Profile* profile = m_core->currentProfile(); if (selectionModel()->hasSelection()) { - QList modsToDisable; - for (auto row : selectionModel()->selectedRows(ModList::COL_PRIORITY)) { - int modID = profile->modIndexByPriority(row.data().toInt()); - modsToDisable.append(modID); - } - profile->setModsEnabled({}, modsToDisable); + m_core->modList()->setActive(indexViewToModel(selectionModel()->selectedRows()), false); } - invalidate(); } void ModListView::setFilterCriteria(const std::vector& criteria) @@ -279,6 +243,15 @@ QModelIndex ModListView::indexModelToView(const QModelIndex& index) const return qindex; } +QModelIndexList ModListView::indexModelToView(const QModelIndexList& index) const +{ + QModelIndexList result; + for (auto& idx : index) { + result.append(indexModelToView(idx)); + } + return result; +} + QModelIndex ModListView::indexViewToModel(const QModelIndex& index) const { if (index.model() == m_core->modList()) { @@ -292,6 +265,15 @@ QModelIndex ModListView::indexViewToModel(const QModelIndex& index) const } } +QModelIndexList ModListView::indexViewToModel(const QModelIndexList& index) const +{ + QModelIndexList result; + for (auto& idx : index) { + result.append(indexViewToModel(idx)); + } + return result; +} + QModelIndex ModListView::nextIndex(const QModelIndex& index) const { auto* model = index.model(); @@ -329,15 +311,13 @@ QModelIndex ModListView::prevIndex(const QModelIndex& index) const return prev; } -std::vector ModListView::allIndex( +QModelIndexList ModListView::allIndex( const QAbstractItemModel* model, int column, const QModelIndex& parent) const { - std::vector index; + QModelIndexList index; for (std::size_t i = 0; i < model->rowCount(parent); ++i) { - index.push_back(model->index(i, column, parent)); - - auto cindex = allIndex(model, column, index.back()); - index.insert(index.end(), cindex.begin(), cindex.end()); + index.append(model->index(i, column, parent)); + index.append(allIndex(model, column, index.back())); } return index; } @@ -376,10 +356,6 @@ void ModListView::onModPrioritiesChanged(std::vector const& indices) m_core->currentProfile()->writeModlist(); m_core->directoryStructure()->getFileRegister()->sortOrigins(); - if (m_sortProxy) { - m_sortProxy->invalidate(); - } - { // refresh selection QModelIndex current = currentIndex(); if (current.isValid()) { @@ -431,7 +407,7 @@ void ModListView::onModInstalled(const QString& modName) setFocus(Qt::OtherFocusReason); scrollTo(qIndex); setCurrentIndex(qIndex); - selectionModel()->select(qIndex, QItemSelectionModel::Select | QItemSelectionModel::Rows); + selectionModel()->select(qIndex, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); } void ModListView::onModFilterActive(bool filterActive) @@ -666,6 +642,12 @@ void ModListView::setup(OrganizerCore& core, Ui::MainWindow* mwui) }); } +void ModListView::setModel(QAbstractItemModel* model) +{ + QTreeView::setModel(model); + setVerticalScrollBar(new ViewMarkingScrollBar(model, this)); +} + QRect ModListView::visualRect(const QModelIndex& index) const { QRect rect = QTreeView::visualRect(index); @@ -680,12 +662,6 @@ QRect ModListView::visualRect(const QModelIndex& index) const return rect; } -void ModListView::setModel(QAbstractItemModel* model) -{ - QTreeView::setModel(model); - setVerticalScrollBar(new ViewMarkingScrollBar(model, this)); -} - QModelIndexList ModListView::selectedIndexes() const { return m_inDragMoveEvent ? QModelIndexList() : QTreeView::selectedIndexes(); @@ -747,7 +723,7 @@ bool ModListView::moveSelection(int key) offset = -offset; } - m_core->modList()->moveMods(sourceRows, offset); + m_core->modList()->shiftMods(sourceRows, offset); // reset the selection and the index setCurrentIndex(indexModelToView(cindex)); diff --git a/src/modlistview.h b/src/modlistview.h index 88028428..1d8a9b49 100644 --- a/src/modlistview.h +++ b/src/modlistview.h @@ -80,10 +80,6 @@ signals: public slots: - // invalidate the top-level model - // - void invalidate(); - // enable/disable all visible mods // void enableAllVisible(); @@ -108,7 +104,9 @@ protected: // map from/to the view indexes to the model // QModelIndex indexModelToView(const QModelIndex& index) const; + QModelIndexList indexModelToView(const QModelIndexList& index) const; QModelIndex indexViewToModel(const QModelIndex& index) const; + QModelIndexList indexViewToModel(const QModelIndexList& index) const; // returns the next/previous index of the given index // @@ -117,7 +115,7 @@ protected: // all index for the given model under the given index, recursively // - std::vector allIndex( + QModelIndexList allIndex( const QAbstractItemModel* model, int column = 0, const QModelIndex& index = QModelIndex()) const; // re-implemented to fake the return value to allow drag-and-drop on -- cgit v1.3.1