From 15a595b429ee1d0a7d1defc8397d8531164bc240 Mon Sep 17 00:00:00 2001
From: hjk <qtc-committer@nokia.com>
Date: Mon, 3 May 2010 19:12:52 +0200
Subject: [PATCH] debugger: refactor module/symbol view

---
 share/qtcreator/gdbmacros/pdumper.py         | 39 ++++++++++++++--
 src/plugins/debugger/cdb/cdbdebugengine.cpp  |  4 +-
 src/plugins/debugger/cdb/cdbdebugengine.h    |  2 +-
 src/plugins/debugger/debuggermanager.cpp     | 30 ++++++++++--
 src/plugins/debugger/debuggermanager.h       |  4 +-
 src/plugins/debugger/gdb/gdbengine.cpp       |  4 +-
 src/plugins/debugger/gdb/gdbengine.h         |  2 +-
 src/plugins/debugger/idebuggerengine.h       |  2 +-
 src/plugins/debugger/moduleshandler.cpp      | 11 +++--
 src/plugins/debugger/moduleshandler.h        |  1 +
 src/plugins/debugger/moduleswindow.cpp       | 25 ++--------
 src/plugins/debugger/pdb/pdbengine.cpp       | 48 +++++++++++++++++++-
 src/plugins/debugger/pdb/pdbengine.h         |  5 +-
 src/plugins/debugger/script/scriptengine.cpp |  3 +-
 src/plugins/debugger/script/scriptengine.h   |  2 +-
 15 files changed, 135 insertions(+), 47 deletions(-)

diff --git a/share/qtcreator/gdbmacros/pdumper.py b/share/qtcreator/gdbmacros/pdumper.py
index 8ca75eb3353..96addcc951d 100644
--- a/share/qtcreator/gdbmacros/pdumper.py
+++ b/share/qtcreator/gdbmacros/pdumper.py
@@ -16,7 +16,12 @@ class qdebug:
         self.typeformats = typeformats
         self.individualformats = individualformats
         self.watchers = watchers
-        self.doit()
+        if self.options == "listmodules":
+            self.handleListModules()
+        elif self.options == "listsymbols":
+            self.handleListSymbols(expanded)
+        else:
+            self.handleListVars()
 
     def put(self, value):
         sys.stdout.write(value)
@@ -90,6 +95,9 @@ class qdebug:
             return
         if str(value).startswith("<class '"):
             return
+        # FIXME: Should we?
+        if str(value).startswith("<enum-item "):
+            return
         self.put("{")
         self.putField("iname", iname)
         self.putName(name)
@@ -146,13 +154,15 @@ class qdebug:
             pass
         elif tt == "function":
             pass
+        elif str(value).startswith("<enum-item "):
+            # FIXME: Having enums always shown like this is not nice.
+            self.putValue(str(value)[11:-1])
+            self.putNumChild(0)
         else:
             v = str(value)
             p = v.find(" object at ")
             if p > 1:
                 v = "@" + v[p + 11:-1]
-            elif v.startswith("<enum-item "):
-                v = v[11:-1]
             self.putValue(v)
             if self.isExpanded(iname):
                 self.put("children=[")
@@ -177,7 +187,7 @@ class qdebug:
     def warn(self, msg):
         self.putField("warning", msg)
 
-    def doit(self):
+    def handleListVars(self):
         # Trigger error to get a backtrace.
         frame = None
         #self.warn("frame: %s" % frame)
@@ -207,3 +217,24 @@ class qdebug:
             n = n + 1
 
         sys.stdout.flush()
+
+    def handleListModules(self):
+        self.put("modules=[");
+        for name in sys.modules:
+            self.put("{")
+            self.putName(name)
+            self.putValue(sys.modules[name])
+            self.put("},")
+        self.put("]")
+        sys.stdout.flush()
+
+    def handleListSymbols(self, module):
+        #self.put("symbols=%s" % dir(sys.modules[module]))
+        self.put("symbols=[");
+        for name in sys.modules:
+            self.put("{")
+            self.putName(name)
+            #self.putValue(sys.modules[name])
+            self.put("},")
+        self.put("]")
+        sys.stdout.flush()
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.cpp b/src/plugins/debugger/cdb/cdbdebugengine.cpp
index cb7bbf55d40..26eb61b118f 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.cpp
+++ b/src/plugins/debugger/cdb/cdbdebugengine.cpp
@@ -1183,7 +1183,7 @@ void CdbDebugEngine::loadAllSymbols()
         qDebug() << Q_FUNC_INFO;
 }
 
-QList<Symbol> CdbDebugEngine::moduleSymbols(const QString &moduleName)
+void> CdbDebugEngine::requestModuleSymbols(const QString &moduleName)
 {
     QList<Symbol> rc;
     QString errorMessage;
@@ -1199,7 +1199,7 @@ QList<Symbol> CdbDebugEngine::moduleSymbols(const QString &moduleName)
     } while (false);
     if (!success)
         warning(errorMessage);
-    return rc;
+    manager()->showModuleSymbols(moduleName, rc);
 }
 
 void CdbDebugEngine::reloadRegisters()
diff --git a/src/plugins/debugger/cdb/cdbdebugengine.h b/src/plugins/debugger/cdb/cdbdebugengine.h
index e15d5e93e13..452f8df87ff 100644
--- a/src/plugins/debugger/cdb/cdbdebugengine.h
+++ b/src/plugins/debugger/cdb/cdbdebugengine.h
@@ -95,7 +95,7 @@ public:
     virtual void reloadModules();
     virtual void loadSymbols(const QString &moduleName);
     virtual void loadAllSymbols();
-    virtual QList<Symbol> moduleSymbols(const QString &moduleName);
+    virtual void requestModuleSymbols(const QString &moduleName);
 
     virtual void reloadRegisters();
     virtual void reloadSourceFiles();
diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp
index c6bf0494bd1..ac645e19c3f 100644
--- a/src/plugins/debugger/debuggermanager.cpp
+++ b/src/plugins/debugger/debuggermanager.cpp
@@ -98,6 +98,7 @@
 #include <QtGui/QTextCursor>
 #include <QtGui/QToolButton>
 #include <QtGui/QToolTip>
+#include <QtGui/QTreeWidget>
 
 #define DEBUG_STATE 1
 #ifdef DEBUG_STATE
@@ -460,8 +461,6 @@ void DebuggerManager::init()
         this, SLOT(loadAllSymbols()));
     connect(modulesView, SIGNAL(fileOpenRequested(QString)),
         this, SLOT(fileOpen(QString)));
-    connect(modulesView, SIGNAL(newDockRequested(QWidget*)),
-        this, SLOT(createNewDock(QWidget*)));
 
     // Source Files
     //d->m_sourceFilesHandler = new SourceFilesHandler;
@@ -1214,10 +1213,31 @@ void DebuggerManager::loadSymbols(const QString &module)
     d->m_engine->loadSymbols(module);
 }
 
-QList<Symbol> DebuggerManager::moduleSymbols(const QString &moduleName)
+void DebuggerManager::requestModuleSymbols(const QString &moduleName)
 {
-    QTC_ASSERT(d->m_engine, return QList<Symbol>());
-    return d->m_engine->moduleSymbols(moduleName);
+    QTC_ASSERT(d->m_engine, return);
+    d->m_engine->requestModuleSymbols(moduleName);
+}
+
+void DebuggerManager::showModuleSymbols(const QString &moduleName,
+    const QList<Symbol> &symbols)
+{ 
+    QTC_ASSERT(d->m_engine, return);
+    QTreeWidget *w = new QTreeWidget;
+    w->setColumnCount(3);
+    w->setRootIsDecorated(false);
+    w->setAlternatingRowColors(true);
+    w->setSortingEnabled(true);
+    w->setHeaderLabels(QStringList() << tr("Symbol") << tr("Address") << tr("Code"));
+    w->setWindowTitle(tr("Symbols in \"%1\"").arg(moduleName));
+    foreach (const Symbol &s, symbols) {
+        QTreeWidgetItem *it = new QTreeWidgetItem;
+        it->setData(0, Qt::DisplayRole, s.name);
+        it->setData(1, Qt::DisplayRole, s.address);
+        it->setData(2, Qt::DisplayRole, s.state);
+        w->addTopLevelItem(it);
+    }
+    createNewDock(w);
 }
 
 void DebuggerManager::executeStep()
diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h
index e3793ed5e1c..9c2ee51f876 100644
--- a/src/plugins/debugger/debuggermanager.h
+++ b/src/plugins/debugger/debuggermanager.h
@@ -329,7 +329,9 @@ private:
 public:
     // stuff in this block should be made private by moving it to
     // one of the interfaces
-    QList<Internal::Symbol> moduleSymbols(const QString &moduleName);
+    void requestModuleSymbols(const QString &moduleName);
+    void showModuleSymbols(const QString &moduleName,
+        const QList<Internal::Symbol> &symbols);
 
 signals:
     void debuggingFinished();
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index 17ac63a1705..58f01e7318b 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -2587,7 +2587,7 @@ void GdbEngine::loadAllSymbols()
     reloadModulesInternal();
 }
 
-QList<Symbol> GdbEngine::moduleSymbols(const QString &moduleName)
+void GdbEngine::requestModuleSymbols(const QString &moduleName)
 {
     QList<Symbol> rc;
     bool success = false;
@@ -2618,7 +2618,7 @@ QList<Symbol> GdbEngine::moduleSymbols(const QString &moduleName)
     } while (false);
     if (!success)
         qWarning("moduleSymbols: %s\n", qPrintable(errorMessage));
-    return rc;
+    manager()->showModuleSymbols(moduleName, rc);
 }
 
 void GdbEngine::reloadModules()
diff --git a/src/plugins/debugger/gdb/gdbengine.h b/src/plugins/debugger/gdb/gdbengine.h
index b5950703f39..b51c5ec3204 100644
--- a/src/plugins/debugger/gdb/gdbengine.h
+++ b/src/plugins/debugger/gdb/gdbengine.h
@@ -358,7 +358,7 @@ private: ////////// View & Data Stuff //////////
     //
     virtual void loadSymbols(const QString &moduleName);
     virtual void loadAllSymbols();
-    virtual QList<Symbol> moduleSymbols(const QString &moduleName);
+    virtual void requestModuleSymbols(const QString &moduleName);
     virtual void reloadModules();
     void reloadModulesInternal();
     void handleModulesList(const GdbResponse &response);
diff --git a/src/plugins/debugger/idebuggerengine.h b/src/plugins/debugger/idebuggerengine.h
index f0933763253..b7882471905 100644
--- a/src/plugins/debugger/idebuggerengine.h
+++ b/src/plugins/debugger/idebuggerengine.h
@@ -105,7 +105,7 @@ public:
     virtual void reloadModules() = 0;
     virtual void loadSymbols(const QString &moduleName) = 0;
     virtual void loadAllSymbols() = 0;
-    virtual QList<Symbol> moduleSymbols(const QString &moduleName) = 0;
+    virtual void requestModuleSymbols(const QString &moduleName) = 0;
 
     virtual void reloadRegisters() = 0;
 
diff --git a/src/plugins/debugger/moduleshandler.cpp b/src/plugins/debugger/moduleshandler.cpp
index dc7c1ac0c75..ea01954600f 100644
--- a/src/plugins/debugger/moduleshandler.cpp
+++ b/src/plugins/debugger/moduleshandler.cpp
@@ -62,7 +62,7 @@ public:
 
     // QAbstractItemModel
     int columnCount(const QModelIndex &parent) const
-        { return parent.isValid() ? 0 : 4; }
+        { return parent.isValid() ? 0 : 5; }
     int rowCount(const QModelIndex &parent) const
         { return parent.isValid() ? 0 : m_modules.size(); }
     QModelIndex parent(const QModelIndex &) const { return QModelIndex(); }
@@ -85,6 +85,7 @@ QVariant ModulesModel::headerData(int section,
     if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
         static QString headers[] = {
             tr("Module name") + "        ",
+            tr("Module path") + "        ",
             tr("Symbols read") + "        ",
             tr("Start address") + "        ",
             tr("End address") + "        "
@@ -112,13 +113,17 @@ QVariant ModulesModel::data(const QModelIndex &index, int role) const
             break;
         case 1:
             if (role == Qt::DisplayRole)
-                return module.symbolsRead ? "yes" : "no";
+                return module.modulePath;
             break;
         case 2:
             if (role == Qt::DisplayRole)
-                return module.startAddress;
+                return module.symbolsRead ? "yes" : "no";
             break;
         case 3:
+            if (role == Qt::DisplayRole)
+                return module.startAddress;
+            break;
+        case 4:
             if (role == Qt::DisplayRole)
                 return module.endAddress;
             break;
diff --git a/src/plugins/debugger/moduleshandler.h b/src/plugins/debugger/moduleshandler.h
index 249d6ca242e..2d9f15db23a 100644
--- a/src/plugins/debugger/moduleshandler.h
+++ b/src/plugins/debugger/moduleshandler.h
@@ -78,6 +78,7 @@ public:
 
 public:
     QString moduleName;
+    QString modulePath;
     bool symbolsRead;
     QString startAddress;
     QString endAddress;
diff --git a/src/plugins/debugger/moduleswindow.cpp b/src/plugins/debugger/moduleswindow.cpp
index 4144f82563f..df427bafb80 100644
--- a/src/plugins/debugger/moduleswindow.cpp
+++ b/src/plugins/debugger/moduleswindow.cpp
@@ -175,6 +175,7 @@ void ModulesWindow::resizeColumnsToContents()
     resizeColumnToContents(0);
     resizeColumnToContents(1);
     resizeColumnToContents(2);
+    resizeColumnToContents(3);
 }
 
 void ModulesWindow::setAlwaysResizeColumnsToContents(bool on)
@@ -186,6 +187,7 @@ void ModulesWindow::setAlwaysResizeColumnsToContents(bool on)
     header()->setResizeMode(1, mode);
     header()->setResizeMode(2, mode);
     header()->setResizeMode(3, mode);
+    header()->setResizeMode(4, mode);
     //setColumnHidden(3, true);
 }
 
@@ -197,27 +199,8 @@ void ModulesWindow::setModel(QAbstractItemModel *model)
 
 void ModulesWindow::showSymbols(const QString &name)
 {
-    if (name.isEmpty())
-        return;
-    QApplication::setOverrideCursor(Qt::WaitCursor);
-    const QList<Symbol> symbols = m_debuggerManager->moduleSymbols(name);
-    QApplication::restoreOverrideCursor();
-    if (symbols.empty())
-        return;
-    QTreeWidget *w = new QTreeWidget;
-    w->setColumnCount(3);
-    w->setRootIsDecorated(false);
-    w->setAlternatingRowColors(true);
-    w->setHeaderLabels(QStringList() << tr("Address") << tr("Code") << tr("Symbol"));
-    w->setWindowTitle(tr("Symbols in \"%1\"").arg(name));
-    foreach (const Symbol &s, symbols) {
-        QTreeWidgetItem *it = new QTreeWidgetItem;
-        it->setData(0, Qt::DisplayRole, s.address);
-        it->setData(1, Qt::DisplayRole, s.state);
-        it->setData(2, Qt::DisplayRole, s.name);
-        w->addTopLevelItem(it);
-    }
-    emit newDockRequested(w);
+    if (!name.isEmpty())
+        m_debuggerManager->requestModuleSymbols(name);
 }
 
 } // namespace Internal
diff --git a/src/plugins/debugger/pdb/pdbengine.cpp b/src/plugins/debugger/pdb/pdbengine.cpp
index 0fa670239e4..49eb20a4ba9 100644
--- a/src/plugins/debugger/pdb/pdbengine.cpp
+++ b/src/plugins/debugger/pdb/pdbengine.cpp
@@ -394,13 +394,52 @@ void PdbEngine::loadAllSymbols()
 
 void PdbEngine::reloadModules()
 {
+    postCommand("qdebug('listmodules')", CB(handleListModules));
+}
+
+void PdbEngine::handleListModules(const PdbResponse &response)
+{
+    GdbMi out;
+    out.fromString(response.data.trimmed());
+    QList<Module> modules;
+    foreach (const GdbMi &item, out.children()) {
+        Module module;
+        module.moduleName = _(item.findChild("name").data());
+        QString path = _(item.findChild("value").data());
+        int pos = path.indexOf(_("' from '"));
+        if (pos != -1) {
+            path = path.mid(pos + 8);
+            if (path.size() >= 2)
+                path.chop(2);
+        } else if (path.startsWith(_("<module '"))
+                && path.endsWith(_("' (built-in)>"))) {
+            path = _("(builtin)");
+        }
+        module.modulePath = path;
+        modules.append(module);
+    }
+    manager()->modulesHandler()->setModules(modules);
 }
 
-QList<Symbol> PdbEngine::moduleSymbols(const QString & /*moduleName*/)
+void PdbEngine::requestModuleSymbols(const QString &moduleName)
 {
-    return QList<Symbol>();
+    postCommand("qdebug('listsymbols','" + moduleName.toLatin1() + "')",
+        CB(handleListSymbols), moduleName);
 }
 
+void PdbEngine::handleListSymbols(const PdbResponse &response)
+{
+    GdbMi out;
+    out.fromString(response.data.trimmed());
+    QList<Symbol> symbols;
+    QString moduleName = response.cookie.toString();
+    foreach (const GdbMi &item, out.children()) {
+        Symbol symbol;
+        symbol.name = _(item.findChild("name").data());
+        symbols.append(symbol);
+    }
+    manager()->showModuleSymbols(moduleName, symbols);
+}
 
 //////////////////////////////////////////////////////////////////////
 //
@@ -771,6 +810,11 @@ void PdbEngine::debugMessage(const QString &msg)
     showDebuggerOutput(LogDebug, msg);
 }
 
+unsigned PdbEngine::debuggerCapabilities() const
+{
+    return ReloadModuleCapability;
+}
+
 IDebuggerEngine *createPdbEngine(DebuggerManager *manager)
 {
     return new PdbEngine(manager);
diff --git a/src/plugins/debugger/pdb/pdbengine.h b/src/plugins/debugger/pdb/pdbengine.h
index 2b1f9d12ffd..9262b6a6fc4 100644
--- a/src/plugins/debugger/pdb/pdbengine.h
+++ b/src/plugins/debugger/pdb/pdbengine.h
@@ -94,7 +94,7 @@ private:
 
     void loadSymbols(const QString &moduleName);
     void loadAllSymbols();
-    virtual QList<Symbol> moduleSymbols(const QString &moduleName);
+    void requestModuleSymbols(const QString &moduleName);
     void reloadModules();
     void reloadRegisters() {}
     void reloadSourceFiles() {}
@@ -107,6 +107,7 @@ private:
 private:
     void debugMessage(const QString &msg);
     QString errorMessage(QProcess::ProcessError error) const;
+    unsigned debuggerCapabilities() const;
 
     Q_SLOT void handlePdbFinished(int, QProcess::ExitStatus status);
     Q_SLOT void handlePdbError(QProcess::ProcessError error);
@@ -135,6 +136,8 @@ private:
     void handleStop(const PdbResponse &response);
     void handleBacktrace(const PdbResponse &response);
     void handleListLocals(const PdbResponse &response);
+    void handleListModules(const PdbResponse &response);
+    void handleListSymbols(const PdbResponse &response);
     void handleLoadDumper(const PdbResponse &response);
     void handleBreakInsert(const PdbResponse &response);
 
diff --git a/src/plugins/debugger/script/scriptengine.cpp b/src/plugins/debugger/script/scriptengine.cpp
index 8b0566a999d..3185c10d978 100644
--- a/src/plugins/debugger/script/scriptengine.cpp
+++ b/src/plugins/debugger/script/scriptengine.cpp
@@ -448,9 +448,8 @@ void ScriptEngine::reloadModules()
 {
 }
 
-QList<Symbol> ScriptEngine::moduleSymbols(const QString & /*moduleName*/)
+void ScriptEngine::requestModuleSymbols(const QString & /*moduleName*/)
 {
-    return QList<Symbol>();
 }
 
 
diff --git a/src/plugins/debugger/script/scriptengine.h b/src/plugins/debugger/script/scriptengine.h
index 22d28edaa69..e320c46c09f 100644
--- a/src/plugins/debugger/script/scriptengine.h
+++ b/src/plugins/debugger/script/scriptengine.h
@@ -93,7 +93,7 @@ private:
 
     void loadSymbols(const QString &moduleName);
     void loadAllSymbols();
-    virtual QList<Symbol> moduleSymbols(const QString &moduleName);
+    void requestModuleSymbols(const QString &moduleName);
     void reloadModules();
     void reloadRegisters() {}
     void reloadSourceFiles() {}
-- 
GitLab