summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorisanae <14251494+isanae@users.noreply.github.com>2019-11-29 23:50:33 -0500
committerisanae <14251494+isanae@users.noreply.github.com>2019-11-29 23:50:33 -0500
commit93318a1474031035da5e61ad199171cad5803c2f (patch)
treeddde0238c4453784949f3c6ee454675c953e6825 /src
parent4bbdbb000fd5051fe80b5dca21dda60910284333 (diff)
moved all remaining filter stuff to FilterList
renamed some widgets
Diffstat (limited to 'src')
-rw-r--r--src/categories.cpp34
-rw-r--r--src/categories.h2
-rw-r--r--src/filterlist.cpp135
-rw-r--r--src/filterlist.h6
-rw-r--r--src/mainwindow.cpp107
-rw-r--r--src/mainwindow.h7
-rw-r--r--src/mainwindow.ui12
7 files changed, 204 insertions, 99 deletions
diff --git a/src/categories.cpp b/src/categories.cpp
index 12b18998..082b4fbc 100644
--- a/src/categories.cpp
+++ b/src/categories.cpp
@@ -320,6 +320,40 @@ QString CategoryFactory::getCategoryName(unsigned int index) const
return m_Categories[index].m_Name;
}
+QString CategoryFactory::getSpecialCategoryName(int type) const
+{
+ switch (type)
+ {
+ case CATEGORY_SPECIAL_CHECKED: return QObject::tr("<Checked>");
+ case CATEGORY_SPECIAL_UNCHECKED: return QObject::tr("<Unchecked>");
+ case CATEGORY_SPECIAL_UPDATEAVAILABLE: return QObject::tr("<Update>");
+ case CATEGORY_SPECIAL_NOCATEGORY: return QObject::tr("<Mod Backup>");
+ case CATEGORY_SPECIAL_CONFLICT: return QObject::tr("<Managed by MO>");
+ case CATEGORY_SPECIAL_NOTENDORSED: return QObject::tr("<Managed outside MO>");
+ case CATEGORY_SPECIAL_BACKUP: return QObject::tr("<No category>");
+ case CATEGORY_SPECIAL_MANAGED: return QObject::tr("<Conflicted>");
+ case CATEGORY_SPECIAL_UNMANAGED: return QObject::tr("<Not Endorsed>");
+ case CATEGORY_SPECIAL_NOGAMEDATA: return QObject::tr("<No Nexus ID>");
+ case CATEGORY_SPECIAL_NONEXUSID: return QObject::tr("<No valid game data>");
+ default: return {};
+ }
+}
+
+QString CategoryFactory::getCategoryNameByID(int id) const
+{
+ auto itor = m_IDMap.find(id);
+
+ if (itor == m_IDMap.end()) {
+ return getSpecialCategoryName(id);
+ } else {
+ const auto index = itor->second;
+ if (index >= m_Categories.size()) {
+ return {};
+ }
+
+ return m_Categories[index].m_Name;
+ }
+}
int CategoryFactory::getCategoryID(unsigned int index) const
{
diff --git a/src/categories.h b/src/categories.h
index 67fee3e7..2041ce1f 100644
--- a/src/categories.h
+++ b/src/categories.h
@@ -144,6 +144,8 @@ public:
* @return QString name of the category
**/
QString getCategoryName(unsigned int index) const;
+ QString getSpecialCategoryName(int type) const;
+ QString getCategoryNameByID(int id) const;
/**
* @brief look up the id of a category by its index
diff --git a/src/filterlist.cpp b/src/filterlist.cpp
index 8ef4b62d..5562736d 100644
--- a/src/filterlist.cpp
+++ b/src/filterlist.cpp
@@ -9,13 +9,33 @@ using namespace MOBase;
FilterList::FilterList(Ui::MainWindow* ui, CategoryFactory& factory)
: ui(ui), m_factory(factory)
{
- QObject::connect(
- ui->categoriesList, &QTreeWidget::customContextMenuRequested,
+ connect(
+ ui->filters, &QTreeWidget::customContextMenuRequested,
[&](auto&& pos){ onContextMenu(pos); });
- QObject::connect(
- ui->categoriesList, &QTreeWidget::itemSelectionChanged,
+ connect(
+ ui->filters, &QTreeWidget::itemSelectionChanged,
[&]{ onSelection(); });
+
+ connect(
+ ui->filtersClear, &QPushButton::clicked,
+ [&]{ clearSelection(); });
+
+ connect(
+ ui->filtersAnd, &QCheckBox::toggled,
+ [&]{ onCriteriaChanged(); });
+
+ connect(
+ ui->filtersOr, &QCheckBox::toggled,
+ [&]{ onCriteriaChanged(); });
+
+ connect(
+ ui->filtersNot, &QCheckBox::toggled,
+ [&]{ onCriteriaChanged(); });
+
+ connect(
+ ui->filtersSeparators, &QCheckBox::toggled,
+ [&]{ onCriteriaChanged(); });
}
QTreeWidgetItem* FilterList::addFilterItem(
@@ -29,7 +49,7 @@ QTreeWidgetItem* FilterList::addFilterItem(
if (root != nullptr) {
root->addChild(item);
} else {
- ui->categoriesList->addTopLevelItem(item);
+ ui->filters->addTopLevelItem(item);
}
return item;
}
@@ -37,7 +57,9 @@ QTreeWidgetItem* FilterList::addFilterItem(
void FilterList::addContentFilters()
{
for (unsigned i = 0; i < ModInfo::NUM_CONTENT_TYPES; ++i) {
- addFilterItem(nullptr, tr("<Contains %1>").arg(ModInfo::getContentTypeName(i)), i, ModListSortProxy::TYPE_CONTENT);
+ addFilterItem(
+ nullptr, tr("<Contains %1>").arg(ModInfo::getContentTypeName(i)),
+ i, ModListSortProxy::TYPE_CONTENT);
}
}
@@ -59,32 +81,37 @@ void FilterList::addCategoryFilters(QTreeWidgetItem *root, const std::set<int> &
}
}
-void FilterList::refresh()
+void FilterList::addSpecialFilterItem(int type)
{
- QItemSelection currentSelection = ui->modList->selectionModel()->selection();
-
- QVariant currentIndexName = ui->modList->currentIndex().data();
- ui->modList->setCurrentIndex(QModelIndex());
+ addFilterItem(
+ nullptr, m_factory.getSpecialCategoryName(type),
+ type, ModListSortProxy::TYPE_SPECIAL);
+}
+void FilterList::refresh()
+{
QStringList selectedItems;
- for (QTreeWidgetItem *item : ui->categoriesList->selectedItems()) {
+ for (QTreeWidgetItem *item : ui->filters->selectedItems()) {
selectedItems.append(item->text(0));
}
- ui->categoriesList->clear();
- addFilterItem(nullptr, tr("<Checked>"), CategoryFactory::CATEGORY_SPECIAL_CHECKED, ModListSortProxy::TYPE_SPECIAL);
- addFilterItem(nullptr, tr("<Unchecked>"), CategoryFactory::CATEGORY_SPECIAL_UNCHECKED, ModListSortProxy::TYPE_SPECIAL);
- addFilterItem(nullptr, tr("<Update>"), CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE, ModListSortProxy::TYPE_SPECIAL);
- addFilterItem(nullptr, tr("<Mod Backup>"), CategoryFactory::CATEGORY_SPECIAL_BACKUP, ModListSortProxy::TYPE_SPECIAL);
- addFilterItem(nullptr, tr("<Managed by MO>"), CategoryFactory::CATEGORY_SPECIAL_MANAGED, ModListSortProxy::TYPE_SPECIAL);
- addFilterItem(nullptr, tr("<Managed outside MO>"), CategoryFactory::CATEGORY_SPECIAL_UNMANAGED, ModListSortProxy::TYPE_SPECIAL);
- addFilterItem(nullptr, tr("<No category>"), CategoryFactory::CATEGORY_SPECIAL_NOCATEGORY, ModListSortProxy::TYPE_SPECIAL);
- addFilterItem(nullptr, tr("<Conflicted>"), CategoryFactory::CATEGORY_SPECIAL_CONFLICT, ModListSortProxy::TYPE_SPECIAL);
- addFilterItem(nullptr, tr("<Not Endorsed>"), CategoryFactory::CATEGORY_SPECIAL_NOTENDORSED, ModListSortProxy::TYPE_SPECIAL);
- addFilterItem(nullptr, tr("<No Nexus ID>"), CategoryFactory::CATEGORY_SPECIAL_NONEXUSID, ModListSortProxy::TYPE_SPECIAL);
- addFilterItem(nullptr, tr("<No valid game data>"), CategoryFactory::CATEGORY_SPECIAL_NOGAMEDATA, ModListSortProxy::TYPE_SPECIAL);
+ ui->filters->clear();
+
+ using F = CategoryFactory;
+ addSpecialFilterItem(F::CATEGORY_SPECIAL_CHECKED);
+ addSpecialFilterItem(F::CATEGORY_SPECIAL_UNCHECKED);
+ addSpecialFilterItem(F::CATEGORY_SPECIAL_UPDATEAVAILABLE);
+ addSpecialFilterItem(F::CATEGORY_SPECIAL_BACKUP);
+ addSpecialFilterItem(F::CATEGORY_SPECIAL_MANAGED);
+ addSpecialFilterItem(F::CATEGORY_SPECIAL_UNMANAGED);
+ addSpecialFilterItem(F::CATEGORY_SPECIAL_NOCATEGORY);
+ addSpecialFilterItem(F::CATEGORY_SPECIAL_CONFLICT);
+ addSpecialFilterItem(F::CATEGORY_SPECIAL_NOTENDORSED);
+ addSpecialFilterItem(F::CATEGORY_SPECIAL_NONEXUSID);
+ addSpecialFilterItem(F::CATEGORY_SPECIAL_NOGAMEDATA);
addContentFilters();
+
std::set<int> categoriesUsed;
for (unsigned int modIdx = 0; modIdx < ModInfo::getNumMods(); ++modIdx) {
ModInfo::Ptr modInfo = ModInfo::getByIndex(modIdx);
@@ -106,27 +133,20 @@ void FilterList::refresh()
addCategoryFilters(nullptr, categoriesUsed, 0);
for (const QString &item : selectedItems) {
- QList<QTreeWidgetItem*> matches = ui->categoriesList->findItems(item, Qt::MatchFixedString | Qt::MatchRecursive);
+ QList<QTreeWidgetItem*> matches = ui->filters->findItems(
+ item, Qt::MatchFixedString | Qt::MatchRecursive);
+
if (matches.size() > 0) {
matches.at(0)->setSelected(true);
}
}
- 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 FilterList::setSelection(std::vector<int> categories)
{
- for (int i = 0; i < ui->categoriesList->topLevelItemCount(); ++i) {
- if (ui->categoriesList->topLevelItem(i)->data(0, Qt::UserRole) == CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE) {
- ui->categoriesList->setCurrentItem(ui->categoriesList->topLevelItem(i));
+ for (int i = 0; i < ui->filters->topLevelItemCount(); ++i) {
+ if (ui->filters->topLevelItem(i)->data(0, Qt::UserRole) == CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE) {
+ ui->filters->setCurrentItem(ui->filters->topLevelItem(i));
break;
}
}
@@ -134,40 +154,32 @@ void FilterList::setSelection(std::vector<int> categories)
void FilterList::clearSelection()
{
- ui->categoriesList->clearSelection();
+ ui->filters->clearSelection();
}
void FilterList::onSelection()
{
- QModelIndexList indices = ui->categoriesList->selectionModel()->selectedRows();
+ QModelIndexList indices = ui->filters->selectionModel()->selectedRows();
std::vector<int> categories;
std::vector<int> content;
+
for (const QModelIndex &index : indices) {
- int filterType = index.data(Qt::UserRole + 1).toInt();
- if ((filterType == ModListSortProxy::TYPE_CATEGORY)
- || (filterType == ModListSortProxy::TYPE_SPECIAL)) {
- int categoryId = index.data(Qt::UserRole).toInt();
+ const int filterType = index.data(Qt::UserRole + 1).toInt();
+
+ if ((filterType == ModListSortProxy::TYPE_CATEGORY) || (filterType == ModListSortProxy::TYPE_SPECIAL)) {
+ const int categoryId = index.data(Qt::UserRole).toInt();
if (categoryId != CategoryFactory::CATEGORY_NONE) {
categories.push_back(categoryId);
}
} else if (filterType == ModListSortProxy::TYPE_CONTENT) {
- int contentId = index.data(Qt::UserRole).toInt();
+ const int contentId = index.data(Qt::UserRole).toInt();
content.push_back(contentId);
}
}
- emit changed(categories, content);
-
- ui->clickBlankButton->setEnabled(categories.size() > 0 || content.size() >0);
+ ui->filtersClear->setEnabled(categories.size() > 0 || content.size() >0);
- if (indices.count() == 0) {
- ui->currentCategoryLabel->setText(QString("(%1)").arg(tr("<All>")));
- } else if (indices.count() > 1) {
- ui->currentCategoryLabel->setText(QString("(%1)").arg(tr("<Multiple>")));
- } else {
- ui->currentCategoryLabel->setText(QString("(%1)").arg(indices.first().data().toString()));
- }
- ui->modList->reset();
+ emit filtersChanged(categories, content);
}
void FilterList::onContextMenu(const QPoint &pos)
@@ -176,7 +188,7 @@ void FilterList::onContextMenu(const QPoint &pos)
menu.addAction(tr("Edit Categories..."), [&]{ editCategories(); });
menu.addAction(tr("Deselect filter"), [&]{ clearSelection(); });
- menu.exec(ui->categoriesList->viewport()->mapToGlobal(pos));
+ menu.exec(ui->filters->viewport()->mapToGlobal(pos));
}
void FilterList::editCategories()
@@ -187,3 +199,14 @@ void FilterList::editCategories()
dialog.commitChanges();
}
}
+
+void FilterList::onCriteriaChanged()
+{
+ const auto mode = ui->filtersAnd->isChecked() ?
+ ModListSortProxy::FILTER_AND : ModListSortProxy::FILTER_OR;
+
+ const bool inverse = ui->filtersNot->isChecked();
+ const bool separators = ui->filtersSeparators->isChecked();
+
+ emit criteriaChanged(mode, inverse, separators);
+}
diff --git a/src/filterlist.h b/src/filterlist.h
index ca74021a..85982392 100644
--- a/src/filterlist.h
+++ b/src/filterlist.h
@@ -19,7 +19,8 @@ public:
void refresh();
signals:
- void changed(std::vector<int> categories, std::vector<int> content);
+ void filtersChanged(std::vector<int> categories, std::vector<int> content);
+ void criteriaChanged(ModListSortProxy::FilterMode mode, bool inverse, bool separators);
private:
Ui::MainWindow* ui;
@@ -27,6 +28,7 @@ private:
void onContextMenu(const QPoint &pos);
void onSelection();
+ void onCriteriaChanged();
void editCategories();
@@ -37,6 +39,8 @@ private:
void addContentFilters();
void addCategoryFilters(
QTreeWidgetItem *root, const std::set<int> &categoriesUsed, int targetID);
+ void addSpecialFilterItem(int type);
+
};
#endif // MODORGANIZER_CATEGORIESLIST_INCLUDED
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index b63f9211..1319d906 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -262,10 +262,14 @@ MainWindow::MainWindow(Settings &settings
m_CategoryFactory.loadCategories();
m_Filters.reset(new FilterList(ui, m_CategoryFactory));
- connect(m_Filters.get(), &FilterList::changed, [&](auto&& cats, auto&& content) {
- m_ModListSortProxy->setCategoryFilter(cats);
- m_ModListSortProxy->setContentFilter(content);
- });
+
+ connect(
+ m_Filters.get(), &FilterList::filtersChanged,
+ [&](auto&& cats, auto&& content) { onFilters(cats, content); });
+
+ connect(
+ m_Filters.get(), &FilterList::criteriaChanged,
+ [&](auto mode, bool inv, bool sep) { onFiltersCriteria(mode, inv, sep); });
ui->logList->setCore(m_OrganizerCore);
@@ -1229,7 +1233,7 @@ void MainWindow::showEvent(QShowEvent *event)
if (!m_WasVisible) {
readSettings();
- m_Filters->refresh();
+ refreshFilters();
// this needs to be connected here instead of in the constructor because the
// actual changing of the stylesheet is done by MOApplication, which
@@ -4025,7 +4029,7 @@ void MainWindow::addRemoveCategories_MenuHandler() {
m_OrganizerCore.modList()->notifyChange(m_ContextRow);
}
- m_Filters->refresh();
+ refreshFilters();
}
void MainWindow::replaceCategories_MenuHandler() {
@@ -4069,7 +4073,7 @@ void MainWindow::replaceCategories_MenuHandler() {
m_OrganizerCore.modList()->notifyChange(m_ContextRow);
}
- m_Filters->refresh();
+ refreshFilters();
}
void MainWindow::saveArchiveList()
@@ -4936,7 +4940,7 @@ void MainWindow::on_actionSettings_triggered()
instManager->setDownloadDirectory(settings.paths().downloads());
fixCategories();
- m_Filters->refresh();
+ refreshFilters();
if (settings.paths().profiles() != oldProfilesDirectory) {
refreshProfiles();
@@ -6083,6 +6087,69 @@ void MainWindow::deselectFilters()
m_Filters->clearSelection();
}
+void MainWindow::refreshFilters()
+{
+ QItemSelection currentSelection = ui->modList->selectionModel()->selection();
+
+ QVariant currentIndexName = ui->modList->currentIndex().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::onFilters(
+ const std::vector<int>& categories, const std::vector<int>& content)
+{
+ m_ModListSortProxy->setCategoryFilter(categories);
+ m_ModListSortProxy->setContentFilter(content);
+
+ QString label = "?";
+
+ if ((categories.size() + content.size()) > 1) {
+ label = tr("<Multiple>");
+ } else if (!categories.empty()) {
+ const int c = categories[0];
+ label = m_CategoryFactory.getCategoryNameByID(c);
+ if (label.isEmpty()) {
+ log::error("category '{}' not found", c);
+ }
+ } else if (!content.empty()) {
+ const int c = content[0];
+ try {
+ label = ModInfo::getContentTypeName(c);
+ }
+ catch(std::exception&) {
+ log::error("content filter '{}' not found", c);
+ }
+ } else {
+ label = "";
+ }
+
+ ui->currentCategoryLabel->setText(label);
+ ui->modList->reset();
+}
+
+void MainWindow::onFiltersCriteria(
+ ModListSortProxy::FilterMode mode, bool inverse, bool separators)
+{
+ m_ModListSortProxy->setFilterMode(mode);
+ m_ModListSortProxy->setFilterNot(inverse);
+ m_ModListSortProxy->setFilterSeparators(separators);
+}
void MainWindow::updateESPLock(bool locked)
{
@@ -6385,30 +6452,6 @@ void MainWindow::on_restoreModsButton_clicked()
}
}
-void MainWindow::on_categoriesAndBtn_toggled(bool checked)
-{
- if (checked) {
- m_ModListSortProxy->setFilterMode(ModListSortProxy::FILTER_AND);
- }
-}
-
-void MainWindow::on_categoriesOrBtn_toggled(bool checked)
-{
- if (checked) {
- m_ModListSortProxy->setFilterMode(ModListSortProxy::FILTER_OR);
- }
-}
-
-void MainWindow::on_categoriesNotBtn_toggled(bool checked)
-{
- m_ModListSortProxy->setFilterNot(checked);
-}
-
-void MainWindow::on_categoriesSeparators_toggled(bool checked)
-{
- m_ModListSortProxy->setFilterSeparators(checked);
-}
-
void MainWindow::on_managedArchiveLabel_linkHovered(const QString&)
{
QToolTip::showText(QCursor::pos(),
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 04ba7a35..9837378b 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -513,6 +513,9 @@ private slots:
void onRequestsChanged(const APIStats& stats, const APIUserAccount& user);
void deselectFilters();
+ void refreshFilters();
+ void onFilters(const std::vector<int>& categories, const std::vector<int>& content);
+ void onFiltersCriteria(ModListSortProxy::FilterMode mode, bool inverse, bool separators);
void displayModInformation(const QString &modName, ModInfoTabIDs tabID);
@@ -651,10 +654,6 @@ private slots: // ui slots
void on_restoreButton_clicked();
void on_restoreModsButton_clicked();
void on_saveModsButton_clicked();
- void on_categoriesAndBtn_toggled(bool checked);
- void on_categoriesOrBtn_toggled(bool checked);
- void on_categoriesNotBtn_toggled(bool checked);
- void on_categoriesSeparators_toggled(bool checked);
void on_managedArchiveLabel_linkHovered(const QString &link);
void storeSettings();
diff --git a/src/mainwindow.ui b/src/mainwindow.ui
index 7e11c70e..ed35f783 100644
--- a/src/mainwindow.ui
+++ b/src/mainwindow.ui
@@ -66,7 +66,7 @@
<number>1</number>
</property>
<item>
- <widget class="QTreeWidget" name="categoriesList">
+ <widget class="QTreeWidget" name="filters">
<property name="minimumSize">
<size>
<width>120</width>
@@ -96,7 +96,7 @@
</widget>
</item>
<item>
- <widget class="QPushButton" name="clickBlankButton">
+ <widget class="QPushButton" name="filtersClear">
<property name="enabled">
<bool>false</bool>
</property>
@@ -130,7 +130,7 @@
</property>
<layout class="QHBoxLayout" name="horizontalLayout_11">
<item>
- <widget class="QRadioButton" name="categoriesAndBtn">
+ <widget class="QRadioButton" name="filtersAnd">
<property name="toolTip">
<string>Display mods that match all selected categories.</string>
</property>
@@ -143,7 +143,7 @@
</widget>
</item>
<item>
- <widget class="QRadioButton" name="categoriesOrBtn">
+ <widget class="QRadioButton" name="filtersOr">
<property name="toolTip">
<string>Display mods that match at least one of the selected categories</string>
</property>
@@ -153,7 +153,7 @@
</widget>
</item>
<item>
- <widget class="QCheckBox" name="categoriesNotBtn">
+ <widget class="QCheckBox" name="filtersNot">
<property name="toolTip">
<string>Invert each selected category</string>
</property>
@@ -163,7 +163,7 @@
</widget>
</item>
<item>
- <widget class="QCheckBox" name="categoriesSeparators">
+ <widget class="QCheckBox" name="filtersSeparators">
<property name="toolTip">
<string>Include separators</string>
</property>