diff options
| author | Mikaël Capelle <capelle.mikael@gmail.com> | 2020-12-31 13:25:42 +0100 |
|---|---|---|
| committer | Mikaël Capelle <capelle.mikael@gmail.com> | 2021-01-02 15:38:17 +0100 |
| commit | a19ede5b6faaf8bf5299ae02da92e8d604e39468 (patch) | |
| tree | 7bc4ed2a98fffcd49e5c77c2309465019f20a4da | |
| parent | a105e4c8c881ac720c41ef342769adee14caca47 (diff) | |
Move filter list to ModListView.
| -rw-r--r-- | src/filterlist.cpp | 6 | ||||
| -rw-r--r-- | src/filterlist.h | 4 | ||||
| -rw-r--r-- | src/mainwindow.cpp | 109 | ||||
| -rw-r--r-- | src/mainwindow.h | 8 | ||||
| -rw-r--r-- | src/modlistview.cpp | 122 | ||||
| -rw-r--r-- | src/modlistview.h | 23 |
6 files changed, 140 insertions, 132 deletions
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<unsigned int>(), std::set<unsigned int>()); - m_OrganizerCore.modList()->setArchiveOverwriteMarkers(std::set<unsigned int>(), std::set<unsigned int>()); - m_OrganizerCore.modList()->setArchiveLooseOverwriteMarkers(std::set<unsigned int>(), std::set<unsigned int>()); - } - 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<ModListSortProxy::Criteria>& 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("<Multiple>"); - } - - 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<FilterList> m_Filters; std::unique_ptr<DataTab> m_DataTab; std::unique_ptr<DownloadsTab> m_DownloadsTab; std::unique_ptr<SavesTab> m_SavesTab; @@ -370,11 +368,6 @@ private slots: void onRequestsChanged(const APIStats& stats, const APIUserAccount& user); - void deselectFilters(); - void onFiltersCriteria(const std::vector<ModListSortProxy::Criteria>& 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<QModelIndex, QModelIndexList> 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<ModListSortProxy::Criteria>& 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("<Multiple>");
+ }
+
+ 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 <vector>
+#include <QLabel>
#include <QTreeView>
#include <QDragEnterEvent>
#include <QLCDNumber>
@@ -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<ModListSortProxy::Criteria>& 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<QModelIndex, QModelIndexList> 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<FilterList> m_filters;
CategoryFactory* m_categories;
ModListViewUi ui;
ModListViewActions* m_actions;
|
