Debugger: Some infrastructure for stricter watch model testing

Targeting re-use for tooltips, and potentially sorting.

Change-Id: I1ce8f4da73ab5ca13cd70d7c651bc76c67f91a39
Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
hjk
2014-06-02 10:43:26 +02:00
parent c3cb944eec
commit 99271c2343
8 changed files with 67 additions and 19 deletions

View File

@@ -136,6 +136,8 @@ void BaseTreeView::resizeColumnsToContents()
void BaseTreeView::setAlwaysResizeColumnsToContents(bool on) void BaseTreeView::setAlwaysResizeColumnsToContents(bool on)
{ {
if (!header())
return;
QHeaderView::ResizeMode mode = on QHeaderView::ResizeMode mode = on
? QHeaderView::ResizeToContents : QHeaderView::Interactive; ? QHeaderView::ResizeToContents : QHeaderView::Interactive;
for (int i = 0, n = header()->count(); i != n; ++i) for (int i = 0, n = header()->count(); i != n; ++i)

View File

@@ -2758,13 +2758,13 @@ void DebuggerPluginPrivate::extensionsInitialized()
m_sourceFilesWindow->setObjectName(QLatin1String(DOCKWIDGET_SOURCE_FILES)); m_sourceFilesWindow->setObjectName(QLatin1String(DOCKWIDGET_SOURCE_FILES));
m_threadsWindow = new ThreadsWindow; m_threadsWindow = new ThreadsWindow;
m_threadsWindow->setObjectName(QLatin1String(DOCKWIDGET_THREADS)); m_threadsWindow->setObjectName(QLatin1String(DOCKWIDGET_THREADS));
m_returnWindow = new WatchWindow(WatchTreeView::ReturnType); m_returnWindow = new WatchWindow(ReturnType);
m_returnWindow->setObjectName(QLatin1String("CppDebugReturn")); m_returnWindow->setObjectName(QLatin1String("CppDebugReturn"));
m_localsWindow = new WatchWindow(WatchTreeView::LocalsType); m_localsWindow = new WatchWindow(LocalsType);
m_localsWindow->setObjectName(QLatin1String("CppDebugLocals")); m_localsWindow->setObjectName(QLatin1String("CppDebugLocals"));
m_watchersWindow = new WatchWindow(WatchTreeView::WatchersType); m_watchersWindow = new WatchWindow(WatchersType);
m_watchersWindow->setObjectName(QLatin1String("CppDebugWatchers")); m_watchersWindow->setObjectName(QLatin1String("CppDebugWatchers"));
m_inspectorWindow = new WatchWindow(WatchTreeView::InspectType); m_inspectorWindow = new WatchWindow(InspectType);
m_inspectorWindow->setObjectName(QLatin1String("Inspector")); m_inspectorWindow->setObjectName(QLatin1String("Inspector"));
// Snapshot // Snapshot

View File

@@ -652,7 +652,7 @@ void QmlInspectorAgent::verifyAndInsertObjectInTree(const ObjectReference &objec
QByteArray parentIname = m_debugIdToIname.value(parentId); QByteArray parentIname = m_debugIdToIname.value(parentId);
if (parentId != -1 && !handler->isExpandedIName(parentIname)) { if (parentId != -1 && !handler->isExpandedIName(parentIname)) {
m_objectStack.push(object); m_objectStack.push(object);
handler->model()->fetchMore(handler->watchDataIndex(parentIname)); handler->fetchMore(parentIname);
return; // recursive return; // recursive
} }
insertObjectInTree(object); insertObjectInTree(object);
@@ -669,7 +669,7 @@ void QmlInspectorAgent::verifyAndInsertObjectInTree(const ObjectReference &objec
if (object.children().contains(top)) { if (object.children().contains(top)) {
QByteArray objectIname = m_debugIdToIname.value(objectDebugId); QByteArray objectIname = m_debugIdToIname.value(objectDebugId);
if (!handler->isExpandedIName(objectIname)) { if (!handler->isExpandedIName(objectIname)) {
handler->model()->fetchMore(handler->watchDataIndex(objectIname)); handler->fetchMore(objectIname);
} else { } else {
verifyAndInsertObjectInTree(m_objectStack.pop()); verifyAndInsertObjectInTree(m_objectStack.pop());
return; // recursive return; // recursive

View File

@@ -132,7 +132,7 @@ private:
friend void itemDestructor(WatchModel *model, WatchItem *item); friend void itemDestructor(WatchModel *model, WatchItem *item);
WatchItem() { parent = 0; } WatchItem() { parent = 0; }
~WatchItem() {} ~WatchItem() { parent = 0; }
WatchItem(const WatchItem &); // Not implemented. WatchItem(const WatchItem &); // Not implemented.
}; };
@@ -331,6 +331,7 @@ private:
void checkItem(const WatchItem *item) const; void checkItem(const WatchItem *item) const;
void checkTree(WatchItem *item, QSet<QByteArray> *inames); void checkTree(WatchItem *item, QSet<QByteArray> *inames);
#endif #endif
void checkIndex(const QModelIndex &index) const;
}; };
WatchModel::WatchModel(WatchHandler *handler) WatchModel::WatchModel(WatchHandler *handler)
@@ -454,6 +455,7 @@ void WatchModel::destroyItem(WatchItem *item)
WatchItem *parent = item->parent; WatchItem *parent = item->parent;
QTC_ASSERT(parent, return); QTC_ASSERT(parent, return);
QModelIndex parentIndex = watchIndex(parent); QModelIndex parentIndex = watchIndex(parent);
checkIndex(parentIndex);
const int i = parent->children.indexOf(item); const int i = parent->children.indexOf(item);
//MODEL_DEBUG("NEED TO REMOVE: " << item->iname << "AT" << n); //MODEL_DEBUG("NEED TO REMOVE: " << item->iname << "AT" << n);
beginRemoveRows(parentIndex, i, i); beginRemoveRows(parentIndex, i, i);
@@ -479,6 +481,7 @@ void WatchModel::destroyChildren(WatchItem *item)
// Deregister from model and parent. // Deregister from model and parent.
// It's sufficient to do this non-recursively. // It's sufficient to do this non-recursively.
QModelIndex idx = watchIndex(item); QModelIndex idx = watchIndex(item);
checkIndex(idx);
beginRemoveRows(idx, 0, items.size() - 1); beginRemoveRows(idx, 0, items.size() - 1);
item->children.clear(); item->children.clear();
endRemoveRows(); endRemoveRows();
@@ -493,6 +496,11 @@ WatchItem *WatchModel::findItem(const QByteArray &iname) const
return m_cache.value(iname, 0); return m_cache.value(iname, 0);
} }
void WatchModel::checkIndex(const QModelIndex &index) const
{
QTC_CHECK(index.isValid() ? index.model() == this : index.model() == 0);
}
WatchItem *WatchModel::createItem(const WatchData &data) WatchItem *WatchModel::createItem(const WatchData &data)
{ {
WatchItem *item = itemConstructor(this, data.iname); WatchItem *item = itemConstructor(this, data.iname);
@@ -837,6 +845,7 @@ bool WatchModel::canFetchMore(const QModelIndex &idx) const
void WatchModel::fetchMore(const QModelIndex &idx) void WatchModel::fetchMore(const QModelIndex &idx)
{ {
checkIndex(idx);
if (!idx.isValid()) if (!idx.isValid())
return; // Triggered by ModelTester. return; // Triggered by ModelTester.
WatchItem *item = watchItem(idx); WatchItem *item = watchItem(idx);
@@ -855,6 +864,7 @@ void WatchModel::fetchMore(const QModelIndex &idx)
QModelIndex WatchModel::index(int row, int column, const QModelIndex &parent) const QModelIndex WatchModel::index(int row, int column, const QModelIndex &parent) const
{ {
checkIndex(parent);
if (!hasIndex(row, column, parent)) if (!hasIndex(row, column, parent))
return QModelIndex(); return QModelIndex();
@@ -867,6 +877,7 @@ QModelIndex WatchModel::index(int row, int column, const QModelIndex &parent) co
QModelIndex WatchModel::parent(const QModelIndex &idx) const QModelIndex WatchModel::parent(const QModelIndex &idx) const
{ {
checkIndex(idx);
if (!idx.isValid()) if (!idx.isValid())
return QModelIndex(); return QModelIndex();
@@ -889,6 +900,7 @@ QModelIndex WatchModel::parent(const QModelIndex &idx) const
int WatchModel::rowCount(const QModelIndex &idx) const int WatchModel::rowCount(const QModelIndex &idx) const
{ {
checkIndex(idx);
if (!idx.isValid()) if (!idx.isValid())
return m_root->children.size(); return m_root->children.size();
if (idx.column() > 0) if (idx.column() > 0)
@@ -898,18 +910,20 @@ int WatchModel::rowCount(const QModelIndex &idx) const
int WatchModel::columnCount(const QModelIndex &idx) const int WatchModel::columnCount(const QModelIndex &idx) const
{ {
Q_UNUSED(idx) checkIndex(idx);
return 3; return 3;
} }
bool WatchModel::hasChildren(const QModelIndex &parent) const bool WatchModel::hasChildren(const QModelIndex &parent) const
{ {
checkIndex(parent);
WatchItem *item = watchItem(parent); WatchItem *item = watchItem(parent);
return !item || item->hasChildren; return !item || item->hasChildren;
} }
WatchItem *WatchModel::watchItem(const QModelIndex &idx) const WatchItem *WatchModel::watchItem(const QModelIndex &idx) const
{ {
checkIndex(idx);
WatchItem *item = idx.isValid() WatchItem *item = idx.isValid()
? static_cast<WatchItem*>(idx.internalPointer()) : m_root; ? static_cast<WatchItem*>(idx.internalPointer()) : m_root;
CHECK(checkItem(item)); CHECK(checkItem(item));
@@ -925,12 +939,14 @@ QModelIndex WatchModel::watchIndex(const WatchItem *item) const
QModelIndex WatchModel::watchIndexHelper(const WatchItem *needle, QModelIndex WatchModel::watchIndexHelper(const WatchItem *needle,
const WatchItem *parentItem, const QModelIndex &parentIndex) const const WatchItem *parentItem, const QModelIndex &parentIndex) const
{ {
checkIndex(parentIndex);
if (needle == parentItem) if (needle == parentItem)
return parentIndex; return parentIndex;
for (int i = parentItem->children.size(); --i >= 0; ) { for (int i = parentItem->children.size(); --i >= 0; ) {
const WatchItem *childItem = parentItem->children.at(i); const WatchItem *childItem = parentItem->children.at(i);
QModelIndex childIndex = index(i, 0, parentIndex); QModelIndex childIndex = index(i, 0, parentIndex);
QModelIndex idx = watchIndexHelper(needle, childItem, childIndex); QModelIndex idx = watchIndexHelper(needle, childItem, childIndex);
checkIndex(idx);
if (idx.isValid()) if (idx.isValid())
return idx; return idx;
} }
@@ -939,20 +955,26 @@ QModelIndex WatchModel::watchIndexHelper(const WatchItem *needle,
void WatchModel::emitDataChanged(int column, const QModelIndex &parentIndex) void WatchModel::emitDataChanged(int column, const QModelIndex &parentIndex)
{ {
checkIndex(parentIndex);
QModelIndex idx1 = index(0, column, parentIndex); QModelIndex idx1 = index(0, column, parentIndex);
QModelIndex idx2 = index(rowCount(parentIndex) - 1, column, parentIndex); QModelIndex idx2 = index(rowCount(parentIndex) - 1, column, parentIndex);
if (idx1.isValid() && idx2.isValid()) if (idx1.isValid() && idx2.isValid())
emit dataChanged(idx1, idx2); emit dataChanged(idx1, idx2);
//qDebug() << "CHANGING:\n" << idx1 << "\n" << idx2 << "\n" //qDebug() << "CHANGING:\n" << idx1 << "\n" << idx2 << "\n"
// << data(parentIndex, INameRole).toString(); // << data(parentIndex, INameRole).toString();
checkIndex(idx1);
checkIndex(idx2);
for (int i = rowCount(parentIndex); --i >= 0; ) for (int i = rowCount(parentIndex); --i >= 0; )
emitDataChanged(column, index(i, 0, parentIndex)); emitDataChanged(column, index(i, 0, parentIndex));
} }
void WatchModel::invalidateAll(const QModelIndex &parentIndex) void WatchModel::invalidateAll(const QModelIndex &parentIndex)
{ {
checkIndex(parentIndex);
QModelIndex idx1 = index(0, 0, parentIndex); QModelIndex idx1 = index(0, 0, parentIndex);
QModelIndex idx2 = index(rowCount(parentIndex) - 1, columnCount(parentIndex) - 1, parentIndex); QModelIndex idx2 = index(rowCount(parentIndex) - 1, columnCount(parentIndex) - 1, parentIndex);
checkIndex(idx1);
checkIndex(idx2);
if (idx1.isValid() && idx2.isValid()) if (idx1.isValid() && idx2.isValid())
emit dataChanged(idx1, idx2); emit dataChanged(idx1, idx2);
} }
@@ -1074,6 +1096,7 @@ QString WatchModel::displayType(const WatchData &data) const
QVariant WatchModel::data(const QModelIndex &idx, int role) const QVariant WatchModel::data(const QModelIndex &idx, int role) const
{ {
checkIndex(idx);
if (!idx.isValid()) if (!idx.isValid())
return QVariant(); // Triggered by ModelTester. return QVariant(); // Triggered by ModelTester.
@@ -1198,6 +1221,8 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role) bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role)
{ {
checkIndex(idx);
if (!idx.isValid()) if (!idx.isValid())
return false; // Triggered by ModelTester. return false; // Triggered by ModelTester.
@@ -1247,10 +1272,13 @@ bool WatchModel::setData(const QModelIndex &idx, const QVariant &value, int role
Qt::ItemFlags WatchModel::flags(const QModelIndex &idx) const Qt::ItemFlags WatchModel::flags(const QModelIndex &idx) const
{ {
checkIndex(idx);
if (!idx.isValid()) if (!idx.isValid())
return Qt::ItemFlags(); return Qt::ItemFlags();
const WatchData &data = *watchItem(idx); WatchItem *item = watchItem(idx);
QTC_ASSERT(item, return Qt::ItemFlags());
const WatchData &data = *item;
if (!contentIsValid() && !data.isInspect()) if (!contentIsValid() && !data.isInspect())
return Qt::ItemFlags(); return Qt::ItemFlags();
@@ -1476,6 +1504,7 @@ void WatchModel::insertDataItem(const WatchData &data, bool destructive)
// Overwrite old entry. // Overwrite old entry.
assignData(item, data); assignData(item, data);
QModelIndex idx = watchIndex(item); QModelIndex idx = watchIndex(item);
checkIndex(idx);
emit dataChanged(idx, idx.sibling(idx.row(), 2)); emit dataChanged(idx, idx.sibling(idx.row(), 2));
} else { } else {
// Add new entry. // Add new entry.
@@ -1485,6 +1514,7 @@ void WatchModel::insertDataItem(const WatchData &data, bool destructive)
newItem->parent = parent; newItem->parent = parent;
const int row = findInsertPosition(parent->children, newItem); const int row = findInsertPosition(parent->children, newItem);
QModelIndex idx = watchIndex(parent); QModelIndex idx = watchIndex(parent);
checkIndex(idx);
beginInsertRows(idx, row, row); beginInsertRows(idx, row, row);
parent->children.insert(row, newItem); parent->children.insert(row, newItem);
endInsertRows(); endInsertRows();
@@ -1583,6 +1613,7 @@ void WatchModel::setCurrentItem(const QByteArray &iname)
{ {
if (WatchItem *item = findItem(iname)) { if (WatchItem *item = findItem(iname)) {
QModelIndex idx = watchIndex(item); QModelIndex idx = watchIndex(item);
checkIndex(idx);
emit currentIndexRequested(idx); emit currentIndexRequested(idx);
} }
} }
@@ -1951,9 +1982,11 @@ const WatchData *WatchHandler::watchData(const QModelIndex &idx) const
return m_model->watchItem(idx); return m_model->watchItem(idx);
} }
const QModelIndex WatchHandler::watchDataIndex(const QByteArray &iname) const void WatchHandler::fetchMore(const QByteArray &iname) const
{ {
return m_model->watchIndex(m_model->findItem(iname)); QModelIndex idx = m_model->watchIndex(m_model->findItem(iname));
m_model->checkIndex(idx);
model()->fetchMore(idx);
} }
const WatchData *WatchHandler::findData(const QByteArray &iname) const const WatchData *WatchHandler::findData(const QByteArray &iname) const

View File

@@ -143,7 +143,7 @@ public:
void showEditValue(const WatchData &data); void showEditValue(const WatchData &data);
const WatchData *watchData(const QModelIndex &) const; const WatchData *watchData(const QModelIndex &) const;
const QModelIndex watchDataIndex(const QByteArray &iname) const; void fetchMore(const QByteArray &iname) const;
const WatchData *findData(const QByteArray &iname) const; const WatchData *findData(const QByteArray &iname) const;
const WatchData *findCppLocalVariable(const QString &name) const; const WatchData *findCppLocalVariable(const QString &name) const;
bool hasItem(const QByteArray &iname) const; bool hasItem(const QByteArray &iname) const;

View File

@@ -59,6 +59,12 @@
#include <QInputDialog> #include <QInputDialog>
#include <QMessageBox> #include <QMessageBox>
//#define USE_WATCH_MODEL_TEST 1
#if USE_WATCH_MODEL_TEST
#include <modeltest.h>
#endif
Q_DECLARE_METATYPE(QModelIndex) Q_DECLARE_METATYPE(QModelIndex)
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
@@ -464,7 +470,7 @@ static void addStackLayoutMemoryView(DebuggerEngine *engine, bool separateView,
// //
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
WatchTreeView::WatchTreeView(Type type, QWidget *parent) WatchTreeView::WatchTreeView(WatchType type, QWidget *parent)
: BaseTreeView(parent), : BaseTreeView(parent),
m_type(type) m_type(type)
{ {
@@ -999,11 +1005,14 @@ void WatchTreeView::setModel(QAbstractItemModel *model)
SLOT(setCurrentIndex(QModelIndex))); SLOT(setCurrentIndex(QModelIndex)));
connect(model, SIGNAL(itemIsExpanded(QModelIndex)), connect(model, SIGNAL(itemIsExpanded(QModelIndex)),
SLOT(handleItemIsExpanded(QModelIndex))); SLOT(handleItemIsExpanded(QModelIndex)));
#if USE_WATCH_MODEL_TEST
(void) new ModelTest(&m_filter, this);
#endif
} }
void WatchTreeView::rowActivated(const QModelIndex &index) void WatchTreeView::rowActivated(const QModelIndex &index)
{ {
currentEngine()->watchDataSelected(currentEngine()->watchHandler()->watchData(index)->iname); currentEngine()->watchDataSelected(index.data(LocalsINameRole).toByteArray());
} }
void WatchTreeView::handleItemIsExpanded(const QModelIndex &idx) void WatchTreeView::handleItemIsExpanded(const QModelIndex &idx)

View File

@@ -41,15 +41,16 @@ namespace Internal {
// //
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
enum WatchType { LocalsType, InspectType, WatchersType, ReturnType, TooltipType };
class WatchTreeView : public BaseTreeView class WatchTreeView : public BaseTreeView
{ {
Q_OBJECT Q_OBJECT
public: public:
enum Type { LocalsType, InspectType, WatchersType, ReturnType, TooltipType };
explicit WatchTreeView(Type type, QWidget *parent = 0); explicit WatchTreeView(WatchType type, QWidget *parent = 0);
Type type() const { return m_type; } WatchType type() const { return m_type; }
void setModel(QAbstractItemModel *model); void setModel(QAbstractItemModel *model);
void rowActivated(const QModelIndex &index); void rowActivated(const QModelIndex &index);
void reset(); void reset();
@@ -92,7 +93,7 @@ private:
void setModelData(int role, const QVariant &value = QVariant(), void setModelData(int role, const QVariant &value = QVariant(),
const QModelIndex &index = QModelIndex()); const QModelIndex &index = QModelIndex());
Type m_type; WatchType m_type;
bool m_grabbing; bool m_grabbing;
}; };
@@ -101,7 +102,7 @@ class WatchWindow : public BaseWindow
Q_OBJECT Q_OBJECT
public: public:
explicit WatchWindow(WatchTreeView::Type type) explicit WatchWindow(WatchType type)
: BaseWindow(new WatchTreeView(type)) : BaseWindow(new WatchTreeView(type))
{ {
setWindowTitle(tr("Locals and Expressions")); setWindowTitle(tr("Locals and Expressions"));

View File

@@ -119,6 +119,9 @@ void ModelTest::nonDestructiveBasicTest()
QVariant cache; QVariant cache;
model->match(QModelIndex(), -1, cache); model->match(QModelIndex(), -1, cache);
model->mimeTypes(); model->mimeTypes();
QModelIndex m1 = model->parent(QModelIndex());
QModelIndex m2 = QModelIndex();
Q_ASSERT(m1 == m2);
Q_ASSERT(model->parent(QModelIndex()) == QModelIndex()); Q_ASSERT(model->parent(QModelIndex()) == QModelIndex());
Q_ASSERT(model->rowCount() >= 0); Q_ASSERT(model->rowCount() >= 0);
QVariant variant; QVariant variant;