diff options
Diffstat (limited to 'tools')
87 files changed, 2171 insertions, 1129 deletions
diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp index 82a3a17..a1ba001 100644 --- a/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp +++ b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp @@ -83,9 +83,8 @@ void QHelpSearchIndexReader::cancelSearching() mutex.unlock(); } -void QHelpSearchIndexReader::search(const QString &collectionFile, - const QString &indexFilesFolder, - const QList<QHelpSearchQuery> &queryList) +void QHelpSearchIndexReader::search(const QString &collectionFile, const QString &indexFilesFolder, + const QList<QHelpSearchQuery> &queryList) { QMutexLocker lock(&mutex); @@ -147,17 +146,16 @@ void QHelpSearchIndexReader::run() try { #endif QCLuceneBooleanQuery booleanQuery; - if (!buildQuery(booleanQuery, queryList)) { + QCLuceneStandardAnalyzer analyzer; + if (!buildQuery(booleanQuery, queryList, analyzer)) { emit searchingFinished(0); return; } const QStringList attribList = engine.filterAttributes(engine.currentFilter()); if (!attribList.isEmpty()) { - QCLuceneStandardAnalyzer analyzer; QCLuceneQuery* query = QCLuceneQueryParser::parse(QLatin1String("+") - + attribList.join(QLatin1String(" +")), QLatin1String("attribute"), - analyzer); + + attribList.join(QLatin1String(" +")), QLatin1String("attribute"), analyzer); if (!query) { emit searchingFinished(0); @@ -168,10 +166,26 @@ void QHelpSearchIndexReader::run() QCLuceneIndexSearcher indexSearcher(indexPath); QCLuceneHits hits = indexSearcher.search(booleanQuery); - const QStringList namespaceList = engine.registeredDocumentations(); + + bool boost = true; + QCLuceneBooleanQuery tryHarderQuery; + if (hits.length() == 0) { + if (buildTryHarderQuery(tryHarderQuery, queryList, analyzer)) { + if (!attribList.isEmpty()) { + QCLuceneQuery* query = QCLuceneQueryParser::parse(QLatin1String("+") + + attribList.join(QLatin1String(" +")), QLatin1String("attribute"), + analyzer); + tryHarderQuery.add(query, true, true, false); + } + hits = indexSearcher.search(tryHarderQuery); + boost = (hits.length() == 0); + } + } QSet<QString> pathSet; QCLuceneDocument document; + const QStringList namespaceList = engine.registeredDocumentations(); + for (qint32 i = 0; i < hits.length(); i++) { document = hits.document(i); const QString path = document.get(QLatin1String("path")); @@ -192,8 +206,8 @@ void QHelpSearchIndexReader::run() } indexSearcher.close(); - int count = hitList.count(); - if (count > 0) + const int count = hitList.count(); + if ((count > 0) && boost) boostSearchHits(engine, hitList, queryList); emit searchingFinished(hitList.count()); @@ -206,11 +220,9 @@ void QHelpSearchIndexReader::run() } } -bool QHelpSearchIndexReader::defaultQuery(const QString &term, - QCLuceneBooleanQuery &booleanQuery) +bool QHelpSearchIndexReader::defaultQuery(const QString &term, QCLuceneBooleanQuery &booleanQuery, + QCLuceneStandardAnalyzer &analyzer) { - QCLuceneStandardAnalyzer analyzer; - const QLatin1String c("content"); const QLatin1String t("titleTokenized"); @@ -226,21 +238,23 @@ bool QHelpSearchIndexReader::defaultQuery(const QString &term, } bool QHelpSearchIndexReader::buildQuery(QCLuceneBooleanQuery &booleanQuery, - const QList<QHelpSearchQuery> &queryList) + const QList<QHelpSearchQuery> &queryList, QCLuceneStandardAnalyzer &analyzer) { foreach (const QHelpSearchQuery query, queryList) { switch (query.fieldName) { case QHelpSearchQuery::FUZZY: { const QLatin1String fuzzy("~"); - foreach (const QString term, query.wordList) { - if (term.isEmpty() || !defaultQuery(term.toLower() + fuzzy, booleanQuery)) + foreach (const QString &term, query.wordList) { + if (term.isEmpty() + || !defaultQuery(term.toLower() + fuzzy, booleanQuery, analyzer)) { return false; + } } } break; case QHelpSearchQuery::WITHOUT: { QStringList stopWords = QCLuceneStopAnalyzer().englishStopWords(); - foreach (const QString term, query.wordList) { + foreach (const QString &term, query.wordList) { if (stopWords.contains(term, Qt::CaseInsensitive)) continue; @@ -259,14 +273,14 @@ bool QHelpSearchIndexReader::buildQuery(QCLuceneBooleanQuery &booleanQuery, } break; case QHelpSearchQuery::PHRASE: { - const QString term = query.wordList.at(0).toLower(); + const QString &term = query.wordList.at(0).toLower(); if (term.contains(QLatin1Char(' '))) { QStringList termList = term.split(QLatin1String(" ")); QCLucenePhraseQuery *q = new QCLucenePhraseQuery(); QStringList stopWords = QCLuceneStopAnalyzer().englishStopWords(); - foreach (const QString t, termList) { - if (!stopWords.contains(t, Qt::CaseInsensitive)) - q->addTerm(QCLuceneTerm(QLatin1String("content"), t.toLower())); + foreach (const QString &term, termList) { + if (!stopWords.contains(term, Qt::CaseInsensitive)) + q->addTerm(QCLuceneTerm(QLatin1String("content"), term.toLower())); } booleanQuery.add(q, true, true, false); } else { @@ -286,7 +300,7 @@ bool QHelpSearchIndexReader::buildQuery(QCLuceneBooleanQuery &booleanQuery, case QHelpSearchQuery::ALL: { QStringList stopWords = QCLuceneStopAnalyzer().englishStopWords(); - foreach (const QString term, query.wordList) { + foreach (const QString &term, query.wordList) { if (stopWords.contains(term, Qt::CaseInsensitive)) continue; @@ -302,9 +316,8 @@ bool QHelpSearchIndexReader::buildQuery(QCLuceneBooleanQuery &booleanQuery, } break; case QHelpSearchQuery::DEFAULT: { - QCLuceneStandardAnalyzer analyzer; - foreach (const QString t, query.wordList) { - QCLuceneQuery *query = QCLuceneQueryParser::parse(t.toLower(), + foreach (const QString &term, query.wordList) { + QCLuceneQuery *query = QCLuceneQueryParser::parse(term.toLower(), QLatin1String("content"), analyzer); if (query) @@ -313,8 +326,8 @@ bool QHelpSearchIndexReader::buildQuery(QCLuceneBooleanQuery &booleanQuery, } break; case QHelpSearchQuery::ATLEAST: { - foreach (const QString term, query.wordList) { - if (term.isEmpty() || !defaultQuery(term.toLower(), booleanQuery)) + foreach (const QString &term, query.wordList) { + if (term.isEmpty() || !defaultQuery(term.toLower(), booleanQuery, analyzer)) return false; } } @@ -324,16 +337,38 @@ bool QHelpSearchIndexReader::buildQuery(QCLuceneBooleanQuery &booleanQuery, return true; } +bool QHelpSearchIndexReader::buildTryHarderQuery(QCLuceneBooleanQuery &booleanQuery, + const QList<QHelpSearchQuery> &queryList, QCLuceneStandardAnalyzer &analyzer) +{ + bool retVal = false; + foreach (const QHelpSearchQuery query, queryList) { + switch (query.fieldName) { + default: break; + case QHelpSearchQuery::DEFAULT: { + foreach (const QString &term, query.wordList) { + QCLuceneQuery *query = QCLuceneQueryParser::parse(term.toLower(), + QLatin1String("content"), analyzer); + + if (query) { + retVal = true; + booleanQuery.add(query, true, false, false); + } + } + } break; + } + } + return retVal; +} + void QHelpSearchIndexReader::boostSearchHits(const QHelpEngineCore &engine, - QList<QHelpSearchEngine::SearchHit> &hitList, - const QList<QHelpSearchQuery> &queryList) + QList<QHelpSearchEngine::SearchHit> &hitList, const QList<QHelpSearchQuery> &queryList) { foreach (const QHelpSearchQuery query, queryList) { if (query.fieldName != QHelpSearchQuery::DEFAULT) continue; QString joinedQuery = query.wordList.join(QLatin1String(" ")); - + QCLuceneStandardAnalyzer analyzer; QCLuceneQuery *parsedQuery = QCLuceneQueryParser::parse( joinedQuery, QLatin1String("content"), analyzer); @@ -351,8 +386,7 @@ void QHelpSearchIndexReader::boostSearchHits(const QHelpEngineCore &engine, QStringList searchTerms; while (index != -1) { nextIndex = joinedQuery.indexOf(QLatin1String("content:"), index + 1); - term = joinedQuery.mid(index + length, nextIndex - (length + index)) - .simplified(); + term = joinedQuery.mid(index + length, nextIndex - (length + index)).simplified(); if (term.startsWith(QLatin1String("\"")) && term.endsWith(QLatin1String("\""))) { searchTerms.append(term.remove(QLatin1String("\""))); @@ -370,17 +404,19 @@ void QHelpSearchIndexReader::boostSearchHits(const QHelpEngineCore &engine, QString data = QString::fromUtf8(engine.fileData(hit.first)); int counter = 0; - foreach (const QString& term, searchTerms) + foreach (const QString &term, searchTerms) counter += data.count(term, Qt::CaseInsensitive); hitMap.insertMulti(counter, hit); } QList<QHelpSearchEngine::SearchHit> boostedList; - QMap<int, QHelpSearchEngine::SearchHit>::const_iterator i; - for (i = hitMap.constEnd(), --i; i != hitMap.constBegin(); --i) - boostedList.append(i.value()); - boostedList += hitList.mid(count - 1, hitList.count()); - + QMap<int, QHelpSearchEngine::SearchHit>::const_iterator it = hitMap.constEnd(); + do { + --it; + boostedList.append(it.value()); + } while (it != hitMap.constBegin()); + boostedList += hitList.mid(count, hitList.count()); + hitList = boostedList; } } diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h index 892c4e6..f7536e9 100644 --- a/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h +++ b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h @@ -54,6 +54,8 @@ // #include "qhelpsearchengine.h" + +#include "fulltextsearch/qanalyzer_p.h" #include "fulltextsearch/qquery_p.h" #include <QtCore/QList> @@ -93,12 +95,13 @@ signals: private: void run(); - bool defaultQuery(const QString &term, - QCLuceneBooleanQuery &booleanQuery); - bool buildQuery(QCLuceneBooleanQuery &booleanQuery, - const QList<QHelpSearchQuery> &queryList); - void boostSearchHits(const QHelpEngineCore &engine, - QList<QHelpSearchEngine::SearchHit> &hitList, + bool defaultQuery(const QString &term, QCLuceneBooleanQuery &booleanQuery, + QCLuceneStandardAnalyzer &analyzer); + bool buildQuery(QCLuceneBooleanQuery &booleanQuery, const QList<QHelpSearchQuery> &queryList, + QCLuceneStandardAnalyzer &analyzer); + bool buildTryHarderQuery(QCLuceneBooleanQuery &booleanQuery, + const QList<QHelpSearchQuery> &queryList, QCLuceneStandardAnalyzer &analyzer); + void boostSearchHits(const QHelpEngineCore &engine, QList<QHelpSearchEngine::SearchHit> &hitList, const QList<QHelpSearchQuery> &queryList); private: diff --git a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp index e53bbae..195c490 100644 --- a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp +++ b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp @@ -59,16 +59,340 @@ #include <QtNetwork/QLocalSocket> #include <QtNetwork/QLocalServer> +#include "private/qfunctions_p.h" + QT_BEGIN_NAMESPACE namespace qt { namespace fulltextsearch { namespace clucene { +// taken from qtexthtmlparser +static const struct QTextHtmlEntity +{ + const char *name; + quint16 code; +} entities[] = { + { "AElig", 0x00c6 }, + { "AMP", 38 }, + { "Aacute", 0x00c1 }, + { "Acirc", 0x00c2 }, + { "Agrave", 0x00c0 }, + { "Alpha", 0x0391 }, + { "Aring", 0x00c5 }, + { "Atilde", 0x00c3 }, + { "Auml", 0x00c4 }, + { "Beta", 0x0392 }, + { "Ccedil", 0x00c7 }, + { "Chi", 0x03a7 }, + { "Dagger", 0x2021 }, + { "Delta", 0x0394 }, + { "ETH", 0x00d0 }, + { "Eacute", 0x00c9 }, + { "Ecirc", 0x00ca }, + { "Egrave", 0x00c8 }, + { "Epsilon", 0x0395 }, + { "Eta", 0x0397 }, + { "Euml", 0x00cb }, + { "GT", 62 }, + { "Gamma", 0x0393 }, + { "Iacute", 0x00cd }, + { "Icirc", 0x00ce }, + { "Igrave", 0x00cc }, + { "Iota", 0x0399 }, + { "Iuml", 0x00cf }, + { "Kappa", 0x039a }, + { "LT", 60 }, + { "Lambda", 0x039b }, + { "Mu", 0x039c }, + { "Ntilde", 0x00d1 }, + { "Nu", 0x039d }, + { "OElig", 0x0152 }, + { "Oacute", 0x00d3 }, + { "Ocirc", 0x00d4 }, + { "Ograve", 0x00d2 }, + { "Omega", 0x03a9 }, + { "Omicron", 0x039f }, + { "Oslash", 0x00d8 }, + { "Otilde", 0x00d5 }, + { "Ouml", 0x00d6 }, + { "Phi", 0x03a6 }, + { "Pi", 0x03a0 }, + { "Prime", 0x2033 }, + { "Psi", 0x03a8 }, + { "QUOT", 34 }, + { "Rho", 0x03a1 }, + { "Scaron", 0x0160 }, + { "Sigma", 0x03a3 }, + { "THORN", 0x00de }, + { "Tau", 0x03a4 }, + { "Theta", 0x0398 }, + { "Uacute", 0x00da }, + { "Ucirc", 0x00db }, + { "Ugrave", 0x00d9 }, + { "Upsilon", 0x03a5 }, + { "Uuml", 0x00dc }, + { "Xi", 0x039e }, + { "Yacute", 0x00dd }, + { "Yuml", 0x0178 }, + { "Zeta", 0x0396 }, + { "aacute", 0x00e1 }, + { "acirc", 0x00e2 }, + { "acute", 0x00b4 }, + { "aelig", 0x00e6 }, + { "agrave", 0x00e0 }, + { "alefsym", 0x2135 }, + { "alpha", 0x03b1 }, + { "amp", 38 }, + { "and", 0x22a5 }, + { "ang", 0x2220 }, + { "apos", 0x0027 }, + { "aring", 0x00e5 }, + { "asymp", 0x2248 }, + { "atilde", 0x00e3 }, + { "auml", 0x00e4 }, + { "bdquo", 0x201e }, + { "beta", 0x03b2 }, + { "brvbar", 0x00a6 }, + { "bull", 0x2022 }, + { "cap", 0x2229 }, + { "ccedil", 0x00e7 }, + { "cedil", 0x00b8 }, + { "cent", 0x00a2 }, + { "chi", 0x03c7 }, + { "circ", 0x02c6 }, + { "clubs", 0x2663 }, + { "cong", 0x2245 }, + { "copy", 0x00a9 }, + { "crarr", 0x21b5 }, + { "cup", 0x222a }, + { "curren", 0x00a4 }, + { "dArr", 0x21d3 }, + { "dagger", 0x2020 }, + { "darr", 0x2193 }, + { "deg", 0x00b0 }, + { "delta", 0x03b4 }, + { "diams", 0x2666 }, + { "divide", 0x00f7 }, + { "eacute", 0x00e9 }, + { "ecirc", 0x00ea }, + { "egrave", 0x00e8 }, + { "empty", 0x2205 }, + { "emsp", 0x2003 }, + { "ensp", 0x2002 }, + { "epsilon", 0x03b5 }, + { "equiv", 0x2261 }, + { "eta", 0x03b7 }, + { "eth", 0x00f0 }, + { "euml", 0x00eb }, + { "euro", 0x20ac }, + { "exist", 0x2203 }, + { "fnof", 0x0192 }, + { "forall", 0x2200 }, + { "frac12", 0x00bd }, + { "frac14", 0x00bc }, + { "frac34", 0x00be }, + { "frasl", 0x2044 }, + { "gamma", 0x03b3 }, + { "ge", 0x2265 }, + { "gt", 62 }, + { "hArr", 0x21d4 }, + { "harr", 0x2194 }, + { "hearts", 0x2665 }, + { "hellip", 0x2026 }, + { "iacute", 0x00ed }, + { "icirc", 0x00ee }, + { "iexcl", 0x00a1 }, + { "igrave", 0x00ec }, + { "image", 0x2111 }, + { "infin", 0x221e }, + { "int", 0x222b }, + { "iota", 0x03b9 }, + { "iquest", 0x00bf }, + { "isin", 0x2208 }, + { "iuml", 0x00ef }, + { "kappa", 0x03ba }, + { "lArr", 0x21d0 }, + { "lambda", 0x03bb }, + { "lang", 0x2329 }, + { "laquo", 0x00ab }, + { "larr", 0x2190 }, + { "lceil", 0x2308 }, + { "ldquo", 0x201c }, + { "le", 0x2264 }, + { "lfloor", 0x230a }, + { "lowast", 0x2217 }, + { "loz", 0x25ca }, + { "lrm", 0x200e }, + { "lsaquo", 0x2039 }, + { "lsquo", 0x2018 }, + { "lt", 60 }, + { "macr", 0x00af }, + { "mdash", 0x2014 }, + { "micro", 0x00b5 }, + { "middot", 0x00b7 }, + { "minus", 0x2212 }, + { "mu", 0x03bc }, + { "nabla", 0x2207 }, + { "nbsp", 0x00a0 }, + { "ndash", 0x2013 }, + { "ne", 0x2260 }, + { "ni", 0x220b }, + { "not", 0x00ac }, + { "notin", 0x2209 }, + { "nsub", 0x2284 }, + { "ntilde", 0x00f1 }, + { "nu", 0x03bd }, + { "oacute", 0x00f3 }, + { "ocirc", 0x00f4 }, + { "oelig", 0x0153 }, + { "ograve", 0x00f2 }, + { "oline", 0x203e }, + { "omega", 0x03c9 }, + { "omicron", 0x03bf }, + { "oplus", 0x2295 }, + { "or", 0x22a6 }, + { "ordf", 0x00aa }, + { "ordm", 0x00ba }, + { "oslash", 0x00f8 }, + { "otilde", 0x00f5 }, + { "otimes", 0x2297 }, + { "ouml", 0x00f6 }, + { "para", 0x00b6 }, + { "part", 0x2202 }, + { "percnt", 0x0025 }, + { "permil", 0x2030 }, + { "perp", 0x22a5 }, + { "phi", 0x03c6 }, + { "pi", 0x03c0 }, + { "piv", 0x03d6 }, + { "plusmn", 0x00b1 }, + { "pound", 0x00a3 }, + { "prime", 0x2032 }, + { "prod", 0x220f }, + { "prop", 0x221d }, + { "psi", 0x03c8 }, + { "quot", 34 }, + { "rArr", 0x21d2 }, + { "radic", 0x221a }, + { "rang", 0x232a }, + { "raquo", 0x00bb }, + { "rarr", 0x2192 }, + { "rceil", 0x2309 }, + { "rdquo", 0x201d }, + { "real", 0x211c }, + { "reg", 0x00ae }, + { "rfloor", 0x230b }, + { "rho", 0x03c1 }, + { "rlm", 0x200f }, + { "rsaquo", 0x203a }, + { "rsquo", 0x2019 }, + { "sbquo", 0x201a }, + { "scaron", 0x0161 }, + { "sdot", 0x22c5 }, + { "sect", 0x00a7 }, + { "shy", 0x00ad }, + { "sigma", 0x03c3 }, + { "sigmaf", 0x03c2 }, + { "sim", 0x223c }, + { "spades", 0x2660 }, + { "sub", 0x2282 }, + { "sube", 0x2286 }, + { "sum", 0x2211 }, + { "sup", 0x2283 }, + { "sup1", 0x00b9 }, + { "sup2", 0x00b2 }, + { "sup3", 0x00b3 }, + { "supe", 0x2287 }, + { "szlig", 0x00df }, + { "tau", 0x03c4 }, + { "there4", 0x2234 }, + { "theta", 0x03b8 }, + { "thetasym", 0x03d1 }, + { "thinsp", 0x2009 }, + { "thorn", 0x00fe }, + { "tilde", 0x02dc }, + { "times", 0x00d7 }, + { "trade", 0x2122 }, + { "uArr", 0x21d1 }, + { "uacute", 0x00fa }, + { "uarr", 0x2191 }, + { "ucirc", 0x00fb }, + { "ugrave", 0x00f9 }, + { "uml", 0x00a8 }, + { "upsih", 0x03d2 }, + { "upsilon", 0x03c5 }, + { "uuml", 0x00fc }, + { "weierp", 0x2118 }, + { "xi", 0x03be }, + { "yacute", 0x00fd }, + { "yen", 0x00a5 }, + { "yuml", 0x00ff }, + { "zeta", 0x03b6 }, + { "zwj", 0x200d }, + { "zwnj", 0x200c } +}; + +Q_STATIC_GLOBAL_OPERATOR bool operator<(const QString &entityStr, const QTextHtmlEntity &entity) +{ + return entityStr < QLatin1String(entity.name); +} + +Q_STATIC_GLOBAL_OPERATOR bool operator<(const QTextHtmlEntity &entity, const QString &entityStr) +{ + return QLatin1String(entity.name) < entityStr; +} + +static QChar resolveEntity(const QString &entity) +{ + const QTextHtmlEntity *start = &entities[0]; + const QTextHtmlEntity *end = &entities[(sizeof(entities) / sizeof(entities[0]))]; + const QTextHtmlEntity *e = qBinaryFind(start, end, entity); + if (e == end) + return QChar(); + return e->code; +} + +static const uint latin1Extended[0xA0 - 0x80] = { + 0x20ac, // 0x80 + 0x0081, // 0x81 direct mapping + 0x201a, // 0x82 + 0x0192, // 0x83 + 0x201e, // 0x84 + 0x2026, // 0x85 + 0x2020, // 0x86 + 0x2021, // 0x87 + 0x02C6, // 0x88 + 0x2030, // 0x89 + 0x0160, // 0x8A + 0x2039, // 0x8B + 0x0152, // 0x8C + 0x008D, // 0x8D direct mapping + 0x017D, // 0x8E + 0x008F, // 0x8F directmapping + 0x0090, // 0x90 directmapping + 0x2018, // 0x91 + 0x2019, // 0x92 + 0x201C, // 0x93 + 0X201D, // 0x94 + 0x2022, // 0x95 + 0x2013, // 0x96 + 0x2014, // 0x97 + 0x02DC, // 0x98 + 0x2122, // 0x99 + 0x0161, // 0x9A + 0x203A, // 0x9B + 0x0153, // 0x9C + 0x009D, // 0x9D direct mapping + 0x017E, // 0x9E + 0x0178 // 0x9F +}; +// end taken from qtexthtmlparser + class DocumentHelper { public: - DocumentHelper(const QString& fileName, const QByteArray &data) + DocumentHelper(const QString &fileName, const QByteArray &data) : fileName(fileName) , data(readData(data)) {} ~DocumentHelper() {} @@ -131,8 +455,15 @@ private: while (j < length) { c = buf[j++]; if (c == QLatin1Char('<') || c == QLatin1Char('&')) { - if (count > 1) + if (count > 1 && c != QLatin1Char('&')) parsedContent.append(QLatin1Char(' ')); + else if (c == QLatin1Char('&')) { + // Note: this will modify the counter j, in case we sucessful parsed the entity + // we will have modified the counter to stay 1 before the closing ';', so + // the following if condition will be met with if (c == QLatin1Char(';')) + parsedContent.append(parseEntity(length, buf, j)); + } + count = 0; valid = false; continue; @@ -157,6 +488,63 @@ private: return parsedContent; } + // taken from qtexthtmlparser + // parses an entity after "&", and returns it + QString parseEntity(int len, const QChar *buf, int &pos) const + { + int recover = pos; + QString entity; + while (pos < len) { + QChar c = buf[pos++]; + if (c.isSpace() || pos - recover > 9) { + goto error; + } + if (c == QLatin1Char(';')) { + pos--; + break; + } + entity += c; + } + { + QChar resolved = resolveEntity(entity); + if (!resolved.isNull()) + return QString(resolved); + } + if (entity.length() > 1 && entity.at(0) == QLatin1Char('#')) { + entity.remove(0, 1); // removing leading # + + int base = 10; + bool ok = false; + + if (entity.at(0).toLower() == QLatin1Char('x')) { // hex entity? + entity.remove(0, 1); + base = 16; + } + + uint uc = entity.toUInt(&ok, base); + if (ok) { + if (uc >= 0x80 && uc < 0x80 + (sizeof(latin1Extended) / sizeof(latin1Extended[0]))) + uc = latin1Extended[uc - 0x80]; // windows latin 1 extended + QString str; + if (uc > 0xffff) { + // surrogate pair + uc -= 0x10000; + ushort high = uc/0x400 + 0xd800; + ushort low = uc%0x400 + 0xdc00; + str.append(QChar(high)); + str.append(QChar(low)); + } else { + str.append(QChar(uc)); + } + return str; + } + } + error: + pos = recover; + return QLatin1String(" "); + } + // end taken from qtexthtmlparser + private: QString fileName; QString data; @@ -239,7 +627,7 @@ void QHelpSearchIndexWriter::run() // old style qhc file < 4.4.2, need to convert... const QStringList indexedNamespaces = engine.customValue(oldKey). toString().split(QLatin1String("|"), QString::SkipEmptyParts); - foreach (const QString& nameSpace, indexedNamespaces) + foreach (const QString &nameSpace, indexedNamespaces) indexMap.insert(nameSpace, QDateTime()); engine.removeCustomValue(oldKey); } else { @@ -294,7 +682,7 @@ void QHelpSearchIndexWriter::run() } if (QCLuceneIndexReader::indexExists(indexPath) && !reindex) { - foreach(const QString& namespaceName, registeredDocs) { + foreach(const QString &namespaceName, registeredDocs) { mutexLocker.relock(); if (m_cancel) { emit indexingFinished(); @@ -342,7 +730,7 @@ void QHelpSearchIndexWriter::run() writer->setMaxFieldLength(QCLuceneIndexWriter::DEFAULT_MAX_FIELD_LENGTH); QStringList namespaces; - foreach(const QString& namespaceName, registeredDocs) { + foreach(const QString &namespaceName, registeredDocs) { mutexLocker.relock(); if (m_cancel) { writer->close(); @@ -367,7 +755,7 @@ void QHelpSearchIndexWriter::run() break; } else { bool bail = false; - foreach (const QStringList& attributes, attributeSets) { + foreach (const QStringList &attributes, attributeSets) { const QList<QUrl> docFiles = indexableFiles(&engine, namespaceName, attributes); if (!addDocuments(docFiles, engine, attributes, namespaceName, @@ -397,7 +785,7 @@ void QHelpSearchIndexWriter::run() mutexLocker.unlock(); QStringList indexedNamespaces = indexMap.keys(); - foreach(const QString& namespaceName, indexedNamespaces) { + foreach(const QString &namespaceName, indexedNamespaces) { mutexLocker.relock(); if (m_cancel) break; @@ -422,7 +810,7 @@ bool QHelpSearchIndexWriter::addDocuments(const QList<QUrl> docFiles, const QString attrList = attributes.join(QLatin1String(" ")); locker.unlock(); - foreach(const QUrl& url, docFiles) { + foreach(const QUrl &url, docFiles) { QCLuceneDocument document; DocumentHelper helper(url.toString(), engine.fileData(url)); if (helper.addFieldsToDocument(&document, namespaceName, attrList)) @@ -450,8 +838,8 @@ void QHelpSearchIndexWriter::removeDocuments(const QString &indexPath, reader.close(); } -bool QHelpSearchIndexWriter::writeIndexMap(QHelpEngineCore& engine, - const QMap<QString, QDateTime>& indexMap) +bool QHelpSearchIndexWriter::writeIndexMap(QHelpEngineCore &engine, + const QMap<QString, QDateTime> &indexMap) { QByteArray bArray; diff --git a/tools/assistant/tools/assistant/contentwindow.cpp b/tools/assistant/tools/assistant/contentwindow.cpp index ef272e8..89060bd 100644 --- a/tools/assistant/tools/assistant/contentwindow.cpp +++ b/tools/assistant/tools/assistant/contentwindow.cpp @@ -118,19 +118,24 @@ void ContentWindow::keyPressEvent(QKeyEvent *e) bool ContentWindow::eventFilter(QObject *o, QEvent *e) { - if (m_contentWidget && o == m_contentWidget->viewport() && e->type() - == QEvent::MouseButtonRelease) { + if (m_contentWidget && o == m_contentWidget->viewport() + && e->type() == QEvent::MouseButtonRelease) { QMouseEvent *me = static_cast<QMouseEvent*>(e); - if (m_contentWidget->indexAt(me->pos()).isValid() - && me->button() == Qt::LeftButton) { - itemClicked(m_contentWidget->currentIndex()); - } else if (m_contentWidget->indexAt(me->pos()).isValid() - && me->button() == Qt::MidButton) { - QHelpContentModel *contentModel = - qobject_cast<QHelpContentModel*>(m_contentWidget->model()); - QHelpContentItem *itm = - contentModel->contentItemAt(m_contentWidget->currentIndex()); - CentralWidget::instance()->setSourceInNewTab(itm->url()); + QModelIndex index = m_contentWidget->indexAt(me->pos()); + QItemSelectionModel *sm = m_contentWidget->selectionModel(); + + if (index.isValid() && (sm && sm->isSelected(index))) { + if (me->button() == Qt::LeftButton) { + itemClicked(index); + } else if (me->button() == Qt::MidButton) { + QHelpContentModel *contentModel = + qobject_cast<QHelpContentModel*>(m_contentWidget->model()); + if (contentModel) { + QHelpContentItem *itm = contentModel->contentItemAt(index); + if (itm && !isPdfFile(itm)) + CentralWidget::instance()->setSourceInNewTab(itm->url()); + } + } } } return QWidget::eventFilter(o, e); @@ -141,16 +146,19 @@ void ContentWindow::showContextMenu(const QPoint &pos) if (!m_contentWidget->indexAt(pos).isValid()) return; - QMenu menu; - QAction *curTab = menu.addAction(tr("Open Link")); - QAction *newTab = menu.addAction(tr("Open Link in New Tab")); - menu.move(m_contentWidget->mapToGlobal(pos)); - QHelpContentModel *contentModel = qobject_cast<QHelpContentModel*>(m_contentWidget->model()); QHelpContentItem *itm = contentModel->contentItemAt(m_contentWidget->currentIndex()); + QMenu menu; + QAction *curTab = menu.addAction(tr("Open Link")); + QAction *newTab = menu.addAction(tr("Open Link in New Tab")); + if (isPdfFile(itm)) + newTab->setEnabled(false); + + menu.move(m_contentWidget->mapToGlobal(pos)); + QAction *action = menu.exec(); if (curTab == action) emit linkActivated(itm->url()); @@ -160,14 +168,20 @@ void ContentWindow::showContextMenu(const QPoint &pos) void ContentWindow::itemClicked(const QModelIndex &index) { - if (!index.isValid()) - return; QHelpContentModel *contentModel = qobject_cast<QHelpContentModel*>(m_contentWidget->model()); - QHelpContentItem *itm = - contentModel->contentItemAt(index); - if (itm) - emit linkActivated(itm->url()); + + if (contentModel) { + QHelpContentItem *itm = contentModel->contentItemAt(index); + if (itm) + emit linkActivated(itm->url()); + } +} + +bool ContentWindow::isPdfFile(QHelpContentItem *item) const +{ + const QString &path = item->url().path(); + return path.endsWith(QLatin1String(".pdf"), Qt::CaseInsensitive); } QT_END_NAMESPACE diff --git a/tools/assistant/tools/assistant/contentwindow.h b/tools/assistant/tools/assistant/contentwindow.h index ab8f8dd..ddc3e7c 100644 --- a/tools/assistant/tools/assistant/contentwindow.h +++ b/tools/assistant/tools/assistant/contentwindow.h @@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE class QHelpEngine; +class QHelpContentItem; class QHelpContentWidget; class ContentWindow : public QWidget @@ -75,6 +76,7 @@ private: void focusInEvent(QFocusEvent *e); void keyPressEvent(QKeyEvent *e); bool eventFilter(QObject *o, QEvent *e); + bool isPdfFile(QHelpContentItem *item) const; QHelpEngine *m_helpEngine; QHelpContentWidget *m_contentWidget; diff --git a/tools/assistant/tools/assistant/doc/assistant.qdocconf b/tools/assistant/tools/assistant/doc/assistant.qdocconf index 50f18c0..0d2271d 100644 --- a/tools/assistant/tools/assistant/doc/assistant.qdocconf +++ b/tools/assistant/tools/assistant/doc/assistant.qdocconf @@ -10,8 +10,8 @@ description = "Qt Assistant" HTML.{postheader,address} = "" HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \ "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \ - "<td width=\"30%\" align=\"left\">Copyright © 2008 Nokia Corporation " \ + "<td width=\"30%\" align=\"left\">Copyright © 2009 Nokia Corporation " \ "and/or its subsidiary(-ies)</td>\n" \ "<td width=\"40%\" align=\"center\">Trademarks</td>\n" \ - "<td width=\"30%\" align=\"right\"><div align=\"right\">Qt 4.5.0</div></td>\n" \ + "<td width=\"30%\" align=\"right\"><div align=\"right\">Qt 4.5.1</div></td>\n" \ "</tr></table></div></address>" diff --git a/tools/assistant/tools/assistant/helpviewer.cpp b/tools/assistant/tools/assistant/helpviewer.cpp index 9817f23..f7225fa 100644 --- a/tools/assistant/tools/assistant/helpviewer.cpp +++ b/tools/assistant/tools/assistant/helpviewer.cpp @@ -164,6 +164,7 @@ public: protected: virtual QWebPage *createWindow(QWebPage::WebWindowType); + virtual void triggerAction(WebAction action, bool checked = false); virtual bool acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type); @@ -171,16 +172,30 @@ protected: private: CentralWidget *centralWidget; QHelpEngine *helpEngine; + bool closeNewTabIfNeeded; + + friend class HelpViewer; + Qt::MouseButtons m_pressedButtons; + Qt::KeyboardModifiers m_keyboardModifiers; }; HelpPage::HelpPage(CentralWidget *central, QHelpEngine *engine, QObject *parent) - : QWebPage(parent), centralWidget(central), helpEngine(engine) + : QWebPage(parent) + , centralWidget(central) + , helpEngine(engine) + , closeNewTabIfNeeded(false) + , m_pressedButtons(Qt::NoButton) + , m_keyboardModifiers(Qt::NoModifier) { } QWebPage *HelpPage::createWindow(QWebPage::WebWindowType) { - return centralWidget->newEmptyTab()->page(); + HelpPage* newPage = static_cast<HelpPage*>(centralWidget->newEmptyTab()->page()); + if (newPage) + newPage->closeNewTabIfNeeded = closeNewTabIfNeeded; + closeNewTabIfNeeded = false; + return newPage; } static bool isLocalUrl(const QUrl &url) @@ -196,15 +211,33 @@ static bool isLocalUrl(const QUrl &url) return false; } +void HelpPage::triggerAction(WebAction action, bool checked) +{ + switch (action) { + case OpenLinkInNewWindow: + closeNewTabIfNeeded = true; + default: // fall through + QWebPage::triggerAction(action, checked); + break; + } +} + bool HelpPage::acceptNavigationRequest(QWebFrame *, - const QNetworkRequest &request, QWebPage::NavigationType) + const QNetworkRequest &request, QWebPage::NavigationType type) { const QUrl &url = request.url(); + const bool closeNewTab = closeNewTabIfNeeded; + closeNewTabIfNeeded = false; + if (isLocalUrl(url)) { - if (url.path().endsWith(QLatin1String("pdf"))) { - QString fileName = url.toString(); - fileName = QDir::tempPath() + QDir::separator() + fileName.right - (fileName.length() - fileName.lastIndexOf(QChar('/'))); + const QString& path = url.path(); + if (path.endsWith(QLatin1String(".pdf"))) { + const int lastDash = path.lastIndexOf(QChar('/')); + QString fileName = QDir::tempPath() + QDir::separator(); + if (lastDash < 0) + fileName += path; + else + fileName += path.mid(lastDash + 1, path.length()); QFile tmpFile(QDir::cleanPath(fileName)); if (tmpFile.open(QIODevice::ReadWrite)) { @@ -212,8 +245,22 @@ bool HelpPage::acceptNavigationRequest(QWebFrame *, tmpFile.close(); } QDesktopServices::openUrl(QUrl(tmpFile.fileName())); + + if (closeNewTab) + QMetaObject::invokeMethod(CentralWidget::instance(), "closeTab"); return false; } + + if (type == QWebPage::NavigationTypeLinkClicked + && (m_keyboardModifiers & Qt::ControlModifier + || m_pressedButtons == Qt::MidButton)) { + HelpViewer* viewer = centralWidget->newEmptyTab(); + if (viewer) + CentralWidget::instance()->setSource(url); + m_pressedButtons = Qt::NoButton; + m_keyboardModifiers = Qt::NoModifier; + return false; + } return true; } @@ -328,6 +375,16 @@ void HelpViewer::actionChanged() emit forwardAvailable(a->isEnabled()); } +void HelpViewer::mousePressEvent(QMouseEvent *event) +{ + HelpPage *currentPage = static_cast<HelpPage*>(page()); + if (currentPage) { + currentPage->m_pressedButtons = event->buttons(); + currentPage->m_keyboardModifiers = event->modifiers(); + } + QWebView::mousePressEvent(event); +} + #else // !defined(QT_NO_WEBKIT) HelpViewer::HelpViewer(QHelpEngine *engine, CentralWidget *parent) @@ -396,15 +453,19 @@ void HelpViewer::zoomOut(int range) bool HelpViewer::launchedWithExternalApp(const QUrl &url) { - bool isPdf = url.path().endsWith(QLatin1String("pdf")); + bool isPdf = url.path().endsWith(QLatin1String(".pdf")); if (url.scheme() == QLatin1String("http") || url.scheme() == QLatin1String("ftp") || url.scheme() == QLatin1String("mailto") || isPdf) { bool launched = false; if (isPdf && url.scheme() == QLatin1String("qthelp")) { - QString fileName = url.toString(); - fileName = QDir::tempPath() + QDir::separator() + fileName.right - (fileName.length() - fileName.lastIndexOf(QLatin1Char('/'))); + const QString& path = url.path(); + const int lastDash = path.lastIndexOf(QChar('/')); + QString fileName = QDir::tempPath() + QDir::separator(); + if (lastDash < 0) + fileName += path; + else + fileName += path.mid(lastDash + 1, path.length()); QFile tmpFile(QDir::cleanPath(fileName)); if (tmpFile.open(QIODevice::ReadWrite)) { diff --git a/tools/assistant/tools/assistant/helpviewer.h b/tools/assistant/tools/assistant/helpviewer.h index af5c197..eea7340 100644 --- a/tools/assistant/tools/assistant/helpviewer.h +++ b/tools/assistant/tools/assistant/helpviewer.h @@ -107,6 +107,7 @@ Q_SIGNALS: protected: virtual void wheelEvent(QWheelEvent *); void mouseReleaseEvent(QMouseEvent *e); + void mousePressEvent(QMouseEvent *event); private Q_SLOTS: void actionChanged(); diff --git a/tools/assistant/tools/assistant/indexwindow.cpp b/tools/assistant/tools/assistant/indexwindow.cpp index e7575fa..0beb5ee 100644 --- a/tools/assistant/tools/assistant/indexwindow.cpp +++ b/tools/assistant/tools/assistant/indexwindow.cpp @@ -122,10 +122,9 @@ bool IndexWindow::eventFilter(QObject *obj, QEvent *e) m_indexWidget->setCurrentIndex(idx); break; case Qt::Key_Escape: - emit escapePressed(); + emit escapePressed(); break; - default: - ; + default: ; // stop complaining } } else if (obj == m_indexWidget && e->type() == QEvent::ContextMenu) { QContextMenuEvent *ctxtEvent = static_cast<QContextMenuEvent*>(e); @@ -140,44 +139,15 @@ bool IndexWindow::eventFilter(QObject *obj, QEvent *e) if (curTab == action) m_indexWidget->activateCurrentItem(); else if (newTab == action) { - QHelpIndexModel *model = - qobject_cast<QHelpIndexModel*>(m_indexWidget->model()); - QString keyword = model->data(idx, Qt::DisplayRole).toString(); - if (model) { - QMap<QString, QUrl> links = model->linksForKeyword(keyword); - if (links.count() == 1) { - CentralWidget::instance()-> - setSourceInNewTab(links.constBegin().value()); - } else { - TopicChooser tc(this, keyword, links); - if (tc.exec() == QDialog::Accepted) { - CentralWidget::instance()->setSourceInNewTab(tc.link()); - } - } - } + open(m_indexWidget, idx); } } } else if (m_indexWidget && obj == m_indexWidget->viewport() && e->type() == QEvent::MouseButtonRelease) { QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(e); QModelIndex idx = m_indexWidget->indexAt(mouseEvent->pos()); - if (idx.isValid() && mouseEvent->button()==Qt::MidButton) { - QHelpIndexModel *model = - qobject_cast<QHelpIndexModel*>(m_indexWidget->model()); - QString keyword = model->data(idx, Qt::DisplayRole).toString(); - if (model) { - QMap<QString, QUrl> links = model->linksForKeyword(keyword); - if (links.count() > 1) { - TopicChooser tc(this, keyword, links); - if (tc.exec() == QDialog::Accepted) { - CentralWidget::instance()->setSourceInNewTab(tc.link()); - } - } else if (links.count() == 1) { - CentralWidget::instance()-> - setSourceInNewTab(links.constBegin().value()); - } - } - } + if (idx.isValid() && mouseEvent->button()==Qt::MidButton) + open(m_indexWidget, idx); } #ifdef Q_OS_MAC else if (obj == m_indexWidget && e->type() == QEvent::KeyPress) { @@ -213,4 +183,27 @@ void IndexWindow::focusInEvent(QFocusEvent *e) } } +void IndexWindow::open(QHelpIndexWidget* indexWidget, const QModelIndex &index) +{ + QHelpIndexModel *model = qobject_cast<QHelpIndexModel*>(indexWidget->model()); + if (model) { + QString keyword = model->data(index, Qt::DisplayRole).toString(); + QMap<QString, QUrl> links = model->linksForKeyword(keyword); + + QUrl url; + if (links.count() > 1) { + TopicChooser tc(this, keyword, links); + if (tc.exec() == QDialog::Accepted) + url = tc.link(); + } else if (links.count() == 1) { + url = links.constBegin().value(); + } + + if (url.path().endsWith(QLatin1String(".pdf"), Qt::CaseInsensitive)) + CentralWidget::instance()->setSource(url); + else + CentralWidget::instance()->setSourceInNewTab(url); + } +} + QT_END_NAMESPACE diff --git a/tools/assistant/tools/assistant/indexwindow.h b/tools/assistant/tools/assistant/indexwindow.h index f1f57f9..14ed83c 100644 --- a/tools/assistant/tools/assistant/indexwindow.h +++ b/tools/assistant/tools/assistant/indexwindow.h @@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE class QHelpIndexWidget; class QHelpEngine; +class QModelIndex; class IndexWindow : public QWidget { @@ -79,6 +80,7 @@ private slots: private: bool eventFilter(QObject *obj, QEvent *e); void focusInEvent(QFocusEvent *e); + void open(QHelpIndexWidget *indexWidget, const QModelIndex &index); QLineEdit *m_searchLineEdit; QHelpIndexWidget *m_indexWidget; diff --git a/tools/assistant/tools/assistant/mainwindow.cpp b/tools/assistant/tools/assistant/mainwindow.cpp index 0f246be..df39650 100644 --- a/tools/assistant/tools/assistant/mainwindow.cpp +++ b/tools/assistant/tools/assistant/mainwindow.cpp @@ -186,9 +186,11 @@ MainWindow::MainWindow(CmdLineParser *cmdLine, QWidget *parent) m_helpEngine->setCustomValue(QLatin1String("useAppFont"), false); m_helpEngine->setCustomValue(QLatin1String("useBrowserFont"), false); m_helpEngine->setCustomValue(QLatin1String("appFont"), qApp->font()); - m_helpEngine->setCustomValue(QLatin1String("appWritingSystem"), QFontDatabase::Latin); + m_helpEngine->setCustomValue(QLatin1String("appWritingSystem"), + QFontDatabase::Latin); m_helpEngine->setCustomValue(QLatin1String("browserFont"), qApp->font()); - m_helpEngine->setCustomValue(QLatin1String("browserWritingSystem"), QFontDatabase::Latin); + m_helpEngine->setCustomValue(QLatin1String("browserWritingSystem"), + QFontDatabase::Latin); } else { updateApplicationFont(); } @@ -377,118 +379,107 @@ void MainWindow::insertLastPages() void MainWindow::setupActions() { - QString system = QLatin1String("win"); + QString resourcePath = QLatin1String(":/trolltech/assistant/images/"); #ifdef Q_OS_MAC - system = QLatin1String("mac"); setUnifiedTitleAndToolBarOnMac(true); + resourcePath.append(QLatin1String("mac")); +#else + resourcePath.append(QLatin1String("win")); #endif QMenu *menu = menuBar()->addMenu(tr("&File")); - m_pageSetupAction = menu->addAction(tr("Page Set&up..."), m_centralWidget, SLOT(pageSetup())); - m_printPreviewAction = menu->addAction(tr("Print Preview..."), m_centralWidget, SLOT(printPreview())); + m_pageSetupAction = menu->addAction(tr("Page Set&up..."), m_centralWidget, + SLOT(pageSetup())); + m_printPreviewAction = menu->addAction(tr("Print Preview..."), m_centralWidget, + SLOT(printPreview())); + m_printAction = menu->addAction(tr("&Print..."), m_centralWidget, SLOT(print())); - m_printAction->setIcon(QIcon( - QString::fromUtf8(":/trolltech/assistant/images/%1/print.png").arg(system))); - m_printAction->setShortcut(tr("CTRL+P")); + m_printAction->setIcon(QIcon(resourcePath + QLatin1String("/print.png"))); + m_printAction->setShortcut(QKeySequence::Print); menu->addSeparator(); m_newTabAction = menu->addAction(tr("New &Tab"), m_centralWidget, SLOT(newTab())); - m_newTabAction->setShortcut(tr("CTRL+T")); - m_closeTabAction = menu->addAction(tr("&Close Tab"), m_centralWidget, SLOT(closeTab())); - m_closeTabAction->setShortcut(tr("CTRL+W")); + m_newTabAction->setShortcut(QKeySequence::AddTab); + + m_closeTabAction = menu->addAction(tr("&Close Tab"), m_centralWidget, + SLOT(closeTab())); + m_closeTabAction->setShortcuts(QKeySequence::Close); QAction *tmp = menu->addAction(tr("&Quit"), this, SLOT(close())); tmp->setShortcut(tr("CTRL+Q")); tmp->setMenuRole(QAction::QuitRole); menu = menuBar()->addMenu(tr("&Edit")); - m_copyAction = menu->addAction(tr("&Copy selected Text"), - m_centralWidget, SLOT(copySelection())); - m_copyAction->setIcon(QIcon( - QString::fromUtf8(":/trolltech/assistant/images/%1/editcopy.png").arg(system))); - m_copyAction->setShortcut(tr("Ctrl+C")); + m_copyAction = menu->addAction(tr("&Copy selected Text"), m_centralWidget, + SLOT(copySelection())); + m_copyAction->setIcon(QIcon(resourcePath + QLatin1String("/editcopy.png"))); + m_copyAction->setShortcuts(QKeySequence::Copy); m_copyAction->setEnabled(false); - m_findAction = menu->addAction(tr("&Find in Text..."), - m_centralWidget, SLOT(showTextSearch())); - m_findAction->setIcon(QIcon( - QString::fromUtf8(":/trolltech/assistant/images/%1/find.png").arg(system))); - m_findAction->setShortcut(tr("Ctrl+F")); - m_findAction->setShortcut(QKeySequence::Find); + m_findAction = menu->addAction(tr("&Find in Text..."), m_centralWidget, + SLOT(showTextSearch())); + m_findAction->setIcon(QIcon(resourcePath + QLatin1String("/find.png"))); + m_findAction->setShortcuts(QKeySequence::Find); - QAction *findNextAction = menu->addAction(tr("Find &Next"), - m_centralWidget, SLOT(findNext())); - findNextAction->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("F3")) - << QKeySequence(tr("CTRL+G"))); + QAction *findNextAction = menu->addAction(tr("Find &Next"), m_centralWidget, + SLOT(findNext())); + findNextAction->setShortcuts(QKeySequence::FindNext); QAction *findPreviousAction = menu->addAction(tr("Find &Previous"), m_centralWidget, SLOT(findPrevious())); - findPreviousAction->setShortcuts(QList<QKeySequence>() << - QKeySequence(tr("Shift+F3")) << QKeySequence(tr("CTRL+SHIFT+G"))); + findPreviousAction->setShortcuts(QKeySequence::FindPrevious); menu->addSeparator(); tmp = menu->addAction(tr("Preferences..."), this, SLOT(showPreferences())); tmp->setMenuRole(QAction::PreferencesRole); m_viewMenu = menuBar()->addMenu(tr("&View")); - m_zoomInAction = m_viewMenu->addAction(tr("Zoom &in"), - m_centralWidget, SLOT(zoomIn())); - m_zoomInAction->setIcon(QIcon( - QString::fromUtf8(":/trolltech/assistant/images/%1/zoomin.png").arg(system))); - m_zoomInAction->setShortcut(tr("Ctrl++")); - - m_zoomOutAction = m_viewMenu->addAction(tr("Zoom &out"), - m_centralWidget, SLOT(zoomOut())); - m_zoomOutAction->setIcon(QIcon( - QString::fromUtf8(":/trolltech/assistant/images/%1/zoomout.png").arg(system))); - m_zoomOutAction->setShortcut(tr("Ctrl+-")); - - m_resetZoomAction = m_viewMenu->addAction(tr("Normal &Size"), - m_centralWidget, SLOT(resetZoom())); - m_resetZoomAction->setIcon(QIcon( - QString::fromUtf8(":/trolltech/assistant/images/%1/resetzoom.png").arg(system))); + m_zoomInAction = m_viewMenu->addAction(tr("Zoom &in"), m_centralWidget, + SLOT(zoomIn())); + m_zoomInAction->setIcon(QIcon(resourcePath + QLatin1String("/zoomin.png"))); + m_zoomInAction->setShortcut(QKeySequence::ZoomIn); + + m_zoomOutAction = m_viewMenu->addAction(tr("Zoom &out"), m_centralWidget, + SLOT(zoomOut())); + m_zoomOutAction->setIcon(QIcon(resourcePath + QLatin1String("/zoomout.png"))); + m_zoomOutAction->setShortcut(QKeySequence::ZoomOut); + + m_resetZoomAction = m_viewMenu->addAction(tr("Normal &Size"), m_centralWidget, + SLOT(resetZoom())); + m_resetZoomAction->setIcon(QIcon(resourcePath + QLatin1String("/resetzoom.png"))); m_resetZoomAction->setShortcut(tr("Ctrl+0")); m_viewMenu->addSeparator(); - m_viewMenu->addAction(tr("Contents"), this, - SLOT(showContents()), QKeySequence(tr("ALT+C"))); - m_viewMenu->addAction(tr("Index"), this, - SLOT(showIndex()), QKeySequence(tr("ALT+I"))); - m_viewMenu->addAction(tr("Bookmarks"), this, - SLOT(showBookmarks()), QKeySequence(tr("ALT+O"))); - m_viewMenu->addAction(tr("Search"), this, - SLOT(showSearch()), QKeySequence(tr("ALT+S"))); + m_viewMenu->addAction(tr("Contents"), this, SLOT(showContents()), + QKeySequence(tr("ALT+C"))); + m_viewMenu->addAction(tr("Index"), this, SLOT(showIndex()), + QKeySequence(tr("ALT+I"))); + m_viewMenu->addAction(tr("Bookmarks"), this, SLOT(showBookmarks()), + QKeySequence(tr("ALT+O"))); + m_viewMenu->addAction(tr("Search"), this, SLOT(showSearch()), + QKeySequence(tr("ALT+S"))); menu = menuBar()->addMenu(tr("&Go")); - m_homeAction = menu->addAction(tr("&Home"), - m_centralWidget, SLOT(home())); + m_homeAction = menu->addAction(tr("&Home"), m_centralWidget, SLOT(home())); m_homeAction->setShortcut(tr("Ctrl+Home")); - m_homeAction->setIcon(QIcon( - QString::fromUtf8(":/trolltech/assistant/images/%1/home.png").arg(system))); + m_homeAction->setIcon(QIcon(resourcePath + QLatin1String("/home.png"))); - m_backAction = menu->addAction(tr("&Back"), - m_centralWidget, SLOT(backward())); + m_backAction = menu->addAction(tr("&Back"), m_centralWidget, SLOT(backward())); m_backAction->setEnabled(false); - m_backAction->setShortcuts(QList<QKeySequence>() - << QKeySequence(Qt::CTRL|Qt::Key_Left) << QKeySequence::Back); - m_backAction->setIcon(QIcon( - QString::fromUtf8(":/trolltech/assistant/images/%1/previous.png").arg(system))); + m_backAction->setShortcuts(QKeySequence::Back); + m_backAction->setIcon(QIcon(resourcePath + QLatin1String("/previous.png"))); - m_nextAction = menu->addAction(tr("&Forward"), - m_centralWidget, SLOT(forward())); + m_nextAction = menu->addAction(tr("&Forward"), m_centralWidget, SLOT(forward())); m_nextAction->setEnabled(false); - m_nextAction->setShortcuts(QList<QKeySequence>() - << QKeySequence(Qt::CTRL|Qt::Key_Right) << QKeySequence::Forward); - m_nextAction->setIcon(QIcon( - QString::fromUtf8(":/trolltech/assistant/images/%1/next.png").arg(system))); + m_nextAction->setShortcuts(QKeySequence::Forward); + m_nextAction->setIcon(QIcon(resourcePath + QLatin1String("/next.png"))); - m_syncAction = menu->addAction(tr("Sync with Table of Contents"), - this, SLOT(syncContents())); - m_syncAction->setIcon(QIcon( - QString::fromUtf8(":/trolltech/assistant/images/%1/synctoc.png").arg(system))); + m_syncAction = menu->addAction(tr("Sync with Table of Contents"), this, + SLOT(syncContents())); + m_syncAction->setIcon(QIcon(resourcePath + QLatin1String("/synctoc.png"))); menu->addSeparator(); @@ -496,8 +487,7 @@ void MainWindow::setupActions() tmp->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+Alt+Right")) << QKeySequence(Qt::CTRL + Qt::Key_PageDown)); - tmp = menu->addAction(tr("Previous Page"), - m_centralWidget, SLOT(previousPage())); + tmp = menu->addAction(tr("Previous Page"), m_centralWidget, SLOT(previousPage())); tmp->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+Alt+Left")) << QKeySequence(Qt::CTRL + Qt::Key_PageUp)); @@ -525,53 +515,52 @@ void MainWindow::setupActions() navigationBar->addAction(m_resetZoomAction); QList<QAction*> actionList; - actionList << m_backAction << m_nextAction << m_homeAction; - actionList << sep << m_zoomInAction << m_zoomOutAction; - actionList << sep2 << m_copyAction << m_printAction << m_findAction; + actionList << m_backAction << m_nextAction << m_homeAction << sep + << m_zoomInAction << m_zoomOutAction << sep2 << m_copyAction + << m_printAction << m_findAction; m_centralWidget->setGlobalActions(actionList); #if defined(Q_WS_MAC) QMenu *windowMenu = new QMenu(tr("&Window"), this); menuBar()->insertMenu(menu->menuAction(), windowMenu); - windowMenu->addAction(tr("Minimize"), this, - SLOT(showMinimized()), QKeySequence(tr("Ctrl+M"))); - windowMenu->addAction(tr("Zoom"), this, - SLOT(showMaximized())); + windowMenu->addAction(tr("Zoom"), this, SLOT(showMaximized())); + windowMenu->addAction(tr("Minimize"), this, SLOT(showMinimized()), + QKeySequence(tr("Ctrl+M"))); #endif // content viewer connections - connect(m_centralWidget, SIGNAL(copyAvailable(bool)), - this, SLOT(copyAvailable(bool))); - connect(m_centralWidget, SIGNAL(currentViewerChanged()), - this, SLOT(updateNavigationItems())); - connect(m_centralWidget, SIGNAL(forwardAvailable(bool)), - this, SLOT(updateNavigationItems())); - connect(m_centralWidget, SIGNAL(backwardAvailable(bool)), - this, SLOT(updateNavigationItems())); - connect(m_centralWidget, SIGNAL(highlighted(const QString&)), - statusBar(), SLOT(showMessage(const QString&))); - connect(m_centralWidget, SIGNAL(addNewBookmark(const QString&, - const QString&)), this, SLOT(addNewBookmark(const QString&, const QString&))); + connect(m_centralWidget, SIGNAL(copyAvailable(bool)), this, + SLOT(copyAvailable(bool))); + connect(m_centralWidget, SIGNAL(currentViewerChanged()), this, + SLOT(updateNavigationItems())); + connect(m_centralWidget, SIGNAL(forwardAvailable(bool)), this, + SLOT(updateNavigationItems())); + connect(m_centralWidget, SIGNAL(backwardAvailable(bool)), this, + SLOT(updateNavigationItems())); + connect(m_centralWidget, SIGNAL(highlighted(QString)), statusBar(), + SLOT(showMessage(QString))); + connect(m_centralWidget, SIGNAL(addNewBookmark(QString, QString)), this, + SLOT(addNewBookmark(QString, QString))); // bookmarks - connect(m_bookmarkWidget, SIGNAL(requestShowLink(const QUrl&)), - m_centralWidget, SLOT(setSource(const QUrl&))); - connect(m_bookmarkWidget, SIGNAL(escapePressed()), - this, SLOT(activateCurrentCentralWidgetTab())); + connect(m_bookmarkWidget, SIGNAL(requestShowLink(QUrl)), m_centralWidget, + SLOT(setSource(QUrl))); + connect(m_bookmarkWidget, SIGNAL(escapePressed()), this, + SLOT(activateCurrentCentralWidgetTab())); // index window - connect(m_indexWindow, SIGNAL(linkActivated(const QUrl&)), - m_centralWidget, SLOT(setSource(const QUrl&))); - connect(m_indexWindow, SIGNAL(linksActivated(const QMap<QString, QUrl>&, const QString&)), - this, SLOT(showTopicChooser(const QMap<QString, QUrl>&, const QString&))); - connect(m_indexWindow, SIGNAL(escapePressed()), - this, SLOT(activateCurrentCentralWidgetTab())); + connect(m_indexWindow, SIGNAL(linkActivated(QUrl)), m_centralWidget, + SLOT(setSource(QUrl))); + connect(m_indexWindow, SIGNAL(linksActivated(QMap<QString, QUrl>, QString)), + this, SLOT(showTopicChooser(QMap<QString, QUrl>, QString))); + connect(m_indexWindow, SIGNAL(escapePressed()), this, + SLOT(activateCurrentCentralWidgetTab())); // content window - connect(m_contentWindow, SIGNAL(linkActivated(const QUrl&)), - m_centralWidget, SLOT(setSource(const QUrl&))); - connect(m_contentWindow, SIGNAL(escapePressed()), - this, SLOT(activateCurrentCentralWidgetTab())); + connect(m_contentWindow, SIGNAL(linkActivated(QUrl)), m_centralWidget, + SLOT(setSource(QUrl))); + connect(m_contentWindow, SIGNAL(escapePressed()), this, + SLOT(activateCurrentCentralWidgetTab())); #if defined(QT_NO_PRINTER) m_pageSetupAction->setVisible(false); @@ -601,17 +590,19 @@ void MainWindow::setupFilterToolbar() QToolBar *filterToolBar = addToolBar(tr("Filter Toolbar")); filterToolBar->setObjectName(QLatin1String("FilterToolBar")); - filterToolBar->addWidget(new QLabel(tr("Filtered by:").append(QLatin1String(" ")), this)); + filterToolBar->addWidget(new QLabel(tr("Filtered by:").append(QLatin1Char(' ')), + this)); filterToolBar->addWidget(m_filterCombo); - if (m_helpEngine->customValue(QLatin1String("HideFilterFunctionality"), true).toBool()) + const QLatin1String hideFilter("HideFilterFunctionality"); + if (m_helpEngine->customValue(hideFilter, true).toBool()) filterToolBar->hide(); toolBarMenu()->addAction(filterToolBar->toggleViewAction()); - connect(m_helpEngine, SIGNAL(setupFinished()), - this, SLOT(setupFilterCombo())); - connect(m_filterCombo, SIGNAL(activated(const QString&)), - this, SLOT(filterDocumentation(const QString&))); + connect(m_helpEngine, SIGNAL(setupFinished()), this, + SLOT(setupFilterCombo())); + connect(m_filterCombo, SIGNAL(activated(const QString&)), this, + SLOT(filterDocumentation(const QString&))); setupFilterCombo(); } @@ -626,7 +617,8 @@ void MainWindow::setupAddressToolbar() addressToolBar->setObjectName(QLatin1String("AddressToolBar")); insertToolBarBreak(addressToolBar); - addressToolBar->addWidget(new QLabel(tr("Address:").append(QLatin1String(" ")), this)); + addressToolBar->addWidget(new QLabel(tr("Address:").append(QLatin1String(" ")), + this)); addressToolBar->addWidget(m_addressLineEdit); if (m_helpEngine->customValue(QLatin1String("HideAddressBar"), true).toBool()) @@ -684,7 +676,8 @@ void MainWindow::showNewAddress(const QUrl &url) void MainWindow::addBookmark() { - addNewBookmark(m_centralWidget->currentTitle(), m_centralWidget->currentSource().toString()); + addNewBookmark(m_centralWidget->currentTitle(), + m_centralWidget->currentSource().toString()); } void MainWindow::gotoAddress() @@ -784,7 +777,8 @@ void MainWindow::showAboutDialog() if (!contents.isEmpty()) { iconArray = m_helpEngine->customValue(QLatin1String("AboutIcon"), QByteArray()).toByteArray(); - QByteArray resources = m_helpEngine->customValue(QLatin1String("AboutImages"), + QByteArray resources = + m_helpEngine->customValue(QLatin1String("AboutImages"), QByteArray()).toByteArray(); QPixmap pix; pix.loadFromData(iconArray); @@ -795,13 +789,16 @@ void MainWindow::showAboutDialog() } else { #if QT_EDITION == QT_EDITION_OPENSOURCE QString edition = tr("Open Source Edition"); - QString info = tr("This version of Qt Assistant is part of the Qt Open Source Edition, for use " + QString info = tr("This version of Qt Assistant is part of the Qt Open " + "Source Edition, for use " "in the development of Open Source applications. " "Qt is a comprehensive C++ framework for cross-platform application " "development."); - QString moreInfo = tr("You need a commercial Qt license for development of proprietary (closed " - "source) applications. Please see <a href=\"http://qtsoftware.com/company/about/businessmodel" - "\">http://qtsoftware.com/company/about/businessmodel</a> for an overview of Qt licensing."); + QString moreInfo = tr("You need a commercial Qt license for development " + "of proprietary (closed source) applications. Please see " + "<a href=\"http://qtsoftware.com/company/about/businessmodel" + "\">http://qtsoftware.com/company/about/businessmodel</a> for an " + "overview of Qt licensing."); #else QString edition; QString info; @@ -816,13 +813,14 @@ void MainWindow::showAboutDialog() "<p>Version %2 %3</p></center>" "<p>%4</p>" "<p>%5</p>" - "<p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).</p>" - "<p>The program is provided AS IS with NO WARRANTY OF ANY KIND," + "<p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)" + ".</p><p>The program is provided AS IS with NO WARRANTY OF ANY KIND," " INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A" " PARTICULAR PURPOSE.<p/>") .arg(tr("Qt Assistant")).arg(QLatin1String(QT_VERSION_STR)) .arg(edition).arg(info).arg(moreInfo), resources); - aboutDia.setPixmap(QString::fromLatin1(":/trolltech/assistant/images/assistant-128.png")); + QLatin1String path(":/trolltech/assistant/images/assistant-128.png"); + aboutDia.setPixmap(QString(path)); } if (aboutDia.windowTitle().isEmpty()) aboutDia.setWindowTitle(tr("About %1").arg(windowTitle())); @@ -974,20 +972,19 @@ QWidget* MainWindow::setupBookmarkWidget() QString MainWindow::collectionFileDirectory(bool createDir, const QString &cacheDir) { - QString collectionPath = QDesktopServices::storageLocation(QDesktopServices::DataLocation); + QString collectionPath = + QDesktopServices::storageLocation(QDesktopServices::DataLocation); if (collectionPath.isEmpty()) { if (cacheDir.isEmpty()) collectionPath = QDir::homePath() + QDir::separator() + QLatin1String(".assistant"); else - collectionPath = QDir::homePath() + QLatin1String("/.") - + cacheDir; + collectionPath = QDir::homePath() + QLatin1String("/.") + cacheDir; } else { if (cacheDir.isEmpty()) collectionPath = collectionPath + QLatin1String("/Trolltech/Assistant"); else - collectionPath = collectionPath + QDir::separator() - + cacheDir; + collectionPath = collectionPath + QDir::separator() + cacheDir; } collectionPath = QDir::cleanPath(collectionPath); if (createDir) { @@ -1001,8 +998,8 @@ QString MainWindow::collectionFileDirectory(bool createDir, const QString &cache QString MainWindow::defaultHelpCollectionFileName() { return collectionFileDirectory() + QDir::separator() + - QString(QLatin1String("qthelpcollection_%1.qhc")). - arg(QLatin1String(QT_VERSION_STR)); + QString(QLatin1String("qthelpcollection_%1.qhc")). + arg(QLatin1String(QT_VERSION_STR)); } QT_END_NAMESPACE diff --git a/tools/assistant/tools/assistant/mainwindow.h b/tools/assistant/tools/assistant/mainwindow.h index 8b87b7b..c716b1c 100644 --- a/tools/assistant/tools/assistant/mainwindow.h +++ b/tools/assistant/tools/assistant/mainwindow.h @@ -72,7 +72,7 @@ public: MainWindow(CmdLineParser *cmdLine, QWidget *parent = 0); ~MainWindow(); - static void activateCurrentBrowser(); + static void activateCurrentBrowser(); static QString collectionFileDirectory(bool createDir = false, const QString &cacheDir = QString()); static QString defaultHelpCollectionFileName(); @@ -103,12 +103,12 @@ private slots: void gotoAddress(); void showPreferences(); void showNewAddress(); - void showAboutDialog(); + void showAboutDialog(); void copyAvailable(bool yes); void updateNavigationItems(); void showNewAddress(const QUrl &url); void addNewBookmark(const QString &title, const QString &url); - void showTopicChooser(const QMap<QString, QUrl> &links, const QString &keyword); + void showTopicChooser(const QMap<QString, QUrl> &links, const QString &keyword); void updateApplicationFont(); void filterDocumentation(const QString &customFilter); void setupFilterCombo(); @@ -128,7 +128,7 @@ private: void setupFilterToolbar(); void setupAddressToolbar(); QMenu *toolBarMenu(); - QWidget *setupBookmarkWidget(); + QWidget *setupBookmarkWidget(); QHelpEngine *m_helpEngine; CentralWidget *m_centralWidget; diff --git a/tools/checksdk/main.cpp b/tools/checksdk/main.cpp index 1d4b616..717f5c9 100644 --- a/tools/checksdk/main.cpp +++ b/tools/checksdk/main.cpp @@ -97,12 +97,6 @@ int main(int argc, char **argv) } } - // Check for SDK Name, otherwise use Windows Mobile as default - if (sdkName.isEmpty()) { - qWarning("No SDK specified: Defaulting to Windows Mobile 5.0 Pocket PC SDK"); - sdkName = QString::fromLatin1("Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"); - } - CeSdkHandler handler; if (!handler.parse()) { qWarning("Could not find any installed SDK, aborting!"); @@ -118,6 +112,12 @@ int main(int argc, char **argv) return 0; } + // Check for SDK Name, otherwise use Windows Mobile as default + if (sdkName.isEmpty()) { + qWarning("No SDK specified: Defaulting to Windows Mobile 5.0 Pocket PC SDK"); + sdkName = QString::fromLatin1("Windows Mobile 5.0 Pocket PC SDK (ARMV4I)"); + } + // finally find the given SDK and prompt out the environment to be set for (QList<CeSdkInfo>::iterator it = list.begin(); it != list.end(); ++it ) { if (sdkName == it->name()) { diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 83abd38..bcbf557 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -474,6 +474,9 @@ void Configure::parseCmdLine() else if( configCmdLine.at(i) == "-developer-build" ) dictionary[ "BUILDDEV" ] = "yes"; else if( configCmdLine.at(i) == "-nokia-developer" ) { + cout << "Detected -nokia-developer option" << endl; + cout << "Nokia employees and agents are allowed to use this software under" << endl; + cout << "the authority of Nokia Corporation and/or its subsidiary(-ies)" << endl; dictionary[ "BUILDNOKIA" ] = "yes"; dictionary[ "BUILDDEV" ] = "yes"; dictionary["LICENSE_CONFIRMED"] = "yes"; @@ -675,6 +678,9 @@ void Configure::parseCmdLine() } else if ( configCmdLine.at(i) == "-opengl-es-cl" ) { dictionary[ "OPENGL" ] = "yes"; dictionary[ "OPENGL_ES_CL" ] = "yes"; + } else if ( configCmdLine.at(i) == "-opengl-es-2" ) { + dictionary[ "OPENGL" ] = "yes"; + dictionary[ "OPENGL_ES_2" ] = "yes"; } // Databases ------------------------------------------------ else if( configCmdLine.at(i) == "-qt-sql-mysql" ) @@ -1632,6 +1638,7 @@ bool Configure::displayHelp() desc( "-signature <file>", "Use file for signing the target project"); desc("OPENGL_ES_CM", "no", "-opengl-es-cm", "Enable support for OpenGL ES Common"); desc("OPENGL_ES_CL", "no", "-opengl-es-cl", "Enable support for OpenGL ES Common Lite"); + desc("OPENGL_ES_2", "no", "-opengl-es-2", "Enable support for OpenGL ES 2.0"); desc("DIRECTSHOW", "no", "-phonon-wince-ds9", "Enable Phonon Direct Show 9 backend for Windows CE"); return true; @@ -1785,6 +1792,8 @@ bool Configure::checkAvailability(const QString &part) available = (dictionary[ "ARCHITECTURE" ] == "windowsce"); else if (part == "OPENGL_ES_CL") available = (dictionary[ "ARCHITECTURE" ] == "windowsce"); + else if (part == "OPENGL_ES_2") + available = (dictionary[ "ARCHITECTURE" ] == "windowsce"); else if (part == "DIRECTSHOW") available = (dictionary[ "ARCHITECTURE" ] == "windowsce"); else if (part == "SSE2") @@ -2264,6 +2273,10 @@ void Configure::generateOutputVars() qtConfig += "opengles1"; } + if ( dictionary["OPENGL_ES_2"] == "yes" ) { + qtConfig += "opengles2"; + } + if ( dictionary["OPENGL_ES_CL"] == "yes" ) { qtConfig += "opengles1cl"; } @@ -2664,9 +2677,11 @@ void Configure::generateConfigfiles() if(dictionary["SCRIPTTOOLS"] == "no") qconfigList += "QT_NO_SCRIPTTOOLS"; if(dictionary["OPENGL_ES_CM"] == "yes" || - dictionary["OPENGL_ES_CL"] == "yes") qconfigList += "QT_OPENGL_ES"; + dictionary["OPENGL_ES_CL"] == "yes" || + dictionary["OPENGL_ES_2"] == "yes") qconfigList += "QT_OPENGL_ES"; if(dictionary["OPENGL_ES_CM"] == "yes") qconfigList += "QT_OPENGL_ES_1"; + if(dictionary["OPENGL_ES_2"] == "yes") qconfigList += "QT_OPENGL_ES_2"; if(dictionary["OPENGL_ES_CL"] == "yes") qconfigList += "QT_OPENGL_ES_1_CL"; if(dictionary["SQL_MYSQL"] == "yes") qconfigList += "QT_SQL_MYSQL"; @@ -3030,7 +3045,7 @@ void Configure::generateHeaders() args += buildPath + "/bin/syncqt.bat"; QStringList env; env += QString("QTDIR=" + sourcePath); - //env += QString("PATH=" + buildPath + "/bin/;%PATH%"); + env += QString("PATH=" + buildPath + "/bin/;" + qgetenv("PATH")); Environment::execute(args, env, QStringList()); } } @@ -3500,7 +3515,7 @@ void Configure::readLicense() #else } else { Tools::checkLicense(dictionary, licenseInfo, firstLicensePath()); - if (dictionary["DONE"] != "error") { + if (dictionary["DONE"] != "error" && dictionary["BUILDNOKIA"] != "yes") { // give the user some feedback, and prompt for license acceptance cout << endl << "This is the " << dictionary["PLATFORM NAME"] << " " << dictionary["EDITION"] << " Edition."<< endl << endl; if (!showLicense(dictionary["LICENSE FILE"])) { diff --git a/tools/configure/tools.cpp b/tools/configure/tools.cpp index ae1ecda..2649d44 100644 --- a/tools/configure/tools.cpp +++ b/tools/configure/tools.cpp @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #include "tools.h" #include <QDir> @@ -17,6 +58,13 @@ using namespace std; void Tools::checkLicense(QMap<QString,QString> &dictionary, QMap<QString,QString> &licenseInfo, const QString &path) { + if (dictionary[ "BUILDNOKIA" ] == "yes") { + dictionary["EDITION"] = "NokiaInternalBuild"; + dictionary["LICENSE_FILE"] = ""; // No License for nokia developers + dictionary["QT_EDITION"] = "QT_EDITION_OPENSOURCE"; + return; // No license key checking in internal builds + } + QString tpLicense = dictionary["QT_SOURCE_TREE"] + "/LICENSE.PREVIEW.OPENSOURCE"; if (QFile::exists(tpLicense)) { dictionary["EDITION"] = "Preview"; @@ -101,25 +149,28 @@ void Tools::checkLicense(QMap<QString,QString> &dictionary, QMap<QString,QString dictionary["EDITION"] = "GUIFramework"; dictionary["QT_EDITION"] = "QT_EDITION_DESKTOPLIGHT"; } + + if (platforms == 'X') { + dictionary["LICENSE_EXTENSION"] = "-ALLOS"; + } else if (strchr("3679ACDEHJKMSUWX", platforms)) { + dictionary["LICENSE_EXTENSION"] = "-EMBEDDED"; + } else if (strchr("4BFPQRTY", platforms)) { + dictionary["LICENSE_EXTENSION"] = "-DESKTOP"; + } } else if (strcmp(licenseSchema,"Z4M") == 0 || strcmp(licenseSchema,"R4M") == 0 || strcmp(licenseSchema,"Q4M") == 0) { if (products == 'B') { dictionary["EDITION"] = "Evaluation"; dictionary["QT_EDITION"] = "QT_EDITION_EVALUATION"; + dictionary["LICENSE_EXTENSION"] = "-EVALUATION"; } } - // Determine license extension ----------------------------------------------------------------- if (QFile::exists(dictionary["QT_SOURCE_TREE"] + "/.LICENSE")) { // Generic, no-suffix license dictionary["LICENSE_EXTENSION"] = QString(); - } else if (platforms == 'X') { - dictionary["LICENSE_EXTENSION"] = "-ALLOS"; - } else if (/*Windows CE */platforms == '6' || /*Embedded */ platforms == '8' || /*Embedded + Windows CE*/platforms == 'K' || /*Windows + Windows CE*/ platforms == 'H') { - dictionary["LICENSE_EXTENSION"] = "-EMBEDDED"; - } else if (/*Windows*/ platforms == 'R' || /*Mac+X11+Windows*/ platforms == 'F') { - dictionary["LICENSE_EXTENSION"] = "-DESKTOP"; - } else if (dictionary["EDITION"] == "Evaluation") { - dictionary["LICENSE_EXTENSION"] = "-EVALUATION"; + } else if (dictionary["LICENSE_EXTENSION"].isEmpty()) { + cout << "License file does not contain proper license key." << endl; + dictionary["DONE"] = "error"; } if (licenseType.isEmpty() || dictionary["EDITION"].isEmpty() @@ -129,19 +180,9 @@ void Tools::checkLicense(QMap<QString,QString> &dictionary, QMap<QString,QString return; } - // verify that we are licensed to use Qt for Windows if (dictionary["PLATFORM NAME"].contains("Windows CE")) { - // verify that we are licensed to use Qt for Windows AND Qt for Windows CE - if (platforms != 'H') { - cout << "You are not licensed for the " << dictionary["PLATFORM NAME"] << " platform." << endl << endl; - cout << "Please contact sales@trolltech.com to upgrade your license" << endl; - cout << "to include the " << dictionary["PLATFORM NAME"] << " platform, or install the" << endl; - cout << "Qt Open Source Edition if you intend to develop free software." << endl; - dictionary["DONE"] = "error"; - return; - } - } else { - if (!( platforms == 'R' || ( platforms == '6' )|| platforms == '8' )) { + // verify that we are licensed to use Qt for Windows CE + if (dictionary["LICENSE_EXTENSION"] != "-EMBEDDED" && dictionary["LICENSE_EXTENSION"] != "-ALLOS") { cout << "You are not licensed for the " << dictionary["PLATFORM NAME"] << " platform." << endl << endl; cout << "Please contact sales@trolltech.com to upgrade your license" << endl; cout << "to include the " << dictionary["PLATFORM NAME"] << " platform, or install the" << endl; diff --git a/tools/configure/tools.h b/tools/configure/tools.h index e95ff13..68a439a 100644 --- a/tools/configure/tools.h +++ b/tools/configure/tools.h @@ -1,3 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the tools applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, 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. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + #ifndef _TOOLS_H_ #define _TOOLS_H_ diff --git a/tools/designer/src/components/objectinspector/objectinspectormodel.cpp b/tools/designer/src/components/objectinspector/objectinspectormodel.cpp index 3effa60..bc1ac0c 100644 --- a/tools/designer/src/components/objectinspector/objectinspectormodel.cpp +++ b/tools/designer/src/components/objectinspector/objectinspectormodel.cpp @@ -202,12 +202,15 @@ namespace qdesigner_internal { isContainer = widgetItem->isContainer(); } + // We might encounter temporary states with no layouts when re-layouting. + // Just default to Widget handling for the moment. if (isQLayoutWidget(w)) { - m_type = LayoutWidget; - const QLayout *layout = w->layout(); - m_managedLayoutType = LayoutInfo::layoutType(ctx.core, layout); - m_className = QLatin1String(layout->metaObject()->className()); - m_objectName = layout->objectName(); + if (const QLayout *layout = w->layout()) { + m_type = LayoutWidget; + m_managedLayoutType = LayoutInfo::layoutType(ctx.core, layout); + m_className = QLatin1String(layout->metaObject()->className()); + m_objectName = layout->objectName(); + } return; } diff --git a/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp b/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp index 1b267aa..346da18 100644 --- a/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp +++ b/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp @@ -271,7 +271,7 @@ void TextEditor::fileActionActivated() const QString newPath = m_core->dialogGui()->getOpenFileName(this, tr("Choose a File"), oldPath); if (newPath.isEmpty() || newPath == oldPath) return; - const QString newText = QLatin1String("file:") + newPath; + const QString newText = QUrl::fromLocalFile(newPath).toString(); m_editor->setText(newText); emit textChanged(newText); } diff --git a/tools/designer/src/lib/shared/actioneditor.cpp b/tools/designer/src/lib/shared/actioneditor.cpp index 6a66442..7f96a15 100644 --- a/tools/designer/src/lib/shared/actioneditor.cpp +++ b/tools/designer/src/lib/shared/actioneditor.cpp @@ -456,7 +456,7 @@ void ActionEditor::slotNewAction() if (actionData.checkable) setInitialProperty(sheet, QLatin1String(checkablePropertyC), QVariant(true)); - if (!actionData.keysequence.isEmpty()) + if (!actionData.keysequence.value().isEmpty()) setInitialProperty(sheet, QLatin1String(shortcutPropertyC), qVariantFromValue(actionData.keysequence)); sheet->setProperty(sheet->indexOf(QLatin1String(iconPropertyC)), qVariantFromValue(actionData.icon)); @@ -491,10 +491,10 @@ static QDesignerFormWindowCommand *setIconPropertyCommand(const PropertySheetIco // return a FormWindow command to apply a QKeySequence or a reset command // in case it is empty. -static QDesignerFormWindowCommand *setKeySequencePropertyCommand(const QKeySequence &ks, QAction *action, QDesignerFormWindowInterface *fw) +static QDesignerFormWindowCommand *setKeySequencePropertyCommand(const PropertySheetKeySequenceValue &ks, QAction *action, QDesignerFormWindowInterface *fw) { const QString shortcutProperty = QLatin1String(shortcutPropertyC); - if (ks.isEmpty()) { + if (ks.value().isEmpty()) { ResetPropertyCommand *cmd = new ResetPropertyCommand(fw); cmd->init(action, shortcutProperty); return cmd; @@ -544,7 +544,7 @@ void ActionEditor::editAction(QAction *action) oldActionData.text = action->text(); oldActionData.toolTip = textPropertyValue(sheet, QLatin1String(toolTipPropertyC)); oldActionData.icon = qVariantValue<PropertySheetIconValue>(sheet->property(sheet->indexOf(QLatin1String(iconPropertyC)))); - oldActionData.keysequence = qVariantValue<QKeySequence>(sheet->property(sheet->indexOf(QLatin1String(shortcutPropertyC)))); + oldActionData.keysequence = ActionModel::actionShortCut(sheet); oldActionData.checkable = action->isCheckable(); dlg.setActionData(oldActionData); diff --git a/tools/designer/src/lib/shared/actionrepository.cpp b/tools/designer/src/lib/shared/actionrepository.cpp index 941a9ba..1b638c3 100644 --- a/tools/designer/src/lib/shared/actionrepository.cpp +++ b/tools/designer/src/lib/shared/actionrepository.cpp @@ -42,6 +42,7 @@ #include "actionrepository_p.h" #include "qtresourceview_p.h" #include "iconloader_p.h" +#include "qdesigner_utils_p.h" #include <QtDesigner/QDesignerFormEditorInterface> #include <QtDesigner/QDesignerPropertySheetExtension> @@ -168,16 +169,20 @@ QWidgetList ActionModel::associatedWidgets(const QAction *action) } // shortcut is a fake property, need to retrieve it via property sheet. -static QString actionShortCut(QDesignerFormEditorInterface *core, QAction *action) +PropertySheetKeySequenceValue ActionModel::actionShortCut(QDesignerFormEditorInterface *core, QAction *action) { QDesignerPropertySheetExtension *sheet = qt_extension<QDesignerPropertySheetExtension*>(core->extensionManager(), action); if (!sheet) - return QString(); + return PropertySheetKeySequenceValue(); + return actionShortCut(sheet); +} + +PropertySheetKeySequenceValue ActionModel::actionShortCut(const QDesignerPropertySheetExtension *sheet) +{ const int index = sheet->indexOf(QLatin1String("shortcut")); if (index == -1) - return QString(); - const QKeySequence keysequence = qvariant_cast<QKeySequence>(sheet->property(index)); - return keysequence.toString(); + return PropertySheetKeySequenceValue(); + return qvariant_cast<PropertySheetKeySequenceValue>(sheet->property(index)); } void ActionModel::setItems(QDesignerFormEditorInterface *core, QAction *action, QStandardItemList &sl) @@ -221,7 +226,7 @@ void ActionModel::setItems(QDesignerFormEditorInterface *core, QAction *action, item->setText(action->text()); item->setToolTip(action->text()); // shortcut - const QString shortcut = actionShortCut(core, action); + const QString shortcut = actionShortCut(core, action).value().toString(); item = sl[ShortCutColumn]; item->setText(shortcut); item->setToolTip(shortcut); diff --git a/tools/designer/src/lib/shared/actionrepository_p.h b/tools/designer/src/lib/shared/actionrepository_p.h index 9d1af5a..66d77ce 100644 --- a/tools/designer/src/lib/shared/actionrepository_p.h +++ b/tools/designer/src/lib/shared/actionrepository_p.h @@ -65,9 +65,12 @@ QT_BEGIN_NAMESPACE class QPixmap; class QDesignerFormEditorInterface; +class QDesignerPropertySheetExtension; namespace qdesigner_internal { +class PropertySheetKeySequenceValue; + // Shared model of actions, to be used for several views (detailed/icon view). class QDESIGNER_SHARED_EXPORT ActionModel: public QStandardItemModel { @@ -99,6 +102,10 @@ public: // Find the associated menus and toolbars, ignore toolbuttons static QWidgetList associatedWidgets(const QAction *action); + // Retrieve shortcut via property sheet as it is a fake property + static PropertySheetKeySequenceValue actionShortCut(QDesignerFormEditorInterface *core, QAction *action); + static PropertySheetKeySequenceValue actionShortCut(const QDesignerPropertySheetExtension *ps); + signals: void resourceImageDropped(const QString &path, QAction *action); diff --git a/tools/designer/src/lib/shared/newactiondialog.cpp b/tools/designer/src/lib/shared/newactiondialog.cpp index 53aec4b..bb163d6 100644 --- a/tools/designer/src/lib/shared/newactiondialog.cpp +++ b/tools/designer/src/lib/shared/newactiondialog.cpp @@ -134,7 +134,7 @@ ActionData NewActionDialog::actionData() const rc.toolTip = m_ui->tooltipEditor->text(); rc.icon = m_ui->iconSelector->icon(); rc.checkable = m_ui->checkableCheckBox->checkState() == Qt::Checked; - rc.keysequence = m_ui->keySequenceEdit->keySequence(); + rc.keysequence = PropertySheetKeySequenceValue(m_ui->keySequenceEdit->keySequence()); return rc; } @@ -144,7 +144,7 @@ void NewActionDialog::setActionData(const ActionData &d) m_ui->editObjectName->setText(d.name); m_ui->iconSelector->setIcon(d.icon); m_ui->tooltipEditor->setText(d.toolTip); - m_ui->keySequenceEdit->setKeySequence(d.keysequence); + m_ui->keySequenceEdit->setKeySequence(d.keysequence.value()); m_ui->checkableCheckBox->setCheckState(d.checkable ? Qt::Checked : Qt::Unchecked); m_auto_update_object_name = false; diff --git a/tools/designer/src/lib/shared/newactiondialog_p.h b/tools/designer/src/lib/shared/newactiondialog_p.h index c8bd34c..d4e9b5b 100644 --- a/tools/designer/src/lib/shared/newactiondialog_p.h +++ b/tools/designer/src/lib/shared/newactiondialog_p.h @@ -84,7 +84,7 @@ struct ActionData { QString toolTip; PropertySheetIconValue icon; bool checkable; - QKeySequence keysequence; + PropertySheetKeySequenceValue keysequence; }; inline bool operator==(const ActionData &a1, const ActionData &a2) { return a1.compare(a2) == 0u; } diff --git a/tools/designer/src/lib/shared/plugindialog_p.h b/tools/designer/src/lib/shared/plugindialog_p.h index d50a804..a2601d4 100644 --- a/tools/designer/src/lib/shared/plugindialog_p.h +++ b/tools/designer/src/lib/shared/plugindialog_p.h @@ -42,6 +42,17 @@ #ifndef PLUGINDIALOG_H #define PLUGINDIALOG_H +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + #include "ui_plugindialog.h" QT_BEGIN_NAMESPACE diff --git a/tools/designer/src/lib/shared/qdesigner_utils.cpp b/tools/designer/src/lib/shared/qdesigner_utils.cpp index d2f092e..75fa180 100644 --- a/tools/designer/src/lib/shared/qdesigner_utils.cpp +++ b/tools/designer/src/lib/shared/qdesigner_utils.cpp @@ -397,7 +397,7 @@ namespace qdesigner_internal QMapIterator<QPair<QIcon::Mode, QIcon::State>, PropertySheetPixmapValue> itPath(paths); while (itPath.hasNext()) { QPair<QIcon::Mode, QIcon::State> pair = itPath.next().key(); - icon.addPixmap(m_pixmapCache->pixmap(itPath.value()), pair.first, pair.second); + icon.addFile(itPath.value().path(), QSize(), pair.first, pair.second); } m_cache.insert(value, icon); return icon; diff --git a/tools/designer/src/lib/shared/textpropertyeditor.cpp b/tools/designer/src/lib/shared/textpropertyeditor.cpp index cf12842..95a9f85 100644 --- a/tools/designer/src/lib/shared/textpropertyeditor.cpp +++ b/tools/designer/src/lib/shared/textpropertyeditor.cpp @@ -293,6 +293,7 @@ namespace qdesigner_internal { } setFocusProxy(m_lineEdit); + setText(m_cachedText); markIntermediateState(); } diff --git a/tools/designer/src/lib/uilib/resourcebuilder.cpp b/tools/designer/src/lib/uilib/resourcebuilder.cpp index 3679f92..5df10e9 100644 --- a/tools/designer/src/lib/uilib/resourcebuilder.cpp +++ b/tools/designer/src/lib/uilib/resourcebuilder.cpp @@ -98,21 +98,21 @@ QVariant QResourceBuilder::loadResource(const QDir &workingDirectory, const DomP if (const int flags = iconStateFlags(dpi)) { // new, post 4.4 format QIcon icon; if (flags & NormalOff) - icon.addPixmap(QFileInfo(workingDirectory, dpi->elementNormalOff()->text()).absoluteFilePath(), QIcon::Normal, QIcon::Off); + icon.addFile(QFileInfo(workingDirectory, dpi->elementNormalOff()->text()).absoluteFilePath(), QSize(), QIcon::Normal, QIcon::Off); if (flags & NormalOn) - icon.addPixmap(QFileInfo(workingDirectory, dpi->elementNormalOn()->text()).absoluteFilePath(), QIcon::Normal, QIcon::On); + icon.addFile(QFileInfo(workingDirectory, dpi->elementNormalOn()->text()).absoluteFilePath(), QSize(), QIcon::Normal, QIcon::On); if (flags & DisabledOff) - icon.addPixmap(QFileInfo(workingDirectory, dpi->elementDisabledOff()->text()).absoluteFilePath(), QIcon::Disabled, QIcon::Off); + icon.addFile(QFileInfo(workingDirectory, dpi->elementDisabledOff()->text()).absoluteFilePath(), QSize(), QIcon::Disabled, QIcon::Off); if (flags & DisabledOn) - icon.addPixmap(QFileInfo(workingDirectory, dpi->elementDisabledOn()->text()).absoluteFilePath(), QIcon::Disabled, QIcon::On); + icon.addFile(QFileInfo(workingDirectory, dpi->elementDisabledOn()->text()).absoluteFilePath(), QSize(), QIcon::Disabled, QIcon::On); if (flags & ActiveOff) - icon.addPixmap(QFileInfo(workingDirectory, dpi->elementActiveOff()->text()).absoluteFilePath(), QIcon::Active, QIcon::Off); + icon.addFile(QFileInfo(workingDirectory, dpi->elementActiveOff()->text()).absoluteFilePath(), QSize(), QIcon::Active, QIcon::Off); if (flags & ActiveOn) - icon.addPixmap(QFileInfo(workingDirectory, dpi->elementActiveOn()->text()).absoluteFilePath(), QIcon::Active, QIcon::On); + icon.addFile(QFileInfo(workingDirectory, dpi->elementActiveOn()->text()).absoluteFilePath(), QSize(), QIcon::Active, QIcon::On); if (flags & SelectedOff) - icon.addPixmap(QFileInfo(workingDirectory, dpi->elementSelectedOff()->text()).absoluteFilePath(), QIcon::Selected, QIcon::Off); + icon.addFile(QFileInfo(workingDirectory, dpi->elementSelectedOff()->text()).absoluteFilePath(), QSize(), QIcon::Selected, QIcon::Off); if (flags & SelectedOn) - icon.addPixmap(QFileInfo(workingDirectory, dpi->elementSelectedOn()->text()).absoluteFilePath(), QIcon::Selected, QIcon::On); + icon.addFile(QFileInfo(workingDirectory, dpi->elementSelectedOn()->text()).absoluteFilePath(), QSize(), QIcon::Selected, QIcon::On); return qVariantFromValue(icon); } else { // 4.3 legacy const QIcon icon(QFileInfo(workingDirectory, dpi->text()).absoluteFilePath()); diff --git a/tools/linguist/lconvert/main.cpp b/tools/linguist/lconvert/main.cpp index 2842bc7..9ccc60e 100644 --- a/tools/linguist/lconvert/main.cpp +++ b/tools/linguist/lconvert/main.cpp @@ -210,6 +210,7 @@ int main(int argc, char *argv[]) qWarning() << qPrintable(cd.error()); return 2; } + Translator::reportDuplicates(tr.resolveDuplicates(), inFiles[0].name, verbose); for (int i = 1; i < inFiles.size(); ++i) { Translator tr2; @@ -217,6 +218,7 @@ int main(int argc, char *argv[]) qWarning() << qPrintable(cd.error()); return 2; } + Translator::reportDuplicates(tr2.resolveDuplicates(), inFiles[i].name, verbose); for (int j = 0; j < tr2.messageCount(); ++j) tr.replaceSorted(tr2.message(j)); } diff --git a/tools/linguist/linguist/formpreviewview.cpp b/tools/linguist/linguist/formpreviewview.cpp index 990414b..184f01b 100644 --- a/tools/linguist/linguist/formpreviewview.cpp +++ b/tools/linguist/linguist/formpreviewview.cpp @@ -473,7 +473,7 @@ void FormPreviewView::setSourceContext(int model, MessageItem *messageItem) } QDir dir = QFileInfo(m_dataModel->srcFileName(model)).dir(); - QString fileName = dir.absoluteFilePath(messageItem->fileName()); + QString fileName = QDir::cleanPath(dir.absoluteFilePath(messageItem->fileName())); if (m_lastFormName != fileName) { delete m_form; m_form = 0; diff --git a/tools/linguist/linguist/mainwindow.cpp b/tools/linguist/linguist/mainwindow.cpp index e0a8a56..84200d4 100644 --- a/tools/linguist/linguist/mainwindow.cpp +++ b/tools/linguist/linguist/mainwindow.cpp @@ -188,7 +188,7 @@ private: static const QVariant &pxObsolete() { - static const QVariant v = + static const QVariant v = qVariantFromValue(QPixmap(QLatin1String(":/images/s_check_obsolete.png"))); return v; } @@ -1535,7 +1535,7 @@ void MainWindow::selectedMessageChanged(const QModelIndex &sortedIndex, const QM } else { m_sourceAndFormView->setCurrentWidget(m_sourceCodeView); QDir dir = QFileInfo(m_dataModel->srcFileName(model)).dir(); - QString fileName = dir.absoluteFilePath(m->fileName()); + QString fileName = QDir::cleanPath(dir.absoluteFilePath(m->fileName())); m_sourceCodeView->setSourceContext(fileName, m->lineNumber()); } m_errorsView->setEnabled(true); diff --git a/tools/linguist/linguist/messageeditor.cpp b/tools/linguist/linguist/messageeditor.cpp index f8c679c..dc8b8e4 100644 --- a/tools/linguist/linguist/messageeditor.cpp +++ b/tools/linguist/linguist/messageeditor.cpp @@ -67,7 +67,7 @@ QT_BEGIN_NAMESPACE // Allow translators to provide localized names for QLocale::languageToString // At least the own language should be translated ... This is a "hack" until // functionality is provided within Qt (see task 196275). -static const char * language_strings[] = +static const char * language_strings[] = { QT_TRANSLATE_NOOP("MessageEditor", "German"), QT_TRANSLATE_NOOP("MessageEditor", "Japanese"), @@ -786,6 +786,7 @@ void MessageEditor::selectAll() void MessageEditor::emitTranslationChanged() { + static_cast<FormWidget *>(sender())->getEditor()->setFocus(); // DND proofness updateBeginFromSource(); updateUndoRedo(); emit translationChanged(translations(m_currentModel)); @@ -793,6 +794,7 @@ void MessageEditor::emitTranslationChanged() void MessageEditor::emitTranslatorCommentChanged() { + static_cast<FormWidget *>(sender())->getEditor()->setFocus(); // DND proofness updateUndoRedo(); emit translatorCommentChanged(m_editors[m_currentModel].transCommentText->getTranslation()); } diff --git a/tools/linguist/linguist/messagemodel.cpp b/tools/linguist/linguist/messagemodel.cpp index 0ea462d..7a8063b 100644 --- a/tools/linguist/linguist/messagemodel.cpp +++ b/tools/linguist/linguist/messagemodel.cpp @@ -209,19 +209,19 @@ bool DataModel::load(const QString &fileName, bool *langGuessed, QWidget *parent return false; } - QList<TranslatorMessage> dupes = tor.findDuplicates(); + QSet<TranslatorMessagePtr> dupes = tor.resolveDuplicates(); if (!dupes.isEmpty()) { QString err = tr("<qt>Duplicate messages found in '%1':").arg(Qt::escape(fileName)); int numdups = 0; - foreach (const TranslatorMessage &msg, dupes) { + foreach (const TranslatorMessagePtr &msg, dupes) { if (++numdups >= 5) { err += tr("<p>[more duplicates omitted]"); break; } err += tr("<p>* Context: %1<br>* Source: %2") - .arg(Qt::escape(msg.context()), Qt::escape(msg.sourceText())); - if (!msg.comment().isEmpty()) - err += tr("<br>* Comment: %3").arg(Qt::escape(msg.comment())); + .arg(Qt::escape(msg->context()), Qt::escape(msg->sourceText())); + if (!msg->comment().isEmpty()) + err += tr("<br>* Comment: %3").arg(Qt::escape(msg->comment())); } QMessageBox::warning(parent, QObject::tr("Qt Linguist"), err); } @@ -289,7 +289,11 @@ bool DataModel::load(const QString &fileName, bool *langGuessed, QWidget *parent c = sys.country(); *langGuessed = true; } - setLanguageAndCountry(l, c); + if (!setLanguageAndCountry(l, c)) + QMessageBox::warning(parent, QObject::tr("Qt Linguist"), + tr("Linguist does not know the plural rules for '%1'.\n" + "Will assume a single universal form.") + .arg(m_localizedLanguage)); // Try to detect the correct source language in the following order // 1. Look for the language attribute in the ts // if that fails @@ -379,17 +383,17 @@ void DataModel::doCharCounting(const QString &text, int &trW, int &trC, int &trC } } -void DataModel::setLanguageAndCountry(QLocale::Language lang, QLocale::Country country) +bool DataModel::setLanguageAndCountry(QLocale::Language lang, QLocale::Country country) { if (m_language == lang && m_country == country) - return; + return true; m_language = lang; m_country = country; if (lang == QLocale::C || uint(lang) > uint(QLocale::LastLanguage)) // XXX does this make any sense? lang = QLocale::English; QByteArray rules; - getNumerusInfo(lang, country, &rules, &m_numerusForms); + bool ok = getNumerusInfo(lang, country, &rules, &m_numerusForms); m_localizedLanguage = QCoreApplication::translate("MessageEditor", QLocale::languageToString(lang).toAscii()); m_countRefNeeds.clear(); for (int i = 0; i < rules.size(); ++i) { @@ -397,8 +401,13 @@ void DataModel::setLanguageAndCountry(QLocale::Language lang, QLocale::Country c while (++i < rules.size() && rules.at(i) != (char)Q_NEWRULE) {} } m_countRefNeeds.append(true); + if (!ok) { + m_numerusForms.clear(); + m_numerusForms << tr("Universal Form"); + } emit languageChanged(); setModified(true); + return ok; } void DataModel::setSourceLanguageAndCountry(QLocale::Language lang, QLocale::Country country) @@ -451,7 +460,7 @@ QString DataModel::prettifyFileName(const QString &fn) /****************************************************************************** * - * DataModelIterator + * DataModelIterator * *****************************************************************************/ @@ -1100,7 +1109,7 @@ void MultiDataModel::updateCountsOnRemove(int model, bool writable) /****************************************************************************** * - * MultiDataModelIterator + * MultiDataModelIterator * *****************************************************************************/ @@ -1205,17 +1214,17 @@ int MessageModel::columnCount(const QModelIndex &) const QVariant MessageModel::data(const QModelIndex &index, int role) const { - static QVariant pxOn = + static QVariant pxOn = qVariantFromValue(QPixmap(QLatin1String(":/images/s_check_on.png"))); - static QVariant pxOff = + static QVariant pxOff = qVariantFromValue(QPixmap(QLatin1String(":/images/s_check_off.png"))); - static QVariant pxObsolete = + static QVariant pxObsolete = qVariantFromValue(QPixmap(QLatin1String(":/images/s_check_obsolete.png"))); static QVariant pxDanger = qVariantFromValue(QPixmap(QLatin1String(":/images/s_check_danger.png"))); static QVariant pxWarning = qVariantFromValue(QPixmap(QLatin1String(":/images/s_check_warning.png"))); - static QVariant pxEmpty = + static QVariant pxEmpty = qVariantFromValue(QPixmap(QLatin1String(":/images/s_check_empty.png"))); int row = index.row(); diff --git a/tools/linguist/linguist/messagemodel.h b/tools/linguist/linguist/messagemodel.h index 7fc2aa6..3b75f7a 100644 --- a/tools/linguist/linguist/messagemodel.h +++ b/tools/linguist/linguist/messagemodel.h @@ -210,7 +210,7 @@ public: static QString prettifyPlainFileName(const QString &fn); static QString prettifyFileName(const QString &fn); - void setLanguageAndCountry(QLocale::Language lang, QLocale::Country country); + bool setLanguageAndCountry(QLocale::Language lang, QLocale::Country country); QLocale::Language language() const { return m_language; } QLocale::Country country() const { return m_country; } void setSourceLanguageAndCountry(QLocale::Language lang, QLocale::Country country); diff --git a/tools/linguist/linguist/phrase.cpp b/tools/linguist/linguist/phrase.cpp index 563c72d..300f6e8 100644 --- a/tools/linguist/linguist/phrase.cpp +++ b/tools/linguist/linguist/phrase.cpp @@ -243,7 +243,7 @@ bool PhraseBook::load(const QString &fileName, bool *langGuessed) // don't click on these! reader.setFeature(QLatin1String("http://xml.org/sax/features/namespaces"), false); reader.setFeature(QLatin1String("http://xml.org/sax/features/namespace-prefixes"), true); - reader.setFeature(QLatin1String("http://qtsoftware.com/xml/features/report-whitespace" + reader.setFeature(QLatin1String("http://trolltech.com/xml/features/report-whitespace" "-only-CharData"), false); QphHandler *hand = new QphHandler(this); reader.setContentHandler(hand); diff --git a/tools/linguist/linguist/phraseview.cpp b/tools/linguist/linguist/phraseview.cpp index 78c9151..72c27dc 100644 --- a/tools/linguist/linguist/phraseview.cpp +++ b/tools/linguist/linguist/phraseview.cpp @@ -135,7 +135,7 @@ void PhraseView::contextMenuEvent(QContextMenuEvent *event) void PhraseView::mouseDoubleClickEvent(QMouseEvent *event) { QModelIndex index = indexAt(event->pos()); - if (!index.isValid()) + if (!index.isValid()) return; emit phraseSelected(m_modelIndex, m_phraseModel->phrase(index)->target()); diff --git a/tools/linguist/linguist/translationsettingsdialog.h b/tools/linguist/linguist/translationsettingsdialog.h index 8a633d9..a7ed1b4 100644 --- a/tools/linguist/linguist/translationsettingsdialog.h +++ b/tools/linguist/linguist/translationsettingsdialog.h @@ -76,4 +76,4 @@ private: QT_END_NAMESPACE -#endif // TRANSLATIONSETTINGSDIALOG_H +#endif // TRANSLATIONSETTINGSDIALOG_H diff --git a/tools/linguist/lrelease/main.cpp b/tools/linguist/lrelease/main.cpp index f1fdb3a..3bcc998 100644 --- a/tools/linguist/lrelease/main.cpp +++ b/tools/linguist/lrelease/main.cpp @@ -94,19 +94,6 @@ static bool loadTsFile(Translator &tor, const QString &tsFileName, bool /* verbo } else { if (!cd.errors().isEmpty()) printOut(cd.error()); - const QList<TranslatorMessage> dupes = tor.findDuplicates(); - if (!dupes.isEmpty()) { - qWarning("lrelease error: duplicate messages found in '%s':", - qPrintable(tsFileName)); - foreach (const TranslatorMessage &msg, dupes) { - qWarning("\n* Context: %s\n* Source: %s", - qPrintable(msg.context()), - qPrintable(msg.sourceText())); - if (!msg.comment().isEmpty()) - qWarning("\n* Comment: %s", qPrintable(msg.comment())); - } - ok = false; - } } return ok; } @@ -115,6 +102,8 @@ static bool releaseTranslator(Translator &tor, const QString &qmFileName, bool verbose, bool ignoreUnfinished, bool removeIdentical, TranslatorSaveMode mode) { + Translator::reportDuplicates(tor.resolveDuplicates(), qmFileName, verbose); + if (verbose) printOut(QCoreApplication::tr( "Updating '%1'...\n").arg(qmFileName)); if (removeIdentical) { diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp index e7865d5..b537b6e 100644 --- a/tools/linguist/lupdate/main.cpp +++ b/tools/linguist/lupdate/main.cpp @@ -73,7 +73,7 @@ static void recursiveFileInfoList(const QDir &dir, if (fname != QLatin1String(".") && fname != QLatin1String("..")) { if (it->isDir()) recursiveFileInfoList(QDir(it->absoluteFilePath()), nameFilters, filter, recursive, fileinfolist); - else + else fileinfolist->append(*it); } } @@ -146,6 +146,7 @@ static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFil *fail = true; continue; } + tor.resolveDuplicates(); cd.clearErrors(); if (!codecForTr.isEmpty() && codecForTr != tor.codecName()) qWarning("lupdate warning: Codec for tr() '%s' disagrees with " diff --git a/tools/linguist/shared/cpp.cpp b/tools/linguist/shared/cpp.cpp index a7854d9..2e137cf 100644 --- a/tools/linguist/shared/cpp.cpp +++ b/tools/linguist/shared/cpp.cpp @@ -107,6 +107,7 @@ enum { static QString yyFileName; static int yyCh; static bool yyCodecIsUtf8; +static bool yyForceUtf8; static QString yyIdent; static QString yyComment; static QString yyString; @@ -129,12 +130,19 @@ static int yyInPos; static uint getChar() { - if (yyInPos >= yyInStr.size()) - return EOF; - QChar c = yyInStr[yyInPos++]; - if (c.unicode() == '\n') - ++yyCurLineNo; - return c.unicode(); + forever { + if (yyInPos >= yyInStr.size()) + return EOF; + uint c = yyInStr[yyInPos++].unicode(); + if (c == '\\' && yyInPos < yyInStr.size() && yyInStr[yyInPos].unicode() == '\n') { + ++yyCurLineNo; + ++yyInPos; + continue; + } + if (c == '\n') + ++yyCurLineNo; + return c; + } } static uint getToken() @@ -692,7 +700,7 @@ static void recordMessage( yyFileName, line, QStringList(), TranslatorMessage::Unfinished, plural); msg.setExtraComment(transcode(extracomment.simplified(), utf8)); - if (utf8 && !yyCodecIsUtf8 && msg.needs8Bit()) + if ((utf8 || yyForceUtf8) && !yyCodecIsUtf8 && msg.needs8Bit()) msg.setUtf8(true); tor->extend(msg); } @@ -783,7 +791,7 @@ static void parse(Translator *tor, const QString &initialContext, const QString if (yyTok == Tok_ColonColon) fullName.append(QString()); while (yyTok == Tok_ColonColon || yyTok == Tok_Ident) { - if (yyTok == Tok_Ident) + if (yyTok == Tok_Ident) fullName.append(yyIdent); yyTok = getToken(); } @@ -1007,6 +1015,9 @@ void fetchtrInlinedCpp(const QString &in, Translator &translator, const QString yyInStr = in; yyInPos = 0; yyFileName = QString(); + yyCodecIsUtf8 = (translator.codecName() == "UTF-8"); + yyForceUtf8 = true; + yySourceIsUnicode = true; yySavedBraceDepth.clear(); yySavedParenDepth.clear(); yyBraceDepth = 0; @@ -1025,6 +1036,7 @@ bool loadCPP(Translator &translator, QIODevice &dev, ConversionData &cd) QString defaultContext = cd.m_defaultContext; yyCodecIsUtf8 = (translator.codecName() == "UTF-8"); + yyForceUtf8 = false; QTextStream ts(&dev); QByteArray codecName = cd.m_codecForSource.isEmpty() ? translator.codecName() : cd.m_codecForSource; diff --git a/tools/linguist/shared/numerus.cpp b/tools/linguist/shared/numerus.cpp index e2a6719..f3a29cc 100644 --- a/tools/linguist/shared/numerus.cpp +++ b/tools/linguist/shared/numerus.cpp @@ -104,7 +104,7 @@ static const uchar arabicRules[] = Q_MOD_100 | Q_BETWEEN, 3, 10, Q_NEWRULE, Q_MOD_100 | Q_NEQ, 0 }; -static const char * const japaneseStyleForms[] = { "Unique Form", 0 }; +static const char * const japaneseStyleForms[] = { "Universal Form", 0 }; static const char * const englishStyleForms[] = { "Singular", "Plural", 0 }; static const char * const frenchStyleForms[] = { "Singular", "Plural", 0 }; static const char * const latvianForms[] = { "Singular", "Plural", "Nullar", 0 }; diff --git a/tools/linguist/shared/po.cpp b/tools/linguist/shared/po.cpp index e9375e9..5842771 100644 --- a/tools/linguist/shared/po.cpp +++ b/tools/linguist/shared/po.cpp @@ -389,7 +389,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) for (; l != lines.size(); ++l) { QString line = lines.at(l); if (line.isEmpty()) - continue; + continue; if (isTranslationLine(line)) { bool isObsolete = line.startsWith(QLatin1String("#~ msgstr")); const QString prefix = QLatin1String(isObsolete ? "#~ " : ""); diff --git a/tools/linguist/shared/profileevaluator.cpp b/tools/linguist/shared/profileevaluator.cpp index 1e91f92..5440752 100644 --- a/tools/linguist/shared/profileevaluator.cpp +++ b/tools/linguist/shared/profileevaluator.cpp @@ -157,11 +157,6 @@ ProFileEvaluator::Private::Private(ProFileEvaluator *q_) m_prevLineNo = 0; m_prevProFile = 0; m_verbose = true; - m_block = 0; - m_commentItem = 0; - m_syntaxError = 0; - m_lineNo = 0; - m_contNextLine = false; } bool ProFileEvaluator::Private::read(ProFile *pro) @@ -172,8 +167,12 @@ bool ProFileEvaluator::Private::read(ProFile *pro) return false; } + m_block = 0; + m_commentItem = 0; + m_contNextLine = false; m_syntaxError = false; m_lineNo = 1; + m_blockstack.clear(); m_blockstack.push(pro); QTextStream ts(&file); @@ -276,6 +275,9 @@ void ProFileEvaluator::Private::insertVariable(const QString &line, int *i) { ProVariable::VariableOperator opkind; + if (m_proitem.isEmpty()) // Line starting with '=', like a conflict marker + return; + switch (m_proitem.at(m_proitem.length() - 1).unicode()) { case '+': m_proitem.chop(1); @@ -711,7 +713,7 @@ QStringList ProFileEvaluator::Private::qmakeFeaturePaths() // if (!specdir.cdUp() || specdir.isRoot()) // break; // if (QFile::exists(specdir.path() + QDir::separator() + "features")) { - // foreach (const QString &concat_it, concat) + // foreach (const QString &concat_it, concat) // feature_roots << (specdir.path() + concat_it); // break; // } @@ -1002,9 +1004,10 @@ bool ProFileEvaluator::Private::isActiveConfig(const QString &config, bool regex QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &func, const QString &arguments) { QStringList argumentsList = split_arg_list(arguments); + QStringList args; for (int i = 0; i < argumentsList.count(); ++i) - args += expandVariableReferences(argumentsList[i]); + args += expandVariableReferences(argumentsList[i]).join(Option::field_sep); enum ExpandFunc { E_MEMBER=1, E_FIRST, E_LAST, E_CAT, E_FROMFILE, E_EVAL, E_LIST, E_SPRINTF, E_JOIN, E_SPLIT, E_BASENAME, E_DIRNAME, E_SECTION, @@ -1265,10 +1268,11 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct for (int mut = 0; mut < mutuals.count(); mut++) { if (configs[i] == mutuals[mut].trimmed()) { cond = (configs[i] == args[0]); - break; + goto done_T_CONFIG; } } } + done_T_CONFIG: break; } case CF_CONTAINS: { @@ -1295,12 +1299,12 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct for (int mut = 0; mut < mutuals.count(); mut++) { if (val == mutuals[mut].trimmed()) { cond = (regx.exactMatch(val) || val == args[1]); - break; + goto done_T_CONTAINS; } } } } - + done_T_CONTAINS: break; } case CF_COUNT: { @@ -1373,7 +1377,7 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct parents.append(proFile->fileName()); if (!parents.isEmpty()) parents.takeLast(); - if (parents.isEmpty()) + if (parents.isEmpty()) q->fileMessage(format("Project ERROR: %1").arg(msg)); else q->fileMessage(format("Project ERROR: %1. File was included from: '%2'") @@ -1472,7 +1476,13 @@ ProFile *ProFileEvaluator::parsedProFile(const QString &fileName) { QFileInfo fi(fileName); if (fi.exists()) { - ProFile *pro = new ProFile(fi.absoluteFilePath()); + QString fn = QDir::cleanPath(fi.absoluteFilePath()); + foreach (const ProFile *pf, d->m_profileStack) + if (pf->fileName() == fn) { + errorMessage(d->format("circular inclusion of %1").arg(fn)); + return 0; + } + ProFile *pro = new ProFile(fn); if (d->read(pro)) return pro; delete pro; diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp index c197e2b..5563ac5 100644 --- a/tools/linguist/shared/qm.cpp +++ b/tools/linguist/shared/qm.cpp @@ -103,6 +103,43 @@ static uint elfHash(const QByteArray &ba) return h; } +class ByteTranslatorMessage +{ +public: + ByteTranslatorMessage( + const QByteArray &context, + const QByteArray &sourceText, + const QByteArray &comment, + const QStringList &translations) : + m_context(context), + m_sourcetext(sourceText), + m_comment(comment), + m_translations(translations) + {} + const QByteArray &context() const { return m_context; } + const QByteArray &sourceText() const { return m_sourcetext; } + const QByteArray &comment() const { return m_comment; } + const QStringList &translations() const { return m_translations; } + bool operator<(const ByteTranslatorMessage& m) const; + +private: + QByteArray m_context; + QByteArray m_sourcetext; + QByteArray m_comment; + QStringList m_translations; +}; + +Q_DECLARE_TYPEINFO(ByteTranslatorMessage, Q_MOVABLE_TYPE); + +bool ByteTranslatorMessage::operator<(const ByteTranslatorMessage& m) const +{ + if (m_context != m.m_context) + return m_context < m.m_context; + if (m_sourcetext != m.m_sourcetext) + return m_sourcetext < m.m_sourcetext; + return m_comment < m.m_comment; +} + class Releaser { public: @@ -133,27 +170,12 @@ public: m_codec = QTextCodec::codecForName(codecName); } - TranslatorMessage findMessage(const QString &context, - const QString &sourceText, const QString &comment, - const QString &fileName = QString(), int lineNumber = -1) const; - bool save(QIODevice *iod); - void insert(const TranslatorMessage &); - void remove(const TranslatorMessage &); - - bool contains(const QString &context, const QString &sourceText, - const QString & comment) const; - - bool contains(const QString &context, const QString &comment, - const QString &fileName, int lineNumber) const; + void insert(const TranslatorMessage &msg, bool forceComment); void squeeze(TranslatorSaveMode mode); - QList<TranslatorMessage> messages() const; - - bool isEmpty() const; - void setNumerusRules(const QByteArray &rules); private: @@ -163,18 +185,20 @@ private: // on turn should be the same as passed to the actual tr(...) calls QByteArray originalBytes(const QString &str, bool isUtf8) const; - Prefix commonPrefix(const TranslatorMessage &m1, const TranslatorMessage &m2) const; + void insertInternal(const TranslatorMessage &message, bool forceComment, bool isUtf8); + + static Prefix commonPrefix(const ByteTranslatorMessage &m1, const ByteTranslatorMessage &m2); - uint msgHash(const TranslatorMessage &msg) const; + static uint msgHash(const ByteTranslatorMessage &msg); - void writeMessage(const TranslatorMessage & msg, QDataStream & stream, + void writeMessage(const ByteTranslatorMessage & msg, QDataStream & stream, TranslatorSaveMode strip, Prefix prefix) const; // for squeezed but non-file data, this is what needs to be deleted QByteArray m_messageArray; QByteArray m_offsetArray; QByteArray m_contextArray; - QMap<TranslatorMessage, void *> m_messages; + QMap<ByteTranslatorMessage, void *> m_messages; QByteArray m_numerusRules; // Used to reproduce the original bytes @@ -193,12 +217,12 @@ QByteArray Releaser::originalBytes(const QString &str, bool isUtf8) const return m_codec ? m_codec->fromUnicode(str) : str.toLatin1(); } -uint Releaser::msgHash(const TranslatorMessage &msg) const +uint Releaser::msgHash(const ByteTranslatorMessage &msg) { - return elfHash(originalBytes(msg.sourceText() + msg.comment(), msg.isUtf8())); + return elfHash(msg.sourceText() + msg.comment()); } -Prefix Releaser::commonPrefix(const TranslatorMessage &m1, const TranslatorMessage &m2) const +Prefix Releaser::commonPrefix(const ByteTranslatorMessage &m1, const ByteTranslatorMessage &m2) { if (msgHash(m1) != msgHash(m2)) return NoPrefix; @@ -211,7 +235,7 @@ Prefix Releaser::commonPrefix(const TranslatorMessage &m1, const TranslatorMessa return HashContextSourceTextComment; } -void Releaser::writeMessage(const TranslatorMessage & msg, QDataStream & stream, +void Releaser::writeMessage(const ByteTranslatorMessage &msg, QDataStream &stream, TranslatorSaveMode mode, Prefix prefix) const { for (int i = 0; i < msg.translations().count(); ++i) { @@ -228,14 +252,14 @@ void Releaser::writeMessage(const TranslatorMessage & msg, QDataStream & stream, switch (prefix) { default: case HashContextSourceTextComment: - stream << quint8(Tag_Comment) << originalBytes(msg.comment(), msg.isUtf8()); + stream << quint8(Tag_Comment) << msg.comment(); // fall through case HashContextSourceText: - stream << quint8(Tag_SourceText) << originalBytes(msg.sourceText(), msg.isUtf8()); + stream << quint8(Tag_SourceText) << msg.sourceText(); // fall through case HashContext: - stream << quint8(Tag_Context) << originalBytes(msg.context(), msg.isUtf8()); - ; + stream << quint8(Tag_Context) << msg.context(); + break; } stream << quint8(Tag_End); @@ -275,7 +299,7 @@ void Releaser::squeeze(TranslatorSaveMode mode) if (m_messages.isEmpty() && mode == SaveEverything) return; - QMap<TranslatorMessage, void *> messages = m_messages; + QMap<ByteTranslatorMessage, void *> messages = m_messages; // re-build contents m_messageArray.clear(); @@ -286,7 +310,7 @@ void Releaser::squeeze(TranslatorSaveMode mode) QMap<Offset, void *> offsets; QDataStream ms(&m_messageArray, QIODevice::WriteOnly); - QMap<TranslatorMessage, void *>::const_iterator it, next; + QMap<ByteTranslatorMessage, void *>::const_iterator it, next; int cpPrev = 0, cpNext = 0; for (it = messages.constBegin(); it != messages.constEnd(); ++it) { cpPrev = cpNext; @@ -310,7 +334,7 @@ void Releaser::squeeze(TranslatorSaveMode mode) } if (mode == SaveStripped) { - QMap<QString, int> contextSet; + QMap<QByteArray, int> contextSet; for (it = messages.constBegin(); it != messages.constEnd(); ++it) ++contextSet[it.key().context()]; @@ -322,10 +346,10 @@ void Releaser::squeeze(TranslatorSaveMode mode) else hTableSize = (contextSet.size() < 10000) ? 15013 : 3 * contextSet.size() / 2; - QMultiMap<int, QString> hashMap; - QMap<QString, int>::const_iterator c; + QMultiMap<int, QByteArray> hashMap; + QMap<QByteArray, int>::const_iterator c; for (c = contextSet.constBegin(); c != contextSet.constEnd(); ++c) - hashMap.insert(elfHash(originalBytes(c.key(), false /*FIXME*/)) % hTableSize, c.key()); + hashMap.insert(elfHash(c.key()) % hTableSize, c.key()); /* The contexts found in this translator are stored in a hash @@ -360,16 +384,14 @@ void Releaser::squeeze(TranslatorSaveMode mode) t << quint16(0); // the entry at offset 0 cannot be used uint upto = 2; - QMap<int, QString>::const_iterator entry = hashMap.constBegin(); + QMap<int, QByteArray>::const_iterator entry = hashMap.constBegin(); while (entry != hashMap.constEnd()) { int i = entry.key(); hTable[i] = quint16(upto >> 1); do { - QString context = entry.value(); - QByteArray ba = context.toUtf8(); - const char *con = ba.data(); - uint len = uint(qstrlen(con)); + const char *con = entry.value().constData(); + uint len = uint(entry.value().length()); len = qMin(len, 255u); t << quint8(len); t.writeRawData(con, len); @@ -394,68 +416,28 @@ void Releaser::squeeze(TranslatorSaveMode mode) } } -bool Releaser::contains(const QString &context, const QString &sourceText, - const QString &comment) const -{ - return !findMessage(context, sourceText, comment).translation().isNull(); -} - -bool Releaser::contains(const QString &context, const QString &comment, - const QString &fileName, int lineNumber) const -{ - return !findMessage(context, QString(), comment, fileName, lineNumber).isNull(); -} - -void Releaser::insert(const TranslatorMessage &message) -{ - m_messages.insert(message, 0); -} - -void Releaser::remove(const TranslatorMessage &message) +void Releaser::insertInternal(const TranslatorMessage &message, bool forceComment, bool isUtf8) { - m_messages.remove(message); -} - - -TranslatorMessage Releaser::findMessage(const QString &context, - const QString &sourceText, const QString &comment, - const QString &fileName, int lineNumber) const -{ - if (m_messages.isEmpty()) - return TranslatorMessage(); - - QMap<TranslatorMessage, void *>::const_iterator it; - - // Either we want to find an item that matches context, sourcetext - // (and optionally comment) Or we want to find an item that - // matches context, filename, linenumber (and optionally comment) - TranslatorMessage msg(context, sourceText, comment, QString(), fileName, lineNumber); - it = m_messages.constFind(msg); - if (it != m_messages.constEnd()) - return it.key(); - - if (!comment.isEmpty()) { - it = m_messages.constFind(TranslatorMessage(context, sourceText, QString(), QString(), fileName, lineNumber)); - if (it != m_messages.constEnd()) - return it.key(); + ByteTranslatorMessage bmsg(originalBytes(message.context(), isUtf8), + originalBytes(message.sourceText(), isUtf8), + originalBytes(message.comment(), isUtf8), + message.translations()); + if (!forceComment) { + ByteTranslatorMessage bmsg2( + bmsg.context(), bmsg.sourceText(), QByteArray(""), bmsg.translations()); + if (!m_messages.contains(bmsg2)) { + m_messages.insert(bmsg2, 0); + return; + } } - - it = m_messages.constFind(TranslatorMessage(context, QString(), comment, QString(), fileName, lineNumber)); - if (it != m_messages.constEnd()) - return it.key(); - if (comment.isEmpty()) - return TranslatorMessage(); - - it = m_messages.constFind(TranslatorMessage(context, QString(), QString(), QString(), fileName, lineNumber)); - if (it != m_messages.constEnd()) - return it.key(); - return TranslatorMessage(); + m_messages.insert(bmsg, 0); } -bool Releaser::isEmpty() const +void Releaser::insert(const TranslatorMessage &message, bool forceComment) { - return m_messageArray.isEmpty() && m_offsetArray.isEmpty() - && m_contextArray.isEmpty() && m_messages.isEmpty(); + insertInternal(message, forceComment, message.isUtf8()); + if (message.isUtf8() && message.isNonUtf8()) + insertInternal(message, forceComment, false); } void Releaser::setNumerusRules(const QByteArray &rules) @@ -463,11 +445,6 @@ void Releaser::setNumerusRules(const QByteArray &rules) m_numerusRules = rules; } -QList<TranslatorMessage> Releaser::messages() const -{ - return m_messages.keys(); -} - static quint8 read8(const uchar *data) { return *data; @@ -478,6 +455,31 @@ static quint32 read32(const uchar *data) return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | (data[3]); } +static void fromBytes(const char *str, int len, QTextCodec *codec, QTextCodec *utf8Codec, + QString *out, QString *utf8Out, + bool *isSystem, bool *isUtf8, bool *needs8Bit) +{ + for (int i = 0; i < len; ++i) + if (str[i] & 0x80) { + if (utf8Codec) { + QTextCodec::ConverterState cvtState; + *utf8Out = utf8Codec->toUnicode(str, len, &cvtState); + *isUtf8 = !cvtState.invalidChars; + } + QTextCodec::ConverterState cvtState; + *out = codec->toUnicode(str, len, &cvtState); + *isSystem = !cvtState.invalidChars; + *needs8Bit = true; + return; + } + *out = QString::fromLatin1(str, len); + *isSystem = true; + if (utf8Codec) { + *utf8Out = *out; + *isUtf8 = true; + } + *needs8Bit = false; +} bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) { @@ -543,10 +545,19 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) size_t numItems = offsetLength / (2 * sizeof(quint32)); //qDebug() << "NUMITEMS: " << numItems; - TranslatorMessage msg; - // FIXME: that's just a guess, the original locale data is lost... QTextCodec *codec = QTextCodec::codecForLocale(); + QTextCodec *utf8Codec = 0; + if (codec->name() != "UTF-8") + utf8Codec = QTextCodec::codecForName("UTF-8"); + + QString context, contextUtf8; + bool contextIsSystem, contextIsUtf8, contextNeeds8Bit; + QString sourcetext, sourcetextUtf8; + bool sourcetextIsSystem, sourcetextIsUtf8, sourcetextNeeds8Bit; + QString comment, commentUtf8; + bool commentIsSystem, commentIsUtf8, commentNeeds8Bit; + QStringList translations; for (const uchar *start = offsetArray; start != offsetArray + (numItems << 3); start += 8) { //quint32 hash = read32(start); @@ -575,7 +586,7 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) } str.replace(QChar(Translator::InternalVariantSeparator), QChar(Translator::DefaultVariantSeparator)); - msg.appendTranslation(str); + translations << str; m += len; break; } @@ -588,7 +599,9 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) m += 4; //qDebug() << "SOURCE LEN: " << len; //qDebug() << "SOURCE: " << QByteArray((const char*)m, len); - msg.setSourceText(codec->toUnicode(QByteArray((const char*)m, len))); + fromBytes((const char*)m, len, codec, utf8Codec, + &sourcetext, &sourcetextUtf8, + &sourcetextIsSystem, &sourcetextIsUtf8, &sourcetextNeeds8Bit); m += len; break; } @@ -597,7 +610,9 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) m += 4; //qDebug() << "CONTEXT LEN: " << len; //qDebug() << "CONTEXT: " << QByteArray((const char*)m, len); - msg.setContext(codec->toUnicode(QByteArray((const char*)m, len))); + fromBytes((const char*)m, len, codec, utf8Codec, + &context, &contextUtf8, + &contextIsSystem, &contextIsUtf8, &contextNeeds8Bit); m += len; break; } @@ -606,7 +621,9 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) m += 4; //qDebug() << "COMMENT LEN: " << len; //qDebug() << "COMMENT: " << QByteArray((const char*)m, len); - msg.setComment(codec->toUnicode(QByteArray((const char*)m, len))); + fromBytes((const char*)m, len, codec, utf8Codec, + &comment, &commentUtf8, + &commentIsSystem, &commentIsUtf8, &commentNeeds8Bit); m += len; break; } @@ -616,10 +633,31 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) } } end:; + TranslatorMessage msg; msg.setType(TranslatorMessage::Finished); + msg.setTranslations(translations); + translations.clear(); + if (contextNeeds8Bit || sourcetextNeeds8Bit || commentNeeds8Bit) { + if (utf8Codec && contextIsUtf8 && sourcetextIsUtf8 && commentIsUtf8) { + // The message is utf-8, but file is not. + msg.setUtf8(true); + msg.setContext(contextUtf8); + msg.setSourceText(sourcetextUtf8); + msg.setComment(commentUtf8); + translator.append(msg); + continue; + } + if (!(contextIsSystem && sourcetextIsSystem && commentIsSystem)) { + cd.appendError(QLatin1String( + "Cannot read file with current system character codec")); + return false; + } + // The message is 8-bit in the file's encoding (utf-8 or not). + } + msg.setContext(context); + msg.setSourceText(sourcetext); + msg.setComment(comment); translator.append(msg); - //qDebug() << "\nHASH:" << hash << msg.sourceText() << msg.context(); - msg.setTranslations(QStringList()); } return ok; } @@ -646,39 +684,27 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData TranslatorMessage::Type typ = msg.type(); if (typ != TranslatorMessage::Obsolete) { if (typ == TranslatorMessage::Unfinished) { - if (msg.translation().isEmpty()) + if (msg.translation().isEmpty()) { ++untranslated; - else + continue; + } else { + if (cd.ignoreUnfinished()) + continue; ++unfinished; + } } else { ++finished; } - QString context = msg.context(); - QString sourceText = msg.sourceText(); - QString comment = msg.comment(); - QStringList translations = msg.translations(); - - if (!cd.ignoreUnfinished() || typ != TranslatorMessage::Unfinished) { - /* - Drop the comment in (context, sourceText, comment), - unless the context is empty, - unless (context, sourceText, "") already exists or - unless we already dropped the comment of (context, - sourceText, comment0). - */ - if (comment.isEmpty() - || context.isEmpty() - || translator.contains(context, sourceText, QString()) - || !releaser.findMessage(context, sourceText, QString()).translation() - .isNull() ) { - releaser.insert(msg); - } else { - TranslatorMessage tm(context, sourceText, QString(), - QString(), QString(), -1, translations); - //filename and lineNumbers will be ignored from now. - releaser.insert(tm); - } - } + // Drop the comment in (context, sourceText, comment), + // unless the context is empty, + // unless (context, sourceText, "") already exists or + // unless we already dropped the comment of (context, + // sourceText, comment0). + bool forceComment = + msg.comment().isEmpty() + || msg.context().isEmpty() + || translator.contains(msg.context(), msg.sourceText(), QString()); + releaser.insert(msg, forceComment); } } diff --git a/tools/linguist/shared/qph.cpp b/tools/linguist/shared/qph.cpp index 45d3a20..799bf7d 100644 --- a/tools/linguist/shared/qph.cpp +++ b/tools/linguist/shared/qph.cpp @@ -101,7 +101,7 @@ bool QPHReader::read(Translator &translator) m_currentField = TargetField; else if (name() == QLatin1String("definition")) m_currentField = DefinitionField; - else + else m_currentField = NoField; } else if (isWhiteSpace()) { // ignore these @@ -133,14 +133,47 @@ static bool loadQPH(Translator &translator, QIODevice &dev, ConversionData &cd) return reader.read(translator); } -static bool saveQPH(const Translator &translator, QIODevice &dev, ConversionData &cd) +static QString protect(const QString &str) +{ + QString result; + result.reserve(str.length() * 12 / 10); + for (int i = 0; i != str.size(); ++i) { + uint c = str.at(i).unicode(); + switch (c) { + case '\"': + result += QLatin1String("""); + break; + case '&': + result += QLatin1String("&"); + break; + case '>': + result += QLatin1String(">"); + break; + case '<': + result += QLatin1String("<"); + break; + case '\'': + result += QLatin1String("'"); + break; + default: + if (c < 0x20 && c != '\r' && c != '\n' && c != '\t') + result += QString(QLatin1String("&#%1;")).arg(c); + else // this also covers surrogates + result += QChar(c); + } + } + return result; +} + +static bool saveQPH(const Translator &translator, QIODevice &dev, ConversionData &) { QTextStream t(&dev); - t << "<!DOCTYPE QPH><QPH>\n"; + t.setCodec(QTextCodec::codecForName("UTF-8")); + t << "<!DOCTYPE QPH>\n<QPH>\n"; foreach (const TranslatorMessage &msg, translator.messages()) { t << "<phrase>\n"; - t << " <source>" << msg.sourceText() << "</source>\n"; - t << " <target>" << msg.translations().join(QLatin1String("@")) + t << " <source>" << protect(msg.sourceText()) << "</source>\n"; + t << " <target>" << protect(msg.translations().join(QLatin1String("@"))) << "</target>\n"; if (!msg.context().isEmpty() || !msg.comment().isEmpty()) t << " <definition>" << msg.context() << msg.comment() diff --git a/tools/linguist/shared/qscript.cpp b/tools/linguist/shared/qscript.cpp index 9ab5e16..7377cba 100644 --- a/tools/linguist/shared/qscript.cpp +++ b/tools/linguist/shared/qscript.cpp @@ -2382,7 +2382,7 @@ bool loadQScript(Translator &translator, QIODevice &dev, ConversionData &cd) return true; } -bool saveQScript(const Translator &translator, QIODevice &dev, ConversionData &cd) +bool saveQScript(const Translator &translator, QIODevice &dev, ConversionData &cd) { Q_UNUSED(dev); Q_UNUSED(translator); diff --git a/tools/linguist/shared/qscript.g b/tools/linguist/shared/qscript.g index c7ee80d..8d33277 100644 --- a/tools/linguist/shared/qscript.g +++ b/tools/linguist/shared/qscript.g @@ -2012,7 +2012,7 @@ bool loadQScript(Translator &translator, QIODevice &dev, ConversionData &cd) return true; } -bool saveQScript(const Translator &translator, QIODevice &dev, ConversionData &cd) +bool saveQScript(const Translator &translator, QIODevice &dev, ConversionData &cd) { Q_UNUSED(dev); Q_UNUSED(translator); diff --git a/tools/linguist/shared/translator.cpp b/tools/linguist/shared/translator.cpp index a5cb4d0..312bb71 100644 --- a/tools/linguist/shared/translator.cpp +++ b/tools/linguist/shared/translator.cpp @@ -105,13 +105,18 @@ void Translator::extend(const TranslatorMessage &msg) if (index == -1) { m_messages.append(msg); } else { - m_messages[index].addReferenceUniq(msg.fileName(), msg.lineNumber()); + TranslatorMessage &emsg = m_messages[index]; + emsg.addReferenceUniq(msg.fileName(), msg.lineNumber()); if (!msg.extraComment().isEmpty()) { - QString cmt = m_messages[index].extraComment(); + QString cmt = emsg.extraComment(); if (!cmt.isEmpty()) cmt.append(QLatin1String("\n----------\n")); cmt.append(msg.extraComment()); - m_messages[index].setExtraComment(cmt); + emsg.setExtraComment(cmt); + } + if (msg.isUtf8() != emsg.isUtf8()) { + emsg.setUtf8(true); + emsg.setNonUtf8(true); } } } @@ -259,7 +264,7 @@ bool Translator::save(const QString &filename, ConversionData &cd, const QString if (fmt == format.extension) { if (format.saver) return (*format.saver)(*this, file, cd); - cd.appendError(QString(QLatin1String("Cannit save %1 files")).arg(fmt)); + cd.appendError(QString(QLatin1String("Cannot save %1 files")).arg(fmt)); return false; } } @@ -411,17 +416,53 @@ void Translator::dropTranslations() } } -QList<TranslatorMessage> Translator::findDuplicates() const +QSet<TranslatorMessagePtr> Translator::resolveDuplicates() +{ + QSet<TranslatorMessagePtr> dups; + QHash<TranslatorMessagePtr, int> refs; + for (int i = 0; i < m_messages.count();) { + const TranslatorMessage &msg = m_messages.at(i); + QHash<TranslatorMessagePtr, int>::ConstIterator it = refs.constFind(msg); + if (it != refs.constEnd()) { + TranslatorMessage &omsg = m_messages[*it]; + if (omsg.isUtf8() != msg.isUtf8() && !omsg.isNonUtf8()) { + // Dual-encoded message + omsg.setUtf8(true); + omsg.setNonUtf8(true); + } else { + // Duplicate + dups.insert(omsg); + } + if (!omsg.isTranslated() && msg.isTranslated()) + omsg.setTranslations(msg.translations()); + m_messages.removeAt(i); + } else { + refs[msg] = i; + ++i; + } + } + return dups; +} + +void Translator::reportDuplicates(const QSet<TranslatorMessagePtr> &dupes, + const QString &fileName, bool verbose) { - QHash<TranslatorMessage, int> dups; - foreach (const TranslatorMessage &msg, m_messages) - dups[msg]++; - QList<TranslatorMessage> ret; - QHash<TranslatorMessage, int>::ConstIterator it = dups.constBegin(), end = dups.constEnd(); - for (; it != end; ++it) - if (it.value() > 1) - ret.append(it.key()); - return ret; + if (!dupes.isEmpty()) { + if (!verbose) { + qWarning("Warning: dropping duplicate messages in '%s'\n(try -verbose for more info).", + qPrintable(fileName)); + } else { + qWarning("Warning: dropping duplicate messages in '%s':", qPrintable(fileName)); + foreach (const TranslatorMessagePtr &msg, dupes) { + qWarning("\n* Context: %s\n* Source: %s", + qPrintable(msg->context()), + qPrintable(msg->sourceText())); + if (!msg->comment().isEmpty()) + qWarning("* Comment: %s", qPrintable(msg->comment())); + } + qWarning(); + } + } } // Used by lupdate to be able to search using absolute paths during merging @@ -464,8 +505,8 @@ QStringList Translator::normalizedTranslations(const TranslatorMessage &msg, int numTranslations = 1; if (msg.isPlural() && language != QLocale::C) { QStringList forms; - getNumerusInfo(language, country, 0, &forms); - numTranslations = forms.count(); // includes singular + if (getNumerusInfo(language, country, 0, &forms)) + numTranslations = forms.count(); // includes singular } // make sure that the stringlist always have the size of the @@ -544,7 +585,7 @@ void Translator::setCodecName(const QByteArray &name) if (!codec) { if (!name.isEmpty()) qWarning("No QTextCodec for %s available. Using Latin1\n", name.constData()); - m_codecName.clear(); + m_codecName = "ISO-8859-1"; } else { m_codecName = codec->name(); } diff --git a/tools/linguist/shared/translator.h b/tools/linguist/shared/translator.h index f4279da..6b88b23 100644 --- a/tools/linguist/shared/translator.h +++ b/tools/linguist/shared/translator.h @@ -52,8 +52,6 @@ QT_BEGIN_NAMESPACE -Q_DECLARE_TYPEINFO(TranslatorMessage, Q_MOVABLE_TYPE); - class QIODevice; // A struct of "interesting" data passed to and from the load and save routines @@ -88,7 +86,7 @@ public: QString m_targetFileName; QDir m_sourceDir; QDir m_targetDir; // FIXME: TS spefic - QStringList m_dropTags; // tags to be dropped + QStringList m_dropTags; // tags to be dropped QStringList m_errors; bool m_verbose; bool m_ignoreUnfinished; @@ -129,8 +127,10 @@ public: void stripNonPluralForms(); void stripIdenticalSourceTranslations(); void dropTranslations(); - QList<TranslatorMessage> findDuplicates() const; void makeFileNamesAbsolute(const QDir &originalPath); + QSet<TranslatorMessagePtr> resolveDuplicates(); + static void reportDuplicates(const QSet<TranslatorMessagePtr> &dupes, + const QString &fileName, bool verbose); void setCodecName(const QByteArray &name); QByteArray codecName() const { return m_codecName; } diff --git a/tools/linguist/shared/translatormessage.cpp b/tools/linguist/shared/translatormessage.cpp index ab4301f..afe66fe 100644 --- a/tools/linguist/shared/translatormessage.cpp +++ b/tools/linguist/shared/translatormessage.cpp @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE TranslatorMessage::TranslatorMessage() - : m_lineNumber(-1), m_type(Unfinished), m_utf8(false), m_plural(false) + : m_lineNumber(-1), m_type(Unfinished), m_utf8(false), m_nonUtf8(false), m_plural(false) { } @@ -66,7 +66,7 @@ TranslatorMessage::TranslatorMessage(const QString &context, : m_context(context), m_sourcetext(sourceText), m_comment(comment), m_userData(userData), m_translations(translations), m_fileName(fileName), m_lineNumber(lineNumber), - m_type(type), m_utf8(false), m_plural(plural) + m_type(type), m_utf8(false), m_nonUtf8(false), m_plural(plural) { } diff --git a/tools/linguist/shared/translatormessage.h b/tools/linguist/shared/translatormessage.h index fa37ff5..9f847b0 100644 --- a/tools/linguist/shared/translatormessage.h +++ b/tools/linguist/shared/translatormessage.h @@ -136,6 +136,8 @@ public: void setType(Type t) { m_type = t; } bool isUtf8() const { return m_utf8; } // codecForTr override void setUtf8(bool on) { m_utf8 = on; } + bool isNonUtf8() const { return m_nonUtf8; } // codecForTr override + void setNonUtf8(bool on) { m_nonUtf8 = on; } bool isPlural() const { return m_plural; } void setPlural(bool isplural) { m_plural = isplural; } @@ -169,11 +171,40 @@ private: Type m_type; bool m_utf8; + bool m_nonUtf8; bool m_plural; }; +Q_DECLARE_TYPEINFO(TranslatorMessage, Q_MOVABLE_TYPE); + int qHash(const TranslatorMessage &msg); +struct TranslatorMessagePtr { + TranslatorMessagePtr(const TranslatorMessage &tm) + { + ptr = &tm; + } + + inline const TranslatorMessage *operator->() const + { + return ptr; + } + + const TranslatorMessage *ptr; +}; + +Q_DECLARE_TYPEINFO(TranslatorMessagePtr, Q_MOVABLE_TYPE); + +inline int qHash(TranslatorMessagePtr tmp) +{ + return qHash(*tmp.ptr); +} + +inline bool operator==(TranslatorMessagePtr tmp1, TranslatorMessagePtr tmp2) +{ + return *tmp1.ptr == *tmp2.ptr; +} + QT_END_NAMESPACE #endif // QT_NO_TRANSLATION diff --git a/tools/linguist/shared/translatortools.cpp b/tools/linguist/shared/translatortools.cpp index dcff546..96301d5 100644 --- a/tools/linguist/shared/translatortools.cpp +++ b/tools/linguist/shared/translatortools.cpp @@ -69,7 +69,7 @@ static int numberLength(const QString &s, int i) int pos = i; do { ++i; - } while (i < s.size() + } while (i < s.size() && (s.at(i).isDigit() || (isDigitFriendly(s[i]) && i + 1 < s.size() @@ -445,7 +445,7 @@ Translator merge(const Translator &tor, const Translator &virginTor, if (mv.sourceText().isEmpty()) { if (tor.contains(mv.context())) continue; - } else { + } else { if (tor.contains(mv.context(), mv.sourceText(), mv.comment())) continue; if (options & HeuristicSimilarText) { diff --git a/tools/linguist/shared/ts.cpp b/tools/linguist/shared/ts.cpp index 2e7d40f..22f2a1b 100644 --- a/tools/linguist/shared/ts.cpp +++ b/tools/linguist/shared/ts.cpp @@ -212,6 +212,7 @@ QString TSReader::readTransContents() bool TSReader::read(Translator &translator) { + STRING(both); STRING(byte); STRING(comment); STRING(context); @@ -241,7 +242,7 @@ bool TSReader::read(Translator &translator) STRING(userdata); STRING(utf8); STRING(value); - STRING(version); + //STRING(version); STRING(yes); static const QString strextrans(QLatin1String("extra-")); @@ -277,7 +278,9 @@ bool TSReader::read(Translator &translator) // ignore these, just whitespace } else if (elementStarts(strdefaultcodec)) { // <defaultcodec> - translator.setCodecName(readElementText().toLatin1()); + const QString &codec = readElementText(); + if (!codec.isEmpty()) + translator.setCodecName(codec.toLatin1()); // </defaultcodec> } else if (isStartElement() && name().toString().startsWith(strextrans)) { @@ -309,7 +312,9 @@ bool TSReader::read(Translator &translator) msg.setContext(context); msg.setType(TranslatorMessage::Finished); msg.setPlural(attributes().value(strnumerus) == stryes); - msg.setUtf8(attributes().value(strutf8) == strtrue + const QStringRef &utf8Attr = attributes().value(strutf8); + msg.setNonUtf8(utf8Attr == strboth); + msg.setUtf8(msg.isNonUtf8() || utf8Attr == strtrue || attributes().value(strencoding) == strUtf8); while (!atEnd()) { readNext(); @@ -373,7 +378,7 @@ bool TSReader::read(Translator &translator) } else if (elementStarts(strtranslation)) { // <translation> QXmlStreamAttributes atts = attributes(); - QStringRef type = atts.value(strtype); + QStringRef type = atts.value(strtype); if (type == strunfinished) msg.setType(TranslatorMessage::Unfinished); else if (type == strobsolete) @@ -440,7 +445,7 @@ static QString protect(const QString &str) QString result; result.reserve(str.length() * 12 / 10); for (int i = 0; i != str.size(); ++i) { - uint c = str.at(i).unicode(); + uint c = str.at(i).unicode(); switch (c) { case '\"': result += QLatin1String("""); @@ -592,107 +597,126 @@ bool saveTS(const Translator &translator, QIODevice &dev, ConversionData &cd, in foreach (const TranslatorMessage &msg, messageOrder[context]) { //msg.dump(); - t << " <message"; - if (!msg.id().isEmpty()) - t << " id=\"" << msg.id() << "\""; - if (format == 11 && !trIsUtf8 && msg.isUtf8()) - t << " encoding=\"UTF-8\""; - if (format == 20 && !trIsUtf8 && msg.isUtf8()) - t << " utf8=\"true\""; - if (msg.isPlural()) - t << " numerus=\"yes\""; - t << ">\n"; - if (translator.locationsType() != Translator::NoLocations) { - QString cfile = currentFile; - bool first = true; - foreach (const TranslatorMessage::Reference &ref, msg.allReferences()) { - QString fn = cd.m_targetDir.relativeFilePath(ref.fileName()) - .replace(QLatin1Char('\\'),QLatin1Char('/')); - int ln = ref.lineNumber(); - QString ld; - if (translator.locationsType() == Translator::RelativeLocations) { - if (ln != -1) { - int dlt = ln - currentLine[fn]; - if (dlt >= 0) - ld.append(QLatin1Char('+')); - ld.append(QString::number(dlt)); - currentLine[fn] = ln; + bool isUtf8 = msg.isUtf8(); + bool second = false; + forever { + + t << " <message"; + if (!msg.id().isEmpty()) + t << " id=\"" << msg.id() << "\""; + if (!trIsUtf8) { + if (format == 11) { + if (isUtf8) + t << " encoding=\"UTF-8\""; + } else { + if (msg.isUtf8()) { + if (msg.isNonUtf8()) + t << " utf8=\"both\""; + else + t << " utf8=\"true\""; } + } + } + if (msg.isPlural()) + t << " numerus=\"yes\""; + t << ">\n"; + if (translator.locationsType() != Translator::NoLocations) { + QString cfile = currentFile; + bool first = true; + foreach (const TranslatorMessage::Reference &ref, msg.allReferences()) { + QString fn = cd.m_targetDir.relativeFilePath(ref.fileName()) + .replace(QLatin1Char('\\'),QLatin1Char('/')); + int ln = ref.lineNumber(); + QString ld; + if (translator.locationsType() == Translator::RelativeLocations) { + if (ln != -1) { + int dlt = ln - currentLine[fn]; + if (dlt >= 0) + ld.append(QLatin1Char('+')); + ld.append(QString::number(dlt)); + currentLine[fn] = ln; + } - if (fn != cfile) { - if (first) - currentFile = fn; - cfile = fn; + if (fn != cfile) { + if (first) + currentFile = fn; + cfile = fn; + } else { + fn.clear(); + } + first = false; } else { - fn.clear(); + if (ln != -1) + ld = QString::number(ln); } - first = false; - } else { - if (ln != -1) - ld = QString::number(ln); + t << " <location"; + if (!fn.isEmpty()) + t << " filename=\"" << fn << "\""; + if (!ld.isEmpty()) + t << " line=\"" << ld << "\""; + t << "/>\n"; } - t << " <location"; - if (!fn.isEmpty()) - t << " filename=\"" << fn << "\""; - if (!ld.isEmpty()) - t << " line=\"" << ld << "\""; - t << "/>\n"; } - } - t << " <source>" - << evilBytes(msg.sourceText(), msg.isUtf8(), format, codecName) - << "</source>\n"; + t << " <source>" + << evilBytes(msg.sourceText(), isUtf8, format, codecName) + << "</source>\n"; - if (format != 11 && !msg.oldSourceText().isEmpty()) - t << " <oldsource>" << protect(msg.oldSourceText()) << "</oldsource>\n"; + if (format != 11 && !msg.oldSourceText().isEmpty()) + t << " <oldsource>" << protect(msg.oldSourceText()) << "</oldsource>\n"; - if (!msg.comment().isEmpty()) { - t << " <comment>" - << evilBytes(msg.comment(), msg.isUtf8(), format, codecName) - << "</comment>\n"; - } + if (!msg.comment().isEmpty()) { + t << " <comment>" + << evilBytes(msg.comment(), isUtf8, format, codecName) + << "</comment>\n"; + } - if (format != 11) { + if (format != 11) { - if (!msg.oldComment().isEmpty()) - t << " <oldcomment>" << protect(msg.oldComment()) << "</oldcomment>\n"; + if (!msg.oldComment().isEmpty()) + t << " <oldcomment>" << protect(msg.oldComment()) << "</oldcomment>\n"; - if (!msg.extraComment().isEmpty()) - t << " <extracomment>" << protect(msg.extraComment()) - << "</extracomment>\n"; + if (!msg.extraComment().isEmpty()) + t << " <extracomment>" << protect(msg.extraComment()) + << "</extracomment>\n"; - if (!msg.translatorComment().isEmpty()) - t << " <translatorcomment>" << protect(msg.translatorComment()) - << "</translatorcomment>\n"; + if (!msg.translatorComment().isEmpty()) + t << " <translatorcomment>" << protect(msg.translatorComment()) + << "</translatorcomment>\n"; - } + } - t << " <translation"; - if (msg.type() == TranslatorMessage::Unfinished) - t << " type=\"unfinished\""; - else if (msg.type() == TranslatorMessage::Obsolete) - t << " type=\"obsolete\""; - if (msg.isPlural()) { - t << ">"; - QStringList translns = translator.normalizedTranslations(msg, cd, &result); - for (int j = 0; j < qMax(1, translns.count()); ++j) { - t << "\n <numerusform"; - writeVariants(t, " ", translns[j]); - t << "</numerusform>"; + t << " <translation"; + if (msg.type() == TranslatorMessage::Unfinished) + t << " type=\"unfinished\""; + else if (msg.type() == TranslatorMessage::Obsolete) + t << " type=\"obsolete\""; + if (msg.isPlural()) { + t << ">"; + QStringList translns = translator.normalizedTranslations(msg, cd, &result); + for (int j = 0; j < qMax(1, translns.count()); ++j) { + t << "\n <numerusform"; + writeVariants(t, " ", translns[j]); + t << "</numerusform>"; + } + t << "\n "; + } else { + writeVariants(t, " ", msg.translation()); } - t << "\n "; - } else { - writeVariants(t, " ", msg.translation()); - } - t << "</translation>\n"; + t << "</translation>\n"; + + if (format != 11) + writeExtras(t, " ", msg.extras(), drops); - if (format != 11) - writeExtras(t, " ", msg.extras(), drops); + if (!msg.userData().isEmpty()) + t << " <userdata>" << msg.userData() << "</userdata>\n"; + t << " </message>\n"; - if (!msg.userData().isEmpty()) - t << " <userdata>" << msg.userData() << "</userdata>\n"; - t << " </message>\n"; + if (format != 11 || second || !msg.isUtf8() || !msg.isNonUtf8()) + break; + isUtf8 = false; + second = true; + } } t << "</context>\n"; } @@ -708,12 +732,12 @@ bool loadTS(Translator &translator, QIODevice &dev, ConversionData &cd) return reader.read(translator); } -bool saveTS11(const Translator &translator, QIODevice &dev, ConversionData &cd) +bool saveTS11(const Translator &translator, QIODevice &dev, ConversionData &cd) { return saveTS(translator, dev, cd, 11); } -bool saveTS20(const Translator &translator, QIODevice &dev, ConversionData &cd) +bool saveTS20(const Translator &translator, QIODevice &dev, ConversionData &cd) { return saveTS(translator, dev, cd, 20); } diff --git a/tools/linguist/shared/ts.dtd b/tools/linguist/shared/ts.dtd index d979f0b..ab77f64 100644 --- a/tools/linguist/shared/ts.dtd +++ b/tools/linguist/shared/ts.dtd @@ -4,6 +4,8 @@ ! ! The location element is set as optional since it was introduced first in Qt 4.2. ! The userdata element is set as optional since it was introduced first in Qt 4.4. + ! The source and translation elements are optional starting with version 3.0 + ! (Qt 4.6) to support S60 blank messages. ! --> <!-- @@ -12,39 +14,100 @@ --> <!ENTITY % evilstring '(#PCDATA | byte)*' > <!ELEMENT byte EMPTY> +<!-- value contains decimal (e.g. 1000) or hex (e.g. x3e8) unicode encoding of one char --> <!ATTLIST byte value CDATA #REQUIRED> -<!ELEMENT TS (defaultcodec?, context+) > +<!-- + ! This element wildcard is no valid DTD. No better solution available. + ! extra elements may appear in TS and message elements. Each element may appear + ! only once within each scope. The contents are preserved verbatim; any + ! attributes are dropped. Currently recognized extra tags include: + ! extra-po-msgid_plural, extra-po-old_msgid_plural + ! extra-po-flags (comma-space separated list) + ! extra-loc-layout_id + ! extra-loc-feature + ! extra-loc-blank + --> +<!ELEMENT extra-* %evilstring; > +<!ELEMENT TS (defaultcodec?, extra-**, (context|message)+) > <!ATTLIST TS version CDATA #IMPLIED + sourcelanguage CDATA #IMPLIED language CDATA #IMPLIED> +<!-- The encoding to use in the .qm file by default. Default is ISO-8859-1. --> <!ELEMENT defaultcodec (#PCDATA) > -<!ELEMENT context (name, comment?, extracomment?, message+) > +<!ELEMENT context (name?, comment?, (context|message)+) > <!ATTLIST context encoding CDATA #IMPLIED> <!ELEMENT name %evilstring; > +<!-- If "no", then the context nesting is for informational puposes only --> +<!ATTLIST name + nest (yes|no) "yes"> +<!-- This is "disambiguation" in the (new) API, or "msgctxt" in gettext speak --> <!ELEMENT comment %evilstring; > +<!-- Previous content of comment (result of merge) --> <!ELEMENT oldcomment %evilstring; > -<!ELEMENT translatorcomment %evilstring; > +<!-- The real comment (added by developer/designer) --> <!ELEMENT extracomment %evilstring; > -<!ELEMENT message (location*, source, oldsource?, comment?, oldcomment?, extracomment?, translatorcomment?, translation, userdata?) > +<!-- Comment added by translator --> +<!ELEMENT translatorcomment %evilstring; > +<!ELEMENT message (location*, source?, oldsource?, comment?, oldcomment?, extracomment?, translatorcomment?, translation?, userdata?, extra-**) > +<!-- + ! If utf8 is true, the defaultcodec is overridden and the message is encoded + ! in UTF-8 in the .qm file. + --> <!ATTLIST message - encoding CDATA #IMPLIED + id CDATA #IMPLIED + utf8 (true|false) "false" numerus (yes|no) "no"> <!ELEMENT location EMPTY> +<!-- + ! If the line is omitted, the location specifies only a file. + ! + ! location supports relative specifications as well. Line numbers are + ! relative (explicitly positive or negative) to the last reference to a + ! given filename; each file starts with current line 0. If the filename + ! is omitted, the "current" one is used. For the 1st location in a message, + ! "current" is the filename used for the 1st location of the previous message. + ! For subsequent locations, it is the filename used for the previous location. + ! A single .ts file has either all absolute or all relative locations. + --> <!ATTLIST location - filename CDATA #REQUIRED - line CDATA #REQUIRED> + filename CDATA #IMPLIED + line CDATA #IMPLIED> <!ELEMENT source %evilstring;> -<!-- - ! The following should really say one evilstring macro or several numerusform elements, - ! but the DTD can't express this. +<!-- Previous content of source (result of merge) --> +<!ELEMENT oldsource %evilstring;> +<!-- + ! The following should really say one evilstring macro or several + ! numerusform or lengthvariant elements, but the DTD can't express this. + --> +<!ELEMENT translation (#PCDATA|byte|numerusform|lengthvariant)* > +<!-- + ! If no type is set, the message is "finished". + ! Length variants must be ordered by falling display length. + ! variants may not be yes if the message has numerus yes. --> -<!ELEMENT translation (#PCDATA|byte|numerusform)* > <!ATTLIST translation type (unfinished|obsolete) #IMPLIED - encoding CDATA #IMPLIED> + variants (yes|no) "no"> +<!-- Deprecated. Use extra-* --> <!ELEMENT userdata (#PCDATA)* > -<!ELEMENT numerusform %evilstring; > - - +<!-- + ! The following should really say one evilstring macro or several + ! lengthvariant elements, but the DTD can't express this. + ! Length variants must be ordered by falling display length. + --> +<!ELEMENT numerusform (#PCDATA|byte|lengthvariant)* > +<!ATTLIST numerusform + plurality (nullar|singular|dual|trial|paucal|greaterpaucal|plural|greaterplural) #IMPLIED> + variants (yes|no) "no"> +<!ELEMENT lengthvariant %evilstring; > +<!-- + ! The translation variants have a priority between 1 ("highest") and 9 ("lowest") + ! Typically longer translations get a higher priority. + ! If omitted, the order of appearance of the variants in the .ts files is used. + --> +<!ATTLIST lengthvariant + priority (1|2|3|4|5|6|7|8|9) #IMPLIED> + diff --git a/tools/linguist/shared/ui.cpp b/tools/linguist/shared/ui.cpp index d562285..ff98a90 100644 --- a/tools/linguist/shared/ui.cpp +++ b/tools/linguist/shared/ui.cpp @@ -60,7 +60,8 @@ class UiReader : public QXmlDefaultHandler { public: UiReader(Translator &translator, ConversionData &cd) - : m_translator(translator), m_cd(cd), m_lineNumber(-1) + : m_translator(translator), m_cd(cd), m_lineNumber(-1), m_isTrString(false), + m_needUtf8(translator.codecName() != "UTF-8") {} bool startElement(const QString &namespaceURI, const QString &localName, @@ -80,11 +81,13 @@ private: QString m_context; QString m_source; QString m_comment; + QString m_extracomment; QXmlLocator *m_locator; QString m_accum; int m_lineNumber; bool m_isTrString; + bool m_needUtf8; }; bool UiReader::startElement(const QString &namespaceURI, @@ -93,22 +96,27 @@ bool UiReader::startElement(const QString &namespaceURI, Q_UNUSED(namespaceURI); Q_UNUSED(localName); - if (qName == QLatin1String("item")) { + if (qName == QLatin1String("item")) { // UI3 menu entries flush(); - if (!atts.value(QLatin1String("text")).isEmpty()) + if (!atts.value(QLatin1String("text")).isEmpty()) { m_source = atts.value(QLatin1String("text")); + m_isTrString = true; + if (!m_cd.m_noUiLines) + m_lineNumber = m_locator->lineNumber(); + } } else if (qName == QLatin1String("string")) { flush(); if (atts.value(QLatin1String("notr")).isEmpty() || atts.value(QLatin1String("notr")) != QLatin1String("true")) { m_isTrString = true; m_comment = atts.value(QLatin1String("comment")); + m_extracomment = atts.value(QLatin1String("extracomment")); + if (!m_cd.m_noUiLines) + m_lineNumber = m_locator->lineNumber(); } else { m_isTrString = false; } } - if (m_isTrString && !m_cd.m_noUiLines) - m_lineNumber = m_locator->lineNumber(); m_accum.clear(); return true; } @@ -121,15 +129,15 @@ bool UiReader::endElement(const QString &namespaceURI, m_accum.replace(QLatin1String("\r\n"), QLatin1String("\n")); - if (qName == QLatin1String("class")) { + if (qName == QLatin1String("class")) { // UI "header" if (m_context.isEmpty()) m_context = m_accum; } else if (qName == QLatin1String("string") && m_isTrString) { m_source = m_accum; - } else if (qName == QLatin1String("comment")) { + } else if (qName == QLatin1String("comment")) { // FIXME: what's that? m_comment = m_accum; flush(); - } else if (qName == QLatin1String("function")) { + } else if (qName == QLatin1String("function")) { // UI3 embedded code fetchtrInlinedCpp(m_accum, m_translator, m_context); } else { flush(); @@ -149,7 +157,7 @@ bool UiReader::fatalError(const QXmlParseException &exception) msg.sprintf("XML error: Parse error at line %d, column %d (%s).", exception.lineNumber(), exception.columnNumber(), exception.message().toLatin1().data()); - m_cd.appendError(msg); + m_cd.appendError(msg); return false; } @@ -159,10 +167,14 @@ void UiReader::flush() TranslatorMessage msg(m_context, m_source, m_comment, QString(), m_cd.m_sourceFileName, m_lineNumber, QStringList()); + msg.setExtraComment(m_extracomment); + if (m_needUtf8 && msg.needs8Bit()) + msg.setUtf8(true); m_translator.extend(msg); } m_source.clear(); m_comment.clear(); + m_extracomment.clear(); } bool loadUI(Translator &translator, QIODevice &dev, ConversionData &cd) @@ -184,7 +196,7 @@ bool loadUI(Translator &translator, QIODevice &dev, ConversionData &cd) return result; } -bool saveUI(const Translator &translator, QIODevice &dev, ConversionData &cd) +bool saveUI(const Translator &translator, QIODevice &dev, ConversionData &cd) { Q_UNUSED(dev); Q_UNUSED(translator); diff --git a/tools/linguist/shared/xliff.cpp b/tools/linguist/shared/xliff.cpp index 115e1f4..6acf67a 100644 --- a/tools/linguist/shared/xliff.cpp +++ b/tools/linguist/shared/xliff.cpp @@ -744,7 +744,7 @@ bool saveXLIFF(const Translator &translator, QIODevice &dev, ConversionData &cd) int indent = 0; QTextStream ts(&dev); - //ts.setCodec( QTextCodec::codecForName("ISO-8859-1") ); // FIXME: Huh? + ts.setCodec(QTextCodec::codecForName("UTF-8")); QStringList dtgs = cd.dropTags(); dtgs << QLatin1String("po-(old_)?msgid_plural"); diff --git a/tools/macdeployqt/macdeployqt/main.cpp b/tools/macdeployqt/macdeployqt/main.cpp index 24ab9a3..0026c40 100644 --- a/tools/macdeployqt/macdeployqt/main.cpp +++ b/tools/macdeployqt/macdeployqt/main.cpp @@ -63,7 +63,7 @@ int main(int argc, char **argv) qDebug() << "framework. The accessibilty, image formats, and text codec"; qDebug() << "plugins are always copied, unless \"-no-plugins\" is specified."; qDebug() << ""; - qDebug() << "See the \"Deploying an Application on Qt/Mac\" typic in the"; + qDebug() << "See the \"Deploying an Application on Qt/Mac\" topic in the"; qDebug() << "documentation for more information about deployment on Mac OS X."; return 0; @@ -76,22 +76,26 @@ int main(int argc, char **argv) qDebug() << "Error: Could not find app bundle" << appBundlePath; return 0; } - - DeploymentInfo deploymentInfo = deployQtFrameworks(appBundlePath); - + bool plugins = true; bool dmg = false; extern bool runStripEnabled; - + for (int i = 2; i < argc; ++i) { QByteArray argument = QByteArray(argv[i]); - if (argument == QByteArray("-no-plugins")) + if (argument == QByteArray("-no-plugins")) { plugins = false; - if (argument == QByteArray("-dmg")) + } else if (argument == QByteArray("-dmg")) { dmg = true; - if (argument == QByteArray("-no-strip")) + } else if (argument == QByteArray("-no-strip")) { runStripEnabled = false; - } + } else if (argument.startsWith("-")) { + qDebug() << "Error: Unknown option" << argument << "\n"; + return 0; + } + } + + DeploymentInfo deploymentInfo = deployQtFrameworks(appBundlePath); if (plugins) { if (deploymentInfo.qtPath.isEmpty()) diff --git a/tools/qdoc3/atom.cpp b/tools/qdoc3/atom.cpp index a764653..f341862 100644 --- a/tools/qdoc3/atom.cpp +++ b/tools/qdoc3/atom.cpp @@ -106,6 +106,7 @@ QString Atom::UPPERROMAN_ ("upperroman"); \value CodeOld \value CodeQuoteArgument \value CodeQuoteCommand + \value EndQmlText \value FormatElse \value FormatEndif \value FormatIf @@ -131,6 +132,7 @@ QString Atom::UPPERROMAN_ ("upperroman"); \value ParaLeft \value ParaRight \value Qml + \value QmlText \value QuotationLeft \value QuotationRight \value RawString @@ -174,6 +176,9 @@ static const struct { { "CodeOld", Atom::CodeOld }, { "CodeQuoteArgument", Atom::CodeQuoteArgument }, { "CodeQuoteCommand", Atom::CodeQuoteCommand }, +#ifdef QDOC_QML + { "EndQmlText", Atom::EndQmlText }, +#endif { "FootnoteLeft", Atom::FootnoteLeft }, { "FootnoteRight", Atom::FootnoteRight }, { "FormatElse", Atom::FormatElse }, @@ -202,6 +207,7 @@ static const struct { { "ParaRight", Atom::ParaRight }, #ifdef QDOC_QML { "Qml", Atom::Qml}, + { "QmlText", Atom::QmlText }, #endif { "QuotationLeft", Atom::QuotationLeft }, { "QuotationRight", Atom::QuotationRight }, diff --git a/tools/qdoc3/atom.h b/tools/qdoc3/atom.h index 0d2a924..178d9ed 100644 --- a/tools/qdoc3/atom.h +++ b/tools/qdoc3/atom.h @@ -71,6 +71,9 @@ class Atom CodeOld, CodeQuoteArgument, CodeQuoteCommand, +#ifdef QDOC_QML + EndQmlText, +#endif FootnoteLeft, FootnoteRight, FormatElse, @@ -99,6 +102,7 @@ class Atom ParaRight, #ifdef QDOC_QML Qml, + QmlText, #endif QuotationLeft, QuotationRight, diff --git a/tools/qdoc3/codeparser.cpp b/tools/qdoc3/codeparser.cpp index 63b6865..9a58bc6 100644 --- a/tools/qdoc3/codeparser.cpp +++ b/tools/qdoc3/codeparser.cpp @@ -177,6 +177,11 @@ QSet<QString> CodeParser::commonMetaCommands() << COMMAND_TITLE; } +/*! + The topic command has been processed. Now process the other + metacommands that were found. These are not the text markup + commands. + */ void CodeParser::processCommonMetaCommand(const Location &location, const QString &command, const QString &arg, @@ -185,31 +190,43 @@ void CodeParser::processCommonMetaCommand(const Location &location, { if (command == COMMAND_COMPAT) { node->setStatus(Node::Compat); - } else if (command == COMMAND_DEPRECATED) { + } + else if (command == COMMAND_DEPRECATED) { node->setStatus(Node::Deprecated); - } else if (command == COMMAND_INGROUP) { + } + else if (command == COMMAND_INGROUP) { tree->addToGroup(node, arg); - } else if (command == COMMAND_INPUBLICGROUP) { + } + else if (command == COMMAND_INPUBLICGROUP) { tree->addToPublicGroup(node, arg); - } else if (command == COMMAND_INMODULE) { + } + else if (command == COMMAND_INMODULE) { node->setModuleName(arg); - } else if (command == COMMAND_MAINCLASS) { + } + else if (command == COMMAND_MAINCLASS) { node->setStatus(Node::Main); - } else if (command == COMMAND_OBSOLETE) { + } + else if (command == COMMAND_OBSOLETE) { if (node->status() != Node::Compat) node->setStatus(Node::Obsolete); - } else if (command == COMMAND_NONREENTRANT) { + } + else if (command == COMMAND_NONREENTRANT) { node->setThreadSafeness(Node::NonReentrant); - } else if (command == COMMAND_PRELIMINARY) { + } + else if (command == COMMAND_PRELIMINARY) { node->setStatus(Node::Preliminary); - } else if (command == COMMAND_INTERNAL) { + } + else if (command == COMMAND_INTERNAL) { node->setAccess(Node::Private); node->setStatus(Node::Internal); - } else if (command == COMMAND_REENTRANT) { + } + else if (command == COMMAND_REENTRANT) { node->setThreadSafeness(Node::Reentrant); - } else if (command == COMMAND_SINCE) { + } + else if (command == COMMAND_SINCE) { node->setSince(arg); - } else if (command == COMMAND_SUBTITLE) { + } + else if (command == COMMAND_SUBTITLE) { if (node->type() == Node::Fake) { FakeNode *fake = static_cast<FakeNode *>(node); fake->setSubTitle(arg); diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index fcf77f5..1ad5843 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -672,11 +672,13 @@ Node *CppCodeParser::processTopicCommand(const Doc& doc, else if (command == COMMAND_QMLCLASS) { const ClassNode* classNode = 0; QStringList names = arg.split(" "); - qDebug() << "QMLCLASS" << names; - Node* n = tre->findNode(names[1].split("::"),Node::Class); - if (n) { - classNode = static_cast<const ClassNode*>(n); - qDebug() << "FOUND IT!" << classNode->name(); + //qDebug() << "QMLCLASS" << names; + if (names.size() > 1) { + Node* n = tre->findNode(names[1].split("::"),Node::Class); + if (n) { + classNode = static_cast<const ClassNode*>(n); + //qDebug() << "FOUND IT!" << classNode->name(); + } } return new QmlNode(tre->root(), names[0], classNode); } diff --git a/tools/qdoc3/doc.cpp b/tools/qdoc3/doc.cpp index 1d3a7d4..61d0ed6 100644 --- a/tools/qdoc3/doc.cpp +++ b/tools/qdoc3/doc.cpp @@ -311,7 +311,8 @@ bool DocPrivate::isEnumDocSimplifiable() const while (atom) { if (atom->type() == Atom::AutoLink || atom->type() == Atom::String) { justMetColon = atom->string().endsWith(":"); - } else if ((atom->type() == Atom::ListLeft) && + } + else if ((atom->type() == Atom::ListLeft) && (atom->string() == ATOM_LIST_VALUE)) { if (justMetColon || numValueTables > 0) return false; @@ -478,7 +479,8 @@ void DocParser::parse(const QString& source, if (ch.isLetterOrNumber()) { cmdStr += ch; pos++; - } else { + } + else { break; } } @@ -488,7 +490,8 @@ void DocParser::parse(const QString& source, if (in.at(pos).isSpace()) { skipAllSpaces(); appendChar(QLatin1Char(' ')); - } else { + } + else { appendChar(in.at(pos++)); } } @@ -570,6 +573,9 @@ void DocParser::parse(const QString& source, leavePara(); append(Atom::Qml, getCode(CMD_QML, marker)); break; + case CMD_QMLTEXT: + append(Atom::QmlText); + break; #endif case CMD_CODELINE: { @@ -579,7 +585,7 @@ void DocParser::parse(const QString& source, && priv->text.lastAtom()->string().endsWith("\n\n")) priv->text.lastAtom()->chopString(); appendToCode("\n"); - } else { + } lse { append(Atom::CodeQuoteCommand, cmdStr); append(Atom::CodeQuoteArgument, " "); } @@ -589,7 +595,8 @@ void DocParser::parse(const QString& source, && priv->text.lastAtom()->string().endsWith("\n\n")) priv->text.lastAtom()->chopString(); appendToCode("\n"); - } else { + } + else { append(Atom::CodeQuoteCommand, cmdStr); append(Atom::CodeQuoteArgument, " "); } @@ -651,14 +658,16 @@ void DocParser::parse(const QString& source, if (preprocessorSkipping.size() > 0) { if (preprocessorSkipping.top()) { --numPreprocessorSkipping; - } else { + } + else { ++numPreprocessorSkipping; } preprocessorSkipping.top() = !preprocessorSkipping.top(); (void)getRestOfLine(); // ### should ensure that it's empty if (numPreprocessorSkipping) skipToNextPreprocessorCommand(); - } else { + } + else { location().warning(tr("Unexpected '\\%1'").arg(cmdName(CMD_ELSE))); } break; @@ -678,6 +687,9 @@ void DocParser::parse(const QString& source, case CMD_ENDQML: closeCommand(cmd); break; + case CMD_ENDQMLTEXT: + append(Atom::EndQmlText); + break; #endif case CMD_ENDFOOTNOTE: if (closeCommand(cmd)) { @@ -693,7 +705,8 @@ void DocParser::parse(const QString& source, (void)getRestOfLine(); // ### should ensure that it's empty if (numPreprocessorSkipping) skipToNextPreprocessorCommand(); - } else { + } + else { location().warning(tr("Unexpected '\\%1'").arg(cmdName(CMD_ENDIF))); } break; @@ -784,12 +797,14 @@ void DocParser::parse(const QString& source, leaveTableRow(); append(Atom::TableHeaderLeft); inTableHeader = true; - } else { + } + else { if (openedCommands.contains(CMD_TABLE)) { location().warning(tr("Cannot use '\\%1' within '\\%2'") .arg(cmdName(CMD_HEADER)) .arg(cmdName(openedCommands.top()))); - } else { + } + else { location().warning(tr("Cannot use '\\%1' outside of '\\%2'") .arg(cmdName(CMD_HEADER)) .arg(cmdName(CMD_TABLE))); @@ -824,7 +839,8 @@ void DocParser::parse(const QString& source, if (paraState == OutsidePara) { enterPara(); indexStartedPara = true; - } else { + } + else { const Atom *last = priv->text.lastAtom(); if (indexStartedPara && (last->type() != Atom::FormattingRight || @@ -844,12 +860,14 @@ void DocParser::parse(const QString& source, if (isLeftBraceAhead()) { currentLinkAtom = priv->text.lastAtom(); startFormat(ATOM_FORMATTING_LINK, cmd); - } else { + } + else { append(Atom::FormattingLeft, ATOM_FORMATTING_LINK); append(Atom::String, cleanLink(x)); append(Atom::FormattingRight, ATOM_FORMATTING_LINK); } - } else { + } + else { x = getArgument(); append(Atom::Link, x); append(Atom::FormattingLeft, ATOM_FORMATTING_LINK); @@ -893,7 +911,8 @@ void DocParser::parse(const QString& source, if (openedLists.top().isStarted()) { append(Atom::ListItemRight, openedLists.top().styleString()); - } else { + } + else { append(Atom::ListLeft, openedLists.top().styleString()); } @@ -903,7 +922,8 @@ void DocParser::parse(const QString& source, append(Atom::ListItemLeft, openedLists.top().styleString()); enterPara(); - } else if (openedCommands.top() == CMD_TABLE) { + } + else if (openedCommands.top() == CMD_TABLE) { x = "1,1"; if (isLeftBraceAhead()) x = getArgument(); @@ -915,14 +935,16 @@ void DocParser::parse(const QString& source, .arg(cmdName(CMD_O))); append(Atom::TableRowLeft); inTableRow = true; - } else if (inTableItem) { + } + else if (inTableItem) { append(Atom::TableItemRight); inTableItem = false; } append(Atom::TableItemLeft, x); inTableItem = true; - } else { + } + else { location().warning(tr("Command '\\%1' outside of '\\%2' and '\\%3'") .arg(cmdName(cmd)) .arg(cmdName(CMD_LIST)) @@ -1003,7 +1025,8 @@ void DocParser::parse(const QString& source, append(Atom::Code, quoter.quoteTo(location(), cmdStr, "")); quoter.reset(); - } else { + } + else { append(Atom::CodeQuoteCommand, cmdStr); append(Atom::CodeQuoteArgument, fileName); } @@ -1029,7 +1052,8 @@ void DocParser::parse(const QString& source, quoter.quoteUntil(location(), cmdStr, slashed(marker->functionEndRegExp(x)))); quoter.reset(); - } else { + } + else { append(Atom::CodeQuoteCommand, cmdStr); append(Atom::CodeQuoteArgument, slashed(marker->functionEndRegExp(x))); } @@ -1050,12 +1074,14 @@ void DocParser::parse(const QString& source, leaveTableRow(); append(Atom::TableRowLeft); inTableRow = true; - } else { + } + else { if (openedCommands.contains(CMD_TABLE)) { location().warning(tr("Cannot use '\\%1' within '\\%2'") .arg(cmdName(CMD_ROW)) .arg(cmdName(openedCommands.top()))); - } else { + } + else { location().warning(tr("Cannot use '\\%1' outside of '\\%2'") .arg(cmdName(CMD_ROW)) .arg(cmdName(CMD_TABLE))); @@ -1126,7 +1152,8 @@ void DocParser::parse(const QString& source, append(Atom::SnippetCommand, cmdStr); append(Atom::SnippetLocation, snippet); append(Atom::SnippetIdentifier, identifier); - } else { + } + else { Doc::quoteFromFile(location(),quoter,snippet); appendToCode(quoter.quoteSnippet(location(), identifier)); @@ -1136,7 +1163,8 @@ void DocParser::parse(const QString& source, append(Atom::SnippetCommand, cmdStr); append(Atom::SnippetLocation, snippet); append(Atom::SnippetIdentifier, identifier); - } else { + } + else { Doc::quoteFromFile(location(),quoter,snippet); appendToCode(quoter.quoteSnippet(location(), identifier)); @@ -1189,7 +1217,8 @@ void DocParser::parse(const QString& source, location().warning(tr("Invalid Unicode character '%1' specified " "with '%2'") .arg(x, cmdName(CMD_UNICODE))); - } else { + } + else { append(Atom::String, QChar(unicodeChar)); } } @@ -1210,7 +1239,8 @@ void DocParser::parse(const QString& source, skipSpacesOrOneEndl(); if (isBlankLine()) append(Atom::Nop); - } else { + } + else { // ### problems } break; @@ -1349,7 +1379,8 @@ void DocParser::parse(const QString& source, if (ch.isSpace()) { ++pos; newWord = false; - } else { + } + else { enterPara(); newWord = true; } @@ -1461,7 +1492,8 @@ void DocParser::parse(const QString& source, if (openedCommands.top() != CMD_OMIT) { location().warning(tr("Missing '\\%1'").arg(endCmdName(openedCommands.top()))); - } else if (preprocessorSkipping.count() > 0) { + } + else if (preprocessorSkipping.count() > 0) { location().warning(tr("Missing '\\%1'").arg(cmdName(CMD_ENDIF))); } @@ -1526,16 +1558,20 @@ void DocParser::checkExpiry(const QString& date) int days = expiryDate.daysTo(QDate::currentDate()); if (days == 0) { location().warning(tr("Documentation expires today")); - } else if (days == 1) { + } + else if (days == 1) { location().warning(tr("Documentation expired yesterday")); - } else if (days >= 2) { + } + else if (days >= 2) { location().warning(tr("Documentation expired %1 days ago") .arg(days)); } - } else { + } + else { location().warning(tr("Date '%1' invalid").arg(date)); } - } else { + } + else { location().warning(tr("Date '%1' not in YYYY-MM-DD format") .arg(date)); } @@ -1546,7 +1582,8 @@ void DocParser::insertBaseName(const QString &baseName) priv->constructExtra(); if (currentSectioningUnit == priv->extra->sectioningUnit) { priv->extra->baseName = baseName; - } else { + } + else { Atom *atom = priv->text.firstAtom(); Atom *sectionLeft = 0; @@ -1568,7 +1605,8 @@ void DocParser::insertTarget(const QString &target, bool keyword) if (targetMap.contains(target)) { location().warning(tr("Duplicate target name '%1'").arg(target)); targetMap[target].warning(tr("(The previous occurrence is here)")); - } else { + } + else { targetMap.insert(target, location()); append(Atom::Target, target); priv->constructExtra(); @@ -1594,12 +1632,14 @@ void DocParser::include(const QString& fileName) userFriendlyFilePath); if (filePath.isEmpty()) { location().warning(tr("Cannot find leaf file '%1'").arg(fileName)); - } else { + } + else { QFile inFile(filePath); if (!inFile.open(QFile::ReadOnly)) { location().warning(tr("Cannot open leaf file '%1'") .arg(userFriendlyFilePath)); - } else { + } + else { location().push(userFriendlyFilePath); QTextStream inStream(&inFile); @@ -1634,7 +1674,8 @@ void DocParser::startFormat(const QString& format, int cmd) pendingFormats.insert(braceDepth, format); ++braceDepth; ++pos; - } else { + } + else { append(Atom::String, getArgument()); append(Atom::FormattingRight, format); if (format == ATOM_FORMATTING_INDEX && indexStartedPara) { @@ -1652,28 +1693,34 @@ bool DocParser::openCommand(int cmd) if (cmd != CMD_LINK) { if (outer == CMD_LIST) { ok = (cmd == CMD_FOOTNOTE || cmd == CMD_LIST); - } else if (outer == CMD_ABSTRACT) { + } + else if (outer == CMD_ABSTRACT) { ok = (cmd == CMD_LIST || cmd == CMD_QUOTATION || cmd == CMD_TABLE); - } else if (outer == CMD_SIDEBAR) { + } + else if (outer == CMD_SIDEBAR) { ok = (cmd == CMD_LIST || cmd == CMD_QUOTATION || cmd == CMD_SIDEBAR); - } else if (outer == CMD_QUOTATION) { + } + else if (outer == CMD_QUOTATION) { ok = (cmd == CMD_LIST); - } else if (outer == CMD_TABLE) { + } + else if (outer == CMD_TABLE) { ok = (cmd == CMD_LIST || cmd == CMD_FOOTNOTE || cmd == CMD_QUOTATION); - } else if (outer == CMD_FOOTNOTE || outer == CMD_LINK) { + } + else if (outer == CMD_FOOTNOTE || outer == CMD_LINK) { ok = false; } } if (ok) { openedCommands.push(cmd); - } else { + } + else { location().warning(tr("Cannot use '\\%1' within '\\%2'") .arg(cmdName(cmd)).arg(cmdName(outer))); } @@ -1685,7 +1732,8 @@ bool DocParser::closeCommand(int endCmd) if (endCmdFor(openedCommands.top()) == endCmd && openedCommands.size() > 1) { openedCommands.pop(); return true; - } else { + } + else { bool contains = false; QStack<int> opened2 = openedCommands; while (opened2.size() > 1) { @@ -1703,7 +1751,8 @@ bool DocParser::closeCommand(int endCmd) .arg(cmdName(endCmd))); openedCommands.pop(); } - } else { + } + else { location().warning(tr("Unexpected '\\%1'") .arg(cmdName(endCmd))); } @@ -1728,10 +1777,12 @@ void DocParser::startSection(Doc::SectioningUnit unit, int cmd) if (unit <= priv->extra->sectioningUnit) { location().warning(tr("Unexpected '\\%1' in this documentation") .arg(cmdName(cmd))); - } else if (unit - currentSectioningUnit > 1) { + } + else if (unit - currentSectioningUnit > 1) { location().warning(tr("Unexpected '\\%1' at this point") .arg(cmdName(cmd))); - } else { + } + else { if (currentSectioningUnit >= unit) endSection(unit, cmd); @@ -1754,10 +1805,12 @@ void DocParser::endSection(int unit, int endCmd) if (unit < priv->extra->sectioningUnit) { location().warning(tr("Unexpected '\\%1' in this documentation") .arg(cmdName(endCmd))); - } else if (unit > currentSectioningUnit) { + } + else if (unit > currentSectioningUnit) { location().warning(tr("Unexpected '\\%1' at this point") .arg(cmdName(endCmd))); - } else { + } + else { while (currentSectioningUnit >= unit) { int delta = currentSectioningUnit - priv->extra->sectioningUnit; append(Atom::SectionRight, QString::number(delta)); @@ -1895,7 +1948,8 @@ void DocParser::enterPara(Atom::Type leftType, #endif leftType == Atom::SectionHeadingLeft) { paraState = InsideSingleLinePara; - } else { + } + else { paraState = InsideMultiLinePara; } skipSpacesOrOneEndl(); @@ -1912,7 +1966,8 @@ void DocParser::leavePara() if (priv->text.lastAtom()->type() == pendingParaLeftType) { priv->text.stripLastAtom(); - } else { + } + else { if (priv->text.lastAtom()->type() == Atom::String && priv->text.lastAtom()->string().endsWith(" ")) { priv->text.lastAtom()->chopString(); @@ -1932,7 +1987,8 @@ void DocParser::leaveValue() if (openedLists.isEmpty()) { openedLists.push(OpenedList(OpenedList::Value)); append(Atom::ListLeft, ATOM_LIST_VALUE); - } else { + } + else { if (priv->text.lastAtom()->type() == Atom::Nop) priv->text.stripLastAtom(); append(Atom::ListItemRight, ATOM_LIST_VALUE); @@ -1980,14 +2036,16 @@ void DocParser::expandMacro(const QString &name, { if (numParams == 0) { append(Atom::RawString, def); - } else { + } + else { QStringList args; QString rawString; for (int i = 0; i < numParams; i++) { if (numParams == 1 || isLeftBraceAhead()) { args << getArgument(true); - } else { + } + else { location().warning(tr("Macro '\\%1' invoked with too few" " arguments (expected %2, got %3)") .arg(name).arg(numParams).arg(i)); @@ -2007,7 +2065,8 @@ void DocParser::expandMacro(const QString &name, } append(Atom::String, args[paramNo - 1]); j += 2; - } else { + } + else { rawString += def[j++]; } } @@ -2022,19 +2081,26 @@ Doc::SectioningUnit DocParser::getSectioningUnit() if (name == "part") { return Doc::Part; - } else if (name == "chapter") { + } + else if (name == "chapter") { return Doc::Chapter; - } else if (name == "section1") { + } + else if (name == "section1") { return Doc::Section1; - } else if (name == "section2") { + } + else if (name == "section2") { return Doc::Section2; - } else if (name == "section3") { + } + else if (name == "section3") { return Doc::Section3; - } else if (name == "section4") { + } + else if (name == "section4") { return Doc::Section4; - } else if (name.isEmpty()) { + } + else if (name.isEmpty()) { return Doc::Section4; - } else { + } + else { location().warning(tr("Invalid sectioning unit '%1'").arg(name)); return Doc::Book; } @@ -2081,7 +2147,8 @@ QString DocParser::getArgument(bool verbatim) if (verbatim) { arg += in[pos]; pos++; - } else { + } + else { pos++; if (pos < (int) in.length()) { if (in[pos].isLetterOrNumber()) @@ -2089,7 +2156,8 @@ QString DocParser::getArgument(bool verbatim) arg += in[pos]; if (in[pos].isSpace()) { skipAllSpaces(); - } else { + } + else { pos++; } } @@ -2102,7 +2170,8 @@ QString DocParser::getArgument(bool verbatim) } if (delimDepth > 0) location().warning(tr("Missing '}'")); - } else { + } + else { while (pos < in.length() && ((delimDepth > 0) || ((delimDepth == 0) && @@ -2128,7 +2197,8 @@ QString DocParser::getArgument(bool verbatim) if (verbatim) { arg += in[pos]; pos++; - } else { + } + else { pos++; if (pos < (int) in.length()) { if (in[pos].isLetterOrNumber()) @@ -2136,7 +2206,8 @@ QString DocParser::getArgument(bool verbatim) arg += in[pos]; if (in[pos].isSpace()) { skipAllSpaces(); - } else { + } + else { pos++; } } @@ -2167,7 +2238,8 @@ QString DocParser::getOptionalArgument() if (pos + 1 < (int) in.length() && in[pos] == '\\' && in[pos + 1].isLetterOrNumber()) { return ""; - } else { + } + else { return getArgument(); } } @@ -2191,7 +2263,8 @@ QString DocParser::getRestOfLine() in[pos].isSpace() && (in[pos] != '\n')) ++pos; - } else { + } + else { trailingSlash = false; ++pos; } @@ -2252,7 +2325,8 @@ QString DocParser::getUntilEnd(int cmd) if (end == -1) { location().warning(tr("Missing '\\%1'").arg(cmdName(endCmd))); pos = in.length(); - } else { + } + else { t = in.mid(pos, end - pos); pos = end + rx.matchedLength(); } @@ -2327,7 +2401,8 @@ void DocParser::skipSpacesOrOneEndl() if (ch == '\n') { if (firstEndl == -1) { firstEndl = pos; - } else { + } + else { pos = firstEndl; break; } @@ -2369,6 +2444,8 @@ int DocParser::endCmdFor(int cmd) #ifdef QDOC_QML case CMD_QML: return CMD_ENDQML; + case CMD_QMLTEXT: + return CMD_ENDQMLTEXT; #endif case CMD_FOOTNOTE: return CMD_ENDFOOTNOTE; @@ -2459,7 +2536,8 @@ int DocParser::indentLevel(const QString& str) for (int i = 0; i < (int) str.length(); i++) { if (str[i] == '\n') { column = 0; - } else { + } + else { if (str[i] != ' ' && column < minIndent) minIndent = column; column++; @@ -2480,7 +2558,8 @@ QString DocParser::unindent(int level, const QString& str) if (str[i] == QLatin1Char('\n')) { t += '\n'; column = 0; - } else { + } + else { if (column >= level) t += str[i]; column++; @@ -2615,7 +2694,8 @@ void Doc::simplifyEnumDoc() atom = atom->next(); if (atom) atom = atom->next(); - } else { + } + else { newText << *atom; atom = atom->next(); } @@ -2730,7 +2810,8 @@ Text Doc::trimmedBriefText(const QString &className) const tr("Nonstandard wording in '\\%1' text for '%2' (expected more text)") .arg(COMMAND_BRIEF).arg(className)); standardWording = false; - } else + } + else whats[0] = whats[0].toUpper(); // ### move this once \brief is abolished for properties @@ -2753,7 +2834,8 @@ const QString& Doc::baseName() const static QString null; if (priv == 0 || priv->extra == 0) { return null; - } else { + } + else { return priv->extra->baseName; } } @@ -2762,7 +2844,8 @@ Doc::SectioningUnit Doc::granularity() const { if (priv == 0 || priv->extra == 0) { return DocPrivateExtra().granularity; - } else { + } + else { return priv->extra->granularity; } } @@ -2772,7 +2855,8 @@ Doc::SectioningUnit Doc::sectioningUnit() const { if (priv == 0 || priv->extra == 0) { return DocPrivateExtra().sectioningUnit; - } else { + } + else { return priv->extra->sectioningUnit; } } @@ -2873,7 +2957,8 @@ void Doc::initialize(const Config& config) .arg(alias) .arg(reverseAliasMap[alias]) .arg(*c)); - } else { + } + else { reverseAliasMap.insert(alias, *c); } aliasMap()->insert(*c, alias); @@ -2912,7 +2997,8 @@ void Doc::initialize(const Config& config) int m = Config::numParams(macro.defaultDef); if (macro.numParams == -1) { macro.numParams = m; - } else if (macro.numParams != m) { + } + else if (macro.numParams != m) { if (!silent) { QString other = tr("default"); if (macro.defaultDef.isEmpty()) @@ -3016,11 +3102,13 @@ CodeMarker *Doc::quoteFromFile(const Location &location, fileName, userFriendlyFilePath); if (filePath.isEmpty()) { location.warning(tr("Cannot find example file '%1'").arg(fileName)); - } else { + } + else { QFile inFile(filePath); if (!inFile.open(QFile::ReadOnly)) { location.warning(tr("Cannot open example file '%1'").arg(userFriendlyFilePath)); - } else { + } + else { QTextStream inStream(&inFile); code = DocParser::untabifyEtc(inStream.readAll()); } @@ -3061,11 +3149,13 @@ QString Doc::canonicalTitle(const QString &title) begun = true; slurping = false; lastAlnum = result.size(); - } else if (!slurping) { + } + else if (!slurping) { if (begun) result += QLatin1Char('-'); slurping = true; - } else { + } + else { // !alnum && slurping -> nothin } } diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index 8a90636..d89d6af 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -96,21 +96,22 @@ void Generator::terminateGenerator() void Generator::initialize(const Config &config) { outputFormats = config.getStringSet(CONFIG_OUTPUTFORMATS); - if ( !outputFormats.isEmpty() ) { + if (!outputFormats.isEmpty()) { outDir = config.getString(CONFIG_OUTPUTDIR); - if ( outDir.isEmpty() ) + if (outDir.isEmpty()) config.lastLocation().fatal(tr("No output directory specified in configuration file")); QDir dirInfo; - if ( dirInfo.exists(outDir) ) { - if ( !Config::removeDirContents(outDir) ) + if (dirInfo.exists(outDir)) { + if (!Config::removeDirContents(outDir)) config.lastLocation().error(tr("Cannot empty output directory '%1'").arg(outDir)); - } else { - if ( !dirInfo.mkpath(outDir) ) + } + else { + if (!dirInfo.mkpath(outDir)) config.lastLocation().fatal(tr("Cannot create output directory '%1'").arg(outDir)); } - if ( !dirInfo.mkdir(outDir + "/images") ) + if (!dirInfo.mkdir(outDir + "/images")) config.lastLocation().fatal(tr("Cannot create output directory '%1'") .arg(outDir + "/images")); } @@ -119,9 +120,9 @@ void Generator::initialize(const Config &config) imageDirs = config.getStringList(CONFIG_IMAGEDIRS); QString imagesDotFileExtensions = CONFIG_IMAGES + Config::dot + CONFIG_FILEEXTENSIONS; - QSet<QString> formats = config.subVars( imagesDotFileExtensions ); + QSet<QString> formats = config.subVars(imagesDotFileExtensions); QSet<QString>::ConstIterator f = formats.begin(); - while ( f != formats.end() ) { + while (f != formats.end()) { imgFileExts[*f] = config.getStringList(imagesDotFileExtensions + Config::dot + *f); ++f; } @@ -146,33 +147,35 @@ void Generator::initialize(const Config &config) ++g; } - QRegExp secondParamAndAbove( "[\2-\7]" ); - QSet<QString> formattingNames = config.subVars( CONFIG_FORMATTING ); + QRegExp secondParamAndAbove("[\2-\7]"); + QSet<QString> formattingNames = config.subVars(CONFIG_FORMATTING); QSet<QString>::ConstIterator n = formattingNames.begin(); - while ( n != formattingNames.end() ) { + while (n != formattingNames.end()) { QString formattingDotName = CONFIG_FORMATTING + Config::dot + *n; - QSet<QString> formats = config.subVars( formattingDotName ); + QSet<QString> formats = config.subVars(formattingDotName); QSet<QString>::ConstIterator f = formats.begin(); - while ( f != formats.end() ) { - QString def = config.getString( formattingDotName + Config::dot + - *f ); - if ( !def.isEmpty() ) { - int numParams = Config::numParams( def ); + while (f != formats.end()) { + QString def = config.getString(formattingDotName + Config::dot + + *f); + if (!def.isEmpty()) { + int numParams = Config::numParams(def); int numOccs = def.count("\1"); - if ( numParams != 1 ) { + if (numParams != 1) { config.lastLocation().warning(tr("Formatting '%1' must have exactly one" " parameter (found %2)") .arg(*n).arg(numParams)); - } else if ( numOccs > 1 ) { + } + else if (numOccs > 1) { config.lastLocation().fatal(tr("Formatting '%1' must contain exactly one" " occurrence of '\\1' (found %2)") .arg(*n).arg(numOccs)); - } else { - int paramPos = def.indexOf( "\1" ); - fmtLeftMaps[*f].insert( *n, def.left(paramPos) ); - fmtRightMaps[*f].insert( *n, def.mid(paramPos + 1) ); + } + else { + int paramPos = def.indexOf("\1"); + fmtLeftMaps[*f].insert(*n, def.left(paramPos)); + fmtRightMaps[*f].insert(*n, def.mid(paramPos + 1)); } } ++f; @@ -186,7 +189,7 @@ void Generator::initialize(const Config &config) void Generator::terminate() { QList<Generator *>::ConstIterator g = generators.begin(); - while ( g != generators.end() ) { + while (g != generators.end()) { if (outputFormats.contains((*g)->format())) (*g)->terminateGenerator(); ++g; @@ -200,65 +203,97 @@ void Generator::terminate() outDir = ""; } -Generator *Generator::generatorForFormat( const QString& format ) +Generator *Generator::generatorForFormat(const QString& format) { QList<Generator *>::ConstIterator g = generators.begin(); - while ( g != generators.end() ) { - if ( (*g)->format() == format ) + while (g != generators.end()) { + if ((*g)->format() == format) return *g; ++g; } return 0; } -void Generator::startText( const Node * /* relative */, - CodeMarker * /* marker */ ) +void Generator::startText(const Node * /* relative */, + CodeMarker * /* marker */) { } -void Generator::endText( const Node * /* relative */, - CodeMarker * /* marker */ ) +void Generator::endText(const Node * /* relative */, + CodeMarker * /* marker */) { } -int Generator::generateAtom( const Atom * /* atom */, - const Node * /* relative */, - CodeMarker * /* marker */ ) +int Generator::generateAtom(const Atom * /* atom */, + const Node * /* relative */, + CodeMarker * /* marker */) { return 0; } -void Generator::generateClassLikeNode(const InnerNode * /* classe */, CodeMarker * /* marker */) +void Generator::generateClassLikeNode(const InnerNode * /* classe */, + CodeMarker * /* marker */) { } -void Generator::generateFakeNode( const FakeNode * /* fake */, - CodeMarker * /* marker */ ) +void Generator::generateFakeNode(const FakeNode * /* fake */, + CodeMarker * /* marker */) { } -void Generator::generateText( const Text& text, const Node *relative, - CodeMarker *marker ) +void Generator::generateText(const Text& text, + const Node *relative, + CodeMarker *marker) { - if ( text.firstAtom() != 0 ) { + if (text.firstAtom() != 0) { int numAtoms = 0; - startText( relative, marker ); - generateAtomList( text.firstAtom(), relative, marker, true, numAtoms ); - endText( relative, marker ); + startText(relative, marker); + generateAtomList(text.firstAtom(), + relative, + marker, + true, + numAtoms); + endText(relative, marker); } } -void Generator::generateBody( const Node *node, CodeMarker *marker ) +#ifdef QDOC_QML +void Generator::generateQmlText(const Text& text, + const Node *relative, + CodeMarker *marker) +{ + if (text.firstAtom() != 0) { + startText(relative, marker); + const Atom *atom = text.firstAtom(); + while (atom) { + if (atom->type() != Atom::QmlText) + atom = atom->next(); + else { + atom = atom->next(); + while (atom && (atom->type() != Atom::EndQmlText)) { + int n = 1 + generateAtom(atom, relative, marker); + while (n-- > 0) + atom = atom->next(); + } + } + } + endText(relative, marker); + } +} +#endif + +void Generator::generateBody(const Node *node, CodeMarker *marker) { bool quiet = false; - if ( node->type() == Node::Function ) { + if (node->type() == Node::Function) { #if 0 const FunctionNode *func = (const FunctionNode *) node; - if ( func->isOverload() && func->metaness() != FunctionNode::Ctor ) - generateOverload( node, marker ); + if (func->isOverload() && func->metaness() != FunctionNode::Ctor) + generateOverload(node, marker); #endif - } else if (node->type() == Node::Fake) { + } + else if (node->type() == Node::Fake) { const FakeNode *fake = static_cast<const FakeNode *>(node); if (fake->subType() == FakeNode::Example) generateExampleFiles(fake, marker); @@ -270,42 +305,45 @@ void Generator::generateBody( const Node *node, CodeMarker *marker ) if (!quiet) // ### might be unnecessary node->location().warning(tr("No documentation for '%1'") .arg(marker->plainFullName(node))); - } else { + } + else { generateText(node->doc().body(), node, marker); - if ( node->type() == Node::Enum ) { + if (node->type() == Node::Enum) { const EnumNode *enume = (const EnumNode *) node; QSet<QString> definedItems; QList<EnumItem>::ConstIterator it = enume->items().begin(); - while ( it != enume->items().end() ) { - definedItems.insert( (*it).name() ); + while (it != enume->items().end()) { + definedItems.insert((*it).name()); ++it; } QSet<QString> documentedItems = enume->doc().enumItemNames().toSet(); QSet<QString> allItems = definedItems + documentedItems; - if ( allItems.count() > definedItems.count() || - allItems.count() > documentedItems.count() ) { + if (allItems.count() > definedItems.count() || + allItems.count() > documentedItems.count()) { QSet<QString>::ConstIterator a = allItems.begin(); - while ( a != allItems.end() ) { - if ( !definedItems.contains(*a) ) { + while (a != allItems.end()) { + if (!definedItems.contains(*a)) { QString details; - QString best = nearestName( *a, definedItems ); - if ( !best.isEmpty() && !documentedItems.contains(best) ) - details = tr( "Maybe you meant '%1'?" ).arg( best ); + QString best = nearestName(*a, definedItems); + if (!best.isEmpty() && !documentedItems.contains(best)) + details = tr("Maybe you meant '%1'?").arg(best); node->doc().location().warning( tr("No such enum item '%1' in %2").arg(*a).arg(marker->plainFullName(node)), details); - } else if ( !documentedItems.contains(*a) ) { + } + else if (!documentedItems.contains(*a)) { node->doc().location().warning( tr("Undocumented enum item '%1' in %2").arg(*a).arg(marker->plainFullName(node))); } ++a; } } - } else if ( node->type() == Node::Function ) { + } + else if (node->type() == Node::Function) { const FunctionNode *func = static_cast<const FunctionNode *>(node); QSet<QString> definedParams; @@ -315,8 +353,9 @@ void Generator::generateBody( const Node *node, CodeMarker *marker ) && func->name() != QLatin1String("operator++") && func->name() != QLatin1String("operator--")) { node->doc().location().warning(tr("Missing parameter name")); - } else { - definedParams.insert( (*p).name() ); + } + else { + definedParams.insert((*p).name()); } ++p; } @@ -330,13 +369,14 @@ void Generator::generateBody( const Node *node, CodeMarker *marker ) if (!definedParams.contains(*a)) { QString details; QString best = nearestName(*a, definedParams); - if ( !best.isEmpty() ) + if (!best.isEmpty()) details = tr("Maybe you meant '%1'?").arg(best); node->doc().location().warning( tr("No such parameter '%1' in %2").arg(*a).arg(marker->plainFullName(node)), details); - } else if ( !(*a).isEmpty() && !documentedParams.contains(*a) ) { + } + else if (!(*a).isEmpty() && !documentedParams.contains(*a)) { bool needWarning = (func->status() > Node::Obsolete); if (func->overloadNumber() > 1) { FunctionNode *primaryFunc = @@ -365,8 +405,8 @@ void Generator::generateBody( const Node *node, CodeMarker *marker ) node->doc().location().warning(tr("Undocumented return value")); } - if ( func->reimplementedFrom() != 0 ) - generateReimplementedFrom( func, marker ); + if (func->reimplementedFrom() != 0) + generateReimplementedFrom(func, marker); } } @@ -383,7 +423,7 @@ void Generator::generateBody( const Node *node, CodeMarker *marker ) } } -void Generator::generateAlsoList( const Node *node, CodeMarker *marker ) +void Generator::generateAlsoList(const Node *node, CodeMarker *marker) { QList<Text> alsoList = node->doc().alsoList(); supplementAlsoList(node, alsoList); @@ -396,7 +436,7 @@ void Generator::generateAlsoList( const Node *node, CodeMarker *marker ) text << alsoList.at(i) << separator(i, alsoList.size()); text << Atom::ParaRight; - generateText( text, node, marker ); + generateText(text, node, marker); } } @@ -405,41 +445,41 @@ void Generator::generateInherits(const ClassNode *classe, CodeMarker *marker) QList<RelatedClass>::ConstIterator r; int index; - if ( !classe->baseClasses().isEmpty() ) { + if (!classe->baseClasses().isEmpty()) { Text text; text << Atom::ParaLeft << "Inherits "; r = classe->baseClasses().begin(); index = 0; - while ( r != classe->baseClasses().end() ) { + while (r != classe->baseClasses().end()) { text << Atom(Atom::LinkNode, CodeMarker::stringForNode((*r).node)) << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) << Atom(Atom::String, (*r).dataTypeWithTemplateArgs) << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); - if ( (*r).access == Node::Protected ) { + if ((*r).access == Node::Protected) { text << " (protected)"; - } else if ( (*r).access == Node::Private ) { + } else if ((*r).access == Node::Private) { text << " (private)"; } - text << separator( index++, classe->baseClasses().count() ); + text << separator(index++, classe->baseClasses().count()); ++r; } text << Atom::ParaRight; - generateText( text, classe, marker ); + generateText(text, classe, marker); } } -void Generator::generateInheritedBy( const ClassNode *classe, - CodeMarker *marker ) +void Generator::generateInheritedBy(const ClassNode *classe, + CodeMarker *marker) { - if ( !classe->derivedClasses().isEmpty() ) { + if (!classe->derivedClasses().isEmpty()) { Text text; text << Atom::ParaLeft << "Inherited by "; appendSortedNames(text, classe, classe->derivedClasses(), marker); text << Atom::ParaRight; - generateText( text, classe, marker ); + generateText(text, classe, marker); } } @@ -480,17 +520,19 @@ void Generator::generateModuleWarning(const ClassNode *classe, CodeMarker *marke << "This class is not part of the Qt Console Edition." << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << Atom::ParaRight; - } else if (Tokenizer::isTrue("defined(desktoplightedition)") + } + else if (Tokenizer::isTrue("defined(desktoplightedition)") && !editionModuleMap["DesktopLight"].contains(module)) { text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) << "This class is not part of the Qt Desktop Light Edition." << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << Atom::ParaRight; - } else if (module == "Qt3Support" && Tokenizer::isTrue("defined(opensourceedition)")) { - text << Atom::ParaLeft << Atom( Atom::FormattingLeft, ATOM_FORMATTING_BOLD ) + } + else if (module == "Qt3Support" && Tokenizer::isTrue("defined(opensourceedition)")) { + text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) << "Note to Qt Desktop Light Edition users:" - << Atom( Atom::FormattingRight, ATOM_FORMATTING_BOLD ) + << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << " This class is only available in the " << Atom(Atom::AutoLink, "Qt Desktop Edition") << "." << Atom::ParaRight; @@ -500,28 +542,28 @@ void Generator::generateModuleWarning(const ClassNode *classe, CodeMarker *marke } } -QString Generator::indent( int level, const QString& markedCode ) +QString Generator::indent(int level, const QString& markedCode) { - if ( level == 0 ) + if (level == 0) return markedCode; QString t; int column = 0; int i = 0; - while ( i < (int) markedCode.length() ) { - if ( markedCode.at(i) == QLatin1Char('<') ) { - while ( i < (int) markedCode.length() ) { + while (i < (int) markedCode.length()) { + if (markedCode.at(i) == QLatin1Char('<')) { + while (i < (int) markedCode.length()) { t += markedCode.at(i++); - if ( markedCode.at(i - 1) == QLatin1Char('>') ) + if (markedCode.at(i - 1) == QLatin1Char('>')) break; } } else { - if ( markedCode.at(i) == QLatin1Char('\n') ) { + if (markedCode.at(i) == QLatin1Char('\n')) { column = 0; } else { - if ( column == 0 ) { - for ( int j = 0; j < level; j++ ) + if (column == 0) { + for (int j = 0; j < level; j++) t += QLatin1Char(' '); } column++; @@ -532,20 +574,20 @@ QString Generator::indent( int level, const QString& markedCode ) return t; } -QString Generator::plainCode( const QString& markedCode ) +QString Generator::plainCode(const QString& markedCode) { QString t = markedCode; - t.replace( tag, QString() ); - t.replace( quot, QLatin1String("\"") ); - t.replace( gt, QLatin1String(">") ); - t.replace( lt, QLatin1String("<") ); - t.replace( amp, QLatin1String("&") ); + t.replace(tag, QString()); + t.replace(quot, QLatin1String("\"")); + t.replace(gt, QLatin1String(">")); + t.replace(lt, QLatin1String("<")); + t.replace(amp, QLatin1String("&")); return t; } -QString Generator::typeString( const Node *node ) +QString Generator::typeString(const Node *node) { - switch ( node->type() ) { + switch (node->type()) { case Node::Namespace: return "namespace"; case Node::Class: @@ -564,7 +606,7 @@ QString Generator::typeString( const Node *node ) } } -QString Generator::imageFileName( const Node *relative, const QString& fileBase ) +QString Generator::imageFileName(const Node *relative, const QString& fileBase) { QString userFriendlyFilePath; QString filePath = Config::findFile( @@ -580,18 +622,18 @@ QString Generator::imageFileName( const Node *relative, const QString& fileBase outputDir() + QLatin1String("/images")); } -void Generator::setImageFileExtensions( const QStringList& extensions ) +void Generator::setImageFileExtensions(const QStringList& extensions) { imgFileExts[format()] = extensions; } -void Generator::unknownAtom( const Atom *atom ) +void Generator::unknownAtom(const Atom *atom) { - Location::internalError( tr("unknown atom type '%1' in %2 generator") - .arg(atom->typeString()).arg(format()) ); + Location::internalError(tr("unknown atom type '%1' in %2 generator") + .arg(atom->typeString()).arg(format())); } -bool Generator::matchAhead( const Atom *atom, Atom::Type expectedAtomType ) +bool Generator::matchAhead(const Atom *atom, Atom::Type expectedAtomType) { return atom->next() != 0 && atom->next()->type() == expectedAtomType; } @@ -664,44 +706,44 @@ QString Generator::trimmedTrailing(const QString &string) return trimmed; } -void Generator::generateStatus( const Node *node, CodeMarker *marker ) +void Generator::generateStatus(const Node *node, CodeMarker *marker) { Text text; - switch ( node->status() ) { + switch (node->status()) { case Node::Commendable: case Node::Main: break; case Node::Preliminary: - text << Atom::ParaLeft << Atom( Atom::FormattingLeft, ATOM_FORMATTING_BOLD ) << "This " - << typeString( node ) << " is under development and is subject to change." - << Atom( Atom::FormattingRight, ATOM_FORMATTING_BOLD ) << Atom::ParaRight; + text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) << "This " + << typeString(node) << " is under development and is subject to change." + << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << Atom::ParaRight; break; case Node::Deprecated: text << Atom::ParaLeft; if (node->isInnerNode()) - text << Atom( Atom::FormattingLeft, ATOM_FORMATTING_BOLD ); - text << "This " << typeString( node ) << " is deprecated."; + text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD); + text << "This " << typeString(node) << " is deprecated."; if (node->isInnerNode()) - text << Atom( Atom::FormattingRight, ATOM_FORMATTING_BOLD ); + text << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD); text << Atom::ParaRight; break; case Node::Obsolete: text << Atom::ParaLeft; if (node->isInnerNode()) - text << Atom( Atom::FormattingLeft, ATOM_FORMATTING_BOLD ); - text << "This " << typeString( node ) << " is obsolete."; + text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD); + text << "This " << typeString(node) << " is obsolete."; if (node->isInnerNode()) - text << Atom( Atom::FormattingRight, ATOM_FORMATTING_BOLD ); + text << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD); text << " It is provided to keep old source code working. We strongly advise against " << "using it in new code." << Atom::ParaRight; break; case Node::Compat: // reimplemented in HtmlGenerator subclass if (node->isInnerNode()) { - text << Atom::ParaLeft << Atom( Atom::FormattingLeft, ATOM_FORMATTING_BOLD ) << "This " - << typeString( node ) << " is part of the Qt 3 compatibility layer." - << Atom( Atom::FormattingRight, ATOM_FORMATTING_BOLD ) + text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) << "This " + << typeString(node) << " is part of the Qt 3 compatibility layer." + << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << " It is provided to keep old source code working. We strongly advise against " << "using it in new code. See " << Atom(Atom::AutoLink, "Porting to Qt 4") @@ -759,7 +801,8 @@ void Generator::generateThreadSafeness(const Node *node, CodeMarker *marker) } if (except.isEmpty()) { text << "."; - } else { + } + else { text << ", except "; NodeList::ConstIterator e = except.begin(); @@ -770,7 +813,8 @@ void Generator::generateThreadSafeness(const Node *node, CodeMarker *marker) ++e; } } - } else { + } + else { text << "This " << typeString(node) << " is " << theStockLink << "."; } text << Atom::ParaRight; @@ -796,7 +840,7 @@ void Generator::generateSince(const Node *node, CodeMarker *marker) /*! No longer in use. */ -void Generator::generateOverload( const Node *node, CodeMarker *marker ) +void Generator::generateOverload(const Node *node, CodeMarker *marker) { Text text; text << Atom::ParaLeft @@ -804,55 +848,71 @@ void Generator::generateOverload( const Node *node, CodeMarker *marker ) QString t = node->name() + "()"; text << Atom::AutoLink << t << Atom::ParaRight; - generateText( text, node, marker ); + generateText(text, node, marker); } -void Generator::generateReimplementedFrom( const FunctionNode *func, - CodeMarker *marker ) +void Generator::generateReimplementedFrom(const FunctionNode *func, + CodeMarker *marker) { - if ( func->reimplementedFrom() != 0 ) { + if (func->reimplementedFrom() != 0) { const FunctionNode *from = func->reimplementedFrom(); if (from->access() != Node::Private && from->parent()->access() != Node::Private) { Text text; text << Atom::ParaLeft << "Reimplemented from "; - appendFullName( text, from->parent(), func, marker, from ); + appendFullName(text, from->parent(), func, marker, from); text << "." << Atom::ParaRight; - generateText( text, func, marker ); + generateText(text, func, marker); } } } -const Atom *Generator::generateAtomList(const Atom *atom, const Node *relative, CodeMarker *marker, - bool generate, int &numAtoms) +const Atom *Generator::generateAtomList(const Atom *atom, + const Node *relative, + CodeMarker *marker, + bool generate, + int &numAtoms) { while (atom) { if (atom->type() == Atom::FormatIf) { int numAtoms0 = numAtoms; bool rightFormat = canHandleFormat(atom->string()); - atom = generateAtomList(atom->next(), relative, marker, generate && rightFormat, + atom = generateAtomList(atom->next(), + relative, + marker, + generate && rightFormat, numAtoms); if (!atom) return 0; if (atom->type() == Atom::FormatElse) { ++numAtoms; - atom = generateAtomList( atom->next(), relative, marker, - generate && !rightFormat, numAtoms ); + atom = generateAtomList(atom->next(), + relative, + marker, + generate && !rightFormat, + numAtoms); if (!atom) return 0; } if (atom->type() == Atom::FormatEndif) { if (generate && numAtoms0 == numAtoms) { - relative->location().warning(tr("Output format %1 not handled").arg(format())); + relative->location().warning(tr("Output format %1 not handled"). + arg(format())); Atom unhandledFormatAtom(Atom::UnhandledFormat, format()); - generateAtomList(&unhandledFormatAtom, relative, marker, generate, numAtoms); + generateAtomList(&unhandledFormatAtom, + relative, + marker, + generate, + numAtoms); } atom = atom->next(); } - } else if (atom->type() == Atom::FormatElse || atom->type() == Atom::FormatEndif) { + } + else if (atom->type() == Atom::FormatElse || atom->type() == Atom::FormatEndif) { return atom; - } else { + } + else { int n = 1; if (generate) { n += generateAtom(atom, relative, marker); @@ -865,11 +925,13 @@ const Atom *Generator::generateAtomList(const Atom *atom, const Node *relative, return 0; } -void Generator::appendFullName( Text& text, const Node *apparentNode, - const Node *relative, CodeMarker *marker, - const Node *actualNode ) +void Generator::appendFullName(Text& text, + const Node *apparentNode, + const Node *relative, + CodeMarker *marker, + const Node *actualNode) { - if ( actualNode == 0 ) + if (actualNode == 0) actualNode = apparentNode; text << Atom(Atom::LinkNode, CodeMarker::stringForNode(actualNode)) << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) @@ -877,7 +939,8 @@ void Generator::appendFullName( Text& text, const Node *apparentNode, << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); } -void Generator::appendSortedNames(Text& text, const ClassNode *classe, +void Generator::appendSortedNames(Text& text, + const ClassNode *classe, const QList<RelatedClass> &classes, CodeMarker *marker) { @@ -886,11 +949,11 @@ void Generator::appendSortedNames(Text& text, const ClassNode *classe, int index = 0; r = classes.begin(); - while ( r != classes.end() ) { + while (r != classes.end()) { if ((*r).node->access() == Node::Public && (*r).node->status() != Node::Internal && !(*r).node->doc().isEmpty()) { Text className; - appendFullName( className, (*r).node, classe, marker ); + appendFullName(className, (*r).node, classe, marker); classMap[className.toString().toLower()] = className; } ++r; @@ -901,7 +964,7 @@ void Generator::appendSortedNames(Text& text, const ClassNode *classe, foreach (const QString &className, classNames) { text << classMap[className]; - text << separator( index++, classNames.count() ); + text << separator(index++, classNames.count()); } } @@ -909,14 +972,15 @@ int Generator::skipAtoms(const Atom *atom, Atom::Type type) const { int skipAhead = 0; atom = atom->next(); - while ( atom != 0 && atom->type() != type ) { + while (atom != 0 && atom->type() != type) { skipAhead++; atom = atom->next(); } return skipAhead; } -QString Generator::fullName(const Node *node, const Node *relative, +QString Generator::fullName(const Node *node, + const Node *relative, CodeMarker *marker) const { if (node->type() == Node::Fake) diff --git a/tools/qdoc3/generator.h b/tools/qdoc3/generator.h index 2c06480..3db2d8d 100644 --- a/tools/qdoc3/generator.h +++ b/tools/qdoc3/generator.h @@ -70,7 +70,7 @@ class Tree; class Generator { -public: + public: Generator(); virtual ~Generator(); @@ -80,47 +80,57 @@ public: virtual bool canHandleFormat(const QString &format) { return format == this->format(); } virtual void generateTree(const Tree *tree, CodeMarker *marker) = 0; - static void initialize( const Config& config ); + static void initialize(const Config& config); static void terminate(); - static Generator *generatorForFormat( const QString& format ); - -protected: - virtual void startText( const Node *relative, CodeMarker *marker ); - virtual void endText( const Node *relative, CodeMarker *marker ); - virtual int generateAtom( const Atom *atom, const Node *relative, - CodeMarker *marker ); + static Generator *generatorForFormat(const QString& format); + + protected: + virtual void startText(const Node *relative, CodeMarker *marker); + virtual void endText(const Node *relative, CodeMarker *marker); + virtual int generateAtom(const Atom *atom, + const Node *relative, + CodeMarker *marker); virtual void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker); - virtual void generateFakeNode( const FakeNode *fake, CodeMarker *marker ); - - virtual void generateText( const Text& text, const Node *relative, - CodeMarker *marker ); - virtual void generateBody( const Node *node, CodeMarker *marker ); - virtual void generateAlsoList( const Node *node, CodeMarker *marker ); - virtual void generateInherits( const ClassNode *classe, - CodeMarker *marker ); - virtual void generateInheritedBy( const ClassNode *classe, - CodeMarker *marker ); - - void generateThreadSafeness( const Node *node, CodeMarker *marker ); + virtual void generateFakeNode(const FakeNode *fake, CodeMarker *marker); + + virtual void generateText(const Text& text, + const Node *relative, + CodeMarker *marker); +#ifdef QDOC_QML + virtual void generateQmlText(const Text& text, + const Node *relative, + CodeMarker *marker); +#endif + virtual void generateBody(const Node *node, CodeMarker *marker); + virtual void generateAlsoList(const Node *node, CodeMarker *marker); + virtual void generateInherits(const ClassNode *classe, + CodeMarker *marker); + virtual void generateInheritedBy(const ClassNode *classe, + CodeMarker *marker); + + void generateThreadSafeness(const Node *node, CodeMarker *marker); void generateSince(const Node *node, CodeMarker *marker); - void generateStatus( const Node *node, CodeMarker *marker ); - const Atom *generateAtomList( const Atom *atom, const Node *relative, - CodeMarker *marker, bool generate, - int& numGeneratedAtoms ); + void generateStatus(const Node *node, CodeMarker *marker); + const Atom *generateAtomList(const Atom *atom, + const Node *relative, + CodeMarker *marker, + bool generate, + int& numGeneratedAtoms); void generateExampleFiles(const FakeNode *fake, CodeMarker *marker); - void generateModuleWarning( const ClassNode *classe, CodeMarker *marker); + void generateModuleWarning(const ClassNode *classe, CodeMarker *marker); virtual int skipAtoms(const Atom *atom, Atom::Type type) const; - virtual QString fullName(const Node *node, const Node *relative, + virtual QString fullName(const Node *node, + const Node *relative, CodeMarker *marker) const; const QString& outputDir() { return outDir; } - QString indent( int level, const QString& markedCode ); - QString plainCode( const QString& markedCode ); - virtual QString typeString( const Node *node ); - virtual QString imageFileName( const Node *relative, const QString& fileBase ); - void setImageFileExtensions( const QStringList& extensions ); - void unknownAtom( const Atom *atom ); + QString indent(int level, const QString& markedCode); + QString plainCode(const QString& markedCode); + virtual QString typeString(const Node *node); + virtual QString imageFileName(const Node *relative, const QString& fileBase); + void setImageFileExtensions(const QStringList& extensions); + void unknownAtom(const Atom *atom); QMap<QString, QString> &formattingLeftMap(); QMap<QString, QString> &formattingRightMap(); @@ -128,17 +138,20 @@ protected: QMap<QString, QStringList> editionGroupMap; static QString trimmedTrailing(const QString &string); - static bool matchAhead( const Atom *atom, Atom::Type expectedAtomType ); + static bool matchAhead(const Atom *atom, Atom::Type expectedAtomType); static void supplementAlsoList(const Node *node, QList<Text> &alsoList); private: - void generateOverload( const Node *node, CodeMarker *marker ); - void generateReimplementedFrom( const FunctionNode *func, - CodeMarker *marker ); - void appendFullName( Text& text, const Node *apparentNode, - const Node *relative, CodeMarker *marker, - const Node *actualNode = 0 ); - void appendSortedNames(Text& text, const ClassNode *classe, + void generateOverload(const Node *node, CodeMarker *marker); + void generateReimplementedFrom(const FunctionNode *func, + CodeMarker *marker); + void appendFullName(Text& text, + const Node *apparentNode, + const Node *relative, + CodeMarker *marker, + const Node *actualNode = 0); + void appendSortedNames(Text& text, + const ClassNode *classe, const QList<RelatedClass> &classes, CodeMarker *marker); diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index a0fc743..13d52bf 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -319,7 +319,8 @@ int HtmlGenerator::generateAtom(const Atom *atom, out() << formattingLeftMap()[ATOM_FORMATTING_TELETYPE]; if (inLink) { out() << protect(plainCode(atom->string())); - } else { + } + else { out() << highlightedCode(atom->string(), marker, relative); } out() << formattingRightMap()[ATOM_FORMATTING_TELETYPE]; @@ -382,22 +383,26 @@ int HtmlGenerator::generateAtom(const Atom *atom, case Atom::FormattingRight: if (atom->string() == ATOM_FORMATTING_LINK) { endLink(); - } else { + } + else { out() << formattingRightMap()[atom->string()]; } break; case Atom::GeneratedList: if (atom->string() == "annotatedclasses") { generateAnnotatedList(relative, marker, nonCompatClasses); - } else if (atom->string() == "classes") { + } + else if (atom->string() == "classes") { generateCompactList(relative, marker, nonCompatClasses); - } else if (atom->string().contains("classesbymodule")) { + } + else if (atom->string().contains("classesbymodule")) { QString arg = atom->string().trimmed(); QString moduleName = atom->string().mid(atom->string().indexOf( "classesbymodule") + 15).trimmed(); if (moduleClassMap.contains(moduleName)) generateAnnotatedList(relative, marker, moduleClassMap[moduleName]); - } else if (atom->string().contains("classesbyedition")) { + } + else if (atom->string().contains("classesbyedition")) { QString arg = atom->string().trimmed(); QString editionName = atom->string().mid(atom->string().indexOf( @@ -422,7 +427,8 @@ int HtmlGenerator::generateAtom(const Atom *atom, groupClasses = groups.values(groupName.mid(1)); foreach (const Node *node, groupClasses) editionClasses.remove(node->name()); - } else { + } + else { groupClasses = groups.values(groupName); foreach (const Node *node, groupClasses) editionClasses.insert(node->name(), node); @@ -430,23 +436,32 @@ int HtmlGenerator::generateAtom(const Atom *atom, } generateAnnotatedList(relative, marker, editionClasses); } - } else if (atom->string() == "classhierarchy") { + } + else if (atom->string() == "classhierarchy") { generateClassHierarchy(relative, marker, nonCompatClasses); - } else if (atom->string() == "compatclasses") { + } + else if (atom->string() == "compatclasses") { generateCompactList(relative, marker, compatClasses); - } else if (atom->string() == "functionindex") { + } + else if (atom->string() == "functionindex") { generateFunctionIndex(relative, marker); - } else if (atom->string() == "legalese") { + } + else if (atom->string() == "legalese") { generateLegaleseList(relative, marker); - } else if (atom->string() == "mainclasses") { + } + else if (atom->string() == "mainclasses") { generateCompactList(relative, marker, mainClasses); - } else if (atom->string() == "services") { + } + else if (atom->string() == "services") { generateCompactList(relative, marker, serviceClasses); - } else if (atom->string() == "overviews") { + } + else if (atom->string() == "overviews") { generateOverviewList(relative, marker); - } else if (atom->string() == "namespaces") { + } + else if (atom->string() == "namespaces") { generateAnnotatedList(relative, marker, namespaceIndex); - } else if (atom->string() == "related") { + } + else if (atom->string() == "related") { const FakeNode *fake = static_cast<const FakeNode *>(relative); if (fake && !fake->groupMembers().isEmpty()) { QMap<QString, const Node *> groupMembersMap; @@ -456,7 +471,8 @@ int HtmlGenerator::generateAtom(const Atom *atom, } generateAnnotatedList(fake, marker, groupMembersMap); } - } else if (atom->string() == "relatedinline") { + } + else if (atom->string() == "relatedinline") { const FakeNode *fake = static_cast<const FakeNode *>(relative); if (fake && !fake->groupMembers().isEmpty()) { // Reverse the list into the original scan order. @@ -482,7 +498,8 @@ int HtmlGenerator::generateAtom(const Atom *atom, if (fileName.isEmpty()) { out() << "<font color=\"red\">[Missing image " << protect(atom->string()) << "]</font>"; - } else { + } + else { out() << "<img src=\"" << protect(fileName) << "\""; if (!text.isEmpty()) out() << " alt=\"" << protect(text) << "\""; @@ -530,29 +547,37 @@ int HtmlGenerator::generateAtom(const Atom *atom, } if (atom->string() == ATOM_LIST_BULLET) { out() << "<ul>\n"; - } else if (atom->string() == ATOM_LIST_TAG) { + } + else if (atom->string() == ATOM_LIST_TAG) { out() << "<dl>\n"; - } else if (atom->string() == ATOM_LIST_VALUE) { + } + else if (atom->string() == ATOM_LIST_VALUE) { threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom); if (threeColumnEnumValueTable) { out() << "<p><table border=\"1\" cellpadding=\"2\" cellspacing=\"1\" width=\"100%\">\n" "<tr><th width=\"25%\">Constant</th><th width=\"15%\">Value</th>" "<th width=\"60%\">Description</th></tr>\n"; - } else { + } + else { out() << "<p><table border=\"1\" cellpadding=\"2\" cellspacing=\"1\" width=\"40%\">\n" << "<tr><th width=\"60%\">Constant</th><th width=\"40%\">Value</th></tr>\n"; } - } else { + } + else { out() << "<ol type="; if (atom->string() == ATOM_LIST_UPPERALPHA) { out() << "\"A\""; - } else if (atom->string() == ATOM_LIST_LOWERALPHA) { + } + else if (atom->string() == ATOM_LIST_LOWERALPHA) { out() << "\"a\""; - } else if (atom->string() == ATOM_LIST_UPPERROMAN) { + } + else if (atom->string() == ATOM_LIST_UPPERROMAN) { out() << "\"I\""; - } else if (atom->string() == ATOM_LIST_LOWERROMAN) { + } + else if (atom->string() == ATOM_LIST_LOWERROMAN) { out() << "\"i\""; - } else { // (atom->string() == ATOM_LIST_NUMERIC) + } + else { // (atom->string() == ATOM_LIST_NUMERIC) out() << "\"1\""; } if (atom->next() != 0 && atom->next()->string().toInt() != 1) @@ -565,7 +590,8 @@ int HtmlGenerator::generateAtom(const Atom *atom, case Atom::ListTagLeft: if (atom->string() == ATOM_LIST_TAG) { out() << "<dt>"; - } else { // (atom->string() == ATOM_LIST_VALUE) + } + else { // (atom->string() == ATOM_LIST_VALUE) // ### Trenton out() << "<tr><td valign=\"top\"><tt>" @@ -594,13 +620,15 @@ int HtmlGenerator::generateAtom(const Atom *atom, case Atom::ListItemLeft: if (atom->string() == ATOM_LIST_TAG) { out() << "<dd>"; - } else if (atom->string() == ATOM_LIST_VALUE) { + } + else if (atom->string() == ATOM_LIST_VALUE) { if (threeColumnEnumValueTable) { out() << "</td><td valign=\"top\">"; if (matchAhead(atom, Atom::ListItemRight)) out() << " "; } - } else { + } + else { out() << "<li>"; } if (matchAhead(atom, Atom::ParaLeft)) @@ -609,20 +637,25 @@ int HtmlGenerator::generateAtom(const Atom *atom, case Atom::ListItemRight: if (atom->string() == ATOM_LIST_TAG) { out() << "</dd>\n"; - } else if (atom->string() == ATOM_LIST_VALUE) { + } + else if (atom->string() == ATOM_LIST_VALUE) { out() << "</td></tr>\n"; - } else { + } + else { out() << "</li>\n"; } break; case Atom::ListRight: if (atom->string() == ATOM_LIST_BULLET) { out() << "</ul>\n"; - } else if (atom->string() == ATOM_LIST_TAG) { + } + else if (atom->string() == ATOM_LIST_TAG) { out() << "</dl>\n"; - } else if (atom->string() == ATOM_LIST_VALUE) { + } + else if (atom->string() == ATOM_LIST_VALUE) { out() << "</table></p>\n"; - } else { + } + else { out() << "</ol>\n"; } break; @@ -658,7 +691,8 @@ int HtmlGenerator::generateAtom(const Atom *atom, do { sectionNumber.append("1"); } while (sectionNumber.size() < nextLevel); - } else { + } + else { while (sectionNumber.size() > nextLevel) { sectionNumber.removeLast(); } @@ -688,7 +722,8 @@ int HtmlGenerator::generateAtom(const Atom *atom, case Atom::String: if (inLink && !inContents && !inSectionHeading) { generateLink(atom, relative, marker); - } else { + } + else { out() << protect(atom->string()); } break; @@ -704,7 +739,8 @@ int HtmlGenerator::generateAtom(const Atom *atom, << "cellspacing=\"1\" border=\"0\">\n"; else out() << "<p><table align=\"center\" cellpadding=\"2\" cellspacing=\"1\" border=\"0\">\n"; - } else { + } + else { out() << "<p><table align=\"center\" cellpadding=\"2\" cellspacing=\"1\" border=\"0\">\n"; } numTableRows = 0; @@ -721,7 +757,8 @@ int HtmlGenerator::generateAtom(const Atom *atom, if (matchAhead(atom, Atom::TableHeaderLeft)) { skipAhead = 1; out() << "\n<tr valign=\"top\" class=\"qt-style\">"; - } else { + } + else { out() << "</thead>\n"; inTableHeader = false; } @@ -798,6 +835,12 @@ int HtmlGenerator::generateAtom(const Atom *atom, out() << "<font color=\"red\"><b><code>\\" << protect(atom->string()) << "</code></b></font>"; break; +#ifdef QDOC_QML + case Atom::QmlText: + case Atom::EndQmlText: + // don't do anything with these. They are just tags. + break; +#endif default: unknownAtom(atom); } @@ -821,7 +864,8 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner, rawTitle = marker->plainName(inner); fullTitle = marker->plainFullName(inner); title = rawTitle + " Namespace Reference"; - } else if (inner->type() == Node::Class) { + } + else if (inner->type() == Node::Class) { classe = static_cast<const ClassNode *>(inner); rawTitle = marker->plainName(inner); fullTitle = marker->plainFullName(inner); @@ -1101,12 +1145,12 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) generateBody(fake, marker); #ifdef QDOC_QML if (fake->subType() == FakeNode::QmlClass) { - qDebug() << "generateFakeNode(): QML CLASS" << fake->name(); + //qDebug() << "generateFakeNode(): QML CLASS" << fake->name(); const QmlNode* qmlNode = static_cast<const QmlNode*>(fake); const ClassNode* cn = qmlNode->classNode(); if (cn) { - qDebug() << " CPP CLASS" << cn->name(); - generateBody(cn, marker); + //qDebug() << " CPP CLASS" << cn->name(); + generateQmlText(cn->doc().body(), cn, marker); } } #endif @@ -1142,18 +1186,23 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) if (fake->subType() == FakeNode::Example) { appendDcfSubSection(&dcfExamplesRoot, fakeSection); - } else if (fake->subType() != FakeNode::File) { + } + else if (fake->subType() != FakeNode::File) { QString contentsPage = fake->links().value(Node::ContentsLink).first; if (contentsPage == "Qt Designer Manual") { appendDcfSubSection(&dcfDesignerRoot, fakeSection); - } else if (contentsPage == "Qt Linguist Manual") { + } + else if (contentsPage == "Qt Linguist Manual") { appendDcfSubSection(&dcfLinguistRoot, fakeSection); - } else if (contentsPage == "Qt Assistant Manual") { + } + else if (contentsPage == "Qt Assistant Manual") { appendDcfSubSection(&dcfAssistantRoot, fakeSection); - } else if (contentsPage == "qmake Manual") { + } + else if (contentsPage == "qmake Manual") { appendDcfSubSection(&dcfQmakeRoot, fakeSection); - } else { + } + else { appendDcfSubSection(&dcfOverviewsRoot, fakeSection); } } @@ -2865,10 +2914,10 @@ void HtmlGenerator::findAllQmlClasses(const InnerNode *node) const FakeNode* fakeNode = static_cast<const FakeNode *>(*c); if (fakeNode->subType() == FakeNode::QmlClass) { const QmlNode* qmlNode = static_cast<const QmlNode*>(fakeNode); - qDebug() << "HtmlGenerator: QML CLASS" << qmlNode->name(); + //qDebug() << "HtmlGenerator: QML CLASS" << qmlNode->name(); const Node* n = qmlNode->classNode(); if (n) - qDebug() << " FOUND IT!" << n->name(); + //qDebug() << " FOUND IT!" << n->name(); } qmlClasses.insert(fakeNode->name(),*c); } @@ -2922,9 +2971,11 @@ const Node *HtmlGenerator::findNodeForTarget(const QString &target, if (target.isEmpty()) { node = relative; - } else if (target.endsWith(".html")) { + } + else if (target.endsWith(".html")) { node = tre->root()->findNode(target, Node::Fake); - } else if (marker) { + } + else if (marker) { node = marker->resolveTarget(target, tre, relative); if (!node) node = tre->findFakeNodeByTitle(target); @@ -2969,11 +3020,13 @@ QString HtmlGenerator::getLink(const Atom *atom, || atom->string().startsWith("mailto:"))) { link = atom->string(); - } else { + } + else { QStringList path; if (atom->string().contains('#')) { path = atom->string().split('#'); - } else { + } + else { path.append(atom->string()); } @@ -2982,9 +3035,11 @@ QString HtmlGenerator::getLink(const Atom *atom, QString first = path.first().trimmed(); if (first.isEmpty()) { node = relative; - } else if (first.endsWith(".html")) { + } + else if (first.endsWith(".html")) { node = tre->root()->findNode(first, Node::Fake); - } else { + } + else { node = marker->resolveTarget(first, tre, relative); if (!node) node = tre->findFakeNodeByTitle(first); @@ -2997,7 +3052,8 @@ QString HtmlGenerator::getLink(const Atom *atom, return node->url(); else path.removeFirst(); - } else { + } + else { node = relative; } diff --git a/tools/qdoc3/pagegenerator.cpp b/tools/qdoc3/pagegenerator.cpp index 39e286e..2d50279 100644 --- a/tools/qdoc3/pagegenerator.cpp +++ b/tools/qdoc3/pagegenerator.cpp @@ -198,9 +198,11 @@ void PageGenerator::generateInnerNode(const InnerNode *node, } else if (node->type() == Node::Fake) { const FakeNode* fakeNode = static_cast<const FakeNode *>(node); +#ifdef QDOC_QML if (fakeNode->subType() == FakeNode::QmlClass) { - qDebug() << "FILENAME:" << fileName(node); + //qDebug() << "FILENAME:" << fileName(node); } +#endif generateFakeNode(static_cast<const FakeNode *>(node), marker); } endSubPage(); diff --git a/tools/qdoc3/test/classic.css b/tools/qdoc3/test/classic.css index 0d0b664..6cf7377 100644 --- a/tools/qdoc3/test/classic.css +++ b/tools/qdoc3/test/classic.css @@ -99,6 +99,14 @@ body pre color: black } +table tr.qt-code pre +{ + padding: 0.2em; + border: #e7e7e7 1px solid; + background: #f1f1f1; + color: black +} + span.preprocessor, span.preprocessor a { color: darkblue; diff --git a/tools/qdoc3/test/macros.qdocconf b/tools/qdoc3/test/macros.qdocconf index d14f80a..85fe1db 100644 --- a/tools/qdoc3/test/macros.qdocconf +++ b/tools/qdoc3/test/macros.qdocconf @@ -23,5 +23,7 @@ macro.rarrow.HTML = "→" macro.reg.HTML = "<sup>®</sup>" macro.return = "Returns" macro.starslash = "\\c{*/}" +macro.begincomment = "\\c{/*}" +macro.endcomment = "\\c{*/}" macro.uuml.HTML = "ü" macro.mdash.HTML = "—" diff --git a/tools/qdoc3/test/qt-api-only.qdocconf b/tools/qdoc3/test/qt-api-only.qdocconf index 2e91ba2..bc5656b 100644 --- a/tools/qdoc3/test/qt-api-only.qdocconf +++ b/tools/qdoc3/test/qt-api-only.qdocconf @@ -9,7 +9,7 @@ url = ./ # Ensures that the documentation for the tools is not included in the generated # .qhp file. -qhp.Qt.excluded = $QT_SOURCE_TREE/doc/src/assistant-manual.qdoc \ +qhp.Qt.excluded += $QT_SOURCE_TREE/doc/src/assistant-manual.qdoc \ $QT_SOURCE_TREE/doc/src/examples/simpletextviewer.qdoc \ $QT_SOURCE_TREE/doc/src/designer-manual.qdoc \ $QT_SOURCE_TREE/doc/src/examples/calculatorbuilder.qdoc \ diff --git a/tools/qdoc3/test/qt-build-docs.qdocconf b/tools/qdoc3/test/qt-build-docs.qdocconf index a085768..25cdc5a 100644 --- a/tools/qdoc3/test/qt-build-docs.qdocconf +++ b/tools/qdoc3/test/qt-build-docs.qdocconf @@ -92,7 +92,11 @@ excludedirs = $QT_SOURCE_TREE/src/3rdparty/clucene \ $QT_SOURCE_TREE/src/3rdparty/webkit/WebCore \ $QT_SOURCE_TREE/src/3rdparty/wintab \ $QT_SOURCE_TREE/src/3rdparty/zlib \ - $QT_SOURCE_TREE/doc/src/snippets + $QT_SOURCE_TREE/doc/src/snippets \ + $QT_SOURCE_TREE/src/3rdparty/phonon/gstreamer \ + $QT_SOURCE_TREE/src/3rdparty/phonon/ds9 \ + $QT_SOURCE_TREE/src/3rdparty/phonon/qt7 \ + $QT_SOURCE_TREE/src/3rdparty/phonon/waveout sources.fileextensions = "*.cpp *.qdoc *.mm" examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp" diff --git a/tools/qdoc3/test/qt.qdocconf b/tools/qdoc3/test/qt.qdocconf index 298311e..4d401a4 100644 --- a/tools/qdoc3/test/qt.qdocconf +++ b/tools/qdoc3/test/qt.qdocconf @@ -22,7 +22,7 @@ edition.DesktopLight.groups = -graphicsview-api qhp.projects = Qt qhp.Qt.file = qt.qhp -qhp.Qt.namespace = com.trolltech.qt.450 +qhp.Qt.namespace = com.trolltech.qt.451 qhp.Qt.virtualFolder = qdoc qhp.Qt.indexTitle = Qt Reference Documentation qhp.Qt.indexRoot = diff --git a/tools/qvfb/qvfb.cpp b/tools/qvfb/qvfb.cpp index b6a715c..62149a1 100644 --- a/tools/qvfb/qvfb.cpp +++ b/tools/qvfb/qvfb.cpp @@ -217,16 +217,10 @@ QVFb::QVFb( int display_id, int w, int h, int d, int r, const QString &skin, Dis setWindowIcon( pix ); rateDlg = 0; refreshRate = 30; -#if QT_VERSION >= 0x030000 - // When compiling with Qt 3 we need to create the menu first to - // avoid scroll bars in the main window + // Create the menu first to avoid scroll bars in the main window createMenu( menuBar() ); init( display_id, w, h, d, r, skin ); enableCursor( true ); -#else - init( display_id, w, h, d, r, skin ); - createMenu( menuBar() ); -#endif } QVFb::~QVFb() @@ -354,9 +348,7 @@ void QVFb::init( int display_id, int pw, int ph, int d, int r, const QString& sk scroller->setWidget(view); view->setContentsMargins( 0, 0, 0, 0 ); setCentralWidget(scroller); -#if QT_VERSION >= 0x030000 ph += 2; // avoid scrollbar -#endif scroller->show(); // delete defaultbuttons.conf if it was left behind... unlink(QFileInfo(QString("/tmp/qtembedded-%1/defaultbuttons.conf").arg(view->displayId())).absoluteFilePath().toLatin1().constData()); diff --git a/tools/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp b/tools/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp index ecdaf16..09394e7 100644 --- a/tools/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp +++ b/tools/shared/qtpropertybrowser/qtbuttonpropertybrowser.cpp @@ -48,9 +48,7 @@ #include <QtGui/QToolButton> #include <QtGui/QStyle> -#if QT_VERSION >= 0x040400 QT_BEGIN_NAMESPACE -#endif class QtButtonPropertyBrowserPrivate { @@ -626,8 +624,6 @@ bool QtButtonPropertyBrowser::isExpanded(QtBrowserItem *item) const return false; } -#if QT_VERSION >= 0x040400 QT_END_NAMESPACE -#endif #include "moc_qtbuttonpropertybrowser.cpp" diff --git a/tools/shared/qtpropertybrowser/qtbuttonpropertybrowser.h b/tools/shared/qtpropertybrowser/qtbuttonpropertybrowser.h index 0833c2d..0238f5c 100644 --- a/tools/shared/qtpropertybrowser/qtbuttonpropertybrowser.h +++ b/tools/shared/qtpropertybrowser/qtbuttonpropertybrowser.h @@ -44,9 +44,7 @@ #include "qtpropertybrowser.h" -#if QT_VERSION >= 0x040400 QT_BEGIN_NAMESPACE -#endif class QtButtonPropertyBrowserPrivate; @@ -82,8 +80,6 @@ private: }; -#if QT_VERSION >= 0x040400 QT_END_NAMESPACE -#endif #endif diff --git a/tools/shared/qtpropertybrowser/qteditorfactory.cpp b/tools/shared/qtpropertybrowser/qteditorfactory.cpp index 3e9336f..a2e3917 100644 --- a/tools/shared/qtpropertybrowser/qteditorfactory.cpp +++ b/tools/shared/qtpropertybrowser/qteditorfactory.cpp @@ -62,9 +62,7 @@ # pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */ #endif -#if QT_VERSION >= 0x040400 QT_BEGIN_NAMESPACE -#endif // Set a hard coded left margin to account for the indentation // of the tree view icon when switching to an editor @@ -2583,9 +2581,7 @@ void QtFontEditorFactory::disconnectPropertyManager(QtFontPropertyManager *manag disconnect(manager, SIGNAL(valueChanged(QtProperty*,QFont)), this, SLOT(slotPropertyChanged(QtProperty*,QFont))); } -#if QT_VERSION >= 0x040400 QT_END_NAMESPACE -#endif #include "moc_qteditorfactory.cpp" #include "qteditorfactory.moc" diff --git a/tools/shared/qtpropertybrowser/qteditorfactory.h b/tools/shared/qtpropertybrowser/qteditorfactory.h index 044dd5e..d86f9f6 100644 --- a/tools/shared/qtpropertybrowser/qteditorfactory.h +++ b/tools/shared/qtpropertybrowser/qteditorfactory.h @@ -44,9 +44,7 @@ #include "qtpropertymanager.h" -#if QT_VERSION >= 0x040400 QT_BEGIN_NAMESPACE -#endif class QtSpinBoxFactoryPrivate; @@ -394,8 +392,6 @@ private: Q_PRIVATE_SLOT(d_func(), void slotSetValue(const QFont &)) }; -#if QT_VERSION >= 0x040400 QT_END_NAMESPACE -#endif #endif diff --git a/tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp b/tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp index d7c8f0b..9ac9744 100644 --- a/tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp +++ b/tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.cpp @@ -47,9 +47,7 @@ #include <QtCore/QTimer> #include <QtCore/QMap> -#if QT_VERSION >= 0x040400 QT_BEGIN_NAMESPACE -#endif class QtGroupBoxPropertyBrowserPrivate { @@ -528,8 +526,6 @@ void QtGroupBoxPropertyBrowser::itemChanged(QtBrowserItem *item) d_ptr->propertyChanged(item); } -#if QT_VERSION >= 0x040400 QT_END_NAMESPACE -#endif #include "moc_qtgroupboxpropertybrowser.cpp" diff --git a/tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.h b/tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.h index 29422bd..6d1b2b1 100644 --- a/tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.h +++ b/tools/shared/qtpropertybrowser/qtgroupboxpropertybrowser.h @@ -44,9 +44,7 @@ #include "qtpropertybrowser.h" -#if QT_VERSION >= 0x040400 QT_BEGIN_NAMESPACE -#endif class QtGroupBoxPropertyBrowserPrivate; @@ -73,8 +71,6 @@ private: }; -#if QT_VERSION >= 0x040400 QT_END_NAMESPACE -#endif #endif diff --git a/tools/shared/qtpropertybrowser/qtpropertybrowser.cpp b/tools/shared/qtpropertybrowser/qtpropertybrowser.cpp index 7254245..cca082d 100644 --- a/tools/shared/qtpropertybrowser/qtpropertybrowser.cpp +++ b/tools/shared/qtpropertybrowser/qtpropertybrowser.cpp @@ -48,9 +48,7 @@ # pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */ #endif -#if QT_VERSION >= 0x040400 QT_BEGIN_NAMESPACE -#endif class QtPropertyPrivate { @@ -1958,8 +1956,6 @@ void QtAbstractPropertyBrowser::setCurrentItem(QtBrowserItem *item) emit currentItemChanged(item); } -#if QT_VERSION >= 0x040400 QT_END_NAMESPACE -#endif #include "moc_qtpropertybrowser.cpp" diff --git a/tools/shared/qtpropertybrowser/qtpropertybrowser.h b/tools/shared/qtpropertybrowser/qtpropertybrowser.h index 649a9e3..20ffb81 100644 --- a/tools/shared/qtpropertybrowser/qtpropertybrowser.h +++ b/tools/shared/qtpropertybrowser/qtpropertybrowser.h @@ -45,11 +45,7 @@ #include <QtGui/QWidget> #include <QtCore/QSet> -#if QT_VERSION >= 0x040400 QT_BEGIN_NAMESPACE -#endif - - class QtAbstractPropertyManager; class QtPropertyPrivate; @@ -308,8 +304,6 @@ private: }; -#if QT_VERSION >= 0x040400 QT_END_NAMESPACE -#endif #endif // QTPROPERTYBROWSER_H diff --git a/tools/shared/qtpropertybrowser/qtpropertybrowserutils.cpp b/tools/shared/qtpropertybrowser/qtpropertybrowserutils.cpp index d689e60..94b0285 100644 --- a/tools/shared/qtpropertybrowser/qtpropertybrowserutils.cpp +++ b/tools/shared/qtpropertybrowser/qtpropertybrowserutils.cpp @@ -48,9 +48,7 @@ #include <QtGui/QLineEdit> #include <QtGui/QMenu> -#if QT_VERSION >= 0x040400 QT_BEGIN_NAMESPACE -#endif QtCursorDatabase::QtCursorDatabase() { @@ -426,9 +424,4 @@ bool QtKeySequenceEdit::event(QEvent *e) return QWidget::event(e); } - - - -#if QT_VERSION >= 0x040400 QT_END_NAMESPACE -#endif diff --git a/tools/shared/qtpropertybrowser/qtpropertybrowserutils_p.h b/tools/shared/qtpropertybrowser/qtpropertybrowserutils_p.h index 2eab3c8..fe8c6d1 100644 --- a/tools/shared/qtpropertybrowser/qtpropertybrowserutils_p.h +++ b/tools/shared/qtpropertybrowser/qtpropertybrowserutils_p.h @@ -58,9 +58,7 @@ #include <QtGui/QWidget> #include <QtCore/QStringList> -#if QT_VERSION >= 0x040400 QT_BEGIN_NAMESPACE -#endif class QMouseEvent; class QCheckBox; @@ -154,8 +152,6 @@ private: QLineEdit *m_lineEdit; }; -#if QT_VERSION >= 0x040400 QT_END_NAMESPACE -#endif #endif diff --git a/tools/shared/qtpropertybrowser/qtpropertymanager.cpp b/tools/shared/qtpropertybrowser/qtpropertymanager.cpp index 8b84eb9..47b8c9b 100644 --- a/tools/shared/qtpropertybrowser/qtpropertymanager.cpp +++ b/tools/shared/qtpropertybrowser/qtpropertymanager.cpp @@ -61,9 +61,7 @@ # pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */ #endif -#if QT_VERSION >= 0x040400 QT_BEGIN_NAMESPACE -#endif template <class PrivateData, class Value> static void setSimpleMinimumData(PrivateData *data, const Value &minVal) @@ -421,23 +419,6 @@ private: QMetaEnum m_policyEnum; }; -#if QT_VERSION < 0x040300 - -static QList<QLocale::Country> countriesForLanguage(QLocale::Language language) -{ - QList<QLocale::Country> countries; - QLocale::Country country = QLocale::AnyCountry; - while (country <= QLocale::LastCountry) { - QLocale locale(language, country); - if (locale.language() == language && !countries.contains(locale.country())) - countries << locale.country(); - country = (QLocale::Country)((uint)country + 1); // ++country - } - return countries; -} - -#endif - static QList<QLocale::Country> sortCountries(const QList<QLocale::Country> &countries) { QMultiMap<QString, QLocale::Country> nameToCountry; @@ -469,11 +450,7 @@ void QtMetaEnumProvider::initLocale() while (itLang.hasNext()) { QLocale::Language language = itLang.next(); QList<QLocale::Country> countries; -#if QT_VERSION < 0x040300 - countries = countriesForLanguage(language); -#else countries = QLocale::countriesForLanguage(language); -#endif if (countries.isEmpty() && language == system.language()) countries << system.country(); @@ -5789,9 +5766,7 @@ QtFontPropertyManager::QtFontPropertyManager(QObject *parent) { d_ptr = new QtFontPropertyManagerPrivate; d_ptr->q_ptr = this; -#if QT_VERSION >= 0x040500 QObject::connect(qApp, SIGNAL(fontDatabaseChanged()), this, SLOT(slotFontDatabaseChanged())); -#endif d_ptr->m_intPropertyManager = new QtIntPropertyManager(this); connect(d_ptr->m_intPropertyManager, SIGNAL(valueChanged(QtProperty *, int)), @@ -6485,9 +6460,7 @@ void QtCursorPropertyManager::uninitializeProperty(QtProperty *property) d_ptr->m_values.remove(property); } -#if QT_VERSION >= 0x040400 QT_END_NAMESPACE -#endif #include "moc_qtpropertymanager.cpp" #include "qtpropertymanager.moc" diff --git a/tools/shared/qtpropertybrowser/qtpropertymanager.h b/tools/shared/qtpropertybrowser/qtpropertymanager.h index 90fe5c0..2fb69bf 100644 --- a/tools/shared/qtpropertybrowser/qtpropertymanager.h +++ b/tools/shared/qtpropertybrowser/qtpropertymanager.h @@ -44,9 +44,7 @@ #include "qtpropertybrowser.h" -#if QT_VERSION >= 0x040400 QT_BEGIN_NAMESPACE -#endif class QDate; class QTime; @@ -743,8 +741,6 @@ private: Q_DISABLE_COPY(QtCursorPropertyManager) }; -#if QT_VERSION >= 0x040400 QT_END_NAMESPACE -#endif #endif diff --git a/tools/shared/qtpropertybrowser/qttreepropertybrowser.cpp b/tools/shared/qtpropertybrowser/qttreepropertybrowser.cpp index 446be39..1ad3f6b 100644 --- a/tools/shared/qtpropertybrowser/qttreepropertybrowser.cpp +++ b/tools/shared/qtpropertybrowser/qttreepropertybrowser.cpp @@ -52,9 +52,7 @@ #include <QtGui/QStyle> #include <QtGui/QPalette> -#if QT_VERSION >= 0x040400 QT_BEGIN_NAMESPACE -#endif class QtPropertyEditorView; @@ -436,9 +434,7 @@ void QtTreePropertyBrowserPrivate::init(QWidget *parent) layout->setMargin(0); m_treeWidget = new QtPropertyEditorView(parent); m_treeWidget->setEditorPrivate(this); - const int indicatorWidth = m_treeWidget->style()->pixelMetric(QStyle::PM_IndicatorWidth, 0, m_treeWidget); - QSize iconSize(indicatorWidth, indicatorWidth); - m_treeWidget->setIconSize(QSize(indicatorWidth, indicatorWidth)); + m_treeWidget->setIconSize(QSize(18, 18)); layout->addWidget(m_treeWidget); m_treeWidget->setColumnCount(2); @@ -1042,9 +1038,7 @@ void QtTreePropertyBrowser::editItem(QtBrowserItem *item) d_ptr->editItem(item); } -#if QT_VERSION >= 0x040400 QT_END_NAMESPACE -#endif #include "moc_qttreepropertybrowser.cpp" #include "qttreepropertybrowser.moc" diff --git a/tools/shared/qtpropertybrowser/qttreepropertybrowser.h b/tools/shared/qtpropertybrowser/qttreepropertybrowser.h index 63bd7f6..813e050 100644 --- a/tools/shared/qtpropertybrowser/qttreepropertybrowser.h +++ b/tools/shared/qtpropertybrowser/qttreepropertybrowser.h @@ -44,9 +44,7 @@ #include "qtpropertybrowser.h" -#if QT_VERSION >= 0x040400 QT_BEGIN_NAMESPACE -#endif class QTreeWidgetItem; class QtTreePropertyBrowserPrivate; @@ -131,8 +129,6 @@ private: }; -#if QT_VERSION >= 0x040400 QT_END_NAMESPACE -#endif #endif diff --git a/tools/shared/qtpropertybrowser/qtvariantproperty.cpp b/tools/shared/qtpropertybrowser/qtvariantproperty.cpp index 7e1975e..f712ba6 100644 --- a/tools/shared/qtpropertybrowser/qtvariantproperty.cpp +++ b/tools/shared/qtpropertybrowser/qtvariantproperty.cpp @@ -51,9 +51,7 @@ # pragma warning(disable: 4786) /* MS VS 6: truncating debug info after 255 characters */ #endif -#if QT_VERSION >= 0x040400 QT_BEGIN_NAMESPACE -#endif class QtEnumPropertyType { @@ -69,17 +67,13 @@ class QtGroupPropertyType { }; -#if QT_VERSION >= 0x040400 QT_END_NAMESPACE -#endif Q_DECLARE_METATYPE(QtEnumPropertyType) Q_DECLARE_METATYPE(QtFlagPropertyType) Q_DECLARE_METATYPE(QtGroupPropertyType) -#if QT_VERSION >= 0x040400 QT_BEGIN_NAMESPACE -#endif /*! Returns the type id for an enum property. @@ -2275,8 +2269,6 @@ void QtVariantEditorFactory::disconnectPropertyManager(QtVariantPropertyManager d_ptr->m_checkBoxFactory->removePropertyManager(itFlag.next()->subBoolPropertyManager()); } -#if QT_VERSION >= 0x040400 QT_END_NAMESPACE -#endif #include "moc_qtvariantproperty.cpp" diff --git a/tools/shared/qtpropertybrowser/qtvariantproperty.h b/tools/shared/qtpropertybrowser/qtvariantproperty.h index 91397d8..9253809 100644 --- a/tools/shared/qtpropertybrowser/qtvariantproperty.h +++ b/tools/shared/qtpropertybrowser/qtvariantproperty.h @@ -46,9 +46,7 @@ #include <QtCore/QVariant> #include <QtGui/QIcon> -#if QT_VERSION >= 0x040400 QT_BEGIN_NAMESPACE -#endif typedef QMap<int, QIcon> QtIconMap; @@ -172,9 +170,7 @@ private: Q_DISABLE_COPY(QtVariantEditorFactory) }; -#if QT_VERSION >= 0x040400 QT_END_NAMESPACE -#endif Q_DECLARE_METATYPE(QIcon) Q_DECLARE_METATYPE(QtIconMap) |