Commit 48ac7c18 authored by hjk's avatar hjk

Debugger: Re-organize passing of display formats

The current setup (dumper->gui: list of descriptions,
gui->dumper: index in list) is fragile and not easily
i18n'able. Go with an enum based approach now.

Change-Id: Ie78c596065a8b2ba87ad725274da29d4be3a6da4
Reviewed-by: default avatarChristian Stenger <christian.stenger@theqtcompany.com>
parent b727c15a
This diff is collapsed.
......@@ -1075,35 +1075,8 @@ class Dumper(DumperBase):
self.putItem(self.expensiveDowncast(value), False)
return
format = self.currentItemFormat(typeName)
if self.useFancy and (format is None or format >= 1):
self.putType(typeName)
nsStrippedType = self.stripNamespaceFromType(typeName)\
.replace("::", "__")
# The following block is only needed for D.
if nsStrippedType.startswith("_A"):
# DMD v2.058 encodes string[] as _Array_uns long long.
# With spaces.
if nsStrippedType.startswith("_Array_"):
qdump_Array(self, value)
return
if nsStrippedType.startswith("_AArray_"):
qdump_AArray(self, value)
return
#warn(" STRIPPED: %s" % nsStrippedType)
#warn(" DUMPERS: %s" % self.qqDumpers)
#warn(" DUMPERS: %s" % (nsStrippedType in self.qqDumpers))
dumper = self.qqDumpers.get(nsStrippedType, None)
if not dumper is None:
if tryDynamic:
dumper(self, self.expensiveDowncast(value))
else:
dumper(self, value)
return
if self.tryPutPrettyItem(typeName, value):
return
# D arrays, gdc compiled.
if typeName.endswith("[]"):
......
......@@ -1063,15 +1063,8 @@ class Dumper(DumperBase):
#warn("VALUE: %s" % value)
#warn("FANCY: %s" % self.useFancy)
if self.useFancy:
stripped = self.stripNamespaceFromType(typeName).replace("::", "__")
#warn("STRIPPED: %s" % stripped)
#warn("DUMPABLE: %s" % (stripped in self.qqDumpers))
if stripped in self.qqDumpers:
self.putType(typeName)
self.context = value
self.qqDumpers[stripped](self, value)
return
if self.tryPutPrettyItem(typeName, value):
return
# Normal value
#numchild = 1 if value.MightHaveChildren() else 0
......
......@@ -53,24 +53,25 @@ def qdump__QAtomicPointer(d, value):
d.putSubItem("_q_value", q.dereference())
def qform__QByteArray():
return "Latin1 String,Latin1 String in Separate Window,UTF-8 String,UTF-8 String in Separate Window"
return [Latin1StringFormat, SeparateLatin1StringFormat,
Utf8StringFormat, SeparateUtf8StringFormat ]
def qdump__QByteArray(d, value):
data, size, alloc = d.byteArrayData(value)
d.putNumChild(size)
elided, p = d.encodeByteArrayHelper(d.extractPointer(value), d.displayStringLimit)
format = d.currentItemFormat()
if format == 1 or format is None:
displayFormat = d.currentItemFormat()
if displayFormat == AutomaticFormat or displayFormat == Latin1StringFormat:
d.putDisplay(StopDisplay)
d.putValue(p, Hex2EncodedLatin1, elided=elided)
elif format == 2:
elif displayFormat == SeparateLatin1StringFormat:
d.putValue(p, Hex2EncodedLatin1, elided=elided)
d.putField("editformat", DisplayLatin1String)
d.putField("editvalue", d.encodeByteArray(value, limit=100000))
elif format == 3:
elif displayFormat == Utf8StringFormat:
d.putDisplay(StopDisplay)
d.putValue(p, Hex2EncodedUtf8, elided=elided)
elif format == 4:
elif displayFormat == SeparateUtf8StringFormat:
d.putValue(p, Hex2EncodedUtf8, elided=elided)
d.putField("editformat", DisplayUtf8String)
d.putField("editvalue", d.encodeByteArray(value, limit=100000))
......@@ -92,14 +93,14 @@ def qdump__QChar(d, value):
def qform__QAbstractItemModel():
return "Normal,Enhanced"
return [SimpleFormat, EnhancedFormat]
def qdump__QAbstractItemModel(d, value):
format = d.currentItemFormat()
if format == 1:
displayFormat = d.currentItemFormat()
if displayFormat == SimpleFormat:
d.putPlainChildren(value)
return
#format == 2:
#displayFormat == EnhancedFormat:
# Create a default-constructed QModelIndex on the stack.
try:
ri = d.makeValue(d.qtNamespace() + "QModelIndex", "-1, -1, 0, 0")
......@@ -134,11 +135,11 @@ def qdump__QAbstractItemModel(d, value):
#gdb.execute("call free($ri)")
def qform__QModelIndex():
return "Normal,Enhanced"
return [SimpleFormat, EnhancedFormat]
def qdump__QModelIndex(d, value):
format = d.currentItemFormat()
if format == 1:
displayFormat = d.currentItemFormat()
if displayFormat == SimpleFormat:
d.putPlainChildren(value)
return
r = value["r"]
......@@ -768,7 +769,7 @@ def qdump__QIPv6Address(d, value):
d.putPlainChildren(c)
def qform__QList():
return "Assume Direct Storage,Assume Indirect Storage"
return [DirectQListStorageFormat, IndirectQListStorageFormat]
def qdump__QList(d, value):
base = d.extractPointer(value)
......@@ -794,10 +795,10 @@ def qdump__QList(d, value):
# but this data is available neither in the compiled binary nor
# in the frontend.
# So as first approximation only do the 'isLarge' check:
format = d.currentItemFormat()
if format == 1:
displayFormat = d.currentItemFormat()
if displayFormat == DirectQListStorageFormat:
isInternal = True
elif format == 2:
elif displayFormat == IndirectQListStorageFormat:
isInternal = False
else:
isInternal = innerSize <= stepSize and d.isMovableType(innerType)
......@@ -818,7 +819,7 @@ def qdump__QList(d, value):
d.putSubItem(i, x)
def qform__QImage():
return "Normal,Displayed"
return [SimpleFormat, SeparateFormat]
def qdump__QImage(d, value):
# This relies on current QImage layout:
......@@ -861,10 +862,10 @@ def qdump__QImage(d, value):
d.putNumChild(0)
d.putType("void *")
format = d.currentItemFormat()
if format == 1:
displayFormat = d.currentItemFormat()
if displayFormat == SimpleFormat:
d.putDisplay(StopDisplay)
elif format == 2:
elif displayFormat == SeparateFormat:
# This is critical for performance. Writing to an external
# file using the following is faster when using GDB.
# file = tempfile.mkstemp(prefix="gdbpy_")
......@@ -1751,16 +1752,16 @@ def qedit__QString(d, value, data):
d.setValues(base, "short", [ord(c) for c in data])
def qform__QString():
return "Inline,Separate Window"
return [SimpleFormat, SeparateFormat]
def qdump__QString(d, value):
d.putStringValue(value)
data, size, alloc = d.stringData(value)
d.putNumChild(size)
format = d.currentItemFormat()
if format == 1:
displayFormat = d.currentItemFormat()
if displayFormat == SimpleFormat:
d.putDisplay(StopDisplay)
elif format == 2:
elif displayFormat == SeparateFormat:
d.putField("editformat", DisplayUtf16String)
d.putField("editvalue", d.encodeString(value, limit=100000))
if d.isExpanded():
......@@ -1847,7 +1848,7 @@ def qdump__QTextDocument(d, value):
def qform__QUrl():
return "Inline,Separate Window"
return [SimpleFormat, SeparateFormat]
def qdump__QUrl(d, value):
if d.qtVersion() < 0x050000:
......@@ -1911,10 +1912,10 @@ def qdump__QUrl(d, value):
url += path
d.putValue(url, Hex4EncodedLittleEndian)
format = d.currentItemFormat()
if format == 1:
displayFormat = d.currentItemFormat()
if displayFormat == SimpleFormat:
d.putDisplay(StopDisplay)
elif format == 2:
elif displayFormat == SeparateFormat:
d.putField("editformat", DisplayUtf16String)
d.putField("editvalue", url)
......
......@@ -398,7 +398,8 @@ def qdump__std____debug__stack(d, value):
qdump__std__stack(d, value)
def qform__std__string():
return "Latin1 String,Latin1 String in Separate Window,UTF-8 String,UTF-8 String in Separate Window"
return [Latin1StringFormat, SeparateLatin1StringFormat,
Utf8StringFormat, SeparateUtf8StringFormat ]
def qdump__std__string(d, value):
qdump__std__stringHelper1(d, value, 1, d.currentItemFormat())
......@@ -787,7 +788,7 @@ def qdump__string(d, value):
qdump__std__string(d, value)
def qform__std__wstring():
return "Inline String,String in Separate Window"
return [SimpleFormat, SeparateFormat]
def qdump__std__wstring(d, value):
charSize = d.lookupType('wchar_t').sizeof
......
......@@ -576,17 +576,21 @@ void CdbEngine::setupEngine()
STATE_DEBUG(state(), Q_FUNC_INFO, __LINE__, "notifyEngineSetupFailed")
notifyEngineSetupFailed();
}
const QString normalFormat = tr("Normal");
const QStringList stringFormats = QStringList()
<< normalFormat << tr("Separate Window");
DisplayFormats stringFormats;
stringFormats.append(SimpleFormat);
stringFormats.append(SeparateFormat);
WatchHandler *wh = watchHandler();
wh->addTypeFormats("QString", stringFormats);
wh->addTypeFormats("QString *", stringFormats);
wh->addTypeFormats("QByteArray", stringFormats);
wh->addTypeFormats("QByteArray *", stringFormats);
wh->addTypeFormats("std__basic_string", stringFormats); // Python dumper naming convention for std::[w]string
const QStringList imageFormats = QStringList()
<< normalFormat << tr("Image");
DisplayFormats imageFormats;
imageFormats.append(SimpleFormat);
imageFormats.append(EnhancedFormat);
wh->addTypeFormats("QImage", imageFormats);
wh->addTypeFormats("QImage *", imageFormats);
}
......
......@@ -807,7 +807,7 @@ public:
}
void addTypeFormats(const QString &type,
const QStringList &typeFormats, int current)
const DisplayFormats &typeFormats, int current)
{
const int row = m_layout->rowCount();
int column = 0;
......@@ -815,7 +815,8 @@ public:
m_layout->addWidget(new QLabel(type), row, column++);
for (int i = -1; i != typeFormats.size(); ++i) {
QRadioButton *choice = new QRadioButton(this);
choice->setText(i == -1 ? TypeFormatsDialog::tr("Reset") : typeFormats.at(i));
choice->setText(i == -1 ? TypeFormatsDialog::tr("Reset")
: WatchHandler::nameForFormat(typeFormats.at(i)));
m_layout->addWidget(choice, row, column++);
if (i == current)
choice->setChecked(true);
......@@ -868,7 +869,6 @@ private:
//
///////////////////////////////////////////////////////////////////////
TypeFormatsDialog::TypeFormatsDialog(QWidget *parent)
: QDialog(parent), m_ui(new TypeFormatsDialogUi(this))
{
......@@ -888,7 +888,7 @@ TypeFormatsDialog::~TypeFormatsDialog()
}
void TypeFormatsDialog::addTypeFormats(const QString &type0,
const QStringList &typeFormats, int current)
const DisplayFormats &typeFormats, int current)
{
QString type = type0;
type.replace(QLatin1String("__"), QLatin1String("::"));
......@@ -900,10 +900,5 @@ void TypeFormatsDialog::addTypeFormats(const QString &type0,
m_ui->pages[pos]->addTypeFormats(type, typeFormats, current);
}
DumperTypeFormats TypeFormatsDialog::typeFormats() const
{
return DumperTypeFormats();
}
} // namespace Internal
} // namespace Debugger
......@@ -31,6 +31,8 @@
#ifndef DEBUGGER_DIALOGS_H
#define DEBUGGER_DIALOGS_H
#include "watchhandler.h"
#include <projectexplorer/kitchooser.h>
#include <projectexplorer/abi.h>
......@@ -162,8 +164,6 @@ private:
QDialogButtonBox *m_box;
};
typedef QHash<QString, QStringList> DumperTypeFormats;
class StartRemoteEngineDialog : public QDialog
{
Q_OBJECT
......@@ -191,9 +191,8 @@ public:
explicit TypeFormatsDialog(QWidget *parent);
~TypeFormatsDialog();
void addTypeFormats(const QString &type, const QStringList &formats,
void addTypeFormats(const QString &type, const DisplayFormats &formats,
int currentFormat);
DumperTypeFormats typeFormats() const;
private:
TypeFormatsDialogUi *m_ui;
......
......@@ -40,6 +40,7 @@
#include "simplifytype.h"
#include "imageviewer.h"
#include "watchutils.h"
#include "cdb/cdbengine.h" // Remove after string freeze
#include <coreplugin/icore.h>
......@@ -239,7 +240,7 @@ public:
QSet<QByteArray> m_expandedINames;
QTimer m_requestUpdateTimer;
DumperTypeFormats m_reportedTypeFormats;
QHash<QString, DisplayFormats> m_reportedTypeFormats; // Type name -> Dumper Formats
QHash<QByteArray, QString> m_valueCache;
};
......@@ -943,22 +944,31 @@ static inline QString msgArrayFormat(int n)
QString WatchModel::nameForFormat(int format)
{
switch (format) {
case AutomaticFormat: return QLatin1String("");
case RawFormat: return tr("Raw Data");
case SimpleFormat: return CdbEngine::tr("Normal"); // FIXME: String
case EnhancedFormat: return QLatin1String("Enhanced"); // FIXME: String
case SeparateFormat: return CdbEngine::tr("Separate Window"); // FIXME: String
case Latin1StringFormat: return tr("Latin1 String");
case SeparateLatin1StringFormat: return tr("Latin1 String in Separate Window");
case Utf8StringFormat: return tr("UTF-8 String");
case SeparateUtf8StringFormat: return tr("UTF-8 String in Separate Window");
case Local8BitStringFormat: return tr("Local 8-Bit String");
case Utf16StringFormat: return tr("UTF-16 String");
case Ucs4StringFormat: return tr("UCS-4 String");
case Array10Format: return msgArrayFormat(10);
case Array100Format: return msgArrayFormat(100);
case Array1000Format: return msgArrayFormat(1000);
case Array10000Format: return msgArrayFormat(10000);
case SeparateLatin1StringFormat: return tr("Latin1 String in Separate Window");
case SeparateUtf8StringFormat: return tr("UTF-8 String in Separate Window");
case DecimalIntegerFormat: return tr("Decimal Integer");
case HexadecimalIntegerFormat: return tr("Hexadecimal Integer");
case BinaryIntegerFormat: return tr("Binary Integer");
case OctalIntegerFormat: return tr("Octal Integer");
case CompactFloatFormat: return tr("Compact Float");
case ScientificFloatFormat: return tr("Scientific Float");
}
......@@ -967,9 +977,9 @@ QString WatchModel::nameForFormat(int format)
return QString();
}
TypeFormatList WatchItem::typeFormatList() const
DisplayFormats WatchItem::typeFormatList() const
{
TypeFormatList formats;
DisplayFormats formats;
// Types supported by dumpers:
// Hack: Compensate for namespaces.
......@@ -981,9 +991,7 @@ TypeFormatList WatchItem::typeFormatList() const
if (pos >= 0)
t.truncate(pos);
t.replace(QLatin1Char(':'), QLatin1Char('_'));
QStringList reported = watchModel()->m_reportedTypeFormats.value(t);
for (int i = 0, n = reported.size(); i != n; ++i)
formats.append(TypeFormatItem(reported.at(i), i));
formats << watchModel()->m_reportedTypeFormats.value(t);
// Fixed artificial string and pointer types.
if (origaddr || isPointerType(type)) {
......@@ -1531,6 +1539,11 @@ int WatchHandler::format(const QByteArray &iname) const
return result;
}
QString WatchHandler::nameForFormat(int format)
{
return WatchModel::nameForFormat(format);
}
QByteArray WatchHandler::typeFormatRequests() const
{
QByteArray ba;
......@@ -1539,7 +1552,7 @@ QByteArray WatchHandler::typeFormatRequests() const
while (it.hasNext()) {
it.next();
const int format = it.value();
if (format >= RawFormat && format < ArtificialFormatBase) {
if (format != AutomaticFormat) {
ba.append(it.key().toHex());
ba.append('=');
ba.append(QByteArray::number(format));
......@@ -1559,7 +1572,7 @@ QByteArray WatchHandler::individualFormatRequests() const
while (it.hasNext()) {
it.next();
const int format = it.value();
if (format >= RawFormat && format < ArtificialFormatBase) {
if (format != AutomaticFormat) {
ba.append(it.key());
ba.append('=');
ba.append(QByteArray::number(it.value()));
......@@ -1588,7 +1601,7 @@ void WatchHandler::appendFormatRequests(DebuggerCommand *cmd)
while (it.hasNext()) {
it.next();
const int format = it.value();
if (format >= RawFormat && format < ArtificialFormatBase)
if (format != AutomaticFormat)
cmd->arg(it.key(), format);
}
cmd->endGroup();
......@@ -1598,7 +1611,7 @@ void WatchHandler::appendFormatRequests(DebuggerCommand *cmd)
while (it2.hasNext()) {
it2.next();
const int format = it2.value();
if (format >= RawFormat && format < ArtificialFormatBase)
if (format != AutomaticFormat)
cmd->arg(it2.key(), format);
}
cmd->endGroup();
......@@ -1607,20 +1620,18 @@ void WatchHandler::appendFormatRequests(DebuggerCommand *cmd)
void WatchHandler::addDumpers(const GdbMi &dumpers)
{
foreach (const GdbMi &dumper, dumpers.children()) {
QStringList formats(tr("Raw structure"));
foreach (const QByteArray &format, dumper["formats"].data().split(',')) {
if (format == "Normal")
formats.append(tr("Normal"));
else if (format == "Displayed")
formats.append(tr("Displayed"));
else if (!format.isEmpty())
formats.append(QString::fromLatin1(format));
DisplayFormats formats;
formats.append(RawFormat);
QByteArray reportedFormats = dumper["formats"].data();
foreach (const QByteArray &format, reportedFormats.split(',')) {
if (int f = format.toInt())
formats.append(DisplayFormat(f));
}
addTypeFormats(dumper["type"].data(), formats);
}
}
void WatchHandler::addTypeFormats(const QByteArray &type, const QStringList &formats)
void WatchHandler::addTypeFormats(const QByteArray &type, const DisplayFormats &formats)
{
m_model->m_reportedTypeFormats.insert(QLatin1String(stripForFormat(type)), formats);
}
......@@ -1643,16 +1654,6 @@ QString WatchHandler::editorContents()
return contents;
}
void WatchHandler::setTypeFormats(const DumperTypeFormats &typeFormats)
{
m_model->m_reportedTypeFormats = typeFormats;
}
DumperTypeFormats WatchHandler::typeFormats() const
{
return m_model->m_reportedTypeFormats;
}
void WatchHandler::scheduleResetLocation()
{
m_model->m_contentsValid = false;
......@@ -1698,30 +1699,6 @@ QSet<QByteArray> WatchHandler::expandedINames() const
return m_model->m_expandedINames;
}
////////////////////////////////////////////////////////////////////
//
// TypeFormatItem/List
//
////////////////////////////////////////////////////////////////////
TypeFormatItem::TypeFormatItem(const QString &display, int format)
: display(display), format(format)
{}
void TypeFormatList::append(int format)
{
append(TypeFormatItem(WatchModel::nameForFormat(format), format));
}
TypeFormatItem TypeFormatList::find(int format) const
{
for (int i = 0; i != size(); ++i)
if (at(i).format == format)
return at(i);
return TypeFormatItem();
}
////////////////////////////////////////////////////////////////////
//
// WatchItem
......
......@@ -44,24 +44,49 @@ class DebuggerCommand;
class DebuggerEngine;
class WatchModel;
class TypeFormatItem
// Special formats. Keep in sync with dumper.py.
enum DisplayFormat
{
public:
TypeFormatItem() : format(-1) {}
TypeFormatItem(const QString &display, int format);
AutomaticFormat, // Based on type for individuals, dumper default for types.
RawFormat,
QString display;
int format;
};
SimpleFormat, // Typical simple format (e.g. for QModelIndex row/column)
EnhancedFormat, // Enhanced format (e.g. for QModelIndex with resolved display)
SeparateFormat, // Display in separate Window
class TypeFormatList : public QVector<TypeFormatItem>
{
public:
using QVector::append;
void append(int format);
TypeFormatItem find(int format) const;
Latin1StringFormat,
SeparateLatin1StringFormat,
Utf8StringFormat,
SeparateUtf8StringFormat,
Local8BitStringFormat,
Utf16StringFormat,
Ucs4StringFormat,
Array10Format,
Array100Format,
Array1000Format,
Array10000Format,
ArrayPlotFormat,
CompactMapFormat,
DirectQListStorageFormat,
IndirectQListStorageFormat,
// Not used in *.py.
BoolTextFormat,
BoolIntegerFormat,
DecimalIntegerFormat,
HexadecimalIntegerFormat,
BinaryIntegerFormat,
OctalIntegerFormat,
CompactFloatFormat,
ScientificFloatFormat,
};
typedef QVector<DisplayFormat> DisplayFormats;
class WatchItem : public Utils::TreeItem, public WatchData
{
public:
......@@ -91,7 +116,7 @@ private:
WatchItem *parentItem() const;
const WatchModel *watchModel() const;
WatchModel *watchModel();
TypeFormatList typeFormatList() const;
DisplayFormats typeFormatList() const;
bool canFetchMore() const;
QVariant data(int column, int role) const;
......@@ -101,46 +126,6 @@ private:
bool fetchTriggered;
};
// Special formats. Keep in sync with dumper.py.
enum DisplayFormat
{
AutomaticFormat = -1, // Based on type for individuals, dumper default for types.
RawFormat = 0,
// Values between 1 and 99 refer to dumper provided custom formats.
// Values between 100 and 199 refer to well-known formats handled in dumpers.
KnownDumperFormatBase = 100,
Latin1StringFormat,
Utf8StringFormat,
Local8BitStringFormat,
Utf16StringFormat,
Ucs4StringFormat,
Array10Format,
Array100Format,
Array1000Format,
Array10000Format,
SeparateLatin1StringFormat,
SeparateUtf8StringFormat,
// Values above 200 refer to format solely handled in the WatchHandler code
ArtificialFormatBase = 200,
BoolTextFormat,
BoolIntegerFormat,
DecimalIntegerFormat,
HexadecimalIntegerFormat,
BinaryIntegerFormat,
OctalIntegerFormat,
CompactFloatFormat,
ScientificFloatFormat,
};
class UpdateParameters
{
public:
......@@ -150,8 +135,6 @@ public:
QByteArray varList;
};
typedef QHash<QString, QStringList> DumperTypeFormats; // Type name -> Dumper Formats
class WatchModelBase : public Utils::TreeModel
{
Q_OBJECT
......@@ -201,11 +184,10 @@ public:
QByteArray individualFormatRequests() const;
int format(const QByteArray &iname) const;
static QString nameForFormat(int format);
void addDumpers(const GdbMi &dumpers);
void addTypeFormats(const QByteArray &type, const QStringList &formats);
void setTypeFormats(const DumperTypeFormats &typeFormats);
DumperTypeFormats typeFormats() const;
void addTypeFormats(const QByteArray &type, const DisplayFormats &formats);
void setUnprintableBase(int base);
static int unprintableBase();
......@@ -237,6 +219,6 @@ private:
} // namespace Debugger
Q_DECLARE_METATYPE(Debugger::Internal::UpdateParameters)
Q_DECLARE_METATYPE(Debugger::Internal::TypeFormatList)
Q_DECLARE_METATYPE(Debugger::Internal::DisplayFormats)
#endif // DEBUGGER_WATCHHANDLER_H
......@@ -554,12 +554,10 @@ void WatchTreeView::fillFormatMenu(QMenu *formatMenu, const QModelIndex &mi)
const QModelIndex mi2 = mi.sibling(mi.row(), 2);
const QString type = mi2.data().toString();
const TypeFormatList alternativeFormats =
mi.data(LocalsTypeFormatListRole).value<TypeFormatList>();
int typeFormat =
mi.data(LocalsTypeFormatRole).toInt();
const int individualFormat =
mi.data(LocalsIndividualFormatRole).toInt();
const DisplayFormats alternativeFormats =
mi.data(LocalsTypeFormatListRole).value<DisplayFormats>();
const int typeFormat = mi.data(LocalsTypeFormatRole).toInt();
const int individualFormat = mi.data(LocalsIndividualFormatRole).toInt();
const int unprintableBase = WatchHandler::unprintableBase();
QAction *showUnprintableUnicode = 0;
......@@ -595,7 +593,7 @@ void WatchTreeView::fillFormatMenu(QMenu *formatMenu, const QModelIndex &mi)
dummy->setEnabled(false);
QString msg = (individualFormat == AutomaticFormat && typeFormat != AutomaticFormat)
? tr("Use Format for Type (Currently %1)")
.arg(alternativeFormats.find(typeFormat).display)
.arg(WatchHandler::nameForFormat(typeFormat))
: tr("Use Display Format Based on Type") + QLatin1Char(' ');
QAction *clearIndividualFormatAction = formatMenu->addAction(spacer + msg);
......@@ -608,8 +606,8 @@ void WatchTreeView::fillFormatMenu(QMenu *formatMenu, const QModelIndex &mi)
});