diff --git a/src/plugins/debugger/watchhandler.cpp b/src/plugins/debugger/watchhandler.cpp index 05e6c834cb0664c5e53001c5fd23ef582b82dca4..63b02127b04cd1f91fdeabf64e5543fb2ba30d5e 100644 --- a/src/plugins/debugger/watchhandler.cpp +++ b/src/plugins/debugger/watchhandler.cpp @@ -79,6 +79,7 @@ static int generationCounter = 0; QHash<QByteArray, int> WatchHandler::m_watcherNames; QHash<QByteArray, int> WatchHandler::m_typeFormats; +int WatchHandler::m_unprintableBase = 0; //////////////////////////////////////////////////////////////////// // @@ -627,21 +628,41 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const case Qt::DisplayRole: { const QByteArray ns = engine()->qtNamespace(); + QString result; switch (idx.column()) { case 0: if (data.name.isEmpty()) - return tr("<Edit>"); - if (data.name == QLatin1String("*") && item->parent) - return QVariant(QLatin1Char('*') + item->parent->name); - return removeInitialNamespace(data.name, ns); + result = tr("<Edit>"); + else if (data.name == QLatin1String("*") && item->parent) + result = QLatin1Char('*') + item->parent->name; + else + result = removeInitialNamespace(data.name, ns); + break; case 1: - return removeInitialNamespace(truncateValue( + result = removeInitialNamespace(truncateValue( formattedValue(data, itemFormat(data))), ns); + break; case 2: - return removeNamespaces(displayType(data), ns); + result = removeNamespaces(displayType(data), ns); + break; default: break; } + if (WatchHandler::m_unprintableBase == 0) + return result; + QString encoded; + foreach (const QChar c, result) { + if (c.isPrint()) { + encoded += c; + } else if (WatchHandler::m_unprintableBase == 8) { + encoded += QString("\\%1") + .arg(c.unicode(), 3, 8, QLatin1Char('0')); + } else { + encoded += QString("\\u%1") + .arg(c.unicode(), 4, 16, QLatin1Char('0')); + } + } + return encoded; } case Qt::ToolTipRole: @@ -1092,11 +1113,11 @@ WatchHandler::WatchHandler(DebuggerEngine *engine) m_tooltips = new WatchModel(this, TooltipsWatch); connect(debuggerCore()->action(ShowStdNamespace), - SIGNAL(triggered()), this, SLOT(emitAllChanged())); + SIGNAL(triggered()), SLOT(emitAllChanged())); connect(debuggerCore()->action(ShowQtNamespace), - SIGNAL(triggered()), this, SLOT(emitAllChanged())); + SIGNAL(triggered()), SLOT(emitAllChanged())); connect(debuggerCore()->action(SortStructMembers), - SIGNAL(triggered()), this, SLOT(emitAllChanged())); + SIGNAL(triggered()), SLOT(emitAllChanged())); } void WatchHandler::beginCycle(bool fullCycle) diff --git a/src/plugins/debugger/watchhandler.h b/src/plugins/debugger/watchhandler.h index 10d96826ec0e53c265b540dea3710e0cf45d374f..950bf4fdaa74029e3c7782783900f0d7957ef9cd 100644 --- a/src/plugins/debugger/watchhandler.h +++ b/src/plugins/debugger/watchhandler.h @@ -180,6 +180,9 @@ public: void addTypeFormats(const QByteArray &type, const QStringList &formats); + void setUnprintableBase(int base) { m_unprintableBase = base; } + int unprintableBase() const { return m_unprintableBase; } + QByteArray watcherName(const QByteArray &exp); void synchronizeWatchers(); QString editorContents(); @@ -214,6 +217,7 @@ private: WatchModel *m_watchers; WatchModel *m_tooltips; DebuggerEngine *m_engine; + static int m_unprintableBase; }; } // namespace Internal diff --git a/src/plugins/debugger/watchwindow.cpp b/src/plugins/debugger/watchwindow.cpp index b6708b306791a75ab709514bcf0633db15b4422e..f4c554752a91bd8194971e61f02daeaf8f2217f0 100644 --- a/src/plugins/debugger/watchwindow.cpp +++ b/src/plugins/debugger/watchwindow.cpp @@ -286,14 +286,31 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev) mi0.data(LocalsIndividualFormatRole).toInt(); const int effectiveIndividualFormat = individualFormat == -1 ? typeFormat : individualFormat; + const int unprintableBase = handler->unprintableBase(); QMenu formatMenu; QList<QAction *> typeFormatActions; QList<QAction *> individualFormatActions; QAction *clearTypeFormatAction = 0; QAction *clearIndividualFormatAction = 0; + QAction *showUnprintableUnicode = 0; + QAction *showUnprintableOctal = 0; + QAction *showUnprintableHexadecimal = 0; formatMenu.setTitle(tr("Change Display Format...")); - if (idx.isValid() && !alternativeFormats.isEmpty()) { + if (true /*idx.isValid() && !alternativeFormats.isEmpty() */) { + showUnprintableUnicode = + formatMenu.addAction(tr("Treat All Characters as Printable")); + showUnprintableUnicode->setCheckable(true); + showUnprintableUnicode->setChecked(unprintableBase == 0); + showUnprintableOctal = + formatMenu.addAction(tr("Show Unprintable Characters as Octal")); + showUnprintableOctal->setCheckable(true); + showUnprintableOctal->setChecked(unprintableBase == 8); + showUnprintableHexadecimal = + formatMenu.addAction(tr("Show Unprintable Characters as Hexadecimal")); + showUnprintableHexadecimal->setCheckable(true); + showUnprintableHexadecimal->setChecked(unprintableBase == 16); + formatMenu.addSeparator(); QAction *dummy = formatMenu.addAction( tr("Change Display for Type \"%1\"").arg(type)); dummy->setEnabled(false); @@ -515,6 +532,12 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev) } else if (act == actShowInEditor) { QString contents = handler->editorContents(); debuggerCore()->openTextEditor(tr("Locals & Watchers"), contents); + } else if (act == showUnprintableUnicode) { + handler->setUnprintableBase(0); + } else if (act == showUnprintableOctal) { + handler->setUnprintableBase(8); + } else if (act == showUnprintableHexadecimal) { + handler->setUnprintableBase(16); } else { for (int i = 0; i != typeFormatActions.size(); ++i) { if (act == typeFormatActions.at(i)) diff --git a/tests/manual/gdbdebugger/simple/simple_gdbtest_app.cpp b/tests/manual/gdbdebugger/simple/simple_gdbtest_app.cpp index a45ac4ef60842102a537fe7386538997a7f762c9..d2e970e5f46ec7b23eaae2b1159ac404659b17bb 100644 --- a/tests/manual/gdbdebugger/simple/simple_gdbtest_app.cpp +++ b/tests/manual/gdbdebugger/simple/simple_gdbtest_app.cpp @@ -2060,6 +2060,14 @@ struct Ty }; void testStuff() +{ + char *x = "0\032\0333"; + char *y = "0\032\0333"; + char *z = "0\032\0333"; + int i = 1; +} + +void testStuff5() { using namespace std; typedef map<string, list<string> > map_t;