forked from qt-creator/qt-creator
Debugger: Allow changing item format for all array elements
Change-Id: I05000102d4c6b185340581029006b9254c91fcb1 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: André Hartmann <aha_1980@gmx.de>
This commit is contained in:
@@ -397,6 +397,7 @@ public:
|
|||||||
class WatchModel : public WatchModelBase
|
class WatchModel : public WatchModelBase
|
||||||
{
|
{
|
||||||
Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::WatchModel)
|
Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::WatchModel)
|
||||||
|
typedef QSet<WatchItem *> WatchItemSet;
|
||||||
public:
|
public:
|
||||||
WatchModel(WatchHandler *handler, DebuggerEngine *engine);
|
WatchModel(WatchHandler *handler, DebuggerEngine *engine);
|
||||||
|
|
||||||
@@ -446,9 +447,13 @@ public:
|
|||||||
void grabWidget();
|
void grabWidget();
|
||||||
void ungrabWidget();
|
void ungrabWidget();
|
||||||
void timerEvent(QTimerEvent *event) override;
|
void timerEvent(QTimerEvent *event) override;
|
||||||
int m_grabWidgetTimerId = -1;
|
private:
|
||||||
|
QMenu *createFormatMenuForManySelected(const WatchItemSet &item, QWidget *parent);
|
||||||
|
void setItemsFormat(const WatchItemSet &items, const DisplayFormat &format);
|
||||||
|
void addCharsPrintableMenu(QMenu *menu);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
int m_grabWidgetTimerId = -1;
|
||||||
WatchHandler *m_handler; // Not owned.
|
WatchHandler *m_handler; // Not owned.
|
||||||
DebuggerEngine *m_engine; // Not owned.
|
DebuggerEngine *m_engine; // Not owned.
|
||||||
|
|
||||||
@@ -1673,7 +1678,17 @@ bool WatchModel::contextMenuEvent(const ItemViewEvent &ev)
|
|||||||
[this] { grabWidget(); });
|
[this] { grabWidget(); });
|
||||||
|
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
menu->addMenu(createFormatMenu(item, menu));
|
QModelIndexList mil = ev.currentOrSelectedRows();
|
||||||
|
if (mil.size() > 1) {
|
||||||
|
WatchItemSet wis;
|
||||||
|
for (const QModelIndex &i : mil)
|
||||||
|
wis.insert(itemForIndex(i));
|
||||||
|
|
||||||
|
menu->addMenu(createFormatMenuForManySelected(wis, menu));
|
||||||
|
} else {
|
||||||
|
menu->addMenu(createFormatMenu(item, menu));
|
||||||
|
}
|
||||||
|
|
||||||
menu->addMenu(createMemoryMenu(item, menu));
|
menu->addMenu(createMemoryMenu(item, menu));
|
||||||
menu->addMenu(createBreakpointMenu(item, menu));
|
menu->addMenu(createBreakpointMenu(item, menu));
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
@@ -1835,6 +1850,20 @@ QMenu *WatchModel::createMemoryMenu(WatchItem *item, QWidget *parent)
|
|||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WatchModel::addCharsPrintableMenu(QMenu *menu)
|
||||||
|
{
|
||||||
|
auto addBaseChangeAction = [this, menu](const QString &text, int base) {
|
||||||
|
addCheckableAction(menu, text, true, theUnprintableBase == base, [this, base] {
|
||||||
|
theUnprintableBase = base;
|
||||||
|
emit layoutChanged(); // FIXME
|
||||||
|
});
|
||||||
|
};
|
||||||
|
addBaseChangeAction(tr("Treat All Characters as Printable"), 0);
|
||||||
|
addBaseChangeAction(tr("Show Unprintable Characters as Escape Sequences"), -1);
|
||||||
|
addBaseChangeAction(tr("Show Unprintable Characters as Octal"), 8);
|
||||||
|
addBaseChangeAction(tr("Show Unprintable Characters as Hexadecimal"), 16);
|
||||||
|
}
|
||||||
|
|
||||||
QMenu *WatchModel::createFormatMenu(WatchItem *item, QWidget *parent)
|
QMenu *WatchModel::createFormatMenu(WatchItem *item, QWidget *parent)
|
||||||
{
|
{
|
||||||
auto menu = new QMenu(tr("Change Value Display Format"), parent);
|
auto menu = new QMenu(tr("Change Value Display Format"), parent);
|
||||||
@@ -1849,17 +1878,7 @@ QMenu *WatchModel::createFormatMenu(WatchItem *item, QWidget *parent)
|
|||||||
const int typeFormat = theTypeFormats.value(stripForFormat(item->type), AutomaticFormat);
|
const int typeFormat = theTypeFormats.value(stripForFormat(item->type), AutomaticFormat);
|
||||||
const int individualFormat = theIndividualFormats.value(iname, AutomaticFormat);
|
const int individualFormat = theIndividualFormats.value(iname, AutomaticFormat);
|
||||||
|
|
||||||
auto addBaseChangeAction = [this, menu](const QString &text, int base) {
|
addCharsPrintableMenu(menu);
|
||||||
addCheckableAction(menu, text, true, theUnprintableBase == base, [this, base] {
|
|
||||||
theUnprintableBase = base;
|
|
||||||
emit layoutChanged(); // FIXME
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
addBaseChangeAction(tr("Treat All Characters as Printable"), 0);
|
|
||||||
addBaseChangeAction(tr("Show Unprintable Characters as Escape Sequences"), -1);
|
|
||||||
addBaseChangeAction(tr("Show Unprintable Characters as Octal"), 8);
|
|
||||||
addBaseChangeAction(tr("Show Unprintable Characters as Hexadecimal"), 16);
|
|
||||||
|
|
||||||
const QString spacer = " ";
|
const QString spacer = " ";
|
||||||
menu->addSeparator();
|
menu->addSeparator();
|
||||||
@@ -1911,6 +1930,67 @@ QMenu *WatchModel::createFormatMenu(WatchItem *item, QWidget *parent)
|
|||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WatchModel::setItemsFormat(const WatchItemSet &items, const DisplayFormat &format)
|
||||||
|
{
|
||||||
|
if (format == AutomaticFormat) {
|
||||||
|
for (WatchItem *item : items)
|
||||||
|
theIndividualFormats.remove(item->iname);
|
||||||
|
} else {
|
||||||
|
for (WatchItem *item : items)
|
||||||
|
theIndividualFormats[item->iname] = format;
|
||||||
|
}
|
||||||
|
saveFormats();
|
||||||
|
}
|
||||||
|
|
||||||
|
QMenu *WatchModel::createFormatMenuForManySelected(const WatchItemSet &items, QWidget *parent)
|
||||||
|
{
|
||||||
|
auto menu = new QMenu(tr("Change Display Format for Selected Values"), parent);
|
||||||
|
|
||||||
|
addCharsPrintableMenu(menu);
|
||||||
|
|
||||||
|
QHash<DisplayFormat, int> allItemsFormats;
|
||||||
|
for (WatchItem *item : items) {
|
||||||
|
const DisplayFormats alternativeFormats = typeFormatList(item);
|
||||||
|
for (const DisplayFormat &format : alternativeFormats) {
|
||||||
|
QHash<DisplayFormat, int>::iterator itr = allItemsFormats.find(format);
|
||||||
|
if (itr != allItemsFormats.end())
|
||||||
|
itr.value() += 1;
|
||||||
|
else
|
||||||
|
allItemsFormats[format] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString spacer = " ";
|
||||||
|
menu->addSeparator();
|
||||||
|
|
||||||
|
addAction(menu, tr("Change Display for Objects"), false);
|
||||||
|
QString msg = QString(tr("Use Display Format Based on Type"));
|
||||||
|
addCheckableAction(menu, spacer + msg, true, false,
|
||||||
|
[this, items] {
|
||||||
|
setItemsFormat(items, AutomaticFormat);
|
||||||
|
m_engine->updateLocals();
|
||||||
|
});
|
||||||
|
|
||||||
|
int countOfSelectItems = items.size();
|
||||||
|
QHashIterator<DisplayFormat, int> iter(allItemsFormats);
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
iter.next();
|
||||||
|
DisplayFormat format = iter.key();
|
||||||
|
QString formatName = nameForFormat(format);
|
||||||
|
if (formatName.isEmpty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
addCheckableAction(menu, spacer + formatName,
|
||||||
|
iter.value() == countOfSelectItems,
|
||||||
|
false,
|
||||||
|
[this, format, items] {
|
||||||
|
setItemsFormat(items, format);
|
||||||
|
m_engine->updateLocals();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return menu;
|
||||||
|
}
|
||||||
|
|
||||||
static inline QString msgArrayFormat(int n)
|
static inline QString msgArrayFormat(int n)
|
||||||
{
|
{
|
||||||
return WatchModel::tr("Array of %n items", nullptr, n);
|
return WatchModel::tr("Array of %n items", nullptr, n);
|
||||||
|
Reference in New Issue
Block a user