diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2019-11-29 23:50:33 -0500 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2019-11-29 23:50:33 -0500 |
| commit | 93318a1474031035da5e61ad199171cad5803c2f (patch) | |
| tree | ddde0238c4453784949f3c6ee454675c953e6825 /src | |
| parent | 4bbdbb000fd5051fe80b5dca21dda60910284333 (diff) | |
moved all remaining filter stuff to FilterList
renamed some widgets
Diffstat (limited to 'src')
| -rw-r--r-- | src/categories.cpp | 34 | ||||
| -rw-r--r-- | src/categories.h | 2 | ||||
| -rw-r--r-- | src/filterlist.cpp | 135 | ||||
| -rw-r--r-- | src/filterlist.h | 6 | ||||
| -rw-r--r-- | src/mainwindow.cpp | 107 | ||||
| -rw-r--r-- | src/mainwindow.h | 7 | ||||
| -rw-r--r-- | src/mainwindow.ui | 12 |
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> |
