From 8d3a774fc2146bcad47e82e80a7c446b61e1ac69 Mon Sep 17 00:00:00 2001
From: hjk <qtc-committer@nokia.com>
Date: Mon, 8 Dec 2008 14:26:11 +0100
Subject: [PATCH] new status widget for debugger output. needs a bit more
 polishing...

---
 src/plugins/debugger/debuggermanager.cpp | 31 +++++++------
 src/plugins/debugger/debuggermanager.h   | 14 ++++--
 src/plugins/debugger/gdbengine.cpp       | 58 ++++++++++++------------
 src/plugins/debugger/mode.cpp            |  2 +
 4 files changed, 59 insertions(+), 46 deletions(-)

diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index a94b1fb0931..11e7ef6c82d 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -62,6 +62,7 @@
 #include <QtCore/QDir>
 #include <QtCore/QFileInfo>
 #include <QtCore/QTime>
+#include <QtCore/QTimer>
 
 #include <QtGui/QAction>
 #include <QtGui/QComboBox>
@@ -145,6 +146,7 @@ void DebuggerManager::init()
     m_modulesHandler = 0;
     m_registerHandler = 0;
 
+    m_statusLabel = new QLabel;
     m_breakWindow = new BreakWindow;
     m_disassemblerWindow = new DisassemblerWindow;
     m_modulesWindow = new ModulesWindow;
@@ -157,6 +159,7 @@ void DebuggerManager::init()
     //m_tooltipWindow = new WatchWindow(WatchWindow::TooltipType);
     //m_watchersWindow = new QTreeView;
     m_tooltipWindow = new QTreeView;
+    m_statusTimer = new QTimer(this);
 
     m_mainWindow = new QMainWindow;
     m_mainWindow->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
@@ -408,6 +411,8 @@ void DebuggerManager::init()
         this, SLOT(saveSessionData()));
     connect(m_dumpLogAction, SIGNAL(triggered()),
         this, SLOT(dumpLog()));
+    connect(m_statusTimer, SIGNAL(timeout()),
+        this, SLOT(clearStatusMessage()));
 
     connect(m_outputWindow, SIGNAL(commandExecutionRequested(QString)),
         this, SLOT(executeDebuggerCommand(QString)));
@@ -553,24 +558,24 @@ QAbstractItemModel *DebuggerManager::threadsModel()
     return qobject_cast<ThreadsWindow*>(m_threadsWindow)->model();
 }
 
+void DebuggerManager::clearStatusMessage()
+{
+    m_statusLabel->setText(m_lastPermanentStatusMessage);
+}
+
 void DebuggerManager::showStatusMessage(const QString &msg, int timeout)
 {
     Q_UNUSED(timeout)
     //qDebug() << "STATUS: " << msg;
     showDebuggerOutput("status:", msg);
-    mainWindow()->statusBar()->showMessage(msg, timeout);
-#if 0
-    QString currentTime = QTime::currentTime().toString("hh:mm:ss.zzz");
-
-    ICore *core = m_pm->getObject<Core::ICore>();
-    //qDebug() << qPrintable(currentTime) << "Setting status:    " << msg;
-    if (msg.isEmpty())
-        core->messageManager()->displayStatusBarMessage(msg);
-    else if (timeout == -1)
-        core->messageManager()->displayStatusBarMessage(tr("Debugger: ") + msg);
-    else
-        core->messageManager()->displayStatusBarMessage(tr("Debugger: ") + msg, timeout);
-#endif
+    m_statusLabel->setText("   " + msg);
+    if (timeout > 0) {
+        m_statusTimer->setSingleShot(true);
+        m_statusTimer->start(timeout);
+    } else {
+        m_lastPermanentStatusMessage = msg;
+        m_statusTimer->stop();
+    }
 }
 
 void DebuggerManager::notifyStartupFinished()
diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h
index fd1e7cf5cba..63c225411fc 100644
--- a/src/plugins/debugger/debuggermanager.h
+++ b/src/plugins/debugger/debuggermanager.h
@@ -44,9 +44,11 @@ QT_BEGIN_NAMESPACE
 class QAction;
 class QAbstractItemModel;
 class QDockWidget;
+class QLabel;
 class QMainWindow;
 class QModelIndex;
 class QSplitter;
+class QTimer;
 class QWidget;
 QT_END_NAMESPACE
 
@@ -190,7 +192,8 @@ public:
 private:
     friend class DebugMode;
 
-    virtual QWidget *threadsWindow() = 0;
+    virtual QWidget *threadsWindow() const = 0;
+    virtual QLabel *statusLabel() const = 0;
     virtual QList<QDockWidget*> dockWidgets() const = 0;
     virtual void createDockWidgets() = 0;
 };
@@ -213,6 +216,7 @@ public:
     IDebuggerManagerAccessForEngines *engineInterface();
     IDebuggerManagerAccessForDebugMode *debugModeInterface();
     QMainWindow *mainWindow() const { return m_mainWindow; }
+    QLabel *statusLabel() const { return m_statusLabel; }
 
     enum StartMode { startInternal, startExternal, attachExternal };
     enum DebuggerType { GdbDebugger, ScriptDebugger, WinDebugger };
@@ -272,7 +276,7 @@ public slots:
     void assignValueInDebugger(const QString &expr, const QString &value);
     void executeDebuggerCommand(const QString &command);
 
-    void showStatusMessage(const QString &msg, int timeout); // -1 forever
+    void showStatusMessage(const QString &msg, int timeout = -1); // -1 forever
 
 private slots:
     void showDebuggerOutput(const QString &prefix, const QString &msg);
@@ -290,6 +294,7 @@ private slots:
     void reloadRegisters();
     void registerDockToggled(bool on);
     void setStatus(int status);
+    void clearStatusMessage();
 
 private:
     //
@@ -322,7 +327,7 @@ private:
     //
     // Implementation of IDebuggerManagerAccessForDebugMode
     //
-    QWidget *threadsWindow() { return m_threadsWindow; }
+    QWidget *threadsWindow() const { return m_threadsWindow; }
     QList<QDockWidget*> dockWidgets() const { return m_dockWidgets; }
     void createDockWidgets();
 
@@ -382,6 +387,7 @@ private:
 
     /// Views
     QMainWindow *m_mainWindow;
+    QLabel *m_statusLabel;
     QDockWidget *m_breakDock;
     QDockWidget *m_disassemblerDock;
     QDockWidget *m_modulesDock;
@@ -440,6 +446,8 @@ private:
 
     int m_status;
     bool m_busy;
+    QTimer *m_statusTimer;
+    QString m_lastPermanentStatusMessage;
 
     IDebuggerEngine *engine();
     IDebuggerEngine *m_engine;
diff --git a/src/plugins/debugger/gdbengine.cpp b/src/plugins/debugger/gdbengine.cpp
index 9336981b128..5fce8a96555 100644
--- a/src/plugins/debugger/gdbengine.cpp
+++ b/src/plugins/debugger/gdbengine.cpp
@@ -347,7 +347,7 @@ void GdbEngine::gdbProcError(QProcess::ProcessError error)
                 "This is the default return value of error().");
     }
 
-    q->showStatusMessage(msg, 5000);
+    q->showStatusMessage(msg);
     QMessageBox::critical(q->mainWindow(), tr("Error"), msg);
     // act as if it was closed by the core
     q->exitDebugger();
@@ -710,7 +710,7 @@ void GdbEngine::sendCommand(const QString &command, int type,
 
     bool temporarilyStopped = false;
     if (needStop && q->status() == DebuggerInferiorRunning) {
-        q->showStatusMessage(tr("Temporarily stopped"), -1);
+        q->showStatusMessage(tr("Temporarily stopped"));
         interruptInferior();
         temporarilyStopped = true;
     }
@@ -1055,7 +1055,7 @@ void GdbEngine::handleExecJumpToLine(const GdbResultRecord &record)
     // ~"242\t x *= 2;"
     //109^done"
     qq->notifyInferiorStopped();
-    q->showStatusMessage(tr("Jumped. Stopped."), -1);
+    q->showStatusMessage(tr("Jumped. Stopped."));
     QString output = record.data.findChild("logstreamoutput").data();
     if (!output.isEmpty())
         return;
@@ -1074,7 +1074,7 @@ void GdbEngine::handleExecRunToFunction(const GdbResultRecord &record)
     // func="foo",args=[{name="str",value="@0x7fff0f450460"}],
     // file="main.cpp",fullname="/tmp/g/main.cpp",line="37"}
     qq->notifyInferiorStopped();
-    q->showStatusMessage(tr("Run to Function finished. Stopped."), -1);
+    q->showStatusMessage(tr("Run to Function finished. Stopped."));
     GdbMi frame = record.data.findChild("frame");
     QString file = frame.findChild("fullname").data();
     int line = frame.findChild("line").data().toInt();
@@ -1212,7 +1212,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
             }
         } else {
             // slow start requested.
-            q->showStatusMessage("Loading " + data.toString(), -1);
+            q->showStatusMessage(tr("Loading %1...").arg(QString(data.toString())));
             continueInferior();
         }
         return;
@@ -1231,7 +1231,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
             msg = "Program exited after receiving signal "
                 + data.findChild("signal-name").toString();
         }
-        q->showStatusMessage(msg, -1);
+        q->showStatusMessage(msg);
         q->exitDebugger();
         return;
     }
@@ -1271,7 +1271,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
     if (isStoppedReason(reason) || reason.isEmpty()) {
         // Need another round trip
         if (reason == "breakpoint-hit") {
-            q->showStatusMessage(tr("Stopped at breakpoint."), -1);
+            q->showStatusMessage(tr("Stopped at breakpoint"));
             GdbMi frame = data.findChild("frame");
             //qDebug() << frame.toString();
             m_currentFrame = frame.findChild("addr").data() + '%' +
@@ -1283,7 +1283,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
             QVariant var = QVariant::fromValue<GdbMi>(data);
             sendCommand("p 0", GdbAsyncOutput2, var);  // dummy
         } else {
-            q->showStatusMessage(tr("Stopped. %1").arg(reason), -1);
+            q->showStatusMessage(tr("Stopped. Reason: \"%1\"").arg(reason));
             handleAsyncOutput2(data);
         }
         return;
@@ -1305,7 +1305,7 @@ void GdbEngine::handleAsyncOutput(const GdbMi &data)
     // system="0.00136",start="1218810678.805432",end="1218810678.812011"}
     q->resetLocation();
     qq->notifyInferiorStopped();
-    q->showStatusMessage(tr("Run to Function finished. Stopped."), -1);
+    q->showStatusMessage(tr("Run to Function finished. Stopped."));
     GdbMi frame = data.findChild("frame");
     QString file = frame.findChild("fullname").data();
     int line = frame.findChild("line").data().toInt();
@@ -1378,8 +1378,9 @@ void GdbEngine::handleShowVersion(const GdbResultRecord &response)
     if (response.resultClass == GdbResultDone) {
         m_gdbVersion = 100;
         QString msg = response.data.findChild("consolestreamoutput").data();
-        QRegExp supported("GNU gdb 6.[6789]");
-        if (msg.indexOf(supported) == -1) {
+        QRegExp supported("GNU gdb(.*) (\\d+)\\.(\\d+)\\.(\\d+)");
+        if (supported.indexIn(msg) == -1) {
+            qDebug() << "UNSUPPORTED GDB VERSION " << msg;
             QStringList list = msg.split("\n");
             while (list.size() > 2)
                 list.removeLast();
@@ -1396,11 +1397,11 @@ void GdbEngine::handleShowVersion(const GdbResultRecord &response)
 #else
             //QMessageBox::information(m_mainWindow, tr("Warning"), msg);
 #endif
-        }
-        int pos = msg.indexOf("GNU gdb 6.");
-        if (pos != -1) {
-            m_gdbVersion = 600 + (msg.at(pos + 10).unicode() - '0') * 10;
-            //qDebug() << "GDB VERSION " << m_gdbVersion << msg;
+        } else {
+            m_gdbVersion = 10000 * supported.cap(2).toInt()
+                         +   100 * supported.cap(3).toInt()
+                         +     1 * supported.cap(4).toInt();
+            //qDebug() << "GDB VERSION " << m_gdbVersion;
         }
     }
 }
@@ -1423,14 +1424,14 @@ void GdbEngine::handleExecRun(const GdbResultRecord &response)
 {
     if (response.resultClass == GdbResultRunning) {
         qq->notifyInferiorRunning();
-        q->showStatusMessage(tr("Running..."), -1);
+        q->showStatusMessage(tr("Running..."));
         //reloadModules();
     } else if (response.resultClass == GdbResultError) {
         QString msg = response.data.findChild("msg").data();
         if (msg == "Cannot find bounds of current function") {
             qq->notifyInferiorStopped();
             //q->showStatusMessage(tr("No debug information available. "
-            //  "Leaving function..."), -1);
+            //  "Leaving function..."));
             //stepOutExec();
         } else {
             QMessageBox::critical(q->mainWindow(), tr("Error"),
@@ -1558,7 +1559,7 @@ bool GdbEngine::startDebugger()
     qDebug() << "ExeFile: " << q->m_executable;
     #endif
 
-    q->showStatusMessage("Starting Debugger", -1);
+    q->showStatusMessage(tr("Starting Debugger"));
     emit gdbInputAvailable(QString(), theGdbSettings().m_gdbCmd + ' ' + gdbArgs.join(" "));
 
     m_gdbProc.start(theGdbSettings().m_gdbCmd, gdbArgs);
@@ -1567,7 +1568,7 @@ bool GdbEngine::startDebugger()
     if (m_gdbProc.state() != QProcess::Running)
         return false;
 
-    q->showStatusMessage(tr("Gdb Running"), -1);
+    q->showStatusMessage(tr("Gdb Running"));
 
     sendCommand("show version", GdbShowVersion);
     if (qq->useFastStart()) {
@@ -2337,8 +2338,8 @@ void GdbEngine::handleModulesList(const GdbResultRecord &record)
 void GdbEngine::handleStackSelectThread(const GdbResultRecord &record, int)
 {
     Q_UNUSED(record);
-    qDebug("FIXME: StackHandler::handleOutput: SelectThread");
-    q->showStatusMessage(tr("Retrieving data for stack view..."), -1);
+    //qDebug("FIXME: StackHandler::handleOutput: SelectThread");
+    q->showStatusMessage(tr("Retrieving data for stack view..."), 3000);
     sendCommand("-stack-list-frames", StackListFrames);
 }
 
@@ -2432,7 +2433,7 @@ void GdbEngine::selectThread(int index)
     QList<ThreadData> threads = threadsHandler->threads();
     QWB_ASSERT(index < threads.size(), return);
     int id = threads.at(index).id;
-    q->showStatusMessage(tr("Retrieving data for stack view..."), -1);
+    q->showStatusMessage(tr("Retrieving data for stack view..."), 10000);
     sendCommand(QLatin1String("-thread-select ") + QString::number(id),
         StackSelectThread);
 }
@@ -2545,7 +2546,7 @@ bool GdbEngine::supportsThreads() const
 {
     // 6.3 crashes happily on -thread-list-ids. So don't use it.
     // The test below is a semi-random pick, 6.8 works fine
-    return m_gdbVersion > 650;
+    return m_gdbVersion > 60500;
 }
 
 //////////////////////////////////////////////////////////////////////
@@ -3081,7 +3082,7 @@ void GdbEngine::runCustomDumper(const WatchData & data0, bool dumpChildren)
 
     q->showStatusMessage(
         tr("Retrieving data for watch view (%1 requests pending)...")
-            .arg(m_pendingRequests + 1), -1);
+            .arg(m_pendingRequests + 1), 10000);
     // create response slot for socket data
     QVariant var;
     var.setValue(data);
@@ -3299,7 +3300,7 @@ void GdbEngine::updateWatchModel2()
     PENDING_DEBUG("REBUILDING MODEL")
     emit gdbInputAvailable(QString(),
         "[" + currentTime() + "]    <Rebuild Watchmodel>");
-    q->showStatusMessage(tr("Finished retrieving data."), -1);
+    q->showStatusMessage(tr("Finished retrieving data."), 400);
     qq->watchHandler()->rebuildModel();
 
     if (!m_toolTipExpression.isEmpty()) {
@@ -3313,9 +3314,6 @@ void GdbEngine::updateWatchModel2()
                 "Cannot evaluate expression: " + m_toolTipExpression);
         }
     }
-
-    //qDebug() << "INSERT DATA" << data0.toString();
-    //q->showStatusMessage(tr("Stopped."), 5000);
 }
 
 void GdbEngine::handleQueryDataDumper1(const GdbResultRecord &record)
@@ -3897,7 +3895,7 @@ void GdbEngine::handleToolTip(const GdbResultRecord &record,
             if (isCustomValueDumperAvailable(m_toolTip.type))
                 runCustomDumper(m_toolTip, false);
             else
-                q->showStatusMessage(tr("Retrieving data for tooltip..."), -1);
+                q->showStatusMessage(tr("Retrieving data for tooltip..."), 10000);
                 sendCommand("-data-evaluate-expression " + m_toolTip.exp,
                     WatchToolTip, "evaluate");
                 //sendToolTipCommand("-var-evaluate-expression tooltip")
diff --git a/src/plugins/debugger/mode.cpp b/src/plugins/debugger/mode.cpp
index 3eef7dc8329..2229cbfe6f5 100644
--- a/src/plugins/debugger/mode.cpp
+++ b/src/plugins/debugger/mode.cpp
@@ -169,6 +169,8 @@ QToolBar *DebugMode::createToolBar()
         managerAccess->threadsWindow(), SIGNAL(threadSelected(int)));
     debugToolBar->addWidget(threadBox);
 
+    debugToolBar->addWidget(managerAccess->statusLabel());
+
     QWidget *stretch = new QWidget;
     stretch->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
     debugToolBar->addWidget(stretch);
-- 
GitLab