From 44d02a652b4f3967fdf591693ee60fa521e7b96c Mon Sep 17 00:00:00 2001
From: Friedemann Kleint <Friedemann.Kleint@nokia.com>
Date: Thu, 18 Jun 2009 10:34:53 +0200
Subject: [PATCH] Further cleanup of watch code, do not evaluate "<Edit>"
 watcher.

---
 src/plugins/debugger/cdb/cdb.pri              |  1 +
 src/plugins/debugger/cdb/cdbdebugengine.cpp   | 78 ++++---------------
 src/plugins/debugger/cdb/cdbdebugengine_p.h   |  2 +-
 .../debugger/cdb/cdbstackframecontext.cpp     |  7 +-
 .../debugger/cdb/cdbsymbolgroupcontext_tpl.h  |  4 +-
 src/plugins/debugger/watchhandler.cpp         |  7 ++
 src/plugins/debugger/watchhandler.h           |  2 +
 src/plugins/debugger/watchwindow.cpp          |  6 +-
 8 files changed, 35 insertions(+), 72 deletions(-)

diff --git a/src/plugins/debugger/cdb/cdb.pri b/src/plugins/debugger/cdb/cdb.pri
index 009b97bb82b..06f14409d32 100644
--- a/src/plugins/debugger/cdb/cdb.pri
+++ b/src/plugins/debugger/cdb/cdb.pri
@@ -37,6 +37,7 @@ HEADERS += \
     $$PWD/cdbdebugeventcallback.h \
     $$PWD/cdbdebugoutput.h \
     $$PWD/cdbsymbolgroupcontext.h \
+    $$PWD/cdbsymbolgroupcontext_tpl.h \
     $$PWD/cdbstacktracecontext.h \
     $$PWD/cdbstackframecontext.h \
     $$PWD/cdbbreakpoint.h \
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp
index fdb2eb084fb..1134cd9065a 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp
@@ -650,23 +650,6 @@ bool CdbDebugEngine::startDebuggerWithExecutable(DebuggerStartMode sm, QString *
     return true;
 }
 
-// check for a breakpoint at 'main()'
-static inline bool hasBreakPointAtMain(const BreakHandler *bp)
-{
-    if (const int count = bp->size()) {
-        // check all variations, resolved or not
-        const QString main = QLatin1String("main");
-        const QString qMain = QLatin1String("qMain");
-        const QString moduleMainPattern = QLatin1String("!main");
-        for (int i = 0; i < count ; i++) {
-            const QString &function = bp->at(i)->funcName;
-            if (function == main || function == qMain || function.endsWith(moduleMainPattern))
-                return true;
-        }
-    }
-    return false;
-}
-
 void CdbDebugEnginePrivate::processCreatedAttached(ULONG64 processHandle, ULONG64 initialThreadHandle)
 {
     setDebuggeeHandles(reinterpret_cast<HANDLE>(processHandle), reinterpret_cast<HANDLE>(initialThreadHandle));
@@ -794,40 +777,9 @@ CdbStackFrameContext *CdbDebugEnginePrivate::getStackFrameContext(int frameIndex
     return 0;
 }
 
-static inline QString formatWatchList(const WatchList &wl)
-{
-    const int count = wl.size();
-    QString rc;
-    for (int i = 0; i < count; i++) {
-        if (i)
-            rc += QLatin1String(", ");
-        rc += wl.at(i).iname;
-        rc += QLatin1String(" (");
-        rc += wl.at(i).exp;
-        rc += QLatin1Char(')');
-    }
-    return rc;
-}
-
-bool CdbDebugEnginePrivate::updateLocals(int frameIndex,
-                                         WatchHandler *wh,
-                                         QString *errorMessage)
-{
-    wh->beginCycle();
-    if (debugCDB)
-        qDebug() << Q_FUNC_INFO << "\n    " << frameIndex;
-
-    bool success = false;
-    if (CdbStackFrameContext *sgc = getStackFrameContext(frameIndex, errorMessage))
-        success = sgc->populateModelInitially(wh, errorMessage);
-
-    wh->endCycle();
-    return success;
-}
-
 void CdbDebugEngine::evaluateWatcher(WatchData *wd)
 {
-    if (debugCDB > 1)
+    if (debugCDBWatchHandling)
         qDebug() << Q_FUNC_INFO << wd->exp;
     QString errorMessage;
     QString value;
@@ -844,12 +796,12 @@ void CdbDebugEngine::evaluateWatcher(WatchData *wd)
 
 void CdbDebugEngine::updateWatchData(const WatchData &incomplete)
 {
-    // Stack trace exists and evaluation funcs can only be called
-    // when running
-    if (m_d->isDebuggeeRunning()) {
-        qWarning("updateWatchModel() called while debuggee is running.");
-        return;    
-    }
+    // Watch item was edited while running
+    if (m_d->isDebuggeeRunning())
+        return;
+
+    if (debugCDBWatchHandling)
+        qDebug() << Q_FUNC_INFO << "\n    " << incomplete.toString();
 
     WatchHandler *watchHandler = m_d->m_debuggerManagerAccess->watchHandler();
     if (incomplete.iname.startsWith(QLatin1String("watch."))) {
@@ -861,9 +813,6 @@ void CdbDebugEngine::updateWatchData(const WatchData &incomplete)
 
     const int frameIndex = m_d->m_debuggerManagerAccess->stackHandler()->currentIndex();
 
-    if (debugCDB)
-        qDebug() << Q_FUNC_INFO << "\n    fi=" << frameIndex << incomplete.iname;
-
     bool success = false;
     QString errorMessage;
     do {
@@ -1199,12 +1148,14 @@ void CdbDebugEngine::activateFrame(int frameIndex)
             break;
         }
 
-        if (oldIndex != frameIndex || m_d->m_firstActivatedFrame)
-            if (!m_d->updateLocals(frameIndex, watchHandler, &errorMessage))
-                break;
-
         m_d->m_debuggerManager->gotoLocation(frame.file, frame.line, true);
-        success =true;
+
+        if (oldIndex != frameIndex || m_d->m_firstActivatedFrame) {
+            watchHandler->beginCycle();
+            if (CdbStackFrameContext *sgc = m_d->getStackFrameContext(frameIndex, &errorMessage))
+                success = sgc->populateModelInitially(watchHandler, &errorMessage);
+            watchHandler->endCycle();
+        }
     } while (false);
     if (!success)
         warning(msgFunctionFailed(Q_FUNC_INFO, errorMessage));
@@ -1545,6 +1496,7 @@ void CdbDebugEnginePrivate::updateStackTrace()
         m_debuggerManagerAccess->stackHandler()->setCurrentIndex(current);
         m_engine->activateFrame(current);
     }
+    m_debuggerManagerAccess->watchHandler()->updateWatchers();
 }
 
 void CdbDebugEnginePrivate::updateModules()
diff --git a/src/plugins/debugger/cdb/cdbdebugengine_p.h b/src/plugins/debugger/cdb/cdbdebugengine_p.h
index d3111737d36..23eb5648275 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine_p.h
+++ b/src/plugins/debugger/cdb/cdbdebugengine_p.h
@@ -117,7 +117,6 @@ struct CdbDebugEnginePrivate
     void handleDebugEvent();
     void updateThreadList();    
     void updateStackTrace();
-    bool updateLocals(int frameIndex, WatchHandler *wh, QString *errorMessage);
     void updateModules();
 
     void handleBreakpointEvent(PDEBUG_BREAKPOINT2 pBP);
@@ -182,6 +181,7 @@ QString msgDebugEngineComResult(HRESULT hr);
 QString msgComFailed(const char *func, HRESULT hr);
 
 enum { debugCDB = 0 };
+enum { debugCDBWatchHandling = 0 };
 
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/cdb/cdbstackframecontext.cpp b/src/plugins/debugger/cdb/cdbstackframecontext.cpp
index a3584310ffc..258f81d9949 100644
--- a/src/plugins/debugger/cdb/cdbstackframecontext.cpp
+++ b/src/plugins/debugger/cdb/cdbstackframecontext.cpp
@@ -28,6 +28,7 @@
 **************************************************************************/
 
 #include "cdbstackframecontext.h"
+#include "cdbdebugengine_p.h"
 #include "cdbsymbolgroupcontext.h"
 #include "cdbdumperhelper.h"
 #include "debuggeractions.h"
@@ -131,7 +132,7 @@ bool CdbStackFrameContext::assignValue(const QString &iname, const QString &valu
 
 bool CdbStackFrameContext::populateModelInitially(WatchHandler *wh, QString *errorMessage)
 {
-    if (debug)
+    if (debugCDBWatchHandling)
         qDebug() << "populateModelInitially";
     const bool rc = m_useDumpers ?
         CdbSymbolGroupContext::populateModelInitially(m_symbolContext,
@@ -149,8 +150,8 @@ bool CdbStackFrameContext::completeData(const WatchData &incompleteLocal,
                                         WatchHandler *wh,
                                         QString *errorMessage)
 {
-    if (debug)
-        qDebug() << ">completeData " << incompleteLocal.iname;
+    if (debugCDBWatchHandling)
+        qDebug() << ">completeData " << incompleteLocal.iname << " src=" << incompleteLocal.source;
 
     if (!m_useDumpers) {
         return CdbSymbolGroupContext::completeData(m_symbolContext, incompleteLocal,
diff --git a/src/plugins/debugger/cdb/cdbsymbolgroupcontext_tpl.h b/src/plugins/debugger/cdb/cdbsymbolgroupcontext_tpl.h
index afa6e49c722..be9e4b6082a 100644
--- a/src/plugins/debugger/cdb/cdbsymbolgroupcontext_tpl.h
+++ b/src/plugins/debugger/cdb/cdbsymbolgroupcontext_tpl.h
@@ -202,7 +202,9 @@ bool CdbSymbolGroupContext::completeData(CdbSymbolGroupContext *sg,
     const bool contextExpanded = sg->isExpanded(incompleteLocal.iname);
     if (debugSgRecursion)
         qDebug() << "  " << incompleteLocal.iname << "CE=" << contextExpanded;
-    if (contextExpanded) { // TODO: Legacy, should not be required any more
+    // The view reinserts any node being expanded with flag 'ChildrenNeeded'.
+    // Recurse down one level in context unless this is already the case.
+    if (contextExpanded) {
         incompleteLocal.setChildrenUnneeded();
         *it = incompleteLocal;
         ++it;
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index b6b0d68f3c1..f9ae90d9cfe 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -879,6 +879,8 @@ void WatchHandler::watchExpression(const QString &exp)
     WatchData data;
     data.exp = exp;
     data.name = exp;
+    if (exp == watcherEditPlaceHolder())
+        data.setAllUnneeded();
     data.iname = watcherName(exp);
     insertData(data);
     saveWatchers();
@@ -1063,5 +1065,10 @@ WatchData *WatchHandler::findItem(const QString &iname) const
     return model->findItem(iname, model->m_root);
 }
 
+QString WatchHandler::watcherEditPlaceHolder()
+{
+    static const QString rc = tr("<Edit>");
+    return rc;
+}
 } // namespace Internal
 } // namespace Debugger
diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h
index 9fcf4956261..8c679b823a1 100644
--- a/src/plugins/debugger/watchhandler.h
+++ b/src/plugins/debugger/watchhandler.h
@@ -210,6 +210,8 @@ public:
     QSet<QString> expandedINames() const
         { return m_expandedINames; }
 
+    static QString watcherEditPlaceHolder();
+
 signals:
     void watchDataUpdateNeeded(const WatchData &data);
     void sessionValueRequested(const QString &name, QVariant *value);
diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp
index c6c07ed7ce3..9a11053dad5 100644
--- a/src/plugins/debugger/watchwindow.cpp
+++ b/src/plugins/debugger/watchwindow.cpp
@@ -28,6 +28,7 @@
 **************************************************************************/
 
 #include "watchwindow.h"
+#include "watchhandler.h"
 
 #include "debuggeractions.h"
 
@@ -54,8 +55,6 @@ using namespace Debugger::Internal;
 //
 /////////////////////////////////////////////////////////////////////
 
-enum { INameRole = Qt::UserRole, ExpressionRole, ExpandedRole };
-
 class WatchDelegate : public QItemDelegate
 {
 public:
@@ -64,7 +63,6 @@ public:
     QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &,
         const QModelIndex &) const
     {
-        qDebug() << "CREATE EDITOR";
         return new QLineEdit(parent);
     }
 
@@ -236,7 +234,7 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
     else if (act == act2)
         setAlwaysResizeColumnsToContents(!m_alwaysResizeColumnsToContents);
     else if (act == act3)
-        theDebuggerAction(WatchExpression)->trigger(tr("<Edit>"));
+        theDebuggerAction(WatchExpression)->trigger(WatchHandler::watcherEditPlaceHolder());
 }
 
 void WatchWindow::resizeColumnsToContents()
-- 
GitLab