aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/debugger/watchhandler.cpp
diff options
context:
space:
mode:
authorhjk <[email protected]>2010-06-16 11:08:54 +0200
committerhjk <[email protected]>2010-06-22 10:59:57 +0200
commit6a6cba5518fb88345c53a7cd645f6cb6466a84e3 (patch)
tree88d7875ae5bd6f70a3654b11f80c6ed9b9685369 /src/plugins/debugger/watchhandler.cpp
parent4cc244469a4c7d9fb2b3e598727c6d8a2e7c1813 (diff)
debugger: The DebuggerEngine refactoring.
This replaces the (de facto) singleton engines and data handlers by classes that are instantiated per run. The DebuggerRunControl will now create an object of (a class derived from) DebuggerEngine that contains all the relevant "dynamic" data. DebuggerManager is no more. The "singleton" bits are merged into DebuggerPlugin, whereas the data bits went to DebuggerEngine. There is no formal notion of a "current" DebuggerEngine. However, as there's only one DebuggerEngine at a time that has its data models connected to the view, there's still some "de facto" notion of a "current" engine. Calling SomeModel::setData(int role, QVariant data) with custom role is used as the primary dispatch mechanism from the views to the "current" data models (and the engine, as all data models know their engine).
Diffstat (limited to 'src/plugins/debugger/watchhandler.cpp')
-rw-r--r--src/plugins/debugger/watchhandler.cpp164
1 files changed, 119 insertions, 45 deletions
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index 3652a31199a..63a5a578353 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -28,10 +28,14 @@
**************************************************************************/
#include "watchhandler.h"
-#include "watchutils.h"
+
+#include "breakhandler.h"
+#include "breakpoint.h"
#include "debuggeractions.h"
-#include "debuggermanager.h"
-#include "idebuggerengine.h"
+#include "debuggeragents.h"
+#include "debuggerengine.h"
+#include "debuggerplugin.h"
+#include "watchutils.h"
#if USE_MODEL_TEST
#include "modeltest.h"
@@ -76,6 +80,8 @@ static const QString strNotInScope =
static int watcherCounter = 0;
static int generationCounter = 0;
+static DebuggerPlugin *plugin() { return DebuggerPlugin::instance(); }
+
////////////////////////////////////////////////////////////////////
//
// WatchItem
@@ -178,6 +184,11 @@ void WatchModel::endCycle()
m_fetchTriggered.clear();
emit enableUpdates(true);
}
+
+DebuggerEngine *WatchModel::engine() const
+{
+ return m_handler->m_engine;
+}
void WatchModel::dump()
{
@@ -375,9 +386,8 @@ QString WatchModel::niceType(const QString &typeIn) const
QString type = niceTypeHelper(typeIn);
if (!theDebuggerBoolSetting(ShowStdNamespace))
type = type.remove("std::");
- IDebuggerEngine *engine = m_handler->m_manager->currentEngine();
- if (engine && !theDebuggerBoolSetting(ShowQtNamespace))
- type = type.remove(engine->qtNamespace());
+ if (!theDebuggerBoolSetting(ShowQtNamespace))
+ type = type.remove(engine()->qtNamespace());
return type;
}
@@ -459,7 +469,7 @@ void WatchModel::fetchMore(const QModelIndex &index)
if (item->children.isEmpty()) {
WatchData data = *item;
data.setChildrenNeeded();
- m_handler->m_manager->updateWatchData(data);
+ engine()->updateWatchData(data);
}
}
@@ -583,6 +593,14 @@ static inline quint64 pointerValue(QString data)
QVariant WatchModel::data(const QModelIndex &idx, int role) const
{
+ switch (role) {
+ case EngineCapabilitiesRole:
+ return engine()->debuggerCapabilities();
+
+ case EngineActionsEnabledRole:
+ return engine()->debuggerActionsEnabled();
+ }
+
const WatchItem *item = watchItem(idx);
const WatchItem &data = *item;
@@ -623,16 +641,16 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
break;
}
- case ExpressionRole:
+ case LocalsExpressionRole:
return data.exp;
- case INameRole:
+ case LocalsINameRole:
return data.iname;
- case ExpandedRole:
+ case LocalsExpandedRole:
return m_handler->m_expandedINames.contains(data.iname);
- case TypeFormatListRole:
+ case LocalsTypeFormatListRole:
if (!data.typeFormats.isEmpty())
return data.typeFormats.split(',');
if (isIntType(data.type))
@@ -647,28 +665,33 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
<< tr("UCS4 string");
break;
- case TypeFormatRole:
+ case LocalsTypeFormatRole:
return m_handler->m_typeFormats.value(data.type, -1);
- case IndividualFormatRole:
+ case LocalsIndividualFormatRole:
return m_handler->m_individualFormats.value(data.addr, -1);
- case AddressRole:
- if (!data.addr.isEmpty()) {
- bool ok;
- const quint64 address = data.addr.toULongLong(&ok, 16);
- if (ok)
- return QVariant(address);
- }
- return QVariant(quint64(0));
-
- case RawValueRole:
+ case LocalsRawValueRole:
return data.value;
- case PointerValue:
+ case LocalsPointerValueRole:
if (isPointerType(data.type))
return pointerValue(data.value);
return QVariant(quint64(0));
+
+ case LocalsIsWatchpointAtAddressRole:
+ return engine()->breakHandler()
+ ->watchPointAt(data.coreAddress());
+
+ case LocalsAddressRole:
+ return data.coreAddress();
+
+ case LocalsIsWatchpointAtPointerValueRole:
+ if (isPointerType(data.type))
+ return engine()->breakHandler()
+ ->watchPointAt(pointerValue(data.addr));
+ return false;
+
default:
break;
}
@@ -677,8 +700,54 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
bool WatchModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
+ switch (role) {
+ case RequestAssignValueRole: {
+ QString str = value.toString();
+ int i = str.indexOf('=');
+ if (i != -1)
+ engine()->assignValueInDebugger(str.left(i), str.mid(i + 1));
+ return true;
+ }
+
+ case RequestAssignTypeRole: {
+ QString str = value.toString();
+ int i = str.indexOf('=');
+ if (i != -1)
+ engine()->assignValueInDebugger(str.left(i), str.mid(i + 1));
+ return true;
+ }
+
+ case RequestToggleWatchRole: {
+ BreakHandler *handler = engine()->breakHandler();
+ const quint64 address = value.toULongLong();
+ const QByteArray addressBA =
+ QByteArray("0x") + QByteArray::number(address, 16);
+ const int index = handler->findWatchPointIndexByAddress(addressBA);
+ if (index == -1) {
+ BreakpointData *data = new BreakpointData;
+ data->type = BreakpointData::WatchpointType;
+ data->address = addressBA;
+ handler->appendBreakpoint(data);
+ } else {
+ handler->removeBreakpoint(index);
+ }
+ engine()->attemptBreakpointSynchronization();
+ return true;
+ }
+
+ case RequestShowMemoryRole: {
+ (void) new MemoryViewAgent(engine(), value.toULongLong());
+ return true;
+ }
+
+ case RequestClearCppCodeModelSnapshotRole: {
+ plugin()->clearCppCodeModelSnapshot();
+ return true;
+ }
+ }
+
WatchItem &data = *watchItem(index);
- if (role == ExpandedRole) {
+ if (role == LocalsExpandedRole) {
if (value.toBool()) {
// Should already have been triggered by fetchMore()
//QTC_ASSERT(m_handler->m_expandedINames.contains(data.iname), /**/);
@@ -686,17 +755,17 @@ bool WatchModel::setData(const QModelIndex &index, const QVariant &value, int ro
} else {
m_handler->m_expandedINames.remove(data.iname);
}
- } else if (role == TypeFormatRole) {
+ } else if (role == LocalsTypeFormatRole) {
m_handler->setFormat(data.type, value.toInt());
- m_handler->m_manager->updateWatchData(data);
- } else if (role == IndividualFormatRole) {
+ engine()->updateWatchData(data);
+ } else if (role == LocalsIndividualFormatRole) {
const int format = value.toInt();
if (format == -1) {
m_handler->m_individualFormats.remove(data.addr);
} else {
m_handler->m_individualFormats[data.addr] = format;
}
- m_handler->m_manager->updateWatchData(data);
+ engine()->updateWatchData(data);
}
emit dataChanged(index, index);
return true;
@@ -985,9 +1054,9 @@ void WatchModel::formatRequests(QByteArray *out, const WatchItem *item) const
//
///////////////////////////////////////////////////////////////////////
-WatchHandler::WatchHandler(DebuggerManager *manager)
+WatchHandler::WatchHandler(DebuggerEngine *engine)
{
- m_manager = manager;
+ m_engine = engine;
m_expandPointers = true;
m_inChange = false;
@@ -1021,7 +1090,7 @@ void WatchHandler::endCycle()
m_locals->endCycle();
m_watchers->endCycle();
m_tooltips->endCycle();
- m_manager->updateWatchersWindow();
+ updateWatchersWindow();
}
void WatchHandler::cleanup()
@@ -1063,9 +1132,8 @@ void WatchHandler::insertData(const WatchData &data)
if (data.isSomethingNeeded() && data.iname.contains('.')) {
MODEL_DEBUG("SOMETHING NEEDED: " << data.toString());
- IDebuggerEngine *engine = m_manager->currentEngine();
- if (engine && !engine->isSynchroneous()) {
- m_manager->updateWatchData(data);
+ if (!m_engine->isSynchroneous()) {
+ m_engine->updateWatchData(data);
} else {
qDebug() << "ENDLESS LOOP: SOMETHING NEEDED: " << data.toString();
WatchData data1 = data;
@@ -1116,7 +1184,7 @@ void WatchHandler::insertBulkData(const QList<WatchData> &list)
foreach (const WatchData &data, list) {
if (data.isSomethingNeeded())
- m_manager->updateWatchData(data);
+ m_engine->updateWatchData(data);
}
}
@@ -1151,13 +1219,12 @@ void WatchHandler::watchExpression(const QString &exp)
if (exp.isEmpty() || exp == watcherEditPlaceHolder())
data.setAllUnneeded();
data.iname = watcherName(data.exp);
- IDebuggerEngine *engine = m_manager->currentEngine();
- if (engine && engine->isSynchroneous())
- m_manager->updateWatchData(data);
+ if (m_engine && m_engine->isSynchroneous())
+ m_engine->updateWatchData(data);
else
insertData(data);
- m_manager->updateWatchData(data);
- m_manager->updateWatchersWindow();
+ m_engine->updateWatchData(data);
+ updateWatchersWindow();
saveWatchers();
}
@@ -1275,6 +1342,13 @@ void WatchHandler::removeWatchExpression(const QString &exp0)
}
}
+void WatchHandler::updateWatchersWindow()
+{
+ const bool showWatchers = m_watchers->rowCount(QModelIndex()) > 0;
+ const bool showReturn = m_return->rowCount(QModelIndex()) > 0;
+ plugin()->updateWatchersWindow(showWatchers, showReturn);
+}
+
void WatchHandler::updateWatchers()
{
//qDebug() << "UPDATE WATCHERS";
@@ -1291,7 +1365,7 @@ void WatchHandler::updateWatchers()
void WatchHandler::loadWatchers()
{
- QVariant value = m_manager->sessionValue("Watchers");
+ QVariant value = plugin()->sessionValue("Watchers");
foreach (const QString &exp, value.toStringList())
m_watcherNames[exp.toLatin1()] = watcherCounter++;
@@ -1316,12 +1390,12 @@ QStringList WatchHandler::watchedExpressions() const
void WatchHandler::saveWatchers()
{
//qDebug() << "SAVE WATCHERS: " << m_watchers;
- m_manager->setSessionValue("Watchers", QVariant(watchedExpressions()));
+ plugin()->setSessionValue("Watchers", QVariant(watchedExpressions()));
}
void WatchHandler::loadTypeFormats()
{
- QVariant value = m_manager->sessionValue("DefaultFormats");
+ QVariant value = plugin()->sessionValue("DefaultFormats");
QMap<QString, QVariant> typeFormats = value.toMap();
QMapIterator<QString, QVariant> it(typeFormats);
while (it.hasNext()) {
@@ -1344,7 +1418,7 @@ void WatchHandler::saveTypeFormats()
typeFormats.insert(key, format);
}
}
- m_manager->setSessionValue("DefaultFormats", QVariant(typeFormats));
+ plugin()->setSessionValue("DefaultFormats", QVariant(typeFormats));
}
void WatchHandler::saveSessionData()