summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMikaël Capelle <capelle.mikael@gmail.com>2020-12-31 13:25:42 +0100
committerMikaël Capelle <capelle.mikael@gmail.com>2021-01-02 15:38:17 +0100
commita19ede5b6faaf8bf5299ae02da92e8d604e39468 (patch)
tree7bc4ed2a98fffcd49e5c77c2309465019f20a4da /src
parenta105e4c8c881ac720c41ef342769adee14caca47 (diff)
Move filter list to ModListView.
Diffstat (limited to 'src')
-rw-r--r--src/filterlist.cpp6
-rw-r--r--src/filterlist.h4
-rw-r--r--src/mainwindow.cpp109
-rw-r--r--src/mainwindow.h8
-rw-r--r--src/modlistview.cpp122
-rw-r--r--src/modlistview.h23
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;