From 35bfbec79765047e71a36ac728f38e4662c1553c Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 18 May 2010 12:12:22 +0200 Subject: [PATCH] debugger: refactor thread related class --- src/plugins/debugger/breakwindow.cpp | 1 + src/plugins/debugger/debugger.pro | 8 +- src/plugins/debugger/debuggermanager.cpp | 1 + src/plugins/debugger/gdb/gdbengine.cpp | 1 + src/plugins/debugger/gdb/trkgdbadapter.cpp | 2 +- src/plugins/debugger/stackframe.cpp | 112 +++++++++++ src/plugins/debugger/stackhandler.cpp | 219 --------------------- src/plugins/debugger/stackhandler.h | 64 +----- src/plugins/debugger/threadshandler.cpp | 205 +++++++++++++++++++ src/plugins/debugger/threadshandler.h | 122 ++++++++++++ 10 files changed, 455 insertions(+), 280 deletions(-) create mode 100644 src/plugins/debugger/stackframe.cpp create mode 100644 src/plugins/debugger/threadshandler.cpp create mode 100644 src/plugins/debugger/threadshandler.h diff --git a/src/plugins/debugger/breakwindow.cpp b/src/plugins/debugger/breakwindow.cpp index 938ffbdd1f1..b2174bad41b 100644 --- a/src/plugins/debugger/breakwindow.cpp +++ b/src/plugins/debugger/breakwindow.cpp @@ -30,6 +30,7 @@ #include "breakwindow.h" #include "breakhandler.h" +#include "threadshandler.h" #include "debuggeractions.h" #include "debuggermanager.h" #include "stackhandler.h" diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro index 93eec280b68..57b53ead9e8 100644 --- a/src/plugins/debugger/debugger.pro +++ b/src/plugins/debugger/debugger.pro @@ -35,6 +35,7 @@ HEADERS += breakhandler.h \ procinterrupt.h \ registerhandler.h \ registerwindow.h \ + stackframe.h \ stackhandler.h \ stackwindow.h \ snapshothandler.h \ @@ -46,7 +47,8 @@ HEADERS += breakhandler.h \ watchwindow.h \ name_demangler.h \ debuggeruiswitcher.h \ - debuggermainwindow.h + debuggermainwindow.h \ + threadshandler.h SOURCES += breakhandler.cpp \ breakwindow.cpp \ breakwindow.h \ @@ -77,7 +79,9 @@ SOURCES += breakhandler.cpp \ watchutils.cpp \ name_demangler.cpp \ debuggeruiswitcher.cpp \ - debuggermainwindow.cpp + debuggermainwindow.cpp \ + threadshandler.cpp \ + stackframe.cpp FORMS += attachexternaldialog.ui \ attachcoredialog.ui \ diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index e2f91b60ed5..905495bc3ac 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -57,6 +57,7 @@ #include "snapshothandler.h" #include "stackhandler.h" #include "stackframe.h" +#include "threadshandler.h" #include "watchhandler.h" #include "debuggerdialogs.h" diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index 81986228765..36037e631d7 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -56,6 +56,7 @@ #include "registerhandler.h" #include "snapshothandler.h" #include "stackhandler.h" +#include "threadshandler.h" #include "watchhandler.h" #include "sourcefileswindow.h" diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index 2caaf5d52a0..f64fbdf6ee5 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -35,7 +35,7 @@ #include "bluetoothlistener_gui.h" #include "registerhandler.h" -#include "stackhandler.h" +#include "threadshandler.h" #include "debuggeractions.h" #include "debuggerstringutils.h" #include "watchutils.h" diff --git a/src/plugins/debugger/stackframe.cpp b/src/plugins/debugger/stackframe.cpp new file mode 100644 index 00000000000..9a0797f8219 --- /dev/null +++ b/src/plugins/debugger/stackframe.cpp @@ -0,0 +1,112 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "stackframe.h" +#include "stackhandler.h" + +#include +#include +#include +#include + +namespace Debugger { +namespace Internal { + +//////////////////////////////////////////////////////////////////////// +// +// StackFrame +// +//////////////////////////////////////////////////////////////////////// + +StackFrame::StackFrame() + : level(0), line(0) +{} + +void StackFrame::clear() +{ + line = level = 0; + function.clear(); + file.clear(); + from.clear(); + to.clear(); + address.clear(); +} + +bool StackFrame::isUsable() const +{ + return !file.isEmpty() && QFileInfo(file).isReadable(); +} + +QString StackFrame::toString() const +{ + QString res; + QTextStream str(&res); + str << StackHandler::tr("Address:") << ' ' << address << ' ' + << StackHandler::tr("Function:") << ' ' << function << ' ' + << StackHandler::tr("File:") << ' ' << file << ' ' + << StackHandler::tr("Line:") << ' ' << line << ' ' + << StackHandler::tr("From:") << ' ' << from << ' ' + << StackHandler::tr("To:") << ' ' << to; + return res; +} + +QString StackFrame::toToolTip() const +{ + QString res; + QTextStream str(&res); + str << "" + << "" + << "" + << "" + << "" + << "" + << "" + << "
" << StackHandler::tr("Address:") << "" << address << "
" << StackHandler::tr("Function:") << "" << function << "
" << StackHandler::tr("File:") << "" << QDir::toNativeSeparators(file) << "
" << StackHandler::tr("Line:") << "" << line << "
" << StackHandler::tr("From:") << "" << from << "
" << StackHandler::tr("To:") << "" << to << "
"; + return res; +} + +QDebug operator<<(QDebug d, const StackFrame &f) +{ + QString res; + QTextStream str(&res); + str << "level=" << f.level << " address=" << f.address; + if (!f.function.isEmpty()) + str << ' ' << f.function; + if (!f.file.isEmpty()) + str << ' ' << f.file << ':' << f.line; + if (!f.from.isEmpty()) + str << " from=" << f.from; + if (!f.to.isEmpty()) + str << " to=" << f.to; + d.nospace() << res; + return d; +} + +} // namespace Internal +} // namespace Debugger diff --git a/src/plugins/debugger/stackhandler.cpp b/src/plugins/debugger/stackhandler.cpp index 95c64c68689..bdfc7b5c116 100644 --- a/src/plugins/debugger/stackhandler.cpp +++ b/src/plugins/debugger/stackhandler.cpp @@ -42,69 +42,6 @@ namespace Debugger { namespace Internal { -StackFrame::StackFrame() - : level(0), line(0) -{} - -void StackFrame::clear() -{ - line = level = 0; - function.clear(); - file.clear(); - from.clear(); - to.clear(); - address.clear(); -} - -bool StackFrame::isUsable() const -{ - return !file.isEmpty() && QFileInfo(file).isReadable(); -} - -QString StackFrame::toString() const -{ - QString res; - QTextStream str(&res); - str << StackHandler::tr("Address:") << ' ' << address << ' ' - << StackHandler::tr("Function:") << ' ' << function << ' ' - << StackHandler::tr("File:") << ' ' << file << ' ' - << StackHandler::tr("Line:") << ' ' << line << ' ' - << StackHandler::tr("From:") << ' ' << from << ' ' - << StackHandler::tr("To:") << ' ' << to; - return res; -} - -QString StackFrame::toToolTip() const -{ - QString res; - QTextStream str(&res); - str << "" - << "" - << "" - << "" - << "" - << "" - << "" - << "
" << StackHandler::tr("Address:") << "" << address << "
" << StackHandler::tr("Function:") << "" << function << "
" << StackHandler::tr("File:") << "" << QDir::toNativeSeparators(file) << "
" << StackHandler::tr("Line:") << "" << line << "
" << StackHandler::tr("From:") << "" << from << "
" << StackHandler::tr("To:") << "" << to << "
"; - return res; -} - -QDebug operator<<(QDebug d, const StackFrame &f) -{ - QString res; - QTextStream str(&res); - str << "level=" << f.level << " address=" << f.address; - if (!f.function.isEmpty()) - str << ' ' << f.function; - if (!f.file.isEmpty()) - str << ' ' << f.file << ':' << f.line; - if (!f.from.isEmpty()) - str << " from=" << f.from; - if (!f.to.isEmpty()) - str << " to=" << f.to; - d.nospace() << res; - return d; -} //////////////////////////////////////////////////////////////////////// // @@ -262,161 +199,5 @@ bool StackHandler::isDebuggingDebuggingHelpers() const } -//////////////////////////////////////////////////////////////////////// -// -// ThreadsHandler -// -//////////////////////////////////////////////////////////////////////// - -ThreadData::ThreadData(int threadId) -{ - notifyRunning(); - id = threadId; -} - -void ThreadData::notifyRunning() -{ - address = 0; - function.clear(); - fileName.clear(); - frameLevel = -1; - state.clear(); - lineNumber = -1; -} - -enum { IdColumn, AddressColumn, FunctionColumn, FileColumn, LineColumn, ColumnCount }; - -ThreadsHandler::ThreadsHandler(QObject *parent) : - QAbstractTableModel(parent), - m_currentIndex(0), - m_positionIcon(QLatin1String(":/debugger/images/location_16.png")), - m_emptyIcon(QLatin1String(":/debugger/images/debugger_empty_14.png")) -{ -} - -int ThreadsHandler::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_threads.size(); -} - -int ThreadsHandler::columnCount(const QModelIndex &parent) const -{ - return parent.isValid() ? 0 : int(ColumnCount); -} - -QVariant ThreadsHandler::data(const QModelIndex &index, int role) const -{ - if (!index.isValid()) - return QVariant(); - const int row = index.row(); - if (row >= m_threads.size()) - return QVariant(); - const ThreadData &thread = m_threads.at(row); - - if (role == Qt::DisplayRole) { - switch (index.column()) { - case IdColumn: - return thread.id; - case FunctionColumn: - return thread.function; - case FileColumn: - return thread.fileName; - case LineColumn: - return thread.lineNumber >= 0 ? QString::number(thread.lineNumber) : QString(); - case AddressColumn: - return thread.address > 0 ? QLatin1String("0x") + QString::number(thread.address, 16) : QString(); - } - } else if (role == Qt::ToolTipRole) { - if (thread.address == 0) - return tr("Thread: %1").arg(thread.id); - // Stopped - if (thread.fileName.isEmpty()) - return tr("Thread: %1 at %2 (0x%3)").arg(thread.id).arg(thread.function).arg(thread.address, 0, 16); - return tr("Thread: %1 at %2, %3:%4 (0x%5)"). - arg(thread.id).arg(thread.function, thread.fileName).arg(thread.lineNumber).arg(thread.address, 0, 16); - } else if (role == Qt::DecorationRole && index.column() == 0) { - // Return icon that indicates whether this is the active stack frame - return (index.row() == m_currentIndex) ? m_positionIcon : m_emptyIcon; - } - - return QVariant(); -} - -QVariant ThreadsHandler::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation != Qt::Horizontal || role != Qt::DisplayRole) - return QVariant(); - switch (section) { - case IdColumn: - return tr("Thread ID"); - case FunctionColumn: - return tr("Function"); - case FileColumn: - return tr("File"); - case LineColumn: - return tr("Line"); - case AddressColumn: - return tr("Address"); - } - return QVariant(); -} - -int ThreadsHandler::currentThreadId() const -{ - if (m_currentIndex < 0 || m_currentIndex >= m_threads.size()) - return -1; - return m_threads[m_currentIndex].id; -} - -void ThreadsHandler::setCurrentThread(int index) -{ - if (index == m_currentIndex) - return; - - // Emit changed for previous frame - QModelIndex i = ThreadsHandler::index(m_currentIndex, 0); - emit dataChanged(i, i); - - m_currentIndex = index; - - // Emit changed for new frame - i = ThreadsHandler::index(m_currentIndex, 0); - emit dataChanged(i, i); -} - -void ThreadsHandler::setThreads(const QList &threads) -{ - m_threads = threads; - if (m_currentIndex >= m_threads.size()) - m_currentIndex = m_threads.size() - 1; - reset(); -} - -QList ThreadsHandler::threads() const -{ - return m_threads; -} - -void ThreadsHandler::removeAll() -{ - m_threads.clear(); - m_currentIndex = 0; - reset(); -} - -void ThreadsHandler::notifyRunning() -{ - // Threads stopped (that is, address != 0 showing)? - if (m_threads.empty()) - return; - if (m_threads.front().address == 0) - return; - const QList::iterator end = m_threads.end(); - for (QList::iterator it = m_threads.begin(); it != end; ++it) - it->notifyRunning(); - emit dataChanged(index(0, 1), index(m_threads.size()- 1, ColumnCount - 1)); -} - } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/stackhandler.h b/src/plugins/debugger/stackhandler.h index f0aa893ad51..28c5cd1029f 100644 --- a/src/plugins/debugger/stackhandler.h +++ b/src/plugins/debugger/stackhandler.h @@ -40,6 +40,12 @@ namespace Debugger { namespace Internal { +//////////////////////////////////////////////////////////////////////// +// +// StackModel +// +//////////////////////////////////////////////////////////////////////// + struct StackCookie { StackCookie() : isFull(true), gotoLocation(false) {} @@ -92,64 +98,6 @@ private: }; -//////////////////////////////////////////////////////////////////////// -// -// ThreadsHandler -// -//////////////////////////////////////////////////////////////////////// - -struct ThreadData -{ - ThreadData(int threadId = 0); - - // Permanent data. - int id; - QString targetId; - QString core; - - // State information when stopped - void notifyRunning(); // Clear state information - - int frameLevel; - quint64 address; - QString function; - QString fileName; - QString state; - int lineNumber; -}; - -/*! A model to represent the running threads in a QTreeView or ComboBox */ -class ThreadsHandler : public QAbstractTableModel -{ - Q_OBJECT - -public: - ThreadsHandler(QObject *parent = 0); - - int currentThreadId() const; - void setCurrentThread(int index); - void selectThread(int index); - void setThreads(const QList &threads); - void removeAll(); - QList threads() const; - QAbstractItemModel *threadsModel() { return this; } - - // Clear out all frame information - void notifyRunning(); - -private: - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - -private: - QList m_threads; - int m_currentIndex; - const QIcon m_positionIcon; - const QIcon m_emptyIcon; -}; - } // namespace Internal } // namespace Debugger diff --git a/src/plugins/debugger/threadshandler.cpp b/src/plugins/debugger/threadshandler.cpp new file mode 100644 index 00000000000..3cd67a962c3 --- /dev/null +++ b/src/plugins/debugger/threadshandler.cpp @@ -0,0 +1,205 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#include "threadshandler.h" + +namespace Debugger { +namespace Internal { + +//////////////////////////////////////////////////////////////////////// +// +// ThreadsHandler +// +/////////////////////////////////////////////////////////////////////// + +ThreadData::ThreadData(int threadId) +{ + notifyRunning(); + id = threadId; +} + +void ThreadData::notifyRunning() +{ + address = 0; + function.clear(); + fileName.clear(); + frameLevel = -1; + state.clear(); + lineNumber = -1; +} + +//////////////////////////////////////////////////////////////////////// +// +// ThreadsHandler +// +/////////////////////////////////////////////////////////////////////// + +ThreadsHandler::ThreadsHandler(QObject *parent) : + QAbstractTableModel(parent), + m_currentIndex(0), + m_positionIcon(QLatin1String(":/debugger/images/location_16.png")), + m_emptyIcon(QLatin1String(":/debugger/images/debugger_empty_14.png")) +{ +} + +int ThreadsHandler::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_threads.size(); +} + +int ThreadsHandler::columnCount(const QModelIndex &parent) const +{ + return parent.isValid() ? 0 : int(ThreadData::ColumnCount); +} + +QVariant ThreadsHandler::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + const int row = index.row(); + if (row >= m_threads.size()) + return QVariant(); + const ThreadData &thread = m_threads.at(row); + + if (role == Qt::DisplayRole) { + switch (index.column()) { + case ThreadData::IdColumn: + return thread.id; + case ThreadData::FunctionColumn: + return thread.function; + case ThreadData::FileColumn: + return thread.fileName; + case ThreadData::LineColumn: + return thread.lineNumber >= 0 ? QString::number(thread.lineNumber) : QString(); + case ThreadData::AddressColumn: + return thread.address > 0 ? QLatin1String("0x") + QString::number(thread.address, 16) : QString(); + case ThreadData::CoreColumn: + return thread.core; + case ThreadData::StateColumn: + return thread.state; + } + } else if (role == Qt::ToolTipRole) { + if (thread.address == 0) + return tr("Thread: %1").arg(thread.id); + // Stopped + if (thread.fileName.isEmpty()) + return tr("Thread: %1 at %2 (0x%3)").arg(thread.id).arg(thread.function).arg(thread.address, 0, 16); + return tr("Thread: %1 at %2, %3:%4 (0x%5)"). + arg(thread.id).arg(thread.function, thread.fileName).arg(thread.lineNumber).arg(thread.address, 0, 16); + } else if (role == Qt::DecorationRole && index.column() == 0) { + // Return icon that indicates whether this is the active stack frame + return (index.row() == m_currentIndex) ? m_positionIcon : m_emptyIcon; + } + + return QVariant(); +} + +QVariant ThreadsHandler::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation != Qt::Horizontal || role != Qt::DisplayRole) + return QVariant(); + switch (section) { + case ThreadData::IdColumn: + return tr("Thread ID"); + case ThreadData::FunctionColumn: + return tr("Function"); + case ThreadData::FileColumn: + return tr("File"); + case ThreadData::LineColumn: + return tr("Line"); + case ThreadData::AddressColumn: + return tr("Address"); + case ThreadData::CoreColumn: + return tr("Core"); + case ThreadData::StateColumn: + return tr("State"); + } + return QVariant(); +} + +int ThreadsHandler::currentThreadId() const +{ + if (m_currentIndex < 0 || m_currentIndex >= m_threads.size()) + return -1; + return m_threads[m_currentIndex].id; +} + +void ThreadsHandler::setCurrentThread(int index) +{ + if (index == m_currentIndex) + return; + + // Emit changed for previous frame + QModelIndex i = ThreadsHandler::index(m_currentIndex, 0); + emit dataChanged(i, i); + + m_currentIndex = index; + + // Emit changed for new frame + i = ThreadsHandler::index(m_currentIndex, 0); + emit dataChanged(i, i); +} + +void ThreadsHandler::setThreads(const QList &threads) +{ + m_threads = threads; + if (m_currentIndex >= m_threads.size()) + m_currentIndex = m_threads.size() - 1; + reset(); +} + +QList ThreadsHandler::threads() const +{ + return m_threads; +} + +void ThreadsHandler::removeAll() +{ + m_threads.clear(); + m_currentIndex = 0; + reset(); +} + +void ThreadsHandler::notifyRunning() +{ + // Threads stopped (that is, address != 0 showing)? + if (m_threads.empty()) + return; + if (m_threads.front().address == 0) + return; + const QList::iterator end = m_threads.end(); + for (QList::iterator it = m_threads.begin(); it != end; ++it) + it->notifyRunning(); + emit dataChanged(index(0, 1), + index(m_threads.size() - 1, ThreadData::ColumnCount - 1)); +} + +} // namespace Internal +} // namespace Debugger diff --git a/src/plugins/debugger/threadshandler.h b/src/plugins/debugger/threadshandler.h new file mode 100644 index 00000000000..10e242a301a --- /dev/null +++ b/src/plugins/debugger/threadshandler.h @@ -0,0 +1,122 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ + +#ifndef THREADSHANDLER_H +#define THREADSHANDLER_H + +#include +#include + +#include + + +namespace Debugger { +namespace Internal { + +//////////////////////////////////////////////////////////////////////// +// +// ThreadData +// +//////////////////////////////////////////////////////////////////////// + +/*! A structure containing information about a single thread */ +struct ThreadData +{ + ThreadData(int threadId = 0); + + enum { + IdColumn, + AddressColumn, + FunctionColumn, + FileColumn, + LineColumn, + StateColumn, + CoreColumn, + ColumnCount = CoreColumn + }; + + // Permanent data. + int id; + QString targetId; + QString core; + + // State information when stopped + void notifyRunning(); // Clear state information + + int frameLevel; + quint64 address; + QString function; + QString fileName; + QString state; + int lineNumber; +}; + + +//////////////////////////////////////////////////////////////////////// +// +// ThreadsHandler +// +//////////////////////////////////////////////////////////////////////// + +/*! A model to represent the running threads in a QTreeView or ComboBox */ +class ThreadsHandler : public QAbstractTableModel +{ + Q_OBJECT + +public: + ThreadsHandler(QObject *parent = 0); + + int currentThreadId() const; + void setCurrentThread(int index); + void selectThread(int index); + void setThreads(const QList &threads); + void removeAll(); + QList threads() const; + QAbstractItemModel *threadsModel() { return this; } + + // Clear out all frame information + void notifyRunning(); + +private: + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + +private: + QList m_threads; + int m_currentIndex; + const QIcon m_positionIcon; + const QIcon m_emptyIcon; +}; + +} // namespace Internal +} // namespace Debugger + +#endif // THREADSHANDLER_H