diff options
author | hjk <hjk@qt.io> | 2019-06-24 12:28:07 +0200 |
---|---|---|
committer | hjk <hjk@qt.io> | 2019-06-24 12:54:23 +0000 |
commit | 0d49c2cd2c78ab3eda4722559a8387aebd752537 (patch) | |
tree | 04fd3b0658bf9b00e2f4afc0ce66f0101b98c3a5 | |
parent | 33fde35c1938691e17a5254650e492f1d8b7835c (diff) | |
download | qt-creator-0d49c2cd2c78ab3eda4722559a8387aebd752537.tar.gz |
Debugger: Use Utils::TreeModel as base for StackHandler
Change-Id: I3fcc1b3a149f15cf414a1560d91145b623e40c63
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
-rw-r--r-- | src/plugins/debugger/cdb/cdbengine.cpp | 6 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerengine.cpp | 2 | ||||
-rw-r--r-- | src/plugins/debugger/gdb/gdbengine.cpp | 7 | ||||
-rw-r--r-- | src/plugins/debugger/lldb/lldbengine.cpp | 2 | ||||
-rw-r--r-- | src/plugins/debugger/qml/qmlengine.cpp | 4 | ||||
-rw-r--r-- | src/plugins/debugger/stackhandler.cpp | 115 | ||||
-rw-r--r-- | src/plugins/debugger/stackhandler.h | 31 |
7 files changed, 87 insertions, 80 deletions
diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index da3eb7a774..a77493c450 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -1045,13 +1045,13 @@ void CdbEngine::activateFrame(int index) // TODO: assembler,etc if (index < 0) return; - const StackFrames &frames = stackHandler()->frames(); - if (index >= frames.size()) { + + if (stackHandler()->isSpecialFrame(index)) { reloadFullStack(); // Clicked on "More...". return; } - const StackFrame frame = frames.at(index); + const StackFrame frame = stackHandler()->frameAt(index); if (frame.language != CppLanguage) { gotoLocation(frame); return; diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index 0a32a88876..77cf3b6bd3 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -2522,7 +2522,7 @@ bool DebuggerEngine::isNativeMixedActiveFrame() const { if (!isNativeMixedActive()) return false; - if (stackHandler()->frames().isEmpty()) + if (stackHandler()->rowCount() == 0) return false; StackFrame frame = stackHandler()->frameAt(0); return frame.language == QmlLanguage; diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 9abc456802..8f063be523 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -2581,7 +2581,8 @@ void GdbEngine::loadSymbolsForStack() { bool needUpdate = false; const Modules &modules = modulesHandler()->modules(); - for (const StackFrame &frame : stackHandler()->frames()) { + stackHandler()->forItemsAtLevel<1>([modules, &needUpdate, this](StackFrameItem *frameItem) { + const StackFrame &frame = frameItem->frame; if (frame.function == "??") { //qDebug() << "LOAD FOR " << frame.address; for (const Module &module : modules) { @@ -2592,7 +2593,7 @@ void GdbEngine::loadSymbolsForStack() } } } - } + }); if (needUpdate) { reloadStack(); updateLocals(); @@ -2924,7 +2925,7 @@ void GdbEngine::activateFrame(int frameIndex) StackHandler *handler = stackHandler(); - if (frameIndex == handler->stackSize()) { + if (handler->isSpecialFrame(frameIndex)) { reloadFullStack(); return; } diff --git a/src/plugins/debugger/lldb/lldbengine.cpp b/src/plugins/debugger/lldb/lldbengine.cpp index 03d2861196..2ab109c77d 100644 --- a/src/plugins/debugger/lldb/lldbengine.cpp +++ b/src/plugins/debugger/lldb/lldbengine.cpp @@ -434,7 +434,7 @@ void LldbEngine::activateFrame(int frameIndex) return; StackHandler *handler = stackHandler(); - if (frameIndex == handler->stackSize()) { + if (handler->isSpecialFrame(frameIndex)) { fetchStack(handler->stackSize() * 10 + 3); return; } diff --git a/src/plugins/debugger/qml/qmlengine.cpp b/src/plugins/debugger/qml/qmlengine.cpp index 674870f6bf..d518d77701 100644 --- a/src/plugins/debugger/qml/qmlengine.cpp +++ b/src/plugins/debugger/qml/qmlengine.cpp @@ -663,7 +663,9 @@ void QmlEngine::activateFrame(int index) return; stackHandler()->setCurrentIndex(index); - gotoLocation(stackHandler()->frames().value(index)); + auto frameItem = stackHandler()->rootItem()->childAt(index); + QTC_ASSERT(frameItem, return); + gotoLocation(frameItem->frame); d->updateLocals(); } diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp index bd57ea0c6d..aef248dc20 100644 --- a/src/plugins/debugger/stackhandler.cpp +++ b/src/plugins/debugger/stackhandler.cpp @@ -68,6 +68,7 @@ StackHandler::StackHandler(DebuggerEngine *engine) : m_engine(engine) { setObjectName("StackModel"); + setHeader({tr("Level"), tr("Function"), tr("File"), tr("Line"), tr("Address") }); connect(action(ExpandStack), &QAction::triggered, this, &StackHandler::reloadFullStack); @@ -77,23 +78,12 @@ StackHandler::StackHandler(DebuggerEngine *engine) StackHandler::~StackHandler() = default; -int StackHandler::rowCount(const QModelIndex &parent) const -{ - // Since the stack is not a tree, row count is 0 for any valid parent - return parent.isValid() ? 0 : (m_stackFrames.size() + m_canExpand); -} - -int StackHandler::columnCount(const QModelIndex &parent) const -{ - return parent.isValid() ? 0 : StackColumnCount; -} - QVariant StackHandler::data(const QModelIndex &index, int role) const { - if (!index.isValid() || index.row() >= m_stackFrames.size() + m_canExpand) + if (!index.isValid() || index.row() > rowCount()) return QVariant(); - if (index.row() == m_stackFrames.size()) { + if (isSpecialFrame(index.row())) { if (role == Qt::DisplayRole && index.column() == StackLevelColumn) return tr("..."); if (role == Qt::DisplayRole && index.column() == StackFunctionNameColumn) @@ -103,7 +93,8 @@ QVariant StackHandler::data(const QModelIndex &index, int role) const return QVariant(); } - const StackFrame &frame = m_stackFrames.at(index.row()); + const StackFrameItem *frameItem = static_cast<StackFrameItem *>(itemForIndex(index)); + const StackFrame &frame = frameItem->frame; if (role == Qt::DisplayRole) { switch (index.column()) { @@ -135,31 +126,16 @@ QVariant StackHandler::data(const QModelIndex &index, int role) const return QVariant(); } - -QVariant StackHandler::headerData(int section, Qt::Orientation orient, int role) const -{ - if (orient == Qt::Horizontal && role == Qt::DisplayRole) { - switch (section) { - case 0: return tr("Level"); - case 1: return tr("Function"); - case 2: return tr("File"); - case 3: return tr("Line"); - case 4: return tr("Address"); - }; - } - return QVariant(); -} - Qt::ItemFlags StackHandler::flags(const QModelIndex &index) const { - if (index.row() >= m_stackFrames.size() + m_canExpand) - return nullptr; - if (index.row() == m_stackFrames.size()) - return QAbstractTableModel::flags(index); - const StackFrame &frame = m_stackFrames.at(index.row()); + if (index.row() >= rowCount()) + return {}; + if (index.row() == rowCount() - 1 && m_canExpand) + return StackHandlerModel::flags(index); + const StackFrame &frame = rootItem()->childAt(index.row())->frame; const bool isValid = frame.isUsable() || m_engine->operatesByInstruction(); return isValid && m_contentsValid - ? QAbstractTableModel::flags(index) : Qt::ItemFlags(); + ? StackHandlerModel::flags(index) : Qt::ItemFlags(); } bool StackHandler::setData(const QModelIndex &idx, const QVariant &data, int role) @@ -181,10 +157,27 @@ bool StackHandler::setData(const QModelIndex &idx, const QVariant &data, int rol StackFrame StackHandler::currentFrame() const { if (m_currentIndex == -1) - return StackFrame(); - QTC_ASSERT(m_currentIndex >= 0, return StackFrame()); - QTC_ASSERT(m_currentIndex < m_stackFrames.size(), return StackFrame()); - return m_stackFrames.at(m_currentIndex); + return {}; + QTC_ASSERT(m_currentIndex >= 0, return {}); + return frameAt(m_currentIndex); +} + +StackFrame StackHandler::frameAt(int index) const +{ + auto frameItem = static_cast<StackFrameItem *>(m_root->childAt(index)); + QTC_ASSERT(frameItem, return {}); + return frameItem->frame; +} + +int StackHandler::stackSize() const +{ + return rowCount() - m_canExpand; +} + +quint64 StackHandler::topAddress() const +{ + QTC_ASSERT(rowCount() > 0, return 0); + return rootItem()->childAt(0)->frame.address; } void StackHandler::setCurrentIndex(int level) @@ -206,24 +199,29 @@ void StackHandler::setCurrentIndex(int level) void StackHandler::removeAll() { - beginResetModel(); - m_stackFrames.clear(); + clear(); setCurrentIndex(-1); - endResetModel(); } void StackHandler::setFrames(const StackFrames &frames, bool canExpand) { - beginResetModel(); + clear(); + m_resetLocationScheduled = false; m_contentsValid = true; m_canExpand = canExpand; - m_stackFrames = frames; - if (m_stackFrames.size() >= 0) + + for (const StackFrame &frame : frames) + rootItem()->appendChild(new StackFrameItem(frame)); + + if (canExpand) + rootItem()->appendChild(new StackFrameItem(StackFrame())); + + if (rowCount() >= 0) setCurrentIndex(0); else m_currentIndex = -1; - endResetModel(); + emit stackChanged(); } @@ -271,30 +269,28 @@ void StackHandler::prependFrames(const StackFrames &frames) if (frames.isEmpty()) return; const int count = frames.size(); - beginInsertRows(QModelIndex(), 0, count - 1); for (int i = count - 1; i >= 0; --i) - m_stackFrames.prepend(frames.at(i)); - endInsertRows(); + rootItem()->prependChild(new StackFrameItem(frames.at(i))); if (m_currentIndex >= 0) setCurrentIndex(m_currentIndex + count); emit stackChanged(); } +bool StackHandler::isSpecialFrame(int index) const +{ + return m_canExpand && index + 1 == rowCount(); +} + int StackHandler::firstUsableIndex() const { if (!m_engine->operatesByInstruction()) { - for (int i = 0, n = m_stackFrames.size(); i != n; ++i) - if (m_stackFrames.at(i).isUsable()) + for (int i = 0, n = rowCount(); i != n; ++i) + if (rootItem()->childAt(i)->frame.isUsable()) return i; } return 0; } -const StackFrames &StackHandler::frames() const -{ - return m_stackFrames; -} - void StackHandler::scheduleResetLocation() { m_resetLocationScheduled = true; @@ -357,10 +353,11 @@ void StackHandler::saveTaskFile() } QTextStream str(&file); - for (const StackFrame &frame : frames()) { + forItemsAtLevel<1>([&str](StackFrameItem *item) { + const StackFrame &frame = item->frame; if (frame.isUsable()) str << frame.file << '\t' << frame.line << "\tstack\tFrame #" << frame.level << '\n'; - } + }); } bool StackHandler::contextMenuEvent(const ItemViewEvent &ev) @@ -441,7 +438,7 @@ void StackHandler::copyContentsToClipboard() { QString str; int n = rowCount(); - int m = columnCount(); + int m = columnCount(QModelIndex()); QVector<int> largestColumnWidths(m, 0); // First, find the widths of the largest columns, diff --git a/src/plugins/debugger/stackhandler.h b/src/plugins/debugger/stackhandler.h index 02268e400a..5d846235c0 100644 --- a/src/plugins/debugger/stackhandler.h +++ b/src/plugins/debugger/stackhandler.h @@ -27,9 +27,8 @@ #include "stackframe.h" -#include <QAbstractItemModel> - -namespace Utils { class ItemViewEvent; } +#include <utils/basetreeview.h> +#include <utils/treemodel.h> namespace Debugger { namespace Internal { @@ -46,7 +45,19 @@ enum StackColumns StackColumnCount }; -class StackHandler : public QAbstractTableModel +class StackFrameItem : public Utils::TreeItem +{ +public: + StackFrameItem(); + explicit StackFrameItem(const StackFrame &frame) : frame(frame) {} + +public: + StackFrame frame; +}; + +using StackHandlerModel = Utils::TreeModel<Utils::TypedTreeItem<StackFrameItem>, StackFrameItem>; + +class StackHandler : public StackHandlerModel { Q_OBJECT @@ -58,14 +69,14 @@ public: void setFramesAndCurrentIndex(const GdbMi &frames, bool isFull); int updateTargetFrame(bool isFull); void prependFrames(const StackFrames &frames); - const StackFrames &frames() const; + bool isSpecialFrame(int index) const; void setCurrentIndex(int index); int currentIndex() const { return m_currentIndex; } int firstUsableIndex() const; StackFrame currentFrame() const; - const StackFrame &frameAt(int index) const { return m_stackFrames.at(index); } - int stackSize() const { return m_stackFrames.size(); } - quint64 topAddress() const { return m_stackFrames.at(0).address; } + StackFrame frameAt(int index) const; + int stackSize() const; + quint64 topAddress() const; // Called from StackHandler after a new stack list has been received void removeAll(); @@ -80,10 +91,7 @@ signals: void currentIndexChanged(); private: - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - int columnCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role) const override; - QVariant headerData(int section, Qt::Orientation orientation, int role) const override; Qt::ItemFlags flags(const QModelIndex &index) const override; bool setData(const QModelIndex &idx, const QVariant &data, int role) override; @@ -93,7 +101,6 @@ private: void saveTaskFile(); DebuggerEngine *m_engine; - StackFrames m_stackFrames; int m_currentIndex = -1; bool m_canExpand = false; bool m_resetLocationScheduled = false; |