diff --git a/addons/gdbplugin/localsview.cpp b/addons/gdbplugin/localsview.cpp index 4cfe6752b..e0b821dbe 100644 --- a/addons/gdbplugin/localsview.cpp +++ b/addons/gdbplugin/localsview.cpp @@ -1,264 +1,269 @@ // // Description: Widget that local variables of the gdb inferior // // Copyright (c) 2010 Kåre Särs // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public // License version 2 as published by the Free Software Foundation. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Library General Public License for more details. // // You should have received a copy of the GNU Library General Public License // along with this library; see the file COPYING.LIB. If not, write to // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, // Boston, MA 02110-1301, USA. #include "localsview.h" #include #include #include LocalsView::LocalsView(QWidget *parent) : QTreeWidget(parent) { QStringList headers; headers << i18n("Symbol"); headers << i18n("Value"); setHeaderLabels(headers); - setAutoScroll(false); + setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); } LocalsView::~LocalsView() { } void LocalsView::showEvent(QShowEvent *) { emit localsVisible(true); } void LocalsView::hideEvent(QHideEvent *) { emit localsVisible(false); } void LocalsView::createWrappedItem(QTreeWidgetItem *parent, const QString &name, const QString &value) { QTreeWidgetItem *item = new QTreeWidgetItem(parent, QStringList(name)); QLabel *label = new QLabel(value); label->setWordWrap(true); setItemWidget(item, 1, label); item->setData(1, Qt::UserRole, value); + item->setToolTip(0, QStringLiteral("%1").arg(name)); + item->setToolTip(1, QStringLiteral("%1").arg(value)); + parent->setToolTip(0, QStringLiteral("%1").arg(parent->text(0))); } void LocalsView::createWrappedItem(QTreeWidget *parent, const QString &name, const QString &value) { QTreeWidgetItem *item = new QTreeWidgetItem(parent, QStringList(name)); QLabel *label = new QLabel(value); label->setWordWrap(true); setItemWidget(item, 1, label); + item->setToolTip(0, QStringLiteral("%1").arg(name)); + item->setToolTip(1, QStringLiteral("%1").arg(value)); } void LocalsView::addLocal(const QString &vString) { static QRegExp isValue(QStringLiteral("(\\S*)\\s=\\s(.*)")); static QRegExp isStruct(QStringLiteral("\\{\\S*\\s=\\s.*")); static QRegExp isStartPartial(QStringLiteral("\\S*\\s=\\s\\S*\\s=\\s\\{")); static QRegExp isPrettyQList(QStringLiteral("\\s*\\[\\S*\\]\\s=\\s\\S*")); static QRegExp isPrettyValue(QStringLiteral("(\\S*)\\s=\\s(\\S*)\\s=\\s(.*)")); static QRegExp isThisValue(QStringLiteral("\\$\\d+")); if (m_allAdded) { clear(); m_allAdded = false; } if (vString.isEmpty()) { m_allAdded = true; return; } if (isStartPartial.exactMatch(vString)) { m_local = vString; return; } if (isPrettyQList.exactMatch(vString)) { m_local += vString.trimmed(); if (m_local.endsWith(QLatin1Char(','))) m_local += QLatin1Char(' '); return; } if (vString == QLatin1String("}")) { m_local += vString; } QStringList symbolAndValue; QString value; if (m_local.isEmpty()) { if (vString == QLatin1String("No symbol table info available.")) { return; /* this is not an error */ } if (!isValue.exactMatch(vString)) { qDebug() << "Could not parse:" << vString; return; } symbolAndValue << isValue.cap(1); // check out for "print *this" if (isThisValue.exactMatch(symbolAndValue[0])) { symbolAndValue[0] = QStringLiteral("*this"); } value = isValue.cap(2); } else { if (!isPrettyValue.exactMatch(m_local)) { qDebug() << "Could not parse:" << m_local; m_local.clear(); return; } symbolAndValue << isPrettyValue.cap(1) << isPrettyValue.cap(2); value = isPrettyValue.cap(3); } QTreeWidgetItem *item; if (value[0] == QLatin1Char('{')) { if (value[1] == QLatin1Char('{')) { item = new QTreeWidgetItem(this, symbolAndValue); addArray(item, value.mid(1, value.size() - 2)); } else { if (isStruct.exactMatch(value)) { item = new QTreeWidgetItem(this, symbolAndValue); addStruct(item, value.mid(1, value.size() - 2)); } else { createWrappedItem(this, symbolAndValue[0], value); } } } else { createWrappedItem(this, symbolAndValue[0], value); } m_local.clear(); } void LocalsView::addStruct(QTreeWidgetItem *parent, const QString &vString) { static QRegExp isArray(QStringLiteral("\\{\\.*\\s=\\s.*")); static QRegExp isStruct(QStringLiteral("\\.*\\s=\\s.*")); QTreeWidgetItem *item; QStringList symbolAndValue; QString subValue; int start = 0; int end; while (start < vString.size()) { // Symbol symbolAndValue.clear(); end = vString.indexOf(QLatin1String(" = "), start); if (end < 0) { // error situation -> bail out createWrappedItem(parent, QString(), vString.right(start)); break; } symbolAndValue << vString.mid(start, end - start); // qDebug() << symbolAndValue; // Value start = end + 3; end = start; if (start < 0 || start >= vString.size()) { qDebug() << vString << start; break; } if (vString[start] == QLatin1Char('{')) { start++; end++; int count = 1; bool inComment = false; // search for the matching } while (end < vString.size()) { if (!inComment) { if (vString[end] == QLatin1Char('"')) inComment = true; else if (vString[end] == QLatin1Char('}')) count--; else if (vString[end] == QLatin1Char('{')) count++; if (count == 0) break; } else { if ((vString[end] == QLatin1Char('"')) && (vString[end - 1] != QLatin1Char('\\'))) { inComment = false; } } end++; } subValue = vString.mid(start, end - start); if (isArray.exactMatch(subValue)) { item = new QTreeWidgetItem(parent, symbolAndValue); addArray(item, subValue); } else if (isStruct.exactMatch(subValue)) { item = new QTreeWidgetItem(parent, symbolAndValue); addStruct(item, subValue); } else { createWrappedItem(parent, symbolAndValue[0], vString.mid(start, end - start)); } start = end + 3; // },_ } else { // look for the end of the value in the vString bool inComment = false; while (end < vString.size()) { if (!inComment) { if (vString[end] == QLatin1Char('"')) inComment = true; else if (vString[end] == QLatin1Char(',')) break; } else { if ((vString[end] == QLatin1Char('"')) && (vString[end - 1] != QLatin1Char('\\'))) { inComment = false; } } end++; } createWrappedItem(parent, symbolAndValue[0], vString.mid(start, end - start)); start = end + 2; // ,_ } } } void LocalsView::addArray(QTreeWidgetItem *parent, const QString &vString) { // getting here we have this kind of string: // "{...}" or "{...}, {...}" or ... QTreeWidgetItem *item; int count = 1; bool inComment = false; int index = 0; int start = 1; int end = 1; while (end < vString.size()) { if (!inComment) { if (vString[end] == QLatin1Char('"')) inComment = true; else if (vString[end] == QLatin1Char('}')) count--; else if (vString[end] == QLatin1Char('{')) count++; if (count == 0) { QStringList name; name << QStringLiteral("[%1]").arg(index); index++; item = new QTreeWidgetItem(parent, name); addStruct(item, vString.mid(start, end - start)); end += 4; // "}, {" start = end; count = 1; } } else { if ((vString[end] == QLatin1Char('"')) && (vString[end - 1] != QLatin1Char('\\'))) { inComment = false; } } end++; } }