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:
zarelaky
2019-07-08 13:45:48 +08:00
committed by hjk
parent 72ca179633
commit 7e148d8a07

View File

@@ -397,6 +397,7 @@ public:
class WatchModel : public WatchModelBase
{
Q_DECLARE_TR_FUNCTIONS(Debugger::Internal::WatchModel)
typedef QSet<WatchItem *> WatchItemSet;
public:
WatchModel(WatchHandler *handler, DebuggerEngine *engine);
@@ -446,9 +447,13 @@ public:
void grabWidget();
void ungrabWidget();
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:
int m_grabWidgetTimerId = -1;
WatchHandler *m_handler; // Not owned.
DebuggerEngine *m_engine; // Not owned.
@@ -1673,7 +1678,17 @@ bool WatchModel::contextMenuEvent(const ItemViewEvent &ev)
[this] { grabWidget(); });
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(createBreakpointMenu(item, menu));
menu->addSeparator();
@@ -1835,6 +1850,20 @@ QMenu *WatchModel::createMemoryMenu(WatchItem *item, QWidget *parent)
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)
{
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 individualFormat = theIndividualFormats.value(iname, AutomaticFormat);
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);
addCharsPrintableMenu(menu);
const QString spacer = " ";
menu->addSeparator();
@@ -1911,6 +1930,67 @@ QMenu *WatchModel::createFormatMenu(WatchItem *item, QWidget *parent)
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)
{
return WatchModel::tr("Array of %n items", nullptr, n);