forked from qt-creator/qt-creator
debugger: rework WatchModel
It's one model for all locals, watch, return, tooltip and inspector data. This allows more streamlined code paths and better isolation of the model data from the WatchHandler. WatchItems are now registered in a hash indexed by iname, so inames can be used as the primary handle to watch data in the WatchHandler interface. Change-Id: Idac0a808b5d785307496d1de4198a1f2e9ce3880 Reviewed-by: Aurindam Jana <aurindam.jana@nokia.com>
This commit is contained in:
@@ -2397,6 +2397,14 @@ def qdump__Debugger__Internal__GdbMi(d, value):
|
|||||||
d.putByteArrayValue(value["m_data"])
|
d.putByteArrayValue(value["m_data"])
|
||||||
d.putPlainChildren(value)
|
d.putPlainChildren(value)
|
||||||
|
|
||||||
|
def qdump__Debugger__Internal__WatchData(d, value):
|
||||||
|
d.putByteArrayValue(value["iname"])
|
||||||
|
d.putPlainChildren(value)
|
||||||
|
|
||||||
|
def qdump__Debugger__Internal__WatchItem(d, value):
|
||||||
|
d.putByteArrayValue(value["iname"])
|
||||||
|
d.putPlainChildren(value)
|
||||||
|
|
||||||
def qdump__CPlusPlus__ByteArrayRef(d, value):
|
def qdump__CPlusPlus__ByteArrayRef(d, value):
|
||||||
d.putValue(encodeCharArray(value["m_start"], 100, value["m_length"]),
|
d.putValue(encodeCharArray(value["m_start"], 100, value["m_length"]),
|
||||||
Hex2EncodedLatin1)
|
Hex2EncodedLatin1)
|
||||||
|
@@ -98,6 +98,12 @@ enum { debugSourceMapping = 0 };
|
|||||||
enum { debugWatches = 0 };
|
enum { debugWatches = 0 };
|
||||||
enum { debugBreakpoints = 0 };
|
enum { debugBreakpoints = 0 };
|
||||||
|
|
||||||
|
enum HandleLocalsFlags
|
||||||
|
{
|
||||||
|
PartialLocalsUpdate = 0x1,
|
||||||
|
LocalsUpdateForNewFrame = 0x2
|
||||||
|
};
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
# define STATE_DEBUG(state, func, line, notifyFunc) qDebug("%s in %s at %s:%d", notifyFunc, stateName(state), func, line);
|
# define STATE_DEBUG(state, func, line, notifyFunc) qDebug("%s in %s at %s:%d", notifyFunc, stateName(state), func, line);
|
||||||
#else
|
#else
|
||||||
@@ -550,18 +556,16 @@ bool CdbEngine::setToolTipExpression(const QPoint &mousePos,
|
|||||||
// Can this be found as a local variable?
|
// Can this be found as a local variable?
|
||||||
const QByteArray localsPrefix(localsPrefixC);
|
const QByteArray localsPrefix(localsPrefixC);
|
||||||
QByteArray iname = localsPrefix + exp.toAscii();
|
QByteArray iname = localsPrefix + exp.toAscii();
|
||||||
QModelIndex index = watchHandler()->itemIndex(iname);
|
if (!watchHandler()->hasItem(iname)) {
|
||||||
if (!index.isValid()) {
|
|
||||||
// Nope, try a 'local.this.m_foo'.
|
// Nope, try a 'local.this.m_foo'.
|
||||||
exp.prepend(QLatin1String("this."));
|
exp.prepend(QLatin1String("this."));
|
||||||
iname.insert(localsPrefix.size(), "this.");
|
iname.insert(localsPrefix.size(), "this.");
|
||||||
index = watchHandler()->itemIndex(iname);
|
if (!watchHandler()->hasItem(iname))
|
||||||
if (!index.isValid())
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
DebuggerToolTipWidget *tw = new DebuggerToolTipWidget;
|
DebuggerToolTipWidget *tw = new DebuggerToolTipWidget;
|
||||||
tw->setContext(context);
|
tw->setContext(context);
|
||||||
tw->setDebuggerModel(LocalsWatch);
|
tw->setDebuggerModel(LocalsType);
|
||||||
tw->setExpression(exp);
|
tw->setExpression(exp);
|
||||||
tw->acquireEngine(this);
|
tw->acquireEngine(this);
|
||||||
DebuggerToolTipManager::instance()->showToolTip(mousePos, editor, tw);
|
DebuggerToolTipManager::instance()->showToolTip(mousePos, editor, tw);
|
||||||
@@ -1048,7 +1052,7 @@ void CdbEngine::handleAddWatch(const CdbExtensionCommandPtr &reply)
|
|||||||
updateLocalVariable(item.iname);
|
updateLocalVariable(item.iname);
|
||||||
} else {
|
} else {
|
||||||
item.setError(tr("Unable to add expression"));
|
item.setError(tr("Unable to add expression"));
|
||||||
watchHandler()->insertData(item);
|
watchHandler()->insertIncompleteData(item);
|
||||||
showMessage(QString::fromLatin1("Unable to add watch item '%1'/'%2': %3").
|
showMessage(QString::fromLatin1("Unable to add watch item '%1'/'%2': %3").
|
||||||
arg(QString::fromLatin1(item.iname), QString::fromLatin1(item.exp),
|
arg(QString::fromLatin1(item.iname), QString::fromLatin1(item.exp),
|
||||||
QString::fromLocal8Bit(reply->errorMessage)), LogError);
|
QString::fromLocal8Bit(reply->errorMessage)), LogError);
|
||||||
@@ -1086,7 +1090,10 @@ void CdbEngine::updateLocalVariable(const QByteArray &iname)
|
|||||||
str << blankSeparator << stackFrame;
|
str << blankSeparator << stackFrame;
|
||||||
}
|
}
|
||||||
str << blankSeparator << iname;
|
str << blankSeparator << iname;
|
||||||
postExtensionCommand(isWatch ? "watches" : "locals", localsArguments, 0, &CdbEngine::handleLocals);
|
postExtensionCommand(isWatch ? "watches" : "locals",
|
||||||
|
localsArguments, 0,
|
||||||
|
&CdbEngine::handleLocals,
|
||||||
|
0, QVariant(int(PartialLocalsUpdate)));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CdbEngine::hasCapability(unsigned cap) const
|
bool CdbEngine::hasCapability(unsigned cap) const
|
||||||
@@ -1465,8 +1472,7 @@ void CdbEngine::activateFrame(int index)
|
|||||||
stackHandler()->setCurrentIndex(index);
|
stackHandler()->setCurrentIndex(index);
|
||||||
const bool showAssembler = !frames.at(index).isUsable();
|
const bool showAssembler = !frames.at(index).isUsable();
|
||||||
if (showAssembler) { // Assembly code: Clean out model and force instruction mode.
|
if (showAssembler) { // Assembly code: Clean out model and force instruction mode.
|
||||||
watchHandler()->beginCycle();
|
watchHandler()->removeAllData();
|
||||||
watchHandler()->endCycle();
|
|
||||||
QAction *assemblerAction = theAssemblerAction();
|
QAction *assemblerAction = theAssemblerAction();
|
||||||
if (assemblerAction->isChecked()) {
|
if (assemblerAction->isChecked()) {
|
||||||
gotoLocation(frame);
|
gotoLocation(frame);
|
||||||
@@ -1485,14 +1491,12 @@ void CdbEngine::updateLocals(bool forNewStackFrame)
|
|||||||
|
|
||||||
const int frameIndex = stackHandler()->currentIndex();
|
const int frameIndex = stackHandler()->currentIndex();
|
||||||
if (frameIndex < 0) {
|
if (frameIndex < 0) {
|
||||||
watchHandler()->beginCycle();
|
watchHandler()->removeAllData();
|
||||||
watchHandler()->endCycle();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const StackFrame frame = stackHandler()->currentFrame();
|
const StackFrame frame = stackHandler()->currentFrame();
|
||||||
if (!frame.isUsable()) {
|
if (!frame.isUsable()) {
|
||||||
watchHandler()->beginCycle();
|
watchHandler()->removeAllData();
|
||||||
watchHandler()->endCycle();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Watchers: Forcibly discard old symbol group as switching from
|
/* Watchers: Forcibly discard old symbol group as switching from
|
||||||
@@ -1542,9 +1546,11 @@ void CdbEngine::updateLocals(bool forNewStackFrame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Required arguments: frame
|
// Required arguments: frame
|
||||||
|
const int flags = forNewStackFrame ? LocalsUpdateForNewFrame : 0;
|
||||||
str << blankSeparator << frameIndex;
|
str << blankSeparator << frameIndex;
|
||||||
watchHandler()->beginCycle();
|
postExtensionCommand("locals", arguments, 0,
|
||||||
postExtensionCommand("locals", arguments, 0, &CdbEngine::handleLocals, 0, QVariant(forNewStackFrame));
|
&CdbEngine::handleLocals, 0,
|
||||||
|
QVariant(flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CdbEngine::selectThread(int index)
|
void CdbEngine::selectThread(int index)
|
||||||
@@ -1925,6 +1931,9 @@ void CdbEngine::handleRegisters(const CdbExtensionCommandPtr &reply)
|
|||||||
|
|
||||||
void CdbEngine::handleLocals(const CdbExtensionCommandPtr &reply)
|
void CdbEngine::handleLocals(const CdbExtensionCommandPtr &reply)
|
||||||
{
|
{
|
||||||
|
const int flags = reply->cookie.toInt();
|
||||||
|
if (!(flags & PartialLocalsUpdate))
|
||||||
|
watchHandler()->removeAllData();
|
||||||
if (reply->success) {
|
if (reply->success) {
|
||||||
QList<WatchData> watchData;
|
QList<WatchData> watchData;
|
||||||
GdbMi root;
|
GdbMi root;
|
||||||
@@ -1940,16 +1949,14 @@ void CdbEngine::handleLocals(const CdbExtensionCommandPtr &reply)
|
|||||||
dummy.name = QLatin1String(child.findChild("name").data());
|
dummy.name = QLatin1String(child.findChild("name").data());
|
||||||
parseWatchData(watchHandler()->expandedINames(), dummy, child, &watchData);
|
parseWatchData(watchHandler()->expandedINames(), dummy, child, &watchData);
|
||||||
}
|
}
|
||||||
watchHandler()->insertBulkData(watchData);
|
watchHandler()->insertData(watchData);
|
||||||
watchHandler()->endCycle();
|
|
||||||
if (debugLocals) {
|
if (debugLocals) {
|
||||||
QDebug nsp = qDebug().nospace();
|
QDebug nsp = qDebug().nospace();
|
||||||
nsp << "Obtained " << watchData.size() << " items:\n";
|
nsp << "Obtained " << watchData.size() << " items:\n";
|
||||||
foreach (const WatchData &wd, watchData)
|
foreach (const WatchData &wd, watchData)
|
||||||
nsp << wd.toString() <<'\n';
|
nsp << wd.toString() <<'\n';
|
||||||
}
|
}
|
||||||
const bool forNewStackFrame = reply->cookie.toBool();
|
if (flags & LocalsUpdateForNewFrame)
|
||||||
if (forNewStackFrame)
|
|
||||||
emit stackFrameCompleted();
|
emit stackFrameCompleted();
|
||||||
} else {
|
} else {
|
||||||
showMessage(QString::fromLatin1(reply->errorMessage), LogWarning);
|
showMessage(QString::fromLatin1(reply->errorMessage), LogWarning);
|
||||||
|
@@ -85,7 +85,7 @@ public:
|
|||||||
virtual QVariant configValue(const QString &name) const = 0;
|
virtual QVariant configValue(const QString &name) const = 0;
|
||||||
virtual void setConfigValue(const QString &name, const QVariant &value) = 0;
|
virtual void setConfigValue(const QString &name, const QVariant &value) = 0;
|
||||||
virtual void updateState(DebuggerEngine *engine) = 0;
|
virtual void updateState(DebuggerEngine *engine) = 0;
|
||||||
virtual void updateWatchersWindow() = 0;
|
virtual void updateWatchersWindow(bool showWatch, bool showReturn) = 0;
|
||||||
virtual void showQtDumperLibraryWarning(const QString &details) = 0;
|
virtual void showQtDumperLibraryWarning(const QString &details) = 0;
|
||||||
virtual QIcon locationMarkIcon() const = 0;
|
virtual QIcon locationMarkIcon() const = 0;
|
||||||
virtual const CPlusPlus::Snapshot &cppCodeModelSnapshot() const = 0;
|
virtual const CPlusPlus::Snapshot &cppCodeModelSnapshot() const = 0;
|
||||||
|
@@ -491,42 +491,32 @@ QAbstractItemModel *DebuggerEngine::threadsModel() const
|
|||||||
|
|
||||||
QAbstractItemModel *DebuggerEngine::localsModel() const
|
QAbstractItemModel *DebuggerEngine::localsModel() const
|
||||||
{
|
{
|
||||||
QAbstractItemModel *model = watchHandler()->model(LocalsWatch);
|
return watchHandler()->model();
|
||||||
if (model->objectName().isEmpty()) // Make debugging easier.
|
|
||||||
model->setObjectName(objectName() + QLatin1String("LocalsModel"));
|
|
||||||
return model;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QAbstractItemModel *DebuggerEngine::watchersModel() const
|
QAbstractItemModel *DebuggerEngine::watchersModel() const
|
||||||
{
|
{
|
||||||
QAbstractItemModel *model = watchHandler()->model(WatchersWatch);
|
return watchHandler()->model();
|
||||||
if (model->objectName().isEmpty()) // Make debugging easier.
|
|
||||||
model->setObjectName(objectName() + QLatin1String("WatchersModel"));
|
|
||||||
return model;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QAbstractItemModel *DebuggerEngine::returnModel() const
|
QAbstractItemModel *DebuggerEngine::returnModel() const
|
||||||
{
|
{
|
||||||
QAbstractItemModel *model = watchHandler()->model(ReturnWatch);
|
return watchHandler()->model();
|
||||||
if (model->objectName().isEmpty()) // Make debugging easier.
|
|
||||||
model->setObjectName(objectName() + QLatin1String("ReturnModel"));
|
|
||||||
return model;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QAbstractItemModel *DebuggerEngine::inspectorModel() const
|
QAbstractItemModel *DebuggerEngine::inspectorModel() const
|
||||||
{
|
{
|
||||||
QAbstractItemModel *model = watchHandler()->model(InspectWatch);
|
return watchHandler()->model();
|
||||||
if (model->objectName().isEmpty()) // Make debugging easier.
|
|
||||||
model->setObjectName(objectName() + QLatin1String("InspectorModel"));
|
|
||||||
return model;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QAbstractItemModel *DebuggerEngine::toolTipsModel() const
|
QAbstractItemModel *DebuggerEngine::toolTipsModel() const
|
||||||
{
|
{
|
||||||
QAbstractItemModel *model = watchHandler()->model(TooltipsWatch);
|
return watchHandler()->model();
|
||||||
if (model->objectName().isEmpty()) // Make debugging easier.
|
}
|
||||||
model->setObjectName(objectName() + QLatin1String("TooltipsModel"));
|
|
||||||
return model;
|
QAbstractItemModel *DebuggerEngine::watchModel() const
|
||||||
|
{
|
||||||
|
return watchHandler()->model();
|
||||||
}
|
}
|
||||||
|
|
||||||
QAbstractItemModel *DebuggerEngine::sourceFilesModel() const
|
QAbstractItemModel *DebuggerEngine::sourceFilesModel() const
|
||||||
|
@@ -229,11 +229,12 @@ public:
|
|||||||
virtual QAbstractItemModel *registerModel() const;
|
virtual QAbstractItemModel *registerModel() const;
|
||||||
virtual QAbstractItemModel *stackModel() const;
|
virtual QAbstractItemModel *stackModel() const;
|
||||||
virtual QAbstractItemModel *threadsModel() const;
|
virtual QAbstractItemModel *threadsModel() const;
|
||||||
virtual QAbstractItemModel *localsModel() const;
|
virtual QAbstractItemModel *localsModel() const; // Deprecated, FIXME: use watchModel
|
||||||
virtual QAbstractItemModel *watchersModel() const;
|
virtual QAbstractItemModel *watchersModel() const; // Deprecated, FIXME: use watchModel
|
||||||
virtual QAbstractItemModel *returnModel() const;
|
virtual QAbstractItemModel *returnModel() const; // Deprecated, FIXME: use watchModel
|
||||||
virtual QAbstractItemModel *inspectorModel() const;
|
virtual QAbstractItemModel *inspectorModel() const; // Deprecated, FIXME: use watchModel
|
||||||
virtual QAbstractItemModel *toolTipsModel() const;
|
virtual QAbstractItemModel *toolTipsModel() const; // Deprecated, FIXME: use watchModel
|
||||||
|
virtual QAbstractItemModel *watchModel() const;
|
||||||
virtual QAbstractItemModel *sourceFilesModel() const;
|
virtual QAbstractItemModel *sourceFilesModel() const;
|
||||||
virtual QAbstractItemModel *qtMessageLogModel() const;
|
virtual QAbstractItemModel *qtMessageLogModel() const;
|
||||||
|
|
||||||
|
@@ -815,7 +815,7 @@ public slots:
|
|||||||
void fontSettingsChanged(const TextEditor::FontSettings &settings);
|
void fontSettingsChanged(const TextEditor::FontSettings &settings);
|
||||||
|
|
||||||
void updateState(DebuggerEngine *engine);
|
void updateState(DebuggerEngine *engine);
|
||||||
void updateWatchersWindow();
|
void updateWatchersWindow(bool showWatch, bool showReturn);
|
||||||
void onCurrentProjectChanged(ProjectExplorer::Project *project);
|
void onCurrentProjectChanged(ProjectExplorer::Project *project);
|
||||||
|
|
||||||
void sessionLoaded();
|
void sessionLoaded();
|
||||||
@@ -2238,12 +2238,10 @@ void DebuggerPluginPrivate::setInitialState()
|
|||||||
m_qtMessageLogWindow->setEnabled(true);
|
m_qtMessageLogWindow->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerPluginPrivate::updateWatchersWindow()
|
void DebuggerPluginPrivate::updateWatchersWindow(bool showWatch, bool showReturn)
|
||||||
{
|
{
|
||||||
m_watchersWindow->setVisible(
|
m_watchersWindow->setVisible(showWatch);
|
||||||
m_watchersWindow->model()->rowCount(QModelIndex()) > 0);
|
m_returnWindow->setVisible(showReturn);
|
||||||
m_returnWindow->setVisible(
|
|
||||||
m_returnWindow->model()->rowCount(QModelIndex()) > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
|
void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
|
||||||
@@ -2254,8 +2252,7 @@ void DebuggerPluginPrivate::updateState(DebuggerEngine *engine)
|
|||||||
QTC_ASSERT(!engine->isSlaveEngine(), return);
|
QTC_ASSERT(!engine->isSlaveEngine(), return);
|
||||||
|
|
||||||
m_threadBox->setCurrentIndex(engine->threadsHandler()->currentThread());
|
m_threadBox->setCurrentIndex(engine->threadsHandler()->currentThread());
|
||||||
|
engine->watchHandler()->updateWatchersWindow();
|
||||||
updateWatchersWindow();
|
|
||||||
|
|
||||||
const DebuggerState state = engine->state();
|
const DebuggerState state = engine->state();
|
||||||
//showMessage(QString("PLUGIN SET STATE: ")
|
//showMessage(QString("PLUGIN SET STATE: ")
|
||||||
|
@@ -230,7 +230,6 @@ QDataStream &operator<<(QDataStream &stream, const WatchData &wd)
|
|||||||
stream << wd.address;
|
stream << wd.address;
|
||||||
stream << wd.size;
|
stream << wd.size;
|
||||||
stream << wd.hasChildren;
|
stream << wd.hasChildren;
|
||||||
stream << wd.generation;
|
|
||||||
stream << wd.valueEnabled;
|
stream << wd.valueEnabled;
|
||||||
stream << wd.valueEditable;
|
stream << wd.valueEditable;
|
||||||
stream << wd.error;
|
stream << wd.error;
|
||||||
@@ -256,7 +255,6 @@ QDataStream &operator>>(QDataStream &stream, WatchData &wd)
|
|||||||
stream >> wd.address;
|
stream >> wd.address;
|
||||||
stream >> wd.size;
|
stream >> wd.size;
|
||||||
stream >> wd.hasChildren;
|
stream >> wd.hasChildren;
|
||||||
stream >> wd.generation;
|
|
||||||
stream >> wd.valueEnabled;
|
stream >> wd.valueEnabled;
|
||||||
stream >> wd.valueEditable;
|
stream >> wd.valueEditable;
|
||||||
stream >> wd.error;
|
stream >> wd.error;
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "debuggertooltipmanager.h"
|
#include "debuggertooltipmanager.h"
|
||||||
|
#include "debuggerinternalconstants.h"
|
||||||
#include "watchutils.h"
|
#include "watchutils.h"
|
||||||
#include "debuggerengine.h"
|
#include "debuggerengine.h"
|
||||||
#include "debuggeractions.h"
|
#include "debuggeractions.h"
|
||||||
@@ -617,7 +618,7 @@ DebuggerToolTipWidget::DebuggerToolTipWidget(QWidget *parent) :
|
|||||||
m_titleLabel(new DraggableLabel),
|
m_titleLabel(new DraggableLabel),
|
||||||
m_engineAcquired(false),
|
m_engineAcquired(false),
|
||||||
m_creationDate(QDate::currentDate()),
|
m_creationDate(QDate::currentDate()),
|
||||||
m_debuggerModel(TooltipsWatch),
|
m_debuggerModel(TooltipType),
|
||||||
m_treeView(new DebuggerToolTipTreeView),
|
m_treeView(new DebuggerToolTipTreeView),
|
||||||
m_defaultModel(new QStandardItemModel(this))
|
m_defaultModel(new QStandardItemModel(this))
|
||||||
{
|
{
|
||||||
@@ -664,7 +665,7 @@ bool DebuggerToolTipWidget::matches(const QString &fileName,
|
|||||||
return function == m_context.function;
|
return function == m_context.function;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerToolTipWidget::acquireEngine(Debugger::DebuggerEngine *engine)
|
void DebuggerToolTipWidget::acquireEngine(DebuggerEngine *engine)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(engine, return);
|
QTC_ASSERT(engine, return);
|
||||||
|
|
||||||
@@ -836,7 +837,7 @@ void DebuggerToolTipWidget::saveSessionData(QXmlStreamWriter &w) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class Debugger::Internal::DebuggerToolTipExpressionFilterModel
|
\class Debugger::Internal::TooltipFilterModel
|
||||||
|
|
||||||
\brief Model for tooltips filtering a local variable using the locals or tooltip model,
|
\brief Model for tooltips filtering a local variable using the locals or tooltip model,
|
||||||
matching on the name.
|
matching on the name.
|
||||||
@@ -847,50 +848,46 @@ void DebuggerToolTipWidget::saveSessionData(QXmlStreamWriter &w) const
|
|||||||
In addition, suppress the model's tooltip data to avoid a tooltip on a tooltip.
|
In addition, suppress the model's tooltip data to avoid a tooltip on a tooltip.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class DebuggerToolTipExpressionFilterModel : public QSortFilterProxyModel
|
class TooltipFilterModel : public QSortFilterProxyModel
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit DebuggerToolTipExpressionFilterModel(QAbstractItemModel *model, const QString &exp, QObject *parent = 0);
|
TooltipFilterModel(QAbstractItemModel *model, const QString &exp, int debuggerModel) :
|
||||||
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
|
m_expressions(exp.split(QLatin1Char('.'))),
|
||||||
|
m_debuggerModel(debuggerModel)
|
||||||
|
{
|
||||||
|
setSourceModel(model);
|
||||||
|
}
|
||||||
|
|
||||||
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const
|
||||||
|
{
|
||||||
|
return role == Qt::ToolTipRole
|
||||||
|
? QVariant() : QSortFilterProxyModel::data(index, role);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QStringList m_expressions;
|
const QStringList m_expressions;
|
||||||
|
int m_debuggerModel;
|
||||||
};
|
};
|
||||||
|
|
||||||
DebuggerToolTipExpressionFilterModel::DebuggerToolTipExpressionFilterModel(QAbstractItemModel *model,
|
bool TooltipFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||||
const QString &exp,
|
|
||||||
QObject *parent) :
|
|
||||||
QSortFilterProxyModel(parent),
|
|
||||||
m_expressions(exp.split(QLatin1Char('.')))
|
|
||||||
{
|
{
|
||||||
setSourceModel(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant DebuggerToolTipExpressionFilterModel::data(const QModelIndex &index, int role) const
|
|
||||||
{
|
|
||||||
return role != Qt::ToolTipRole ?
|
|
||||||
QSortFilterProxyModel::data(index, role) : QVariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return depth of a model index, that is, 0 for root index, 1 for level-1 children, etc.
|
|
||||||
static inline int indexDepth(QModelIndex index)
|
|
||||||
{
|
|
||||||
int depth = 0;
|
|
||||||
for ( ; index.isValid() ; index = index.parent())
|
|
||||||
depth++;
|
|
||||||
return depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DebuggerToolTipExpressionFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
|
||||||
{
|
|
||||||
// Match on expression for top level, else pass through.
|
|
||||||
const int depth = indexDepth(sourceParent);
|
|
||||||
if (depth >= m_expressions.size()) // No filters at this level
|
|
||||||
return true;
|
|
||||||
const QModelIndex nameIndex = sourceModel()->index(sourceRow, 0, sourceParent);
|
const QModelIndex nameIndex = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||||
return nameIndex.data().toString() == m_expressions.at(depth);
|
QByteArray iname = nameIndex.data(LocalsINameRole).toByteArray();
|
||||||
|
if (m_debuggerModel == LocalsType && !iname.startsWith("local"))
|
||||||
|
return false;
|
||||||
|
if (m_debuggerModel == TooltipType && !iname.startsWith("tooltip"))
|
||||||
|
return false;
|
||||||
|
// Match on expression for top level, else pass through.
|
||||||
|
const int depth = iname.count('.');
|
||||||
|
if (depth == 0)
|
||||||
|
return true;
|
||||||
|
if (depth > m_expressions.size())
|
||||||
|
return true;
|
||||||
|
const QString name = nameIndex.data().toString();
|
||||||
|
//const QString exp = nameIndex.data(LocalsExpressionRole).toString();
|
||||||
|
return name == m_expressions.at(depth - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@@ -924,6 +921,7 @@ QAbstractItemModel *DebuggerToolTipTreeView::swapModel(QAbstractItemModel *newMo
|
|||||||
if (previousModel)
|
if (previousModel)
|
||||||
previousModel->disconnect(SIGNAL(rowsInserted(QModelIndex,int,int)), this);
|
previousModel->disconnect(SIGNAL(rowsInserted(QModelIndex,int,int)), this);
|
||||||
setModel(newModel);
|
setModel(newModel);
|
||||||
|
//setRootIndex(newModel->index(0, 0));
|
||||||
connect(newModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
|
connect(newModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
|
||||||
this, SLOT(computeSize()), Qt::QueuedConnection);
|
this, SLOT(computeSize()), Qt::QueuedConnection);
|
||||||
computeSize();
|
computeSize();
|
||||||
@@ -991,24 +989,12 @@ void DebuggerToolTipTreeView::computeSize()
|
|||||||
setRootIsDecorated(rootDecorated);
|
setRootIsDecorated(rootDecorated);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerToolTipWidget::doAcquireEngine(Debugger::DebuggerEngine *engine)
|
void DebuggerToolTipWidget::doAcquireEngine(DebuggerEngine *engine)
|
||||||
{
|
{
|
||||||
// Create a filter model on the debugger's model and switch to it.
|
// Create a filter model on the debugger's model and switch to it.
|
||||||
QAbstractItemModel *model = 0;
|
QAbstractItemModel *model = engine->watchModel();
|
||||||
switch (m_debuggerModel) {
|
TooltipFilterModel *filterModel =
|
||||||
case LocalsWatch:
|
new TooltipFilterModel(model, m_expression, m_debuggerModel);
|
||||||
model = engine->localsModel();
|
|
||||||
break;
|
|
||||||
case WatchersWatch:
|
|
||||||
model = engine->watchersModel();
|
|
||||||
break;
|
|
||||||
case TooltipsWatch:
|
|
||||||
model = engine->toolTipsModel();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
QTC_ASSERT(model, return);
|
|
||||||
DebuggerToolTipExpressionFilterModel *filterModel =
|
|
||||||
new DebuggerToolTipExpressionFilterModel(model, m_expression);
|
|
||||||
swapModel(filterModel);
|
swapModel(filterModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1311,7 +1297,7 @@ void DebuggerToolTipManager::slotUpdateVisibleToolTips()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DebuggerToolTipManager::slotDebuggerStateChanged(Debugger::DebuggerState state)
|
void DebuggerToolTipManager::slotDebuggerStateChanged(DebuggerState state)
|
||||||
{
|
{
|
||||||
const QObject *engine = sender();
|
const QObject *engine = sender();
|
||||||
QTC_ASSERT(engine, return);
|
QTC_ASSERT(engine, return);
|
||||||
@@ -1319,7 +1305,7 @@ void DebuggerToolTipManager::slotDebuggerStateChanged(Debugger::DebuggerState st
|
|||||||
const QString name = engine->objectName();
|
const QString name = engine->objectName();
|
||||||
if (debugToolTips)
|
if (debugToolTips)
|
||||||
qDebug() << "DebuggerToolTipWidget::debuggerStateChanged"
|
qDebug() << "DebuggerToolTipWidget::debuggerStateChanged"
|
||||||
<< engine << Debugger::DebuggerEngine::stateName(state);
|
<< engine << DebuggerEngine::stateName(state);
|
||||||
|
|
||||||
// Release at earliest possible convenience.
|
// Release at earliest possible convenience.
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
@@ -63,8 +63,11 @@ void AbstractPlainGdbAdapter::setupInferior()
|
|||||||
QString args = startParameters().processArgs;
|
QString args = startParameters().processArgs;
|
||||||
m_engine->postCommand("-exec-arguments " + toLocalEncoding(args));
|
m_engine->postCommand("-exec-arguments " + toLocalEncoding(args));
|
||||||
}
|
}
|
||||||
m_engine->postCommand("-file-exec-and-symbols \"" + execFilePath() + '"',
|
if (m_engine->gdbVersion() > 70000)
|
||||||
CB(handleFileExecAndSymbols));
|
m_engine->postCommand("-file-exec-and-symbols \"" + execFilePath() + '"',
|
||||||
|
CB(handleFileExecAndSymbols));
|
||||||
|
else
|
||||||
|
m_engine->postCommand("file " + execFilePath(), CB(handleFileExecAndSymbols));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractPlainGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response)
|
void AbstractPlainGdbAdapter::handleFileExecAndSymbols(const GdbResponse &response)
|
||||||
|
@@ -716,7 +716,7 @@ static bool parseConsoleStream(const GdbResponse &response, GdbMi *contents)
|
|||||||
void GdbEngine::updateLocalsClassic()
|
void GdbEngine::updateLocalsClassic()
|
||||||
{
|
{
|
||||||
PRECONDITION;
|
PRECONDITION;
|
||||||
m_pendingWatchRequests = 0;
|
//m_pendingWatchRequests = 0;
|
||||||
m_pendingBreakpointRequests = 0;
|
m_pendingBreakpointRequests = 0;
|
||||||
m_processedNames.clear();
|
m_processedNames.clear();
|
||||||
|
|
||||||
@@ -724,15 +724,14 @@ void GdbEngine::updateLocalsClassic()
|
|||||||
qDebug() << "\nRESET PENDING";
|
qDebug() << "\nRESET PENDING";
|
||||||
//m_toolTipCache.clear();
|
//m_toolTipCache.clear();
|
||||||
clearToolTip();
|
clearToolTip();
|
||||||
watchHandler()->beginCycle();
|
|
||||||
|
|
||||||
QByteArray level = QByteArray::number(currentFrame());
|
QByteArray level = QByteArray::number(currentFrame());
|
||||||
// '2' is 'list with type and value'
|
// '2' is 'list with type and value'
|
||||||
QByteArray cmd = "-stack-list-arguments 2 " + level + ' ' + level;
|
QByteArray cmd = "-stack-list-arguments 2 " + level + ' ' + level;
|
||||||
postCommand(cmd, WatchUpdate,
|
postCommand(cmd, Discardable,
|
||||||
CB(handleStackListArgumentsClassic));
|
CB(handleStackListArgumentsClassic));
|
||||||
// '2' is 'list with type and value'
|
// '2' is 'list with type and value'
|
||||||
postCommand("-stack-list-locals 2", WatchUpdate,
|
postCommand("-stack-list-locals 2", Discardable,
|
||||||
CB(handleStackListLocalsClassic)); // stage 2/2
|
CB(handleStackListLocalsClassic)); // stage 2/2
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -754,9 +753,9 @@ void GdbEngine::runDirectDebuggingHelperClassic(const WatchData &data, bool dump
|
|||||||
|
|
||||||
QVariant var;
|
QVariant var;
|
||||||
var.setValue(data);
|
var.setValue(data);
|
||||||
postCommand(cmd, WatchUpdate, CB(handleDebuggingHelperValue3Classic), var);
|
postCommand(cmd, Discardable, CB(handleDebuggingHelperValue3Classic), var);
|
||||||
|
|
||||||
showStatusMessage(msgRetrievingWatchData(m_pendingWatchRequests + 1), 10000);
|
showStatusMessage(msgRetrievingWatchData(m_uncompleted.size()), 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::runDebuggingHelperClassic(const WatchData &data0, bool dumpChildren)
|
void GdbEngine::runDebuggingHelperClassic(const WatchData &data0, bool dumpChildren)
|
||||||
@@ -811,25 +810,25 @@ void GdbEngine::runDebuggingHelperClassic(const WatchData &data0, bool dumpChild
|
|||||||
cmd += ',' + ex;
|
cmd += ',' + ex;
|
||||||
cmd += ')';
|
cmd += ')';
|
||||||
|
|
||||||
postCommand(cmd, WatchUpdate | NonCriticalResponse);
|
postCommand(cmd, Discardable | NonCriticalResponse);
|
||||||
|
|
||||||
showStatusMessage(msgRetrievingWatchData(m_pendingWatchRequests + 1), 10000);
|
showStatusMessage(msgRetrievingWatchData(m_uncompleted.size()), 10000);
|
||||||
|
|
||||||
// retrieve response
|
// retrieve response
|
||||||
postCommand("p (char*)&qDumpOutBuffer", WatchUpdate,
|
postCommand("p (char*)&qDumpOutBuffer", Discardable,
|
||||||
CB(handleDebuggingHelperValue2Classic), qVariantFromValue(data));
|
CB(handleDebuggingHelperValue2Classic), qVariantFromValue(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::createGdbVariableClassic(const WatchData &data)
|
void GdbEngine::createGdbVariableClassic(const WatchData &data)
|
||||||
{
|
{
|
||||||
PRECONDITION;
|
PRECONDITION;
|
||||||
postCommand("-var-delete \"" + data.iname + '"', WatchUpdate);
|
postCommand("-var-delete \"" + data.iname + '"', Discardable);
|
||||||
QByteArray exp = data.exp;
|
QByteArray exp = data.exp;
|
||||||
if (exp.isEmpty() && data.address)
|
if (exp.isEmpty() && data.address)
|
||||||
exp = "*(" + gdbQuoteTypes(data.type) + "*)" + data.hexAddress();
|
exp = "*(" + gdbQuoteTypes(data.type) + "*)" + data.hexAddress();
|
||||||
QVariant val = QVariant::fromValue<WatchData>(data);
|
QVariant val = QVariant::fromValue<WatchData>(data);
|
||||||
postCommand("-var-create \"" + data.iname + "\" * \"" + exp + '"',
|
postCommand("-var-create \"" + data.iname + "\" * \"" + exp + '"',
|
||||||
WatchUpdate, CB(handleVarCreate), val);
|
Discardable, CB(handleVarCreate), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::updateSubItemClassic(const WatchData &data0)
|
void GdbEngine::updateSubItemClassic(const WatchData &data0)
|
||||||
@@ -929,7 +928,7 @@ void GdbEngine::updateSubItemClassic(const WatchData &data0)
|
|||||||
if (debugSubItem)
|
if (debugSubItem)
|
||||||
qDebug() << "UPDATE SUBITEM: VALUE";
|
qDebug() << "UPDATE SUBITEM: VALUE";
|
||||||
QByteArray cmd = "-var-evaluate-expression \"" + data.iname + '"';
|
QByteArray cmd = "-var-evaluate-expression \"" + data.iname + '"';
|
||||||
postCommand(cmd, WatchUpdate,
|
postCommand(cmd, Discardable,
|
||||||
CB(handleEvaluateExpressionClassic), QVariant::fromValue(data));
|
CB(handleEvaluateExpressionClassic), QVariant::fromValue(data));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -953,7 +952,7 @@ void GdbEngine::updateSubItemClassic(const WatchData &data0)
|
|||||||
if (data.isChildrenNeeded()) {
|
if (data.isChildrenNeeded()) {
|
||||||
QTC_ASSERT(!data.variable.isEmpty(), return); // tested above
|
QTC_ASSERT(!data.variable.isEmpty(), return); // tested above
|
||||||
QByteArray cmd = "-var-list-children --all-values \"" + data.variable + '"';
|
QByteArray cmd = "-var-list-children --all-values \"" + data.variable + '"';
|
||||||
postCommand(cmd, WatchUpdate,
|
postCommand(cmd, Discardable,
|
||||||
CB(handleVarListChildrenClassic), QVariant::fromValue(data));
|
CB(handleVarListChildrenClassic), QVariant::fromValue(data));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -999,7 +998,7 @@ void GdbEngine::handleDebuggingHelperValue2Classic(const GdbResponse &response)
|
|||||||
if (m_cookieForToken.contains(response.token - 1)) {
|
if (m_cookieForToken.contains(response.token - 1)) {
|
||||||
m_cookieForToken.remove(response.token - 1);
|
m_cookieForToken.remove(response.token - 1);
|
||||||
showMessage(_("DETECTING LOST COMMAND %1").arg(response.token - 1));
|
showMessage(_("DETECTING LOST COMMAND %1").arg(response.token - 1));
|
||||||
--m_pendingWatchRequests;
|
// --m_pendingWatchRequests;
|
||||||
data.setError(WatchData::msgNotInScope());
|
data.setError(WatchData::msgNotInScope());
|
||||||
insertData(data);
|
insertData(data);
|
||||||
return;
|
return;
|
||||||
@@ -1025,7 +1024,7 @@ void GdbEngine::handleDebuggingHelperValue2Classic(const GdbResponse &response)
|
|||||||
parseWatchData(watchHandler()->expandedINames(), data, contents, &list);
|
parseWatchData(watchHandler()->expandedINames(), data, contents, &list);
|
||||||
//for (int i = 0; i != list.size(); ++i)
|
//for (int i = 0; i != list.size(); ++i)
|
||||||
// qDebug() << "READ: " << list.at(i).toString();
|
// qDebug() << "READ: " << list.at(i).toString();
|
||||||
watchHandler()->insertBulkData(list);
|
watchHandler()->insertData(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::handleDebuggingHelperValue3Classic(const GdbResponse &response)
|
void GdbEngine::handleDebuggingHelperValue3Classic(const GdbResponse &response)
|
||||||
@@ -1082,7 +1081,7 @@ void GdbEngine::handleDebuggingHelperValue3Classic(const GdbResponse &response)
|
|||||||
QByteArray cmd = "qdumpqstring (" + data1.exp + ')';
|
QByteArray cmd = "qdumpqstring (" + data1.exp + ')';
|
||||||
QVariant var;
|
QVariant var;
|
||||||
var.setValue(data1);
|
var.setValue(data1);
|
||||||
postCommand(cmd, WatchUpdate,
|
postCommand(cmd, Discardable,
|
||||||
CB(handleDebuggingHelperValue3Classic), var);
|
CB(handleDebuggingHelperValue3Classic), var);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1101,6 +1100,9 @@ void GdbEngine::handleDebuggingHelperValue3Classic(const GdbResponse &response)
|
|||||||
|
|
||||||
void GdbEngine::tryLoadDebuggingHelpersClassic()
|
void GdbEngine::tryLoadDebuggingHelpersClassic()
|
||||||
{
|
{
|
||||||
|
if (m_forceAsyncModel)
|
||||||
|
return;
|
||||||
|
|
||||||
PRECONDITION;
|
PRECONDITION;
|
||||||
if (m_gdbAdapter->dumperHandling() == AbstractGdbAdapter::DumperNotAvailable) {
|
if (m_gdbAdapter->dumperHandling() == AbstractGdbAdapter::DumperNotAvailable) {
|
||||||
// Load at least gdb macro based dumpers.
|
// Load at least gdb macro based dumpers.
|
||||||
@@ -1171,12 +1173,12 @@ void GdbEngine::updateAllClassic()
|
|||||||
qDebug() << state());
|
qDebug() << state());
|
||||||
tryLoadDebuggingHelpersClassic();
|
tryLoadDebuggingHelpersClassic();
|
||||||
reloadModulesInternal();
|
reloadModulesInternal();
|
||||||
postCommand("-stack-list-frames", WatchUpdate,
|
postCommand("-stack-list-frames", Discardable,
|
||||||
CB(handleStackListFrames),
|
CB(handleStackListFrames),
|
||||||
QVariant::fromValue<StackCookie>(StackCookie(false, true)));
|
QVariant::fromValue<StackCookie>(StackCookie(false, true)));
|
||||||
stackHandler()->setCurrentIndex(0);
|
stackHandler()->setCurrentIndex(0);
|
||||||
if (supportsThreads())
|
if (supportsThreads())
|
||||||
postCommand("-thread-list-ids", WatchUpdate, CB(handleThreadListIds), 0);
|
postCommand("-thread-list-ids", Discardable, CB(handleThreadListIds), 0);
|
||||||
reloadRegisters();
|
reloadRegisters();
|
||||||
updateLocals();
|
updateLocals();
|
||||||
}
|
}
|
||||||
@@ -1248,11 +1250,10 @@ void GdbEngine::handleStackListLocalsClassic(const GdbResponse &response)
|
|||||||
frame.function, frame.file, frame.line,
|
frame.function, frame.file, frame.line,
|
||||||
&uninitializedVariables);
|
&uninitializedVariables);
|
||||||
}
|
}
|
||||||
QList<WatchData> list;
|
|
||||||
foreach (const GdbMi &item, locals) {
|
foreach (const GdbMi &item, locals) {
|
||||||
const WatchData data = localVariable(item, uninitializedVariables, &seen);
|
const WatchData data = localVariable(item, uninitializedVariables, &seen);
|
||||||
if (data.isValid())
|
if (data.isValid())
|
||||||
list.push_back(data);
|
insertData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_resultVarName.isEmpty()) {
|
if (!m_resultVarName.isEmpty()) {
|
||||||
@@ -1260,10 +1261,9 @@ void GdbEngine::handleStackListLocalsClassic(const GdbResponse &response)
|
|||||||
rd.iname = "return.0";
|
rd.iname = "return.0";
|
||||||
rd.name = QLatin1String("return");
|
rd.name = QLatin1String("return");
|
||||||
rd.exp = m_resultVarName;
|
rd.exp = m_resultVarName;
|
||||||
list.append(rd);
|
insertData(rd);
|
||||||
}
|
}
|
||||||
|
|
||||||
watchHandler()->insertBulkData(list);
|
|
||||||
watchHandler()->updateWatchers();
|
watchHandler()->updateWatchers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1371,7 +1371,7 @@ void GdbEngine::handleVarListChildrenHelperClassic(const GdbMi &item,
|
|||||||
data.setChildrenUnneeded();
|
data.setChildrenUnneeded();
|
||||||
QByteArray cmd = "-var-list-children --all-values \"" + data.variable + '"';
|
QByteArray cmd = "-var-list-children --all-values \"" + data.variable + '"';
|
||||||
//iname += '.' + exp;
|
//iname += '.' + exp;
|
||||||
postCommand(cmd, WatchUpdate,
|
postCommand(cmd, Discardable,
|
||||||
CB(handleVarListChildrenClassic), QVariant::fromValue(data));
|
CB(handleVarListChildrenClassic), QVariant::fromValue(data));
|
||||||
} else if (!startsWithDigit(QLatin1String(exp))
|
} else if (!startsWithDigit(QLatin1String(exp))
|
||||||
&& item.findChild("numchild").data() == "0") {
|
&& item.findChild("numchild").data() == "0") {
|
||||||
@@ -1390,7 +1390,7 @@ void GdbEngine::handleVarListChildrenHelperClassic(const GdbMi &item,
|
|||||||
WatchData data;
|
WatchData data;
|
||||||
data.iname = name;
|
data.iname = name;
|
||||||
QByteArray cmd = "-var-list-children --all-values \"" + data.variable + '"';
|
QByteArray cmd = "-var-list-children --all-values \"" + data.variable + '"';
|
||||||
postCommand(cmd, WatchUpdate,
|
postCommand(cmd, Discardable,
|
||||||
CB(handleVarListChildrenClassic), QVariant::fromValue(data));
|
CB(handleVarListChildrenClassic), QVariant::fromValue(data));
|
||||||
} else if (exp == "staticMetaObject") {
|
} else if (exp == "staticMetaObject") {
|
||||||
// && item.findChild("type").data() == "const QMetaObject")
|
// && item.findChild("type").data() == "const QMetaObject")
|
||||||
@@ -1464,9 +1464,6 @@ void GdbEngine::handleVarListChildrenClassic(const GdbResponse &response)
|
|||||||
//qDebug() << "VAR_LIST_CHILDREN: PARENT" << data.toString();
|
//qDebug() << "VAR_LIST_CHILDREN: PARENT" << data.toString();
|
||||||
QList<GdbMi> children = response.data.findChild("children").children();
|
QList<GdbMi> children = response.data.findChild("children").children();
|
||||||
|
|
||||||
for (int i = 0; i != children.size(); ++i)
|
|
||||||
handleVarListChildrenHelperClassic(children.at(i), data, i);
|
|
||||||
|
|
||||||
if (children.isEmpty()) {
|
if (children.isEmpty()) {
|
||||||
// happens e.g. if no debug information is present or
|
// happens e.g. if no debug information is present or
|
||||||
// if the class really has no children
|
// if the class really has no children
|
||||||
@@ -1479,14 +1476,18 @@ void GdbEngine::handleVarListChildrenClassic(const GdbResponse &response)
|
|||||||
insertData(data1);
|
insertData(data1);
|
||||||
data.setAllUnneeded();
|
data.setAllUnneeded();
|
||||||
insertData(data);
|
insertData(data);
|
||||||
} else if (data.variable.endsWith("private")
|
} else {
|
||||||
|
if (data.variable.endsWith("private")
|
||||||
|| data.variable.endsWith("protected")
|
|| data.variable.endsWith("protected")
|
||||||
|| data.variable.endsWith("public")) {
|
|| data.variable.endsWith("public")) {
|
||||||
// this skips the spurious "public", "private" etc levels
|
// this skips the spurious "public", "private" etc levels
|
||||||
// gdb produces
|
// gdb produces
|
||||||
} else {
|
} else {
|
||||||
data.setChildrenUnneeded();
|
data.setChildrenUnneeded();
|
||||||
insertData(data);
|
insertData(data);
|
||||||
|
}
|
||||||
|
for (int i = 0; i != children.size(); ++i)
|
||||||
|
handleVarListChildrenHelperClassic(children.at(i), data, i);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
data.setError(QString::fromLocal8Bit(response.data.findChild("msg").data()));
|
data.setError(QString::fromLocal8Bit(response.data.findChild("msg").data()));
|
||||||
|
@@ -255,7 +255,6 @@ GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters,
|
|||||||
m_oldestAcceptableToken = -1;
|
m_oldestAcceptableToken = -1;
|
||||||
m_nonDiscardableCount = 0;
|
m_nonDiscardableCount = 0;
|
||||||
m_outputCodec = QTextCodec::codecForLocale();
|
m_outputCodec = QTextCodec::codecForLocale();
|
||||||
m_pendingWatchRequests = 0;
|
|
||||||
m_pendingBreakpointRequests = 0;
|
m_pendingBreakpointRequests = 0;
|
||||||
m_commandsDoneCallback = 0;
|
m_commandsDoneCallback = 0;
|
||||||
m_stackNeeded = false;
|
m_stackNeeded = false;
|
||||||
@@ -263,6 +262,7 @@ GdbEngine::GdbEngine(const DebuggerStartParameters &startParameters,
|
|||||||
m_disassembleUsesComma = false;
|
m_disassembleUsesComma = false;
|
||||||
m_actingOnExpectedStop = false;
|
m_actingOnExpectedStop = false;
|
||||||
m_fullStartDone = false;
|
m_fullStartDone = false;
|
||||||
|
m_forceAsyncModel = false;
|
||||||
|
|
||||||
invalidateSourcesList();
|
invalidateSourcesList();
|
||||||
|
|
||||||
@@ -788,7 +788,8 @@ void GdbEngine::readGdbStandardOutput()
|
|||||||
int newstart = 0;
|
int newstart = 0;
|
||||||
int scan = m_inbuffer.size();
|
int scan = m_inbuffer.size();
|
||||||
|
|
||||||
m_inbuffer.append(gdbProc()->readAllStandardOutput());
|
QByteArray out = gdbProc()->readAllStandardOutput();
|
||||||
|
m_inbuffer.append(out);
|
||||||
|
|
||||||
// This can trigger when a dialog starts a nested event loop.
|
// This can trigger when a dialog starts a nested event loop.
|
||||||
if (m_busy)
|
if (m_busy)
|
||||||
@@ -811,7 +812,8 @@ void GdbEngine::readGdbStandardOutput()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
m_busy = true;
|
m_busy = true;
|
||||||
handleResponse(QByteArray::fromRawData(m_inbuffer.constData() + start, end - start));
|
QByteArray ba = QByteArray::fromRawData(m_inbuffer.constData() + start, end - start);
|
||||||
|
handleResponse(ba);
|
||||||
m_busy = false;
|
m_busy = false;
|
||||||
}
|
}
|
||||||
m_inbuffer.clear();
|
m_inbuffer.clear();
|
||||||
@@ -903,17 +905,13 @@ void GdbEngine::postCommandHelper(const GdbCommand &cmd)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd.flags & RebuildWatchModel) {
|
if (cmd.flags & RebuildBreakpointModel) {
|
||||||
++m_pendingWatchRequests;
|
|
||||||
PENDING_DEBUG(" WATCH MODEL:" << cmd.command << "=>" << cmd.callbackName
|
|
||||||
<< "INCREMENTS PENDING TO" << m_pendingWatchRequests);
|
|
||||||
} else if (cmd.flags & RebuildBreakpointModel) {
|
|
||||||
++m_pendingBreakpointRequests;
|
++m_pendingBreakpointRequests;
|
||||||
PENDING_DEBUG(" BRWAKPOINT MODEL:" << cmd.command << "=>" << cmd.callbackName
|
PENDING_DEBUG(" BRWAKPOINT MODEL:" << cmd.command << "=>" << cmd.callbackName
|
||||||
<< "INCREMENTS PENDING TO" << m_pendingBreakpointRequests);
|
<< "INCREMENTS PENDING TO" << m_pendingBreakpointRequests);
|
||||||
} else {
|
} else {
|
||||||
PENDING_DEBUG(" OTHER (IN):" << cmd.command << "=>" << cmd.callbackName
|
PENDING_DEBUG(" OTHER (IN):" << cmd.command << "=>" << cmd.callbackName
|
||||||
<< "LEAVES PENDING WATCH AT" << m_pendingWatchRequests
|
<< "LEAVES PENDING WATCH AT" << m_uncompleted.size()
|
||||||
<< "LEAVES PENDING BREAKPOINT AT" << m_pendingBreakpointRequests);
|
<< "LEAVES PENDING BREAKPOINT AT" << m_pendingBreakpointRequests);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1055,7 +1053,6 @@ void GdbEngine::commandTimeout()
|
|||||||
if (mb->exec() == QMessageBox::Ok) {
|
if (mb->exec() == QMessageBox::Ok) {
|
||||||
showMessage(_("KILLING DEBUGGER AS REQUESTED BY USER"));
|
showMessage(_("KILLING DEBUGGER AS REQUESTED BY USER"));
|
||||||
// This is an undefined state, so we just pull the emergency brake.
|
// This is an undefined state, so we just pull the emergency brake.
|
||||||
watchHandler()->endCycle();
|
|
||||||
gdbProc()->kill();
|
gdbProc()->kill();
|
||||||
} else {
|
} else {
|
||||||
showMessage(_("CONTINUE DEBUGGER AS REQUESTED BY USER"));
|
showMessage(_("CONTINUE DEBUGGER AS REQUESTED BY USER"));
|
||||||
@@ -1205,25 +1202,17 @@ void GdbEngine::handleResultRecord(GdbResponse *response)
|
|||||||
else if (cmd.adapterCallback)
|
else if (cmd.adapterCallback)
|
||||||
(m_gdbAdapter->*cmd.adapterCallback)(*response);
|
(m_gdbAdapter->*cmd.adapterCallback)(*response);
|
||||||
|
|
||||||
if (cmd.flags & RebuildWatchModel) {
|
if (cmd.flags & RebuildBreakpointModel) {
|
||||||
--m_pendingWatchRequests;
|
|
||||||
PENDING_DEBUG(" WATCH" << cmd.command << "=>" << cmd.callbackName
|
|
||||||
<< "DECREMENTS PENDING WATCH TO" << m_pendingWatchRequests);
|
|
||||||
if (m_pendingWatchRequests <= 0) {
|
|
||||||
PENDING_DEBUG("\n\n ... AND TRIGGERS WATCH MODEL UPDATE\n");
|
|
||||||
rebuildWatchModel();
|
|
||||||
}
|
|
||||||
} else if (cmd.flags & RebuildBreakpointModel) {
|
|
||||||
--m_pendingBreakpointRequests;
|
--m_pendingBreakpointRequests;
|
||||||
PENDING_DEBUG(" BREAKPOINT" << cmd.command << "=>" << cmd.callbackName
|
PENDING_DEBUG(" BREAKPOINT" << cmd.command << "=>" << cmd.callbackName
|
||||||
<< "DECREMENTS PENDING TO" << m_pendingWatchRequests);
|
<< "DECREMENTS PENDING TO" << m_uncompleted.size());
|
||||||
if (m_pendingBreakpointRequests <= 0) {
|
if (m_pendingBreakpointRequests <= 0) {
|
||||||
PENDING_DEBUG("\n\n ... AND TRIGGERS BREAKPOINT MODEL UPDATE\n");
|
PENDING_DEBUG("\n\n ... AND TRIGGERS BREAKPOINT MODEL UPDATE\n");
|
||||||
attemptBreakpointSynchronization();
|
attemptBreakpointSynchronization();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PENDING_DEBUG(" OTHER (OUT):" << cmd.command << "=>" << cmd.callbackName
|
PENDING_DEBUG(" OTHER (OUT):" << cmd.command << "=>" << cmd.callbackName
|
||||||
<< "LEAVES PENDING WATCH AT" << m_pendingWatchRequests
|
<< "LEAVES PENDING WATCH AT" << m_uncompleted.size()
|
||||||
<< "LEAVES PENDING BREAKPOINT AT" << m_pendingBreakpointRequests);
|
<< "LEAVES PENDING BREAKPOINT AT" << m_pendingBreakpointRequests);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3918,10 +3907,10 @@ bool GdbEngine::supportsThreads() const
|
|||||||
//
|
//
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool GdbEngine::showToolTip()
|
void GdbEngine::showToolTip()
|
||||||
{
|
{
|
||||||
if (m_toolTipContext.isNull())
|
if (m_toolTipContext.isNull())
|
||||||
return false;
|
return;
|
||||||
const QString expression = m_toolTipContext->expression;
|
const QString expression = m_toolTipContext->expression;
|
||||||
const QByteArray iname = tooltipIName(m_toolTipContext->expression);
|
const QByteArray iname = tooltipIName(m_toolTipContext->expression);
|
||||||
if (DebuggerToolTipManager::debug())
|
if (DebuggerToolTipManager::debug())
|
||||||
@@ -3929,15 +3918,15 @@ bool GdbEngine::showToolTip()
|
|||||||
|
|
||||||
if (!debuggerCore()->boolSetting(UseToolTipsInMainEditor)) {
|
if (!debuggerCore()->boolSetting(UseToolTipsInMainEditor)) {
|
||||||
watchHandler()->removeData(iname);
|
watchHandler()->removeData(iname);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!watchHandler()->isValidToolTip(iname)) {
|
if (!watchHandler()->isValidToolTip(iname)) {
|
||||||
watchHandler()->removeData(iname);
|
watchHandler()->removeData(iname);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
DebuggerToolTipWidget *tw = new DebuggerToolTipWidget;
|
DebuggerToolTipWidget *tw = new DebuggerToolTipWidget;
|
||||||
tw->setDebuggerModel(TooltipsWatch);
|
tw->setDebuggerModel(TooltipType);
|
||||||
tw->setExpression(expression);
|
tw->setExpression(expression);
|
||||||
tw->setContext(*m_toolTipContext);
|
tw->setContext(*m_toolTipContext);
|
||||||
tw->acquireEngine(this);
|
tw->acquireEngine(this);
|
||||||
@@ -3945,7 +3934,6 @@ bool GdbEngine::showToolTip()
|
|||||||
m_toolTipContext->editor, tw);
|
m_toolTipContext->editor, tw);
|
||||||
// Prevent tooltip from re-occurring (classic GDB, QTCREATORBUG-4711).
|
// Prevent tooltip from re-occurring (classic GDB, QTCREATORBUG-4711).
|
||||||
m_toolTipContext.reset();
|
m_toolTipContext.reset();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString GdbEngine::tooltipExpression() const
|
QString GdbEngine::tooltipExpression() const
|
||||||
@@ -4034,7 +4022,6 @@ bool GdbEngine::setToolTipExpression(const QPoint &mousePos,
|
|||||||
toolTip.exp = exp.toLatin1();
|
toolTip.exp = exp.toLatin1();
|
||||||
toolTip.name = exp;
|
toolTip.name = exp;
|
||||||
toolTip.iname = tooltipIName(exp);
|
toolTip.iname = tooltipIName(exp);
|
||||||
watchHandler()->removeData(toolTip.iname);
|
|
||||||
watchHandler()->insertData(toolTip);
|
watchHandler()->insertData(toolTip);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -4071,19 +4058,12 @@ bool GdbEngine::hasDebuggingHelperForType(const QByteArray &type) const
|
|||||||
return m_dumperHelper.type(type) != DumperHelper::UnknownType;
|
return m_dumperHelper.type(type) != DumperHelper::UnknownType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GdbEngine::updateWatchData(const WatchData &data, const WatchUpdateFlags &flags)
|
void GdbEngine::updateWatchData(const WatchData &data, const WatchUpdateFlags &flags)
|
||||||
{
|
{
|
||||||
if (isSynchronous()) {
|
if (isSynchronous()) {
|
||||||
// This should only be called for fresh expanded items, not for
|
// This should only be called for fresh expanded items, not for
|
||||||
// items that had their children retrieved earlier.
|
// items that had their children retrieved earlier.
|
||||||
//qDebug() << "\nUPDATE WATCH DATA: " << data.toString() << "\n";
|
//qDebug() << "\nUPDATE WATCH DATA: " << data.toString() << "\n";
|
||||||
#if 0
|
|
||||||
WatchData data1 = data;
|
|
||||||
data1.setAllUnneeded();
|
|
||||||
insertData(data1);
|
|
||||||
rebuildModel();
|
|
||||||
#else
|
|
||||||
if (data.iname.endsWith("."))
|
if (data.iname.endsWith("."))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -4106,53 +4086,26 @@ void GdbEngine::updateWatchData(const WatchData &data, const WatchUpdateFlags &f
|
|||||||
// triggered e.g. by manually entered command in the gdb console?
|
// triggered e.g. by manually entered command in the gdb console?
|
||||||
//qDebug() << "TRY PARTIAL: " << flags.tryIncremental
|
//qDebug() << "TRY PARTIAL: " << flags.tryIncremental
|
||||||
// << hasPython()
|
// << hasPython()
|
||||||
// << (m_pendingWatchRequests == 0)
|
|
||||||
// << (m_pendingBreakpointRequests == 0);
|
// << (m_pendingBreakpointRequests == 0);
|
||||||
|
|
||||||
UpdateParameters params;
|
UpdateParameters params;
|
||||||
params.tooltipOnly = data.iname.startsWith("tooltip");
|
params.tooltipOnly = data.iname.startsWith("tooltip");
|
||||||
params.tryPartial = flags.tryIncremental
|
params.tryPartial = flags.tryIncremental
|
||||||
&& hasPython()
|
&& hasPython()
|
||||||
&& m_pendingWatchRequests == 0
|
|
||||||
&& m_pendingBreakpointRequests == 0;
|
&& m_pendingBreakpointRequests == 0;
|
||||||
params.varList = data.iname;
|
params.varList = data.iname;
|
||||||
|
|
||||||
updateLocalsPython(params);
|
updateLocalsPython(params);
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
// Bump requests to avoid model rebuilding during the nested
|
PENDING_DEBUG("UPDATE WATCH BUMPS PENDING UP TO " << m_uncompleted.size());
|
||||||
// updateWatchModel runs.
|
updateSubItemClassic(data);
|
||||||
++m_pendingWatchRequests;
|
|
||||||
PENDING_DEBUG("UPDATE WATCH BUMPS PENDING UP TO " << m_pendingWatchRequests);
|
|
||||||
#if 1
|
|
||||||
QMetaObject::invokeMethod(this, "updateWatchDataHelper",
|
|
||||||
Qt::QueuedConnection, Q_ARG(WatchData, data));
|
|
||||||
#else
|
|
||||||
updateWatchDataHelper(data);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::updateWatchDataHelper(const WatchData &data)
|
|
||||||
{
|
|
||||||
//m_pendingRequests = 0;
|
|
||||||
PENDING_DEBUG("UPDATE WATCH DATA");
|
|
||||||
# if DEBUG_PENDING
|
|
||||||
//qDebug() << "##############################################";
|
|
||||||
qDebug() << "UPDATE MODEL, FOUND INCOMPLETE:";
|
|
||||||
//qDebug() << data.toString();
|
|
||||||
# endif
|
|
||||||
|
|
||||||
updateSubItemClassic(data);
|
|
||||||
//PENDING_DEBUG("INTERNAL TRIGGERING UPDATE WATCH MODEL");
|
|
||||||
--m_pendingWatchRequests;
|
|
||||||
PENDING_DEBUG("UPDATE WATCH DONE BUMPS PENDING DOWN TO " << m_pendingWatchRequests);
|
|
||||||
if (m_pendingWatchRequests <= 0)
|
|
||||||
rebuildWatchModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GdbEngine::rebuildWatchModel()
|
void GdbEngine::rebuildWatchModel()
|
||||||
{
|
{
|
||||||
|
QTC_CHECK(m_completed.isEmpty());
|
||||||
|
QTC_CHECK(m_uncompleted.isEmpty());
|
||||||
static int count = 0;
|
static int count = 0;
|
||||||
++count;
|
++count;
|
||||||
if (!isSynchronous())
|
if (!isSynchronous())
|
||||||
@@ -4162,7 +4115,6 @@ void GdbEngine::rebuildWatchModel()
|
|||||||
showMessage(LogWindow::logTimeStamp(), LogMiscInput);
|
showMessage(LogWindow::logTimeStamp(), LogMiscInput);
|
||||||
showMessage(_("<Rebuild Watchmodel %1>").arg(count), LogMiscInput);
|
showMessage(_("<Rebuild Watchmodel %1>").arg(count), LogMiscInput);
|
||||||
showStatusMessage(tr("Finished retrieving data"), 400);
|
showStatusMessage(tr("Finished retrieving data"), 400);
|
||||||
watchHandler()->endCycle();
|
|
||||||
showToolTip();
|
showToolTip();
|
||||||
handleAutoTests();
|
handleAutoTests();
|
||||||
}
|
}
|
||||||
@@ -4332,15 +4284,23 @@ WatchData GdbEngine::localVariable(const GdbMi &item,
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::insertData(const WatchData &data0)
|
void GdbEngine::insertData(const WatchData &data)
|
||||||
{
|
{
|
||||||
PENDING_DEBUG("INSERT DATA" << data0.toString());
|
PENDING_DEBUG("INSERT DATA" << data.toString());
|
||||||
WatchData data = data0;
|
if (data.isSomethingNeeded()) {
|
||||||
if (data.value.startsWith(QLatin1String("mi_cmd_var_create:"))) {
|
m_uncompleted.insert(data.iname);
|
||||||
qDebug() << "BOGUS VALUE:" << data.toString();
|
WatchUpdateFlags flags;
|
||||||
return;
|
flags.tryIncremental = true;
|
||||||
|
updateWatchData(data, flags);
|
||||||
|
} else {
|
||||||
|
m_completed.append(data);
|
||||||
|
m_uncompleted.remove(data.iname);
|
||||||
|
if (m_uncompleted.isEmpty()) {
|
||||||
|
watchHandler()->insertData(m_completed);
|
||||||
|
m_completed.clear();
|
||||||
|
rebuildWatchModel();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
watchHandler()->insertData(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::assignValueInDebugger(const WatchData *data,
|
void GdbEngine::assignValueInDebugger(const WatchData *data,
|
||||||
@@ -4901,12 +4861,6 @@ bool GdbEngine::startGdb(const QStringList &args, const QString &settingsIdHint)
|
|||||||
|
|
||||||
postCommand("disassemble 0 0", ConsoleCommand, CB(handleDisassemblerCheck));
|
postCommand("disassemble 0 0", ConsoleCommand, CB(handleDisassemblerCheck));
|
||||||
|
|
||||||
if (sp.breakOnMain) {
|
|
||||||
QByteArray cmd = "tbreak ";
|
|
||||||
cmd += sp.toolChainAbi.os() == Abi::WindowsOS ? "qMain" : "main";
|
|
||||||
postCommand(cmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attemptQuickStart()) {
|
if (attemptQuickStart()) {
|
||||||
postCommand("set auto-solib-add off", ConsoleCommand);
|
postCommand("set auto-solib-add off", ConsoleCommand);
|
||||||
} else {
|
} else {
|
||||||
@@ -4941,6 +4895,9 @@ void GdbEngine::loadInitScript()
|
|||||||
|
|
||||||
void GdbEngine::loadPythonDumpers()
|
void GdbEngine::loadPythonDumpers()
|
||||||
{
|
{
|
||||||
|
if (m_forceAsyncModel)
|
||||||
|
return;
|
||||||
|
|
||||||
const QByteArray dumperSourcePath =
|
const QByteArray dumperSourcePath =
|
||||||
Core::ICore::resourcePath().toLocal8Bit() + "/dumper/";
|
Core::ICore::resourcePath().toLocal8Bit() + "/dumper/";
|
||||||
|
|
||||||
@@ -5091,6 +5048,12 @@ void GdbEngine::handleInferiorPrepared()
|
|||||||
|
|
||||||
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
|
QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
|
||||||
|
|
||||||
|
if (sp.breakOnMain) {
|
||||||
|
QByteArray cmd = "tbreak ";
|
||||||
|
cmd += sp.toolChainAbi.os() == Abi::WindowsOS ? "qMain" : "main";
|
||||||
|
postCommand(cmd);
|
||||||
|
}
|
||||||
|
|
||||||
// Initial attempt to set breakpoints.
|
// Initial attempt to set breakpoints.
|
||||||
if (sp.startMode != AttachCore) {
|
if (sp.startMode != AttachCore) {
|
||||||
showStatusMessage(tr("Setting breakpoints..."));
|
showStatusMessage(tr("Setting breakpoints..."));
|
||||||
@@ -5361,6 +5324,9 @@ void GdbEngine::requestDebugInformation(const DebugInfoTask &task)
|
|||||||
|
|
||||||
bool GdbEngine::attemptQuickStart() const
|
bool GdbEngine::attemptQuickStart() const
|
||||||
{
|
{
|
||||||
|
if (m_forceAsyncModel)
|
||||||
|
return false;
|
||||||
|
|
||||||
// Don't try if the user does not ask for it.
|
// Don't try if the user does not ask for it.
|
||||||
if (!debuggerCore()->boolSetting(AttemptQuickStart))
|
if (!debuggerCore()->boolSetting(AttemptQuickStart))
|
||||||
return false;
|
return false;
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
#include "debuggerengine.h"
|
#include "debuggerengine.h"
|
||||||
|
|
||||||
#include "stackframe.h"
|
#include "stackframe.h"
|
||||||
|
#include "watchhandler.h"
|
||||||
#include "watchutils.h"
|
#include "watchutils.h"
|
||||||
|
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
@@ -80,16 +81,6 @@ enum DebuggingHelperState
|
|||||||
DebuggingHelperUnavailable
|
DebuggingHelperUnavailable
|
||||||
};
|
};
|
||||||
|
|
||||||
class UpdateParameters
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
UpdateParameters() { tryPartial = tooltipOnly = false; }
|
|
||||||
|
|
||||||
bool tryPartial;
|
|
||||||
bool tooltipOnly;
|
|
||||||
QByteArray varList;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This is only used with Mac gdb since 2.2
|
/* This is only used with Mac gdb since 2.2
|
||||||
*
|
*
|
||||||
* "Custom dumper" is a library compiled against the current
|
* "Custom dumper" is a library compiled against the current
|
||||||
@@ -322,9 +313,6 @@ private: ////////// Gdb Command Management //////////
|
|||||||
NeedsStop = 1,
|
NeedsStop = 1,
|
||||||
// No need to wait for the reply before continuing inferior.
|
// No need to wait for the reply before continuing inferior.
|
||||||
Discardable = 2,
|
Discardable = 2,
|
||||||
// Trigger watch model rebuild when no such commands are pending anymore.
|
|
||||||
RebuildWatchModel = 4,
|
|
||||||
WatchUpdate = Discardable | RebuildWatchModel,
|
|
||||||
// We can live without receiving an answer.
|
// We can live without receiving an answer.
|
||||||
NonCriticalResponse = 8,
|
NonCriticalResponse = 8,
|
||||||
// Callback expects GdbResultRunning instead of GdbResultDone.
|
// Callback expects GdbResultRunning instead of GdbResultDone.
|
||||||
@@ -407,7 +395,6 @@ private: ////////// Gdb Command Management //////////
|
|||||||
int m_oldestAcceptableToken;
|
int m_oldestAcceptableToken;
|
||||||
int m_nonDiscardableCount;
|
int m_nonDiscardableCount;
|
||||||
|
|
||||||
int m_pendingWatchRequests; // Watch updating commands in flight
|
|
||||||
int m_pendingBreakpointRequests; // Watch updating commands in flight
|
int m_pendingBreakpointRequests; // Watch updating commands in flight
|
||||||
|
|
||||||
typedef void (GdbEngine::*CommandsDoneCallback)();
|
typedef void (GdbEngine::*CommandsDoneCallback)();
|
||||||
@@ -630,13 +617,11 @@ private: ////////// View & Data Stuff //////////
|
|||||||
virtual void watchPoint(const QPoint &);
|
virtual void watchPoint(const QPoint &);
|
||||||
void handleWatchPoint(const GdbResponse &response);
|
void handleWatchPoint(const GdbResponse &response);
|
||||||
|
|
||||||
// FIXME: BaseClass. called to improve situation for a watch item
|
|
||||||
void updateSubItemClassic(const WatchData &data);
|
void updateSubItemClassic(const WatchData &data);
|
||||||
|
|
||||||
void virtual updateWatchData(const WatchData &data, const WatchUpdateFlags &flags);
|
void updateWatchData(const WatchData &data, const WatchUpdateFlags &flags);
|
||||||
Q_SLOT void updateWatchDataHelper(const WatchData &data);
|
|
||||||
void rebuildWatchModel();
|
void rebuildWatchModel();
|
||||||
bool showToolTip();
|
void showToolTip();
|
||||||
|
|
||||||
void insertData(const WatchData &data);
|
void insertData(const WatchData &data);
|
||||||
void sendWatchParameters(const QByteArray ¶ms0);
|
void sendWatchParameters(const QByteArray ¶ms0);
|
||||||
@@ -753,6 +738,11 @@ private: ////////// View & Data Stuff //////////
|
|||||||
// debug information.
|
// debug information.
|
||||||
bool attemptQuickStart() const;
|
bool attemptQuickStart() const;
|
||||||
bool m_fullStartDone;
|
bool m_fullStartDone;
|
||||||
|
|
||||||
|
// Test
|
||||||
|
bool m_forceAsyncModel;
|
||||||
|
QList<WatchData> m_completed;
|
||||||
|
QSet<QByteArray> m_uncompleted;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
@@ -54,12 +54,11 @@ namespace Internal {
|
|||||||
void GdbEngine::updateLocalsPython(const UpdateParameters ¶ms)
|
void GdbEngine::updateLocalsPython(const UpdateParameters ¶ms)
|
||||||
{
|
{
|
||||||
PRECONDITION;
|
PRECONDITION;
|
||||||
m_pendingWatchRequests = 0;
|
//m_pendingWatchRequests = 0;
|
||||||
m_pendingBreakpointRequests = 0;
|
m_pendingBreakpointRequests = 0;
|
||||||
m_processedNames.clear();
|
m_processedNames.clear();
|
||||||
WatchHandler *handler = watchHandler();
|
|
||||||
handler->beginCycle(!params.tryPartial);
|
|
||||||
|
|
||||||
|
WatchHandler *handler = watchHandler();
|
||||||
QByteArray expanded = "expanded:" + handler->expansionRequests() + ' ';
|
QByteArray expanded = "expanded:" + handler->expansionRequests() + ' ';
|
||||||
expanded += "typeformats:" + handler->typeFormatRequests() + ' ';
|
expanded += "typeformats:" + handler->typeFormatRequests() + ' ';
|
||||||
expanded += "formats:" + handler->individualFormatRequests();
|
expanded += "formats:" + handler->individualFormatRequests();
|
||||||
@@ -117,7 +116,7 @@ void GdbEngine::updateLocalsPython(const UpdateParameters ¶ms)
|
|||||||
|
|
||||||
postCommand("bb options:" + options + " vars:" + params.varList + ' '
|
postCommand("bb options:" + options + " vars:" + params.varList + ' '
|
||||||
+ resultVar + expanded + " watchers:" + watchers.toHex(),
|
+ resultVar + expanded + " watchers:" + watchers.toHex(),
|
||||||
WatchUpdate, CB(handleStackFramePython), QVariant(params.tryPartial));
|
Discardable, CB(handleStackFramePython), QVariant(params.tryPartial));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GdbEngine::handleStackFramePython(const GdbResponse &response)
|
void GdbEngine::handleStackFramePython(const GdbResponse &response)
|
||||||
@@ -136,9 +135,11 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
|
|||||||
}
|
}
|
||||||
GdbMi all;
|
GdbMi all;
|
||||||
all.fromStringMultiple(out);
|
all.fromStringMultiple(out);
|
||||||
|
|
||||||
GdbMi data = all.findChild("data");
|
GdbMi data = all.findChild("data");
|
||||||
|
|
||||||
|
WatchHandler *handler = watchHandler();
|
||||||
QList<WatchData> list;
|
QList<WatchData> list;
|
||||||
|
|
||||||
foreach (const GdbMi &child, data.children()) {
|
foreach (const GdbMi &child, data.children()) {
|
||||||
WatchData dummy;
|
WatchData dummy;
|
||||||
dummy.iname = child.findChild("iname").data();
|
dummy.iname = child.findChild("iname").data();
|
||||||
@@ -151,7 +152,7 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
|
|||||||
} else {
|
} else {
|
||||||
dummy.name = _(child.findChild("name").data());
|
dummy.name = _(child.findChild("name").data());
|
||||||
}
|
}
|
||||||
parseWatchData(watchHandler()->expandedINames(), dummy, child, &list);
|
parseWatchData(handler->expandedINames(), dummy, child, &list);
|
||||||
}
|
}
|
||||||
const GdbMi typeInfo = all.findChild("typeinfo");
|
const GdbMi typeInfo = all.findChild("typeinfo");
|
||||||
if (typeInfo.type() == GdbMi::List) {
|
if (typeInfo.type() == GdbMi::List) {
|
||||||
@@ -169,15 +170,20 @@ void GdbEngine::handleStackFramePython(const GdbResponse &response)
|
|||||||
list[i].size = ti.size;
|
list[i].size = ti.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
watchHandler()->insertBulkData(list);
|
if (!partial) {
|
||||||
|
handler->removeChildren("local");
|
||||||
|
handler->removeChildren("watch");
|
||||||
|
}
|
||||||
|
|
||||||
|
handler->insertData(list);
|
||||||
|
|
||||||
//PENDING_DEBUG("AFTER handleStackFrame()");
|
//PENDING_DEBUG("AFTER handleStackFrame()");
|
||||||
// FIXME: This should only be used when updateLocals() was
|
// FIXME: This should only be used when updateLocals() was
|
||||||
// triggered by expanding an item in the view.
|
// triggered by expanding an item in the view.
|
||||||
if (m_pendingWatchRequests <= 0) {
|
//if (m_pendingWatchRequests <= 0) {
|
||||||
//PENDING_DEBUG("\n\n .... AND TRIGGERS MODEL UPDATE\n");
|
//PENDING_DEBUG("\n\n .... AND TRIGGERS MODEL UPDATE\n");
|
||||||
rebuildWatchModel();
|
rebuildWatchModel();
|
||||||
}
|
//}
|
||||||
if (!partial)
|
if (!partial)
|
||||||
emit stackFrameCompleted();
|
emit stackFrameCompleted();
|
||||||
} else {
|
} else {
|
||||||
|
@@ -496,9 +496,7 @@ void IPCEngineHost::rpcCallback(quint64 f, QByteArray payload)
|
|||||||
WatchHandler *wh = watchHandler();
|
WatchHandler *wh = watchHandler();
|
||||||
if (!wh)
|
if (!wh)
|
||||||
break;
|
break;
|
||||||
wh->beginCycle(fullCycle);
|
wh->insertData(wd);
|
||||||
wh->insertBulkData(wd);
|
|
||||||
wh->endCycle();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IPCEngineGuest::NotifyAddBreakpointOk:
|
case IPCEngineGuest::NotifyAddBreakpointOk:
|
||||||
|
@@ -720,14 +720,12 @@ void PdbEngine::updateAll()
|
|||||||
|
|
||||||
void PdbEngine::updateLocals()
|
void PdbEngine::updateLocals()
|
||||||
{
|
{
|
||||||
WatchHandler *handler = watchHandler();
|
|
||||||
handler->beginCycle(true);
|
|
||||||
|
|
||||||
QByteArray watchers;
|
QByteArray watchers;
|
||||||
//if (!m_toolTipExpression.isEmpty())
|
//if (!m_toolTipExpression.isEmpty())
|
||||||
// watchers += m_toolTipExpression.toLatin1()
|
// watchers += m_toolTipExpression.toLatin1()
|
||||||
// + '#' + tooltipINameForExpression(m_toolTipExpression.toLatin1());
|
// + '#' + tooltipINameForExpression(m_toolTipExpression.toLatin1());
|
||||||
|
|
||||||
|
WatchHandler *handler = watchHandler();
|
||||||
QHash<QByteArray, int> watcherNames = handler->watcherNames();
|
QHash<QByteArray, int> watcherNames = handler->watcherNames();
|
||||||
QHashIterator<QByteArray, int> it(watcherNames);
|
QHashIterator<QByteArray, int> it(watcherNames);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
@@ -831,8 +829,7 @@ void PdbEngine::handleListLocals(const PdbResponse &response)
|
|||||||
//qDebug() << "CHILD: " << child.toString();
|
//qDebug() << "CHILD: " << child.toString();
|
||||||
parseWatchData(handler->expandedINames(), dummy, child, &list);
|
parseWatchData(handler->expandedINames(), dummy, child, &list);
|
||||||
}
|
}
|
||||||
handler->insertBulkData(list);
|
handler->insertData(list);
|
||||||
handler->endCycle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PdbEngine::hasCapability(unsigned cap) const
|
bool PdbEngine::hasCapability(unsigned cap) const
|
||||||
|
@@ -1000,7 +1000,6 @@ void QmlEngine::updateWatchData(const WatchData &data,
|
|||||||
const WatchUpdateFlags &)
|
const WatchUpdateFlags &)
|
||||||
{
|
{
|
||||||
// qDebug() << "UPDATE WATCH DATA" << data.toString();
|
// qDebug() << "UPDATE WATCH DATA" << data.toString();
|
||||||
//watchHandler()->rebuildModel();
|
|
||||||
//showStatusMessage(tr("Stopped."), 5000);
|
//showStatusMessage(tr("Stopped."), 5000);
|
||||||
|
|
||||||
if (data.isInspect()) {
|
if (data.isInspect()) {
|
||||||
@@ -1020,7 +1019,7 @@ void QmlEngine::updateWatchData(const WatchData &data,
|
|||||||
|
|
||||||
|
|
||||||
if (!data.isSomethingNeeded())
|
if (!data.isSomethingNeeded())
|
||||||
watchHandler()->insertData(data);
|
watchHandler()->insertIncompleteData(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlEngine::synchronizeWatchers()
|
void QmlEngine::synchronizeWatchers()
|
||||||
|
@@ -103,15 +103,11 @@ void QmlInspectorAgent::updateWatchData(const WatchData &data)
|
|||||||
if (debug)
|
if (debug)
|
||||||
qDebug() << __FUNCTION__ << "(" << data.id << ")";
|
qDebug() << __FUNCTION__ << "(" << data.id << ")";
|
||||||
|
|
||||||
if (data.id) {
|
if (data.id && !m_fetchDataIds.contains(data.id)) {
|
||||||
// objects
|
// objects
|
||||||
|
m_fetchDataIds << data.id;
|
||||||
ObjectReference ref(data.id);
|
ObjectReference ref(data.id);
|
||||||
m_fetchCurrentObjectsQueryIds << fetchContextObject(ref);
|
m_fetchCurrentObjectsQueryIds << fetchContextObject(ref);
|
||||||
WatchData d = data;
|
|
||||||
d.setAllUnneeded();
|
|
||||||
m_engine->watchHandler()->beginCycle(InspectWatch, false);
|
|
||||||
m_engine->watchHandler()->insertData(d);
|
|
||||||
m_engine->watchHandler()->endCycle(InspectWatch);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,12 +122,9 @@ void QmlInspectorAgent::selectObjectInTree(int debugId)
|
|||||||
if (m_debugIdToIname.contains(debugId)) {
|
if (m_debugIdToIname.contains(debugId)) {
|
||||||
QByteArray iname = m_debugIdToIname.value(debugId);
|
QByteArray iname = m_debugIdToIname.value(debugId);
|
||||||
QTC_ASSERT(iname.startsWith("inspect."), qDebug() << iname);
|
QTC_ASSERT(iname.startsWith("inspect."), qDebug() << iname);
|
||||||
QModelIndex itemIndex = m_engine->watchHandler()->itemIndex(iname);
|
|
||||||
QTC_ASSERT(itemIndex.isValid(),
|
|
||||||
qDebug() << "No for " << debugId << ", iname " << iname; return;);
|
|
||||||
if (debug)
|
if (debug)
|
||||||
qDebug() << " selecting" << iname << "in tree";
|
qDebug() << " selecting" << iname << "in tree";
|
||||||
m_engine->watchHandler()->setCurrentModelIndex(InspectWatch, itemIndex);
|
m_engine->watchHandler()->setCurrentItem(iname);
|
||||||
m_objectToSelect = 0;
|
m_objectToSelect = 0;
|
||||||
} else {
|
} else {
|
||||||
// we've to fetch it
|
// we've to fetch it
|
||||||
@@ -370,9 +363,8 @@ void QmlInspectorAgent::updateStatus()
|
|||||||
&& debuggerCore()->boolSetting(ShowQmlObjectTree)) {
|
&& debuggerCore()->boolSetting(ShowQmlObjectTree)) {
|
||||||
reloadEngines();
|
reloadEngines();
|
||||||
} else {
|
} else {
|
||||||
// clear view
|
// Clear view.
|
||||||
m_engine->watchHandler()->beginCycle(InspectWatch, true);
|
m_engine->watchHandler()->removeChildren("inspect");
|
||||||
m_engine->watchHandler()->endCycle(InspectWatch);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -588,10 +580,7 @@ void QmlInspectorAgent::objectTreeFetched(const ObjectReference &object)
|
|||||||
<< "entries into watch handler ...";
|
<< "entries into watch handler ...";
|
||||||
}
|
}
|
||||||
|
|
||||||
WatchHandler *watchHandler = m_engine->watchHandler();
|
m_engine->watchHandler()->insertData(watchData);
|
||||||
watchHandler->beginCycle(InspectWatch, true);
|
|
||||||
watchHandler->insertBulkData(watchData);
|
|
||||||
watchHandler->endCycle(InspectWatch);
|
|
||||||
|
|
||||||
if (debug)
|
if (debug)
|
||||||
qDebug() << "inserting entries took" << t.elapsed() << "ms";
|
qDebug() << "inserting entries took" << t.elapsed() << "ms";
|
||||||
@@ -615,15 +604,16 @@ void QmlInspectorAgent::onCurrentObjectsFetched(const ObjectReference &obj)
|
|||||||
|
|
||||||
ObjectReference last = m_fetchCurrentObjects.last();
|
ObjectReference last = m_fetchCurrentObjects.last();
|
||||||
m_fetchCurrentObjects.clear();
|
m_fetchCurrentObjects.clear();
|
||||||
|
m_fetchDataIds.clear();
|
||||||
|
|
||||||
if (m_objectToSelect == last.debugId()) {
|
if (m_objectToSelect == last.debugId()) {
|
||||||
// select item in view
|
// select item in view
|
||||||
QByteArray iname = m_debugIdToIname.value(last.debugId());
|
QByteArray iname = m_debugIdToIname.value(last.debugId());
|
||||||
QModelIndex itemIndex = m_engine->watchHandler()->itemIndex(iname);
|
WatchHandler *handler = m_engine->watchHandler();
|
||||||
QTC_ASSERT(itemIndex.isValid(), return);
|
QTC_ASSERT(handler->hasItem(iname), return);
|
||||||
if (debug)
|
if (debug)
|
||||||
qDebug() << " selecting" << iname << "in tree";
|
qDebug() << " selecting" << iname << "in tree";
|
||||||
m_engine->watchHandler()->setCurrentModelIndex(InspectWatch, itemIndex);
|
handler->setCurrentItem(iname);
|
||||||
m_objectToSelect = -1;
|
m_objectToSelect = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -780,12 +770,11 @@ void QmlInspectorAgent::addObjectToTree(const ObjectReference &obj,
|
|||||||
// find parent
|
// find parent
|
||||||
QTC_ASSERT(m_debugIdToIname.contains(parentId), break);
|
QTC_ASSERT(m_debugIdToIname.contains(parentId), break);
|
||||||
QByteArray iname = m_debugIdToIname.value(parentId);
|
QByteArray iname = m_debugIdToIname.value(parentId);
|
||||||
const WatchData *parent = m_engine->watchHandler()->findItem(iname);
|
WatchHandler *handler = m_engine->watchHandler();
|
||||||
|
const WatchData *parent = handler->findData(iname);
|
||||||
if (parent) {
|
if (parent) {
|
||||||
QList<WatchData> watches = buildWatchData(obj, *parent);
|
QList<WatchData> watches = buildWatchData(obj, *parent);
|
||||||
m_engine->watchHandler()->beginCycle(false);
|
handler->insertData(watches);
|
||||||
m_engine->watchHandler()->insertBulkData(watches);
|
|
||||||
m_engine->watchHandler()->endCycle();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -153,6 +153,7 @@ private:
|
|||||||
DebugIdHash m_debugIdHash;
|
DebugIdHash m_debugIdHash;
|
||||||
|
|
||||||
QList<int> m_objectWatches;
|
QList<int> m_objectWatches;
|
||||||
|
QList<int> m_fetchDataIds;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Internal
|
} // Internal
|
||||||
|
@@ -272,7 +272,7 @@ void QmlV8DebuggerClientPrivate::evaluate(const QString expr, bool global,
|
|||||||
QScriptValue ctxtList = parser.call(QScriptValue(), QScriptValueList() << _(ARRAY ));
|
QScriptValue ctxtList = parser.call(QScriptValue(), QScriptValueList() << _(ARRAY ));
|
||||||
while (rowCount) {
|
while (rowCount) {
|
||||||
QModelIndex index = localsModel->index(--rowCount, 0);
|
QModelIndex index = localsModel->index(--rowCount, 0);
|
||||||
const WatchData *data = engine->watchHandler()->watchData(LocalsWatch, index);
|
const WatchData *data = engine->watchHandler()->watchData(index);
|
||||||
QScriptValue ctxt = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
|
QScriptValue ctxt = parser.call(QScriptValue(), QScriptValueList() << QScriptValue(_(OBJECT)));
|
||||||
ctxt.setProperty(_(NAME), QScriptValue(data->name));
|
ctxt.setProperty(_(NAME), QScriptValue(data->name));
|
||||||
ctxt.setProperty(_(HANDLE), QScriptValue(int(data->id)));
|
ctxt.setProperty(_(HANDLE), QScriptValue(int(data->id)));
|
||||||
@@ -1173,7 +1173,7 @@ void QmlV8DebuggerClient::expandObject(const QByteArray &iname, quint64 objectId
|
|||||||
{
|
{
|
||||||
if (objectId == 0) {
|
if (objectId == 0) {
|
||||||
//We may have got the global object
|
//We may have got the global object
|
||||||
const WatchData *watch = d->engine->watchHandler()->findItem(iname);
|
const WatchData *watch = d->engine->watchHandler()->findData(iname);
|
||||||
if (watch->value == QLatin1String("global")) {
|
if (watch->value == QLatin1String("global")) {
|
||||||
StackHandler *stackHandler = d->engine->stackHandler();
|
StackHandler *stackHandler = d->engine->stackHandler();
|
||||||
if (stackHandler->isContentsValid() && stackHandler->currentFrame().isUsable()) {
|
if (stackHandler->isContentsValid() && stackHandler->currentFrame().isUsable()) {
|
||||||
@@ -1706,9 +1706,7 @@ void QmlV8DebuggerClient::setCurrentFrameDetails(const QVariant &bodyVal, const
|
|||||||
data.setHasChildren(true);
|
data.setHasChildren(true);
|
||||||
data.id = 0;
|
data.id = 0;
|
||||||
}
|
}
|
||||||
d->engine->watchHandler()->beginCycle();
|
|
||||||
d->engine->watchHandler()->insertData(data);
|
d->engine->watchHandler()->insertData(data);
|
||||||
d->engine->watchHandler()->endCycle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const QVariantList currentFrameScopes = currentFrame.value(_("scopes")).toList();
|
const QVariantList currentFrameScopes = currentFrame.value(_("scopes")).toList();
|
||||||
@@ -1785,11 +1783,8 @@ void QmlV8DebuggerClient::updateScope(const QVariant &bodyVal, const QVariant &r
|
|||||||
if (!handlesToLookup.isEmpty())
|
if (!handlesToLookup.isEmpty())
|
||||||
d->lookup(handlesToLookup);
|
d->lookup(handlesToLookup);
|
||||||
|
|
||||||
if (!locals.isEmpty()) {
|
if (!locals.isEmpty())
|
||||||
d->engine->watchHandler()->beginCycle(false);
|
d->engine->watchHandler()->insertData(locals);
|
||||||
d->engine->watchHandler()->insertBulkData(locals);
|
|
||||||
d->engine->watchHandler()->endCycle();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QmlV8DebuggerClient::updateEvaluationResult(int sequence, bool success, const QVariant &bodyVal,
|
void QmlV8DebuggerClient::updateEvaluationResult(int sequence, bool success, const QVariant &bodyVal,
|
||||||
@@ -1810,7 +1805,7 @@ void QmlV8DebuggerClient::updateEvaluationResult(int sequence, bool success, con
|
|||||||
d->scope(index);
|
d->scope(index);
|
||||||
//Also update "this"
|
//Also update "this"
|
||||||
QByteArray iname("local.this");
|
QByteArray iname("local.this");
|
||||||
const WatchData *parent = d->engine->watchHandler()->findItem(iname);
|
const WatchData *parent = d->engine->watchHandler()->findData(iname);
|
||||||
d->localsAndWatchers.insertMulti(parent->id, iname);
|
d->localsAndWatchers.insertMulti(parent->id, iname);
|
||||||
d->lookup(QList<int>() << parent->id);
|
d->lookup(QList<int>() << parent->id);
|
||||||
|
|
||||||
@@ -1833,7 +1828,7 @@ void QmlV8DebuggerClient::updateEvaluationResult(int sequence, bool success, con
|
|||||||
WatchData data;
|
WatchData data;
|
||||||
//Do we have request to evaluate a local?
|
//Do we have request to evaluate a local?
|
||||||
if (exp.startsWith("local.")) {
|
if (exp.startsWith("local.")) {
|
||||||
const WatchData *watch = d->engine->watchHandler()->findItem(exp.toLatin1());
|
const WatchData *watch = d->engine->watchHandler()->findData(exp.toLatin1());
|
||||||
watchDataList << createWatchDataList(watch, body.properties, refsVal);
|
watchDataList << createWatchDataList(watch, body.properties, refsVal);
|
||||||
} else {
|
} else {
|
||||||
QByteArray iname = d->engine->watchHandler()->watcherName(exp.toLatin1());
|
QByteArray iname = d->engine->watchHandler()->watcherName(exp.toLatin1());
|
||||||
@@ -1854,9 +1849,7 @@ void QmlV8DebuggerClient::updateEvaluationResult(int sequence, bool success, con
|
|||||||
watchDataList << data << createWatchDataList(&data, body.properties, refsVal);
|
watchDataList << data << createWatchDataList(&data, body.properties, refsVal);
|
||||||
}
|
}
|
||||||
//Insert the newly evaluated expression to the Watchers Window
|
//Insert the newly evaluated expression to the Watchers Window
|
||||||
d->engine->watchHandler()->beginCycle(false);
|
d->engine->watchHandler()->insertData(watchDataList);
|
||||||
d->engine->watchHandler()->insertBulkData(watchDataList);
|
|
||||||
d->engine->watchHandler()->endCycle();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1933,7 +1926,7 @@ void QmlV8DebuggerClient::expandLocalsAndWatchers(const QVariant &bodyVal, const
|
|||||||
if (prepend.startsWith("local.") || prepend.startsWith("watch.")) {
|
if (prepend.startsWith("local.") || prepend.startsWith("watch.")) {
|
||||||
//Data for expanded local/watch
|
//Data for expanded local/watch
|
||||||
//Could be an object or function
|
//Could be an object or function
|
||||||
const WatchData *parent = d->engine->watchHandler()->findItem(prepend);
|
const WatchData *parent = d->engine->watchHandler()->findData(prepend);
|
||||||
watchDataList << createWatchDataList(parent, bodyObjectData.properties, refsVal);
|
watchDataList << createWatchDataList(parent, bodyObjectData.properties, refsVal);
|
||||||
} else {
|
} else {
|
||||||
//rest
|
//rest
|
||||||
@@ -1952,9 +1945,7 @@ void QmlV8DebuggerClient::expandLocalsAndWatchers(const QVariant &bodyVal, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
d->engine->watchHandler()->beginCycle(false);
|
d->engine->watchHandler()->insertData(watchDataList);
|
||||||
d->engine->watchHandler()->insertBulkData(watchDataList);
|
|
||||||
d->engine->watchHandler()->endCycle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<WatchData> QmlV8DebuggerClient::createWatchDataList(const WatchData *parent,
|
QList<WatchData> QmlV8DebuggerClient::createWatchDataList(const WatchData *parent,
|
||||||
|
@@ -403,6 +403,8 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
|
|||||||
QByteArray command;
|
QByteArray command;
|
||||||
stream >> command;
|
stream >> command;
|
||||||
|
|
||||||
|
WatchHandler *watchHandler = d->engine->watchHandler();
|
||||||
|
|
||||||
if (command == "STOPPED") {
|
if (command == "STOPPED") {
|
||||||
d->engine->inferiorSpontaneousStop();
|
d->engine->inferiorSpontaneousStop();
|
||||||
|
|
||||||
@@ -432,15 +434,13 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
|
|||||||
|
|
||||||
d->engine->stackHandler()->setFrames(ideStackFrames);
|
d->engine->stackHandler()->setFrames(ideStackFrames);
|
||||||
|
|
||||||
d->engine->watchHandler()->beginCycle();
|
|
||||||
bool needPing = false;
|
bool needPing = false;
|
||||||
|
|
||||||
foreach (WatchData data, watches) {
|
foreach (WatchData data, watches) {
|
||||||
data.iname = d->engine->watchHandler()->watcherName(data.exp);
|
data.iname = watchHandler->watcherName(data.exp);
|
||||||
d->engine->watchHandler()->insertData(data);
|
watchHandler->insertIncompleteData(data);
|
||||||
|
|
||||||
if (d->engine->watchHandler()->expandedINames().contains(data.iname) &&
|
if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) {
|
||||||
qint64(data.id) != -1) {
|
|
||||||
needPing = true;
|
needPing = true;
|
||||||
expandObject(data.iname,data.id);
|
expandObject(data.iname,data.id);
|
||||||
}
|
}
|
||||||
@@ -448,20 +448,16 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
|
|||||||
|
|
||||||
foreach (WatchData data, locals) {
|
foreach (WatchData data, locals) {
|
||||||
data.iname = "local." + data.exp;
|
data.iname = "local." + data.exp;
|
||||||
d->engine->watchHandler()->insertData(data);
|
watchHandler->insertIncompleteData(data);
|
||||||
|
|
||||||
if (d->engine->watchHandler()->expandedINames().contains(data.iname) &&
|
if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) {
|
||||||
qint64(data.id) != -1) {
|
|
||||||
needPing = true;
|
needPing = true;
|
||||||
expandObject(data.iname,data.id);
|
expandObject(data.iname,data.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needPing) {
|
if (needPing)
|
||||||
sendPing();
|
sendPing();
|
||||||
} else {
|
|
||||||
d->engine->watchHandler()->endCycle();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool becauseOfException;
|
bool becauseOfException;
|
||||||
stream >> becauseOfException;
|
stream >> becauseOfException;
|
||||||
@@ -518,12 +514,12 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
|
|||||||
+ QLatin1String(iname) + QLatin1Char(' ') + data.value);
|
+ QLatin1String(iname) + QLatin1Char(' ') + data.value);
|
||||||
data.iname = iname;
|
data.iname = iname;
|
||||||
if (iname.startsWith("watch.")) {
|
if (iname.startsWith("watch.")) {
|
||||||
d->engine->watchHandler()->insertData(data);
|
watchHandler->insertIncompleteData(data);
|
||||||
} else if (iname == "console") {
|
} else if (iname == "console") {
|
||||||
d->engine->showMessage(data.value, QtMessageLogOutput);
|
d->engine->showMessage(data.value, QtMessageLogOutput);
|
||||||
} else if (iname.startsWith("local.")) {
|
} else if (iname.startsWith("local.")) {
|
||||||
data.name = data.name.left(data.name.indexOf(QLatin1Char(' ')));
|
data.name = data.name.left(data.name.indexOf(QLatin1Char(' ')));
|
||||||
d->engine->watchHandler()->insertData(data);
|
watchHandler->insertIncompleteData(data);
|
||||||
} else {
|
} else {
|
||||||
qWarning() << "QmlEngine: Unexcpected result: " << iname << data.value;
|
qWarning() << "QmlEngine: Unexcpected result: " << iname << data.value;
|
||||||
}
|
}
|
||||||
@@ -538,10 +534,9 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
|
|||||||
|
|
||||||
foreach (WatchData data, result) {
|
foreach (WatchData data, result) {
|
||||||
data.iname = iname + '.' + data.exp;
|
data.iname = iname + '.' + data.exp;
|
||||||
d->engine->watchHandler()->insertData(data);
|
watchHandler->insertIncompleteData(data);
|
||||||
|
|
||||||
if (d->engine->watchHandler()->expandedINames().contains(data.iname) &&
|
if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) {
|
||||||
qint64(data.id) != -1) {
|
|
||||||
needPing = true;
|
needPing = true;
|
||||||
expandObject(data.iname, data.id);
|
expandObject(data.iname, data.id);
|
||||||
}
|
}
|
||||||
@@ -560,14 +555,12 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
|
|||||||
d->logReceiveMessage(QString::fromLatin1("%1 %2 (%3 x locals) (%4 x watchdata)").arg(
|
d->logReceiveMessage(QString::fromLatin1("%1 %2 (%3 x locals) (%4 x watchdata)").arg(
|
||||||
QLatin1String(command), QString::number(frameId),
|
QLatin1String(command), QString::number(frameId),
|
||||||
QString::number(locals.size()), QString::number(watches.size())));
|
QString::number(locals.size()), QString::number(watches.size())));
|
||||||
d->engine->watchHandler()->beginCycle();
|
|
||||||
bool needPing = false;
|
bool needPing = false;
|
||||||
foreach (WatchData data, watches) {
|
foreach (WatchData data, watches) {
|
||||||
data.iname = d->engine->watchHandler()->watcherName(data.exp);
|
data.iname = watchHandler->watcherName(data.exp);
|
||||||
d->engine->watchHandler()->insertData(data);
|
watchHandler->insertIncompleteData(data);
|
||||||
|
|
||||||
if (d->engine->watchHandler()->expandedINames().contains(data.iname) &&
|
if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) {
|
||||||
qint64(data.id) != -1) {
|
|
||||||
needPing = true;
|
needPing = true;
|
||||||
expandObject(data.iname, data.id);
|
expandObject(data.iname, data.id);
|
||||||
}
|
}
|
||||||
@@ -575,26 +568,19 @@ void QScriptDebuggerClient::messageReceived(const QByteArray &data)
|
|||||||
|
|
||||||
foreach (WatchData data, locals) {
|
foreach (WatchData data, locals) {
|
||||||
data.iname = "local." + data.exp;
|
data.iname = "local." + data.exp;
|
||||||
d->engine->watchHandler()->insertData(data);
|
watchHandler->insertIncompleteData(data);
|
||||||
if (d->engine->watchHandler()->expandedINames().contains(data.iname) &&
|
if (watchHandler->isExpandedIName(data.iname) && qint64(data.id) != -1) {
|
||||||
qint64(data.id) != -1) {
|
|
||||||
needPing = true;
|
needPing = true;
|
||||||
expandObject(data.iname, data.id);
|
expandObject(data.iname, data.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (needPing)
|
if (needPing)
|
||||||
sendPing();
|
sendPing();
|
||||||
else
|
|
||||||
d->engine->watchHandler()->endCycle();
|
|
||||||
|
|
||||||
} else if (command == "PONG") {
|
} else if (command == "PONG") {
|
||||||
int ping;
|
int ping;
|
||||||
stream >> ping;
|
stream >> ping;
|
||||||
|
|
||||||
d->logReceiveMessage(QLatin1String(command) + QLatin1Char(' ') + QString::number(ping));
|
d->logReceiveMessage(QLatin1String(command) + QLatin1Char(' ') + QString::number(ping));
|
||||||
|
|
||||||
if (ping == d->ping)
|
|
||||||
d->engine->watchHandler()->endCycle();
|
|
||||||
} else {
|
} else {
|
||||||
qDebug() << Q_FUNC_INFO << "Unknown command: " << command;
|
qDebug() << Q_FUNC_INFO << "Unknown command: " << command;
|
||||||
d->logReceiveMessage(QLatin1String(command) + QLatin1String(" UNKNOWN COMMAND!!"));
|
d->logReceiveMessage(QLatin1String(command) + QLatin1String(" UNKNOWN COMMAND!!"));
|
||||||
|
@@ -651,7 +651,6 @@ bool ScriptEngine::checkForBreakCondition(bool byFunction)
|
|||||||
void ScriptEngine::updateLocals()
|
void ScriptEngine::updateLocals()
|
||||||
{
|
{
|
||||||
QScriptContext *context = m_scriptEngine->currentContext();
|
QScriptContext *context = m_scriptEngine->currentContext();
|
||||||
watchHandler()->beginCycle();
|
|
||||||
SDEBUG(Q_FUNC_INFO);
|
SDEBUG(Q_FUNC_INFO);
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -686,9 +685,7 @@ void ScriptEngine::updateLocals()
|
|||||||
data.iname = "local";
|
data.iname = "local";
|
||||||
data.name = _(data.iname);
|
data.name = _(data.iname);
|
||||||
|
|
||||||
watchHandler()->beginCycle();
|
|
||||||
updateSubItem(data);
|
updateSubItem(data);
|
||||||
watchHandler()->endCycle();
|
|
||||||
// FIXME: Use an extra thread. This here is evil.
|
// FIXME: Use an extra thread. This here is evil.
|
||||||
m_stopped = true;
|
m_stopped = true;
|
||||||
showStatusMessage(tr("Stopped."), 5000);
|
showStatusMessage(tr("Stopped."), 5000);
|
||||||
@@ -809,9 +806,9 @@ void ScriptEngine::updateSubItem(const WatchData &data0)
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDEBUG(msgDebugInsert(data, children));
|
SDEBUG(msgDebugInsert(data, children));
|
||||||
watchHandler()->insertData(data);
|
watchHandler()->insertIncompleteData(data);
|
||||||
if (!children.isEmpty())
|
if (!children.isEmpty())
|
||||||
watchHandler()->insertBulkData(children);
|
watchHandler()->insertData(children);
|
||||||
}
|
}
|
||||||
|
|
||||||
DebuggerEngine *createScriptEngine(const DebuggerStartParameters &sp)
|
DebuggerEngine *createScriptEngine(const DebuggerStartParameters &sp)
|
||||||
|
@@ -143,7 +143,6 @@ WatchData::WatchData() :
|
|||||||
size(0),
|
size(0),
|
||||||
bitpos(0),
|
bitpos(0),
|
||||||
bitsize(0),
|
bitsize(0),
|
||||||
generation(-1),
|
|
||||||
hasChildren(false),
|
hasChildren(false),
|
||||||
valueEnabled(true),
|
valueEnabled(true),
|
||||||
valueEditable(true),
|
valueEditable(true),
|
||||||
@@ -399,8 +398,6 @@ QString WatchData::toToolTip() const
|
|||||||
if (size)
|
if (size)
|
||||||
formatToolTipRow(str, tr("Static Object Size"), tr("%1 bytes").arg(size));
|
formatToolTipRow(str, tr("Static Object Size"), tr("%1 bytes").arg(size));
|
||||||
formatToolTipRow(str, tr("Internal ID"), QLatin1String(iname));
|
formatToolTipRow(str, tr("Internal ID"), QLatin1String(iname));
|
||||||
formatToolTipRow(str, tr("Generation"),
|
|
||||||
QString::number(generation));
|
|
||||||
str << "</table></body></html>";
|
str << "</table></body></html>";
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@@ -135,7 +135,6 @@ public:
|
|||||||
uint size; // Size
|
uint size; // Size
|
||||||
uint bitpos; // Position within bit fields
|
uint bitpos; // Position within bit fields
|
||||||
uint bitsize; // Size in case of bit fields
|
uint bitsize; // Size in case of bit fields
|
||||||
qint32 generation; // When updated?
|
|
||||||
bool hasChildren;
|
bool hasChildren;
|
||||||
bool valueEnabled; // Value will be enabled or not
|
bool valueEnabled; // Value will be enabled or not
|
||||||
bool valueEditable; // Value will be editable
|
bool valueEditable; // Value will be editable
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -35,28 +35,38 @@
|
|||||||
|
|
||||||
#include "watchdata.h"
|
#include "watchdata.h"
|
||||||
|
|
||||||
#include <QPointer>
|
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QSet>
|
#include <QSet>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QAbstractItemModel>
|
#include <QAbstractItemModel>
|
||||||
|
|
||||||
namespace Debugger {
|
namespace Debugger {
|
||||||
|
|
||||||
class DebuggerEngine;
|
class DebuggerEngine;
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
class WatchItem;
|
class WatchModel;
|
||||||
class WatchHandler;
|
|
||||||
|
class UpdateParameters
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UpdateParameters() { tryPartial = tooltipOnly = false; }
|
||||||
|
|
||||||
|
bool tryPartial;
|
||||||
|
bool tooltipOnly;
|
||||||
|
QByteArray varList;
|
||||||
|
};
|
||||||
|
|
||||||
typedef QHash<QString, QStringList> TypeFormats;
|
typedef QHash<QString, QStringList> TypeFormats;
|
||||||
|
|
||||||
enum WatchType
|
enum WatchType
|
||||||
{
|
{
|
||||||
ReturnWatch,
|
LocalsType,
|
||||||
LocalsWatch,
|
InspectType,
|
||||||
WatchersWatch,
|
WatchersType,
|
||||||
TooltipsWatch,
|
ReturnType,
|
||||||
InspectWatch
|
TooltipType
|
||||||
};
|
};
|
||||||
|
|
||||||
enum IntegerFormat
|
enum IntegerFormat
|
||||||
@@ -67,126 +77,38 @@ enum IntegerFormat
|
|||||||
OctalFormat
|
OctalFormat
|
||||||
};
|
};
|
||||||
|
|
||||||
class WatchModel : public QAbstractItemModel
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit WatchModel(WatchHandler *handler, WatchType type);
|
|
||||||
virtual ~WatchModel();
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual int rowCount(const QModelIndex &idx = QModelIndex()) const;
|
|
||||||
virtual int columnCount(const QModelIndex &idx) const;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void setCurrentIndex(const QModelIndex &index);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QVariant data(const QModelIndex &index, int role) const;
|
|
||||||
bool setData(const QModelIndex &index, const QVariant &value, int role);
|
|
||||||
QModelIndex index(int, int, const QModelIndex &idx) const;
|
|
||||||
QModelIndex parent(const QModelIndex &idx) const;
|
|
||||||
bool hasChildren(const QModelIndex &idx) const;
|
|
||||||
Qt::ItemFlags flags(const QModelIndex &idx) const;
|
|
||||||
QVariant headerData(int section, Qt::Orientation orientation,
|
|
||||||
int role = Qt::DisplayRole) const;
|
|
||||||
bool canFetchMore(const QModelIndex &parent) const;
|
|
||||||
void fetchMore(const QModelIndex &parent);
|
|
||||||
|
|
||||||
void invalidateAll(const QModelIndex &parentIndex = QModelIndex());
|
|
||||||
|
|
||||||
friend class WatchHandler;
|
|
||||||
|
|
||||||
WatchItem *watchItem(const QModelIndex &) const;
|
|
||||||
QModelIndex watchIndex(const WatchItem *needle) const;
|
|
||||||
QModelIndex watchIndexHelper(const WatchItem *needle,
|
|
||||||
const WatchItem *parentItem, const QModelIndex &parentIndex) const;
|
|
||||||
|
|
||||||
void insertData(const WatchData &data);
|
|
||||||
void reinsertAllData();
|
|
||||||
void reinsertAllDataHelper(WatchItem *item, QList<WatchData> *data);
|
|
||||||
void insertBulkData(const QList<WatchData> &data);
|
|
||||||
WatchItem *findItem(const QByteArray &iname, WatchItem *root) const;
|
|
||||||
QString displayForAutoTest(const QByteArray &iname) const;
|
|
||||||
void reinitialize();
|
|
||||||
void removeOutdated();
|
|
||||||
void removeOutdatedHelper(WatchItem *item);
|
|
||||||
WatchItem *rootItem() const;
|
|
||||||
void destroyItem(WatchItem *item);
|
|
||||||
|
|
||||||
void emitDataChanged(int column,
|
|
||||||
const QModelIndex &parentIndex = QModelIndex());
|
|
||||||
void beginCycle(bool fullCycle); // Called at begin of updateLocals() cycle.
|
|
||||||
void endCycle(); // Called after all results have been received.
|
|
||||||
|
|
||||||
friend QDebug operator<<(QDebug d, const WatchModel &m);
|
|
||||||
|
|
||||||
void dump();
|
|
||||||
void dumpHelper(WatchItem *item);
|
|
||||||
void emitAllChanged();
|
|
||||||
|
|
||||||
private:
|
|
||||||
QString displayType(const WatchData &typeIn) const;
|
|
||||||
QString formattedValue(const WatchData &data) const;
|
|
||||||
QString removeInitialNamespace(QString str) const;
|
|
||||||
QString removeNamespaces(QString str) const;
|
|
||||||
void formatRequests(QByteArray *out, const WatchItem *item) const;
|
|
||||||
DebuggerEngine *engine() const;
|
|
||||||
QString display(const WatchItem *item, int col) const;
|
|
||||||
int itemFormat(const WatchData &data) const;
|
|
||||||
bool contentIsValid() const;
|
|
||||||
int m_generationCounter;
|
|
||||||
|
|
||||||
WatchHandler *m_handler;
|
|
||||||
WatchType m_type;
|
|
||||||
WatchItem *m_root;
|
|
||||||
QSet<QByteArray> m_fetchTriggered;
|
|
||||||
};
|
|
||||||
|
|
||||||
class WatchHandler : public QObject
|
class WatchHandler : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit WatchHandler(DebuggerEngine *engine);
|
explicit WatchHandler(DebuggerEngine *engine);
|
||||||
WatchModel *model(WatchType type) const;
|
~WatchHandler();
|
||||||
WatchModel *modelForIName(const QByteArray &iname) const;
|
|
||||||
|
QAbstractItemModel *model() const;
|
||||||
|
|
||||||
void cleanup();
|
void cleanup();
|
||||||
void watchExpression(const QString &exp);
|
void watchExpression(const QString &exp);
|
||||||
void removeWatchExpression(const QString &exp);
|
void removeWatchExpression(const QString &exp);
|
||||||
Q_SLOT void clearWatches();
|
Q_SLOT void clearWatches();
|
||||||
Q_SLOT void emitAllChanged();
|
|
||||||
|
|
||||||
void beginCycle(bool fullCycle = true); // Called at begin of updateLocals() cycle
|
|
||||||
void updateWatchers(); // Called after locals are fetched
|
void updateWatchers(); // Called after locals are fetched
|
||||||
void endCycle(); // Called after all results have been received
|
|
||||||
|
|
||||||
void beginCycle(WatchType type, bool fullCycle = true);
|
|
||||||
void endCycle(WatchType type);
|
|
||||||
|
|
||||||
void showEditValue(const WatchData &data);
|
void showEditValue(const WatchData &data);
|
||||||
|
|
||||||
void insertData(const WatchData &data);
|
const WatchData *watchData(const QModelIndex &) const;
|
||||||
void insertBulkData(const QList<WatchData> &data);
|
const WatchData *findData(const QByteArray &iname) const;
|
||||||
void removeData(const QByteArray &iname);
|
|
||||||
Q_SLOT void reinsertAllData();
|
|
||||||
|
|
||||||
const WatchData *watchData(WatchType type, const QModelIndex &) const;
|
|
||||||
const WatchData *findItem(const QByteArray &iname) const;
|
|
||||||
QString displayForAutoTest(const QByteArray &iname) const;
|
QString displayForAutoTest(const QByteArray &iname) const;
|
||||||
QModelIndex itemIndex(const QByteArray &iname) const;
|
bool hasItem(const QByteArray &iname) const;
|
||||||
|
|
||||||
void loadSessionData();
|
void loadSessionData();
|
||||||
void saveSessionData();
|
void saveSessionData();
|
||||||
void removeTooltip();
|
void removeTooltip();
|
||||||
void rebuildModel();
|
void rebuildModel();
|
||||||
|
|
||||||
bool isExpandedIName(const QByteArray &iname) const
|
bool isExpandedIName(const QByteArray &iname) const;
|
||||||
{ return m_expandedINames.contains(iname); }
|
QSet<QByteArray> expandedINames() const;
|
||||||
QSet<QByteArray> expandedINames() const
|
|
||||||
{ return m_expandedINames; }
|
|
||||||
static QStringList watchedExpressions();
|
static QStringList watchedExpressions();
|
||||||
static QHash<QByteArray, int> watcherNames();
|
static QHash<QByteArray, int> watcherNames();
|
||||||
|
|
||||||
@@ -199,7 +121,6 @@ public:
|
|||||||
void addTypeFormats(const QByteArray &type, const QStringList &formats);
|
void addTypeFormats(const QByteArray &type, const QStringList &formats);
|
||||||
void setTypeFormats(const TypeFormats &typeFormats);
|
void setTypeFormats(const TypeFormats &typeFormats);
|
||||||
TypeFormats typeFormats() const;
|
TypeFormats typeFormats() const;
|
||||||
QStringList typeFormatList(const WatchData &data) const;
|
|
||||||
|
|
||||||
void setUnprintableBase(int base);
|
void setUnprintableBase(int base);
|
||||||
static int unprintableBase();
|
static int unprintableBase();
|
||||||
@@ -213,7 +134,15 @@ public:
|
|||||||
void resetLocation();
|
void resetLocation();
|
||||||
bool isValidToolTip(const QByteArray &iname) const;
|
bool isValidToolTip(const QByteArray &iname) const;
|
||||||
|
|
||||||
void setCurrentModelIndex(WatchType modelType, const QModelIndex &index);
|
void setCurrentItem(const QByteArray &iname);
|
||||||
|
void updateWatchersWindow();
|
||||||
|
|
||||||
|
void insertData(const WatchData &data); // Convenience.
|
||||||
|
void insertData(const QList<WatchData> &list);
|
||||||
|
void insertIncompleteData(const WatchData &data);
|
||||||
|
void removeData(const QByteArray &iname);
|
||||||
|
void removeChildren(const QByteArray &iname);
|
||||||
|
void removeAllData();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class WatchModel;
|
friend class WatchModel;
|
||||||
@@ -223,25 +152,8 @@ private:
|
|||||||
static void saveTypeFormats();
|
static void saveTypeFormats();
|
||||||
|
|
||||||
void setFormat(const QByteArray &type, int format);
|
void setFormat(const QByteArray &type, int format);
|
||||||
void updateWatchersWindow();
|
|
||||||
void showInEditorHelper(QString *contents, WatchItem *item, int level);
|
|
||||||
|
|
||||||
bool m_inChange;
|
WatchModel *m_model;
|
||||||
|
|
||||||
// QWidgets and QProcesses taking care of special displays.
|
|
||||||
typedef QMap<QByteArray, QPointer<QObject> > EditHandlers;
|
|
||||||
EditHandlers m_editHandlers;
|
|
||||||
|
|
||||||
TypeFormats m_reportedTypeFormats;
|
|
||||||
|
|
||||||
// Items expanded in the Locals & Watchers view.
|
|
||||||
QSet<QByteArray> m_expandedINames;
|
|
||||||
|
|
||||||
WatchModel *m_return;
|
|
||||||
WatchModel *m_locals;
|
|
||||||
WatchModel *m_watchers;
|
|
||||||
WatchModel *m_tooltips;
|
|
||||||
WatchModel *m_inspect;
|
|
||||||
DebuggerEngine *m_engine;
|
DebuggerEngine *m_engine;
|
||||||
|
|
||||||
int m_watcherCounter;
|
int m_watcherCounter;
|
||||||
@@ -253,4 +165,6 @@ private:
|
|||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(Debugger::Internal::UpdateParameters)
|
||||||
|
|
||||||
#endif // DEBUGGER_WATCHHANDLER_H
|
#endif // DEBUGGER_WATCHHANDLER_H
|
||||||
|
@@ -530,12 +530,12 @@ void WatchTreeView::keyPressEvent(QKeyEvent *ev)
|
|||||||
QString exp = model()->data(idx1).toString();
|
QString exp = model()->data(idx1).toString();
|
||||||
watchExpression(exp);
|
watchExpression(exp);
|
||||||
}
|
}
|
||||||
QTreeView::keyPressEvent(ev);
|
BaseTreeView::keyPressEvent(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchTreeView::dragEnterEvent(QDragEnterEvent *ev)
|
void WatchTreeView::dragEnterEvent(QDragEnterEvent *ev)
|
||||||
{
|
{
|
||||||
//QTreeView::dragEnterEvent(ev);
|
//BaseTreeView::dragEnterEvent(ev);
|
||||||
if (ev->mimeData()->hasText()) {
|
if (ev->mimeData()->hasText()) {
|
||||||
ev->setDropAction(Qt::CopyAction);
|
ev->setDropAction(Qt::CopyAction);
|
||||||
ev->accept();
|
ev->accept();
|
||||||
@@ -544,7 +544,7 @@ void WatchTreeView::dragEnterEvent(QDragEnterEvent *ev)
|
|||||||
|
|
||||||
void WatchTreeView::dragMoveEvent(QDragMoveEvent *ev)
|
void WatchTreeView::dragMoveEvent(QDragMoveEvent *ev)
|
||||||
{
|
{
|
||||||
//QTreeView::dragMoveEvent(ev);
|
//BaseTreeView::dragMoveEvent(ev);
|
||||||
if (ev->mimeData()->hasText()) {
|
if (ev->mimeData()->hasText()) {
|
||||||
ev->setDropAction(Qt::CopyAction);
|
ev->setDropAction(Qt::CopyAction);
|
||||||
ev->accept();
|
ev->accept();
|
||||||
@@ -559,7 +559,7 @@ void WatchTreeView::dropEvent(QDropEvent *ev)
|
|||||||
ev->setDropAction(Qt::CopyAction);
|
ev->setDropAction(Qt::CopyAction);
|
||||||
ev->accept();
|
ev->accept();
|
||||||
}
|
}
|
||||||
//QTreeView::dropEvent(ev);
|
//BaseTreeView::dropEvent(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchTreeView::mouseDoubleClickEvent(QMouseEvent *ev)
|
void WatchTreeView::mouseDoubleClickEvent(QMouseEvent *ev)
|
||||||
@@ -570,7 +570,7 @@ void WatchTreeView::mouseDoubleClickEvent(QMouseEvent *ev)
|
|||||||
watchExpression(QString());
|
watchExpression(QString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QTreeView::mouseDoubleClickEvent(ev);
|
BaseTreeView::mouseDoubleClickEvent(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Text for add watch action with truncated expression.
|
// Text for add watch action with truncated expression.
|
||||||
@@ -971,7 +971,7 @@ bool WatchTreeView::event(QEvent *ev)
|
|||||||
releaseMouse();
|
releaseMouse();
|
||||||
currentEngine()->watchPoint(mapToGlobal(mev->pos()));
|
currentEngine()->watchPoint(mapToGlobal(mev->pos()));
|
||||||
}
|
}
|
||||||
return QTreeView::event(ev);
|
return BaseTreeView::event(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchTreeView::editItem(const QModelIndex &idx)
|
void WatchTreeView::editItem(const QModelIndex &idx)
|
||||||
@@ -982,6 +982,7 @@ void WatchTreeView::editItem(const QModelIndex &idx)
|
|||||||
void WatchTreeView::setModel(QAbstractItemModel *model)
|
void WatchTreeView::setModel(QAbstractItemModel *model)
|
||||||
{
|
{
|
||||||
BaseTreeView::setModel(model);
|
BaseTreeView::setModel(model);
|
||||||
|
setRootIndex(model->index(m_type, 0, QModelIndex()));
|
||||||
setRootIsDecorated(true);
|
setRootIsDecorated(true);
|
||||||
if (header()) {
|
if (header()) {
|
||||||
header()->setDefaultAlignment(Qt::AlignLeft);
|
header()->setDefaultAlignment(Qt::AlignLeft);
|
||||||
@@ -990,15 +991,25 @@ void WatchTreeView::setModel(QAbstractItemModel *model)
|
|||||||
}
|
}
|
||||||
|
|
||||||
connect(model, SIGNAL(layoutChanged()), SLOT(resetHelper()));
|
connect(model, SIGNAL(layoutChanged()), SLOT(resetHelper()));
|
||||||
|
connect(model, SIGNAL(currentIndexRequested(QModelIndex)),
|
||||||
QTC_ASSERT(qobject_cast<WatchModel*>(model), return);
|
|
||||||
connect(model, SIGNAL(setCurrentIndex(QModelIndex)),
|
|
||||||
SLOT(setCurrentIndex(QModelIndex)));
|
SLOT(setCurrentIndex(QModelIndex)));
|
||||||
|
connect(model, SIGNAL(itemIsExpanded(QModelIndex)),
|
||||||
|
SLOT(handleItemIsExpanded(QModelIndex)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WatchTreeView::handleItemIsExpanded(const QModelIndex &idx)
|
||||||
|
{
|
||||||
|
bool on = idx.data(LocalsExpandedRole).toBool();
|
||||||
|
QTC_ASSERT(on, return);
|
||||||
|
if (!isExpanded(idx))
|
||||||
|
expand(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchTreeView::resetHelper()
|
void WatchTreeView::resetHelper()
|
||||||
{
|
{
|
||||||
resetHelper(model()->index(0, 0));
|
QModelIndex idx = model()->index(m_type, 0);
|
||||||
|
resetHelper(idx);
|
||||||
|
expand(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WatchTreeView::resetHelper(const QModelIndex &idx)
|
void WatchTreeView::resetHelper(const QModelIndex &idx)
|
||||||
@@ -1019,6 +1030,13 @@ void WatchTreeView::resetHelper(const QModelIndex &idx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WatchTreeView::reset()
|
||||||
|
{
|
||||||
|
BaseTreeView::reset();
|
||||||
|
setRootIndex(model()->index(m_type, 0));
|
||||||
|
resetHelper();
|
||||||
|
}
|
||||||
|
|
||||||
void WatchTreeView::watchExpression(const QString &exp)
|
void WatchTreeView::watchExpression(const QString &exp)
|
||||||
{
|
{
|
||||||
currentEngine()->watchHandler()->watchExpression(exp);
|
currentEngine()->watchHandler()->watchExpression(exp);
|
||||||
@@ -1063,7 +1081,5 @@ void WatchTreeView::setWatchpointAtExpression(const QString &exp)
|
|||||||
breakHandler()->appendBreakpoint(data);
|
breakHandler()->appendBreakpoint(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|
||||||
|
@@ -49,15 +49,17 @@ class WatchTreeView : public BaseTreeView
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum Type { ReturnType, LocalsType, TooltipType, WatchersType, InspectType };
|
enum Type { LocalsType, InspectType, WatchersType, ReturnType, TooltipType };
|
||||||
|
|
||||||
explicit WatchTreeView(Type type, QWidget *parent = 0);
|
explicit WatchTreeView(Type type, QWidget *parent = 0);
|
||||||
Type type() const { return m_type; }
|
Type type() const { return m_type; }
|
||||||
void setModel(QAbstractItemModel *model);
|
void setModel(QAbstractItemModel *model);
|
||||||
|
void reset();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void watchExpression(const QString &exp);
|
void watchExpression(const QString &exp);
|
||||||
void removeWatchExpression(const QString &exp);
|
void removeWatchExpression(const QString &exp);
|
||||||
|
void handleItemIsExpanded(const QModelIndex &idx);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Q_SLOT void resetHelper();
|
Q_SLOT void resetHelper();
|
||||||
|
Reference in New Issue
Block a user