From d130588469c6a440570d24377a1639be31945177 Mon Sep 17 00:00:00 2001
From: hjk <qtc-committer@nokia.com>
Date: Tue, 6 Oct 2009 10:54:08 +0200
Subject: [PATCH] debugger: add option to automatically derefence pointers in
 locals&watchers

---
 src/plugins/debugger/debuggeractions.cpp | 10 ++++++
 src/plugins/debugger/debuggeractions.h   |  1 +
 src/plugins/debugger/debuggerplugin.cpp  |  1 +
 src/plugins/debugger/gdb/gdbengine.cpp   | 43 +++++++++++++++---------
 src/plugins/debugger/gdb/gdbengine.h     |  2 ++
 src/plugins/debugger/idebuggerengine.h   |  1 +
 src/plugins/debugger/watchwindow.cpp     |  5 +++
 7 files changed, 47 insertions(+), 16 deletions(-)

diff --git a/src/plugins/debugger/debuggeractions.cpp b/src/plugins/debugger/debuggeractions.cpp
index c5f3addd1d6..a2c1da01721 100644
--- a/src/plugins/debugger/debuggeractions.cpp
+++ b/src/plugins/debugger/debuggeractions.cpp
@@ -162,6 +162,16 @@ DebuggerSettings *DebuggerSettings::instance()
         "disassembled instructions."));
     instance->insertItem(OperateByInstruction, item);
 
+    item = new SavedAction(instance);
+    item->setText(tr("Dereference pointers automatically"));
+    item->setCheckable(true);
+    item->setDefaultValue(true);
+    item->setToolTip(tr("This switches the Locals&Watchers view to "
+        "automatically derefence pointers. This saves a level in the "
+        "tree view, but also loses data for the now-missing intermediate "
+        "level."));
+    instance->insertItem(AutoDerefPointers, item);
+
     //
     // Locals & Watchers
     //
diff --git a/src/plugins/debugger/debuggeractions.h b/src/plugins/debugger/debuggeractions.h
index 8e1937f23bd..ffc334b268f 100644
--- a/src/plugins/debugger/debuggeractions.h
+++ b/src/plugins/debugger/debuggeractions.h
@@ -78,6 +78,7 @@ enum DebuggerActionCode
     LockView,
     LogTimeStamps,
     OperateByInstruction,
+    AutoDerefPointers,
 
     RecheckDebuggingHelpers,
     UseDebuggingHelpers,
diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp
index a4de205f95a..3af293e3e6f 100644
--- a/src/plugins/debugger/debuggerplugin.cpp
+++ b/src/plugins/debugger/debuggerplugin.cpp
@@ -295,6 +295,7 @@ QWidget *CommonOptionsPage::createPage(QWidget *parent)
         m_ui.checkBoxSkipKnownFrames);
     m_group.insert(theDebuggerAction(UseToolTipsInMainEditor), 
         m_ui.checkBoxUseToolTipsInMainEditor);
+    m_group.insert(theDebuggerAction(AutoDerefPointers), 0);
     m_group.insert(theDebuggerAction(UseToolTipsInLocalsView), 0);
     m_group.insert(theDebuggerAction(UseToolTipsInBreakpointsView), 0);
     m_group.insert(theDebuggerAction(UseAddressInBreakpointsView), 0);
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 8a12c3061c9..8e3cf81e36f 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -203,6 +203,9 @@ GdbEngine::GdbEngine(DebuggerManager *manager) :
     connect(this, SIGNAL(applicationOutputAvailable(QString)),
         m_manager, SLOT(showApplicationOutput(QString)),
         Qt::QueuedConnection);
+
+    connect(theDebuggerAction(AutoDerefPointers), SIGNAL(valueChanged(QVariant)),
+            this, SLOT(setAutoDerefPointers(QVariant)));
 }
 
 void GdbEngine::connectDebuggingHelperActions()
@@ -2703,6 +2706,13 @@ void GdbEngine::setUseDebuggingHelpers(const QVariant &on)
     updateLocals();
 }
 
+void GdbEngine::setAutoDerefPointers(const QVariant &on)
+{
+    Q_UNUSED(on)
+    setTokenBarrier();
+    updateLocals();
+}
+
 bool GdbEngine::hasDebuggingHelperForType(const QString &type) const
 {
     if (!theDebuggerBoolSetting(UseDebuggingHelpers))
@@ -2864,22 +2874,23 @@ void GdbEngine::updateSubItem(const WatchData &data0)
         #if DEBUG_SUBITEM
         qDebug() << "IT'S A POINTER";
         #endif
-#if 1
-        data.setChildrenUnneeded();
-        insertData(data);
-        WatchData data1;
-        data1.iname = data.iname + QLatin1String(".*");
-        data1.name = QLatin1Char('*') + data.name;
-        data1.exp = QLatin1String("(*(") + data.exp + QLatin1String("))");
-        data1.type = stripPointerType(data.type);
-        data1.setValueNeeded();
-        insertData(data1);
-#else
-        // Try automatic dereferentiation
-        data.exp = _("*(") + data.exp + _(")");
-        data.type = data.type + _("."); // FIXME: fragile HACK to avoid recursion
-        insertData(data);
-#endif
+    
+        if (theDebuggerBoolSetting(AutoDerefPointers)) {
+            // Try automatic dereferentiation
+            data.exp = _("(*(") + data.exp + _("))");
+            data.type = data.type + _("."); // FIXME: fragile HACK to avoid recursion
+            insertData(data);
+        } else {
+            data.setChildrenUnneeded();
+            insertData(data);
+            WatchData data1;
+            data1.iname = data.iname + QLatin1String(".*");
+            data1.name = QLatin1Char('*') + data.name;
+            data1.exp = QLatin1String("(*(") + data.exp + QLatin1String("))");
+            data1.type = stripPointerType(data.type);
+            data1.setValueNeeded();
+            insertData(data1);
+        }
         return;
     }
 
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index 6b5b5ebcb9e..a3135449f52 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -147,6 +147,8 @@ private:
 
     Q_SLOT void setDebugDebuggingHelpers(const QVariant &on);
     Q_SLOT void setUseDebuggingHelpers(const QVariant &on);
+    Q_SLOT void setAutoDerefPointers(const QVariant &on);
+    virtual bool isGdbEngine() const { return true; }
 
     //
     // Own stuff
diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h
index db990fa9389..c4d7202152d 100644
--- a/src/plugins/debugger/idebuggerengine.h
+++ b/src/plugins/debugger/idebuggerengine.h
@@ -116,6 +116,7 @@ public:
         { Q_UNUSED(regnr); Q_UNUSED(value); }
 
     virtual void addOptionPages(QList<Core::IOptionsPage*> *) const {}
+    virtual bool isGdbEngine() const { return false; }
 
 protected:
     void showStatusMessage(const QString &msg, int timeout = -1);
diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp
index ca5e6425b79..f40bb93085d 100644
--- a/src/plugins/debugger/watchwindow.cpp
+++ b/src/plugins/debugger/watchwindow.cpp
@@ -34,6 +34,7 @@
 #include "debuggeragents.h"
 #include "debuggerdialogs.h"
 #include "debuggermanager.h"
+#include "idebuggerengine.h"
 
 #include <utils/qtcassert.h>
 
@@ -274,6 +275,10 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
 
     menu.addSeparator();
     menu.addAction(theDebuggerAction(UseToolTipsInLocalsView));
+    
+    menu.addAction(theDebuggerAction(AutoDerefPointers));
+    theDebuggerAction(AutoDerefPointers)->
+        setEnabled(m_manager->currentEngine()->isGdbEngine());
     QAction *actAdjustColumnWidths =
         menu.addAction(tr("Adjust column widths to contents"));
     QAction *actAlwaysAdjustColumnWidth =
-- 
GitLab