summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/qtcreator/gdbmacros/gdbmacros.cpp110
-rw-r--r--src/plugins/debugger/debuggeroutputwindow.cpp4
-rw-r--r--src/plugins/debugger/gdb/gdbengine.cpp5
-rw-r--r--src/plugins/debugger/watchutils.cpp18
-rw-r--r--src/plugins/debugger/watchutils.h1
-rw-r--r--tests/manual/gdbdebugger/simple/app.cpp17
6 files changed, 143 insertions, 12 deletions
diff --git a/share/qtcreator/gdbmacros/gdbmacros.cpp b/share/qtcreator/gdbmacros/gdbmacros.cpp
index 5f75cc8997..1bf767002b 100644
--- a/share/qtcreator/gdbmacros/gdbmacros.cpp
+++ b/share/qtcreator/gdbmacros/gdbmacros.cpp
@@ -851,6 +851,102 @@ static void qDumpInnerValueOrPointer(QDumper &d,
//////////////////////////////////////////////////////////////////////////////
+struct ModelIndex { int r; int c; void *p; void *m; };
+
+static void qDumpQAbstractItem(QDumper &d)
+{
+ ModelIndex mm;
+ mm.r = mm.c = 0;
+ mm.p = mm.m = 0;
+ sscanf(d.templateParameters[0], "%d,%d,%p,%p", &mm.r, &mm.c, &mm.p, &mm.m);
+ const QModelIndex &mi(*reinterpret_cast<QModelIndex *>(&mm));
+ const QAbstractItemModel *m = mi.model();
+ const int rowCount = m->rowCount(mi);
+ if (rowCount < 0)
+ return;
+ const int columnCount = m->columnCount(mi);
+ if (columnCount < 0)
+ return;
+ P(d, "type", NS"QAbstractItem");
+ P(d, "addr", "$" << mm.r << "," << mm.c << "," << mm.p << "," << mm.m);
+ //P(d, "value", "(" << rowCount << "," << columnCount << ")");
+ P(d, "value", m->data(mi, Qt::DisplayRole).toString());
+ P(d, "valueencoded", "2");
+ P(d, "numchild", "1");
+ if (d.dumpChildren) {
+ d << ",children=[";
+ for (int row = 0; row < rowCount; ++row) {
+ for (int column = 0; column < columnCount; ++column) {
+ QModelIndex child = m->index(row, column, mi);
+ d.beginHash();
+ P(d, "name", "[" << row << "," << column << "]");
+ //P(d, "numchild", (m->hasChildren(child) ? "1" : "0"));
+ P(d, "numchild", "1");
+ P(d, "addr", "$" << child.row() << "," << child.column() << ","
+ << child.internalPointer() << "," << child.model());
+ P(d, "type", NS"QAbstractItem");
+ P(d, "value", m->data(mi, Qt::DisplayRole).toString());
+ P(d, "valueencoded", "2");
+ d.endHash();
+ }
+ }
+ d.beginHash();
+ P(d, "name", "DisplayRole");
+ P(d, "numchild", 0);
+ P(d, "value", m->data(mi, Qt::DisplayRole).toString());
+ P(d, "valueencoded", 2);
+ P(d, "type", NS"QString");
+ d.endHash();
+ d << "]";
+ }
+ d.disarm();
+}
+
+static void qDumpQAbstractItemModel(QDumper &d)
+{
+ const QAbstractItemModel &m = *reinterpret_cast<const QAbstractItemModel *>(d.data);
+
+ const int rowCount = m.rowCount();
+ if (rowCount < 0)
+ return;
+ const int columnCount = m.columnCount();
+ if (columnCount < 0)
+ return;
+
+ P(d, "type", NS"QAbstractItemModel");
+ P(d, "value", "(" << rowCount << "," << columnCount << ")");
+ P(d, "numchild", "1");
+ if (d.dumpChildren) {
+ d << ",children=[";
+ d.beginHash();
+ P(d, "numchild", "1");
+ P(d, "name", NS"QObject");
+ P(d, "addr", d.data);
+ P(d, "value", m.objectName());
+ P(d, "valueencoded", "2");
+ P(d, "type", NS"QObject");
+ P(d, "displayedtype", m.metaObject()->className());
+ d.endHash();
+ for (int row = 0; row < rowCount; ++row) {
+ for (int column = 0; column < columnCount; ++column) {
+ QModelIndex mi = m.index(row, column);
+ d.beginHash();
+ P(d, "name", "[" << row << "," << column << "]");
+ P(d, "value", m.data(mi, Qt::DisplayRole).toString());
+ P(d, "valueencoded", "2");
+ //P(d, "numchild", (m.hasChildren(mi) ? "1" : "0"));
+ P(d, "numchild", "1");
+ P(d, "addr", "$" << mi.row() << "," << mi.column() << ","
+ << mi.internalPointer() << "," << mi.model());
+ P(d, "type", NS"QAbstractItem");
+ d.endHash();
+ }
+ }
+ d << "]";
+ }
+ d.disarm();
+}
+
static void qDumpQByteArray(QDumper &d)
{
const QByteArray &ba = *reinterpret_cast<const QByteArray *>(d.data);
@@ -1210,7 +1306,7 @@ static void qDumpQImage(QDumper &d)
if (d.dumpChildren) {
d << ",children=[";
d.beginHash();
- P(d, "name", "key");
+ P(d, "name", "data");
P(d, "type", NS "QImageData");
P(d, "addr", d.data);
d.endHash();
@@ -2533,7 +2629,8 @@ static void handleProtocolVersion2and3(QDumper & d)
d.setupTemplateParameters();
P(d, "iname", d.iname);
- P(d, "addr", d.data);
+ if (d.data)
+ P(d, "addr", d.data);
#ifdef QT_NO_QDATASTREAM
if (d.protocolVersion == 3) {
@@ -2555,6 +2652,12 @@ static void handleProtocolVersion2and3(QDumper & d)
if (isEqual(type, "map"))
qDumpStdMap(d);
break;
+ case 'A':
+ if (isEqual(type, "QAbstractItemModel"))
+ qDumpQAbstractItemModel(d);
+ else if (isEqual(type, "QAbstractItem"))
+ qDumpQAbstractItem(d);
+ break;
case 'B':
if (isEqual(type, "QByteArray"))
qDumpQByteArray(d);
@@ -2715,6 +2818,8 @@ void *qDumpObjectData440(
// They are mentioned here nevertheless. For types that are not listed
// here, dumpers won't be used.
d << "dumpers=["
+ "\""NS"QAbstractItem\","
+ "\""NS"QAbstractItemModel\","
"\""NS"QByteArray\","
"\""NS"QDateTime\","
"\""NS"QDir\","
@@ -2810,7 +2915,6 @@ void *qDumpObjectData440(
d.iname = inbuffer; while (*inbuffer) ++inbuffer; ++inbuffer;
d.exp = inbuffer; while (*inbuffer) ++inbuffer; ++inbuffer;
d.innertype = inbuffer; while (*inbuffer) ++inbuffer; ++inbuffer;
- d.iname = inbuffer; while (*inbuffer) ++inbuffer; ++inbuffer;
handleProtocolVersion2and3(d);
}
diff --git a/src/plugins/debugger/debuggeroutputwindow.cpp b/src/plugins/debugger/debuggeroutputwindow.cpp
index d50536e7ca..9c51a5300c 100644
--- a/src/plugins/debugger/debuggeroutputwindow.cpp
+++ b/src/plugins/debugger/debuggeroutputwindow.cpp
@@ -252,8 +252,8 @@ void DebuggerOutputWindow::showOutput(const QString &prefix, const QString &outp
foreach (QString line, output.split("\n")) {
// FIXME: QTextEdit asserts on really long lines...
const int n = 3000;
- //if (line.size() > n)
- // line = line.left(n) + " [...] <cut off>";
+ if (line.size() > n)
+ line = line.left(n) + " [...] <cut off>";
m_combinedText->appendPlainText(prefix + line);
}
QTextCursor cursor = m_combinedText->textCursor();
diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp
index b0a62981b5..770586af68 100644
--- a/src/plugins/debugger/gdb/gdbengine.cpp
+++ b/src/plugins/debugger/gdb/gdbengine.cpp
@@ -2813,7 +2813,7 @@ static void setWatchDataAddress(WatchData &data, const GdbMi &mi)
{
if (mi.isValid()) {
data.addr = _(mi.data());
- if (data.exp.isEmpty())
+ if (data.exp.isEmpty() && !data.addr.startsWith(_("$")))
data.exp = _("(*(") + gdbQuoteTypes(data.type) + _("*)") + data.addr + _c(')');
}
}
@@ -2885,7 +2885,6 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
return;
}
WatchData data = data0;
- QTC_ASSERT(!data.exp.isEmpty(), return);
QByteArray params;
QStringList extraArgs;
@@ -2900,6 +2899,8 @@ void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
QString addr;
if (data.addr.startsWith(__("0x")))
addr = _("(void*)") + data.addr;
+ else if (data.exp.isEmpty()) // happens e.g. for QAbstractItem
+ addr = _("0");
else
addr = _("&(") + data.exp + _c(')');
diff --git a/src/plugins/debugger/watchutils.cpp b/src/plugins/debugger/watchutils.cpp
index f074ee2ddc..887d0c7fa8 100644
--- a/src/plugins/debugger/watchutils.cpp
+++ b/src/plugins/debugger/watchutils.cpp
@@ -658,6 +658,7 @@ QtDumperHelper::Type QtDumperHelper::specialType(QString s)
if (s.startsWith(QLatin1String("std::")))
return stdType(s.mid(5));
// Strip namespace
+ // FIXME: that's not a good idea as it makes all namespaces equal.
const int namespaceIndex = s.lastIndexOf(QLatin1String("::"));
if (namespaceIndex == -1) {
// None ... check for std..
@@ -665,7 +666,7 @@ QtDumperHelper::Type QtDumperHelper::specialType(QString s)
if (sType != UnknownType)
return sType;
} else {
- s.remove(namespaceIndex + 2);
+ s = s.mid(namespaceIndex + 2);
}
if (s == QLatin1String("QObject"))
return QObjectType;
@@ -677,6 +678,8 @@ QtDumperHelper::Type QtDumperHelper::specialType(QString s)
return QObjectSignalType;
if (s == QLatin1String("QVector"))
return QVectorType;
+ if (s == QLatin1String("QAbstractItem"))
+ return QAbstractItemType;
if (s == QLatin1String("QMap"))
return QMapType;
if (s == QLatin1String("QMultiMap"))
@@ -689,6 +692,7 @@ QtDumperHelper::Type QtDumperHelper::specialType(QString s)
bool QtDumperHelper::needsExpressionSyntax(Type t)
{
switch (t) {
+ case QAbstractItemType:
case QObjectSlotType:
case QObjectSignalType:
case QMapType:
@@ -1058,6 +1062,7 @@ void QtDumperHelper::addSize(const QString &name, int size)
break;
}
if (name == QLatin1String("std::wstring")) {
+ // FIXME: check space between > > below?
m_sizeCache.insert(QLatin1String("std::basic_string<unsigned short,std::char_traits<unsignedshort>,std::allocator<unsignedshort> >"), size);
break;
}
@@ -1078,7 +1083,7 @@ QtDumperHelper::TypeData QtDumperHelper::typeData(const QString &typeName) const
const Type st = simpleType(typeName);
if (st != UnknownType) {
td.isTemplate = false;
- td.type =st;
+ td.type = st;
return td;
}
// Try template
@@ -1129,6 +1134,8 @@ void QtDumperHelper::evaluationParameters(const WatchData &data,
if (outertype == m_qtNamespace + QLatin1String("QWidget"))
outertype = m_qtNamespace + QLatin1String("QObject");
+ QString inner = td.inner;
+
extraArgs.clear();
if (!inners.empty()) {
@@ -1147,6 +1154,9 @@ void QtDumperHelper::evaluationParameters(const WatchData &data,
// in rare cases we need more or less:
switch (td.type) {
+ case QAbstractItemType:
+ inner = data.addr.mid(1);
+ break;
case QObjectType:
case QWidgetType:
if (debugger == GdbDebugger) {
@@ -1258,9 +1268,7 @@ void QtDumperHelper::evaluationParameters(const WatchData &data,
inBuffer->append('\0');
inBuffer->append(data.exp.toUtf8());
inBuffer->append('\0');
- inBuffer->append(td.inner.toUtf8());
- inBuffer->append('\0');
- inBuffer->append(data.iname.toUtf8());
+ inBuffer->append(inner.toUtf8());
inBuffer->append('\0');
if (debug)
diff --git a/src/plugins/debugger/watchutils.h b/src/plugins/debugger/watchutils.h
index e87b3cd822..2b8ef865ba 100644
--- a/src/plugins/debugger/watchutils.h
+++ b/src/plugins/debugger/watchutils.h
@@ -145,6 +145,7 @@ public:
UnknownType,
SupportedType, // A type that requires no special handling by the dumper
// Below types require special handling
+ QAbstractItemType,
QObjectType, QWidgetType, QObjectSlotType, QObjectSignalType,
QVectorType, QMapType, QMultiMapType, QMapNodeType,
StdVectorType, StdDequeType, StdSetType, StdMapType, StdStackType,
diff --git a/tests/manual/gdbdebugger/simple/app.cpp b/tests/manual/gdbdebugger/simple/app.cpp
index de12a5474c..349055c3b2 100644
--- a/tests/manual/gdbdebugger/simple/app.cpp
+++ b/tests/manual/gdbdebugger/simple/app.cpp
@@ -48,6 +48,7 @@
#include <QtGui/QLabel>
#include <QtGui/QPainter>
#include <QtGui/QPainterPath>
+#include <QtGui/QStandardItemModel>
#include <QtNetwork/QHostAddress>
@@ -787,6 +788,21 @@ void testStdVector()
vec.push_back(false);
}
+void testQStandardItemModel()
+{
+ QStandardItemModel m;
+ QStandardItem *i1, *i2, *i11;
+ m.appendRow(QList<QStandardItem *>()
+ << (i1 = new QStandardItem("1")) << (new QStandardItem("a")));
+ m.appendRow(QList<QStandardItem *>()
+ << (i2 = new QStandardItem("2")) << (new QStandardItem("b")));
+ i1->appendRow(QList<QStandardItem *>()
+ << (i11 = new QStandardItem("11")) << (new QStandardItem("aa")));
+ int i = 1;
+ ++i;
+ ++i;
+}
+
void testQString()
{
QString str = "Hello ";
@@ -1090,6 +1106,7 @@ int main(int argc, char *argv[])
QStringList list;
list << "aaa" << "bbb" << "cc";
+ testQStandardItemModel();
testQImage();
testNoArgumentName(1, 2, 3);
testIO();