From a19ede5b6faaf8bf5299ae02da92e8d604e39468 Mon Sep 17 00:00:00 2001 From: Mikaƫl Capelle Date: Thu, 31 Dec 2020 13:25:42 +0100 Subject: Move filter list to ModListView. --- src/filterlist.cpp | 6 +-- src/filterlist.h | 4 +- src/mainwindow.cpp | 109 ++-------------------------------------------- src/mainwindow.h | 8 ---- src/modlistview.cpp | 122 ++++++++++++++++++++++++++++++++++++++++++++++------ src/modlistview.h | 23 +++++++++- 6 files changed, 140 insertions(+), 132 deletions(-) (limited to 'src') diff --git a/src/filterlist.cpp b/src/filterlist.cpp index 2b72c152..c3f169a6 100644 --- a/src/filterlist.cpp +++ b/src/filterlist.cpp @@ -181,8 +181,8 @@ private: }; -FilterList::FilterList(Ui::MainWindow* ui, OrganizerCore* organizer, CategoryFactory& factory) - : ui(ui), m_Organizer(organizer), m_factory(factory) +FilterList::FilterList(Ui::MainWindow* ui, OrganizerCore& core, CategoryFactory& factory) + : ui(ui), m_core(core), m_factory(factory) { auto* eventFilter = new CriteriaItemFilter( ui->filters, [&](auto* item, int dir){ return cycleItem(item, dir); }); @@ -234,7 +234,7 @@ QTreeWidgetItem* FilterList::addCriteriaItem( void FilterList::addContentCriteria() { - m_Organizer->modDataContents().forEachContent([this](auto const& content) { + m_core.modDataContents().forEachContent([this](auto const& content) { addCriteriaItem( nullptr, QString("<%1>").arg(tr("Contains %1").arg(content.name())), content.id(), ModListSortProxy::TypeContent); diff --git a/src/filterlist.h b/src/filterlist.h index ba9dc71c..0788d224 100644 --- a/src/filterlist.h +++ b/src/filterlist.h @@ -14,7 +14,7 @@ class FilterList : public QObject Q_OBJECT; public: - FilterList(Ui::MainWindow* ui, OrganizerCore *organizer, CategoryFactory& factory); + FilterList(Ui::MainWindow* ui, OrganizerCore& organizer, CategoryFactory& factory); void restoreState(const Settings& s); void saveState(Settings& s) const; @@ -32,7 +32,7 @@ private: class CriteriaItem; Ui::MainWindow* ui; - OrganizerCore* m_Organizer; + OrganizerCore& m_core; CategoryFactory& m_factory; bool onClick(QMouseEvent* e); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 3d509379..df4a875e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -310,16 +310,6 @@ MainWindow::MainWindow(Settings &settings ui->statusBar->setAPI(ni.getAPIStats(), ni.getAPIUserAccount()); } - m_Filters.reset(new FilterList(ui, &m_OrganizerCore, m_CategoryFactory)); - - connect( - m_Filters.get(), &FilterList::criteriaChanged, - [&](auto&& v) { onFiltersCriteria(v); }); - - connect( - m_Filters.get(), &FilterList::optionsChanged, - [&](auto&& mode, auto&& sep) { onFiltersOptions(mode, sep); }); - ui->logList->setCore(m_OrganizerCore); @@ -532,7 +522,7 @@ MainWindow::MainWindow(Settings &settings void MainWindow::setupModList() { - ui->modList->setup(m_OrganizerCore, m_CategoryFactory, *m_Filters, this, ui); + ui->modList->setup(m_OrganizerCore, m_CategoryFactory, this, ui); connect(&ui->modList->actions(), &ModListViewActions::overwriteCleared, [=]() { scheduleCheckForProblems(); }); connect(&ui->modList->actions(), &ModListViewActions::originModified, this, &MainWindow::originModified); @@ -1224,7 +1214,7 @@ void MainWindow::showEvent(QShowEvent *event) if (!m_WasVisible) { readSettings(); - refreshFilters(); + ui->modList->refreshFilters(); // this needs to be connected here instead of in the constructor because the // actual changing of the stylesheet is done by MOApplication, which @@ -1952,11 +1942,9 @@ void MainWindow::readSettings() ui->executablesListBox->setCurrentIndex(*v); } - s.widgets().restoreIndex(ui->groupCombo); s.widgets().restoreIndex(ui->tabWidget); - s.widgets().restoreTreeState(ui->modList); - m_Filters->restoreState(s); + ui->modList->restoreState(s); { s.geometry().restoreVisibility(ui->categoriesGroup, false); @@ -2027,14 +2015,10 @@ void MainWindow::storeSettings() s.geometry().saveState(ui->espList->header()); s.geometry().saveState(ui->downloadView->header()); - s.geometry().saveState(ui->modList->header()); - s.widgets().saveTreeState(ui->modList); - s.widgets().saveIndex(ui->groupCombo); s.widgets().saveIndex(ui->executablesListBox); s.widgets().saveIndex(ui->tabWidget); - m_Filters->saveState(s); m_DataTab->saveState(s); s.interface().setFilterOptions(FilterWidget::options()); @@ -2340,20 +2324,6 @@ void MainWindow::modlistChanged(const QModelIndexList&, int) 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(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()); - } else { - m_OrganizerCore.modList()->setOverwriteMarkers(std::set(), std::set()); - m_OrganizerCore.modList()->setArchiveOverwriteMarkers(std::set(), std::set()); - m_OrganizerCore.modList()->setArchiveLooseOverwriteMarkers(std::set(), std::set()); - } - ui->modList->verticalScrollBar()->repaint(); - m_OrganizerCore.pluginList()->highlightPlugins(ui->modList->selectionModel(), *m_OrganizerCore.directoryStructure(), *m_OrganizerCore.currentProfile()); ui->espList->verticalScrollBar()->repaint(); } @@ -2823,7 +2793,7 @@ void MainWindow::on_actionSettings_triggered() scheduleCheckForProblems(); fixCategories(); - refreshFilters(); + ui->modList->refreshFilters(); ui->modList->refresh(); if (settings.paths().profiles() != oldProfilesDirectory) { @@ -2963,7 +2933,6 @@ void MainWindow::originModified(int originID) DirectoryRefresher::cleanStructure(m_OrganizerCore.directoryStructure()); } - void MainWindow::enableSelectedPlugins_clicked() { m_OrganizerCore.pluginList()->enableSelected(ui->espList->selectionModel()); @@ -3606,70 +3575,6 @@ void MainWindow::on_displayCategoriesBtn_toggled(bool checked) setCategoryListVisible(checked); } -void MainWindow::deselectFilters() -{ - m_Filters->clearSelection(); -} - -void MainWindow::refreshFilters() -{ - QItemSelection currentSelection = ui->modList->selectionModel()->selection(); - - int idxRow = ui->modList->currentIndex().row(); - QVariant currentIndexName = ui->modList->model()->index(idxRow, 0).data(); - ui->modList->setCurrentIndex(QModelIndex()); - - m_Filters->refresh(); - - ui->modList->selectionModel()->select(currentSelection, QItemSelectionModel::Select); - - QModelIndexList matchList; - if (currentIndexName.isValid()) { - matchList = ui->modList->model()->match( - ui->modList->model()->index(0, 0), - Qt::DisplayRole, - currentIndexName); - } - - if (matchList.size() > 0) { - ui->modList->setCurrentIndex(matchList.at(0)); - } -} - -void MainWindow::onFiltersCriteria(const std::vector& criteria) -{ - ui->modList->setFilterCriteria(criteria); - - QString label = "?"; - - if (criteria.empty()) { - label = ""; - } else if (criteria.size() == 1) { - const auto& c = criteria[0]; - - if (c.type == ModListSortProxy::TypeContent) { - const auto *content = m_OrganizerCore.modDataContents().findById(c.id); - label = content ? content->name() : QString(); - } else { - label = m_CategoryFactory.getCategoryNameByID(c.id); - } - - if (label.isEmpty()) { - log::error("category {}:{} not found", c.type, c.id); - } - } else { - label = tr(""); - } - - ui->currentCategoryLabel->setText(label); -} - -void MainWindow::onFiltersOptions( - ModListSortProxy::FilterMode mode, ModListSortProxy::SeparatorsMode sep) -{ - ui->modList->setFilterOptions(mode, sep); -} - void MainWindow::updateESPLock(int espIndex, bool locked) { QItemSelection currentSelection = ui->espList->selectionModel()->selection(); @@ -4079,9 +3984,3 @@ void MainWindow::keyReleaseEvent(QKeyEvent *event) QMainWindow::keyReleaseEvent(event); } - -void MainWindow::on_clearFiltersButton_clicked() -{ - ui->modFilterEdit->clear(); - deselectFilters(); -} diff --git a/src/mainwindow.h b/src/mainwindow.h index d80f4f63..d07fe54c 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -149,7 +149,6 @@ public slots: void directory_refreshed(); void updatePluginCount(); - void refreshFilters(); signals: @@ -253,7 +252,6 @@ private: MOBase::TutorialControl m_Tutorial; - std::unique_ptr m_Filters; std::unique_ptr m_DataTab; std::unique_ptr m_DownloadsTab; std::unique_ptr m_SavesTab; @@ -370,11 +368,6 @@ private slots: void onRequestsChanged(const APIStats& stats, const APIUserAccount& user); - void deselectFilters(); - void onFiltersCriteria(const std::vector& filters); - void onFiltersOptions( - ModListSortProxy::FilterMode mode, ModListSortProxy::SeparatorsMode sep); - void modRenamed(const QString &oldName, const QString &newName); void modRemoved(const QString &fileName); @@ -457,7 +450,6 @@ private slots: // ui slots void on_centralWidget_customContextMenuRequested(const QPoint &pos); void on_bsaList_customContextMenuRequested(const QPoint &pos); - void on_clearFiltersButton_clicked(); void on_executablesListBox_currentIndexChanged(int index); void on_espList_doubleClicked(const QModelIndex &index); void on_profileBox_currentIndexChanged(int index); diff --git a/src/modlistview.cpp b/src/modlistview.cpp index f2b83beb..fe2517c2 100644 --- a/src/modlistview.cpp +++ b/src/modlistview.cpp @@ -10,6 +10,7 @@ #include "ui_mainwindow.h" +#include "filterlist.h" #include "organizercore.h" #include "modlist.h" #include "modlistsortproxy.h" @@ -327,6 +328,20 @@ QModelIndexList ModListView::allIndex( return index; } +std::pair ModListView::selected() const +{ + return { indexViewToModel(currentIndex()), indexViewToModel(selectionModel()->selectedRows()) }; +} + +void ModListView::setSelected(const QModelIndex& current, const QModelIndexList& selected) +{ + // reset the selection and the index + setCurrentIndex(indexModelToView(current)); + for (auto idx : selected) { + selectionModel()->select(indexModelToView(idx), QItemSelectionModel::Select | QItemSelectionModel::Rows); + } +} + void ModListView::expandItem(const QModelIndex& index) { if (index.model() == m_sortProxy->sourceModel()) { expand(m_sortProxy->mapFromSource(index)); @@ -515,6 +530,19 @@ void ModListView::updateModCount() ); } +void ModListView::refreshFilters() +{ + auto [current, sourceRows] = selected(); + + int idxRow = currentIndex().row(); + QVariant currentIndexName = model()->index(idxRow, 0).data(); + setCurrentIndex(QModelIndex()); + + m_filters->refresh(); + + setSelected(current, sourceRows); +} + void ModListView::onExternalFolderDropped(const QUrl& url, int priority) { QFileInfo fileInfo(url.toLocalFile()); @@ -557,8 +585,7 @@ void ModListView::onExternalFolderDropped(const QUrl& url, int priority) bool ModListView::moveSelection(int key) { - QModelIndex cindex = indexViewToModel(currentIndex()); - QModelIndexList sourceRows = indexViewToModel(selectionModel()->selectedRows()); + auto [cindex, sourceRows] = selected(); int offset = key == Qt::Key_Up ? -1 : 1; if (m_sortProxy->sortOrder() == Qt::DescendingOrder) { @@ -568,10 +595,7 @@ bool ModListView::moveSelection(int key) m_core->modList()->shiftModsPriority(sourceRows, offset); // reset the selection and the index - setCurrentIndex(indexModelToView(cindex)); - for (auto idx : sourceRows) { - selectionModel()->select(indexModelToView(idx), QItemSelectionModel::Select | QItemSelectionModel::Rows); - } + setSelected(cindex, sourceRows); return true; } @@ -620,14 +644,14 @@ void ModListView::updateGroupByProxy(int groupIndex) } } - -void ModListView::setup(OrganizerCore& core, CategoryFactory& factory, FilterList& filters, MainWindow* mw, Ui::MainWindow* mwui) +void ModListView::setup(OrganizerCore& core, CategoryFactory& factory, MainWindow* mw, Ui::MainWindow* mwui) { // attributes m_core = &core; + m_filters.reset(new FilterList(mwui, core, factory)); m_categories = &factory; - m_actions = new ModListViewActions(core, filters, factory, mw, this); - ui = { mwui->groupCombo, mwui->activeModsCounter, mwui->modFilterEdit, mwui->clearFiltersButton }; + m_actions = new ModListViewActions(core, *m_filters, factory, mw, this); + ui = { mwui->groupCombo, mwui->activeModsCounter, mwui->modFilterEdit, mwui->currentCategoryLabel, mwui->clearFiltersButton }; connect(m_core, &OrganizerCore::modInstalled, this, &ModListView::onModInstalled); connect(core.modList(), &ModList::modPrioritiesChanged, this, &ModListView::onModPrioritiesChanged); @@ -724,13 +748,41 @@ void ModListView::setup(OrganizerCore& core, CategoryFactory& factory, FilterLis connect(m_core->modList(), &ModList::externalFolderDropped, this, &ModListView::onExternalFolderDropped); connect(m_sortProxy, &ModListSortProxy::filterActive, this, &ModListView::onModFilterActive); - connect(ui.filter, &QLineEdit::textChanged, m_sortProxy, &ModListSortProxy::updateFilter); connect(m_sortProxy, &QAbstractItemModel::layoutChanged, this, [&]() { if (hasCollapsibleSeparators()) { m_byPriorityProxy->refreshExpandedItems(); } - }); + }); connect(selectionModel(), &QItemSelectionModel::selectionChanged, this, &ModListView::onSelectionChanged); + + // filters + connect(m_filters.get(), &FilterList::criteriaChanged, [=](auto&& v) { onFiltersCriteria(v); }); + connect(m_filters.get(), &FilterList::optionsChanged, [=](auto&& mode, auto&& sep) { setFilterOptions(mode, sep); }); + connect(ui.filter, &QLineEdit::textChanged, m_sortProxy, &ModListSortProxy::updateFilter); + connect(ui.clearFilters, &QPushButton::clicked, [=]() { + ui.filter->clear(); + m_filters->clearSelection(); + }); +} + +void ModListView::restoreState(const Settings& s) +{ + s.geometry().restoreState(header()); + + s.widgets().restoreIndex(ui.groupBy); + s.widgets().restoreTreeState(this); + + m_filters->restoreState(s); +} + +void ModListView::saveState(Settings& s) const +{ + s.geometry().saveState(header()); + + s.widgets().saveIndex(ui.groupBy); + s.widgets().saveTreeState(this); + + m_filters->saveState(s); } void ModListView::setModel(QAbstractItemModel* model) @@ -858,6 +910,52 @@ void ModListView::onSelectionChanged(const QItemSelection& selected, const QItem } } } + + if (selected.count()) { + auto index = selected.indexes().last(); + ModInfo::Ptr selectedMod = ModInfo::getByIndex(index.data(ModList::IndexRole).toInt()); + m_core->modList()->setOverwriteMarkers(selectedMod->getModOverwrite(), selectedMod->getModOverwritten()); + m_core->modList()->setArchiveOverwriteMarkers(selectedMod->getModArchiveOverwrite(), selectedMod->getModArchiveOverwritten()); + m_core->modList()->setArchiveLooseOverwriteMarkers(selectedMod->getModArchiveLooseOverwrite(), selectedMod->getModArchiveLooseOverwritten()); + } + else { + m_core->modList()->setOverwriteMarkers({}, {}); + m_core->modList()->setArchiveOverwriteMarkers({}, {}); + m_core->modList()->setArchiveLooseOverwriteMarkers({}, {}); + } + verticalScrollBar()->repaint(); + +} + +void ModListView::onFiltersCriteria(const std::vector& criteria) +{ + setFilterCriteria(criteria); + + QString label = "?"; + + if (criteria.empty()) { + label = ""; + } + else if (criteria.size() == 1) { + const auto& c = criteria[0]; + + if (c.type == ModListSortProxy::TypeContent) { + const auto* content = m_core->modDataContents().findById(c.id); + label = content ? content->name() : QString(); + } + else { + label = m_categories->getCategoryNameByID(c.id); + } + + if (label.isEmpty()) { + log::error("category {}:{} not found", c.type, c.id); + } + } + else { + label = tr(""); + } + + ui.currentCategory->setText(label); } void ModListView::dragEnterEvent(QDragEnterEvent* event) diff --git a/src/modlistview.h b/src/modlistview.h index c7f4e5f0..87d8eac5 100644 --- a/src/modlistview.h +++ b/src/modlistview.h @@ -3,6 +3,7 @@ #include +#include #include #include #include @@ -39,7 +40,12 @@ public: explicit ModListView(QWidget* parent = 0); void setModel(QAbstractItemModel* model) override; - void setup(OrganizerCore& core, CategoryFactory& factory, FilterList& filters, MainWindow* mw, Ui::MainWindow* mwui); + void setup(OrganizerCore& core, CategoryFactory& factory, MainWindow* mw, Ui::MainWindow* mwui); + + // restore/save the state between session + // + void restoreState(const Settings& s); + void saveState(Settings& s) const; // set the current profile // @@ -97,6 +103,10 @@ public slots: // void updateModCount(); + // refresh the filters + // + void refreshFilters(); + // map from/to the view indexes to the model // QModelIndex indexModelToView(const QModelIndex& index) const; @@ -142,6 +152,7 @@ protected slots: void onCustomContextMenuRequested(const QPoint& pos); void onDoubleClicked(const QModelIndex& index); void onSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected); + void onFiltersCriteria(const std::vector& filters); private: @@ -149,6 +160,12 @@ private: void onModInstalled(const QString& modName); void onModFilterActive(bool filterActive); + // 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 + // + std::pair selected() const; + void setSelected(const QModelIndex& current, const QModelIndexList& selected); + // call expand() after fixing the index if it comes from the source // of the proxy // @@ -175,12 +192,14 @@ private: // the mod counter QLCDNumber* counter; - // the text filter and clear filter button + // filters related QLineEdit* filter; + QLabel* currentCategory; QPushButton* clearFilters; }; OrganizerCore* m_core; + std::unique_ptr m_filters; CategoryFactory* m_categories; ModListViewUi ui; ModListViewActions* m_actions; -- cgit v1.3.1