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
|
||||
{
|
||||
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();
|
||||
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);
|
||||
|
Reference in New Issue
Block a user