summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2014-01-10 18:31:41 +0100
committerFrederik Gladhorn <frederik.gladhorn@digia.com>2014-01-10 18:31:41 +0100
commit0378cdb823631234f5d91ac8e0150dfb738aa1c9 (patch)
treec2d2dcb603c20772b6b6ad6c105834e13d2767ca /src
parent8895a66805e1a13bc909af30a545d78da65080d3 (diff)
parent372392cf6e14ececbaff8aa54d2a7230ad17ba5f (diff)
Merge remote-tracking branch 'origin/stable' into dev
Diffstat (limited to 'src')
-rw-r--r--src/linguist/lupdate/cpp.cpp618
-rw-r--r--src/linguist/lupdate/java.cpp4
-rw-r--r--src/linguist/lupdate/lupdate.h16
-rw-r--r--src/linguist/lupdate/main.cpp54
-rw-r--r--src/qdbus/qdbusviewer/logviewer.cpp59
-rw-r--r--src/qdbus/qdbusviewer/logviewer.h57
-rw-r--r--src/qdbus/qdbusviewer/main.cpp3
-rw-r--r--src/qdbus/qdbusviewer/qdbusviewer.cpp5
-rw-r--r--src/qdbus/qdbusviewer/qdbusviewer.pro4
9 files changed, 453 insertions, 367 deletions
diff --git a/src/linguist/lupdate/cpp.cpp b/src/linguist/lupdate/cpp.cpp
index b282e8f57..b644d0c88 100644
--- a/src/linguist/lupdate/cpp.cpp
+++ b/src/linguist/lupdate/cpp.cpp
@@ -207,7 +207,7 @@ public:
void setInput(const QString &in);
void setInput(QTextStream &ts, const QString &fileName);
void setTranslator(Translator *_tor) { tor = _tor; }
- void parse(const QString &initialContext, ConversionData &cd, const QStringList &includeStack, QSet<QString> &inclusions);
+ void parse(ConversionData &cd, const QStringList &includeStack, QSet<QString> &inclusions);
void parseInternal(ConversionData &cd, const QStringList &includeStack, QSet<QString> &inclusions);
const ParseResults *recordResults(bool isHeader);
void deleteResults() { delete results; }
@@ -237,15 +237,25 @@ private:
int elseLine;
};
+ enum TokenType {
+ Tok_Eof, Tok_class, Tok_friend, Tok_namespace, Tok_using, Tok_return,
+ Tok_Q_OBJECT, Tok_Access, Tok_Cancel,
+ Tok_Ident, Tok_String, Tok_Arrow, Tok_Colon, Tok_ColonColon,
+ Tok_Equals, Tok_LeftBracket, Tok_RightBracket,
+ Tok_LeftBrace, Tok_RightBrace, Tok_LeftParen, Tok_RightParen, Tok_Comma, Tok_Semicolon,
+ Tok_Null, Tok_Integer,
+ Tok_QuotedInclude, Tok_AngledInclude,
+ Tok_Other
+ };
+
std::ostream &yyMsg(int line = 0);
int getChar();
- uint getToken();
- bool getMacroArgs();
+ TokenType getToken();
void processComment();
- bool match(uint t);
+ bool match(TokenType t);
bool matchString(QString *s);
bool matchEncoding();
bool matchStringOrNull(QString *s);
@@ -257,21 +267,27 @@ private:
const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra,
bool plural);
+ void handleTr(QString &prefix);
+ void handleTranslate();
+ void handleTrId();
+ void handleDeclareTrFunctions();
+
void processInclude(const QString &file, ConversionData &cd,
const QStringList &includeStack, QSet<QString> &inclusions);
void saveState(SavedState *state);
void loadState(const SavedState *state);
- static QString stringifyNamespace(const NamespaceList &namespaces);
- static QStringList stringListifyNamespace(const NamespaceList &namespaces);
+ static QString stringifyNamespace(int start, const NamespaceList &namespaces);
+ static QString stringifyNamespace(const NamespaceList &namespaces)
+ { return stringifyNamespace(1, namespaces); }
+ static QString joinNamespaces(const QString &one, const QString &two);
typedef bool (CppParser::*VisitNamespaceCallback)(const Namespace *ns, void *context) const;
bool visitNamespace(const NamespaceList &namespaces, int nsCount,
VisitNamespaceCallback callback, void *context,
VisitRecorder &vr, const ParseResults *rslt) const;
bool visitNamespace(const NamespaceList &namespaces, int nsCount,
VisitNamespaceCallback callback, void *context) const;
- static QStringList stringListifySegments(const QList<HashString> &namespaces);
bool qualifyOneCallbackOwn(const Namespace *ns, void *context) const;
bool qualifyOneCallbackUsing(const Namespace *ns, void *context) const;
bool qualifyOne(const NamespaceList &namespaces, int nsCnt, const HashString &segment,
@@ -279,32 +295,20 @@ private:
bool qualifyOne(const NamespaceList &namespaces, int nsCnt, const HashString &segment,
NamespaceList *resolved) const;
bool fullyQualify(const NamespaceList &namespaces, int nsCnt,
- const QList<HashString> &segments, bool isDeclaration,
- NamespaceList *resolved, QStringList *unresolved) const;
+ const NamespaceList &segments, bool isDeclaration,
+ NamespaceList *resolved, NamespaceList *unresolved) const;
bool fullyQualify(const NamespaceList &namespaces,
- const QList<HashString> &segments, bool isDeclaration,
- NamespaceList *resolved, QStringList *unresolved) const;
+ const NamespaceList &segments, bool isDeclaration,
+ NamespaceList *resolved, NamespaceList *unresolved) const;
bool fullyQualify(const NamespaceList &namespaces,
const QString &segments, bool isDeclaration,
- NamespaceList *resolved, QStringList *unresolved) const;
+ NamespaceList *resolved, NamespaceList *unresolved) const;
bool findNamespaceCallback(const Namespace *ns, void *context) const;
const Namespace *findNamespace(const NamespaceList &namespaces, int nsCount = -1) const;
void enterNamespace(NamespaceList *namespaces, const HashString &name);
void truncateNamespaces(NamespaceList *namespaces, int lenght);
Namespace *modifyNamespace(NamespaceList *namespaces, bool haveLast = true);
- enum TokenType {
- Tok_Eof, Tok_class, Tok_friend, Tok_namespace, Tok_using, Tok_return,
- Tok_tr, Tok_trUtf8, Tok_translate, Tok_translateUtf8, Tok_trid,
- Tok_Q_OBJECT, Tok_Q_DECLARE_TR_FUNCTIONS, Tok_Access, Tok_Cancel,
- Tok_Ident, Tok_String, Tok_Arrow, Tok_Colon, Tok_ColonColon,
- Tok_Equals, Tok_LeftBracket, Tok_RightBracket,
- Tok_LeftBrace, Tok_RightBrace, Tok_LeftParen, Tok_RightParen, Tok_Comma, Tok_Semicolon,
- Tok_Null, Tok_Integer,
- Tok_QuotedInclude, Tok_AngledInclude,
- Tok_Other
- };
-
// Tokenizer state
QString yyFileName;
int yyCh;
@@ -327,7 +331,7 @@ private:
const ushort *yyInPtr;
// Parser state
- uint yyTok;
+ TokenType yyTok;
bool metaExpected;
QString context;
@@ -459,34 +463,6 @@ int CppParser::getChar()
}
}
-// This ignores commas, parens and comments.
-// IOW, it understands only a single, simple argument.
-bool CppParser::getMacroArgs()
-{
- // Failing this assertion would mean losing the preallocated buffer.
- Q_ASSERT(yyWord.isDetached());
- yyWord.resize(0);
-
- while (isspace(yyCh))
- yyCh = getChar();
- if (yyCh != '(')
- return false;
- do {
- yyCh = getChar();
- } while (isspace(yyCh));
- ushort *ptr = (ushort *)yyWord.unicode();
- while (yyCh != ')') {
- if (yyCh == EOF)
- return false;
- *ptr++ = yyCh;
- yyCh = getChar();
- }
- yyCh = getChar();
- for (; ptr != (ushort *)yyWord.unicode() && isspace(*(ptr - 1)); --ptr) ;
- yyWord.resize(ptr - (ushort *)yyWord.unicode());
- return true;
-}
-
STRING(Q_OBJECT);
STRING(class);
STRING(friend);
@@ -503,12 +479,11 @@ STRING(signals);
STRING(Q_SLOTS);
STRING(Q_SIGNALS);
-uint CppParser::getToken()
+CppParser::TokenType CppParser::getToken()
{
restart:
// Failing this assertion would mean losing the preallocated buffer.
Q_ASSERT(yyWord.isDetached());
- yyWord.resize(0);
while (yyCh != EOF) {
yyLineNo = yyCurLineNo;
@@ -766,30 +741,6 @@ uint CppParser::getToken()
break;
}
- static const TokenType trFunctionTokens[] = {
- Tok_Q_DECLARE_TR_FUNCTIONS, // Q_DECLARE_TR_FUNCTIONS
- Tok_tr, // QT_TR_NOOP
- Tok_trid, // QT_TRID_NOOP
- Tok_translate, // QT_TRANSLATE_NOOP
- Tok_translate, // QT_TRANSLATE_NOOP3
- Tok_trUtf8, // QT_TR_NOOP_UTF8
- Tok_translateUtf8, // QT_TRANSLATE_NOOP_UTF8
- Tok_translateUtf8, // QT_TRANSLATE_NOOP3_UTF8
- Tok_translate, // findMessage
- Tok_trid, // qtTrId
- Tok_tr, // tr
- Tok_trUtf8, // trUtf8
- Tok_translate, // translate
- Tok_Ident, // qsTr (QML only)
- Tok_Ident, // qsTrId (QML only)
- Tok_Ident, // qsTranslate (QML only)
- };
- Q_STATIC_ASSERT((sizeof trFunctionTokens / sizeof *trFunctionTokens == TrFunctionAliasManager::NumTrFunctions));
-
- const int trFunction = trFunctionAliasManager.trFunctionByName(yyWord);
- if (trFunction >= 0)
- return trFunctionTokens[trFunction];
-
return Tok_Ident;
} else {
switch (yyCh) {
@@ -1038,23 +989,24 @@ Namespace *CppParser::modifyNamespace(NamespaceList *namespaces, bool haveLast)
return ns;
}
-QString CppParser::stringifyNamespace(const NamespaceList &namespaces)
+QString CppParser::stringifyNamespace(int start, const NamespaceList &namespaces)
{
QString ret;
- for (int i = 1; i < namespaces.count(); ++i) {
- if (i > 1)
+ int l = 0;
+ for (int j = start; j < namespaces.count(); ++j)
+ l += namespaces.at(j).value().length();
+ ret.reserve(l + qMax(0, (namespaces.count() - start - 1)) * 2);
+ for (int i = start; i < namespaces.count(); ++i) {
+ if (i > start)
ret += QLatin1String("::");
ret += namespaces.at(i).value();
}
return ret;
}
-QStringList CppParser::stringListifyNamespace(const NamespaceList &namespaces)
+QString CppParser::joinNamespaces(const QString &one, const QString &two)
{
- QStringList ret;
- for (int i = 1; i < namespaces.count(); ++i)
- ret << namespaces.at(i).value();
- return ret;
+ return two.isEmpty() ? one : one.isEmpty() ? two : one + QStringLiteral("::") + two;
}
bool CppParser::visitNamespace(const NamespaceList &namespaces, int nsCount,
@@ -1082,14 +1034,6 @@ bool CppParser::visitNamespace(const NamespaceList &namespaces, int nsCount,
return visitNamespace(namespaces, nsCount, callback, context, vr, results);
}
-QStringList CppParser::stringListifySegments(const QList<HashString> &segments)
-{
- QStringList ret;
- for (int i = 0; i < segments.count(); ++i)
- ret << segments.at(i).value();
- return ret;
-}
-
struct QualifyOneData {
QualifyOneData(const NamespaceList &ns, int nsc, const HashString &seg, NamespaceList *rslvd,
QSet<HashStringList> *visited)
@@ -1163,8 +1107,8 @@ bool CppParser::qualifyOne(const NamespaceList &namespaces, int nsCnt, const Has
}
bool CppParser::fullyQualify(const NamespaceList &namespaces, int nsCnt,
- const QList<HashString> &segments, bool isDeclaration,
- NamespaceList *resolved, QStringList *unresolved) const
+ const NamespaceList &segments, bool isDeclaration,
+ NamespaceList *resolved, NamespaceList *unresolved) const
{
int nsIdx;
int initSegIdx;
@@ -1189,7 +1133,7 @@ bool CppParser::fullyQualify(const NamespaceList &namespaces, int nsCnt,
while (++segIdx < segments.count()) {
if (!qualifyOne(*resolved, resolved->count(), segments[segIdx], resolved)) {
if (unresolved)
- *unresolved = stringListifySegments(segments.mid(segIdx));
+ *unresolved = segments.mid(segIdx);
return false;
}
}
@@ -1199,13 +1143,13 @@ bool CppParser::fullyQualify(const NamespaceList &namespaces, int nsCnt,
resolved->clear();
*resolved << HashString(QString());
if (unresolved)
- *unresolved = stringListifySegments(segments.mid(initSegIdx));
+ *unresolved = segments.mid(initSegIdx);
return false;
}
bool CppParser::fullyQualify(const NamespaceList &namespaces,
- const QList<HashString> &segments, bool isDeclaration,
- NamespaceList *resolved, QStringList *unresolved) const
+ const NamespaceList &segments, bool isDeclaration,
+ NamespaceList *resolved, NamespaceList *unresolved) const
{
return fullyQualify(namespaces, namespaces.count(),
segments, isDeclaration, resolved, unresolved);
@@ -1213,11 +1157,11 @@ bool CppParser::fullyQualify(const NamespaceList &namespaces,
bool CppParser::fullyQualify(const NamespaceList &namespaces,
const QString &quali, bool isDeclaration,
- NamespaceList *resolved, QStringList *unresolved) const
+ NamespaceList *resolved, NamespaceList *unresolved) const
{
static QString strColons(QLatin1String("::"));
- QList<HashString> segments;
+ NamespaceList segments;
foreach (const QString &str, quali.split(strColons)) // XXX slow, but needs to be fast(?)
segments << HashString(str);
return fullyQualify(namespaces, segments, isDeclaration, resolved, unresolved);
@@ -1404,7 +1348,7 @@ void CppParser::processInclude(const QString &file, ConversionData &cd, const QS
parser.setInput(ts, cleanFile);
QStringList stack = includeStack;
stack << cleanFile;
- parser.parse(cd.m_defaultContext, cd, stack, inclusions);
+ parser.parse(cd, stack, inclusions);
results->includes.insert(parser.recordResults(true));
} else {
CppParser parser(results);
@@ -1435,7 +1379,7 @@ void CppParser::processInclude(const QString &file, ConversionData &cd, const QS
appears within a function defined outside the class definition.
*/
-bool CppParser::match(uint t)
+bool CppParser::match(TokenType t)
{
bool matches = (yyTok == t);
if (matches)
@@ -1588,12 +1532,210 @@ void CppParser::recordMessage(int line, const QString &context, const QString &t
tor->append(msg);
}
-void CppParser::parse(const QString &initialContext, ConversionData &cd, const QStringList &includeStack,
+void CppParser::handleTr(QString &prefix)
+{
+ if (!sourcetext.isEmpty())
+ yyMsg() << qPrintable(LU::tr("//% cannot be used with tr() / QT_TR_NOOP(). Ignoring\n"));
+ int line = yyLineNo;
+ yyTok = getToken();
+ if (matchString(&text) && !text.isEmpty()) {
+ comment.clear();
+ bool plural = false;
+
+ if (yyTok == Tok_RightParen) {
+ // no comment
+ } else if (match(Tok_Comma) && matchStringOrNull(&comment)) { //comment
+ if (yyTok == Tok_RightParen) {
+ // ok,
+ } else if (match(Tok_Comma)) {
+ plural = true;
+ }
+ }
+ if (!pendingContext.isEmpty() && !prefix.startsWith(QLatin1String("::"))) {
+ NamespaceList unresolved;
+ if (!fullyQualify(namespaces, pendingContext, true, &functionContext, &unresolved)) {
+ functionContextUnresolved = stringifyNamespace(0, unresolved);
+ yyMsg() << qPrintable(LU::tr("Qualifying with unknown namespace/class %1::%2\n")
+ .arg(stringifyNamespace(functionContext)).arg(unresolved.first().value()));
+ }
+ pendingContext.clear();
+ }
+ if (prefix.isEmpty()) {
+ if (functionContextUnresolved.isEmpty()) {
+ int idx = functionContext.length();
+ if (idx < 2) {
+ yyMsg() << qPrintable(LU::tr("tr() cannot be called without context\n"));
+ return;
+ }
+ Namespace *fctx;
+ while (!(fctx = findNamespace(functionContext, idx)->classDef)->hasTrFunctions) {
+ if (idx == 1) {
+ context = stringifyNamespace(functionContext);
+ fctx = findNamespace(functionContext)->classDef;
+ if (!fctx->complained) {
+ yyMsg() << qPrintable(LU::tr("Class '%1' lacks Q_OBJECT macro\n")
+ .arg(context));
+ fctx->complained = true;
+ }
+ goto gotctx;
+ }
+ --idx;
+ }
+ if (fctx->trQualification.isEmpty()) {
+ context.clear();
+ for (int i = 1;;) {
+ context += functionContext.at(i).value();
+ if (++i == idx)
+ break;
+ context += QLatin1String("::");
+ }
+ fctx->trQualification = context;
+ } else {
+ context = fctx->trQualification;
+ }
+ } else {
+ context = joinNamespaces(stringifyNamespace(functionContext), functionContextUnresolved);
+ }
+ } else {
+#ifdef DIAGNOSE_RETRANSLATABILITY
+ int last = prefix.lastIndexOf(QLatin1String("::"));
+ QString className = prefix.mid(last == -1 ? 0 : last + 2);
+ if (!className.isEmpty() && className == functionName) {
+ yyMsg() << qPrintable(LU::tr("It is not recommended to call tr() from within a constructor '%1::%2'\n")
+ .arg(className).arg(functionName));
+ }
+#endif
+ prefix.chop(2);
+ NamespaceList nsl;
+ NamespaceList unresolved;
+ if (fullyQualify(functionContext, prefix, false, &nsl, &unresolved)) {
+ Namespace *fctx = findNamespace(nsl)->classDef;
+ if (fctx->trQualification.isEmpty()) {
+ context = stringifyNamespace(nsl);
+ fctx->trQualification = context;
+ } else {
+ context = fctx->trQualification;
+ }
+ if (!fctx->hasTrFunctions && !fctx->complained) {
+ yyMsg() << qPrintable(LU::tr("Class '%1' lacks Q_OBJECT macro\n").arg(context));
+ fctx->complained = true;
+ }
+ } else {
+ context = joinNamespaces(stringifyNamespace(nsl), stringifyNamespace(0, unresolved));
+ }
+ prefix.clear();
+ }
+
+ gotctx:
+ recordMessage(line, context, text, comment, extracomment, msgid, extra, plural);
+ }
+ sourcetext.clear(); // Will have warned about that already
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ metaExpected = false;
+}
+
+void CppParser::handleTranslate()
+{
+ if (!sourcetext.isEmpty())
+ yyMsg() << qPrintable(LU::tr("//% cannot be used with translate() / QT_TRANSLATE_NOOP(). Ignoring\n"));
+ int line = yyLineNo;
+ yyTok = getToken();
+ if (matchString(&context)
+ && match(Tok_Comma)
+ && matchString(&text) && !text.isEmpty())
+ {
+ comment.clear();
+ bool plural = false;
+ if (yyTok != Tok_RightParen) {
+ // look for comment
+ if (match(Tok_Comma) && matchStringOrNull(&comment)) {
+ if (yyTok != Tok_RightParen) {
+ // look for encoding
+ if (match(Tok_Comma)) {
+ if (matchEncoding()) {
+ if (yyTok != Tok_RightParen) {
+ // look for the plural quantifier,
+ // this can be a number, an identifier or
+ // a function call,
+ // so for simplicity we mark it as plural if
+ // we know we have a comma instead of an
+ // right parentheses.
+ plural = match(Tok_Comma);
+ }
+ } else {
+ // This can be a QTranslator::translate("context",
+ // "source", "comment", n) plural translation
+ if (matchExpression() && yyTok == Tok_RightParen) {
+ plural = true;
+ } else {
+ return;
+ }
+ }
+ } else {
+ return;
+ }
+ }
+ } else {
+ return;
+ }
+ }
+ recordMessage(line, context, text, comment, extracomment, msgid, extra, plural);
+ }
+ sourcetext.clear(); // Will have warned about that already
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ metaExpected = false;
+}
+
+void CppParser::handleTrId()
+{
+ if (!msgid.isEmpty())
+ yyMsg() << qPrintable(LU::tr("//= cannot be used with qtTrId() / QT_TRID_NOOP(). Ignoring\n"));
+ int line = yyLineNo;
+ yyTok = getToken();
+ if (matchString(&msgid) && !msgid.isEmpty()) {
+ bool plural = match(Tok_Comma);
+ recordMessage(line, QString(), sourcetext, QString(), extracomment,
+ msgid, extra, plural);
+ }
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ metaExpected = false;
+}
+
+void CppParser::handleDeclareTrFunctions()
+{
+ QString name;
+ forever {
+ yyTok = getToken();
+ if (yyTok != Tok_Ident)
+ return;
+ name += yyWord;
+ name.detach();
+ yyTok = getToken();
+ if (yyTok == Tok_RightParen)
+ break;
+ if (yyTok != Tok_ColonColon)
+ return;
+ name += QLatin1String("::");
+ }
+ Namespace *ns = modifyNamespace(&namespaces);
+ ns->hasTrFunctions = true;
+ ns->trQualification = name;
+ ns->trQualification.detach();
+}
+
+void CppParser::parse(ConversionData &cd, const QStringList &includeStack,
QSet<QString> &inclusions)
{
namespaces << HashString();
functionContext = namespaces;
- functionContextUnresolved = initialContext;
+ functionContextUnresolved.clear();
parseInternal(cd, includeStack, inclusions);
}
@@ -1606,7 +1748,6 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac
#ifdef DIAGNOSE_RETRANSLATABILITY
QString functionName;
#endif
- int line;
bool yyTokColonSeen = false; // Start of c'tor's initializer list
metaExpected = true;
@@ -1669,7 +1810,7 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac
*/
yyTok = getToken();
if (yyBraceDepth == namespaceDepths.count() && yyParenDepth == 0) {
- QList<HashString> quali;
+ NamespaceList quali;
HashString fct;
do {
/*
@@ -1753,7 +1894,7 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac
yyTok = getToken();
} else if (yyTok == Tok_Equals) {
// e.g. namespace Is = OuterSpace::InnerSpace;
- QList<HashString> fullName;
+ NamespaceList fullName;
yyTok = getToken();
if (yyTok == Tok_ColonColon)
fullName.append(HashString(QString()));
@@ -1781,7 +1922,7 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac
yyTok = getToken();
// XXX this should affect only the current scope, not the entire current namespace
if (yyTok == Tok_namespace) {
- QList<HashString> fullName;
+ NamespaceList fullName;
yyTok = getToken();
if (yyTok == Tok_ColonColon)
fullName.append(HashString(QString()));
@@ -1797,7 +1938,7 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac
if (fullyQualify(namespaces, fullName, false, &nsl, 0))
modifyNamespace(&namespaces)->usings << HashStringList(nsl);
} else {
- QList<HashString> fullName;
+ NamespaceList fullName;
if (yyTok == Tok_ColonColon)
fullName.append(HashString(QString()));
while (yyTok == Tok_ColonColon || yyTok == Tok_Ident) {
@@ -1814,211 +1955,54 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac
// fullName is already the resolved name we actually want.
// As we do no resolution here, we'll collect useless usings of data
// members and methods as well. This is no big deal.
- HashString &ns = fullName.last();
fullName.append(HashString(QString())); // Mark as unresolved
+ const HashString &ns = *(fullName.constEnd() - 2);
modifyNamespace(&namespaces)->aliases[ns] = fullName;
}
break;
- case Tok_tr:
- case Tok_trUtf8:
- if (!tor)
- goto case_default;
- if (!sourcetext.isEmpty())
- yyMsg() << qPrintable(LU::tr("//% cannot be used with tr() / QT_TR_NOOP(). Ignoring\n"));
- line = yyLineNo;
- yyTok = getToken();
- if (match(Tok_LeftParen) && matchString(&text) && !text.isEmpty()) {
- comment.clear();
- bool plural = false;
-
- if (yyTok == Tok_RightParen) {
- // no comment
- } else if (match(Tok_Comma) && matchStringOrNull(&comment)) { //comment
- if (yyTok == Tok_RightParen) {
- // ok,
- } else if (match(Tok_Comma)) {
- plural = true;
- }
- }
- if (!pendingContext.isEmpty() && !prefix.startsWith(strColons)) {
- QStringList unresolved;
- if (!fullyQualify(namespaces, pendingContext, true, &functionContext, &unresolved)) {
- functionContextUnresolved = unresolved.join(strColons);
- yyMsg() << qPrintable(LU::tr("Qualifying with unknown namespace/class %1::%2\n")
- .arg(stringifyNamespace(functionContext)).arg(unresolved.first()));
- }
- pendingContext.clear();
- }
- if (prefix.isEmpty()) {
- if (functionContextUnresolved.isEmpty()) {
- int idx = functionContext.length();
- if (idx < 2) {
- yyMsg() << qPrintable(LU::tr("tr() cannot be called without context\n"));
- goto case_default;
- }
- Namespace *fctx;
- while (!(fctx = findNamespace(functionContext, idx)->classDef)->hasTrFunctions) {
- if (idx == 1) {
- context = stringifyNamespace(functionContext);
- fctx = findNamespace(functionContext)->classDef;
- if (!fctx->complained) {
- yyMsg() << qPrintable(LU::tr("Class '%1' lacks Q_OBJECT macro\n")
- .arg(context));
- fctx->complained = true;
- }
- goto gotctx;
- }
- --idx;
- }
- if (fctx->trQualification.isEmpty()) {
- context.clear();
- for (int i = 1;;) {
- context += functionContext.at(i).value();
- if (++i == idx)
- break;
- context += strColons;
- }
- fctx->trQualification = context;
- } else {
- context = fctx->trQualification;
- }
- } else {
- context = (stringListifyNamespace(functionContext)
- << functionContextUnresolved).join(strColons);
- }
- } else {
-#ifdef DIAGNOSE_RETRANSLATABILITY
- int last = prefix.lastIndexOf(strColons);
- QString className = prefix.mid(last == -1 ? 0 : last + 2);
- if (!className.isEmpty() && className == functionName) {
- yyMsg() << qPrintable(LU::tr("It is not recommended to call tr() from within a constructor '%1::%2'\n")
- .arg(className).arg(functionName));
- }
-#endif
- prefix.chop(2);
- NamespaceList nsl;
- QStringList unresolved;
- if (fullyQualify(functionContext, prefix, false, &nsl, &unresolved)) {
- Namespace *fctx = findNamespace(nsl)->classDef;
- if (fctx->trQualification.isEmpty()) {
- context = stringifyNamespace(nsl);
- fctx->trQualification = context;
- } else {
- context = fctx->trQualification;
- }
- if (!fctx->hasTrFunctions && !fctx->complained) {
- yyMsg() << qPrintable(LU::tr("Class '%1' lacks Q_OBJECT macro\n").arg(context));
- fctx->complained = true;
- }
- } else {
- context = (stringListifyNamespace(nsl) + unresolved).join(strColons);
- }
- prefix.clear();
- }
-
- gotctx:
- recordMessage(line, context, text, comment, extracomment, msgid, extra, plural);
- }
- sourcetext.clear(); // Will have warned about that already
- extracomment.clear();
- msgid.clear();
- extra.clear();
- metaExpected = false;
- yyTok = getToken();
- break;
- case Tok_translateUtf8:
- case Tok_translate:
- if (!tor)
- goto case_default;
- if (!sourcetext.isEmpty())
- yyMsg() << qPrintable(LU::tr("//% cannot be used with translate() / QT_TRANSLATE_NOOP(). Ignoring\n"));
- line = yyLineNo;
- yyTok = getToken();
- if (match(Tok_LeftParen)
- && matchString(&context)
- && match(Tok_Comma)
- && matchString(&text) && !text.isEmpty())
- {
- comment.clear();
- bool plural = false;
- if (yyTok != Tok_RightParen) {
- // look for comment
- if (match(Tok_Comma) && matchStringOrNull(&comment)) {
- if (yyTok != Tok_RightParen) {
- // look for encoding
- if (match(Tok_Comma)) {
- if (matchEncoding()) {
- if (yyTok != Tok_RightParen) {
- // look for the plural quantifier,
- // this can be a number, an identifier or
- // a function call,
- // so for simplicity we mark it as plural if
- // we know we have a comma instead of an
- // right parentheses.
- plural = match(Tok_Comma);
- }
- } else {
- // This can be a QTranslator::translate("context",
- // "source", "comment", n) plural translation
- if (matchExpression() && yyTok == Tok_RightParen) {
- plural = true;
- } else {
- goto case_default;
- }
- }
- } else {
- goto case_default;
- }
- }
- } else {
- goto case_default;
- }
- }
- recordMessage(line, context, text, comment, extracomment, msgid, extra, plural);
- }
- sourcetext.clear(); // Will have warned about that already
- extracomment.clear();
- msgid.clear();
- extra.clear();
- metaExpected = false;
- yyTok = getToken();
- break;
- case Tok_trid:
- if (!tor)
- goto case_default;
- if (!msgid.isEmpty())
- yyMsg() << qPrintable(LU::tr("//= cannot be used with qtTrId() / QT_TRID_NOOP(). Ignoring\n"));
- line = yyLineNo;
- yyTok = getToken();
- if (match(Tok_LeftParen) && matchString(&msgid) && !msgid.isEmpty()) {
- bool plural = match(Tok_Comma);
- recordMessage(line, QString(), sourcetext, QString(), extracomment,
- msgid, extra, plural);
- }
- sourcetext.clear();
- extracomment.clear();
- msgid.clear();
- extra.clear();
- metaExpected = false;
- break;
- case Tok_Q_DECLARE_TR_FUNCTIONS:
- if (getMacroArgs()) {
- Namespace *ns = modifyNamespace(&namespaces);
- ns->hasTrFunctions = true;
- ns->trQualification = yyWord;
- ns->trQualification.detach();
- }
- yyTok = getToken();
- break;
case Tok_Q_OBJECT:
modifyNamespace(&namespaces)->hasTrFunctions = true;
yyTok = getToken();
break;
case Tok_Ident:
- prefix += yyWord;
- prefix.detach();
yyTok = getToken();
- if (yyTok != Tok_ColonColon) {
+ if (yyTok == Tok_LeftParen) {
+ switch (trFunctionAliasManager.trFunctionByName(yyWord)) {
+ case TrFunctionAliasManager::Function_Q_DECLARE_TR_FUNCTIONS:
+ handleDeclareTrFunctions();
+ break;
+ case TrFunctionAliasManager::Function_tr:
+ case TrFunctionAliasManager::Function_trUtf8:
+ case TrFunctionAliasManager::Function_QT_TR_NOOP:
+ case TrFunctionAliasManager::Function_QT_TR_NOOP_UTF8:
+ if (tor)
+ handleTr(prefix);
+ break;
+ case TrFunctionAliasManager::Function_translate:
+ case TrFunctionAliasManager::Function_findMessage:
+ case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP:
+ case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP_UTF8:
+ case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP3:
+ case TrFunctionAliasManager::Function_QT_TRANSLATE_NOOP3_UTF8:
+ if (tor)
+ handleTranslate();
+ break;
+ case TrFunctionAliasManager::Function_qtTrId:
+ case TrFunctionAliasManager::Function_QT_TRID_NOOP:
+ if (tor)
+ handleTrId();
+ break;
+ default:
+ goto notrfunc;
+ }
+ yyTok = getToken();
+ break;
+ }
+ if (yyTok == Tok_ColonColon) {
+ prefix += yyWord;
+ prefix.detach();
+ } else {
+ notrfunc:
prefix.clear();
if (yyTok == Tok_Ident && !yyParenDepth)
prospectiveContext.clear();
@@ -2027,8 +2011,14 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac
break;
case Tok_Arrow:
yyTok = getToken();
- if (yyTok == Tok_tr || yyTok == Tok_trUtf8)
- yyMsg() << qPrintable(LU::tr("Cannot invoke tr() like this\n"));
+ if (yyTok == Tok_Ident) {
+ switch (trFunctionAliasManager.trFunctionByName(yyWord)) {
+ case TrFunctionAliasManager::Function_tr:
+ case TrFunctionAliasManager::Function_trUtf8:
+ yyMsg() << qPrintable(LU::tr("Cannot invoke tr() like this\n"));
+ break;
+ }
+ }
break;
case Tok_ColonColon:
if (yyBraceDepth == namespaceDepths.count() && yyParenDepth == 0 && !yyTokColonSeen)
@@ -2047,13 +2037,11 @@ void CppParser::parseInternal(ConversionData &cd, const QStringList &includeStac
truncateNamespaces(&namespaces, namespaceDepths.pop());
if (yyBraceDepth == namespaceDepths.count()) {
// function, class or namespace
- if (!yyBraceDepth && !directInclude) {
+ if (!yyBraceDepth && !directInclude)
truncateNamespaces(&functionContext, 1);
- functionContextUnresolved = cd.m_defaultContext;
- } else {
+ else
functionContext = namespaces;
- functionContextUnresolved.clear();
- }
+ functionContextUnresolved.clear();
pendingContext.clear();
}
// fallthrough
@@ -2275,7 +2263,7 @@ void loadCPP(Translator &translator, const QStringList &filenames, ConversionDat
Translator *tor = new Translator;
parser.setTranslator(tor);
QSet<QString> inclusions;
- parser.parse(cd.m_defaultContext, cd, QStringList(), inclusions);
+ parser.parse(cd, QStringList(), inclusions);
parser.recordResults(isHeader(filename));
}
diff --git a/src/linguist/lupdate/java.cpp b/src/linguist/lupdate/java.cpp
index f64de80e3..aad608e82 100644
--- a/src/linguist/lupdate/java.cpp
+++ b/src/linguist/lupdate/java.cpp
@@ -112,7 +112,6 @@ static int yyInPos;
// The parser maintains the following global variables.
static QString yyPackage;
static QStack<Scope*> yyScope;
-static QString yyDefaultContext;
std::ostream &yyMsg(int line = 0)
{
@@ -446,7 +445,7 @@ static const QString context()
innerClass = true;
}
}
- return context.isEmpty() ? yyDefaultContext : context;
+ return context;
}
static void recordMessage(
@@ -606,7 +605,6 @@ bool loadJava(Translator &translator, const QString &filename, ConversionData &c
return false;
}
- yyDefaultContext = cd.m_defaultContext;
yyInPos = -1;
yyFileName = filename;
yyPackage.clear();
diff --git a/src/linguist/lupdate/lupdate.h b/src/linguist/lupdate/lupdate.h
index bc1fa421d..5428306a7 100644
--- a/src/linguist/lupdate/lupdate.h
+++ b/src/linguist/lupdate/lupdate.h
@@ -44,9 +44,9 @@
#include "qglobal.h"
-#include <QByteArray>
#include <QList>
#include <QString>
+#include <QStringList>
#include <QHash>
QT_BEGIN_NAMESPACE
@@ -124,16 +124,12 @@ public:
enum Operation { AddAlias, SetAlias };
- int trFunctionByName(const QByteArray &trFunctionByName) const;
- int trFunctionByName(const QString &trFunctionName) const
- { return trFunctionByName(trFunctionName.toLatin1()); }
+ int trFunctionByName(const QString &trFunctionName) const;
- void modifyAlias(int trFunction, const QByteArray &alias, Operation op);
+ void modifyAlias(int trFunction, const QString &alias, Operation op);
- bool isAliasFor(const QByteArray &identifier, TrFunction trFunction) const
- { return m_trFunctionAliases[trFunction].contains(identifier); }
bool isAliasFor(const QString &identifier, TrFunction trFunction) const
- { return isAliasFor(identifier.toLatin1(), trFunction); }
+ { return m_trFunctionAliases[trFunction].contains(identifier); }
QStringList availableFunctionsWithAliases() const;
@@ -141,8 +137,8 @@ private:
void ensureTrFunctionHashUpdated() const;
private:
- QList<QByteArray> m_trFunctionAliases[NumTrFunctions];
- mutable QHash<QByteArray,TrFunction> m_nameToTrFunctionMap;
+ QStringList m_trFunctionAliases[NumTrFunctions];
+ mutable QHash<QString,TrFunction> m_nameToTrFunctionMap;
};
QT_END_NAMESPACE
diff --git a/src/linguist/lupdate/main.cpp b/src/linguist/lupdate/main.cpp
index 41eb7fbdf..bf3a601eb 100644
--- a/src/linguist/lupdate/main.cpp
+++ b/src/linguist/lupdate/main.cpp
@@ -60,23 +60,23 @@
#include <iostream>
-// Can't have an array of QStaticByteArrayData<N> for different N, so
-// use QByteArray, which requires constructor calls. Doesn't matter
+// Can't have an array of QStaticStringData<N> for different N, so
+// use QString, which requires constructor calls. Doesn't matter
// much, since this is in an app, not a lib:
-static const QByteArray defaultTrFunctionNames[] = {
-// MSVC can't handle the lambda in this array if QByteArrayLiteral expands
-// to a lambda. In that case, use a QByteArray instead.
+static const QString defaultTrFunctionNames[] = {
+// MSVC can't handle the lambda in this array if QStringLiteral expands
+// to a lambda. In that case, use a QString instead.
#if defined(Q_CC_MSVC) && defined(Q_COMPILER_LAMBDA)
-#define BYTEARRAYLITERAL(F) QByteArray(#F),
+#define STRINGLITERAL(F) QLatin1String(#F),
#else
-#define BYTEARRAYLITERAL(F) QByteArrayLiteral(#F),
+#define STRINGLITERAL(F) QStringLiteral(#F),
#endif
- LUPDATE_FOR_EACH_TR_FUNCTION(BYTEARRAYLITERAL)
-#undef BYTEARRAYLITERAL
+ LUPDATE_FOR_EACH_TR_FUNCTION(STRINGLITERAL)
+#undef STRINGLITERAL
};
Q_STATIC_ASSERT((TrFunctionAliasManager::NumTrFunctions == sizeof defaultTrFunctionNames / sizeof *defaultTrFunctionNames));
-static int trFunctionByDefaultName(const QByteArray &trFunctionName)
+static int trFunctionByDefaultName(const QString &trFunctionName)
{
for (int i = 0; i < TrFunctionAliasManager::NumTrFunctions; ++i)
if (trFunctionName == defaultTrFunctionNames[i])
@@ -84,11 +84,6 @@ static int trFunctionByDefaultName(const QByteArray &trFunctionName)
return -1;
}
-static int trFunctionByDefaultName(const QString &trFunctionName)
-{
- return trFunctionByDefaultName(trFunctionName.toLatin1());
-}
-
TrFunctionAliasManager::TrFunctionAliasManager()
: m_trFunctionAliases()
{
@@ -98,18 +93,18 @@ TrFunctionAliasManager::TrFunctionAliasManager()
TrFunctionAliasManager::~TrFunctionAliasManager() {}
-int TrFunctionAliasManager::trFunctionByName(const QByteArray &trFunctionName) const
+int TrFunctionAliasManager::trFunctionByName(const QString &trFunctionName) const
{
ensureTrFunctionHashUpdated();
// this function needs to be fast
- const QHash<QByteArray, TrFunction>::const_iterator it
+ const QHash<QString, TrFunction>::const_iterator it
= m_nameToTrFunctionMap.find(trFunctionName);
return it == m_nameToTrFunctionMap.end() ? -1 : *it;
}
-void TrFunctionAliasManager::modifyAlias(int trFunction, const QByteArray &alias, Operation op)
+void TrFunctionAliasManager::modifyAlias(int trFunction, const QString &alias, Operation op)
{
- QList<QByteArray> &list = m_trFunctionAliases[trFunction];
+ QList<QString> &list = m_trFunctionAliases[trFunction];
if (op == SetAlias)
list.clear();
list.push_back(alias);
@@ -121,9 +116,9 @@ void TrFunctionAliasManager::ensureTrFunctionHashUpdated() const
if (!m_nameToTrFunctionMap.empty())
return;
- QHash<QByteArray, TrFunction> nameToTrFunctionMap;
+ QHash<QString, TrFunction> nameToTrFunctionMap;
for (int i = 0; i < NumTrFunctions; ++i)
- foreach (const QByteArray &alias, m_trFunctionAliases[i])
+ foreach (const QString &alias, m_trFunctionAliases[i])
nameToTrFunctionMap[alias] = TrFunction(i);
// commit:
m_nameToTrFunctionMap.swap(nameToTrFunctionMap);
@@ -134,16 +129,7 @@ static QStringList availableFunctions()
QStringList result;
result.reserve(TrFunctionAliasManager::NumTrFunctions);
for (int i = 0; i < TrFunctionAliasManager::NumTrFunctions; ++i)
- result.push_back(QString::fromLatin1(defaultTrFunctionNames[i]));
- return result;
-}
-
-static QStringList byteArrayToStringList(const QList<QByteArray> &in)
-{
- QStringList result;
- result.reserve(in.size());
- foreach (const QByteArray &function, in)
- result.push_back(QString::fromLatin1(function));
+ result.push_back(defaultTrFunctionNames[i]);
return result;
}
@@ -152,9 +138,9 @@ QStringList TrFunctionAliasManager::availableFunctionsWithAliases() const
QStringList result;
result.reserve(NumTrFunctions);
for (int i = 0; i < NumTrFunctions; ++i)
- result.push_back(QString::fromLatin1(defaultTrFunctionNames[i]) +
+ result.push_back(defaultTrFunctionNames[i] +
QLatin1String(" (=") +
- byteArrayToStringList(m_trFunctionAliases[i]).join(QLatin1Char('=')) +
+ m_trFunctionAliases[i].join(QLatin1Char('=')) +
QLatin1Char(')'));
return result;
}
@@ -280,7 +266,7 @@ static bool handleTrFunctionAliases(const QString &arg)
.arg(trFunctionName));
return false;
}
- trFunctionAliasManager.modifyAlias(trFunction, alias.toLatin1(),
+ trFunctionAliasManager.modifyAlias(trFunction, alias,
plusEqual ? TrFunctionAliasManager::AddAlias : TrFunctionAliasManager::SetAlias);
}
return true;
diff --git a/src/qdbus/qdbusviewer/logviewer.cpp b/src/qdbus/qdbusviewer/logviewer.cpp
new file mode 100644
index 000000000..a230eb65f
--- /dev/null
+++ b/src/qdbus/qdbusviewer/logviewer.cpp
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Tasuku Suzuki <stasuku@gmail.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "logviewer.h"
+
+#include <QtGui/QContextMenuEvent>
+#include <QtWidgets/QMenu>
+
+LogViewer::LogViewer(QWidget *parent)
+ : QTextBrowser(parent)
+{
+}
+
+void LogViewer::contextMenuEvent(QContextMenuEvent *event)
+{
+ QMenu *menu = createStandardContextMenu();
+ QAction *action = menu->addAction(tr("Clear"));
+ connect(action, SIGNAL(triggered()), this, SLOT(clear()));
+ menu->exec(event->globalPos());
+ delete menu;
+}
diff --git a/src/qdbus/qdbusviewer/logviewer.h b/src/qdbus/qdbusviewer/logviewer.h
new file mode 100644
index 000000000..d8dec0ecd
--- /dev/null
+++ b/src/qdbus/qdbusviewer/logviewer.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Tasuku Suzuki <stasuku@gmail.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LOGVIEWER_H
+#define LOGVIEWER_H
+
+#include <QtWidgets/QTextBrowser>
+
+class LogViewer : public QTextBrowser
+{
+ Q_OBJECT
+public:
+ explicit LogViewer(QWidget *parent = 0);
+
+protected:
+ virtual void contextMenuEvent(QContextMenuEvent *event);
+};
+
+#endif // LOGVIEWER_H
diff --git a/src/qdbus/qdbusviewer/main.cpp b/src/qdbus/qdbusviewer/main.cpp
index 5499192c8..f539230be 100644
--- a/src/qdbus/qdbusviewer/main.cpp
+++ b/src/qdbus/qdbusviewer/main.cpp
@@ -82,7 +82,8 @@ int main(int argc, char *argv[])
QMenu *fileMenu = mw.menuBar()->addMenu(QObject::tr("&File"));
QAction *quitAction = fileMenu->addAction(QObject::tr("&Quit"), &mw, SLOT(close()));
- Q_UNUSED(quitAction);
+ quitAction->setShortcut(QKeySequence::Quit);
+ quitAction->setMenuRole(QAction::QuitRole);
QMenu *helpMenu = mw.menuBar()->addMenu(QObject::tr("&Help"));
QAction *aboutAction = helpMenu->addAction(QObject::tr("&About"));
diff --git a/src/qdbus/qdbusviewer/qdbusviewer.cpp b/src/qdbus/qdbusviewer/qdbusviewer.cpp
index 403e954d7..ac0c141b4 100644
--- a/src/qdbus/qdbusviewer/qdbusviewer.cpp
+++ b/src/qdbus/qdbusviewer/qdbusviewer.cpp
@@ -42,7 +42,7 @@
#include "qdbusviewer.h"
#include "qdbusmodel.h"
#include "propertydialog.h"
-
+#include "logviewer.h"
#include <QtWidgets/QTreeWidget>
#include <QtCore/QStringListModel>
@@ -50,7 +50,6 @@
#include <QtCore/QMetaProperty>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QListView>
-#include <QtWidgets/QTextBrowser>
#include <QtWidgets/QAction>
#include <QtWidgets/QShortcut>
#include <QtWidgets/QVBoxLayout>
@@ -115,7 +114,7 @@ QDBusViewer::QDBusViewer(const QDBusConnection &connection, QWidget *parent) :
QSplitter *topSplitter = new QSplitter(Qt::Vertical, this);
layout->addWidget(topSplitter);
- log = new QTextBrowser;
+ log = new LogViewer;
connect(log, SIGNAL(anchorClicked(QUrl)), this, SLOT(anchorClicked(QUrl)));
QSplitter *splitter = new QSplitter(topSplitter);
diff --git a/src/qdbus/qdbusviewer/qdbusviewer.pro b/src/qdbus/qdbusviewer/qdbusviewer.pro
index 23c6ba027..1cd2f8f4d 100644
--- a/src/qdbus/qdbusviewer/qdbusviewer.pro
+++ b/src/qdbus/qdbusviewer/qdbusviewer.pro
@@ -1,10 +1,12 @@
HEADERS = qdbusviewer.h \
qdbusmodel.h \
- propertydialog.h
+ propertydialog.h \
+ logviewer.h
SOURCES = qdbusviewer.cpp \
qdbusmodel.cpp \
propertydialog.cpp \
+ logviewer.cpp \
main.cpp
RESOURCES += qdbusviewer.qrc