diff options
| author | isanae <14251494+isanae@users.noreply.github.com> | 2019-11-27 19:14:37 -0500 |
|---|---|---|
| committer | isanae <14251494+isanae@users.noreply.github.com> | 2019-11-27 19:14:37 -0500 |
| commit | 4bbdbb000fd5051fe80b5dca21dda60910284333 (patch) | |
| tree | 7e1068a2ef8df08e5340a943b9b85da52ca953f2 /src | |
| parent | 8ea346183fa432e4a16e604ae2fa03366c01c6af (diff) | |
split filter list
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | src/filterlist.cpp | 189 | ||||
| -rw-r--r-- | src/filterlist.h | 42 | ||||
| -rw-r--r-- | src/mainwindow.cpp | 177 | ||||
| -rw-r--r-- | src/mainwindow.h | 12 |
5 files changed, 249 insertions, 174 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e3a42409..a46908ef 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -144,6 +144,7 @@ SET(organizer_SRCS uilocker.cpp loot.cpp lootdialog.cpp + filterlist.cpp shared/windows_error.cpp shared/error_report.cpp @@ -268,6 +269,7 @@ SET(organizer_HDRS loot.h lootdialog.h json.h + filterlist.h shared/windows_error.h shared/error_report.h @@ -320,6 +322,7 @@ SET(organizer_RCS source_group(src REGULAR_EXPRESSION ".*\\.(h|cpp|ui)") set(application + filterlist iuserinterface main mainwindow diff --git a/src/filterlist.cpp b/src/filterlist.cpp new file mode 100644 index 00000000..8ef4b62d --- /dev/null +++ b/src/filterlist.cpp @@ -0,0 +1,189 @@ +#include "filterlist.h" +#include "ui_mainwindow.h" +#include "categories.h" +#include "categoriesdialog.h" +#include <utility.h> + +using namespace MOBase; + +FilterList::FilterList(Ui::MainWindow* ui, CategoryFactory& factory) + : ui(ui), m_factory(factory) +{ + QObject::connect( + ui->categoriesList, &QTreeWidget::customContextMenuRequested, + [&](auto&& pos){ onContextMenu(pos); }); + + QObject::connect( + ui->categoriesList, &QTreeWidget::itemSelectionChanged, + [&]{ onSelection(); }); +} + +QTreeWidgetItem* FilterList::addFilterItem( + QTreeWidgetItem *root, const QString &name, int categoryID, + ModListSortProxy::FilterType type) +{ + QTreeWidgetItem *item = new QTreeWidgetItem(QStringList(name)); + item->setData(0, Qt::ToolTipRole, name); + item->setData(0, Qt::UserRole, categoryID); + item->setData(0, Qt::UserRole + 1, type); + if (root != nullptr) { + root->addChild(item); + } else { + ui->categoriesList->addTopLevelItem(item); + } + return item; +} + +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); + } +} + +void FilterList::addCategoryFilters(QTreeWidgetItem *root, const std::set<int> &categoriesUsed, int targetID) +{ + for (unsigned int i = 1; + i < static_cast<unsigned int>(m_factory.numCategories()); ++i) { + if ((m_factory.getParentID(i) == targetID)) { + int categoryID = m_factory.getCategoryID(i); + if (categoriesUsed.find(categoryID) != categoriesUsed.end()) { + QTreeWidgetItem *item = + addFilterItem(root, m_factory.getCategoryName(i), + categoryID, ModListSortProxy::TYPE_CATEGORY); + if (m_factory.hasChildren(i)) { + addCategoryFilters(item, categoriesUsed, categoryID); + } + } + } + } +} + +void FilterList::refresh() +{ + QItemSelection currentSelection = ui->modList->selectionModel()->selection(); + + QVariant currentIndexName = ui->modList->currentIndex().data(); + ui->modList->setCurrentIndex(QModelIndex()); + + QStringList selectedItems; + for (QTreeWidgetItem *item : ui->categoriesList->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); + + addContentFilters(); + std::set<int> categoriesUsed; + for (unsigned int modIdx = 0; modIdx < ModInfo::getNumMods(); ++modIdx) { + ModInfo::Ptr modInfo = ModInfo::getByIndex(modIdx); + for (int categoryID : modInfo->getCategories()) { + int currentID = categoryID; + std::set<int> cycleTest; + // also add parents so they show up in the tree + while (currentID != 0) { + categoriesUsed.insert(currentID); + if (!cycleTest.insert(currentID).second) { + log::warn("cycle in categories: {}", SetJoin(cycleTest, ", ")); + break; + } + currentID = m_factory.getParentID(m_factory.getCategoryIndex(currentID)); + } + } + } + + addCategoryFilters(nullptr, categoriesUsed, 0); + + for (const QString &item : selectedItems) { + QList<QTreeWidgetItem*> matches = ui->categoriesList->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)); + break; + } + } +} + +void FilterList::clearSelection() +{ + ui->categoriesList->clearSelection(); +} + +void FilterList::onSelection() +{ + QModelIndexList indices = ui->categoriesList->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(); + if (categoryId != CategoryFactory::CATEGORY_NONE) { + categories.push_back(categoryId); + } + } else if (filterType == ModListSortProxy::TYPE_CONTENT) { + int contentId = index.data(Qt::UserRole).toInt(); + content.push_back(contentId); + } + } + + emit changed(categories, content); + + ui->clickBlankButton->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(); +} + +void FilterList::onContextMenu(const QPoint &pos) +{ + QMenu menu; + menu.addAction(tr("Edit Categories..."), [&]{ editCategories(); }); + menu.addAction(tr("Deselect filter"), [&]{ clearSelection(); }); + + menu.exec(ui->categoriesList->viewport()->mapToGlobal(pos)); +} + +void FilterList::editCategories() +{ + CategoriesDialog dialog(qApp->activeWindow()); + + if (dialog.exec() == QDialog::Accepted) { + dialog.commitChanges(); + } +} diff --git a/src/filterlist.h b/src/filterlist.h new file mode 100644 index 00000000..ca74021a --- /dev/null +++ b/src/filterlist.h @@ -0,0 +1,42 @@ +#ifndef MODORGANIZER_CATEGORIESLIST_INCLUDED +#define MODORGANIZER_CATEGORIESLIST_INCLUDED + +#include "modlistsortproxy.h" +#include <QTreeWidgetItem> + +namespace Ui { class MainWindow; }; +class CategoryFactory; + +class FilterList : public QObject +{ + Q_OBJECT; + +public: + FilterList(Ui::MainWindow* ui, CategoryFactory& factory); + + void setSelection(std::vector<int> categories); + void clearSelection(); + void refresh(); + +signals: + void changed(std::vector<int> categories, std::vector<int> content); + +private: + Ui::MainWindow* ui; + CategoryFactory& m_factory; + + void onContextMenu(const QPoint &pos); + void onSelection(); + + void editCategories(); + + QTreeWidgetItem* addFilterItem( + QTreeWidgetItem *root, const QString &name, int categoryID, + ModListSortProxy::FilterType type); + + void addContentFilters(); + void addCategoryFilters( + QTreeWidgetItem *root, const std::set<int> &categoriesUsed, int targetID); +}; + +#endif // MODORGANIZER_CATEGORIESLIST_INCLUDED diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d5636ab9..b63f9211 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -75,6 +75,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "appconfig.h" #include "eventfilter.h" #include "statusbar.h" +#include "filterlist.h" #include <utility.h> #include <dataarchives.h> #include <bsainvalidation.h> @@ -260,6 +261,11 @@ MainWindow::MainWindow(Settings &settings languageChange(settings.interface().language()); 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); + }); ui->logList->setCore(m_OrganizerCore); @@ -1223,7 +1229,7 @@ void MainWindow::showEvent(QShowEvent *event) if (!m_WasVisible) { readSettings(); - refreshFilters(); + m_Filters->refresh(); // this needs to be connected here instead of in the constructor because the // actual changing of the stylesheet is done by MOApplication, which @@ -2646,108 +2652,6 @@ void MainWindow::fileMoved(const QString &filePath, const QString &oldOriginName } } -QTreeWidgetItem *MainWindow::addFilterItem(QTreeWidgetItem *root, const QString &name, int categoryID, ModListSortProxy::FilterType type) -{ - QTreeWidgetItem *item = new QTreeWidgetItem(QStringList(name)); - item->setData(0, Qt::ToolTipRole, name); - item->setData(0, Qt::UserRole, categoryID); - item->setData(0, Qt::UserRole + 1, type); - if (root != nullptr) { - root->addChild(item); - } else { - ui->categoriesList->addTopLevelItem(item); - } - return item; -} - -void MainWindow::addContentFilters() -{ - for (unsigned i = 0; i < ModInfo::NUM_CONTENT_TYPES; ++i) { - addFilterItem(nullptr, tr("<Contains %1>").arg(ModInfo::getContentTypeName(i)), i, ModListSortProxy::TYPE_CONTENT); - } -} - -void MainWindow::addCategoryFilters(QTreeWidgetItem *root, const std::set<int> &categoriesUsed, int targetID) -{ - for (unsigned int i = 1; - i < static_cast<unsigned int>(m_CategoryFactory.numCategories()); ++i) { - if ((m_CategoryFactory.getParentID(i) == targetID)) { - int categoryID = m_CategoryFactory.getCategoryID(i); - if (categoriesUsed.find(categoryID) != categoriesUsed.end()) { - QTreeWidgetItem *item = - addFilterItem(root, m_CategoryFactory.getCategoryName(i), - categoryID, ModListSortProxy::TYPE_CATEGORY); - if (m_CategoryFactory.hasChildren(i)) { - addCategoryFilters(item, categoriesUsed, categoryID); - } - } - } - } -} - -void MainWindow::refreshFilters() -{ - QItemSelection currentSelection = ui->modList->selectionModel()->selection(); - - QVariant currentIndexName = ui->modList->currentIndex().data(); - ui->modList->setCurrentIndex(QModelIndex()); - - QStringList selectedItems; - for (QTreeWidgetItem *item : ui->categoriesList->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); - - addContentFilters(); - std::set<int> categoriesUsed; - for (unsigned int modIdx = 0; modIdx < ModInfo::getNumMods(); ++modIdx) { - ModInfo::Ptr modInfo = ModInfo::getByIndex(modIdx); - for (int categoryID : modInfo->getCategories()) { - int currentID = categoryID; - std::set<int> cycleTest; - // also add parents so they show up in the tree - while (currentID != 0) { - categoriesUsed.insert(currentID); - if (!cycleTest.insert(currentID).second) { - log::warn("cycle in categories: {}", SetJoin(cycleTest, ", ")); - break; - } - currentID = m_CategoryFactory.getParentID(m_CategoryFactory.getCategoryIndex(currentID)); - } - } - } - - addCategoryFilters(nullptr, categoriesUsed, 0); - - for (const QString &item : selectedItems) { - QList<QTreeWidgetItem*> matches = ui->categoriesList->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 MainWindow::renameMod_clicked() { @@ -4121,7 +4025,7 @@ void MainWindow::addRemoveCategories_MenuHandler() { m_OrganizerCore.modList()->notifyChange(m_ContextRow); } - refreshFilters(); + m_Filters->refresh(); } void MainWindow::replaceCategories_MenuHandler() { @@ -4165,7 +4069,7 @@ void MainWindow::replaceCategories_MenuHandler() { m_OrganizerCore.modList()->notifyChange(m_ContextRow); } - refreshFilters(); + m_Filters->refresh(); } void MainWindow::saveArchiveList() @@ -4217,12 +4121,7 @@ void MainWindow::checkModsForUpdates() if (updatesAvailable || checkingModsForUpdate) { m_ModListSortProxy->setCategoryFilter(boost::assign::list_of(CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE)); - 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)); - break; - } - } + m_Filters->setSelection({CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE}); } } @@ -4848,40 +4747,6 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos) } -void MainWindow::on_categoriesList_itemSelectionChanged() -{ - QModelIndexList indices = ui->categoriesList->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(); - if (categoryId != CategoryFactory::CATEGORY_NONE) { - categories.push_back(categoryId); - } - } else if (filterType == ModListSortProxy::TYPE_CONTENT) { - int contentId = index.data(Qt::UserRole).toInt(); - content.push_back(contentId); - } - } - - m_ModListSortProxy->setCategoryFilter(categories); - m_ModListSortProxy->setContentFilter(content); - ui->clickBlankButton->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(); -} - - void MainWindow::deleteSavegame_clicked() { SaveGameInfo const *info = m_OrganizerCore.managedGame()->feature<SaveGameInfo>(); @@ -5071,7 +4936,7 @@ void MainWindow::on_actionSettings_triggered() instManager->setDownloadDirectory(settings.paths().downloads()); fixCategories(); - refreshFilters(); + m_Filters->refresh(); if (settings.paths().profiles() != oldProfilesDirectory) { refreshProfiles(); @@ -6213,27 +6078,9 @@ void MainWindow::on_displayCategoriesBtn_toggled(bool checked) setCategoryListVisible(checked); } -void MainWindow::editCategories() -{ - CategoriesDialog dialog(this); - - if (dialog.exec() == QDialog::Accepted) { - dialog.commitChanges(); - } -} - void MainWindow::deselectFilters() { - ui->categoriesList->clearSelection(); -} - -void MainWindow::on_categoriesList_customContextMenuRequested(const QPoint &pos) -{ - QMenu menu; - menu.addAction(tr("Edit Categories..."), this, SLOT(editCategories())); - menu.addAction(tr("Deselect filter"), this, SLOT(deselectFilters())); - - menu.exec(ui->categoriesList->viewport()->mapToGlobal(pos)); + m_Filters->clearSelection(); } diff --git a/src/mainwindow.h b/src/mainwindow.h index c99c724b..04ba7a35 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -39,6 +39,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. class Executable; class CategoryFactory; class OrganizerCore; +class FilterList; class PluginListSortProxy; namespace BSA { class Archive; } @@ -235,8 +236,6 @@ private: void writeDataToFile(QFile &file, const QString &directory, const MOShared::DirectoryEntry &directoryEntry); - void refreshFilters(); - /** * Sets category selections from menu; for multiple mods, this will only apply * the changes made in the menu (which is the delta between the current menu selection and the reference mod) @@ -266,10 +265,6 @@ private: size_t checkForProblems(); - QTreeWidgetItem *addFilterItem(QTreeWidgetItem *root, const QString &name, int categoryID, ModListSortProxy::FilterType type); - void addContentFilters(); - void addCategoryFilters(QTreeWidgetItem *root, const std::set<int> &categoriesUsed, int targetID); - void setCategoryListVisible(bool visible); void displaySaveGameInfo(QListWidgetItem *newItem); @@ -327,6 +322,8 @@ private: MOBase::TutorialControl m_Tutorial; + std::unique_ptr<FilterList> m_Filters; + int m_OldProfileIndex; std::vector<QString> m_ModNameList; // the mod-list to go with the directory structure @@ -515,7 +512,6 @@ private slots: void onRequestsChanged(const APIStats& stats, const APIUserAccount& user); - void editCategories(); void deselectFilters(); void displayModInformation(const QString &modName, ModInfoTabIDs tabID); @@ -630,7 +626,6 @@ private slots: // ui slots void on_clearFiltersButton_clicked(); void on_btnRefreshData_clicked(); void on_btnRefreshDownloads_clicked(); - void on_categoriesList_customContextMenuRequested(const QPoint &pos); void on_conflictsCheckBox_toggled(bool checked); void on_showArchiveDataCheckBox_toggled(bool checked); void on_dataTree_customContextMenuRequested(const QPoint &pos); @@ -647,7 +642,6 @@ private slots: // ui slots void on_espList_customContextMenuRequested(const QPoint &pos); void on_displayCategoriesBtn_toggled(bool checked); void on_groupCombo_currentIndexChanged(int index); - void on_categoriesList_itemSelectionChanged(); void on_linkButton_pressed(); void on_showHiddenBox_toggled(bool checked); void on_bsaList_itemChanged(QTreeWidgetItem *item, int column); |
