diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp index 4cadbb4f4ffb75c09dd1510449fd910d45679935..1692dbb08432be80d2e41af44f0b5ed116e1b531 100644 --- a/src/plugins/projectexplorer/taskwindow.cpp +++ b/src/plugins/projectexplorer/taskwindow.cpp @@ -102,6 +102,8 @@ public: int columnCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QStringList categoryIds() const; + QString categoryDisplayName(const QString &categoryId) const; void addCategory(const QString &categoryId, const QString &categoryName); QList<TaskWindow::Task> tasks(const QString &categoryId = QString()) const; @@ -112,7 +114,7 @@ public: int sizeOfLineNumber(); void setFileNotFound(const QModelIndex &index, bool b); - enum Roles { File = Qt::UserRole, Line, Description, FileNotFound, Type }; + enum Roles { File = Qt::UserRole, Line, Description, FileNotFound, Type, Category }; QIcon iconFor(TaskWindow::TaskType type); @@ -144,6 +146,9 @@ public: bool filterIncludesErrors() const { return m_includeErrors; } void setFilterIncludesErrors(bool b) { m_includeErrors = b; invalidateFilter(); } + QStringList filteredCategories() const { return m_categoryIds; } + void setFilteredCategories(const QStringList &categoryIds) { m_categoryIds = categoryIds; invalidateFilter(); } + protected: bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; @@ -152,6 +157,7 @@ private: bool m_includeUnknowns; bool m_includeWarnings; bool m_includeErrors; + QStringList m_categoryIds; }; } // Internal @@ -321,9 +327,21 @@ QVariant TaskModel::data(const QModelIndex &index, int role) const return m_fileNotFound.value(m_tasks.at(index.row()).file); else if (role == TaskModel::Type) return (int)m_tasks.at(index.row()).type; + else if (role == TaskModel::Category) + return m_tasks.at(index.row()).category; return QVariant(); } +QStringList TaskModel::categoryIds() const +{ + return m_categories.keys(); +} + +QString TaskModel::categoryDisplayName(const QString &categoryId) const +{ + return m_categories.value(categoryId); +} + QIcon TaskModel::iconFor(TaskWindow::TaskType type) { if (type == TaskWindow::Error) @@ -373,21 +391,27 @@ TaskModel *TaskFilterModel::taskModel() const bool TaskFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { + bool accept = true; + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); TaskWindow::TaskType type = TaskWindow::TaskType(index.data(TaskModel::Type).toInt()); switch (type) { case TaskWindow::Unknown: - return m_includeUnknowns; - + accept = m_includeUnknowns; + break; case TaskWindow::Warning: - return m_includeWarnings; - + accept = m_includeWarnings; + break; case TaskWindow::Error: - return m_includeErrors; + accept = m_includeErrors; + break; } - // Not one of the three supported types -- shouldn't happen, but we'll let it slide. - return true; + const QString &categoryId = index.data(TaskModel::Category).toString(); + if (m_categoryIds.contains(categoryId)) + accept = false; + + return accept; } ///// @@ -449,6 +473,17 @@ TaskWindow::TaskWindow() tr("Show Warnings"), m_model, this, SLOT(setShowWarnings(bool))); + m_categoriesMenu = new QMenu; + connect(m_categoriesMenu, SIGNAL(aboutToShow()), this, SLOT(updateCategoriesMenu())); + connect(m_categoriesMenu, SIGNAL(triggered(QAction*)), this, SLOT(filterCategoryTriggered(QAction*))); + + m_categoriesButton = new QToolButton; + m_categoriesButton->setText(tr("categories")); + m_categoriesButton->setToolTip(tr("Filter by categories")); + m_categoriesButton->setAutoRaise(true); + m_categoriesButton->setPopupMode(QToolButton::InstantPopup); + m_categoriesButton->setMenu(m_categoriesMenu); + updateActions(); } @@ -463,7 +498,7 @@ TaskWindow::~TaskWindow() QList<QWidget*> TaskWindow::toolBarWidgets() const { - return QList<QWidget*>() << m_filterWarningsButton; + return QList<QWidget*>() << m_filterWarningsButton << m_categoriesButton; } QWidget *TaskWindow::outputWidget(QWidget *) @@ -544,6 +579,42 @@ void TaskWindow::setShowWarnings(bool show) m_filter->setFilterIncludesUnknowns(show); // "Unknowns" are often associated with warnings } +void TaskWindow::updateCategoriesMenu() +{ + m_categoriesMenu->clear(); + + const QStringList filteredCategories = m_filter->filteredCategories(); + + foreach (const QString &categoryId, m_model->categoryIds()) { + const QString categoryName = m_model->categoryDisplayName(categoryId); + + QAction *action = new QAction(m_categoriesMenu); + action->setCheckable(true); + action->setText(categoryName); + action->setData(categoryId); + action->setChecked(!filteredCategories.contains(categoryId)); + + m_categoriesMenu->addAction(action); + } +} + +void TaskWindow::filterCategoryTriggered(QAction *action) +{ + QString categoryId = action->data().toString(); + Q_ASSERT(!categoryId.isEmpty()); + + QStringList categories = m_filter->filteredCategories(); + Q_ASSERT(m_filter->filteredCategories().contains(categoryId) == action->isChecked()); + + if (action->isChecked()) { + categories.removeOne(categoryId); + } else { + categories.append(categoryId); + } + + m_filter->setFilteredCategories(categories); +} + int TaskWindow::taskCount(const QString &categoryId) const { return m_model->tasks(categoryId).count(); diff --git a/src/plugins/projectexplorer/taskwindow.h b/src/plugins/projectexplorer/taskwindow.h index 20cd59f655678de93dfd00ddce5e7cb3033d9ddf..7fddbcbfba305337cd39a7eecacc1a32c6eeff6e 100644 --- a/src/plugins/projectexplorer/taskwindow.h +++ b/src/plugins/projectexplorer/taskwindow.h @@ -112,6 +112,8 @@ private slots: void showTaskInFile(const QModelIndex &index); void copy(); void setShowWarnings(bool); + void updateCategoriesMenu(); + void filterCategoryTriggered(QAction *action); private: void updateActions(); @@ -123,6 +125,8 @@ private: Internal::TaskWindowContext *m_taskWindowContext; QAction *m_copyAction; QToolButton *m_filterWarningsButton; + QToolButton *m_categoriesButton; + QMenu *m_categoriesMenu; }; bool operator==(const TaskWindow::Task &t1, const TaskWindow::Task &t2);