summaryrefslogtreecommitdiff
path: root/src/plugins/debugger/watchhandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/debugger/watchhandler.cpp')
-rw-r--r--src/plugins/debugger/watchhandler.cpp1048
1 files changed, 585 insertions, 463 deletions
diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp
index c9ada1d5b3..77bc4f9db5 100644
--- a/src/plugins/debugger/watchhandler.cpp
+++ b/src/plugins/debugger/watchhandler.cpp
@@ -40,10 +40,6 @@
#include "debuggerdialogs.h"
#include "watchutils.h"
-#if USE_WATCH_MODEL_TEST
-#include "modeltest.h"
-#endif
-
#include <utils/qtcassert.h>
#include <utils/savedaction.h>
@@ -52,6 +48,7 @@
#include <QDebug>
#include <QEvent>
#include <QFile>
+#include <QPointer>
#include <QProcess>
#include <QTextStream>
#include <QtAlgorithms>
@@ -62,6 +59,12 @@
#include <ctype.h>
#include <utils/qtcassert.h>
+//#define USE_WATCH_MODEL_TEST 0
+//#define USE_EXPENSIVE_CHECKS 0
+
+#if USE_WATCH_MODEL_TEST
+#include "modeltest.h"
+#endif
namespace Debugger {
namespace Internal {
@@ -70,7 +73,13 @@ namespace Internal {
enum { debugModel = 0 };
#define MODEL_DEBUG(s) do { if (debugModel) qDebug() << s; } while (0)
-#define MODEL_DEBUGX(s) qDebug() << s
+
+#if USE_EXPENSIVE_CHECKS
+#define CHECK(s) s
+#else
+#define CHECK(s)
+#endif
+
static QHash<QByteArray, int> theWatcherNames;
static QHash<QByteArray, int> theTypeFormats;
@@ -100,126 +109,222 @@ static QByteArray stripForFormat(const QByteArray &ba)
return res;
}
-void WatchHandler::setUnprintableBase(int base)
-{
- theUnprintableBase = base;
- emitAllChanged();
-}
-
-int WatchHandler::unprintableBase()
-{
- return theUnprintableBase;
-}
-
////////////////////////////////////////////////////////////////////
//
// WatchItem
//
////////////////////////////////////////////////////////////////////
+// Used to make sure the item cache is notified of construction and
+// destruction of items.
+
+class WatchItem;
+WatchItem *itemConstructor(WatchModel *model, const QByteArray &iname);
+void itemDestructor(WatchModel *model, WatchItem *item);
+
class WatchItem : public WatchData
{
public:
- WatchItem() { parent = 0; }
-
- ~WatchItem() {
- if (parent != 0)
- parent->children.removeOne(this);
- qDeleteAll(children);
- }
-
- WatchItem(const WatchData &data) : WatchData(data)
- { parent = 0; }
+ WatchItem *parent;
+ QList<WatchItem *> children;
- void setData(const WatchData &data)
- { static_cast<WatchData &>(*this) = data; }
+private:
+ friend WatchItem *itemConstructor(WatchModel *model, const QByteArray &iname);
+ friend void itemDestructor(WatchModel *model, WatchItem *item);
- WatchItem *parent;
- QList<WatchItem *> children; // fetched children
+ WatchItem() { parent = 0; }
+ ~WatchItem() {}
+ WatchItem(const WatchItem &); // Not implemented.
};
-
///////////////////////////////////////////////////////////////////////
//
// WatchModel
//
///////////////////////////////////////////////////////////////////////
-WatchModel::WatchModel(WatchHandler *handler, WatchType type)
- : QAbstractItemModel(handler), m_generationCounter(0),
- m_handler(handler), m_type(type)
+class WatchModel : public QAbstractItemModel
{
- m_root = new WatchItem;
- m_root->hasChildren = 1;
- m_root->state = 0;
- m_root->name = WatchHandler::tr("Root");
- m_root->parent = 0;
+ Q_OBJECT
- switch (m_type) {
- case ReturnWatch:
- m_root->iname = "return";
- m_root->name = WatchHandler::tr("Return Value");
- break;
- case LocalsWatch:
- m_root->iname = "local";
- m_root->name = WatchHandler::tr("Locals");
- break;
- case WatchersWatch:
- m_root->iname = "watch";
- m_root->name = WatchHandler::tr("Expressions");
- break;
- case TooltipsWatch:
- m_root->iname = "tooltip";
- m_root->name = WatchHandler::tr("Tooltip");
- break;
- case InspectWatch:
- m_root->iname = "inspect";
- m_root->name = WatchHandler::tr("Inspector");
- break;
- }
+private:
+ explicit WatchModel(WatchHandler *handler);
+ ~WatchModel();
+
+ friend WatchItem *itemConstructor(WatchModel *model, const QByteArray &iname);
+ friend void itemDestructor(WatchModel *model, WatchItem *item);
+
+public:
+ int rowCount(const QModelIndex &idx = QModelIndex()) const;
+ int columnCount(const QModelIndex &idx) const;
+
+signals:
+ void currentIndexRequested(const QModelIndex &idx);
+ void itemIsExpanded(const QModelIndex &idx);
+
+private:
+ QVariant data(const QModelIndex &idx, int role) const;
+ bool setData(const QModelIndex &idx, 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());
+ WatchItem *createItem(const QByteArray &iname, const QString &name, WatchItem *parent);
+
+ 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 insertDataItem(const WatchData &data);
+ Q_SLOT void reinsertAllData();
+ void reinsertAllDataHelper(WatchItem *item, QList<WatchData> *data);
+ void insertBulkData(const QList<WatchData> &data);
+ QString displayForAutoTest(const QByteArray &iname) const;
+ void reinitialize();
+ void destroyItem(WatchItem *item); // With model notification.
+ void destroyChildren(WatchItem *item); // With model notification.
+ void destroyHelper(const QList<WatchItem *> &items); // Without model notification.
+ void emitDataChanged(int column,
+ const QModelIndex &parentIndex = QModelIndex());
+
+ friend QDebug operator<<(QDebug d, const WatchModel &m);
+
+ void dump();
+ void dumpHelper(WatchItem *item);
+ Q_SLOT void emitAllChanged();
+
+ void showInEditorHelper(QString *contents, WatchItem *item, int level);
+ void setCurrentItem(const QByteArray &iname);
+
+ 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;
+
+ WatchHandler *m_handler; // Not owned.
+
+ WatchItem *m_root; // Owned.
+ WatchItem *m_localsRoot; // Not owned.
+ WatchItem *m_inspectorRoot; // Not owned.
+ WatchItem *m_watchRoot; // Not owned.
+ WatchItem *m_returnRoot; // Not owned.
+ WatchItem *m_tooltipRoot; // Not owned.
+
+ QSet<QByteArray> m_expandedINames;
+ QSet<QByteArray> m_fetchTriggered;
+
+ QStringList typeFormatList(const WatchData &data) const;
+ TypeFormats m_reportedTypeFormats;
+
+ // QWidgets and QProcesses taking care of special displays.
+ typedef QMap<QByteArray, QPointer<QObject> > EditHandlers;
+ EditHandlers m_editHandlers;
+
+ WatchItem *createItem(const QByteArray &iname);
+ WatchItem *createItem(const WatchData &data);
+ void assignData(WatchItem *item, const WatchData &data);
+ WatchItem *findItem(const QByteArray &iname) const;
+ friend class WatchItem;
+ QHash<QByteArray, WatchItem *> m_cache;
+
+ #if USE_EXPENSIVE_CHECKS
+ QHash<const WatchItem *, QByteArray> m_cache2;
+ void checkTree();
+ void checkItem(const WatchItem *item) const;
+ void checkTree(WatchItem *item, QSet<QByteArray> *inames);
+ #endif
+};
+
+WatchModel::WatchModel(WatchHandler *handler)
+ : m_handler(handler)
+{
+ m_root = createItem(QByteArray(), tr("Root"), 0);
+ // Note: Needs to stay
+ m_localsRoot = createItem("local", tr("Locals"), m_root);
+ m_inspectorRoot = createItem("inspect", tr("Inspector"), m_root);
+ m_watchRoot = createItem("watch", tr("Expressions"), m_root);
+ m_returnRoot = createItem("return", tr("Return Value"), m_root);
+ m_tooltipRoot = createItem("tooltip", tr("Tooltip"), m_root);
+
+ connect(debuggerCore()->action(SortStructMembers), SIGNAL(valueChanged(QVariant)),
+ SLOT(reinsertAllData()));
+ connect(debuggerCore()->action(ShowStdNamespace), SIGNAL(valueChanged(QVariant)),
+ SLOT(reinsertAllData()));
+ connect(debuggerCore()->action(ShowQtNamespace), SIGNAL(valueChanged(QVariant)),
+ SLOT(reinsertAllData()));
}
WatchModel::~WatchModel()
{
- delete m_root;
+ CHECK(checkItem(m_root));
+ destroyChildren(m_root);
+ itemDestructor(this, m_root);
+ QTC_CHECK(m_cache.isEmpty());
}
-WatchItem *WatchModel::rootItem() const
+WatchItem *itemConstructor(WatchModel *model, const QByteArray &iname)
{
- return m_root;
+ QTC_CHECK(!model->m_cache.contains(iname));
+ WatchItem *item = new WatchItem();
+ item->iname = iname;
+ model->m_cache[iname] = item;
+ CHECK(model->m_cache2[item] = iname);
+ CHECK(model->checkItem(item));
+ return item;
}
-void WatchModel::reinitialize()
+void itemDestructor(WatchModel *model, WatchItem *item)
{
- int n = m_root->children.size();
- if (n == 0)
- return;
- //MODEL_DEBUG("REMOVING " << n << " CHILDREN OF " << m_root->iname);
- QModelIndex index = watchIndex(m_root);
- beginRemoveRows(index, 0, n - 1);
- qDeleteAll(m_root->children);
- m_root->children.clear();
- endRemoveRows();
+ QTC_ASSERT(model->m_cache.value(item->iname) == item, return);
+ CHECK(model->checkItem(item));
+ CHECK(model->m_cache2.remove(item));
+ model->m_cache.remove(item->iname);
+ delete item;
}
-void WatchModel::emitAllChanged()
+WatchItem *WatchModel::createItem(const QByteArray &iname, const QString &name, WatchItem *parent)
{
- emit layoutChanged();
+ WatchItem *item = itemConstructor(this, iname);
+ item->name = name;
+ item->hasChildren = true; // parent == 0;
+ item->state = 0;
+ item->parent = parent;
+ if (parent)
+ parent->children.append(item);
+ return item;
}
-void WatchModel::beginCycle(bool fullCycle)
+void WatchModel::reinitialize()
{
- if (fullCycle)
- m_generationCounter++;
-
- //emit enableUpdates(false);
+ CHECK(checkTree());
+ //MODEL_DEBUG("REMOVING " << n << " CHILDREN OF " << m_root->iname);
+ QTC_CHECK(m_root->children.size() == 5);
+ destroyChildren(m_localsRoot);
+ destroyChildren(m_watchRoot);
+ destroyChildren(m_returnRoot);
+ destroyChildren(m_tooltipRoot);
+ destroyChildren(m_inspectorRoot);
+ QTC_CHECK(m_cache.size() == 6);
+ CHECK(checkTree());
}
-void WatchModel::endCycle()
+void WatchModel::emitAllChanged()
{
- removeOutdated();
- m_fetchTriggered.clear();
- //emit enableUpdates(true);
+ emit layoutChanged();
}
DebuggerEngine *WatchModel::engine() const
@@ -237,43 +342,85 @@ void WatchModel::dump()
void WatchModel::dumpHelper(WatchItem *item)
{
qDebug() << "ITEM: " << item->iname
- << (item->parent ? item->parent->iname : "<none>")
- << item->generation;
+ << (item->parent ? item->parent->iname : "<none>");
foreach (WatchItem *child, item->children)
dumpHelper(child);
}
-void WatchModel::removeOutdated()
+void WatchModel::destroyHelper(const QList<WatchItem *> &items)
{
- foreach (WatchItem *child, m_root->children)
- removeOutdatedHelper(child);
-#if DEBUG_MODEL
-#if USE_WATCH_MODEL_TEST
- (void) new ModelTest(this, this);
-#endif
-#endif
-}
-
-void WatchModel::removeOutdatedHelper(WatchItem *item)
-{
- if (item->generation < m_generationCounter) {
- destroyItem(item);
- } else {
- foreach (WatchItem *child, item->children)
- removeOutdatedHelper(child);
+ for (int i = items.size(); --i >= 0; ) {
+ WatchItem *item = items.at(i);
+ destroyHelper(item->children);
+ itemDestructor(this, item);
}
}
void WatchModel::destroyItem(WatchItem *item)
{
+ const QByteArray iname = item->iname;
+ CHECK(checkTree());
+ QTC_ASSERT(m_cache.contains(iname), return);
+
+ // Deregister from model and parent.
+ // It's sufficient to do this non-recursively.
WatchItem *parent = item->parent;
- QModelIndex index = watchIndex(parent);
- int n = parent->children.indexOf(item);
+ QTC_ASSERT(parent, return);
+ QModelIndex parentIndex = watchIndex(parent);
+ const int i = parent->children.indexOf(item);
//MODEL_DEBUG("NEED TO REMOVE: " << item->iname << "AT" << n);
- beginRemoveRows(index, n, n);
- parent->children.removeAt(n);
+ beginRemoveRows(parentIndex, i, i);
+ parent->children.removeAt(i);
endRemoveRows();
- delete item;
+
+ // Destroy contents.
+ destroyHelper(item->children);
+ itemDestructor(this, item);
+ QTC_ASSERT(!m_cache.contains(iname), return);
+ CHECK(checkTree());
+}
+
+void WatchModel::destroyChildren(WatchItem *item)
+{
+ CHECK(checkTree());
+ QTC_ASSERT(m_cache.contains(item->iname), return);
+ if (item->children.isEmpty())
+ return;
+
+ QList<WatchItem *> items = item->children;
+
+ // Deregister from model and parent.
+ // It's sufficient to do this non-recursively.
+ QModelIndex idx = watchIndex(item);
+ beginRemoveRows(idx, 0, items.size() - 1);
+ item->children.clear();
+ endRemoveRows();
+
+ // Destroy contents.
+ destroyHelper(items);
+ CHECK(checkTree());
+}
+
+WatchItem *WatchModel::findItem(const QByteArray &iname) const
+{
+ return m_cache.value(iname, 0);
+}
+
+WatchItem *WatchModel::createItem(const WatchData &data)
+{
+ WatchItem *item = itemConstructor(this, data.iname);
+ static_cast<WatchData &>(*item) = data;
+ return item;
+}
+
+void WatchModel::assignData(WatchItem *item, const WatchData &data)
+{
+ CHECK(checkItem(item));
+ QTC_ASSERT(data.iname == item->iname,
+ m_cache.remove(item->iname);
+ m_cache[data.iname] = item);
+ static_cast<WatchData &>(*item) = data;
+ CHECK(checkItem(item));
}
void WatchModel::reinsertAllData()
@@ -281,26 +428,21 @@ void WatchModel::reinsertAllData()
QList<WatchData> list;
reinsertAllDataHelper(m_root, &list);
reinitialize();
- foreach (WatchItem data, list) {
- data.setAllUnneeded();
- insertData(data);
- }
- layoutChanged();
+ insertBulkData(list);
}
void WatchModel::reinsertAllDataHelper(WatchItem *item, QList<WatchData> *data)
{
data->append(*item);
+ data->back().setAllUnneeded();
foreach (WatchItem *child, item->children)
reinsertAllDataHelper(child, data);
}
static QByteArray parentName(const QByteArray &iname)
{
- int pos = iname.lastIndexOf('.');
- if (pos == -1)
- return QByteArray();
- return iname.left(pos);
+ const int pos = iname.lastIndexOf('.');
+ return pos == -1 ? QByteArray() : iname.left(pos);
}
static QString niceTypeHelper(const QByteArray &typeIn)
@@ -576,20 +718,27 @@ static inline QVariant editValue(const WatchData &d)
return QVariant(translate(stringValue));
}
-bool WatchModel::canFetchMore(const QModelIndex &index) const
+bool WatchModel::canFetchMore(const QModelIndex &idx) const
{
- WatchItem *item = watchItem(index);
+ if (!idx.isValid())
+ return false;
+ if (!contentIsValid())
+ return false;
+ WatchItem *item = watchItem(idx);
QTC_ASSERT(item, return false);
- return index.isValid() && contentIsValid() && !m_fetchTriggered.contains(item->iname);
+ if (!item->iname.contains('.'))
+ return false;
+ return !m_fetchTriggered.contains(item->iname);
}
-void WatchModel::fetchMore(const QModelIndex &index)
+void WatchModel::fetchMore(const QModelIndex &idx)
{
- QTC_ASSERT(index.isValid(), return);
- WatchItem *item = watchItem(index);
+ if (!idx.isValid())
+ return; // Triggered by ModelTester.
+ WatchItem *item = watchItem(idx);
QTC_ASSERT(item, return);
QTC_ASSERT(!m_fetchTriggered.contains(item->iname), return);
- m_handler->m_expandedINames.insert(item->iname);
+ m_expandedINames.insert(item->iname);
m_fetchTriggered.insert(item->iname);
if (item->children.isEmpty()) {
WatchData data = *item;
@@ -634,6 +783,8 @@ QModelIndex WatchModel::parent(const QModelIndex &idx) const
int WatchModel::rowCount(const QModelIndex &idx) const
{
+ if (!idx.isValid())
+ return m_root->children.size();
if (idx.column() > 0)
return 0;
return watchItem(idx)->children.size();
@@ -653,12 +804,15 @@ bool WatchModel::hasChildren(const QModelIndex &parent) const
WatchItem *WatchModel::watchItem(const QModelIndex &idx) const
{
- return idx.isValid()
+ WatchItem *item = idx.isValid()
? static_cast<WatchItem*>(idx.internalPointer()) : m_root;
+ CHECK(checkItem(item));
+ return item;
}
QModelIndex WatchModel::watchIndex(const WatchItem *item) const
{
+ CHECK(checkItem(item));
return watchIndexHelper(item, m_root, QModelIndex());
}
@@ -719,13 +873,40 @@ int WatchModel::itemFormat(const WatchData &data) const
bool WatchModel::contentIsValid() const
{
+ // FIXME:
// inspector doesn't follow normal beginCycle()/endCycle()
- if (m_type == InspectWatch)
- return true;
+ //if (m_type == InspectWatch)
+ // return true;
return m_handler->m_contentsValid;
}
-static inline QString expression(const WatchItem *item)
+#if USE_EXPENSIVE_CHECKS
+void WatchModel::checkTree()
+{
+ QSet<QByteArray> inames;
+ checkTree(m_root, &inames);
+ QSet<QByteArray> current = m_cache.keys().toSet();
+ Q_ASSERT(inames == current);
+}
+
+void WatchModel::checkTree(WatchItem *item, QSet<QByteArray> *inames)
+{
+ checkItem(item);
+ inames->insert(item->iname);
+ for (int i = 0, n = item->children.size(); i != n; ++i)
+ checkTree(item->children.at(i), inames);
+}
+
+void WatchModel::checkItem(const WatchItem *item) const
+{
+ Q_ASSERT(item->children.size() < 1000 * 1000);
+ Q_ASSERT(m_cache2.contains(item));
+ Q_ASSERT(m_cache2.value(item) == item->iname);
+ Q_ASSERT(m_cache.value(item->iname) == item);
+}
+#endif
+
+static QString expression(const WatchItem *item)
{
if (!item->exp.isEmpty())
return QString::fromLatin1(item->exp);
@@ -746,11 +927,11 @@ QString WatchModel::display(const WatchItem *item, int col) const
QString result;
switch (col) {
case 0:
- if (m_type == WatchersWatch && item->name.isEmpty())
+ if (item->parent == m_watchRoot && item->name.isEmpty())
result = tr("<Edit>");
- else if (m_type == ReturnWatch && item->iname.count('.') == 1)
+ else if (item->parent == m_returnRoot)
result = tr("returned value");
- else if (item->name == QLatin1String("*") && item->parent)
+ else if (item->name == QLatin1String("*"))
result = QLatin1Char('*') + item->parent->name;
else
result = removeInitialNamespace(item->name);
@@ -774,7 +955,7 @@ QString WatchModel::display(const WatchItem *item, int col) const
QString WatchModel::displayForAutoTest(const QByteArray &iname) const
{
- const WatchItem *item = findItem(iname, m_root);
+ WatchItem *item = findItem(iname);
if (item)
return display(item, 1) + QLatin1Char(' ') + display(item, 2);
return QString();
@@ -782,6 +963,9 @@ QString WatchModel::displayForAutoTest(const QByteArray &iname) const
QVariant WatchModel::data(const QModelIndex &idx, int role) const
{
+ if (!idx.isValid())
+ return QVariant(); // Triggered by ModelTester.
+
const WatchItem *item = watchItem(idx);
const WatchItem &data = *item;
@@ -840,10 +1024,10 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
return data.iname;
case LocalsExpandedRole:
- return m_handler->m_expandedINames.contains(data.iname);
+ return m_expandedINames.contains(data.iname);
case LocalsTypeFormatListRole:
- return m_handler->typeFormatList(data);
+ return typeFormatList(data);
case LocalsTypeRole:
return removeNamespaces(displayType(data));
@@ -890,13 +1074,16 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
return QVariant();
}
-bool WatchModel::setData(const QModelIndex &index, const QVariant &value, int role)
+bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role)
{
- WatchItem &data = *watchItem(index);
+ if (!idx.isValid())
+ return false; // Triggered by ModelTester.
+
+ WatchItem &data = *watchItem(idx);
switch (role) {
case Qt::EditRole:
- switch (index.column()) {
+ switch (idx.column()) {
case 0: // Watch expression: See delegate.
break;
case 1: // Change value
@@ -909,10 +1096,10 @@ bool WatchModel::setData(const QModelIndex &index, const QVariant &value, int ro
case LocalsExpandedRole:
if (value.toBool()) {
// Should already have been triggered by fetchMore()
- //QTC_CHECK(m_handler->m_expandedINames.contains(data.iname));
- m_handler->m_expandedINames.insert(data.iname);
+ //QTC_CHECK(m_expandedINames.contains(data.iname));
+ m_expandedINames.insert(data.iname);
} else {
- m_handler->m_expandedINames.remove(data.iname);
+ m_expandedINames.remove(data.iname);
}
break;
@@ -933,7 +1120,7 @@ bool WatchModel::setData(const QModelIndex &index, const QVariant &value, int ro
}
}
- emit dataChanged(index, index);
+ //emit dataChanged(idx, idx);
return true;
}
@@ -990,7 +1177,7 @@ QVariant WatchModel::headerData(int section, Qt::Orientation orientation, int ro
return QVariant();
}
-QStringList WatchHandler::typeFormatList(const WatchData &data) const
+QStringList WatchModel::typeFormatList(const WatchData &data) const
{
if (data.referencingAddress || isPointerType(data.type))
return QStringList()
@@ -1026,7 +1213,7 @@ QStringList WatchHandler::typeFormatList(const WatchData &data) const
}
// Determine sort order of watch items by sort order or alphabetical inames
-// according to setting 'SortStructMembers'. We need a map key for bulkInsert
+// according to setting 'SortStructMembers'. We need a map key for insertBulkData
// and a predicate for finding the insertion position of a single item.
// Set this before using any of the below according to action
@@ -1086,98 +1273,153 @@ static int findInsertPosition(const QList<WatchItem *> &list, const WatchItem *i
return it - list.begin();
}
-void WatchModel::insertData(const WatchData &data)
+void WatchModel::insertDataItem(const WatchData &data)
{
+#if USE_WATCH_MODEL_TEST
+ (void) new ModelTest(this, this);
+#endif
+ m_fetchTriggered.remove(data.iname);
+ CHECK(checkTree());
+
QTC_ASSERT(!data.iname.isEmpty(), qDebug() << data.toString(); return);
- WatchItem *parent = findItem(parentName(data.iname), m_root);
+ WatchItem *parent = findItem(parentName(data.iname));
if (!parent) {
WatchData parent;
parent.iname = parentName(data.iname);
MODEL_DEBUG("\nFIXING MISSING PARENT FOR\n" << data.iname);
if (!parent.iname.isEmpty())
- insertData(parent);
+ insertDataItem(parent);
return;
}
- QModelIndex index = watchIndex(parent);
- if (WatchItem *oldItem = findItem(data.iname, parent)) {
- bool hadChildren = oldItem->hasChildren;
+
+ WatchItem *item = findItem(data.iname);
+#if 0
+ if (item) {
// Overwrite old entry.
- bool hasChanged = oldItem->hasChanged(data);
- oldItem->setData(data);
- oldItem->changed = hasChanged;
- oldItem->generation = m_generationCounter;
- QModelIndex idx = watchIndex(oldItem);
- emit dataChanged(idx, idx.sibling(idx.row(), 2));
+ bool hasChanged = item->hasChanged(data);
+ assignData(item, data);
+ item->changed = hasChanged;
+ // QModelIndex idx = watchIndex(oldItem);
+ // emit dataChanged(idx, idx.sibling(idx.row(), 2));
+ } else {
+ // Add new entry.
+ item = createItem(data);
+ item->parent = parent;
+ item->changed = true;
+ }
+ const int n = findInsertPosition(parent->children, item);
+ QModelIndex idx = watchIndex(parent);
+ beginInsertRows(idx, n, n);
+ parent->children.insert(n, item);
+ endInsertRows();
+#else
+ if (item) {
+ // Remove old children.
+ destroyChildren(item);
- // This works around https://bugreports.qt-project.org/browse/QTBUG-7115
- // by creating and destroying a dummy child item.
- if (!hadChildren && oldItem->hasChildren) {
- WatchData dummy = data;
- dummy.iname = data.iname + ".x";
- dummy.hasChildren = false;
- dummy.setAllUnneeded();
- insertData(dummy);
- destroyItem(findItem(dummy.iname, m_root));
- }
+ // Overwrite old entry.
+ bool hasChanged = item->hasChanged(data);
+ assignData(item, data);
+ item->changed = hasChanged;
+ QModelIndex idx = watchIndex(item);
+ emit dataChanged(idx, idx.sibling(idx.row(), 2));
} else {
// Add new entry.
- WatchItem *item = new WatchItem(data);
+ item = createItem(data);
item->parent = parent;
- item->generation = m_generationCounter;
item->changed = true;
- const int n = findInsertPosition(parent->children, item);
- beginInsertRows(index, n, n);
- parent->children.insert(n, item);
+ const int row = findInsertPosition(parent->children, item);
+ QModelIndex idx = watchIndex(parent);
+ beginInsertRows(idx, row, row);
+ parent->children.insert(row, item);
endInsertRows();
+ if (m_expandedINames.contains(parentName(data.iname))) {
+ emit itemIsExpanded(idx);
+ }
+// if (m_expandedINames.contains(data.iname)) {
+// QModelIndex child = index(row, 0, idx);
+// emit itemIsExpanded(child);
+// }
}
+#endif
}
void WatchModel::insertBulkData(const QList<WatchData> &list)
{
+ foreach (const WatchData &data, list)
+ insertDataItem(data);
+ CHECK(checkTree());
+ return;
+
#if 0
- for (int i = 0; i != list.size(); ++i)
- insertData(list.at(i));
+ QMap<QByteArray, QList<WatchData> > hash;
+
+ foreach (const WatchData &data, list) {
+ // we insert everything, including incomplete stuff
+ // to reduce the number of row add operations in the model.
+ if (data.isValid()) {
+ hash[parentName(data.iname)].append(data);
+ } else {
+ qWarning("%s:%d: Attempt to bulk-insert invalid watch item: %s",
+ __FILE__, __LINE__, qPrintable(data.toString()));
+ }
+ }
+ foreach (const QByteArray &parentIName, hash.keys()) {
+ // FIXME
+ insertBulkDataX(hash[parentIName]);
+ }
+
+ foreach (const WatchData &data, list) {
+ if (data.isSomethingNeeded())
+ m_engine->updateWatchData(data);
+ }
+ const int n = list.size();
+#if 0
+ for (int i = 0; i != n; ++i)
+ insertData(list.at(i), false);
+ layoutChanged();
return;
#endif
// This method does not properly insert items in proper "iname sort
- // order", leading to random removal of items in removeOutdated();
+ // order".
//qDebug() << "WMI:" << list.toString();
//static int bulk = 0;
//foreach (const WatchItem &data, list)
// qDebug() << "BULK: " << ++bulk << data.toString();
- QTC_ASSERT(!list.isEmpty(), return);
+ QTC_ASSERT(n > 0, return);
QByteArray parentIName = parentName(list.at(0).iname);
- WatchItem *parent = findItem(parentIName, m_root);
+ WatchItem *parent = m_handler->findItem(parentIName);
if (!parent) {
WatchData parent;
parent.iname = parentIName;
- insertData(parent);
+ insertDataItem(parent, true);
MODEL_DEBUG("\nFIXING MISSING PARENT FOR\n" << list.at(0).iname);
return;
}
- QModelIndex index = watchIndex(parent);
+ QModelIndex idx = watchIndex(parent);
sortWatchDataAlphabetically = debuggerCore()->boolSetting(SortStructMembers);
QMap<WatchDataSortKey, WatchData> newList;
typedef QMap<WatchDataSortKey, WatchData>::iterator Iterator;
- foreach (const WatchItem &data, list)
- newList.insert(WatchDataSortKey(data), data);
- if (newList.size() != list.size()) {
- qDebug() << "LIST: ";
- foreach (const WatchItem &data, list)
- qDebug() << data.toString();
- qDebug() << "NEW LIST: ";
- foreach (const WatchItem &data, newList)
- qDebug() << data.toString();
- qDebug() << "P->CHILDREN: ";
- foreach (const WatchItem *item, parent->children)
- qDebug() << item->toString();
- qDebug()
- << "P->CHILDREN.SIZE: " << parent->children.size()
- << "NEWLIST SIZE: " << newList.size()
- << "LIST SIZE: " << list.size();
- }
+ for (int i = 0; i != n; ++i)
+ newList.insert(WatchDataSortKey(list.at(i)), list.at(i));
+
+ //if (newList.size() != n) {
+ // qDebug() << "LIST: ";
+ // for (int i = 0; i != n; ++i)
+ // qDebug() << list.at(i).toString();
+ // qDebug() << "NEW LIST: ";
+ // foreach (const WatchData &data, newList)
+ // qDebug() << data.toString();
+ // qDebug() << "P->CHILDREN: ";
+ // foreach (const WatchItem *item, parent->children)
+ // qDebug() << item->toString();
+ // qDebug()
+ // << "P->CHILDREN.SIZE: " << parent->children.size()
+ // << "NEWLIST SIZE: " << newList.size()
+ // << "LIST SIZE: " << list.size();
+ //}
QTC_ASSERT(newList.size() == list.size(), return);
foreach (WatchItem *oldItem, parent->children) {
@@ -1185,12 +1427,9 @@ void WatchModel::insertBulkData(const QList<WatchData> &list)
Iterator it = newList.find(oldSortKey);
if (it == newList.end()) {
WatchData data = *oldItem;
- data.generation = m_generationCounter;
newList.insert(oldSortKey, data);
} else {
it->changed = it->hasChanged(*oldItem);
- if (it->generation == -1)
- it->generation = m_generationCounter;
}
}
@@ -1206,9 +1445,7 @@ void WatchModel::insertBulkData(const QList<WatchData> &list)
if (!parent->children[i]->isEqual(*it)) {
qDebug() << "REPLACING" << parent->children.at(i)->iname
<< " WITH " << it->iname << it->generation;
- parent->children[i]->setData(*it);
- if (parent->children[i]->generation == -1)
- parent->children[i]->generation = m_generationCounter;
+ m_handler->setData(parent->children[i], *it);
//emit dataChanged(idx.sibling(i, 0), idx.sibling(i, 2));
} else {
//qDebug() << "SKIPPING REPLACEMENT" << parent->children.at(i)->iname;
@@ -1218,14 +1455,12 @@ void WatchModel::insertBulkData(const QList<WatchData> &list)
// add new items
if (oldCount < newList.size()) {
- beginInsertRows(index, oldCount, newList.size() - 1);
+ beginInsertRows(idx, oldCount, newList.size() - 1);
//MODEL_DEBUG("INSERT : " << data.iname << data.value);
for (int i = oldCount; i < newList.size(); ++i, ++it) {
- WatchItem *item = new WatchItem(*it);
+ WatchItem *item = m_handler->createItem(*it);
qDebug() << "ADDING" << it->iname;
item->parent = parent;
- if (item->generation == -1)
- item->generation = m_generationCounter;
item->changed = true;
parent->children.append(item);
}
@@ -1233,16 +1468,7 @@ void WatchModel::insertBulkData(const QList<WatchData> &list)
}
//qDebug() << "ITEMS: " << parent->children.size();
dump();
-}
-
-WatchItem *WatchModel::findItem(const QByteArray &iname, WatchItem *root) const
-{
- if (root->iname == iname)
- return root;
- for (int i = root->children.size(); --i >= 0; )
- if (WatchItem *item = findItem(iname, root->children.at(i)))
- return item;
- return 0;
+#endif
}
static void debugRecursion(QDebug &d, const WatchItem *item, int depth)
@@ -1271,6 +1497,29 @@ void WatchModel::formatRequests(QByteArray *out, const WatchItem *item) const
formatRequests(out, child);
}
+void WatchModel::showInEditorHelper(QString *contents, WatchItem *item, int depth)
+{
+ const QChar tab = QLatin1Char('\t');
+ const QChar nl = QLatin1Char('\n');
+ contents->append(QString(depth, tab));
+ contents->append(item->name);
+ contents->append(tab);
+ contents->append(item->value);
+ contents->append(tab);
+ contents->append(item->type);
+ contents->append(nl);
+ foreach (WatchItem *child, item->children)
+ showInEditorHelper(contents, child, depth + 1);
+}
+
+void WatchModel::setCurrentItem(const QByteArray &iname)
+{
+ if (WatchItem *item = findItem(iname)) {
+ QModelIndex idx = watchIndex(item);
+ emit currentIndexRequested(idx);
+ }
+}
+
///////////////////////////////////////////////////////////////////////
//
// WatchHandler
@@ -1280,92 +1529,39 @@ void WatchModel::formatRequests(QByteArray *out, const WatchItem *item) const
WatchHandler::WatchHandler(DebuggerEngine *engine)
{
m_engine = engine;
- m_inChange = false;
m_watcherCounter = debuggerCore()->sessionValue(QLatin1String("Watchers"))
.toStringList().count();
-
- m_return = new WatchModel(this, ReturnWatch);
- m_locals = new WatchModel(this, LocalsWatch);
- m_watchers = new WatchModel(this, WatchersWatch);
- m_tooltips = new WatchModel(this, TooltipsWatch);
- m_inspect = new WatchModel(this, InspectWatch);
-
+ m_model = new WatchModel(this);
m_contentsValid = false;
+ m_contentsValid = true; // FIXME
m_resetLocationScheduled = false;
-
- connect(debuggerCore()->action(SortStructMembers), SIGNAL(valueChanged(QVariant)),
- SLOT(reinsertAllData()));
- connect(debuggerCore()->action(ShowStdNamespace), SIGNAL(valueChanged(QVariant)),
- SLOT(reinsertAllData()));
- connect(debuggerCore()->action(ShowQtNamespace), SIGNAL(valueChanged(QVariant)),
- SLOT(reinsertAllData()));
-}
-
-void WatchHandler::beginCycle(bool fullCycle)
-{
- m_return->beginCycle(fullCycle);
- m_locals->beginCycle(fullCycle);
- m_watchers->beginCycle(fullCycle);
- m_tooltips->beginCycle(fullCycle);
- // don't sync m_inspect here: It's updated on it's own
-}
-
-void WatchHandler::endCycle()
-{
- m_return->endCycle();
- m_locals->endCycle();
- m_watchers->endCycle();
- m_tooltips->endCycle();
-
- m_contentsValid = true;
- m_resetLocationScheduled = false;
-
- updateWatchersWindow();
}
-void WatchHandler::beginCycle(WatchType type, bool fullCycle)
+WatchHandler::~WatchHandler()
{
- model(type)->beginCycle(fullCycle);
-}
-
-void WatchHandler::endCycle(WatchType type)
-{
- model(type)->endCycle();
+ // Do it manually to prevent calling back in model destructors
+ // after m_cache is destroyed.
+ delete m_model;
+ m_model = 0;
}
void WatchHandler::cleanup()
{
- m_expandedINames.clear();
+ m_model->m_expandedINames.clear();
theWatcherNames.remove(QByteArray());
- m_return->reinitialize();
- m_locals->reinitialize();
- m_tooltips->reinitialize();
- m_inspect->reinitialize();
- m_return->m_fetchTriggered.clear();
- m_locals->m_fetchTriggered.clear();
- m_watchers->m_fetchTriggered.clear();
- m_tooltips->m_fetchTriggered.clear();
- m_inspect->m_fetchTriggered.clear();
+ m_model->reinitialize();
+ m_model->m_fetchTriggered.clear();
#if 1
- for (EditHandlers::ConstIterator it = m_editHandlers.begin();
- it != m_editHandlers.end(); ++it) {
+ for (WatchModel::EditHandlers::ConstIterator it = m_model->m_editHandlers.begin();
+ it != m_model->m_editHandlers.end(); ++it) {
if (!it.value().isNull())
delete it.value();
}
- m_editHandlers.clear();
+ m_model->m_editHandlers.clear();
#endif
}
-void WatchHandler::emitAllChanged()
-{
- m_return->emitAllChanged();
- m_locals->emitAllChanged();
- m_watchers->emitAllChanged();
- m_tooltips->emitAllChanged();
- m_inspect->emitAllChanged();
-}
-
-void WatchHandler::insertData(const WatchData &data)
+void WatchHandler::insertIncompleteData(const WatchData &data)
{
MODEL_DEBUG("INSERTDATA: " << data.toString());
if (!data.isValid()) {
@@ -1374,14 +1570,10 @@ void WatchHandler::insertData(const WatchData &data)
return;
}
- if (data.isSomethingNeeded() && data.iname.contains(".")) {
+ if (data.isSomethingNeeded() && data.iname.contains('.')) {
MODEL_DEBUG("SOMETHING NEEDED: " << data.toString());
- if (!m_engine->isSynchronous()
- || data.isInspect()) {
- WatchModel *model = modelForIName(data.iname);
- QTC_ASSERT(model, return);
- model->insertData(data);
-
+ if (!m_engine->isSynchronous() || data.isInspect()) {
+ m_model->insertDataItem(data);
m_engine->updateWatchData(data);
} else {
m_engine->showMessage(QLatin1String("ENDLESS LOOP: SOMETHING NEEDED: ")
@@ -1390,71 +1582,47 @@ void WatchHandler::insertData(const WatchData &data)
data1.setAllUnneeded();
data1.setValue(QLatin1String("<unavailable synchronous data>"));
data1.setHasChildren(false);
- WatchModel *model = modelForIName(data.iname);
- QTC_ASSERT(model, return);
- model->insertData(data1);
+ m_model->insertDataItem(data1);
}
} else {
- WatchModel *model = modelForIName(data.iname);
- QTC_ASSERT(model, return);
MODEL_DEBUG("NOTHING NEEDED: " << data.toString());
- model->insertData(data);
+ m_model->insertDataItem(data);
showEditValue(data);
}
}
-void WatchHandler::reinsertAllData()
+void WatchHandler::insertData(const WatchData &data)
{
- m_locals->reinsertAllData();
- m_watchers->reinsertAllData();
- m_tooltips->reinsertAllData();
- m_return->reinsertAllData();
- m_inspect->reinsertAllData();
+ QList<WatchData> list;
+ list.append(data);
+ insertData(list);
}
-// Bulk-insertion
-void WatchHandler::insertBulkData(const QList<WatchData> &list)
+void WatchHandler::insertData(const QList<WatchData> &list)
{
-#if 1
- foreach (const WatchItem &data, list)
- insertData(data);
- return;
-#endif
-
- if (list.isEmpty())
- return;
- QMap<QByteArray, QList<WatchData> > hash;
+ m_model->insertBulkData(list);
- foreach (const WatchData &data, list) {
- // we insert everything, including incomplete stuff
- // to reduce the number of row add operations in the model.
- if (data.isValid()) {
- hash[parentName(data.iname)].append(data);
- } else {
- qWarning("%s:%d: Attempt to bulk-insert invalid watch item: %s",
- __FILE__, __LINE__, qPrintable(data.toString()));
- }
- }
- foreach (const QByteArray &parentIName, hash.keys()) {
- WatchModel *model = modelForIName(parentIName);
- QTC_ASSERT(model, return);
- model->insertBulkData(hash[parentIName]);
- }
+ m_contentsValid = true;
+ updateWatchersWindow();
+}
- foreach (const WatchData &data, list) {
- if (data.isSomethingNeeded())
- m_engine->updateWatchData(data);
- }
+void WatchHandler::removeAllData()
+{
+ m_model->reinitialize();
}
void WatchHandler::removeData(const QByteArray &iname)
{
- WatchModel *model = modelForIName(iname);
- if (!model)
- return;
- WatchItem *item = model->findItem(iname, model->m_root);
+ WatchItem *item = m_model->findItem(iname);
+ if (item)
+ m_model->destroyItem(item);
+}
+
+void WatchHandler::removeChildren(const QByteArray &iname)
+{
+ WatchItem *item = m_model->findItem(iname);
if (item)
- model->destroyItem(item);
+ m_model->destroyChildren(item);
}
QByteArray WatchHandler::watcherName(const QByteArray &exp)
@@ -1483,14 +1651,13 @@ void WatchHandler::watchExpression(const QString &exp)
data.setAllUnneeded();
data.setValue(QString(QLatin1Char(' ')));
data.setHasChildren(false);
- insertData(data);
+ insertIncompleteData(data);
} else if (m_engine->isSynchronous()) {
m_engine->updateWatchData(data);
} else {
- insertData(data);
+ insertIncompleteData(data);
}
updateWatchersWindow();
- emitAllChanged();
}
static void swapEndian(char *d, int nchar)
@@ -1509,9 +1676,9 @@ static void swapEndian(char *d, int nchar)
void WatchHandler::showEditValue(const WatchData &data)
{
const QByteArray key = data.address ? data.hexAddress() : data.iname;
- QObject *w = m_editHandlers.value(key);
+ QObject *w = m_model->m_editHandlers.value(key);
if (data.editformat == 0x0) {
- m_editHandlers.remove(data.iname);
+ m_model->m_editHandlers.remove(data.iname);
delete w;
} else if (data.editformat == 1 || data.editformat == 3) {
// QImage
@@ -1524,7 +1691,7 @@ void WatchHandler::showEditValue(const WatchData &data)
QLatin1String(data.hexAddress())) :
tr("%1 Object at Unknown Address").arg(QLatin1String(data.type));
l->setWindowTitle(title);
- m_editHandlers[key] = l;
+ m_model->m_editHandlers[key] = l;
}
int width, height, format;
QByteArray ba;
@@ -1563,7 +1730,7 @@ void WatchHandler::showEditValue(const WatchData &data)
if (!t) {
delete w;
t = new QTextEdit;
- m_editHandlers[key] = t;
+ m_model->m_editHandlers[key] = t;
}
QByteArray ba = QByteArray::fromHex(data.editvalue);
QString str = QString::fromUtf16((ushort *)ba.constData(), ba.size()/2);
@@ -1580,7 +1747,7 @@ void WatchHandler::showEditValue(const WatchData &data)
p = new QProcess;
p->start(QLatin1String(cmd));
p->waitForStarted();
- m_editHandlers[key] = p;
+ m_model->m_editHandlers[key] = p;
}
p->write(input + '\n');
} else {
@@ -1592,13 +1759,10 @@ void WatchHandler::clearWatches()
{
if (theWatcherNames.isEmpty())
return;
- const QList<WatchItem *> watches = m_watchers->rootItem()->children;
- for (int i = watches.size() - 1; i >= 0; i--)
- m_watchers->destroyItem(watches.at(i));
+ m_model->destroyChildren(m_model->m_watchRoot);
theWatcherNames.clear();
m_watcherCounter = 0;
updateWatchersWindow();
- emitAllChanged();
saveWatchers();
}
@@ -1607,12 +1771,12 @@ void WatchHandler::removeWatchExpression(const QString &exp0)
QByteArray exp = exp0.toLatin1();
MODEL_DEBUG("REMOVE WATCH: " << exp);
theWatcherNames.remove(exp);
- foreach (WatchItem *item, m_watchers->rootItem()->children) {
+
+ foreach (WatchItem *item, m_model->m_watchRoot->children) {
if (item->exp == exp) {
- m_watchers->destroyItem(item);
+ m_model->destroyItem(item);
saveWatchers();
updateWatchersWindow();
- emitAllChanged();
break;
}
}
@@ -1621,7 +1785,15 @@ void WatchHandler::removeWatchExpression(const QString &exp0)
void WatchHandler::updateWatchersWindow()
{
// Force show/hide of watchers and return view.
- debuggerCore()->updateWatchersWindow();
+ static int previousShowWatch = -1;
+ static int previousShowReturn = -1;
+ int showWatch = !m_model->m_watchRoot->children.isEmpty();
+ int showReturn = !m_model->m_returnRoot->children.isEmpty();
+ if (showWatch == previousShowWatch && showReturn == previousShowReturn)
+ return;
+ previousShowWatch = showWatch;
+ previousShowReturn = showReturn;
+ debuggerCore()->updateWatchersWindow(showWatch, showReturn);
}
QStringList WatchHandler::watchedExpressions()
@@ -1684,18 +1856,14 @@ void WatchHandler::loadSessionData()
theWatcherNames.clear();
m_watcherCounter = 0;
QVariant value = debuggerCore()->sessionValue(QLatin1String("Watchers"));
- foreach (WatchItem *item, m_watchers->rootItem()->children)
- m_watchers->destroyItem(item);
+ m_model->destroyChildren(m_model->m_watchRoot);
foreach (const QString &exp, value.toStringList())
watchExpression(exp);
- updateWatchersWindow();
- emitAllChanged();
}
void WatchHandler::updateWatchers()
{
- foreach (WatchItem *item, m_watchers->rootItem()->children)
- m_watchers->destroyItem(item);
+ m_model->destroyChildren(m_model->m_watchRoot);
// Copy over all watchers and mark all watchers as incomplete.
foreach (const QByteArray &exp, theWatcherNames.keys()) {
WatchData data;
@@ -1703,67 +1871,33 @@ void WatchHandler::updateWatchers()
data.setAllNeeded();
data.name = QLatin1String(exp);
data.exp = exp;
- insertData(data);
+ insertIncompleteData(data);
}
}
-WatchModel *WatchHandler::model(WatchType type) const
+QAbstractItemModel *WatchHandler::model() const
{
- switch (type) {
- case ReturnWatch: return m_return;
- case LocalsWatch: return m_locals;
- case WatchersWatch: return m_watchers;
- case TooltipsWatch: return m_tooltips;
- case InspectWatch: return m_inspect;
- }
- QTC_CHECK(false);
- return 0;
+ return m_model;
}
-WatchModel *WatchHandler::modelForIName(const QByteArray &iname) const
+const WatchData *WatchHandler::watchData(const QModelIndex &idx) const
{
- if (iname.startsWith("return"))
- return m_return;
- if (iname.startsWith("local"))
- return m_locals;
- if (iname.startsWith("tooltip"))
- return m_tooltips;
- if (iname.startsWith("watch"))
- return m_watchers;
- if (iname.startsWith("inspect"))
- return m_inspect;
- QTC_ASSERT(false, qDebug() << "INAME: " << iname);
- return 0;
+ return m_model->watchItem(idx);
}
-const WatchData *WatchHandler::watchData(WatchType type, const QModelIndex &index) const
+const WatchData *WatchHandler::findData(const QByteArray &iname) const
{
- if (index.isValid())
- if (const WatchModel *m = model(type))
- return m->watchItem(index);
- return 0;
-}
-
-const WatchData *WatchHandler::findItem(const QByteArray &iname) const
-{
- const WatchModel *model = modelForIName(iname);
- QTC_ASSERT(model, return 0);
- return model->findItem(iname, model->m_root);
+ return m_model->findItem(iname);
}
QString WatchHandler::displayForAutoTest(const QByteArray &iname) const
{
- const WatchModel *model = modelForIName(iname);
- QTC_ASSERT(model, return QString());
- return model->displayForAutoTest(iname);
+ return m_model->displayForAutoTest(iname);
}
-QModelIndex WatchHandler::itemIndex(const QByteArray &iname) const
+bool WatchHandler::hasItem(const QByteArray &iname) const
{
- if (const WatchModel *model = modelForIName(iname))
- if (WatchItem *item = model->findItem(iname, model->m_root))
- return model->watchIndex(item);
- return QModelIndex();
+ return m_model->findItem(iname);
}
void WatchHandler::setFormat(const QByteArray &type0, int format)
@@ -1774,17 +1908,13 @@ void WatchHandler::setFormat(const QByteArray &type0, int format)
else
theTypeFormats[type] = format;
saveTypeFormats();
- m_return->emitDataChanged(1);
- m_locals->emitDataChanged(1);
- m_watchers->emitDataChanged(1);
- m_tooltips->emitDataChanged(1);
- m_inspect->emitDataChanged(1);
+ m_model->emitDataChanged(1);
}
int WatchHandler::format(const QByteArray &iname) const
{
int result = -1;
- if (const WatchData *item = findItem(iname)) {
+ if (const WatchData *item = m_model->findItem(iname)) {
int result = theIndividualFormats.value(item->iname, -1);
if (result == -1)
result = theTypeFormats.value(stripForFormat(item->type), -1);
@@ -1795,10 +1925,9 @@ int WatchHandler::format(const QByteArray &iname) const
QByteArray WatchHandler::expansionRequests() const
{
QByteArray ba;
- //m_locals->formatRequests(&ba, m_locals->m_root);
- //m_watchers->formatRequests(&ba, m_watchers->m_root);
- if (!m_expandedINames.isEmpty()) {
- QSetIterator<QByteArray> jt(m_expandedINames);
+ m_model->formatRequests(&ba, m_model->m_root);
+ if (!m_model->m_expandedINames.isEmpty()) {
+ QSetIterator<QByteArray> jt(m_model->m_expandedINames);
while (jt.hasNext()) {
QByteArray iname = jt.next();
ba.append(iname);
@@ -1845,67 +1974,43 @@ QByteArray WatchHandler::individualFormatRequests() const
void WatchHandler::addTypeFormats(const QByteArray &type, const QStringList &formats)
{
- m_reportedTypeFormats.insert(QLatin1String(stripForFormat(type)), formats);
+ m_model->m_reportedTypeFormats.insert(QLatin1String(stripForFormat(type)), formats);
}
QString WatchHandler::editorContents()
{
QString contents;
- showInEditorHelper(&contents, m_locals->m_root, 0);
- showInEditorHelper(&contents, m_watchers->m_root, 0);
+ m_model->showInEditorHelper(&contents, m_model->m_root, 0);
return contents;
}
-void WatchHandler::showInEditorHelper(QString *contents, WatchItem *item, int depth)
-{
- const QChar tab = QLatin1Char('\t');
- const QChar nl = QLatin1Char('\n');
- contents->append(QString(depth, tab));
- contents->append(item->name);
- contents->append(tab);
- contents->append(item->value);
- contents->append(tab);
- contents->append(item->type);
- contents->append(nl);
- foreach (WatchItem *child, item->children)
- showInEditorHelper(contents, child, depth + 1);
-}
-
void WatchHandler::removeTooltip()
{
- m_tooltips->reinitialize();
- m_tooltips->emitAllChanged();
+ m_model->destroyChildren(m_model->m_tooltipRoot);
}
void WatchHandler::rebuildModel()
{
- beginCycle();
-
- const QList<WatchItem *> watches = m_watchers->rootItem()->children;
- for (int i = watches.size() - 1; i >= 0; i--)
- m_watchers->destroyItem(watches.at(i));
-
- foreach (const QString &exp, watchedExpressions()) {
- WatchData data;
- data.exp = exp.toLatin1();
- data.name = exp;
- data.iname = watcherName(data.exp);
- data.setAllUnneeded();
-
- insertData(data);
- }
+// m_model->destroyChildren(m_model->m_watchRoot);
- endCycle();
+// foreach (const QString &exp, watchedExpressions()) {
+// WatchData data;
+// data.exp = exp.toLatin1();
+// data.name = exp;
+// data.iname = watcherName(data.exp);
+// data.setAllUnneeded();
+// insertIncompleteData(data);
+// }
}
void WatchHandler::setTypeFormats(const TypeFormats &typeFormats)
{
- m_reportedTypeFormats = typeFormats;
+ m_model->m_reportedTypeFormats = typeFormats;
}
TypeFormats WatchHandler::typeFormats() const
{
- return m_reportedTypeFormats;
+ return m_model->m_reportedTypeFormats;
}
void WatchHandler::editTypeFormats(bool includeLocals, const QByteArray &iname)
@@ -1914,11 +2019,11 @@ void WatchHandler::editTypeFormats(bool includeLocals, const QByteArray &iname)
TypeFormatsDialog dlg(0);
//QHashIterator<QString, QStringList> it(m_reportedTypeFormats);
- QList<QString> l = m_reportedTypeFormats.keys();
+ QList<QString> l = m_model->m_reportedTypeFormats.keys();
qSort(l.begin(), l.end());
foreach (const QString &ba, l) {
int f = iname.isEmpty() ? -1 : format(iname);
- dlg.addTypeFormats(ba, m_reportedTypeFormats.value(ba), f);
+ dlg.addTypeFormats(ba, m_model->m_reportedTypeFormats.value(ba), f);
}
if (dlg.exec())
setTypeFormats(dlg.typeFormats());
@@ -1927,6 +2032,7 @@ void WatchHandler::editTypeFormats(bool includeLocals, const QByteArray &iname)
void WatchHandler::scheduleResetLocation()
{
m_contentsValid = false;
+ //m_contentsValid = true; // FIXME
m_resetLocationScheduled = true;
}
@@ -1934,26 +2040,19 @@ void WatchHandler::resetLocation()
{
if (m_resetLocationScheduled) {
m_resetLocationScheduled = false;
- m_return->invalidateAll();
- m_locals->invalidateAll();
- m_watchers->invalidateAll();
- m_tooltips->invalidateAll();
- m_inspect->invalidateAll();
+ //m_model->invalidateAll(); FIXME
}
}
bool WatchHandler::isValidToolTip(const QByteArray &iname) const
{
- WatchItem *item = m_tooltips->findItem(iname, m_tooltips->m_root);
+ WatchItem *item = m_model->findItem(iname);
return item && !item->type.trimmed().isEmpty();
}
-void WatchHandler::setCurrentModelIndex(WatchType modelType,
- const QModelIndex &index)
+void WatchHandler::setCurrentItem(const QByteArray &iname)
{
- if (WatchModel *m = model(modelType)) {
- emit m->setCurrentIndex(index);
- }
+ m_model->setCurrentItem(iname);
}
QHash<QByteArray, int> WatchHandler::watcherNames()
@@ -1961,5 +2060,28 @@ QHash<QByteArray, int> WatchHandler::watcherNames()
return theWatcherNames;
}
+void WatchHandler::setUnprintableBase(int base)
+{
+ theUnprintableBase = base;
+ m_model->emitAllChanged();
+}
+
+int WatchHandler::unprintableBase()
+{
+ return theUnprintableBase;
+}
+
+bool WatchHandler::isExpandedIName(const QByteArray &iname) const
+{
+ return m_model->m_expandedINames.contains(iname);
+}
+
+QSet<QByteArray> WatchHandler::expandedINames() const
+{
+ return m_model->m_expandedINames;
+}
+
} // namespace Internal
} // namespace Debugger
+
+#include "watchhandler.moc"