diff --git a/src/plugins/coreplugin/ioutputpane.h b/src/plugins/coreplugin/ioutputpane.h index 95999a7b56ecd742e670481edc38505bf9f9c87d..e68e05de405e79bbddd0f73132b6a995ef47b0c6 100644 --- a/src/plugins/coreplugin/ioutputpane.h +++ b/src/plugins/coreplugin/ioutputpane.h @@ -86,6 +86,7 @@ public slots: void toggle(bool withFocusIfShown) { emit togglePage(withFocusIfShown); } void navigateStateChanged() { emit navigateStateUpdate(); } void flash() { emit flashButton(); } + void setIconBadgeNumber(int number) { emit setBadgeNumber(number); } signals: void showPage(bool withFocus, bool ensureSizeHint); @@ -93,6 +94,7 @@ signals: void togglePage(bool withFocusIfShown); void navigateStateUpdate(); void flashButton(); + void setBadgeNumber(int number); }; } // namespace Core diff --git a/src/plugins/coreplugin/outputpanemanager.cpp b/src/plugins/coreplugin/outputpanemanager.cpp index 1fafdb2adbd965a7081fad82d3d3180048afd34f..33024b7c9969b70a1ac910c6ba0a0e25e630fba5 100644 --- a/src/plugins/coreplugin/outputpanemanager.cpp +++ b/src/plugins/coreplugin/outputpanemanager.cpp @@ -68,6 +68,7 @@ #include <QStackedWidget> #include <QToolButton> #include <QTimeLine> +#include <QLabel> namespace Core { namespace Internal { @@ -263,6 +264,7 @@ void OutputPaneManager::init() connect(outPane, SIGNAL(togglePage(bool)), this, SLOT(togglePage(bool))); connect(outPane, SIGNAL(navigateStateUpdate()), this, SLOT(updateNavigateState())); connect(outPane, SIGNAL(flashButton()), this, SLOT(flashButton())); + connect(outPane, SIGNAL(setBadgeNumber(int)), this, SLOT(setBadgeNumber(int))); QWidget *toolButtonsContainer = new QWidget(m_opToolBarWidgets); QHBoxLayout *toolButtonsLayout = new QHBoxLayout; @@ -453,6 +455,14 @@ void OutputPaneManager::flashButton() m_buttons.value(idx)->flash(); } +void OutputPaneManager::setBadgeNumber(int number) +{ + IOutputPane* pane = qobject_cast<IOutputPane*>(sender()); + int idx = findIndexForPage(pane); + if (pane) + m_buttons.value(idx)->setIconBadgeNumber(number); +} + // Slot connected to showPage signal of each page void OutputPaneManager::showPage(bool focus, bool ensureSizeHint) { @@ -617,6 +627,15 @@ OutputPaneToggleButton::OutputPaneToggleButton(int number, const QString &text, m_flashTimer->setFrameRange(0, 92); connect(m_flashTimer, SIGNAL(valueChanged(qreal)), this, SLOT(update())); connect(m_flashTimer, SIGNAL(finished()), this, SLOT(update())); + + m_label = new QLabel(this); + fnt.setBold(true); + fnt.setPixelSize(11); + m_label->setFont(fnt); + m_label->setAlignment(Qt::AlignCenter); + m_label->setStyleSheet("background-color: #818181; color: white; border-radius: 6; padding-left: 4; padding-right: 4;"); + m_label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + m_label->hide(); } void OutputPaneToggleButton::updateToolTip() @@ -635,9 +654,21 @@ QSize OutputPaneToggleButton::sizeHint() const s.rwidth() += 19 + 5 + 2; s.rheight() += 2 + 2; + if (!m_label->text().isNull()) + s.rwidth() += m_label->width(); + return s.expandedTo(QApplication::globalStrut()); } +void OutputPaneToggleButton::resizeEvent(QResizeEvent *event) +{ + QToolButton::resizeEvent(event); + if (!m_label->text().isNull()) { + m_label->move(width() - m_label->width() - 3, (height() - m_label->height() + 1) / 2); + m_label->show(); + } +} + void OutputPaneToggleButton::paintEvent(QPaintEvent *event) { // For drawing the style sheet stuff @@ -658,7 +689,8 @@ void OutputPaneToggleButton::paintEvent(QPaintEvent *event) if (!isChecked()) p.setPen(Qt::black); int leftPart = 22; - p.drawText(leftPart, baseLine, fm.elidedText(m_text, Qt::ElideRight, width() - leftPart - 1)); + int labelWidth = m_label->isVisible() ? m_label->width() + 3 : 0; + p.drawText(leftPart, baseLine, fm.elidedText(m_text, Qt::ElideRight, width() - leftPart - 1 - labelWidth)); } void OutputPaneToggleButton::checkStateSet() @@ -666,6 +698,11 @@ void OutputPaneToggleButton::checkStateSet() //Stop flashing when button is checked QToolButton::checkStateSet(); m_flashTimer->stop(); + + if (isChecked()) + m_label->setStyleSheet("background-color: #e1e1e1; color: #606060; border-radius: 6; padding-left: 4; padding-right: 4;"); + else + m_label->setStyleSheet("background-color: #818181; color: white; border-radius: 6; padding-left: 4; padding-right: 4;"); } void OutputPaneToggleButton::flash(int count) @@ -679,6 +716,26 @@ void OutputPaneToggleButton::flash(int count) } } +void OutputPaneToggleButton::setIconBadgeNumber(int number) +{ + if (number) { + const QString text = QString::number(number); + m_label->setText(text); + + QSize size = m_label->sizeHint(); + if (size.width() < size.height()) + //Ensure we increase size by an even number of pixels + size.setWidth(size.height() + ((size.width() - size.height()) & 1)); + m_label->resize(size); + + //Do not show yet, we wait until the button has been resized + } else { + m_label->setText(QString()); + m_label->hide(); + } + updateGeometry(); +} + /////////////////////////////////////////////////////////////////////// // diff --git a/src/plugins/coreplugin/outputpanemanager.h b/src/plugins/coreplugin/outputpanemanager.h index 1f3900fce7063ac5a4de3cf821eeb1f2a493eabb..cbd427f0175051060189f28158094981af55dc25 100644 --- a/src/plugins/coreplugin/outputpanemanager.h +++ b/src/plugins/coreplugin/outputpanemanager.h @@ -45,6 +45,7 @@ class QLabel; class QSplitter; class QStackedWidget; class QTimeLine; +class QLabel; QT_END_NAMESPACE namespace Core { @@ -88,6 +89,7 @@ private slots: void popupMenu(); void saveSettings() const; void flashButton(); + void setBadgeNumber(int number); private: // the only class that is allowed to create and destroy @@ -143,8 +145,10 @@ public: OutputPaneToggleButton(int number, const QString &text, QAction *action, QWidget *parent = 0); QSize sizeHint() const; + void resizeEvent(QResizeEvent *event); void paintEvent(QPaintEvent *event); void flash(int count = 3); + void setIconBadgeNumber(int number); private slots: void updateToolTip(); @@ -156,6 +160,7 @@ private: QString m_text; QAction *m_action; QTimeLine *m_flashTimer; + QLabel *m_label; }; class OutputPaneManageButton : public QToolButton diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp index 2410ba05b68b39fb904e13226a228f7015f97b8c..f0d61d40a1e175118f0032f4eaf0c5e147168681 100644 --- a/src/plugins/projectexplorer/taskwindow.cpp +++ b/src/plugins/projectexplorer/taskwindow.cpp @@ -220,6 +220,7 @@ public: QToolButton *m_categoriesButton; QMenu *m_categoriesMenu; TaskHub *m_taskHub; + int m_badgeCount; }; static QToolButton *createFilterButton(QIcon icon, const QString &toolTip, @@ -256,6 +257,7 @@ TaskWindow::TaskWindow(TaskHub *taskhub) : d(new TaskWindowPrivate) d->m_taskWindowContext = new Internal::TaskWindowContext(d->m_listview); d->m_taskHub = taskhub; + d->m_badgeCount = 0; Core::ICore::addContextObject(d->m_taskWindowContext); @@ -336,11 +338,22 @@ QWidget *TaskWindow::outputWidget(QWidget *) void TaskWindow::clearTasks(const Core::Id &categoryId) { + if (categoryId.uniqueIdentifier() != 0 && !d->m_filter->filteredCategories().contains(categoryId)) { + if (d->m_filter->filterIncludesErrors()) + d->m_badgeCount -= d->m_model->errorTaskCount(categoryId); + if (d->m_filter->filterIncludesWarnings()) + d->m_badgeCount -= d->m_model->warningTaskCount(categoryId); + } else { + d->m_badgeCount = 0; + } + d->m_model->clearTasks(categoryId); emit tasksChanged(); emit tasksCleared(); navigateStateChanged(); + + setBadgeNumber(d->m_badgeCount); } void TaskWindow::setCategoryVisibility(const Core::Id &categoryId, bool visible) @@ -357,6 +370,17 @@ void TaskWindow::setCategoryVisibility(const Core::Id &categoryId, bool visible) } d->m_filter->setFilteredCategories(categories); + + int count = 0; + if (d->m_filter->filterIncludesErrors()) + count += d->m_model->errorTaskCount(categoryId); + if (d->m_filter->filterIncludesWarnings()) + count += d->m_model->warningTaskCount(categoryId); + if (visible) + d->m_badgeCount += count; + else + d->m_badgeCount -= count; + setBadgeNumber(d->m_badgeCount); } void TaskWindow::visibilityChanged(bool /* b */) @@ -383,6 +407,11 @@ void TaskWindow::addTask(const Task &task) if (task.type == Task::Error && d->m_filter->filterIncludesErrors() && !d->m_filter->filteredCategories().contains(task.category)) { flash(); + setBadgeNumber(++d->m_badgeCount); + } + if (task.type == Task::Warning && d->m_filter->filterIncludesWarnings() && + !d->m_filter->filteredCategories().contains(task.category)) { + setBadgeNumber(++d->m_badgeCount); } } @@ -392,6 +421,15 @@ void TaskWindow::removeTask(const Task &task) emit tasksChanged(); navigateStateChanged(); + + if (task.type == Task::Error && d->m_filter->filterIncludesErrors() && + !d->m_filter->filteredCategories().contains(task.category)) { + setBadgeNumber(--d->m_badgeCount); + } + if (task.type == Task::Warning && d->m_filter->filterIncludesWarnings() && + !d->m_filter->filteredCategories().contains(task.category)) { + setBadgeNumber(--d->m_badgeCount); + } } void TaskWindow::updatedTaskFileName(unsigned int id, const QString &fileName) @@ -500,6 +538,7 @@ void TaskWindow::setShowWarnings(bool show) { d->m_filter->setFilterIncludesWarnings(show); d->m_filter->setFilterIncludesUnknowns(show); // "Unknowns" are often associated with warnings + setBadgeNumber(d->m_filter->rowCount()); } void TaskWindow::updateCategoriesMenu() diff --git a/src/plugins/todo/todooutputpane.cpp b/src/plugins/todo/todooutputpane.cpp index 578fc182761cfd712ac94a3f858f7346fabf195f..31d10a261fc399d7baeb403728450df44a3986f3 100755 --- a/src/plugins/todo/todooutputpane.cpp +++ b/src/plugins/todo/todooutputpane.cpp @@ -52,6 +52,7 @@ TodoOutputPane::TodoOutputPane(TodoItemsModel *todoItemsModel, QObject *parent) createScopeButtons(); setScanningScope(ScanningScopeCurrentFile); // default connect(m_todoItemsModel, SIGNAL(layoutChanged()), SIGNAL(navigateStateUpdate())); + connect(m_todoItemsModel, SIGNAL(layoutChanged()), SLOT(updateTodoCount())); } TodoOutputPane::~TodoOutputPane() @@ -149,6 +150,7 @@ void TodoOutputPane::scopeButtonClicked(QAbstractButton* button) emit scanningScopeChanged(ScanningScopeCurrentFile); else if (button == m_wholeProjectButton) emit scanningScopeChanged(ScanningScopeProject); + setBadgeNumber(m_todoItemsModel->rowCount()); } void TodoOutputPane::todoTreeViewClicked(const QModelIndex &index) @@ -167,6 +169,11 @@ void TodoOutputPane::todoTreeViewClicked(const QModelIndex &index) emit todoItemClicked(item); } +void TodoOutputPane::updateTodoCount() +{ + setBadgeNumber(m_todoItemsModel->rowCount()); +} + void TodoOutputPane::createTreeView() { m_todoTreeView = new QTreeView(); diff --git a/src/plugins/todo/todooutputpane.h b/src/plugins/todo/todooutputpane.h index 9508af8231225ec77d3fc02e9bebc3b01ff1ff67..39cc1d37a69a6cacccc3b283a1a9215367646964 100755 --- a/src/plugins/todo/todooutputpane.h +++ b/src/plugins/todo/todooutputpane.h @@ -84,6 +84,7 @@ signals: private slots: void scopeButtonClicked(QAbstractButton *button); void todoTreeViewClicked(const QModelIndex &index); + void updateTodoCount(); private: QTreeView *m_todoTreeView;