Commit 4f522b92 authored by hjk's avatar hjk Committed by hjk
Browse files

debugger: add dialog to edit display types



Change-Id: If1ea8cdab359bcad80e37dd4a932e4b586527264
Reviewed-by: default avatarhjk <qthjk@ovi.com>
parent 9e13fa07
......@@ -45,22 +45,26 @@
#include <coreplugin/icore.h>
#include <projectexplorer/abi.h>
#include <utils/synchronousprocess.h>
#include <utils/historycompleter.h>
#include <utils/qtcassert.h>
#include <utils/synchronousprocess.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtCore/QRegExp>
#include <QtCore/QDir>
#include <QtCore/QCoreApplication>
#include <QtGui/QStandardItemModel>
#include <QtGui/QHeaderView>
#include <QtCore/QRegExp>
#include <QtGui/QButtonGroup>
#include <QtGui/QFileDialog>
#include <QtGui/QPushButton>
#include <QtGui/QGroupBox>
#include <QtGui/QHeaderView>
#include <QtGui/QMessageBox>
#include <QtGui/QProxyModel>
#include <QtGui/QPushButton>
#include <QtGui/QRadioButton>
#include <QtGui/QScrollArea>
#include <QtGui/QSortFilterProxyModel>
#include <QtGui/QMessageBox>
#include <QtGui/QGroupBox>
#include <QtGui/QStandardItemModel>
using namespace Utils;
......@@ -972,5 +976,127 @@ QString StartRemoteEngineDialog::enginePath() const
return m_ui->enginepath->text();
}
///////////////////////////////////////////////////////////////////////
//
// TypeFormatsDialogUi
//
///////////////////////////////////////////////////////////////////////
class TypeFormatsDialogPage : public QWidget
{
public:
TypeFormatsDialogPage()
{
m_layout = new QVBoxLayout;
m_layout->setMargin(5);
m_layout->setSpacing(0);
m_layout->addItem(new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding,
QSizePolicy::MinimumExpanding));
setLayout(m_layout);
}
void addTypeFormats(const QString &type,
const QStringList &typeFormats, int current)
{
QHBoxLayout *hl = new QHBoxLayout;
QButtonGroup *group = new QButtonGroup(this);
QLabel *typeLabel = new QLabel(type, this);
hl->addWidget(typeLabel);
for (int i = -1; i != typeFormats.size(); ++i) {
QRadioButton *choice = new QRadioButton(this);
if (i == -1)
choice->setText(tr("Reset"));
else
choice->setText(typeFormats.at(i));
hl->addWidget(choice);
if (i == current)
choice->setChecked(true);
group->addButton(choice, i);
}
hl->addItem(new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding,
QSizePolicy::MinimumExpanding));
m_layout->insertLayout(m_layout->count() - 1, hl);
}
private:
QVBoxLayout *m_layout;
};
class TypeFormatsDialogUi
{
public:
TypeFormatsDialogUi(TypeFormatsDialog *q)
{
QVBoxLayout *layout = new QVBoxLayout(q);
tabs = new QTabWidget(q);
buttonBox = new QDialogButtonBox(q);
buttonBox->setOrientation(Qt::Horizontal);
buttonBox->setStandardButtons(QDialogButtonBox::Cancel|QDialogButtonBox::Ok);
layout->addWidget(tabs);
layout->addWidget(buttonBox);
q->setLayout(layout);
}
void addPage(const QString &name)
{
TypeFormatsDialogPage *page = new TypeFormatsDialogPage;
pages.append(page);
QScrollArea *scroller = new QScrollArea;
scroller->setWidgetResizable(true);
scroller->setWidget(page);
scroller->setFrameStyle(QFrame::NoFrame);
tabs->addTab(scroller, name);
}
public:
QDialogButtonBox *buttonBox;
QList<TypeFormatsDialogPage *> pages;
private:
QTabWidget *tabs;
};
///////////////////////////////////////////////////////////////////////
//
// TypeFormatsDialog
//
///////////////////////////////////////////////////////////////////////
TypeFormatsDialog::TypeFormatsDialog(QWidget *parent)
: QDialog(parent), m_ui(new TypeFormatsDialogUi(this))
{
m_ui->addPage(tr("Qt Types"));
m_ui->addPage(tr("Standard Types"));
m_ui->addPage(tr("Misc Types"));
connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(accept()));
connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(reject()));
}
TypeFormatsDialog::~TypeFormatsDialog()
{
delete m_ui;
}
void TypeFormatsDialog::addTypeFormats(const QString &type0,
const QStringList &typeFormats, int current)
{
QString type = type0;
type.replace("__", "::");
int pos = 2;
if (type.startsWith(QLatin1Char('Q')))
pos = 0;
else if (type.startsWith(QLatin1String("std::")))
pos = 1;
m_ui->pages[pos]->addTypeFormats(type, typeFormats, current);
}
TypeFormats TypeFormatsDialog::typeFormats() const
{
return TypeFormats();
}
} // namespace Internal
} // namespace Debugger
......@@ -33,7 +33,10 @@
#ifndef DEBUGGER_DIALOGS_H
#define DEBUGGER_DIALOGS_H
#include <QtCore/QHash>
#include <QtCore/QStringList>
#include <QtGui/QDialog>
#include <QtGui/QVBoxLayout>
QT_BEGIN_NAMESPACE
......@@ -278,6 +281,8 @@ private:
QDialogButtonBox *m_box;
};
typedef QHash<QString, QStringList> TypeFormats;
class StartRemoteEngineDialog : public QDialog
{
Q_OBJECT
......@@ -295,6 +300,24 @@ private:
Ui::StartRemoteEngineDialog *m_ui;
};
class TypeFormatsDialogUi;
class TypeFormatsDialog : public QDialog
{
Q_OBJECT
public:
explicit TypeFormatsDialog(QWidget *parent);
~TypeFormatsDialog();
void addTypeFormats(const QString &type, const QStringList &formats,
int currentFormat);
TypeFormats typeFormats() const;
private:
TypeFormatsDialogUi *m_ui;
};
} // namespace Debugger
} // namespace Internal
......
......@@ -37,6 +37,7 @@
#include "debuggeractions.h"
#include "debuggercore.h"
#include "debuggerengine.h"
#include "debuggerdialogs.h"
#include "watchutils.h"
#if USE_WATCH_MODEL_TEST
......@@ -758,43 +759,15 @@ QVariant WatchModel::data(const QModelIndex &idx, int role) const
case LocalsExpandedRole:
return m_handler->m_expandedINames.contains(data.iname);
case LocalsTypeFormatListRole: {
if (data.referencingAddress || isPointerType(data.type))
return QStringList()
<< tr("Raw pointer")
<< tr("Latin1 string")
<< tr("UTF8 string")
<< tr("Local 8bit string")
<< tr("UTF16 string")
<< tr("UCS4 string");
if (data.type.contains("char[") || data.type.contains("char ["))
return QStringList()
<< tr("Latin1 string")
<< tr("UTF8 string")
<< tr("Local 8bit string");
bool ok = false;
(void)data.value.toULongLong(&ok, 0);
if ((isIntType(data.type) && data.type != "bool") || ok)
return QStringList()
<< tr("Decimal")
<< tr("Hexadecimal")
<< tr("Binary")
<< tr("Octal");
// Hack: Compensate for namespaces.
QString type = stripTemplate(data.type);
int pos = type.indexOf("::Q");
if (pos >= 0 && type.count(':') == 2)
type = type.mid(pos + 2);
pos = type.indexOf('<');
if (pos >= 0)
type = type.left(pos);
type.replace(':', '_');
return m_handler->m_reportedTypeFormats.value(type);
}
case LocalsTypeFormatListRole:
return m_handler->typeFormatList(data);
case LocalsTypeRole:
return removeNamespaces(displayType(data));
return removeNamespaces(displayType(data));
case LocalsRawTypeRole:
return QString::fromLatin1(data.type);
return QString::fromLatin1(data.type);
case LocalsTypeFormatRole:
return m_handler->m_typeFormats.value(stripTemplate(data.type), -1);
......@@ -933,6 +906,41 @@ QVariant WatchModel::headerData(int section, Qt::Orientation orientation, int ro
return QVariant();
}
QStringList WatchHandler::typeFormatList(const WatchData &data) const
{
if (data.referencingAddress || isPointerType(data.type))
return QStringList()
<< tr("Raw pointer")
<< tr("Latin1 string")
<< tr("UTF8 string")
<< tr("Local 8bit string")
<< tr("UTF16 string")
<< tr("UCS4 string");
if (data.type.contains("char[") || data.type.contains("char ["))
return QStringList()
<< tr("Latin1 string")
<< tr("UTF8 string")
<< tr("Local 8bit string");
bool ok = false;
(void)data.value.toULongLong(&ok, 0);
if ((isIntType(data.type) && data.type != "bool") || ok)
return QStringList()
<< tr("Decimal")
<< tr("Hexadecimal")
<< tr("Binary")
<< tr("Octal");
// Hack: Compensate for namespaces.
QString type = stripTemplate(data.type);
int pos = type.indexOf("::Q");
if (pos >= 0 && type.count(':') == 2)
type = type.mid(pos + 2);
pos = type.indexOf('<');
if (pos >= 0)
type = type.left(pos);
type.replace(':', '_');
return m_reportedTypeFormats.value(type);
}
// Determine sort order of watch items by sort order or alphabetical inames
// according to setting 'SortStructMembers'. We need a map key for bulkInsert
// and a predicate for finding the insertion position of a single item.
......@@ -1759,5 +1767,31 @@ void WatchHandler::rebuildModel()
endCycle();
}
void WatchHandler::setTypeFormats(const TypeFormats &typeFormats)
{
m_reportedTypeFormats = typeFormats;
}
TypeFormats WatchHandler::typeFormats() const
{
return m_reportedTypeFormats;
}
void WatchHandler::editTypeFormats(bool includeLocals, const QByteArray &iname)
{
Q_UNUSED(includeLocals);
TypeFormatsDialog dlg(0);
//QHashIterator<QString, QStringList> it(m_reportedTypeFormats);
QList<QString> l = 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);
}
if (dlg.exec())
setTypeFormats(dlg.typeFormats());
}
} // namespace Internal
} // namespace Debugger
......@@ -48,6 +48,7 @@ namespace Internal {
class WatchItem;
class WatchHandler;
typedef QHash<QString, QStringList> TypeFormats;
enum WatchType
{
......@@ -183,6 +184,9 @@ public:
int format(const QByteArray &iname) const;
void addTypeFormats(const QByteArray &type, const QStringList &formats);
void setTypeFormats(const TypeFormats &typeFormats);
TypeFormats typeFormats() const;
QStringList typeFormatList(const WatchData &data) const;
void setUnprintableBase(int base);
static int unprintableBase();
......@@ -190,6 +194,7 @@ public:
QByteArray watcherName(const QByteArray &exp);
void synchronizeWatchers();
QString editorContents();
void editTypeFormats(bool includeLocals, const QByteArray &iname);
private:
friend class WatchModel;
......@@ -211,7 +216,7 @@ private:
static QHash<QByteArray, int> m_watcherNames;
static QHash<QByteArray, int> m_typeFormats;
QHash<QByteArray, int> m_individualFormats; // Indexed by iname.
QHash<QString, QStringList> m_reportedTypeFormats;
TypeFormats m_reportedTypeFormats;
// Items expanded in the Locals & Watchers view.
QSet<QByteArray> m_expandedINames;
......
......@@ -637,7 +637,7 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
QAction *showUnprintableEscape = 0;
QAction *showUnprintableOctal = 0;
QAction *showUnprintableHexadecimal = 0;
formatMenu.setTitle(tr("Change Display Format..."));
formatMenu.setTitle(tr("Change Local Display Format..."));
showUnprintableUnicode =
formatMenu.addAction(tr("Treat All Characters as Printable"));
showUnprintableUnicode->setCheckable(true);
......@@ -755,6 +755,8 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
QAction *actSelectWidgetToWatch = menu.addAction(tr("Select Widget to Watch"));
actSelectWidgetToWatch->setEnabled(canHandleWatches
&& (engine->debuggerCapabilities() & WatchWidgetsCapability));
QAction *actEditTypeFormats = menu.addAction(tr("Change Global Display Formats..."));
actEditTypeFormats->setEnabled(true);
menu.addSeparator();
QAction *actWatchExpression = new QAction(addWatchActionText(exp), &menu);
......@@ -839,6 +841,7 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
menu.addAction(actInsertNewWatchItem);
menu.addAction(actSelectWidgetToWatch);
menu.addAction(actEditTypeFormats);
menu.addMenu(&formatMenu);
menu.addMenu(&memoryMenu);
menu.addMenu(&breakpointMenu);
......@@ -911,6 +914,8 @@ void WatchWindow::contextMenuEvent(QContextMenuEvent *ev)
removeWatchExpression(removeExp);
} else if (act == actCopy) {
copyToClipboard(DebuggerToolTipWidget::treeModelClipboardContents(model()));
} else if (act == actEditTypeFormats) {
handler->editTypeFormats(true, mi0.data(LocalsINameRole).toByteArray());
} else if (act == actCopyValue) {
copyToClipboard(mi1.data().toString());
} else if (act == actRemoveWatches) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment