From 54569d5931d5dee4d34879c7b0902036623a5fa3 Mon Sep 17 00:00:00 2001
From: Francois Ferrand <thetypz@gmail.com>
Date: Mon, 11 Jun 2012 10:32:16 +0200
Subject: [PATCH] Support flashing output pane button.

- Add API to IOutputPane to 'flash' the panel button, if it is not open.
- Flash panel button when an error is added.

Change-Id: I842a1d789f28111be85bf4ffc1daf497bfbdc809
Reviewed-by: Daniel Teske <daniel.teske@nokia.com>
---
 src/plugins/coreplugin/ioutputpane.h         |  2 +
 src/plugins/coreplugin/outputpanemanager.cpp | 45 ++++++++++++++++++--
 src/plugins/coreplugin/outputpanemanager.h   |  9 +++-
 src/plugins/projectexplorer/taskwindow.cpp   |  5 +++
 4 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/src/plugins/coreplugin/ioutputpane.h b/src/plugins/coreplugin/ioutputpane.h
index bd73145866f..95999a7b56e 100644
--- a/src/plugins/coreplugin/ioutputpane.h
+++ b/src/plugins/coreplugin/ioutputpane.h
@@ -85,12 +85,14 @@ public slots:
     void toggle() { toggle(true); }
     void toggle(bool withFocusIfShown) { emit togglePage(withFocusIfShown); }
     void navigateStateChanged() { emit navigateStateUpdate(); }
+    void flash() { emit flashButton(); }
 
 signals:
     void showPage(bool withFocus, bool ensureSizeHint);
     void hidePage();
     void togglePage(bool withFocusIfShown);
     void navigateStateUpdate();
+    void flashButton();
 };
 
 } // namespace Core
diff --git a/src/plugins/coreplugin/outputpanemanager.cpp b/src/plugins/coreplugin/outputpanemanager.cpp
index 7e8e7bbc183..1fafdb2adbd 100644
--- a/src/plugins/coreplugin/outputpanemanager.cpp
+++ b/src/plugins/coreplugin/outputpanemanager.cpp
@@ -67,6 +67,7 @@
 #include <QStyle>
 #include <QStackedWidget>
 #include <QToolButton>
+#include <QTimeLine>
 
 namespace Core {
 namespace Internal {
@@ -261,6 +262,7 @@ void OutputPaneManager::init()
         connect(outPane, SIGNAL(hidePage()), this, SLOT(slotHide()));
         connect(outPane, SIGNAL(togglePage(bool)), this, SLOT(togglePage(bool)));
         connect(outPane, SIGNAL(navigateStateUpdate()), this, SLOT(updateNavigateState()));
+        connect(outPane, SIGNAL(flashButton()), this, SLOT(flashButton()));
 
         QWidget *toolButtonsContainer = new QWidget(m_opToolBarWidgets);
         QHBoxLayout *toolButtonsLayout = new QHBoxLayout;
@@ -286,8 +288,8 @@ void OutputPaneManager::init()
         m_ids.append(id);
 
         cmd->setDefaultKeySequence(QKeySequence(paneShortCut(shortcutNumber)));
-        QToolButton *button = new OutputPaneToggleButton(shortcutNumber, outPane->displayName(),
-                                                         cmd->action());
+        OutputPaneToggleButton *button = new OutputPaneToggleButton(shortcutNumber, outPane->displayName(),
+                                                                    cmd->action());
         ++shortcutNumber;
         m_buttonsWidget->layout()->addWidget(button);
         m_buttons.append(button);
@@ -351,7 +353,7 @@ void OutputPaneManager::slotMinMax()
 
 void OutputPaneManager::buttonTriggered()
 {
-    QToolButton *button = qobject_cast<QToolButton *>(sender());
+    OutputPaneToggleButton *button = qobject_cast<OutputPaneToggleButton *>(sender());
     buttonTriggered(m_buttons.indexOf(button));
 }
 
@@ -443,6 +445,14 @@ void OutputPaneManager::updateNavigateState()
     }
 }
 
+void OutputPaneManager::flashButton()
+{
+    IOutputPane* pane = qobject_cast<IOutputPane*>(sender());
+    int idx = findIndexForPage(pane);
+    if (pane)
+        m_buttons.value(idx)->flash();
+}
+
 // Slot connected to showPage signal of each page
 void OutputPaneManager::showPage(bool focus, bool ensureSizeHint)
 {
@@ -592,6 +602,7 @@ OutputPaneToggleButton::OutputPaneToggleButton(int number, const QString &text,
     , m_number(QString::number(number))
     , m_text(text)
     , m_action(action)
+    , m_flashTimer(new QTimeLine(1000, this))
 {
     setFocusPolicy(Qt::NoFocus);
     setCheckable(true);
@@ -600,6 +611,12 @@ OutputPaneToggleButton::OutputPaneToggleButton(int number, const QString &text,
     setStyleSheet(buttonStyleSheet());
     if (m_action)
         connect(m_action, SIGNAL(changed()), this, SLOT(updateToolTip()));
+
+    m_flashTimer->setDirection(QTimeLine::Forward);
+    m_flashTimer->setCurveShape(QTimeLine::SineCurve);
+    m_flashTimer->setFrameRange(0, 92);
+    connect(m_flashTimer, SIGNAL(valueChanged(qreal)), this, SLOT(update()));
+    connect(m_flashTimer, SIGNAL(finished()), this, SLOT(update()));
 }
 
 void OutputPaneToggleButton::updateToolTip()
@@ -631,6 +648,10 @@ void OutputPaneToggleButton::paintEvent(QPaintEvent *event)
     const int numberWidth = fm.width(m_number);
 
     QPainter p(this);
+    if (m_flashTimer->state() == QTimeLine::Running) {
+        p.setPen(Qt::transparent);
+        p.fillRect(rect().adjusted(19, 1, -1, -1), QBrush(QColor(255,0,0, m_flashTimer->currentFrame())));
+    }
     p.setFont(font());
     p.setPen(Qt::white);
     p.drawText((20 - numberWidth) / 2, baseLine, m_number);
@@ -640,6 +661,24 @@ void OutputPaneToggleButton::paintEvent(QPaintEvent *event)
     p.drawText(leftPart, baseLine, fm.elidedText(m_text, Qt::ElideRight, width() - leftPart - 1));
 }
 
+void OutputPaneToggleButton::checkStateSet()
+{
+    //Stop flashing when button is checked
+    QToolButton::checkStateSet();
+    m_flashTimer->stop();
+}
+
+void OutputPaneToggleButton::flash(int count)
+{
+    //Start flashing if button is not checked
+    if (!isChecked()) {
+        m_flashTimer->setLoopCount(count);
+        if (m_flashTimer->state() != QTimeLine::Running)
+            m_flashTimer->start();
+        update();
+    }
+}
+
 
 ///////////////////////////////////////////////////////////////////////
 //
diff --git a/src/plugins/coreplugin/outputpanemanager.h b/src/plugins/coreplugin/outputpanemanager.h
index b50118f9bc1..1f3900fce70 100644
--- a/src/plugins/coreplugin/outputpanemanager.h
+++ b/src/plugins/coreplugin/outputpanemanager.h
@@ -44,6 +44,7 @@ class QComboBox;
 class QLabel;
 class QSplitter;
 class QStackedWidget;
+class QTimeLine;
 QT_END_NAMESPACE
 
 namespace Core {
@@ -53,6 +54,7 @@ class IOutputPane;
 namespace Internal {
 
 class MainWindow;
+class OutputPaneToggleButton;
 class OutputPaneManageButton;
 
 class OutputPaneManager : public QWidget
@@ -85,6 +87,7 @@ private slots:
     void updateNavigateState();
     void popupMenu();
     void saveSettings() const;
+    void flashButton();
 
 private:
     // the only class that is allowed to create and destroy
@@ -121,7 +124,7 @@ private:
     QWidget *m_toolBar;
 
     QList<IOutputPane *> m_panes;
-    QVector<QToolButton *> m_buttons;
+    QVector<OutputPaneToggleButton *> m_buttons;
     QVector<QAction *> m_actions;
     QVector<Id> m_ids;
 
@@ -141,14 +144,18 @@ public:
                            QWidget *parent = 0);
     QSize sizeHint() const;
     void paintEvent(QPaintEvent *event);
+    void flash(int count = 3);
 
 private slots:
     void updateToolTip();
 
 private:
+    void checkStateSet();
+
     QString m_number;
     QString m_text;
     QAction *m_action;
+    QTimeLine *m_flashTimer;
 };
 
 class OutputPaneManageButton : public QToolButton
diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp
index 6312018f4e2..2410ba05b68 100644
--- a/src/plugins/projectexplorer/taskwindow.cpp
+++ b/src/plugins/projectexplorer/taskwindow.cpp
@@ -379,6 +379,11 @@ void TaskWindow::addTask(const Task &task)
 
     emit tasksChanged();
     navigateStateChanged();
+
+    if (task.type == Task::Error && d->m_filter->filterIncludesErrors() &&
+        !d->m_filter->filteredCategories().contains(task.category)) {
+        flash();
+    }
 }
 
 void TaskWindow::removeTask(const Task &task)
-- 
GitLab