diff --git a/src/plugins/todo/constants.h b/src/plugins/todo/constants.h index b4598dd0b97..d597bc5c6fa 100644 --- a/src/plugins/todo/constants.h +++ b/src/plugins/todo/constants.h @@ -68,5 +68,7 @@ const int OUTPUT_TOOLBAR_SPACER_WIDTH = 25; const int OUTPUT_PANE_UPDATE_INTERVAL = 2000; const char OUTPUT_PANE_TITLE[] = QT_TRANSLATE_NOOP("Todo::Internal::TodoOutputPane", "To-Do Entries"); +const char FILTER_KEYWORD_NAME[] = "filterKeywordName"; + } // namespace Constants } // namespace Todo diff --git a/src/plugins/todo/images/bug.png b/src/plugins/todo/images/bug.png new file mode 100644 index 00000000000..68409e843af Binary files /dev/null and b/src/plugins/todo/images/bug.png differ diff --git a/src/plugins/todo/images/bug@2x.png b/src/plugins/todo/images/bug@2x.png new file mode 100644 index 00000000000..ac43ab381db Binary files /dev/null and b/src/plugins/todo/images/bug@2x.png differ diff --git a/src/plugins/todo/images/bugfill.png b/src/plugins/todo/images/bugfill.png new file mode 100644 index 00000000000..421b06104b9 Binary files /dev/null and b/src/plugins/todo/images/bugfill.png differ diff --git a/src/plugins/todo/images/bugfill@2x.png b/src/plugins/todo/images/bugfill@2x.png new file mode 100644 index 00000000000..1e8a716d01e Binary files /dev/null and b/src/plugins/todo/images/bugfill@2x.png differ diff --git a/src/plugins/todo/images/tasklist.png b/src/plugins/todo/images/tasklist.png new file mode 100644 index 00000000000..998484aab3a Binary files /dev/null and b/src/plugins/todo/images/tasklist.png differ diff --git a/src/plugins/todo/images/tasklist@2x.png b/src/plugins/todo/images/tasklist@2x.png new file mode 100644 index 00000000000..c45ab36d0ba Binary files /dev/null and b/src/plugins/todo/images/tasklist@2x.png differ diff --git a/src/plugins/todo/images/todo.png b/src/plugins/todo/images/todo.png index 32160841b06..80b4257017f 100644 Binary files a/src/plugins/todo/images/todo.png and b/src/plugins/todo/images/todo.png differ diff --git a/src/plugins/todo/keyworddialog.cpp b/src/plugins/todo/keyworddialog.cpp index 721f65f6aba..bffa7775b7c 100644 --- a/src/plugins/todo/keyworddialog.cpp +++ b/src/plugins/todo/keyworddialog.cpp @@ -95,6 +95,14 @@ void KeywordDialog::setupListWidget(IconType selectedIcon) item->setData(Qt::UserRole, static_cast(IconType::Error)); ui->listWidget->addItem(item); + item = new QListWidgetItem(icon(IconType::Bug), QLatin1String("bug")); + item->setData(Qt::UserRole, static_cast(IconType::Bug)); + ui->listWidget->addItem(item); + + item = new QListWidgetItem(icon(IconType::Todo), QLatin1String("todo")); + item->setData(Qt::UserRole, static_cast(IconType::Todo)); + ui->listWidget->addItem(item); + for (int i = 0; i < ui->listWidget->count(); ++i) { item = ui->listWidget->item(i); if (static_cast(item->data(Qt::UserRole).toInt()) == selectedIcon) { diff --git a/src/plugins/todo/optionsdialog.ui b/src/plugins/todo/optionsdialog.ui index 321978494e3..6bbb38f1755 100644 --- a/src/plugins/todo/optionsdialog.ui +++ b/src/plugins/todo/optionsdialog.ui @@ -22,8 +22,17 @@ + + QAbstractItemView::DragDrop + + + Qt::MoveAction + + + QAbstractItemView::SelectRows + - true + false diff --git a/src/plugins/todo/settings.cpp b/src/plugins/todo/settings.cpp index 89dfef94091..bb6c9bdaffa 100644 --- a/src/plugins/todo/settings.cpp +++ b/src/plugins/todo/settings.cpp @@ -110,7 +110,7 @@ void Settings::setDefault() Keyword keyword; keyword.name = QLatin1String("TODO"); - keyword.iconType = IconType::Warning; + keyword.iconType = IconType::Todo; keyword.color = QColor(QLatin1String(Constants::COLOR_TODO_BG)); keywords.append(keyword); @@ -125,7 +125,7 @@ void Settings::setDefault() keywords.append(keyword); keyword.name = QLatin1String("BUG"); - keyword.iconType = IconType::Error; + keyword.iconType = IconType::Bug; keyword.color = QColor(QLatin1String(Constants::COLOR_BUG_BG)); keywords.append(keyword); diff --git a/src/plugins/todo/todoicons.cpp b/src/plugins/todo/todoicons.cpp index a0fcef3978e..41f3ac41986 100644 --- a/src/plugins/todo/todoicons.cpp +++ b/src/plugins/todo/todoicons.cpp @@ -23,11 +23,14 @@ ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ****************************************************************************/ - +#include +#include #include #include "todoicons.h" +using namespace Utils; + namespace Todo { namespace Internal { @@ -42,6 +45,23 @@ QIcon icon(IconType type) const static QIcon icon = Core::Icons::WARNING.icon(); return icon; } + case IconType::Bug: { + const static QIcon icon = + Icon({ + {":/todoplugin/images/bugfill.png", Theme::BackgroundColorNormal}, + {":/todoplugin/images/bug.png", Theme::IconsInterruptToolBarColor} + }, Icon::Tint).icon(); + + return icon; + } + case IconType::Todo: { + const static QIcon icon = + Icon({ + {":/todoplugin/images/tasklist.png", Theme::IconsRunToolBarColor} + }, Icon::Tint).icon(); + return icon; + } + default: case IconType::Error: { const static QIcon icon = Core::Icons::ERROR.icon(); diff --git a/src/plugins/todo/todoicons.h b/src/plugins/todo/todoicons.h index 721c81df821..23cb15d951c 100644 --- a/src/plugins/todo/todoicons.h +++ b/src/plugins/todo/todoicons.h @@ -34,7 +34,9 @@ namespace Internal { enum class IconType { Info, Error, - Warning + Warning, + Bug, + Todo }; QIcon icon(IconType type); diff --git a/src/plugins/todo/todoitemsmodel.cpp b/src/plugins/todo/todoitemsmodel.cpp index 5cd1cca36e2..f9f3273092b 100644 --- a/src/plugins/todo/todoitemsmodel.cpp +++ b/src/plugins/todo/todoitemsmodel.cpp @@ -141,6 +141,7 @@ void TodoItemsModel::sort(int column, Qt::SortOrder order) m_currentSortOrder = order; TodoItemSortPredicate predicate(m_currentSortColumn, m_currentSortOrder); + emit layoutAboutToBeChanged(); Utils::sort(*m_todoItemsList, predicate); emit layoutChanged(); } diff --git a/src/plugins/todo/todooutputpane.cpp b/src/plugins/todo/todooutputpane.cpp index e0099626ee0..8add645b073 100644 --- a/src/plugins/todo/todooutputpane.cpp +++ b/src/plugins/todo/todooutputpane.cpp @@ -36,20 +36,22 @@ #include #include #include +#include namespace Todo { namespace Internal { -TodoOutputPane::TodoOutputPane(TodoItemsModel *todoItemsModel, QObject *parent) : +TodoOutputPane::TodoOutputPane(TodoItemsModel *todoItemsModel, const Settings *settings, QObject *parent) : IOutputPane(parent), - m_todoItemsModel(todoItemsModel) + m_todoItemsModel(todoItemsModel), + m_settings(settings) { createTreeView(); createScopeButtons(); setScanningScope(ScanningScopeCurrentFile); // default - connect(m_todoItemsModel, &TodoItemsModel::layoutChanged, + connect(m_todoTreeView->model(), &TodoItemsModel::layoutChanged, this, &TodoOutputPane::navigateStateUpdate); - connect(m_todoItemsModel, &TodoItemsModel::layoutChanged, + connect(m_todoTreeView->model(), &TodoItemsModel::layoutChanged, this, &TodoOutputPane::updateTodoCount); } @@ -67,7 +69,14 @@ QWidget *TodoOutputPane::outputWidget(QWidget *parent) QList TodoOutputPane::toolBarWidgets() const { - return { m_spacer, m_currentFileButton, m_wholeProjectButton, m_subProjectButton }; + QWidgetList widgets; + + for (QToolButton *btn: m_filterButtons) + widgets << btn; + + widgets << m_spacer << m_currentFileButton << m_wholeProjectButton << m_subProjectButton; + + return widgets; } QString TodoOutputPane::displayName() const @@ -82,6 +91,7 @@ int TodoOutputPane::priorityInStatusBar() const void TodoOutputPane::clearContents() { + clearFilter(); } void TodoOutputPane::visibilityChanged(bool visible) @@ -111,19 +121,19 @@ bool TodoOutputPane::canNavigate() const bool TodoOutputPane::canNext() const { - return m_todoTreeView->model()->rowCount() > 1; + return m_todoTreeView->model()->rowCount() > 0; } bool TodoOutputPane::canPrevious() const { - return m_todoTreeView->model()->rowCount() > 1; + return m_todoTreeView->model()->rowCount() > 0; } void TodoOutputPane::goToNext() { const QModelIndex nextIndex = nextModelIndex(); m_todoTreeView->selectionModel()->setCurrentIndex(nextIndex, QItemSelectionModel::SelectCurrent - | QItemSelectionModel::Rows); + | QItemSelectionModel::Rows | QItemSelectionModel::Clear); todoTreeViewClicked(nextIndex); } @@ -131,7 +141,7 @@ void TodoOutputPane::goToPrev() { const QModelIndex prevIndex = previousModelIndex(); m_todoTreeView->selectionModel()->setCurrentIndex(prevIndex, QItemSelectionModel::SelectCurrent - | QItemSelectionModel::Rows); + | QItemSelectionModel::Rows | QItemSelectionModel::Clear); todoTreeViewClicked(prevIndex); } @@ -147,7 +157,7 @@ void TodoOutputPane::setScanningScope(ScanningScope scanningScope) Q_ASSERT_X(false, "Updating scanning scope buttons", "Unknown scanning scope enum value"); } -void TodoOutputPane::scopeButtonClicked(QAbstractButton* button) +void TodoOutputPane::scopeButtonClicked(QAbstractButton *button) { if (button == m_currentFileButton) emit scanningScopeChanged(ScanningScopeCurrentFile); @@ -155,7 +165,7 @@ void TodoOutputPane::scopeButtonClicked(QAbstractButton* button) emit scanningScopeChanged(ScanningScopeSubProject); else if (button == m_wholeProjectButton) emit scanningScopeChanged(ScanningScopeProject); - setBadgeNumber(m_todoItemsModel->rowCount()); + setBadgeNumber(m_todoTreeView->model()->rowCount()); } void TodoOutputPane::todoTreeViewClicked(const QModelIndex &index) @@ -177,13 +187,44 @@ void TodoOutputPane::todoTreeViewClicked(const QModelIndex &index) void TodoOutputPane::updateTodoCount() { - setBadgeNumber(m_todoItemsModel->rowCount()); + setBadgeNumber(m_todoTreeView->model()->rowCount()); +} + +void TodoOutputPane::updateFilter() +{ + QStringList keywords; + for (QToolButton *btn: m_filterButtons) { + if (btn->isChecked()) + keywords.append(btn->property(Constants::FILTER_KEYWORD_NAME).toString()); + } + + QString pattern = keywords.isEmpty() ? QString() : QString("^(%1).*").arg(keywords.join('|')); + int sortColumn = m_todoTreeView->header()->sortIndicatorSection(); + Qt::SortOrder sortOrder = m_todoTreeView->header()->sortIndicatorOrder(); + + m_filteredTodoItemsModel->setFilterRegExp(pattern); + m_filteredTodoItemsModel->sort(sortColumn, sortOrder); + + updateTodoCount(); +} + +void TodoOutputPane::clearFilter() +{ + for (QToolButton *btn: m_filterButtons) + btn->setChecked(false); + + updateFilter(); } void TodoOutputPane::createTreeView() { + m_filteredTodoItemsModel = new QSortFilterProxyModel(); + m_filteredTodoItemsModel->setSourceModel(m_todoItemsModel); + m_filteredTodoItemsModel->setDynamicSortFilter(false); + m_filteredTodoItemsModel->setFilterKeyColumn(Constants::OUTPUT_COLUMN_TEXT); + m_todoTreeView = new TodoOutputTreeView(); - m_todoTreeView->setModel(m_todoItemsModel); + m_todoTreeView->setModel(m_filteredTodoItemsModel); Aggregation::Aggregate *agg = new Aggregation::Aggregate; agg->add(m_todoTreeView); agg->add(new Core::ItemViewFind(m_todoTreeView)); @@ -194,6 +235,19 @@ void TodoOutputPane::createTreeView() void TodoOutputPane::freeTreeView() { delete m_todoTreeView; + delete m_filteredTodoItemsModel; +} + +QToolButton *TodoOutputPane::createCheckableToolButton(const QString &text, const QString &toolTip, const QIcon &icon) +{ + QToolButton *button = new QToolButton(); + + button->setCheckable(true); + button->setText(text); + button->setToolTip(toolTip); + button->setIcon(icon); + + return button; } void TodoOutputPane::createScopeButtons() @@ -222,6 +276,16 @@ void TodoOutputPane::createScopeButtons() m_spacer = new QWidget; m_spacer->setMinimumWidth(Constants::OUTPUT_TOOLBAR_SPACER_WIDTH); + + QString tooltip = tr("Show \"%1\" entries"); + for (const Keyword &keyword: m_settings->keywords) { + QToolButton *button = createCheckableToolButton(keyword.name, tooltip.arg(keyword.name), icon(keyword.iconType)); + button->setProperty(Constants::FILTER_KEYWORD_NAME, keyword.name); + button->setToolButtonStyle(Qt::ToolButtonIconOnly); + connect(button, &QToolButton::clicked, this, &TodoOutputPane::updateFilter); + + m_filterButtons.append(button); + } } void TodoOutputPane::freeScopeButtons() @@ -231,6 +295,8 @@ void TodoOutputPane::freeScopeButtons() delete m_subProjectButton; delete m_scopeButtons; delete m_spacer; + + qDeleteAll(m_filterButtons); } QModelIndex TodoOutputPane::selectedModelIndex() diff --git a/src/plugins/todo/todooutputpane.h b/src/plugins/todo/todooutputpane.h index c534fce0498..c2ef23ec146 100644 --- a/src/plugins/todo/todooutputpane.h +++ b/src/plugins/todo/todooutputpane.h @@ -35,6 +35,7 @@ class QToolButton; class QButtonGroup; class QModelIndex; class QAbstractButton; +class QSortFilterProxyModel; QT_END_NAMESPACE namespace Todo { @@ -44,12 +45,14 @@ class TodoItem; class TodoItemsModel; class TodoOutputTreeView; +typedef QList QToolButtonList; + class TodoOutputPane : public Core::IOutputPane { Q_OBJECT public: - TodoOutputPane(TodoItemsModel *todoItemsModel, QObject *parent = 0); + TodoOutputPane(TodoItemsModel *todoItemsModel, const Settings *settings, QObject *parent = 0); ~TodoOutputPane(); QWidget *outputWidget(QWidget *parent); @@ -77,6 +80,8 @@ private: void scopeButtonClicked(QAbstractButton *button); void todoTreeViewClicked(const QModelIndex &index); void updateTodoCount(); + void updateFilter(); + void clearFilter(); void createTreeView(); void freeTreeView(); @@ -87,6 +92,8 @@ private: QModelIndex nextModelIndex(); QModelIndex previousModelIndex(); + QToolButton *createCheckableToolButton(const QString &text, const QString &toolTip, const QIcon &icon); + TodoOutputTreeView *m_todoTreeView; QToolButton *m_currentFileButton; QToolButton *m_wholeProjectButton; @@ -95,6 +102,9 @@ private: QButtonGroup *m_scopeButtons; QList *items; TodoItemsModel *m_todoItemsModel; + QSortFilterProxyModel *m_filteredTodoItemsModel; + const Settings *m_settings; + QToolButtonList m_filterButtons; }; } // namespace Internal diff --git a/src/plugins/todo/todoplugin.cpp b/src/plugins/todo/todoplugin.cpp index 475c04cc425..bbbe1a077ac 100644 --- a/src/plugins/todo/todoplugin.cpp +++ b/src/plugins/todo/todoplugin.cpp @@ -125,7 +125,7 @@ void TodoPlugin::createItemsProvider() void TodoPlugin::createTodoOutputPane() { - m_todoOutputPane = new TodoOutputPane(m_todoItemsProvider->todoItemsModel()); + m_todoOutputPane = new TodoOutputPane(m_todoItemsProvider->todoItemsModel(), &m_settings); addAutoReleasedObject(m_todoOutputPane); m_todoOutputPane->setScanningScope(m_settings.scanningScope); connect(m_todoOutputPane, &TodoOutputPane::scanningScopeChanged, diff --git a/src/plugins/todo/todoplugin.qrc b/src/plugins/todo/todoplugin.qrc index ac97a969436..b9e44626664 100644 --- a/src/plugins/todo/todoplugin.qrc +++ b/src/plugins/todo/todoplugin.qrc @@ -1,5 +1,11 @@ images/todo.png + images/tasklist@2x.png + images/tasklist.png + images/bug@2x.png + images/bug.png + images/bugfill.png + images/bugfill@2x.png