diff options
| -rw-r--r-- | src/mainwindow.cpp | 115 | ||||
| -rw-r--r-- | src/mainwindow.h | 7 | ||||
| -rw-r--r-- | src/modlist.cpp | 29 | ||||
| -rw-r--r-- | src/modlist.h | 15 | ||||
| -rw-r--r-- | src/modlistbypriorityproxy.cpp | 10 | ||||
| -rw-r--r-- | src/modlistbypriorityproxy.h | 1 | ||||
| -rw-r--r-- | src/organizercore.cpp | 2 |
7 files changed, 125 insertions, 54 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 48a935ae..61d0e5bb 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -548,9 +548,12 @@ MainWindow::MainWindow(Settings &settings void MainWindow::updateModListByPriorityProxy() { + if (ui->groupCombo->currentIndex() != 0) { + return; + } if (m_ModListSortProxy->sortColumn() == ModList::COL_PRIORITY && m_ModListSortProxy->sortOrder() == Qt::AscendingOrder) { m_ModListSortProxy->setSourceModel(m_ModListByPriorityProxy); - emit m_OrganizerCore.modList()->layoutChanged(); + m_ModListByPriorityProxy->refresh(); } else { m_ModListSortProxy->setSourceModel(m_OrganizerCore.modList()); @@ -579,6 +582,7 @@ void MainWindow::setupModList() ui->modList->sortByColumn(ModList::COL_PRIORITY, Qt::AscendingOrder); connect(ui->modList, &ModListView::dragEntered, m_OrganizerCore.modList(), &ModList::onDragEnter); + connect(m_OrganizerCore.modList(), &ModList::modPrioritiesChanged, this, &MainWindow::onModPrioritiesChanged); connect( ui->modList->header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), @@ -2435,8 +2439,58 @@ void MainWindow::esplist_changed() updatePluginCount(); } -void MainWindow::modorder_changed() +QModelIndex MainWindow::modViewIndexToModel(const QModelIndex& index) const +{ + auto sindex = index; + + // remove the sort proxy. + sindex = m_ModListSortProxy->mapToSource(index); + + // if there is another proxy + if (auto* proxy = qobject_cast<QAbstractProxyModel*>(m_ModListSortProxy->sourceModel())) { + sindex = proxy->mapToSource(sindex); + } + + return sindex; +} + +QModelIndex MainWindow::modModelIndexToView(const QModelIndex& index) const +{ + auto dindex = index; + + // if there is another proxy than the sort + if (auto* proxy = qobject_cast<QAbstractProxyModel*>(m_ModListSortProxy->sourceModel())) { + dindex = proxy->mapFromSource(dindex); + } + + // add the sort proxy + dindex = m_ModListSortProxy->mapFromSource(dindex); + + return dindex; + +} + +void MainWindow::onModPrioritiesChanged(std::vector<int> const& indices) { + // if we have collapsible separators, we need to refresh, expand if necessary, + // and recreate the selection + if (m_ModListSortProxy->sourceModel() == m_ModListByPriorityProxy) { + + // manually retain the selection and restore it after + QModelIndex current = modViewIndexToModel(ui->modList->currentIndex()); + std::vector<QModelIndex> selected; + for (const auto& idx : ui->modList->selectionModel()->selectedRows()) { + selected.push_back(modViewIndexToModel(idx)); + } + + m_ModListByPriorityProxy->refresh(); + + ui->modList->setCurrentIndex(modModelIndexToView(current)); + for (auto idx : selected) { + ui->modList->selectionModel()->select(modModelIndexToView(idx), QItemSelectionModel::Select | QItemSelectionModel::Rows); + } + } + for (unsigned int i = 0; i < m_OrganizerCore.currentProfile()->numMods(); ++i) { int priority = m_OrganizerCore.currentProfile()->getModPriority(i); if (m_OrganizerCore.currentProfile()->modEnabled(i)) { @@ -2453,7 +2507,7 @@ void MainWindow::modorder_changed() { // refresh selection QModelIndex current = ui->modList->currentIndex(); if (current.isValid()) { - ModInfo::Ptr modInfo = ModInfo::getByIndex(current.data(Qt::UserRole + 1).toInt()); + ModInfo::Ptr modInfo = ModInfo::getByIndex(current.data(ModList::IndexRole).toInt()); // clear caches on all mods conflicting with the moved mod for (int i : modInfo->getModOverwrite()) { ModInfo::getByIndex(i)->clearCaches(); @@ -2478,8 +2532,9 @@ void MainWindow::modorder_changed() m_OrganizerCore.modList()->setOverwriteMarkers(modInfo->getModOverwrite(), modInfo->getModOverwritten()); m_OrganizerCore.modList()->setArchiveOverwriteMarkers(modInfo->getModArchiveOverwrite(), modInfo->getModArchiveOverwritten()); m_OrganizerCore.modList()->setArchiveLooseOverwriteMarkers(modInfo->getModArchiveLooseOverwrite(), modInfo->getModArchiveLooseOverwritten()); - if (m_ModListSortProxy != nullptr) + if (m_ModListSortProxy != nullptr) { m_ModListSortProxy->invalidate(); + } ui->modList->verticalScrollBar()->repaint(); } } @@ -2624,7 +2679,7 @@ void MainWindow::modlistSelectionsChanged(const QItemSelection &selected) if (selected.count()) { auto selection = selected.last(); auto index = selection.indexes().last(); - ModInfo::Ptr selectedMod = ModInfo::getByIndex(index.data(Qt::UserRole + 1).toInt()); + ModInfo::Ptr selectedMod = ModInfo::getByIndex(index.data(ModList::IndexRole).toInt()); m_OrganizerCore.modList()->setOverwriteMarkers(selectedMod->getModOverwrite(), selectedMod->getModOverwritten()); m_OrganizerCore.modList()->setArchiveOverwriteMarkers(selectedMod->getModArchiveOverwrite(), selectedMod->getModArchiveOverwritten()); m_OrganizerCore.modList()->setArchiveLooseOverwriteMarkers(selectedMod->getModArchiveLooseOverwrite(), selectedMod->getModArchiveLooseOverwritten()); @@ -2669,7 +2724,7 @@ void MainWindow::removeMod_clicked() int i = 0; for (QModelIndex idx : selection->selectedRows()) { QString name = idx.data().toString(); - if (!ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt())->isRegular()) { + if (!ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt())->isRegular()) { continue; } @@ -2684,7 +2739,7 @@ void MainWindow::removeMod_clicked() mods += "<li>...</li>"; } - modNames.append(ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt())->name()); + modNames.append(ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt())->name()); ++i; } if (QMessageBox::question(this, tr("Confirm"), @@ -2776,7 +2831,7 @@ void MainWindow::endorse_clicked() } for (QModelIndex idx : selection->selectedRows()) { - ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt())->endorse(true); + ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt())->endorse(true); } }); } @@ -2786,7 +2841,7 @@ void MainWindow::dontendorse_clicked() QItemSelectionModel *selection = ui->modList->selectionModel(); if (selection->hasSelection() && selection->selectedRows().count() > 1) { for (QModelIndex idx : selection->selectedRows()) { - ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt())->setNeverEndorse(); + ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt())->setNeverEndorse(); } } else { @@ -2812,7 +2867,7 @@ void MainWindow::unendorse_clicked() } for (QModelIndex idx : selection->selectedRows()) { - ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt())->endorse(false); + ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt())->endorse(false); } }); } @@ -2831,7 +2886,7 @@ void MainWindow::track_clicked() m_OrganizerCore.loggedInAction(this, [this] { QItemSelectionModel *selection = ui->modList->selectionModel(); for (auto idx : selection->selectedRows()) { - ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt())->track(true); + ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt())->track(true); } }); } @@ -2841,7 +2896,7 @@ void MainWindow::untrack_clicked() m_OrganizerCore.loggedInAction(this, [this] { QItemSelectionModel *selection = ui->modList->selectionModel(); for (auto idx : selection->selectedRows()) { - ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt())->track(false); + ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt())->track(false); } }); } @@ -3033,7 +3088,7 @@ void MainWindow::ignoreMissingData_clicked() std::vector<ModInfo::Ptr> changed; for (QModelIndex idx : rows) { - int row_idx = idx.data(Qt::UserRole + 1).toInt(); + int row_idx = idx.data(ModList::IndexRole).toInt(); ModInfo::Ptr info = ModInfo::getByIndex(row_idx); info->markValidated(true); changed.push_back(info); @@ -3058,7 +3113,7 @@ void MainWindow::markConverted_clicked() std::vector<ModInfo::Ptr> changed; for (QModelIndex idx : rows) { - int row_idx = idx.data(Qt::UserRole + 1).toInt(); + int row_idx = idx.data(ModList::IndexRole).toInt(); ModInfo::Ptr info = ModInfo::getByIndex(row_idx); info->markConverted(true); changed.push_back(info); @@ -3097,7 +3152,7 @@ void MainWindow::restoreHiddenFiles_clicked() for (QModelIndex idx : selection->selectedRows()) { QString name = idx.data().toString(); - int row_idx = idx.data(Qt::UserRole + 1).toInt(); + int row_idx = idx.data(ModList::IndexRole).toInt(); ModInfo::Ptr modInfo = ModInfo::getByIndex(row_idx); const auto flags = modInfo->getFlags(); @@ -3116,7 +3171,7 @@ void MainWindow::restoreHiddenFiles_clicked() mods += "<li>...</li>"; } - modNames.append(ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt())->name()); + modNames.append(ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt())->name()); ++i; } if (QMessageBox::question(this, tr("Confirm"), @@ -3125,7 +3180,7 @@ void MainWindow::restoreHiddenFiles_clicked() for (QModelIndex idx : selection->selectedRows()) { - int row_idx = idx.data(Qt::UserRole + 1).toInt(); + int row_idx = idx.data(ModList::IndexRole).toInt(); ModInfo::Ptr modInfo = ModInfo::getByIndex(row_idx); const auto flags = modInfo->getFlags(); @@ -3186,7 +3241,7 @@ void MainWindow::visitOnNexus_clicked() QString gameName; for (QModelIndex idx : selection->selectedRows()) { - row_idx = idx.data(Qt::UserRole + 1).toInt(); + row_idx = idx.data(ModList::IndexRole).toInt(); info = ModInfo::getByIndex(row_idx); int modID = info->nexusId(); gameName = info->gameName(); @@ -3224,7 +3279,7 @@ void MainWindow::visitWebPage_clicked() ModInfo::Ptr info; QString gameName; for (QModelIndex idx : selection->selectedRows()) { - row_idx = idx.data(Qt::UserRole + 1).toInt(); + row_idx = idx.data(ModList::IndexRole).toInt(); info = ModInfo::getByIndex(row_idx); const auto url = info->parseCustomURL(); @@ -3245,7 +3300,7 @@ void MainWindow::visitWebPage_clicked() void MainWindow::visitNexusOrWebPage(const QModelIndex& idx) { - int row_idx = idx.data(Qt::UserRole + 1).toInt(); + int row_idx = idx.data(ModList::IndexRole).toInt(); ModInfo::Ptr info = ModInfo::getByIndex(row_idx); if (!info) { @@ -3293,7 +3348,7 @@ void MainWindow::openExplorer_clicked() QItemSelectionModel *selection = ui->modList->selectionModel(); if (selection->hasSelection() && selection->selectedRows().count() > 1) { for (QModelIndex idx : selection->selectedRows()) { - ModInfo::Ptr info = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt()); + ModInfo::Ptr info = ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt()); shell::Explore(info->absolutePath()); } } @@ -3332,7 +3387,7 @@ void MainWindow::openExplorer_activated() if (selection->hasSelection() && selection->selectedRows().count() == 1 ) { QModelIndex idx = selection->currentIndex(); - ModInfo::Ptr modInfo = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt()); + ModInfo::Ptr modInfo = ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt()); std::vector<ModInfo::EFlag> flags = modInfo->getFlags(); if (modInfo->isRegular() || (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end())) { @@ -3621,7 +3676,7 @@ void MainWindow::setColor_clicked() QItemSelectionModel *selection = ui->modList->selectionModel(); if (selection->hasSelection() && selection->selectedRows().count() > 1) { for (QModelIndex idx : selection->selectedRows()) { - ModInfo::Ptr info = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt()); + ModInfo::Ptr info = ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt()); info->setColor(currentColor); } } @@ -3637,7 +3692,7 @@ void MainWindow::resetColor_clicked() QItemSelectionModel *selection = ui->modList->selectionModel(); if (selection->hasSelection() && selection->selectedRows().count() > 1) { for (QModelIndex idx : selection->selectedRows()) { - ModInfo::Ptr info = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt()); + ModInfo::Ptr info = ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt()); info->setColor(color); } } @@ -4196,7 +4251,7 @@ void MainWindow::ignoreUpdate() { QItemSelectionModel *selection = ui->modList->selectionModel(); if (selection->hasSelection() && selection->selectedRows().count() > 1) { for (QModelIndex idx : selection->selectedRows()) { - ModInfo::Ptr info = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt()); + ModInfo::Ptr info = ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt()); info->ignoreUpdate(true); } } @@ -4214,7 +4269,7 @@ void MainWindow::checkModUpdates_clicked() QItemSelectionModel *selection = ui->modList->selectionModel(); if (selection->hasSelection() && selection->selectedRows().count() > 1) { for (QModelIndex idx : selection->selectedRows()) { - ModInfo::Ptr info = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt()); + ModInfo::Ptr info = ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt()); IDs.insert(std::make_pair<QString, int>(info->gameName(), info->nexusId())); } } else { @@ -4229,7 +4284,7 @@ void MainWindow::unignoreUpdate() QItemSelectionModel *selection = ui->modList->selectionModel(); if (selection->hasSelection() && selection->selectedRows().count() > 1) { for (QModelIndex idx : selection->selectedRows()) { - ModInfo::Ptr info = ModInfo::getByIndex(idx.data(Qt::UserRole + 1).toInt()); + ModInfo::Ptr info = ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt()); info->ignoreUpdate(false); } } @@ -4640,6 +4695,12 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos) initModListContextMenu(allMods); allMods->setTitle(tr("All Mods")); menu.addMenu(allMods); + + if (m_ModListSortProxy->sourceModel() == m_ModListByPriorityProxy) { + menu.addAction(tr("Collapse all"), ui->modList, &QTreeView::collapseAll); + menu.addAction(tr("Expand all"), ui->modList, &QTreeView::expandAll); + } + menu.addSeparator(); ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow); diff --git a/src/mainwindow.h b/src/mainwindow.h index ccfd4881..61a8b5e3 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -148,7 +148,7 @@ public: ModInfo::Ptr previousModInList(); public slots: - void modorder_changed(); + void onModPrioritiesChanged(std::vector<int> const& indices); void esplist_changed(); void refresherProgress(const DirectoryRefreshProgress* p); @@ -607,8 +607,13 @@ private slots: // ui slots void storeSettings(); void readSettings(); + void setupModList(); void updateModListByPriorityProxy(); + + // map index from the modlist view to the modlist model, handling proxy + QModelIndex modViewIndexToModel(const QModelIndex& index) const; + QModelIndex modModelIndexToView(const QModelIndex& index) const; }; #endif // MAINWINDOW_H diff --git a/src/modlist.cpp b/src/modlist.cpp index 79dbf815..a6286007 100644 --- a/src/modlist.cpp +++ b/src/modlist.cpp @@ -336,7 +336,7 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const } else { return modInfo->nexusId(); } - } else if (role == Qt::UserRole + 1) { + } else if (role == IndexRole) { return modIndex; } else if (role == Qt::UserRole + 2) { switch (column) { @@ -592,8 +592,7 @@ bool ModList::setData(const QModelIndex &index, const QVariant &value, int role) } if (ok) { m_Profile->setModPriority(modID, newPriority); - - emit modorder_changed(); + emit modPrioritiesChanged({ modID }); result = true; } else { result = false; @@ -765,7 +764,7 @@ void ModList::changeModPriority(std::vector<int> sourceIndices, int newPriority) emit layoutChanged(); - emit modorder_changed(); + emit modPrioritiesChanged(sourceIndices); } @@ -777,8 +776,7 @@ void ModList::changeModPriority(int sourceIndex, int newPriority) m_Profile->setModPriority(sourceIndex, newPriority); emit layoutChanged(); - - emit modorder_changed(); + emit modPrioritiesChanged({ sourceIndex }); } void ModList::setOverwriteMarkers(const std::set<unsigned int> &overwrite, const std::set<unsigned int> &overwritten) @@ -1525,17 +1523,18 @@ bool ModList::moveSelection(QAbstractItemView *itemView, int direction) rows.swapItemsAt(i, rows.size() - i - 1); } } + std::vector<int> allIndex; for (QModelIndex idx : rows) { - if (filterModel != nullptr) { - idx = filterModel->mapToSource(idx); - } - int newPriority = m_Profile->getModPriority(idx.row()) + offset; + auto index = idx.data(IndexRole).toInt(); + allIndex.push_back(index); + int newPriority = m_Profile->getModPriority(index) + offset; if ((newPriority >= 0) && (newPriority < static_cast<int>(m_Profile->numRegularMods()))) { - m_Profile->setModPriority(idx.row(), newPriority); - notifyChange(idx.row()); + m_Profile->setModPriority(index, newPriority); + notifyChange(index); } } - emit modorder_changed(); + + emit modPrioritiesChanged(allIndex); return true; } @@ -1547,7 +1546,7 @@ bool ModList::deleteSelection(QAbstractItemView *itemView) if (rows.count() > 1) { emit removeSelectedMods(); } else if (rows.count() == 1) { - removeRow(rows[0].data(Qt::UserRole + 1).toInt(), QModelIndex()); + removeRow(rows[0].data(IndexRole).toInt(), QModelIndex()); } return true; } @@ -1562,7 +1561,7 @@ bool ModList::toggleSelection(QAbstractItemView *itemView) QList<unsigned int> modsToDisable; QModelIndexList dirtyMods; for (QModelIndex idx : selectionModel->selectedRows()) { - int modId = idx.data(Qt::UserRole + 1).toInt(); + int modId = idx.data(IndexRole).toInt(); if (m_Profile->modEnabled(modId)) { modsToDisable.append(modId); dirtyMods.append(idx); diff --git a/src/modlist.h b/src/modlist.h index 4e50c959..83e8ec9c 100644 --- a/src/modlist.h +++ b/src/modlist.h @@ -55,6 +55,10 @@ class ModList : public QAbstractItemModel public:
+ // role of the index of the mod
+ //
+ constexpr static int IndexRole = Qt::UserRole + 1;
+
enum EColumn {
COL_NAME,
COL_CONFLICTFLAGS,
@@ -70,8 +74,6 @@ public: COL_LASTCOLUMN = COL_NOTES,
};
- friend class ModListProxy;
-
using SignalModInstalled = boost::signals2::signal<void(MOBase::IModInterface*)>;
using SignalModRemoved = boost::signals2::signal<void(QString const&)>;
using SignalModStateChanged = boost::signals2::signal<void (const std::map<QString, MOBase::IModList::ModStates>&)>;
@@ -222,12 +224,12 @@ public slots: signals:
/**
- * @brief emitted whenever the sorting in the list was changed by the user
+ * @brief Emitted whenever the priority of mods changes
*
- * the sorting of the list can only be manually changed if the list is sorted by priority
- * in which case the move is intended to change the priority of a mod
+ * The sorting of the list can only be manually changed if the list is sorted by priority
+ * in which case the move is intended to change the priority of a mod.
**/
- void modorder_changed();
+ void modPrioritiesChanged(std::vector<int> const& index);
/**
* @brief emitted when the model wants a text to be displayed by the UI
@@ -389,6 +391,7 @@ private: private:
+ friend class ModListProxy;
friend class ModListByPriorityProxy;
OrganizerCore *m_Organizer;
diff --git a/src/modlistbypriorityproxy.cpp b/src/modlistbypriorityproxy.cpp index eb931aa9..c4eb14b3 100644 --- a/src/modlistbypriorityproxy.cpp +++ b/src/modlistbypriorityproxy.cpp @@ -20,13 +20,17 @@ void ModListByPriorityProxy::setSourceModel(QAbstractItemModel* model) if (sourceModel()) { m_CollapsedItems.clear(); - connect(sourceModel(), &QAbstractItemModel::layoutChanged, this, &ModListByPriorityProxy::buildTree, Qt::UniqueConnection); connect(sourceModel(), &QAbstractItemModel::rowsRemoved, this, [this]() { buildTree(); }, Qt::UniqueConnection); - connect(sourceModel(), &QAbstractItemModel::modelReset, this, &ModListByPriorityProxy::buildTree, Qt::UniqueConnection); - buildTree(); + // connect(sourceModel(), &QAbstractItemModel::modelReset, this, &ModListByPriorityProxy::buildTree, Qt::UniqueConnection); + refresh(); } } +void ModListByPriorityProxy::refresh() +{ + buildTree(); +} + void ModListByPriorityProxy::buildTree() { if (!sourceModel()) return; diff --git a/src/modlistbypriorityproxy.h b/src/modlistbypriorityproxy.h index 725a3242..19d79f7f 100644 --- a/src/modlistbypriorityproxy.h +++ b/src/modlistbypriorityproxy.h @@ -26,6 +26,7 @@ public: ~ModListByPriorityProxy(); void setProfile(Profile* profile) { m_Profile = profile; } + void refresh(); void setSourceModel(QAbstractItemModel* sourceModel) override; diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 454247b6..159296b7 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -255,8 +255,6 @@ void OrganizerCore::setUserInterface(IUserInterface* ui) SLOT(clearOverwrite())); connect(&m_ModList, SIGNAL(fileMoved(QString, QString, QString)), w, SLOT(fileMoved(QString, QString, QString))); - connect(&m_ModList, SIGNAL(modorder_changed()), w, - SLOT(modorder_changed())); connect(&m_PluginList, SIGNAL(writePluginsList()), w, SLOT(esplist_changed())); connect(&m_PluginList, SIGNAL(esplist_changed()), w, |
