diff options
author | Paul Olav Tvete <paul.tvete@nokia.com> | 2009-11-19 08:58:03 (GMT) |
---|---|---|
committer | Paul Olav Tvete <paul.tvete@nokia.com> | 2009-11-19 08:58:03 (GMT) |
commit | 879e2ea7d15510ec5f94d6d7a005b157b115f69f (patch) | |
tree | 73aedd0bffe7ab39387229a9417aa50cecbbf0aa /tools | |
parent | 8fc2eec5b3282665f76f1e0313a03608bf4e7bc1 (diff) | |
parent | 80cd617b05ad3e647c87dc063d40cde0617344ca (diff) | |
download | Qt-879e2ea7d15510ec5f94d6d7a005b157b115f69f.zip Qt-879e2ea7d15510ec5f94d6d7a005b157b115f69f.tar.gz Qt-879e2ea7d15510ec5f94d6d7a005b157b115f69f.tar.bz2 |
Merge remote branch 'origin/4.6' into lighthouse
Conflicts:
configure
src/plugins/graphicssystems/graphicssystems.pro
Diffstat (limited to 'tools')
83 files changed, 1491 insertions, 926 deletions
diff --git a/tools/assistant/lib/lib.pro b/tools/assistant/lib/lib.pro index 011dec2..51933de 100644 --- a/tools/assistant/lib/lib.pro +++ b/tools/assistant/lib/lib.pro @@ -40,7 +40,8 @@ SOURCES += qhelpenginecore.cpp \ qhelpsearchindex_default.cpp \ qhelpsearchindexwriter_default.cpp \ qhelpsearchindexreader_default.cpp \ - qhelpsearchindexreader.cpp + qhelpsearchindexreader.cpp \ + qhelp_global.cpp # access to clucene SOURCES += qhelpsearchindexwriter_clucene.cpp \ diff --git a/tools/assistant/lib/qhelp_global.cpp b/tools/assistant/lib/qhelp_global.cpp new file mode 100644 index 0000000..749d2c9 --- /dev/null +++ b/tools/assistant/lib/qhelp_global.cpp @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the Qt Assistant 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 Technology Preview License Agreement accompanying +** this package. +** +** 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.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QRegExp> +#include <QtCore/QMutexLocker> +#include <QtGui/QTextDocument> + +#include "qhelp_global.h" + +QString QHelpGlobal::uniquifyConnectionName(const QString &name, void *pointer) +{ + static int counter = 0; + static QMutex mutex; + + QMutexLocker locker(&mutex); + if (++counter > 1000) + counter = 0; + + return QString::fromLatin1("%1-%2-%3"). + arg(name).arg(long(pointer)).arg(counter); +} + +QString QHelpGlobal::documentTitle(const QString &content) +{ + QString title = QObject::tr("Untitled"); + if (!content.isEmpty()) { + int start = content.indexOf(QLatin1String("<title>"), 0, Qt::CaseInsensitive) + 7; + int end = content.indexOf(QLatin1String("</title>"), 0, Qt::CaseInsensitive); + if ((end - start) > 0) { + title = content.mid(start, end - start); + if (Qt::mightBeRichText(title) || title.contains(QLatin1Char('&'))) { + QTextDocument doc; + doc.setHtml(title); + title = doc.toPlainText(); + } + } + } + return title; +} + +QString QHelpGlobal::codecFromData(const QByteArray &data) +{ + QString codec = codecFromXmlData(data); + if (codec.isEmpty()) + codec = codecFromHtmlData(data); + return codec.isEmpty() ? QLatin1String("utf-8") : codec; +} + +QString QHelpGlobal::codecFromHtmlData(const QByteArray &data) +{ + QString content = QString::fromUtf8(data.constData(), data.size()); + int start = content.indexOf(QLatin1String("<meta"), 0, Qt::CaseInsensitive); + if (start > 0) { + int end; + QRegExp r(QLatin1String("charset=([^\"\\s]+)")); + while (start != -1) { + end = content.indexOf(QLatin1Char('>'), start) + 1; + const QString &meta = content.mid(start, end - start).toLower(); + if (r.indexIn(meta) != -1) + return r.cap(1); + start = content.indexOf(QLatin1String("<meta"), end, + Qt::CaseInsensitive); + } + } + return QString(); +} + +QString QHelpGlobal::codecFromXmlData(const QByteArray &data) +{ + QString content = QString::fromUtf8(data.constData(), data.size()); + const QRegExp encodingExp(QLatin1String("^\\s*<\\?xml version=" + "\"\\d\\.\\d\" encoding=\"([^\"]+)\"\\?>.*")); + return encodingExp.exactMatch(content) ? encodingExp.cap(1) : QString(); +} diff --git a/tools/assistant/lib/qhelp_global.h b/tools/assistant/lib/qhelp_global.h index 723d867..4e31d67 100644 --- a/tools/assistant/lib/qhelp_global.h +++ b/tools/assistant/lib/qhelp_global.h @@ -45,9 +45,6 @@ #include <QtCore/qglobal.h> #include <QtCore/QString> #include <QtCore/QObject> -#include <QtCore/QRegExp> -#include <QtCore/QMutexLocker> -#include <QtGui/QTextDocument> QT_BEGIN_HEADER @@ -65,56 +62,13 @@ QT_MODULE(Help) class QHelpGlobal { public: - static QString uniquifyConnectionName(const QString &name, void *pointer) - { - static int counter = 0; - static QMutex mutex; + static QString uniquifyConnectionName(const QString &name, void *pointer); + static QString documentTitle(const QString &content); + static QString codecFromData(const QByteArray &data); - QMutexLocker locker(&mutex); - if (++counter > 1000) - counter = 0; - - return QString::fromLatin1("%1-%2-%3") - .arg(name).arg(long(pointer)).arg(counter); - }; - - static QString documentTitle(const QString &content) - { - QString title = QObject::tr("Untitled"); - if (!content.isEmpty()) { - int start = content.indexOf(QLatin1String("<title>"), 0, Qt::CaseInsensitive) + 7; - int end = content.indexOf(QLatin1String("</title>"), 0, Qt::CaseInsensitive); - if ((end - start) > 0) { - title = content.mid(start, end - start); - if (Qt::mightBeRichText(title) || title.contains(QLatin1Char('&'))) { - QTextDocument doc; - doc.setHtml(title); - title = doc.toPlainText(); - } - } - } - return title; - }; - - static QString charsetFromData(const QByteArray &data) - { - QString content = QString::fromUtf8(data.constData(), data.size()); - int start = - content.indexOf(QLatin1String("<meta"), 0, Qt::CaseInsensitive); - if (start > 0) { - int end; - QRegExp r(QLatin1String("charset=([^\"\\s]+)")); - while (start != -1) { - end = content.indexOf(QLatin1Char('>'), start) + 1; - const QString &meta = content.mid(start, end - start).toLower(); - if (r.indexIn(meta) != -1) - return r.cap(1); - start = content.indexOf(QLatin1String("<meta"), end, - Qt::CaseInsensitive); - } - } - return QLatin1String("utf-8"); - } +private: + static QString codecFromHtmlData(const QByteArray &data); + static QString codecFromXmlData(const QByteArray &data); }; QT_END_NAMESPACE diff --git a/tools/assistant/lib/qhelpcollectionhandler.cpp b/tools/assistant/lib/qhelpcollectionhandler.cpp index f59b227..4aa7ab6 100644 --- a/tools/assistant/lib/qhelpcollectionhandler.cpp +++ b/tools/assistant/lib/qhelpcollectionhandler.cpp @@ -76,7 +76,8 @@ bool QHelpCollectionHandler::isDBOpened() { if (m_dbOpened) return true; - emit error(tr("The collection file is not set up yet!")); + emit error(tr("The collection file '%1' is not set up yet!"). + arg(m_collectionFile)); return false; } @@ -134,7 +135,8 @@ bool QHelpCollectionHandler::copyCollectionFile(const QString &fileName) QFileInfo fi(fileName); if (fi.exists()) { - emit error(tr("The specified collection file already exists!")); + emit error(tr("The collection file '%1' already exists!"). + arg(fileName)); return false; } @@ -281,7 +283,7 @@ bool QHelpCollectionHandler::removeCustomFilter(const QString &filterName) filterNameId = m_query.value(0).toInt(); if (filterNameId < 0) { - emit error(tr("Unknown filter!")); + emit error(tr("Unknown filter '%1'!").arg(filterName)); return false; } @@ -386,7 +388,7 @@ bool QHelpCollectionHandler::registerDocumentation(const QString &fileName) QString ns = reader.namespaceName(); if (ns.isEmpty()) { - emit error(tr("Invalid documentation file!")); + emit error(tr("Invalid documentation file '%1'!").arg(fileName)); return false; } @@ -553,7 +555,7 @@ int QHelpCollectionHandler::registerNamespace(const QString &nspace, const QStri if (m_query.exec()) namespaceId = m_query.lastInsertId().toInt(); if (namespaceId < 1) { - emit error(tr("Cannot register namespace!")); + emit error(tr("Cannot register namespace '%1'!").arg(nspace)); return -1; } return namespaceId; @@ -577,7 +579,7 @@ void QHelpCollectionHandler::optimizeDatabase(const QString &fileName) db.setDatabaseName(fileName); if (!db.open()) { QSqlDatabase::removeDatabase(QLatin1String("optimize")); - emit error(tr("Cannot open database to optimize!")); + emit error(tr("Cannot open database '%1' to optimize!").arg(fileName)); return; } diff --git a/tools/assistant/lib/qhelpenginecore.cpp b/tools/assistant/lib/qhelpenginecore.cpp index 8c6c2fe..140e99a 100644 --- a/tools/assistant/lib/qhelpenginecore.cpp +++ b/tools/assistant/lib/qhelpenginecore.cpp @@ -177,12 +177,11 @@ void QHelpEngineCorePrivate::errorReceived(const QString &msg) instead. When creating a custom help viewer the viewer can be -configured by writing a custom collection file which could contain various -keywords to be used to configure the help engine. These keywords and values -and their meaning can be found in the help information for -\l{assistant-custom-help-viewer.html#creating-a-custom-help-collection-file -}{creating a custom help collection file} for -Assistant. + configured by writing a custom collection file which could contain various + keywords to be used to configure the help engine. These keywords and values + and their meaning can be found in the help information for + \l{assistant-custom-help-viewer.html#creating-a-custom-help-collection-file} + {creating a custom help collection file} for Assistant. */ /*! diff --git a/tools/assistant/lib/qhelpgenerator.cpp b/tools/assistant/lib/qhelpgenerator.cpp index 0294b30..48d73aa 100644 --- a/tools/assistant/lib/qhelpgenerator.cpp +++ b/tools/assistant/lib/qhelpgenerator.cpp @@ -528,7 +528,7 @@ bool QHelpGenerator::insertFiles(const QStringList &files, const QString &rootPa QByteArray data = fi.readAll(); if (fileName.endsWith(QLatin1String(".html")) || fileName.endsWith(QLatin1String(".htm"))) { - charSet = QHelpGlobal::charsetFromData(data); + charSet = QHelpGlobal::codecFromData(data); QTextStream stream(&data); stream.setCodec(QTextCodec::codecForName(charSet.toLatin1().constData())); title = QHelpGlobal::documentTitle(stream.readAll()); diff --git a/tools/assistant/lib/qhelpsearchengine.cpp b/tools/assistant/lib/qhelpsearchengine.cpp index cb18142..893495d 100644 --- a/tools/assistant/lib/qhelpsearchengine.cpp +++ b/tools/assistant/lib/qhelpsearchengine.cpp @@ -95,12 +95,11 @@ private: delete indexWriter; } - - int hitsCount() const + int hitCount() const { int count = 0; if (indexReader) - count = indexReader->hitsCount(); + count = indexReader->hitCount(); return count; } @@ -366,11 +365,22 @@ QHelpSearchResultWidget* QHelpSearchEngine::resultWidget() } /*! + \obsolete Returns the amount of hits the search engine found. + \sa hitCount() */ int QHelpSearchEngine::hitsCount() const { - return d->hitsCount(); + return d->hitCount(); +} + +/*! + \since 4.6 + Returns the amount of hits the search engine found. +*/ +int QHelpSearchEngine::hitCount() const +{ + return d->hitCount(); } /*! diff --git a/tools/assistant/lib/qhelpsearchengine.h b/tools/assistant/lib/qhelpsearchengine.h index 1d53411..21f04c5 100644 --- a/tools/assistant/lib/qhelpsearchengine.h +++ b/tools/assistant/lib/qhelpsearchengine.h @@ -86,7 +86,8 @@ public: QHelpSearchQueryWidget* queryWidget(); QHelpSearchResultWidget* resultWidget(); - int hitsCount() const; + QT_DEPRECATED int hitsCount() const; + int hitCount() const; typedef QPair<QString, QString> SearchHit; QList<SearchHit> hits(int start, int end) const; diff --git a/tools/assistant/lib/qhelpsearchindexreader.cpp b/tools/assistant/lib/qhelpsearchindexreader.cpp index 20d181b..b134605 100644 --- a/tools/assistant/lib/qhelpsearchindexreader.cpp +++ b/tools/assistant/lib/qhelpsearchindexreader.cpp @@ -83,7 +83,7 @@ void QHelpSearchIndexReader::search(const QString &collectionFile, const QString start(QThread::NormalPriority); } -int QHelpSearchIndexReader::hitsCount() const +int QHelpSearchIndexReader::hitCount() const { QMutexLocker lock(&mutex); return hitList.count(); diff --git a/tools/assistant/lib/qhelpsearchindexreader_p.h b/tools/assistant/lib/qhelpsearchindexreader_p.h index 31c392f..adbcdc2 100644 --- a/tools/assistant/lib/qhelpsearchindexreader_p.h +++ b/tools/assistant/lib/qhelpsearchindexreader_p.h @@ -81,7 +81,7 @@ public: void search(const QString &collectionFile, const QString &indexFilesFolder, const QList<QHelpSearchQuery> &queryList); - int hitsCount() const; + int hitCount() const; QList<QHelpSearchEngine::SearchHit> hits(int start, int end) const; signals: diff --git a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp index 284cbd3..ab32537 100644 --- a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp +++ b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp @@ -430,8 +430,8 @@ private: QString readData(const QByteArray &data) { QTextStream textStream(data); - QByteArray charSet = QHelpGlobal::charsetFromData(data).toLatin1(); - textStream.setCodec(QTextCodec::codecForName(charSet.constData())); + const QByteArray &codec = QHelpGlobal::codecFromData(data).toLatin1(); + textStream.setCodec(QTextCodec::codecForName(codec.constData())); QString stream = textStream.readAll(); if (stream.isNull() || stream.isEmpty()) diff --git a/tools/assistant/lib/qhelpsearchindexwriter_default.cpp b/tools/assistant/lib/qhelpsearchindexwriter_default.cpp index 36b115e..06deb85 100644 --- a/tools/assistant/lib/qhelpsearchindexwriter_default.cpp +++ b/tools/assistant/lib/qhelpsearchindexwriter_default.cpp @@ -274,7 +274,7 @@ void QHelpSearchIndexWriter::run() continue; QTextStream s(data); - QString en = QHelpGlobal::charsetFromData(data); + QString en = QHelpGlobal::codecFromData(data); s.setCodec(QTextCodec::codecForName(en.toLatin1().constData())); QString text = s.readAll(); diff --git a/tools/assistant/lib/qhelpsearchquerywidget.cpp b/tools/assistant/lib/qhelpsearchquerywidget.cpp index 361e9ac..f2f40ec 100644 --- a/tools/assistant/lib/qhelpsearchquerywidget.cpp +++ b/tools/assistant/lib/qhelpsearchquerywidget.cpp @@ -289,7 +289,7 @@ private slots: { QList<QHelpSearchQuery> queryList; #if !defined(QT_CLUCENE_SUPPORT) - queryList.append(QHelSearchQuery(QHelpSearchQuery::DEFAULT, + queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT, QStringList(defaultQuery->text()))); #else diff --git a/tools/assistant/lib/qhelpsearchresultwidget.cpp b/tools/assistant/lib/qhelpsearchresultwidget.cpp index a2f0021..c0d17dd 100644 --- a/tools/assistant/lib/qhelpsearchresultwidget.cpp +++ b/tools/assistant/lib/qhelpsearchresultwidget.cpp @@ -169,13 +169,13 @@ private slots: void showNextResultPage() { if (!searchEngine.isNull() - && resultLastToShow < searchEngine->hitsCount()) { + && resultLastToShow < searchEngine->hitCount()) { resultLastToShow += 20; resultFirstToShow += 20; resultTextBrowser->showResultPage(searchEngine->hits(resultFirstToShow, resultLastToShow), isIndexing); - if (resultLastToShow >= searchEngine->hitsCount()) + if (resultLastToShow >= searchEngine->hitCount()) updateNextButtonState(false); } updateHitRange(); @@ -184,7 +184,7 @@ private slots: void showLastResultPage() { if (!searchEngine.isNull()) { - resultLastToShow = searchEngine->hitsCount(); + resultLastToShow = searchEngine->hitCount(); resultFirstToShow = resultLastToShow - (resultLastToShow % 20); if (resultFirstToShow == resultLastToShow) @@ -214,7 +214,7 @@ private slots: { if (!searchEngine.isNull()) { int count = resultLastToShow % 20; - if (count == 0 || resultLastToShow != searchEngine->hitsCount()) + if (count == 0 || resultLastToShow != searchEngine->hitCount()) count = 20; resultLastToShow -= count; @@ -298,7 +298,7 @@ private: int count = 0; if (!searchEngine.isNull()) { - count = searchEngine->hitsCount(); + count = searchEngine->hitCount(); if (count > 0) { first = resultFirstToShow +1; last = resultLastToShow > count ? count : resultLastToShow; diff --git a/tools/assistant/tools/assistant/assistant.pro b/tools/assistant/tools/assistant/assistant.pro index 1cbd1d3..1a7e874 100644 --- a/tools/assistant/tools/assistant/assistant.pro +++ b/tools/assistant/tools/assistant/assistant.pro @@ -4,8 +4,6 @@ TEMPLATE = app LANGUAGE = C++ TARGET = assistant -DEFINES += QT_CLUCENE_SUPPORT - contains(QT_CONFIG, webkit) { QT += webkit } diff --git a/tools/assistant/tools/assistant/assistant.qch b/tools/assistant/tools/assistant/assistant.qch Binary files differindex 3e66bd9..78fe9f3 100644 --- a/tools/assistant/tools/assistant/assistant.qch +++ b/tools/assistant/tools/assistant/assistant.qch diff --git a/tools/assistant/tools/assistant/bookmarkmanager.cpp b/tools/assistant/tools/assistant/bookmarkmanager.cpp index 9cccd82..511a56e 100644 --- a/tools/assistant/tools/assistant/bookmarkmanager.cpp +++ b/tools/assistant/tools/assistant/bookmarkmanager.cpp @@ -621,6 +621,7 @@ Qt::ItemFlags BookmarkModel::flags(const QModelIndex &index) const BookmarkManager::BookmarkManager(QHelpEngineCore *_helpEngine) : treeModel(new BookmarkModel(0, 1, this)) , listModel(new BookmarkModel(0, 1, this)) + , renameItem(0) , helpEngine(_helpEngine) { folderIcon = QApplication::style()->standardIcon(QStyle::SP_DirClosedIcon); diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp index 04739d4..67d803d 100644 --- a/tools/assistant/tools/assistant/centralwidget.cpp +++ b/tools/assistant/tools/assistant/centralwidget.cpp @@ -222,14 +222,15 @@ CentralWidget::CentralWidget(QHelpEngine *engine, MainWindow *parent) QVBoxLayout *vboxLayout = new QVBoxLayout(this); QString resourcePath = QLatin1String(":/trolltech/assistant/images/"); -#ifndef Q_OS_MAC vboxLayout->setMargin(0); +#ifndef Q_OS_MAC resourcePath.append(QLatin1String("win")); #else resourcePath.append(QLatin1String("mac")); #endif tabWidget = new QTabWidget(this); + tabWidget->setDocumentMode(true); connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(currentPageChanged(int))); @@ -665,34 +666,16 @@ void CentralWidget::setSourceInNewTab(const QUrl &url, qreal zoom) tabWidget->setCurrentIndex(tabWidget->addTab(viewer, quoteTabTitle(viewer->documentTitle()))); - QFont font = qApp->font(); - bool userFont = helpEngine->customValue(QLatin1String("useBrowserFont")).toBool(); - if (userFont) { - font = qVariantValue<QFont>(helpEngine->customValue( - QLatin1String("browserFont"))); - } - -#if !defined(QT_NO_WEBKIT) - QWebSettings *settings = QWebSettings::globalSettings(); - if (!userFont) { - int fontSize = settings->fontSize(QWebSettings::DefaultFontSize); - QString fontFamily = settings->fontFamily(QWebSettings::StandardFont); - font = QFont(fontFamily, fontSize); - } + QFont font; + getBrowserFontFor(viewer, &font); - QWebView *view = qobject_cast<QWebView*> (viewer); - if (view) { - settings = view->settings(); - settings->setFontFamily(QWebSettings::StandardFont, font.family()); - settings->setFontSize(QWebSettings::DefaultFontSize, font.pointSize()); - } else if (viewer) { - viewer->setFont(font); - } - viewer->setTextSizeMultiplier(zoom == 0.0 ? 1.0 : zoom); -#else +#if defined(QT_NO_WEBKIT) font.setPointSize((int)(font.pointSize() + zoom)); - viewer->setFont(font); + setBrowserFontFor(viewer, font); viewer->setZoom((int)zoom); +#else + setBrowserFontFor(viewer, font); + viewer->setTextSizeMultiplier(zoom == 0.0 ? 1.0 : zoom); #endif connectSignals(); @@ -1010,41 +993,17 @@ bool CentralWidget::findInTextBrowser(QTextBrowser* browser, const QString &ttf, void CentralWidget::updateBrowserFont() { - QFont font = qApp->font(); - bool userFont = helpEngine->customValue(QLatin1String("useBrowserFont")).toBool(); - if (userFont) { - font = qVariantValue<QFont>(helpEngine->customValue( - QLatin1String("browserFont"))); - } - -#if !defined(QT_NO_WEBKIT) - QWebSettings *settings = QWebSettings::globalSettings(); - if (!userFont) { - int fontSize = settings->fontSize(QWebSettings::DefaultFontSize); - QString fontFamily = settings->fontFamily(QWebSettings::StandardFont); - font = QFont(fontFamily, fontSize); + QFont font; + bool searchAttached = searchWidgetAttached(); + if (searchAttached) { + getBrowserFontFor(m_searchWidget, &font); + setBrowserFontFor(m_searchWidget, font); } -#endif - QWidget *widget = 0; - for (int i = 0; i < tabWidget->count(); ++i) { - widget = tabWidget->widget(i); -#if !defined(QT_NO_WEBKIT) - QWebView *view = qobject_cast<QWebView*> (widget); - if (view) { - settings = view->settings(); - settings->setFontFamily(QWebSettings::StandardFont, font.family()); - settings->setFontSize(QWebSettings::DefaultFontSize, font.pointSize()); - } else if (widget) { - if (!userFont) - font = qApp->font(); - widget->setFont(font); - } -#else - if (widget && widget->font() != font) - widget->setFont(font); -#endif - } + int i = searchAttached ? 1 : 0; + getBrowserFontFor(tabWidget->widget(i), &font); + for (i; i < tabWidget->count(); ++i) + setBrowserFontFor(tabWidget->widget(i), font); } void CentralWidget::createSearchWidget(QHelpSearchEngine *searchEngine) @@ -1057,6 +1016,10 @@ void CentralWidget::createSearchWidget(QHelpSearchEngine *searchEngine) SLOT(setSourceFromSearch(QUrl))); connect(m_searchWidget, SIGNAL(requestShowLinkInNewTab(QUrl)), this, SLOT(setSourceFromSearchInNewTab(QUrl))); + + QFont font; + getBrowserFontFor(m_searchWidget, &font); + setBrowserFontFor(m_searchWidget, font); } void CentralWidget::activateSearchWidget(bool updateLastTabPage) @@ -1078,7 +1041,7 @@ void CentralWidget::activateSearchWidget(bool updateLastTabPage) void CentralWidget::removeSearchWidget() { - if (m_searchWidget && m_searchWidget->isAttached()) { + if (searchWidgetAttached()) { tabWidget->removeTab(0); m_searchWidget->setAttached(false); } @@ -1087,7 +1050,7 @@ void CentralWidget::removeSearchWidget() int CentralWidget::availableHelpViewer() const { int count = tabWidget->count(); - if (m_searchWidget && m_searchWidget->isAttached()) + if (searchWidgetAttached()) count--; return count; } @@ -1095,7 +1058,7 @@ int CentralWidget::availableHelpViewer() const bool CentralWidget::enableTabCloseAction() const { int minTabCount = 1; - if (m_searchWidget && m_searchWidget->isAttached()) + if (searchWidgetAttached()) minTabCount = 2; return (tabWidget->count() > minTabCount); @@ -1198,4 +1161,40 @@ QMap<int, QString> CentralWidget::currentSourceFileList() const return sourceList; } +void CentralWidget::getBrowserFontFor(QWidget *viewer, QFont *font) +{ + const QLatin1String key("useBrowserFont"); + if (!helpEngine->customValue(key, false).toBool()) { + *font = qApp->font(); // case for QTextBrowser and SearchWidget +#if !defined(QT_NO_WEBKIT) + QWebView *view = qobject_cast<QWebView*> (viewer); + if (view) { + QWebSettings *settings = QWebSettings::globalSettings(); + *font = QFont(settings->fontFamily(QWebSettings::StandardFont), + settings->fontSize(QWebSettings::DefaultFontSize)); + } +#endif + } else { + *font = qVariantValue<QFont>(helpEngine->customValue( + QLatin1String("browserFont"))); + } +} + +void CentralWidget::setBrowserFontFor(QWidget *widget, const QFont &font) +{ +#if !defined(QT_NO_WEBKIT) + QWebView *view = qobject_cast<QWebView*> (widget); + if (view) { + QWebSettings *settings = view->settings(); + settings->setFontFamily(QWebSettings::StandardFont, font.family()); + settings->setFontSize(QWebSettings::DefaultFontSize, font.pointSize()); + } else if (widget && widget->font() != font) { + widget->setFont(font); + } +#else + if (widget && widget->font() != font) + widget->setFont(font); +#endif +} + QT_END_NAMESPACE diff --git a/tools/assistant/tools/assistant/centralwidget.h b/tools/assistant/tools/assistant/centralwidget.h index 7ae8ee5..8c186f0 100644 --- a/tools/assistant/tools/assistant/centralwidget.h +++ b/tools/assistant/tools/assistant/centralwidget.h @@ -48,6 +48,8 @@ #include <QtGui/QWidget> +#include "searchwidget.h" + QT_BEGIN_NAMESPACE class QEvent; @@ -65,7 +67,6 @@ class CentralWidget; class PrintHelper; class MainWindow; -class SearchWidget; class QHelpSearchEngine; class FindWidget : public QWidget @@ -123,6 +124,9 @@ public: HelpViewer *currentHelpViewer() const; void activateTab(bool onlyHelpViewer = false); + bool searchWidgetAttached() const { + return m_searchWidget && m_searchWidget->isAttached(); + } void createSearchWidget(QHelpSearchEngine *searchEngine); void activateSearchWidget(bool updateLastTabPage = false); void removeSearchWidget(); @@ -190,6 +194,9 @@ private: void highlightSearchTerms(); void setLastShownPages(); + void getBrowserFontFor(QWidget* viewer, QFont *font); + void setBrowserFontFor(QWidget *widget, const QFont &font); + private: int lastTabPage; QString collectionFile; diff --git a/tools/assistant/tools/assistant/helpviewer.cpp b/tools/assistant/tools/assistant/helpviewer.cpp index 53f3822..3547652 100644 --- a/tools/assistant/tools/assistant/helpviewer.cpp +++ b/tools/assistant/tools/assistant/helpviewer.cpp @@ -133,28 +133,25 @@ HelpNetworkAccessManager::HelpNetworkAccessManager(QHelpEngine *engine, { } -QNetworkReply *HelpNetworkAccessManager::createRequest(Operation op, - const QNetworkRequest &request, QIODevice *outgoingData) -{ - const QString& scheme = request.url().scheme(); - if (scheme == QLatin1String("qthelp") || scheme == QLatin1String("about")) { - const QUrl& url = request.url(); - QString mimeType = url.toString(); - if (mimeType.endsWith(QLatin1String(".svg")) - || mimeType.endsWith(QLatin1String(".svgz"))) { - mimeType = QLatin1String("image/svg+xml"); - } - else if (mimeType.endsWith(QLatin1String(".css"))) { - mimeType = QLatin1String("text/css"); - } - else if (mimeType.endsWith(QLatin1String(".js"))) { - mimeType = QLatin1String("text/javascript"); - } else { - mimeType = QLatin1String("text/html"); - } - return new HelpNetworkReply(request, helpEngine->fileData(url), mimeType); +QNetworkReply *HelpNetworkAccessManager::createRequest(Operation /*op*/, + const QNetworkRequest &request, QIODevice* /*outgoingData*/) +{ + const QUrl& url = request.url(); + QString mimeType = url.toString(); + if (mimeType.endsWith(QLatin1String(".svg")) + || mimeType.endsWith(QLatin1String(".svgz"))) { + mimeType = QLatin1String("image/svg+xml"); } - return QNetworkAccessManager::createRequest(op, request, outgoingData); + else if (mimeType.endsWith(QLatin1String(".css"))) { + mimeType = QLatin1String("text/css"); + } + else if (mimeType.endsWith(QLatin1String(".js"))) { + mimeType = QLatin1String("text/javascript"); + } else { + mimeType = QLatin1String("text/html"); + } + + return new HelpNetworkReply(request, helpEngine->fileData(url), mimeType); } class HelpPage : public QWebPage diff --git a/tools/assistant/tools/assistant/main.cpp b/tools/assistant/tools/assistant/main.cpp index 4d7fe10..9568df0 100644 --- a/tools/assistant/tools/assistant/main.cpp +++ b/tools/assistant/tools/assistant/main.cpp @@ -115,7 +115,7 @@ updateUserCollection(QHelpEngineCore& user, const QHelpEngineCore& caller) const uint userCollectionCreationTime = user. customValue(QLatin1String("CreationTime"), 1).toUInt(); - if (callerCollectionCreationTime == userCollectionCreationTime) + if (callerCollectionCreationTime <= userCollectionCreationTime) return false; user.setCustomValue(QLatin1String("CreationTime"), @@ -124,6 +124,12 @@ updateUserCollection(QHelpEngineCore& user, const QHelpEngineCore& caller) caller.customValue(QLatin1String("WindowTitle"))); user.setCustomValue(QLatin1String("LastShownPages"), caller.customValue(QLatin1String("LastShownPages"))); +#if !defined(QT_NO_WEBKIT) + const QLatin1String zoomKey("LastPagesZoomWebView"); +#else + const QLatin1String zoomKey("LastPagesZoomTextBrowser"); +#endif + user.setCustomValue(zoomKey, caller.customValue(zoomKey)); user.setCustomValue(QLatin1String("CurrentFilter"), caller.customValue(QLatin1String("CurrentFilter"))); user.setCustomValue(QLatin1String("CacheDirectory"), @@ -148,6 +154,8 @@ updateUserCollection(QHelpEngineCore& user, const QHelpEngineCore& caller) caller.customValue(QLatin1String("AboutTexts"))); user.setCustomValue(QLatin1String("AboutImages"), caller.customValue(QLatin1String("AboutImages"))); + user.setCustomValue(QLatin1String("defaultHomepage"), + caller.customValue(QLatin1String("defaultHomepage"))); return true; } @@ -181,6 +189,7 @@ QString indexFilesFolder(const QString &collectionFile) int main(int argc, char *argv[]) { +#ifndef Q_OS_WIN // First do a quick search for arguments that imply command-line mode. const char * cmdModeArgs[] = { "-help", "-register", "-unregister", "-remove-search-index" @@ -194,8 +203,10 @@ int main(int argc, char *argv[]) } } } - QApplication a(argc, argv, useGui); +#else + QApplication a(argc, argv); +#endif a.addLibraryPath(a.applicationDirPath() + QLatin1String("/plugins")); CmdLineParser cmd; diff --git a/tools/assistant/tools/assistant/mainwindow.cpp b/tools/assistant/tools/assistant/mainwindow.cpp index de3f695..01c4f75 100644 --- a/tools/assistant/tools/assistant/mainwindow.cpp +++ b/tools/assistant/tools/assistant/mainwindow.cpp @@ -227,16 +227,8 @@ MainWindow::MainWindow(CmdLineParser *cmdLine, QWidget *parent) if (!m_cmdLine->currentFilter().isEmpty()) { const QString &curFilter = m_cmdLine->currentFilter(); - m_helpEngine->setCurrentFilter(curFilter); - if (m_filterCombo) { - int idx = m_filterCombo->findText(curFilter); - if (idx >= 0) { - bool blocked = m_filterCombo->signalsBlocked(); - m_filterCombo->blockSignals(true); - m_filterCombo->setCurrentIndex(idx); - m_filterCombo->blockSignals(blocked); - } - } + if (m_helpEngine->customFilters().contains(curFilter)) + m_helpEngine->setCurrentFilter(curFilter); } if (usesDefaultCollection()) @@ -459,7 +451,7 @@ void MainWindow::setupActions() m_findAction = menu->addAction(tr("&Find in Text..."), m_centralWidget, SLOT(showTextSearch())); - m_findAction->setIconText("&Find"); + m_findAction->setIconText(tr("&Find")); m_findAction->setIcon(QIcon(resourcePath + QLatin1String("/find.png"))); m_findAction->setShortcuts(QKeySequence::Find); @@ -523,7 +515,7 @@ void MainWindow::setupActions() m_syncAction = menu->addAction(tr("Sync with Table of Contents"), this, SLOT(syncContents())); - m_syncAction->setIconText("Sync"); + m_syncAction->setIconText(tr("Sync")); m_syncAction->setIcon(QIcon(resourcePath + QLatin1String("/synctoc.png"))); menu->addSeparator(); @@ -664,6 +656,8 @@ void MainWindow::setupFilterToolbar() SLOT(setupFilterCombo())); connect(m_filterCombo, SIGNAL(activated(QString)), this, SLOT(filterDocumentation(QString))); + connect(m_helpEngine, SIGNAL(currentFilterChanged(QString)), this, + SLOT(currentFilterChanged(QString))); setupFilterCombo(); } @@ -1041,4 +1035,11 @@ QString MainWindow::defaultHelpCollectionFileName() arg(QLatin1String(QT_VERSION_STR)); } +void MainWindow::currentFilterChanged(const QString &filter) +{ + const int index = m_filterCombo->findText(filter); + Q_ASSERT(index != -1); + m_filterCombo->setCurrentIndex(index); +} + QT_END_NAMESPACE diff --git a/tools/assistant/tools/assistant/mainwindow.h b/tools/assistant/tools/assistant/mainwindow.h index 6b858e9..7559fe4 100644 --- a/tools/assistant/tools/assistant/mainwindow.h +++ b/tools/assistant/tools/assistant/mainwindow.h @@ -95,6 +95,7 @@ public slots: void showSearchWidget(); void syncContents(); void activateCurrentCentralWidgetTab(); + void currentFilterChanged(const QString &filter); private slots: void insertLastPages(); diff --git a/tools/assistant/tools/assistant/remotecontrol.cpp b/tools/assistant/tools/assistant/remotecontrol.cpp index be1c197..474a681 100644 --- a/tools/assistant/tools/assistant/remotecontrol.cpp +++ b/tools/assistant/tools/assistant/remotecontrol.cpp @@ -237,6 +237,8 @@ void RemoteControl::handleCommandString(const QString &cmdString) else m_mainWindow->expandTOC(depth); } else if (cmd == QLatin1String("setcurrentfilter")) { + if (!m_helpEngine->customFilters().contains(arg)) + return; if (m_caching) { clearCache(); m_currentFilter = arg; diff --git a/tools/assistant/tools/assistant/searchwidget.cpp b/tools/assistant/tools/assistant/searchwidget.cpp index 48fa8c6..3b456a3 100644 --- a/tools/assistant/tools/assistant/searchwidget.cpp +++ b/tools/assistant/tools/assistant/searchwidget.cpp @@ -85,7 +85,8 @@ SearchWidget::SearchWidget(QHelpSearchEngine *engine, QWidget *parent) SLOT(searchingFinished(int))); QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget); - browser->viewport()->installEventFilter(this); + if (browser) // Will be null if lib was configured not to use CLucene. + browser->viewport()->installEventFilter(this); } SearchWidget::~SearchWidget() diff --git a/tools/assistant/translations/qt_help.pro b/tools/assistant/translations/qt_help.pro index 0133ea4..db54ae6 100644 --- a/tools/assistant/translations/qt_help.pro +++ b/tools/assistant/translations/qt_help.pro @@ -47,4 +47,5 @@ TRANSLATIONS = \ $$TR_DIR/qt_help_pl.ts \ $$TR_DIR/qt_help_ru.ts \ $$TR_DIR/qt_help_zh_CN.ts \ - $$TR_DIR/qt_help_zh_TW.ts + $$TR_DIR/qt_help_zh_TW.ts \ + $$TR_DIR/qt_help_fr.ts diff --git a/tools/assistant/translations/translations.pro b/tools/assistant/translations/translations.pro index 6ff1fc9..95501ab 100644 --- a/tools/assistant/translations/translations.pro +++ b/tools/assistant/translations/translations.pro @@ -44,6 +44,7 @@ TR_DIR = $$PWD/../../../translations TRANSLATIONS = \ $$TR_DIR/assistant_da.ts \ $$TR_DIR/assistant_de.ts \ + $$TR_DIR/assistant_fr.ts \ $$TR_DIR/assistant_ja.ts \ $$TR_DIR/assistant_pl.ts \ $$TR_DIR/assistant_ru.ts \ diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index f57f3a8..cd3feec 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -249,6 +249,7 @@ Configure::Configure( int& argc, char** argv ) dictionary[ "MULTIMEDIA" ] = "yes"; dictionary[ "DIRECTSHOW" ] = "no"; dictionary[ "WEBKIT" ] = "auto"; + dictionary[ "DECLARATIVE" ] = "auto"; dictionary[ "PLUGIN_MANIFESTS" ] = "yes"; QString version; @@ -350,6 +351,7 @@ Configure::Configure( int& argc, char** argv ) dictionary[ "INCREDIBUILD_XGE" ] = "auto"; dictionary[ "LTCG" ] = "no"; + dictionary[ "NATIVE_GESTURES" ] = "yes"; } Configure::~Configure() @@ -795,6 +797,10 @@ void Configure::parseCmdLine() dictionary[ "INCREDIBUILD_XGE" ] = "no"; else if( configCmdLine.at(i) == "-incredibuild-xge" ) dictionary[ "INCREDIBUILD_XGE" ] = "yes"; + else if( configCmdLine.at(i) == "-native-gestures" ) + dictionary[ "NATIVE_GESTURES" ] = "yes"; + else if( configCmdLine.at(i) == "-no-native-gestures" ) + dictionary[ "NATIVE_GESTURES" ] = "no"; #if !defined(EVAL) // Others --------------------------------------------------- else if (configCmdLine.at(i) == "-fpu" ) @@ -905,6 +911,10 @@ void Configure::parseCmdLine() dictionary[ "WEBKIT" ] = "no"; } else if( configCmdLine.at(i) == "-webkit" ) { dictionary[ "WEBKIT" ] = "yes"; + } else if( configCmdLine.at(i) == "-no-declarative" ) { + dictionary[ "DECLARATIVE" ] = "no"; + } else if( configCmdLine.at(i) == "-declarative" ) { + dictionary[ "DECLARATIVE" ] = "yes"; } else if( configCmdLine.at(i) == "-no-plugin-manifests" ) { dictionary[ "PLUGIN_MANIFESTS" ] = "no"; } else if( configCmdLine.at(i) == "-plugin-manifests" ) { @@ -1412,7 +1422,6 @@ void Configure::applySpecSpecifics() dictionary[ "WEBKIT" ] = "no"; dictionary[ "PHONON" ] = "yes"; dictionary[ "DIRECTSHOW" ] = "no"; - dictionary[ "LTCG" ] = "yes"; // We only apply MMX/IWMMXT for mkspecs we know they work if (dictionary[ "XQMAKESPEC" ].startsWith("wincewm")) { dictionary[ "MMX" ] = "yes"; @@ -1448,10 +1457,10 @@ void Configure::applySpecSpecifics() dictionary[ "IWMMXT" ] = "no"; dictionary[ "CE_CRT" ] = "no"; dictionary[ "DIRECT3D" ] = "no"; - dictionary[ "WEBKIT" ] = "no"; + dictionary[ "WEBKIT" ] = "yes"; dictionary[ "ASSISTANT_WEBKIT" ] = "no"; dictionary[ "PHONON" ] = "yes"; - dictionary[ "XMLPATTERNS" ] = "no"; + dictionary[ "XMLPATTERNS" ] = "yes"; dictionary[ "QT_GLIB" ] = "no"; dictionary[ "S60" ] = "yes"; // iconv makes makes apps start and run ridiculously slowly in symbian emulator (HW not tested) @@ -1746,6 +1755,8 @@ bool Configure::displayHelp() desc("SCRIPT", "yes", "-script", "Build the QtScript module."); desc("SCRIPTTOOLS", "no", "-no-scripttools", "Do not build the QtScriptTools module."); desc("SCRIPTTOOLS", "yes", "-scripttools", "Build the QtScriptTools module."); + desc("DECLARATIVE", "no", "-no-declarative", "Do not build the declarative module"); + desc("DECLARATIVE", "yes", "-declarative", "Build the declarative module"); desc( "-arch <arch>", "Specify an architecture.\n" "Available values for <arch>:"); @@ -1768,6 +1779,8 @@ bool Configure::displayHelp() desc("STYLE_WINDOWSCE", "yes", "", " windowsce", ' '); desc("STYLE_WINDOWSMOBILE" , "yes", "", " windowsmobile", ' '); desc("STYLE_S60" , "yes", "", " s60\n", ' '); + desc("NATIVE_GESTURES", "no", "-no-native-gestures", "Do not use native gestures on Windows 7."); + desc("NATIVE_GESTURES", "yes", "-native-gestures", "Use native gestures on Windows 7."); /* We do not support -qconfig on Windows yet @@ -2032,6 +2045,8 @@ bool Configure::checkAvailability(const QString &part) available = true; } else if (part == "WEBKIT") { available = (dictionary.value("QMAKESPEC") == "win32-msvc2005") || (dictionary.value("QMAKESPEC") == "win32-msvc2008") || (dictionary.value("QMAKESPEC") == "win32-g++"); + } else if (part == "DECLARATIVE") { + available = QFile::exists(sourcePath + "/src/declarative/qml/qmlcomponent.h"); } return available; @@ -2118,6 +2133,8 @@ void Configure::autoDetection() dictionary["PHONON"] = checkAvailability("PHONON") ? "yes" : "no"; if (dictionary["WEBKIT"] == "auto") dictionary["WEBKIT"] = checkAvailability("WEBKIT") ? "yes" : "no"; + if (dictionary["DECLARATIVE"] == "auto") + dictionary["DECLARATIVE"] = checkAvailability("DECLARATIVE") ? "yes" : "no"; // Qt/WinCE remote test application if (dictionary["CETEST"] == "auto") @@ -2438,14 +2455,17 @@ void Configure::generateOutputVars() if ( dictionary["OPENGL_ES_CM"] == "yes" ) { qtConfig += "opengles1"; + qtConfig += "egl"; } if ( dictionary["OPENGL_ES_2"] == "yes" ) { qtConfig += "opengles2"; + qtConfig += "egl"; } if ( dictionary["OPENGL_ES_CL"] == "yes" ) { qtConfig += "opengles1cl"; + qtConfig += "egl"; } if ( dictionary["OPENVG"] == "yes" ) { @@ -2505,6 +2525,12 @@ void Configure::generateOutputVars() if (dictionary["WEBKIT"] == "yes") qtConfig += "webkit"; + if (dictionary["DECLARATIVE"] == "yes") + qtConfig += "declarative"; + + if( dictionary[ "NATIVE_GESTURES" ] == "yes" ) + qtConfig += "native-gestures"; + // We currently have no switch for QtSvg, so add it unconditionally. qtConfig += "svg"; @@ -2569,7 +2595,7 @@ void Configure::generateOutputVars() if (!opensslLibs.isEmpty()) qmakeVars += opensslLibs; else if (dictionary[ "OPENSSL" ] == "linked") { - if(dictionary[ "XQMAKESPEC" ].startsWith("symbian") ) + if(dictionary.contains("XQMAKESPEC") && dictionary[ "XQMAKESPEC" ].startsWith("symbian") ) qmakeVars += QString("OPENSSL_LIBS = -llibssl -llibcrypto"); else qmakeVars += QString("OPENSSL_LIBS = -lssleay32 -llibeay32"); @@ -2780,17 +2806,6 @@ QString Configure::addDefine(QString def) } #if !defined(EVAL) -// ### This should be removed once Qt for S60 is out. -static void applyTemporarySymbianFlags(QStringList &qconfigList) -{ - qconfigList += "QT_NO_CONCURRENT"; - qconfigList += "QT_NO_QFUTURE"; - // This is removed because it uses UNIX signals which are not implemented yet - qconfigList += "QT_NO_CRASHHANDLER"; - qconfigList += "QT_NO_PRINTER"; - qconfigList += "QT_NO_SYSTEMTRAYICON"; -} - void Configure::generateConfigfiles() { QDir(buildPath).mkpath("src/corelib/global"); @@ -2884,6 +2899,7 @@ void Configure::generateConfigfiles() if(dictionary["DBUS"] == "no") qconfigList += "QT_NO_DBUS"; if(dictionary["IPV6"] == "no") qconfigList += "QT_NO_IPV6"; if(dictionary["WEBKIT"] == "no") qconfigList += "QT_NO_WEBKIT"; + if(dictionary["DECLARATIVE"] == "no") qconfigList += "QT_NO_DECLARATIVE"; if(dictionary["PHONON"] == "no") qconfigList += "QT_NO_PHONON"; if(dictionary["MULTIMEDIA"] == "no") qconfigList += "QT_NO_MULTIMEDIA"; if(dictionary["XMLPATTERNS"] == "no") qconfigList += "QT_NO_XMLPATTERNS"; @@ -2891,6 +2907,7 @@ void Configure::generateConfigfiles() if(dictionary["SCRIPTTOOLS"] == "no") qconfigList += "QT_NO_SCRIPTTOOLS"; if(dictionary["FREETYPE"] == "no") qconfigList += "QT_NO_FREETYPE"; if(dictionary["S60"] == "no") qconfigList += "QT_NO_S60"; + if(dictionary["NATIVE_GESTURES"] == "no") qconfigList += "QT_NO_NATIVE_GESTURES"; if(dictionary["OPENGL_ES_CM"] == "yes" || dictionary["OPENGL_ES_CL"] == "yes" || @@ -2913,9 +2930,14 @@ void Configure::generateConfigfiles() if (dictionary["GRAPHICS_SYSTEM"] == "openvg") qconfigList += "QT_GRAPHICSSYSTEM_OPENVG"; if (dictionary["GRAPHICS_SYSTEM"] == "opengl") qconfigList += "QT_GRAPHICSSYSTEM_OPENGL"; if (dictionary["GRAPHICS_SYSTEM"] == "raster") qconfigList += "QT_GRAPHICSSYSTEM_RASTER"; - // ### This block should be removed once Qt for S60 is out. + if (dictionary.contains("XQMAKESPEC") && dictionary["XQMAKESPEC"].startsWith("symbian")) { - applyTemporarySymbianFlags(qconfigList); + // These features are not ported to Symbian (yet) + qconfigList += "QT_NO_CONCURRENT"; + qconfigList += "QT_NO_QFUTURE"; + qconfigList += "QT_NO_CRASHHANDLER"; + qconfigList += "QT_NO_PRINTER"; + qconfigList += "QT_NO_SYSTEMTRAYICON"; } qconfigList.sort(); @@ -3033,7 +3055,11 @@ void Configure::generateConfigfiles() tmpStream.setDevice(&tmpFile2); tmpStream << "/* Licensed */" << endl << "static const char qt_configure_licensee_str [512 + 12] = \"qt_lcnsuser=" << licenseInfo["LICENSEE"] << "\";" << endl - << "static const char qt_configure_licensed_products_str [512 + 12] = \"qt_lcnsprod=" << dictionary["EDITION"] << "\";" << endl; + << "static const char qt_configure_licensed_products_str [512 + 12] = \"qt_lcnsprod=" << dictionary["EDITION"] << "\";" << endl + << endl + << "/* Build date */" << endl + << "static const char qt_configure_installation [11 + 12] = \"qt_instdate=" << QDate::currentDate().toString(Qt::ISODate) << "\";" << endl + << endl; if(!dictionary[ "QT_HOST_PREFIX" ].isNull()) tmpStream << "#if !defined(QT_BOOTSTRAPPED) && !defined(QT_BUILD_QMAKE)" << endl; tmpStream << "static const char qt_configure_prefix_path_str [512 + 12] = \"qt_prfxpath=" << QString(dictionary["QT_INSTALL_PREFIX"]).replace( "\\", "\\\\" ) << "\";" << endl @@ -3087,6 +3113,24 @@ void Configure::generateConfigfiles() tmpFile2.copy(outName); tmpFile2.close(); } + + QTemporaryFile tmpFile3; + if (tmpFile3.open()) { + tmpStream.setDevice(&tmpFile3); + tmpStream << "/* Evaluation license key */" << endl + << "static const char qt_eval_key_data [512 + 12] = \"qt_qevalkey=" << licenseInfo["LICENSEKEYEXT"] << "\";" << endl; + + tmpStream.flush(); + tmpFile3.flush(); + + outName = buildPath + "/src/corelib/global/qconfig_eval.cpp"; + ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL ); + QFile::remove( outName ); + + if (dictionary["EDITION"] == "Evaluation" || qmakeDefines.contains("QT_EVAL")) + tmpFile3.copy(outName); + tmpFile3.close(); + } } #endif @@ -3155,6 +3199,7 @@ void Configure::displayConfig() cout << "Phonon support.............." << dictionary[ "PHONON" ] << endl; cout << "QtMultimedia support........" << dictionary[ "MULTIMEDIA" ] << endl; cout << "WebKit support.............." << dictionary[ "WEBKIT" ] << endl; + cout << "Declarative support........." << dictionary[ "DECLARATIVE" ] << endl; cout << "QtScript support............" << dictionary[ "SCRIPT" ] << endl; cout << "QtScriptTools support......." << dictionary[ "SCRIPTTOOLS" ] << endl; cout << "Graphics System............." << dictionary[ "GRAPHICS_SYSTEM" ] << endl; @@ -3357,10 +3402,8 @@ void Configure::buildHostTools() QString pwd = QDir::currentPath(); QStringList hostToolsDirs; hostToolsDirs - << "src/tools/bootstrap" - << "src/tools/moc" - << "src/tools/rcc" - << "src/tools/uic"; + << "src/tools" + << "tools/linguist/lrelease"; if(dictionary["XQMAKESPEC"].startsWith("wince")) hostToolsDirs << "tools/checksdk"; diff --git a/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp b/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp index 7ab7cb4..e36e828 100644 --- a/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp +++ b/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp @@ -73,6 +73,7 @@ #include <QtGui/QVBoxLayout> #include <QtGui/QToolButton> #include <QtGui/QButtonGroup> +#include <QtGui/QToolBar> QT_BEGIN_NAMESPACE @@ -724,20 +725,20 @@ SignalSlotEditorWindow::SignalSlotEditorWindow(QDesignerFormEditorInterface *cor QVBoxLayout *layout = new QVBoxLayout(this); layout->setMargin(0); - layout->addWidget(m_view); + layout->setSpacing(0); - QHBoxLayout *layout2 = new QHBoxLayout; - layout2->setMargin(3); - layout->addLayout(layout2); - layout2->addStretch(); + QToolBar *toolBar = new QToolBar; + toolBar->setIconSize(QSize(22, 22)); + m_add_button->setIcon(createIconSet(QLatin1String("plus.png"))); + connect(m_add_button, SIGNAL(clicked()), this, SLOT(addConnection())); + toolBar->addWidget(m_add_button); m_remove_button->setIcon(createIconSet(QLatin1String("minus.png"))); connect(m_remove_button, SIGNAL(clicked()), this, SLOT(removeConnection())); - layout2->addWidget(m_remove_button); + toolBar->addWidget(m_remove_button); - m_add_button->setIcon(createIconSet(QLatin1String("plus.png"))); - connect(m_add_button, SIGNAL(clicked()), this, SLOT(addConnection())); - layout2->addWidget(m_add_button); + layout->addWidget(toolBar); + layout->addWidget(m_view); connect(core->formWindowManager(), SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)), diff --git a/tools/designer/src/designer/qdesigner_formwindow.cpp b/tools/designer/src/designer/qdesigner_formwindow.cpp index b2af257..05937cd 100644 --- a/tools/designer/src/designer/qdesigner_formwindow.cpp +++ b/tools/designer/src/designer/qdesigner_formwindow.cpp @@ -182,7 +182,7 @@ int QDesignerFormWindow::getNumberOfUntitledWindows() const if (rx.indexIn(title) != -1) { if (maxUntitled == 0) ++maxUntitled; - if (rx.numCaptures() > 1) { + if (rx.captureCount() > 1) { const QString numberCapture = rx.cap(2); if (!numberCapture.isEmpty()) maxUntitled = qMax(numberCapture.toInt(), maxUntitled); diff --git a/tools/designer/src/lib/shared/qdesigner_tabwidget.cpp b/tools/designer/src/lib/shared/qdesigner_tabwidget.cpp index 2789bd3..f4f3d24 100644 --- a/tools/designer/src/lib/shared/qdesigner_tabwidget.cpp +++ b/tools/designer/src/lib/shared/qdesigner_tabwidget.cpp @@ -399,6 +399,7 @@ static const char *currentTabNameKey = "currentTabName"; static const char *currentTabIconKey = "currentTabIcon"; static const char *currentTabToolTipKey = "currentTabToolTip"; static const char *currentTabWhatsThisKey = "currentTabWhatsThis"; +static const char *tabMovableKey = "movable"; QTabWidgetPropertySheet::QTabWidgetPropertySheet(QTabWidget *object, QObject *parent) : QDesignerPropertySheet(object, parent), @@ -411,6 +412,8 @@ QTabWidgetPropertySheet::QTabWidgetPropertySheet(QTabWidget *object, QObject *pa formWindowBase()->addReloadableProperty(this, indexOf(QLatin1String(currentTabIconKey))); createFakeProperty(QLatin1String(currentTabToolTipKey), qVariantFromValue(qdesigner_internal::PropertySheetStringValue())); createFakeProperty(QLatin1String(currentTabWhatsThisKey), qVariantFromValue(qdesigner_internal::PropertySheetStringValue())); + // Prevent the tab widget's drag and drop handling from interfering with Designer's + createFakeProperty(QLatin1String(tabMovableKey), QVariant(false)); } QTabWidgetPropertySheet::TabWidgetProperty QTabWidgetPropertySheet::tabWidgetPropertyFromName(const QString &name) diff --git a/tools/designer/src/lib/uilib/abstractformbuilder.cpp b/tools/designer/src/lib/uilib/abstractformbuilder.cpp index 24d2c01..eb3dc1c 100644 --- a/tools/designer/src/lib/uilib/abstractformbuilder.cpp +++ b/tools/designer/src/lib/uilib/abstractformbuilder.cpp @@ -285,23 +285,8 @@ void QAbstractFormBuilder::initialize(const DomUI *ui) if (!customWidgets.empty()) { QFormBuilderExtra *formBuilderPrivate = QFormBuilderExtra::instance(this); const DomCustomWidgetList::const_iterator cend = customWidgets.constEnd(); - for (DomCustomWidgetList::const_iterator it = customWidgets.constBegin(); it != cend; ++it) { - const DomCustomWidget *cw = *it; -#ifndef QT_FORMBUILDER_NO_SCRIPT - if (const DomScript *domScript = cw->elementScript()) { - const QString script = domScript->text(); - if (!script.isEmpty()) - formBuilderPrivate->storeCustomWidgetScript(cw->elementClass(), script); - } -#endif - const QString addPageMethod = cw->elementAddPageMethod(); - if (!addPageMethod.isEmpty()) - formBuilderPrivate->storeCustomWidgetAddPageMethod(cw->elementClass(), addPageMethod); - - const QString extends = cw->elementExtends(); - if (!extends.isEmpty()) - formBuilderPrivate->storeCustomWidgetBaseClass(cw->elementClass(), extends); - } + for (DomCustomWidgetList::const_iterator it = customWidgets.constBegin(); it != cend; ++it) + formBuilderPrivate->storeCustomWidgetData((*it)->elementClass(), *it); } } } diff --git a/tools/designer/src/lib/uilib/formbuilder.cpp b/tools/designer/src/lib/uilib/formbuilder.cpp index 0a722ba..2de8388 100644 --- a/tools/designer/src/lib/uilib/formbuilder.cpp +++ b/tools/designer/src/lib/uilib/formbuilder.cpp @@ -123,6 +123,8 @@ QWidget *QFormBuilder::create(DomWidget *ui_widget, QWidget *parentWidget) QFormBuilderExtra *fb = QFormBuilderExtra::instance(this); if (!fb->parentWidgetIsSet()) fb->setParentWidget(parentWidget); + // Is this a QLayoutWidget with a margin of 0: Not a known page-based + // container and no method for adding pages registered. fb->setProcessingLayoutWidget(false); if (ui_widget->attributeClass() == QFormBuilderStrings::instance().qWidgetClass && !ui_widget->hasAttributeNative() && parentWidget @@ -147,8 +149,11 @@ QWidget *QFormBuilder::create(DomWidget *ui_widget, QWidget *parentWidget) #ifndef QT_NO_DOCKWIDGET && !qobject_cast<QDockWidget *>(parentWidget) #endif - ) - fb->setProcessingLayoutWidget(true); + ) { + const QString parentClassName = QLatin1String(parentWidget->metaObject()->className()); + if (!fb->isCustomWidgetContainer(parentClassName)) + fb->setProcessingLayoutWidget(true); + } return QAbstractFormBuilder::create(ui_widget, parentWidget); } diff --git a/tools/designer/src/lib/uilib/formbuilderextra.cpp b/tools/designer/src/lib/uilib/formbuilderextra.cpp index 0e803fb..ce71d59 100644 --- a/tools/designer/src/lib/uilib/formbuilderextra.cpp +++ b/tools/designer/src/lib/uilib/formbuilderextra.cpp @@ -65,6 +65,23 @@ void uiLibWarning(const QString &message) { qWarning("Designer: %s", qPrintable(message)); } + +QFormBuilderExtra::CustomWidgetData::CustomWidgetData() : + isContainer(false) +{ +} + +QFormBuilderExtra::CustomWidgetData::CustomWidgetData(const DomCustomWidget *dcw) : + addPageMethod(dcw->elementAddPageMethod()), + baseClass(dcw->elementExtends()), + isContainer(dcw->hasElementContainer() && dcw->elementContainer() != 0) +{ +#ifndef QT_FORMBUILDER_NO_SCRIPT + if (const DomScript *domScript = dcw->elementScript()) + script = domScript->text(); +#endif +} + QFormBuilderExtra::QFormBuilderExtra() : m_layoutWidget(false), m_resourceBuilder(0), @@ -85,8 +102,8 @@ void QFormBuilderExtra::clear() m_parentWidgetIsSet = false; #ifndef QT_FORMBUILDER_NO_SCRIPT m_FormScriptRunner.clearErrors(); - m_customWidgetScriptHash.clear(); #endif + m_customWidgetDataHash.clear(); m_buttonGroups.clear(); } @@ -160,45 +177,44 @@ QFormScriptRunner &QFormBuilderExtra::formScriptRunner() return m_FormScriptRunner; } -void QFormBuilderExtra::storeCustomWidgetScript(const QString &className, const QString &script) -{ - m_customWidgetScriptHash.insert(className, script); -} - QString QFormBuilderExtra::customWidgetScript(const QString &className) const { - const CustomWidgetScriptHash::const_iterator it = m_customWidgetScriptHash.constFind(className); - if ( it == m_customWidgetScriptHash.constEnd()) - return QString(); - return it.value(); + const QHash<QString, CustomWidgetData>::const_iterator it = m_customWidgetDataHash.constFind(className); + if (it != m_customWidgetDataHash.constEnd()) + return it.value().script; + return QString(); } #endif -void QFormBuilderExtra::storeCustomWidgetBaseClass(const QString &className, const QString &baseClassName) +void QFormBuilderExtra::storeCustomWidgetData(const QString &className, const DomCustomWidget *d) { - m_customWidgetBaseClassHash.insert(className, baseClassName); + if (d) + m_customWidgetDataHash.insert(className, CustomWidgetData(d)); } QString QFormBuilderExtra::customWidgetBaseClass(const QString &className) const { - const QHash<QString, QString>::const_iterator it = m_customWidgetBaseClassHash.constFind(className); - if (it == m_customWidgetBaseClassHash.constEnd()) - return QString(); - return it.value(); + const QHash<QString, CustomWidgetData>::const_iterator it = m_customWidgetDataHash.constFind(className); + if (it != m_customWidgetDataHash.constEnd()) + return it.value().baseClass; + return QString(); } -void QFormBuilderExtra::storeCustomWidgetAddPageMethod(const QString &className, const QString &ct) +QString QFormBuilderExtra::customWidgetAddPageMethod(const QString &className) const { - m_customWidgetAddPageMethodHash.insert(className, ct); + const QHash<QString, CustomWidgetData>::const_iterator it = m_customWidgetDataHash.constFind(className); + if (it != m_customWidgetDataHash.constEnd()) + return it.value().addPageMethod; + return QString(); } -QString QFormBuilderExtra::customWidgetAddPageMethod(const QString &className) const +bool QFormBuilderExtra::isCustomWidgetContainer(const QString &className) const { - const QHash<QString, QString>::const_iterator it = m_customWidgetAddPageMethodHash.constFind(className); - if (it == m_customWidgetAddPageMethodHash.constEnd()) - return QString(); - return it.value(); + const QHash<QString, CustomWidgetData>::const_iterator it = m_customWidgetDataHash.constFind(className); + if (it != m_customWidgetDataHash.constEnd()) + return it.value().isContainer; + return false; } namespace { diff --git a/tools/designer/src/lib/uilib/formbuilderextra_p.h b/tools/designer/src/lib/uilib/formbuilderextra_p.h index ce4d25b..3bcd1eb 100644 --- a/tools/designer/src/lib/uilib/formbuilderextra_p.h +++ b/tools/designer/src/lib/uilib/formbuilderextra_p.h @@ -82,6 +82,7 @@ namespace QFormInternal class DomButtonGroups; class DomButtonGroup; +class DomCustomWidget; class QAbstractFormBuilder; class QResourceBuilder; @@ -92,6 +93,16 @@ class QDESIGNER_UILIB_EXPORT QFormBuilderExtra QFormBuilderExtra(); ~QFormBuilderExtra(); public: + struct CustomWidgetData { + CustomWidgetData(); + explicit CustomWidgetData(const DomCustomWidget *dc); + + QString addPageMethod; + QString script; + QString baseClass; + bool isContainer; + }; + void clear(); bool applyPropertyInternally(QObject *o, const QString &propertyName, const QVariant &value); @@ -107,7 +118,6 @@ public: #ifndef QT_FORMBUILDER_NO_SCRIPT QFormScriptRunner &formScriptRunner(); - void storeCustomWidgetScript(const QString &className, const QString &script); QString customWidgetScript(const QString &className) const; #endif @@ -123,11 +133,10 @@ public: static QFormBuilderExtra *instance(const QAbstractFormBuilder *afb); static void removeInstance(const QAbstractFormBuilder *afb); - void storeCustomWidgetAddPageMethod(const QString &className, const QString &ct); + void storeCustomWidgetData(const QString &className, const DomCustomWidget *d); QString customWidgetAddPageMethod(const QString &className) const; - - void storeCustomWidgetBaseClass(const QString &className, const QString &baseClassName); QString customWidgetBaseClass(const QString &className) const; + bool isCustomWidgetContainer(const QString &className) const; // --- Hash used in creating button groups on demand. Store a map of name and pair of dom group and real group void registerButtonGroups(const DomButtonGroups *groups); @@ -169,13 +178,9 @@ private: #ifndef QT_FORMBUILDER_NO_SCRIPT QFormScriptRunner m_FormScriptRunner; - - typedef QHash<QString, QString> CustomWidgetScriptHash; - CustomWidgetScriptHash m_customWidgetScriptHash; #endif - QHash<QString, QString> m_customWidgetAddPageMethodHash; - QHash<QString, QString> m_customWidgetBaseClassHash; + QHash<QString, CustomWidgetData> m_customWidgetDataHash; ButtonGroupHash m_buttonGroups; diff --git a/tools/designer/translations/translations.pro b/tools/designer/translations/translations.pro index 2323882..03c1415 100644 --- a/tools/designer/translations/translations.pro +++ b/tools/designer/translations/translations.pro @@ -130,6 +130,7 @@ HEADERS += ../../shared/findwidget/abstractfindwidget.h \ TR_DIR = $$PWD/../../../translations TRANSLATIONS = \ $$TR_DIR/designer_de.ts \ + $$TR_DIR/designer_fr.ts \ $$TR_DIR/designer_ja.ts \ $$TR_DIR/designer_pl.ts \ $$TR_DIR/designer_ru.ts \ diff --git a/tools/linguist/lconvert/main.cpp b/tools/linguist/lconvert/main.cpp index 6f5f86a..7807761 100644 --- a/tools/linguist/lconvert/main.cpp +++ b/tools/linguist/lconvert/main.cpp @@ -239,7 +239,7 @@ int main(int argc, char *argv[]) qWarning() << qPrintable(cd.error()); return 2; } - Translator::reportDuplicates(tr.resolveDuplicates(), inFiles[0].name, verbose); + tr.reportDuplicates(tr.resolveDuplicates(), inFiles[0].name, verbose); for (int i = 1; i < inFiles.size(); ++i) { Translator tr2; @@ -247,7 +247,7 @@ int main(int argc, char *argv[]) qWarning() << qPrintable(cd.error()); return 2; } - Translator::reportDuplicates(tr2.resolveDuplicates(), inFiles[i].name, verbose); + tr2.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/mainwindow.cpp b/tools/linguist/linguist/mainwindow.cpp index 9bc6641..7f09a1c 100644 --- a/tools/linguist/linguist/mainwindow.cpp +++ b/tools/linguist/linguist/mainwindow.cpp @@ -269,6 +269,7 @@ MainWindow::MainWindow() m_editActiveModel(-1), m_statistics(0) { + setUnifiedTitleAndToolBarOnMac(true); m_ui.setupUi(this); #ifndef Q_WS_MAC diff --git a/tools/linguist/linguist/messagemodel.cpp b/tools/linguist/linguist/messagemodel.cpp index e6bb9af..024fd91 100644 --- a/tools/linguist/linguist/messagemodel.cpp +++ b/tools/linguist/linguist/messagemodel.cpp @@ -209,20 +209,29 @@ bool DataModel::load(const QString &fileName, bool *langGuessed, QWidget *parent return false; } - QSet<TranslatorMessagePtr> dupes = tor.resolveDuplicates(); - if (!dupes.isEmpty()) { + Translator::Duplicates dupes = tor.resolveDuplicates(); + if (!dupes.byId.isEmpty() || !dupes.byContents.isEmpty()) { QString err = tr("<qt>Duplicate messages found in '%1':").arg(Qt::escape(fileName)); int numdups = 0; - foreach (const TranslatorMessagePtr &msg, dupes) { + foreach (int i, dupes.byId) { + if (++numdups >= 5) { + err += tr("<p>[more duplicates omitted]"); + goto doWarn; + } + err += tr("<p>* ID: %1").arg(Qt::escape(tor.message(i).id())); + } + foreach (int j, dupes.byContents) { + const TranslatorMessage &msg = tor.message(j); 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())); } + doWarn: QMessageBox::warning(parent, QObject::tr("Qt Linguist"), err); } diff --git a/tools/linguist/lrelease/lrelease.pro b/tools/linguist/lrelease/lrelease.pro index 01091b3..e4c18ee 100644 --- a/tools/linguist/lrelease/lrelease.pro +++ b/tools/linguist/lrelease/lrelease.pro @@ -2,21 +2,14 @@ TEMPLATE = app TARGET = lrelease DESTDIR = ../../../bin -QT -= gui - -CONFIG += qt warn_on console -CONFIG -= app_bundle - -build_all:!build_pass { - CONFIG -= build_all - CONFIG += release -} - DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII SOURCES += main.cpp +include(../../../src/tools/bootstrap/bootstrap.pri) include(../shared/formats.pri) include(../shared/proparser.pri) +win32-msvc*:LIBS += advapi32.lib # for qsettings_win.cpp + target.path=$$[QT_INSTALL_BINS] INSTALLS += target diff --git a/tools/linguist/lrelease/main.cpp b/tools/linguist/lrelease/main.cpp index 2867849..c45459a 100644 --- a/tools/linguist/lrelease/main.cpp +++ b/tools/linguist/lrelease/main.cpp @@ -42,7 +42,10 @@ #include "translator.h" #include "proreader.h" +#ifndef QT_BOOTSTRAPPED #include <QtCore/QCoreApplication> +#include <QtCore/QTranslator> +#endif #include <QtCore/QDebug> #include <QtCore/QDir> #include <QtCore/QFile> @@ -51,7 +54,14 @@ #include <QtCore/QString> #include <QtCore/QStringList> #include <QtCore/QTextStream> -#include <QtCore/QTranslator> + +#ifdef QT_BOOTSTRAPPED +static void initBinaryDir( +#ifndef Q_OS_WIN + const char *argv0 +#endif + ); +#endif static void printOut(const QString & out) { @@ -79,6 +89,9 @@ static void printUsage() " -removeidentical\n" " If the translated text is the same as\n" " the source text, do not include the message\n" + " -markuntranslated <prefix>\n" + " If a message has no real translation, use the source text\n" + " prefixed with the given string instead\n" " -silent\n" " Do not explain what is being done\n" " -version\n" @@ -100,15 +113,14 @@ static bool loadTsFile(Translator &tor, const QString &tsFileName, bool /* verbo } static bool releaseTranslator(Translator &tor, const QString &qmFileName, - bool verbose, bool ignoreUnfinished, - bool removeIdentical, bool idBased, TranslatorSaveMode mode) + ConversionData &cd, bool removeIdentical) { - Translator::reportDuplicates(tor.resolveDuplicates(), qmFileName, verbose); + tor.reportDuplicates(tor.resolveDuplicates(), qmFileName, cd.isVerbose()); - if (verbose) + if (cd.isVerbose()) printOut(QCoreApplication::tr( "Updating '%1'...\n").arg(qmFileName)); if (removeIdentical) { - if ( verbose ) + if (cd.isVerbose()) printOut(QCoreApplication::tr( "Removing translations equal to source text in '%1'...\n").arg(qmFileName)); tor.stripIdenticalSourceTranslations(); } @@ -120,12 +132,7 @@ static bool releaseTranslator(Translator &tor, const QString &qmFileName, return false; } - ConversionData cd; tor.normalizeTranslations(cd); - cd.m_verbose = verbose; - cd.m_ignoreUnfinished = ignoreUnfinished; - cd.m_idBased = idBased; - cd.m_saveMode = mode; bool ok = tor.release(&file, cd); file.close(); @@ -139,11 +146,11 @@ static bool releaseTranslator(Translator &tor, const QString &qmFileName, return true; } -static bool releaseTsFile(const QString& tsFileName, bool verbose, - bool ignoreUnfinished, bool removeIdentical, bool idBased, TranslatorSaveMode mode) +static bool releaseTsFile(const QString& tsFileName, + ConversionData &cd, bool removeIdentical) { Translator tor; - if (!loadTsFile(tor, tsFileName, verbose)) + if (!loadTsFile(tor, tsFileName, cd.isVerbose())) return false; QString qmFileName = tsFileName; @@ -155,92 +162,98 @@ static bool releaseTsFile(const QString& tsFileName, bool verbose, } qmFileName += QLatin1String(".qm"); - return releaseTranslator(tor, qmFileName, verbose, ignoreUnfinished, removeIdentical, idBased, mode); + return releaseTranslator(tor, qmFileName, cd, removeIdentical); } int main(int argc, char **argv) { +#ifdef QT_BOOTSTRAPPED + initBinaryDir( +#ifndef Q_OS_WIN + argv[0] +#endif + ); +#else QCoreApplication app(argc, argv); - QStringList args = app.arguments(); QTranslator translator; if (translator.load(QLatin1String("lrelease_") + QLocale::system().name())) app.installTranslator(&translator); +#endif - bool verbose = true; // the default is true starting with Qt 4.2 - bool ignoreUnfinished = false; - bool idBased = false; - // the default mode is SaveEverything starting with Qt 4.2 - TranslatorSaveMode mode = SaveEverything; + ConversionData cd; + cd.m_verbose = true; // the default is true starting with Qt 4.2 bool removeIdentical = false; Translator tor; + QStringList inputFiles; QString outputFile; - int numFiles = 0; for (int i = 1; i < argc; ++i) { - if (args[i] == QLatin1String("-compress")) { - mode = SaveStripped; + if (!strcmp(argv[i], "-compress")) { + cd.m_saveMode = SaveStripped; continue; - } else if (args[i] == QLatin1String("-idbased")) { - idBased = true; + } else if (!strcmp(argv[i], "-idbased")) { + cd.m_idBased = true; continue; - } else if (args[i] == QLatin1String("-nocompress")) { - mode = SaveEverything; + } else if (!strcmp(argv[i], "-nocompress")) { + cd.m_saveMode = SaveEverything; continue; - } else if (args[i] == QLatin1String("-removeidentical")) { + } else if (!strcmp(argv[i], "-removeidentical")) { removeIdentical = true; continue; - } else if (args[i] == QLatin1String("-nounfinished")) { - ignoreUnfinished = true; + } else if (!strcmp(argv[i], "-nounfinished")) { + cd.m_ignoreUnfinished = true; continue; - } else if (args[i] == QLatin1String("-silent")) { - verbose = false; + } else if (!strcmp(argv[i], "-markuntranslated")) { + if (i == argc - 1) { + printUsage(); + return 1; + } + cd.m_unTrPrefix = QString::fromLocal8Bit(argv[++i]); + } else if (!strcmp(argv[i], "-silent")) { + cd.m_verbose = false; continue; - } else if (args[i] == QLatin1String("-verbose")) { - verbose = true; + } else if (!strcmp(argv[i], "-verbose")) { + cd.m_verbose = true; continue; - } else if (args[i] == QLatin1String("-version")) { + } else if (!strcmp(argv[i], "-version")) { printOut(QCoreApplication::tr( "lrelease version %1\n").arg(QLatin1String(QT_VERSION_STR)) ); return 0; - } else if (args[i] == QLatin1String("-qm")) { + } else if (!strcmp(argv[i], "-qm")) { if (i == argc - 1) { printUsage(); return 1; } - i++; - outputFile = args[i]; - } else if (args[i] == QLatin1String("-help")) { + outputFile = QString::fromLocal8Bit(argv[++i]); + } else if (!strcmp(argv[i], "-help")) { printUsage(); return 0; - } else if (args[i][0] == QLatin1Char('-')) { + } else if (argv[i][0] == '-') { printUsage(); return 1; } else { - numFiles++; + inputFiles << QString::fromLocal8Bit(argv[i]); } } - if (numFiles == 0) { + if (inputFiles.isEmpty()) { printUsage(); return 1; } - for (int i = 1; i < argc; ++i) { - if (args[i][0] == QLatin1Char('-') || args[i] == outputFile) - continue; - - if (args[i].endsWith(QLatin1String(".pro"), Qt::CaseInsensitive) - || args[i].endsWith(QLatin1String(".pri"), Qt::CaseInsensitive)) { + foreach (const QString &inputFile, inputFiles) { + if (inputFile.endsWith(QLatin1String(".pro"), Qt::CaseInsensitive) + || inputFile.endsWith(QLatin1String(".pri"), Qt::CaseInsensitive)) { QHash<QByteArray, QStringList> varMap; - bool ok = evaluateProFile(args[i], verbose, &varMap ); + bool ok = evaluateProFile(inputFile, cd.isVerbose(), &varMap); if (ok) { QStringList translations = varMap.value("TRANSLATIONS"); if (translations.isEmpty()) { qWarning("lrelease warning: Met no 'TRANSLATIONS' entry in" " project file '%s'\n", - qPrintable(args[i])); + qPrintable(inputFile)); } else { foreach (const QString &trans, translations) - if (!releaseTsFile(trans, verbose, ignoreUnfinished, removeIdentical, idBased, mode)) + if (!releaseTsFile(trans, cd, removeIdentical)) return 1; } } else { @@ -251,18 +264,93 @@ int main(int argc, char **argv) } } else { if (outputFile.isEmpty()) { - if (!releaseTsFile(args[i], verbose, ignoreUnfinished, removeIdentical, idBased, mode)) + if (!releaseTsFile(inputFile, cd, removeIdentical)) return 1; } else { - if (!loadTsFile(tor, args[i], verbose)) + if (!loadTsFile(tor, inputFile, cd.isVerbose())) return 1; } } } if (!outputFile.isEmpty()) - return releaseTranslator(tor, outputFile, verbose, ignoreUnfinished, - removeIdentical, idBased, mode) ? 0 : 1; + return releaseTranslator(tor, outputFile, cd, removeIdentical) ? 0 : 1; return 0; } + +#ifdef QT_BOOTSTRAPPED + +#ifdef Q_OS_WIN +# include <windows.h> +#endif + +static QString binDir; + +static void initBinaryDir( +#ifndef Q_OS_WIN + const char *_argv0 +#endif + ) +{ +#ifdef Q_OS_WIN + wchar_t module_name[MAX_PATH]; + GetModuleFileName(0, module_name, MAX_PATH); + QFileInfo filePath = QString::fromWCharArray(module_name); + binDir = filePath.filePath(); +#else + QString argv0 = QFile::decodeName(QByteArray(_argv0)); + QString absPath; + + if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) { + /* + If argv0 starts with a slash, it is already an absolute + file path. + */ + absPath = argv0; + } else if (argv0.contains(QLatin1Char('/'))) { + /* + If argv0 contains one or more slashes, it is a file path + relative to the current directory. + */ + absPath = QDir::current().absoluteFilePath(argv0); + } else { + /* + Otherwise, the file path has to be determined using the + PATH environment variable. + */ + QByteArray pEnv = qgetenv("PATH"); + QDir currentDir = QDir::current(); + QStringList paths = QString::fromLocal8Bit(pEnv.constData()).split(QLatin1String(":")); + for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) { + if ((*p).isEmpty()) + continue; + QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0); + QFileInfo candidate_fi(candidate); + if (candidate_fi.exists() && !candidate_fi.isDir()) { + binDir = candidate_fi.canonicalPath(); + return; + } + } + return; + } + + QFileInfo fi(absPath); + if (fi.exists()) + binDir = fi.canonicalPath(); +#endif +} + +QT_BEGIN_NAMESPACE + +// The name is hard-coded in QLibraryInfo +QString qmake_libraryInfoFile() +{ + if (binDir.isEmpty()) + return QString(); + return QDir(binDir).filePath(QString::fromLatin1("qt.conf")); +} + +QT_END_NAMESPACE + +#endif // QT_BOOTSTRAPPED diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 7a616e3..443abd0 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -135,6 +135,11 @@ struct Namespace { // Nested classes may be forward-declared inside a definition, and defined in another file. // The latter will detach the class' child list, so clones need a backlink to the original // definition (either one in case of multiple definitions). + // Namespaces can have tr() functions as well, so we need to track parent definitions for + // them as well. The complication is that we may have to deal with a forrest instead of + // a tree - in that case the parent will be arbitrary. However, it seem likely that + // Q_DECLARE_TR_FUNCTIONS would be used either in "class-like" namespaces with a central + // header or only locally in a file. Namespace *classDef; QString trQualification; @@ -256,17 +261,20 @@ private: bool qualifyOneCallbackUsing(const Namespace *ns, void *context) const; bool qualifyOne(const NamespaceList &namespaces, int nsCnt, const HashString &segment, NamespaceList *resolved) const; - bool fullyQualify(const NamespaceList &namespaces, const QList<HashString> &segments, - bool isDeclaration, + bool fullyQualify(const NamespaceList &namespaces, int nsCnt, + const QList<HashString> &segments, bool isDeclaration, NamespaceList *resolved, QStringList *unresolved) const; - bool fullyQualify(const NamespaceList &namespaces, const QString &segments, - bool isDeclaration, + bool fullyQualify(const NamespaceList &namespaces, + const QList<HashString> &segments, bool isDeclaration, + NamespaceList *resolved, QStringList *unresolved) const; + bool fullyQualify(const NamespaceList &namespaces, + const QString &segments, bool isDeclaration, NamespaceList *resolved, QStringList *unresolved) const; bool findNamespaceCallback(const Namespace *ns, void *context) const; const Namespace *findNamespace(const NamespaceList &namespaces, int nsCount = -1) const; void enterNamespace(NamespaceList *namespaces, const HashString &name); void truncateNamespaces(NamespaceList *namespaces, int lenght); - Namespace *modifyNamespace(NamespaceList *namespaces, bool tryOrigin = true); + Namespace *modifyNamespace(NamespaceList *namespaces, bool haveLast = true); enum { Tok_Eof, Tok_class, Tok_friend, Tok_namespace, Tok_using, Tok_return, @@ -780,7 +788,7 @@ uint CppParser::getToken() if (yyCh == EOF) { qWarning("%s:%d: Unterminated C++ comment\n", qPrintable(yyFileName), yyLineNo); - return Tok_Comment; + break; } *ptr++ = yyCh; @@ -958,7 +966,7 @@ void CppParser::loadState(const SavedState *state) pendingContext = state->pendingContext; } -Namespace *CppParser::modifyNamespace(NamespaceList *namespaces, bool tryOrigin) +Namespace *CppParser::modifyNamespace(NamespaceList *namespaces, bool haveLast) { Namespace *pns, *ns = &results->rootNamespace; for (int i = 1; i < namespaces->count(); ++i) { @@ -966,7 +974,7 @@ Namespace *CppParser::modifyNamespace(NamespaceList *namespaces, bool tryOrigin) if (!(ns = pns->children.value(namespaces->at(i)))) { do { ns = new Namespace; - if (tryOrigin) + if (haveLast || i < namespaces->count() - 1) if (const Namespace *ons = findNamespace(*namespaces, i + 1)) ns->classDef = ons->classDef; pns->children.insert(namespaces->at(i), ns); @@ -1052,7 +1060,18 @@ bool CppParser::qualifyOneCallbackOwn(const Namespace *ns, void *context) const } QHash<HashString, NamespaceList>::ConstIterator nsai = ns->aliases.constFind(data->segment); if (nsai != ns->aliases.constEnd()) { - *data->resolved = *nsai; + const NamespaceList &nsl = *nsai; + if (nsl.last().value().isEmpty()) { // Delayed alias resolution + NamespaceList &nslIn = *const_cast<NamespaceList *>(&nsl); + nslIn.removeLast(); + NamespaceList nslOut; + if (!fullyQualify(data->namespaces, data->nsCount, nslIn, false, &nslOut, 0)) { + const_cast<Namespace *>(ns)->aliases.remove(data->segment); + return false; + } + nslIn = nslOut; + } + *data->resolved = nsl; return true; } return false; @@ -1081,8 +1100,8 @@ bool CppParser::qualifyOne(const NamespaceList &namespaces, int nsCnt, const Has return visitNamespace(namespaces, nsCnt, &CppParser::qualifyOneCallbackUsing, &data); } -bool CppParser::fullyQualify(const NamespaceList &namespaces, const QList<HashString> &segments, - bool isDeclaration, +bool CppParser::fullyQualify(const NamespaceList &namespaces, int nsCnt, + const QList<HashString> &segments, bool isDeclaration, NamespaceList *resolved, QStringList *unresolved) const { int nsIdx; @@ -1099,7 +1118,7 @@ bool CppParser::fullyQualify(const NamespaceList &namespaces, const QList<HashSt nsIdx = 0; } else { initSegIdx = 0; - nsIdx = namespaces.count() - 1; + nsIdx = nsCnt - 1; } do { @@ -1122,8 +1141,16 @@ bool CppParser::fullyQualify(const NamespaceList &namespaces, const QList<HashSt return false; } -bool CppParser::fullyQualify(const NamespaceList &namespaces, const QString &quali, - bool isDeclaration, +bool CppParser::fullyQualify(const NamespaceList &namespaces, + const QList<HashString> &segments, bool isDeclaration, + NamespaceList *resolved, QStringList *unresolved) const +{ + return fullyQualify(namespaces, namespaces.count(), + segments, isDeclaration, resolved, unresolved); +} + +bool CppParser::fullyQualify(const NamespaceList &namespaces, + const QString &quali, bool isDeclaration, NamespaceList *resolved, QStringList *unresolved) const { static QString strColons(QLatin1String("::")); @@ -1633,9 +1660,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions) } if (fullName.isEmpty()) break; - NamespaceList nsl; - if (fullyQualify(namespaces, fullName, false, &nsl, 0)) - modifyNamespace(&namespaces, false)->aliases[ns] = nsl; + fullName.append(HashString(QString())); // Mark as unresolved + modifyNamespace(&namespaces)->aliases[ns] = fullName; } } else if (yyTok == Tok_LeftBrace) { // Anonymous namespace @@ -1661,7 +1687,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions) } NamespaceList nsl; if (fullyQualify(namespaces, fullName, false, &nsl, 0)) - modifyNamespace(&namespaces, false)->usings << HashStringList(nsl); + modifyNamespace(&namespaces)->usings << HashStringList(nsl); } else { QList<HashString> fullName; if (yyTok == Tok_ColonColon) @@ -1676,9 +1702,13 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions) } if (fullName.isEmpty()) break; - NamespaceList nsl; - if (fullyQualify(namespaces, fullName, false, &nsl, 0)) - modifyNamespace(&namespaces, true)->aliases[nsl.last()] = nsl; + // using-declarations cannot rename classes, so the last element of + // fullName is already the resolved name we actually want. + // As we do no resolution here, we'll collect useless usings of data + // members and methods as well. This is no big deal. + HashString &ns = fullName.last(); + fullName.append(HashString(QString())); // Mark as unresolved + modifyNamespace(&namespaces)->aliases[ns] = fullName; } break; case Tok_tr: @@ -1853,29 +1883,25 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions) case Tok_trid: if (!tor) goto case_default; - if (sourcetext.isEmpty()) { - yyTok = getToken(); - } else { - if (!msgid.isEmpty()) - qWarning("%s:%d: //= cannot be used with qtTrId() / QT_TRID_NOOP(). Ignoring\n", - qPrintable(yyFileName), yyLineNo); - //utf8 = false; // Maybe use //%% or something like that - line = yyLineNo; - yyTok = getToken(); - if (match(Tok_LeftParen) && matchString(&msgid) && !msgid.isEmpty()) { - bool plural = match(Tok_Comma); - recordMessage(line, QString(), sourcetext, QString(), extracomment, - msgid, extra, false, plural); - } - sourcetext.clear(); + if (!msgid.isEmpty()) + qWarning("%s:%d: //= cannot be used with qtTrId() / QT_TRID_NOOP(). Ignoring\n", + qPrintable(yyFileName), yyLineNo); + //utf8 = false; // Maybe use //%% or something like that + line = yyLineNo; + yyTok = getToken(); + if (match(Tok_LeftParen) && matchString(&msgid) && !msgid.isEmpty()) { + bool plural = match(Tok_Comma); + recordMessage(line, QString(), sourcetext, QString(), extracomment, + msgid, extra, false, plural); } + sourcetext.clear(); extracomment.clear(); msgid.clear(); extra.clear(); break; case Tok_Q_DECLARE_TR_FUNCTIONS: if (getMacroArgs()) { - Namespace *ns = modifyNamespace(&namespaces, true); + Namespace *ns = modifyNamespace(&namespaces); ns->hasTrFunctions = true; ns->trQualification = yyWord; ns->trQualification.detach(); @@ -1883,7 +1909,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions) yyTok = getToken(); break; case Tok_Q_OBJECT: - modifyNamespace(&namespaces, true)->hasTrFunctions = true; + modifyNamespace(&namespaces)->hasTrFunctions = true; yyTok = getToken(); break; case Tok_Ident: @@ -1896,28 +1922,29 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions) prospectiveContext.clear(); } break; - case Tok_Comment: + case Tok_Comment: { if (!tor) goto case_default; - if (yyWord.startsWith(QLatin1Char(':'))) { - yyWord.remove(0, 1); + const QChar *ptr = yyWord.unicode(); + if (*ptr == QLatin1Char(':') && ptr[1].isSpace()) { + yyWord.remove(0, 2); extracomment += yyWord; extracomment.detach(); - } else if (yyWord.startsWith(QLatin1Char('='))) { - yyWord.remove(0, 1); + } else if (*ptr == QLatin1Char('=') && ptr[1].isSpace()) { + yyWord.remove(0, 2); msgid = yyWord.simplified(); msgid.detach(); - } else if (yyWord.startsWith(QLatin1Char('~'))) { - yyWord.remove(0, 1); + } else if (*ptr == QLatin1Char('~') && ptr[1].isSpace()) { + yyWord.remove(0, 2); text = yyWord.trimmed(); int k = text.indexOf(QLatin1Char(' ')); if (k > -1) extra.insert(text.left(k), text.mid(k + 1).trimmed()); text.clear(); - } else if (yyWord.startsWith(QLatin1Char('%'))) { - sourcetext.reserve(sourcetext.length() + yyWord.length()); + } else if (*ptr == QLatin1Char('%') && ptr[1].isSpace()) { + sourcetext.reserve(sourcetext.length() + yyWord.length() - 2); ushort *ptr = (ushort *)sourcetext.data() + sourcetext.length(); - int p = 1, c; + int p = 2, c; forever { if (p >= yyWord.length()) break; @@ -1977,6 +2004,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions) } yyTok = getToken(); break; + } case Tok_Arrow: yyTok = getToken(); if (yyTok == Tok_tr || yyTok == Tok_trUtf8) diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp index 6b554e0..bdaec4f 100644 --- a/tools/linguist/lupdate/main.cpp +++ b/tools/linguist/lupdate/main.cpp @@ -160,6 +160,8 @@ static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFil tor.setCodecName(codecForTr); if (!targetLanguage.isEmpty()) tor.setLanguageCode(targetLanguage); + else + tor.setLanguageCode(Translator::guessLanguageCodeFromFileName(fileName)); if (!sourceLanguage.isEmpty()) tor.setSourceLanguageCode(sourceLanguage); } diff --git a/tools/linguist/lupdate/merge.cpp b/tools/linguist/lupdate/merge.cpp index b5f77cd..fa0dd3d 100644 --- a/tools/linguist/lupdate/merge.cpp +++ b/tools/linguist/lupdate/merge.cpp @@ -247,10 +247,8 @@ int applyNumberHeuristic(Translator &tor) t = translated.find(zeroKey((*u).sourceText())); if (t != translated.end() && !t.key().isEmpty() && t->sourceText() != u->sourceText()) { - TranslatorMessage m = *u; - m.setTranslation(translationAttempt(t->translation(), t->sourceText(), - u->sourceText())); - tor.replace(m); + u->setTranslation(translationAttempt(t->translation(), t->sourceText(), + u->sourceText())); inserted++; } } @@ -305,9 +303,7 @@ int applySameTextHeuristic(Translator &tor) QString key = u->sourceText(); t = translated.find(key); if (t != translated.end()) { - TranslatorMessage m = *u; - m.setTranslations(t->translations()); - tor.replace(m); + u->setTranslations(t->translations()); ++inserted; } } @@ -345,15 +341,17 @@ Translator merge(const Translator &tor, const Translator &virginTor, foreach (TranslatorMessage m, tor.messages()) { TranslatorMessage::Type newType = TranslatorMessage::Finished; - if (m.sourceText().isEmpty()) { + if (m.sourceText().isEmpty() && m.id().isEmpty()) { // context/file comment TranslatorMessage mv = virginTor.find(m.context()); if (!mv.isNull()) m.setComment(mv.comment()); } else { - TranslatorMessage mv = virginTor.find(m.context(), m.sourceText(), m.comment()); - if (mv.isNull()) { + TranslatorMessage mv; + int mvi = virginTor.find(m); + if (mvi < 0) { if (!(options & HeuristicSimilarText)) { + makeObsolete: newType = TranslatorMessage::Obsolete; if (m.type() != TranslatorMessage::Obsolete) obsoleted++; @@ -362,10 +360,7 @@ Translator merge(const Translator &tor, const Translator &virginTor, mv = virginTor.find(m.context(), m.comment(), m.allReferences()); if (mv.isNull()) { // did not find it in the virgin, mark it as obsolete - newType = TranslatorMessage::Obsolete; - if (m.type() != TranslatorMessage::Obsolete) - obsoleted++; - m.clearReferences(); + goto makeObsolete; } else { // Do not just accept it if its on the same line number, // but different source text. @@ -380,6 +375,7 @@ Translator merge(const Translator &tor, const Translator &virginTor, ++similarTextHeuristicCount; neww++; + outdateSource: m.setOldSourceText(m.sourceText()); m.setSourceText(mv.sourceText()); const QString &oldpluralsource = m.extra(QLatin1String("po-msgid_plural")); @@ -387,38 +383,45 @@ Translator merge(const Translator &tor, const Translator &virginTor, m.setExtra(QLatin1String("po-old_msgid_plural"), oldpluralsource); m.unsetExtra(QLatin1String("po-msgid_plural")); } - m.setReferences(mv.allReferences()); // Update secondary references - m.setPlural(mv.isPlural()); - m.setUtf8(mv.isUtf8()); - m.setExtraComment(mv.extraComment()); + goto copyAttribs; // Update secondary references } else { // The virgin and vernacular sourceTexts are so // different that we could not find it. - newType = TranslatorMessage::Obsolete; - if (m.type() != TranslatorMessage::Obsolete) - obsoleted++; - m.clearReferences(); + goto makeObsolete; } } } } else { - switch (m.type()) { - case TranslatorMessage::Finished: - default: - if (m.isPlural() == mv.isPlural()) { - newType = TranslatorMessage::Finished; - } else { - newType = TranslatorMessage::Unfinished; - } + mv = virginTor.message(mvi); + if (!mv.id().isEmpty() + && (mv.context() != m.context() + || mv.sourceText() != m.sourceText() + || mv.comment() != m.comment())) { known++; - break; - case TranslatorMessage::Unfinished: newType = TranslatorMessage::Unfinished; - known++; - break; - case TranslatorMessage::Obsolete: - newType = TranslatorMessage::Unfinished; - neww++; + m.setContext(mv.context()); + m.setComment(mv.comment()); + if (mv.sourceText() != m.sourceText()) + goto outdateSource; + } else { + switch (m.type()) { + case TranslatorMessage::Finished: + default: + if (m.isPlural() == mv.isPlural()) { + newType = TranslatorMessage::Finished; + } else { + newType = TranslatorMessage::Unfinished; + } + known++; + break; + case TranslatorMessage::Unfinished: + newType = TranslatorMessage::Unfinished; + known++; + break; + case TranslatorMessage::Obsolete: + newType = TranslatorMessage::Unfinished; + neww++; + } } // Always get the filename and linenumber info from the @@ -426,10 +429,12 @@ Translator merge(const Translator &tor, const Translator &virginTor, // This should also enable us to read a file that does not // have the <location> element. // why not use operator=()? Because it overwrites e.g. userData. + copyAttribs: m.setReferences(mv.allReferences()); m.setPlural(mv.isPlural()); m.setUtf8(mv.isUtf8()); m.setExtraComment(mv.extraComment()); + m.setId(mv.id()); } } @@ -442,11 +447,11 @@ Translator merge(const Translator &tor, const Translator &virginTor, vernacular translator. */ foreach (const TranslatorMessage &mv, virginTor.messages()) { - if (mv.sourceText().isEmpty()) { + if (mv.sourceText().isEmpty() && mv.id().isEmpty()) { if (tor.contains(mv.context())) continue; } else { - if (tor.contains(mv.context(), mv.sourceText(), mv.comment())) + if (tor.find(mv) >= 0) continue; if (options & HeuristicSimilarText) { TranslatorMessage m = tor.find(mv.context(), mv.comment(), mv.allReferences()); @@ -460,7 +465,7 @@ Translator merge(const Translator &tor, const Translator &virginTor, outTor.append(mv); else outTor.appendSorted(mv); - if (!mv.sourceText().isEmpty()) + if (!mv.sourceText().isEmpty() || !mv.id().isEmpty()) ++neww; } diff --git a/tools/linguist/lupdate/qscript.cpp b/tools/linguist/lupdate/qscript.cpp index 4600656..6c94588 100644 --- a/tools/linguist/lupdate/qscript.cpp +++ b/tools/linguist/lupdate/qscript.cpp @@ -776,7 +776,7 @@ static void recordMessage( fileName, lineNo, QStringList(), TranslatorMessage::Unfinished, plural); msg.setExtraComment(extracomment.simplified()); - tor->replace(msg); + tor->extend(msg); } diff --git a/tools/linguist/phrasebooks/french.qph b/tools/linguist/phrasebooks/french.qph index d38da5a..d710abd 100644 --- a/tools/linguist/phrasebooks/french.qph +++ b/tools/linguist/phrasebooks/french.qph @@ -1326,4 +1326,80 @@ <source>Close All Except %1</source> <target>Fermer tout sauf %1</target> </phrase> +<phrase> + <source>Remove</source> + <target>Suppression</target> +</phrase> +<phrase> + <source>About...</source> + <target>À propos…</target> +</phrase> +<phrase> + <source>Minimize</source> + <target>Minimiser</target> +</phrase> +<phrase> + <source>Remove</source> + <target>Supprimer</target> +</phrase> +<phrase> + <source>Select All</source> + <target>Sélectionner tout</target> +</phrase> +<phrase> + <source>Cannot create directory: %1</source> + <target>Impossible de créer le répertoire : %1</target> +</phrase> +<phrase> + <source></source> + <target></target> +</phrase> +<phrase> + <source>Whole &words</source> + <target>M&ots complets</target> +</phrase> +<phrase> + <source>Title:</source> + <target>Titre :</target> +</phrase> +<phrase> + <source>Fonts</source> + <target>Polices</target> +</phrase> +<phrase> + <source>Insert</source> + <target>Insérer</target> +</phrase> +<phrase> + <source>Size</source> + <target>Taille</target> +</phrase> +<phrase> + <source>List View</source> + <target>Affichage liste</target> +</phrase> +<phrase> + <source>Read-only</source> + <target>Lecture seule</target> +</phrase> +<phrase> + <source>Minimize</source> + <target>Réduire</target> +</phrase> +<phrase> + <source>Maximize</source> + <target>Maximiser</target> +</phrase> +<phrase> + <source>Retry</source> + <target>Réessayer</target> +</phrase> +<phrase> + <source>Dock</source> + <target>Attacher</target> +</phrase> +<phrase> + <source>&Redo</source> + <target>&Rétablir</target> +</phrase> </QPH> diff --git a/tools/linguist/shared/proparserutils.h b/tools/linguist/shared/proparserutils.h index 9a83733..1ed3d6c 100644 --- a/tools/linguist/shared/proparserutils.h +++ b/tools/linguist/shared/proparserutils.h @@ -43,10 +43,35 @@ #define PROPARSERUTILS_H #include <QtCore/QDir> +#ifndef QT_BOOTSTRAPPED #include <QtCore/QLibraryInfo> +#endif QT_BEGIN_NAMESPACE +#ifdef QT_BOOTSTRAPPED +// this is a stripped down version of the one found in QtCore +class QLibraryInfo +{ +public: + enum LibraryLocation + { + PrefixPath, + DocumentationPath, + HeadersPath, + LibrariesPath, + BinariesPath, + PluginsPath, + DataPath, + TranslationsPath, + SettingsPath, + DemosPath, + ExamplesPath + }; + static QString location(LibraryLocation); +}; +#endif + // Pre- and postcondition macros #define PRE(cond) do {if (!(cond))qt_assert(#cond,__FILE__,__LINE__);} while (0) #define POST(cond) do {if (!(cond))qt_assert(#cond,__FILE__,__LINE__);} while (0) diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp index fefe91c..e4c26bc 100644 --- a/tools/linguist/shared/qm.cpp +++ b/tools/linguist/shared/qm.cpp @@ -41,7 +41,9 @@ #include "translator.h" +#ifndef QT_BOOTSTRAPPED #include <QtCore/QCoreApplication> +#endif #include <QtCore/QDebug> #include <QtCore/QDir> #include <QtCore/QFile> @@ -172,8 +174,8 @@ public: bool save(QIODevice *iod); - void insert(const TranslatorMessage &msg, bool forceComment); - void insertIdBased(const TranslatorMessage &message); + void insert(const TranslatorMessage &msg, const QStringList &tlns, bool forceComment); + void insertIdBased(const TranslatorMessage &message, const QStringList &tlns); void squeeze(TranslatorSaveMode mode); @@ -186,7 +188,8 @@ private: // on turn should be the same as passed to the actual tr(...) calls QByteArray originalBytes(const QString &str, bool isUtf8) const; - void insertInternal(const TranslatorMessage &message, bool forceComment, bool isUtf8); + void insertInternal(const TranslatorMessage &message, const QStringList &tlns, + bool forceComment, bool isUtf8); static Prefix commonPrefix(const ByteTranslatorMessage &m1, const ByteTranslatorMessage &m2); @@ -413,12 +416,13 @@ void Releaser::squeeze(TranslatorSaveMode mode) } } -void Releaser::insertInternal(const TranslatorMessage &message, bool forceComment, bool isUtf8) +void Releaser::insertInternal(const TranslatorMessage &message, const QStringList &tlns, + bool forceComment, bool isUtf8) { ByteTranslatorMessage bmsg(originalBytes(message.context(), isUtf8), originalBytes(message.sourceText(), isUtf8), originalBytes(message.comment(), isUtf8), - message.translations()); + tlns); if (!forceComment) { ByteTranslatorMessage bmsg2( bmsg.context(), bmsg.sourceText(), QByteArray(""), bmsg.translations()); @@ -430,19 +434,15 @@ void Releaser::insertInternal(const TranslatorMessage &message, bool forceCommen m_messages.insert(bmsg, 0); } -void Releaser::insert(const TranslatorMessage &message, bool forceComment) +void Releaser::insert(const TranslatorMessage &message, const QStringList &tlns, bool forceComment) { - insertInternal(message, forceComment, message.isUtf8()); + insertInternal(message, tlns, forceComment, message.isUtf8()); if (message.isUtf8() && message.isNonUtf8()) - insertInternal(message, forceComment, false); + insertInternal(message, tlns, forceComment, false); } -void Releaser::insertIdBased(const TranslatorMessage &message) +void Releaser::insertIdBased(const TranslatorMessage &message, const QStringList &tlns) { - QStringList tlns = message.translations(); - for (int i = 0; i < tlns.size(); ++i) - if (tlns.at(i).isEmpty()) - tlns[i] = message.sourceText(); ByteTranslatorMessage bmsg("", originalBytes(message.id(), false), "", tlns); m_messages.insert(bmsg, 0); } @@ -687,6 +687,16 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) +static bool containsStripped(const Translator &translator, const TranslatorMessage &msg) +{ + foreach (const TranslatorMessage &tmsg, translator.messages()) + if (tmsg.sourceText() == msg.sourceText() + && tmsg.context() == msg.context() + && tmsg.comment().isEmpty()) + return true; + return false; +} + static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData &cd) { Releaser releaser; @@ -713,7 +723,7 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData continue; } if (typ == TranslatorMessage::Unfinished) { - if (msg.translation().isEmpty()) { + if (!cd.m_idBased && msg.translation().isEmpty()) { ++untranslated; continue; } else { @@ -724,10 +734,16 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData } else { ++finished; } + QStringList tlns = msg.translations(); + if (msg.type() == TranslatorMessage::Unfinished + && (cd.m_idBased || !cd.m_unTrPrefix.isEmpty())) + for (int j = 0; j < tlns.size(); ++j) + if (tlns.at(j).isEmpty()) + tlns[j] = cd.m_unTrPrefix + msg.sourceText(); if (cd.m_idBased) { if (!msg.context().isEmpty() || !msg.comment().isEmpty()) ++droppedData; - releaser.insertIdBased(msg); + releaser.insertIdBased(msg, tlns); } else { // Drop the comment in (context, sourceText, comment), // unless the context is empty, @@ -737,8 +753,8 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData bool forceComment = msg.comment().isEmpty() || msg.context().isEmpty() - || translator.contains(msg.context(), msg.sourceText(), QString()); - releaser.insert(msg, forceComment); + || containsStripped(translator, msg); + releaser.insert(msg, tlns, forceComment); } } } diff --git a/tools/linguist/shared/translator.cpp b/tools/linguist/shared/translator.cpp index cd670cc..05fc6e5 100644 --- a/tools/linguist/shared/translator.cpp +++ b/tools/linguist/shared/translator.cpp @@ -56,6 +56,16 @@ QT_BEGIN_NAMESPACE +#ifdef QT_BOOTSTRAPPED +QString QObject::tr(const char *sourceText, const char *, int n) +{ + QString ret = QString::fromLatin1(sourceText); + if (n >= 0) + ret.replace(QLatin1String("%n"), QString::number(n)); + return ret; +} +#endif + Translator::Translator() : m_codecName("ISO-8859-1"), m_locationsType(AbsoluteLocations) @@ -80,18 +90,9 @@ QList<Translator::FileFormat> &Translator::registeredFileFormats() return theFormats; } -void Translator::replace(const TranslatorMessage &msg) -{ - int index = m_messages.indexOf(msg); - if (index == -1) - m_messages.append(msg); - else - m_messages[index] = msg; -} - void Translator::replaceSorted(const TranslatorMessage &msg) { - int index = m_messages.indexOf(msg); + int index = find(msg); if (index == -1) appendSorted(msg); else @@ -100,7 +101,7 @@ void Translator::replaceSorted(const TranslatorMessage &msg) void Translator::extend(const TranslatorMessage &msg) { - int index = m_messages.indexOf(msg); + int index = find(msg); if (index == -1) { m_messages.append(msg); } else { @@ -145,7 +146,7 @@ void Translator::appendSorted(const TranslatorMessage &msg) int prevLine = 0; int curIdx = 0; foreach (const TranslatorMessage &mit, m_messages) { - bool sameFile = mit.fileName() == msg.fileName(); + bool sameFile = mit.fileName() == msg.fileName() && mit.context() == msg.context(); int curLine; if (sameFile && (curLine = mit.lineNumber()) >= prevLine) { if (msgLine >= prevLine && msgLine < curLine) { @@ -311,19 +312,21 @@ bool Translator::release(QFile *iod, ConversionData &cd) const return false; } -bool Translator::contains(const QString &context, - const QString &sourceText, const QString &comment) const -{ - return m_messages.contains(TranslatorMessage(context, sourceText, comment, - QString(), QString(), 0)); -} - -TranslatorMessage Translator::find(const QString &context, - const QString &sourceText, const QString &comment) const +int Translator::find(const TranslatorMessage &msg) const { - TranslatorMessage needle(context, sourceText, comment, QString(), QString(), 0); - int index = m_messages.indexOf(needle); - return index == -1 ? TranslatorMessage() : m_messages.at(index); + for (int i = 0; i < m_messages.count(); ++i) { + const TranslatorMessage &tmsg = m_messages.at(i); + if (msg.id().isEmpty() || tmsg.id().isEmpty()) { + if (msg.context() == tmsg.context() + && msg.sourceText() == tmsg.sourceText() + && msg.comment() == tmsg.comment()) + return i; + } else { + if (msg.id() == tmsg.id()) + return i; + } + } + return -1; } TranslatorMessage Translator::find(const QString &context, @@ -344,7 +347,7 @@ TranslatorMessage Translator::find(const QString &context, bool Translator::contains(const QString &context) const { foreach (const TranslatorMessage &msg, m_messages) - if (msg.context() == context && msg.sourceText().isEmpty()) + if (msg.context() == context && msg.sourceText().isEmpty() && msg.id().isEmpty()) return true; return false; } @@ -352,7 +355,7 @@ bool Translator::contains(const QString &context) const TranslatorMessage Translator::find(const QString &context) const { foreach (const TranslatorMessage &msg, m_messages) - if (msg.context() == context && msg.sourceText().isEmpty()) + if (msg.context() == context && msg.sourceText().isEmpty() && msg.id().isEmpty()) return msg; return TranslatorMessage(); } @@ -435,49 +438,143 @@ void Translator::dropUiLines() } } -QSet<TranslatorMessagePtr> Translator::resolveDuplicates() +struct TranslatorMessageIdPtr { + explicit TranslatorMessageIdPtr(const TranslatorMessage &tm) + { + ptr = &tm; + } + + inline const TranslatorMessage *operator->() const + { + return ptr; + } + + const TranslatorMessage *ptr; +}; + +Q_DECLARE_TYPEINFO(TranslatorMessageIdPtr, Q_MOVABLE_TYPE); + +inline int qHash(TranslatorMessageIdPtr tmp) { - QSet<TranslatorMessagePtr> dups; - QHash<TranslatorMessagePtr, int> refs; + return qHash(tmp->id()); +} + +inline bool operator==(TranslatorMessageIdPtr tmp1, TranslatorMessageIdPtr tmp2) +{ + return tmp1->id() == tmp2->id(); +} + +struct TranslatorMessageContentPtr { + explicit TranslatorMessageContentPtr(const TranslatorMessage &tm) + { + ptr = &tm; + } + + inline const TranslatorMessage *operator->() const + { + return ptr; + } + + const TranslatorMessage *ptr; +}; + +Q_DECLARE_TYPEINFO(TranslatorMessageContentPtr, Q_MOVABLE_TYPE); + +inline int qHash(TranslatorMessageContentPtr tmp) +{ + int hash = qHash(tmp->context()) ^ qHash(tmp->sourceText()); + if (!tmp->sourceText().isEmpty()) + // Special treatment for context comments (empty source). + hash ^= qHash(tmp->comment()); + return hash; +} + +inline bool operator==(TranslatorMessageContentPtr tmp1, TranslatorMessageContentPtr tmp2) +{ + if (tmp1->context() != tmp2->context() || tmp1->sourceText() != tmp2->sourceText()) + return false; + // Special treatment for context comments (empty source). + if (tmp1->sourceText().isEmpty()) + return true; + return tmp1->comment() == tmp2->comment(); +} + +Translator::Duplicates Translator::resolveDuplicates() +{ + Duplicates dups; + QHash<TranslatorMessageIdPtr, int> idRefs; + QHash<TranslatorMessageContentPtr, int> contentRefs; 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); + TranslatorMessage *omsg; + int oi; + QSet<int> *pDup; + if (!msg.id().isEmpty()) { + QHash<TranslatorMessageIdPtr, int>::ConstIterator it = + idRefs.constFind(TranslatorMessageIdPtr(msg)); + if (it != idRefs.constEnd()) { + oi = *it; + omsg = &m_messages[oi]; + pDup = &dups.byId; + goto gotDupe; } - if (!omsg.isTranslated() && msg.isTranslated()) - omsg.setTranslations(msg.translations()); - m_messages.removeAt(i); + } + { + QHash<TranslatorMessageContentPtr, int>::ConstIterator it = + contentRefs.constFind(TranslatorMessageContentPtr(msg)); + if (it != contentRefs.constEnd()) { + oi = *it; + omsg = &m_messages[oi]; + if (msg.id().isEmpty() || omsg->id().isEmpty()) { + if (!msg.id().isEmpty() && omsg->id().isEmpty()) { + omsg->setId(msg.id()); + idRefs[TranslatorMessageIdPtr(*omsg)] = oi; + } + pDup = &dups.byContents; + goto gotDupe; + } + // This is really a content dupe, but with two distinct IDs. + } + } + if (!msg.id().isEmpty()) + idRefs[TranslatorMessageIdPtr(msg)] = i; + contentRefs[TranslatorMessageContentPtr(msg)] = i; + ++i; + continue; + gotDupe: + if (omsg->isUtf8() != msg.isUtf8() && !omsg->isNonUtf8()) { + // Dual-encoded message + omsg->setUtf8(true); + omsg->setNonUtf8(true); } else { - refs[msg] = i; - ++i; + // Duplicate + pDup->insert(oi); } + if (!omsg->isTranslated() && msg.isTranslated()) + omsg->setTranslations(msg.translations()); + m_messages.removeAt(i); } return dups; } -void Translator::reportDuplicates(const QSet<TranslatorMessagePtr> &dupes, +void Translator::reportDuplicates(const Duplicates &dupes, const QString &fileName, bool verbose) { - if (!dupes.isEmpty()) { + if (!dupes.byId.isEmpty() || !dupes.byContents.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) { + foreach (int i, dupes.byId) + qWarning("\n* ID: %s", qPrintable(message(i).id())); + foreach (int j, dupes.byContents) { + const TranslatorMessage &msg = message(j); qWarning("\n* Context: %s\n* Source: %s", - qPrintable(msg->context()), - qPrintable(msg->sourceText())); - if (!msg->comment().isEmpty()) - qWarning("* Comment: %s", qPrintable(msg->comment())); + qPrintable(msg.context()), + qPrintable(msg.sourceText())); + if (!msg.comment().isEmpty()) + qWarning("* Comment: %s", qPrintable(msg.comment())); } qWarning(); } diff --git a/tools/linguist/shared/translator.h b/tools/linguist/shared/translator.h index 1dd6a59..f29317b 100644 --- a/tools/linguist/shared/translator.h +++ b/tools/linguist/shared/translator.h @@ -54,6 +54,18 @@ QT_BEGIN_NAMESPACE +#ifdef QT_BOOTSTRAPPED +struct QObject { + static QString tr(const char *sourceText, const char * = 0, int n = -1); +}; +struct QCoreApplication : public QObject { + enum Encoding { CodecForTr }; + static QString translate(const char *, const char *sourceText, const char * = 0, + Encoding = CodecForTr, int n = -1) + { return tr(sourceText, 0, n); } +}; +#endif + class QIODevice; // A struct of "interesting" data passed to and from the load and save routines @@ -86,6 +98,7 @@ public: QString m_defaultContext; QByteArray m_codecForSource; // CPP, PO & QM specific QByteArray m_outputCodec; // PO specific + QString m_unTrPrefix; // QM specific QString m_sourceFileName; QString m_targetFileName; QDir m_sourceDir; @@ -112,18 +125,13 @@ public: bool save(const QString &filename, ConversionData &err, const QString &format /*= "auto"*/) const; bool release(QFile *iod, ConversionData &cd) const; - bool contains(const QString &context, const QString &sourceText, - const QString &comment) const; - TranslatorMessage find(const QString &context, - const QString &sourceText, const QString &comment) const; - + int find(const TranslatorMessage &msg) const; TranslatorMessage find(const QString &context, const QString &comment, const TranslatorMessage::References &refs) const; bool contains(const QString &context) const; TranslatorMessage find(const QString &context) const; - void replace(const TranslatorMessage &msg); void replaceSorted(const TranslatorMessage &msg); void extend(const TranslatorMessage &msg); // Only for single-location messages void append(const TranslatorMessage &msg); @@ -137,9 +145,10 @@ public: void dropTranslations(); void dropUiLines(); void makeFileNamesAbsolute(const QDir &originalPath); - QSet<TranslatorMessagePtr> resolveDuplicates(); - static void reportDuplicates(const QSet<TranslatorMessagePtr> &dupes, - const QString &fileName, bool verbose); + + struct Duplicates { QSet<int> byId, byContents; }; + Duplicates resolveDuplicates(); + void reportDuplicates(const Duplicates &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 417f6b1..5151ebd 100644 --- a/tools/linguist/shared/translatormessage.cpp +++ b/tools/linguist/shared/translatormessage.cpp @@ -143,36 +143,6 @@ bool TranslatorMessage::needs8Bit() const } -bool TranslatorMessage::operator==(const TranslatorMessage& m) const -{ - static QString msgIdPlural = QLatin1String("po-msgid_plural"); - - // Special treatment for context comments (empty source). - return (m_context == m.m_context) - && m_sourcetext == m.m_sourcetext - && m_extra[msgIdPlural] == m.m_extra[msgIdPlural] - && (m_sourcetext.isEmpty() || m_comment == m.m_comment); -} - - -bool TranslatorMessage::operator<(const TranslatorMessage& 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; -} - -int qHash(const TranslatorMessage &msg) -{ - return - qHash(msg.context()) ^ - qHash(msg.sourceText()) ^ - qHash(msg.extra(QLatin1String("po-msgid_plural"))) ^ - qHash(msg.comment()); -} - bool TranslatorMessage::hasExtra(const QString &key) const { return m_extra.contains(key); diff --git a/tools/linguist/shared/translatormessage.h b/tools/linguist/shared/translatormessage.h index 675bba7..60b60c5 100644 --- a/tools/linguist/shared/translatormessage.h +++ b/tools/linguist/shared/translatormessage.h @@ -109,9 +109,6 @@ public: return false; } - bool operator==(const TranslatorMessage& m) const; - bool operator<(const TranslatorMessage& m) const; - QString fileName() const { return m_fileName; } void setFileName(const QString &fileName) { m_fileName = fileName; } int lineNumber() const { return m_lineNumber; } @@ -177,34 +174,6 @@ private: 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/makeqpf/mainwindow.cpp b/tools/makeqpf/mainwindow.cpp index 8fa372b..45ea0a3 100644 --- a/tools/makeqpf/mainwindow.cpp +++ b/tools/makeqpf/mainwindow.cpp @@ -269,7 +269,7 @@ void MainWindow::populateCharacterRanges() if (line.isEmpty() || line.startsWith(QLatin1Char('#'))) continue; - if (!rangeExpr.exactMatch(line) || rangeExpr.numCaptures() != 3) + if (!rangeExpr.exactMatch(line) || rangeExpr.captureCount() != 3) continue; QPF::CharacterRange range; diff --git a/tools/makeqpf/qpf2.cpp b/tools/makeqpf/qpf2.cpp index 23006f0..a0af1a0 100644 --- a/tools/makeqpf/qpf2.cpp +++ b/tools/makeqpf/qpf2.cpp @@ -519,7 +519,7 @@ void QPF::addGlyphs(QFontEngine *fe, const QList<CharacterRange> &ranges) glyph_metrics_t metrics = fe->boundingBox(glyphIndex); const quint32 oldSize = glyphs.size(); - glyphs.resize(glyphs.size() + sizeof(QFontEngineQPF::Glyph) + img.numBytes()); + glyphs.resize(glyphs.size() + sizeof(QFontEngineQPF::Glyph) + img.byteCount()); uchar *data = reinterpret_cast<uchar *>(glyphs.data() + oldSize); uchar *gmapPtr = reinterpret_cast<uchar *>(gmap.data() + glyphIndex * sizeof(quint32)); @@ -543,7 +543,7 @@ void QPF::addGlyphs(QFontEngine *fe, const QList<CharacterRange> &ranges) ; } - qMemCopy(data, img.bits(), img.numBytes()); + qMemCopy(data, img.bits(), img.byteCount()); } } } diff --git a/tools/qdoc3/codemarker.cpp b/tools/qdoc3/codemarker.cpp index a9da841..c8c92ec 100644 --- a/tools/qdoc3/codemarker.cpp +++ b/tools/qdoc3/codemarker.cpp @@ -602,10 +602,10 @@ QString CodeMarker::macName(const Node *node, const QString &name) } if (node->name().isEmpty()) { - return QLatin1Char('/') + myName; + return QLatin1Char('/') + protect(myName); } else { - return plainFullName(node) + QLatin1Char('/') + myName; + return plainFullName(node) + QLatin1Char('/') + protect(myName); } } diff --git a/tools/qdoc3/config.h b/tools/qdoc3/config.h index 07cdb59..725129a 100644 --- a/tools/qdoc3/config.h +++ b/tools/qdoc3/config.h @@ -162,6 +162,10 @@ class Config #define CONFIG_FILEEXTENSIONS "fileextensions" +#ifdef QDOC_QML +#define CONFIG_QMLONLY "qmlonly" +#endif + QT_END_NAMESPACE #endif diff --git a/tools/qdoc3/cppcodemarker.cpp b/tools/qdoc3/cppcodemarker.cpp index ed3d150..a8f6a02 100644 --- a/tools/qdoc3/cppcodemarker.cpp +++ b/tools/qdoc3/cppcodemarker.cpp @@ -194,6 +194,8 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node, synopsis = "class " + name; break; case Node::Function: + case Node::QmlSignal: + case Node::QmlMethod: func = (const FunctionNode *) node; if (style != SeparateList && !func->returnType().isEmpty()) synopsis = typified(func->returnType()) + " "; @@ -353,6 +355,10 @@ QString CppCodeMarker::markedUpQmlItem(const Node* node, bool summary) QString name = taggedQmlNode(node); if (summary) { name = linkTag(node,name); + } else if (node->type() == Node::QmlProperty) { + const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(node); + if (pn->isAttached()) + name.prepend(pn->element() + QLatin1Char('.')); } name = "<@name>" + name + "</@name>"; QString synopsis = name; @@ -1109,17 +1115,29 @@ QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, if (qmlClassNode) { if (style == Summary) { FastSection qmlproperties(qmlClassNode, - "QML Properties", + "Properties", "property", "properties"); + FastSection qmlattachedproperties(qmlClassNode, + "Attached Properties", + "property", + "properties"); FastSection qmlsignals(qmlClassNode, - "QML Signals", + "Signals", "signal", "signals"); + FastSection qmlattachedsignals(qmlClassNode, + "QML Attached Signals", + "signal", + "signals"); FastSection qmlmethods(qmlClassNode, - "QML Methods", + "Methods", "method", "methods"); + FastSection qmlattachedmethods(qmlClassNode, + "QML Attached Methods", + "method", + "methods"); NodeList::ConstIterator c = qmlClassNode->childNodes().begin(); while (c != qmlClassNode->childNodes().end()) { @@ -1128,43 +1146,76 @@ QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, NodeList::ConstIterator p = qpgn->childNodes().begin(); while (p != qpgn->childNodes().end()) { if ((*p)->type() == Node::QmlProperty) { - insert(qmlproperties,*p,style,Okay); + const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*p); + if (pn->isAttached()) + insert(qmlattachedproperties,*p,style,Okay); + else + insert(qmlproperties,*p,style,Okay); } ++p; } } else if ((*c)->type() == Node::QmlSignal) { - insert(qmlsignals,*c,style,Okay); + const FunctionNode* sn = static_cast<const FunctionNode*>(*c); + if (sn->isAttached()) + insert(qmlattachedsignals,*c,style,Okay); + else + insert(qmlsignals,*c,style,Okay); } else if ((*c)->type() == Node::QmlMethod) { - insert(qmlmethods,*c,style,Okay); + const FunctionNode* mn = static_cast<const FunctionNode*>(*c); + if (mn->isAttached()) + insert(qmlattachedmethods,*c,style,Okay); + else + insert(qmlmethods,*c,style,Okay); } ++c; } append(sections,qmlproperties); + append(sections,qmlattachedproperties); append(sections,qmlsignals); + append(sections,qmlattachedsignals); append(sections,qmlmethods); + append(sections,qmlattachedmethods); } else if (style == Detailed) { - FastSection qmlproperties(qmlClassNode,"QML Property Documentation"); - FastSection qmlsignals(qmlClassNode,"QML Signal Documentation"); - FastSection qmlmethods(qmlClassNode,"QML Method Documentation"); + FastSection qmlproperties(qmlClassNode, "Property Documentation"); + FastSection qmlattachedproperties(qmlClassNode,"Attached Property Documentation"); + FastSection qmlsignals(qmlClassNode,"Signal Documentation"); + FastSection qmlattachedsignals(qmlClassNode,"Attached Signal Documentation"); + FastSection qmlmethods(qmlClassNode,"Method Documentation"); + FastSection qmlattachedmethods(qmlClassNode,"Attached Method Documentation"); NodeList::ConstIterator c = qmlClassNode->childNodes().begin(); while (c != qmlClassNode->childNodes().end()) { if ((*c)->subType() == Node::QmlPropertyGroup) { - insert(qmlproperties,*c,style,Okay); + const QmlPropGroupNode* pgn = static_cast<const QmlPropGroupNode*>(*c); + if (pgn->isAttached()) + insert(qmlattachedproperties,*c,style,Okay); + else + insert(qmlproperties,*c,style,Okay); } else if ((*c)->type() == Node::QmlSignal) { - insert(qmlsignals,*c,style,Okay); + const FunctionNode* sn = static_cast<const FunctionNode*>(*c); + if (sn->isAttached()) + insert(qmlattachedsignals,*c,style,Okay); + else + insert(qmlsignals,*c,style,Okay); } else if ((*c)->type() == Node::QmlMethod) { - insert(qmlmethods,*c,style,Okay); + const FunctionNode* mn = static_cast<const FunctionNode*>(*c); + if (mn->isAttached()) + insert(qmlattachedmethods,*c,style,Okay); + else + insert(qmlmethods,*c,style,Okay); } ++c; } append(sections,qmlproperties); + append(sections,qmlattachedproperties); append(sections,qmlsignals); + append(sections,qmlattachedsignals); append(sections,qmlmethods); + append(sections,qmlattachedmethods); } } diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index d93e24c..ce71e51 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -88,9 +88,12 @@ QT_BEGIN_NAMESPACE #ifdef QDOC_QML #define COMMAND_QMLCLASS Doc::alias("qmlclass") #define COMMAND_QMLPROPERTY Doc::alias("qmlproperty") +#define COMMAND_QMLATTACHEDPROPERTY Doc::alias("qmlattachedproperty") #define COMMAND_QMLINHERITS Doc::alias("inherits") #define COMMAND_QMLSIGNAL Doc::alias("qmlsignal") +#define COMMAND_QMLATTACHEDSIGNAL Doc::alias("qmlattachedsignal") #define COMMAND_QMLMETHOD Doc::alias("qmlmethod") +#define COMMAND_QMLATTACHEDMETHOD Doc::alias("qmlattachedmethod") #define COMMAND_QMLDEFAULT Doc::alias("default") #endif @@ -482,8 +485,11 @@ QSet<QString> CppCodeParser::topicCommands() << COMMAND_VARIABLE << COMMAND_QMLCLASS << COMMAND_QMLPROPERTY + << COMMAND_QMLATTACHEDPROPERTY << COMMAND_QMLSIGNAL - << COMMAND_QMLMETHOD; + << COMMAND_QMLATTACHEDSIGNAL + << COMMAND_QMLMETHOD + << COMMAND_QMLATTACHEDMETHOD; #else << COMMAND_VARIABLE; #endif @@ -676,18 +682,26 @@ Node *CppCodeParser::processTopicCommand(const Doc& doc, return new QmlClassNode(tre->root(), names[0], classNode); } else if ((command == COMMAND_QMLSIGNAL) || - (command == COMMAND_QMLMETHOD)) { + (command == COMMAND_QMLMETHOD) || + (command == COMMAND_QMLATTACHEDSIGNAL) || + (command == COMMAND_QMLATTACHEDMETHOD)) { QString element; - QString name; + QString type; QmlClassNode* qmlClass = 0; - if (splitQmlArg(doc,arg,element,name)) { + if (splitQmlMethodArg(doc,arg,type,element)) { Node* n = tre->findNode(QStringList(element),Node::Fake); if (n && n->subType() == Node::QmlClass) { qmlClass = static_cast<QmlClassNode*>(n); if (command == COMMAND_QMLSIGNAL) - return new QmlSignalNode(qmlClass,name); + return makeFunctionNode(doc,arg,qmlClass,Node::QmlSignal,false,COMMAND_QMLSIGNAL); + else if (command == COMMAND_QMLATTACHEDSIGNAL) + return makeFunctionNode(doc,arg,qmlClass,Node::QmlSignal,true,COMMAND_QMLATTACHEDSIGNAL); + else if (command == COMMAND_QMLMETHOD) + return makeFunctionNode(doc,arg,qmlClass,Node::QmlMethod,false,COMMAND_QMLMETHOD); + else if (command == COMMAND_QMLATTACHEDMETHOD) + return makeFunctionNode(doc,arg,qmlClass,Node::QmlMethod,true,COMMAND_QMLATTACHEDMETHOD); else - return new QmlMethodNode(qmlClass,name); + return 0; // never get here. } } } @@ -703,15 +717,15 @@ Node *CppCodeParser::processTopicCommand(const Doc& doc, <type> <element>::<name> This function splits the argument into those three - parts, sets \a type, \a element, and \a property, + parts, sets \a type, \a element, and \a name, and returns true. If any of the parts isn't found, - a debug message is output and false is returned. + a qdoc warning is output and false is returned. */ bool CppCodeParser::splitQmlPropertyArg(const Doc& doc, const QString& arg, QString& type, QString& element, - QString& property) + QString& name) { QStringList blankSplit = arg.split(" "); if (blankSplit.size() > 1) { @@ -719,72 +733,99 @@ bool CppCodeParser::splitQmlPropertyArg(const Doc& doc, QStringList colonSplit(blankSplit[1].split("::")); if (colonSplit.size() > 1) { element = colonSplit[0]; - property = colonSplit[1]; + name = colonSplit[1]; return true; } else - doc.location().warning(tr("Missing QML element name or property name")); + doc.location().warning(tr("Missing parent QML element name")); } else - doc.location().warning(tr("Missing QML property type or property path")); + doc.location().warning(tr("Missing property type")); return false; } /*! A QML signal or method argument has the form... - <element>::<name> + <type> <element>::<name>(<param>, <param>, ...) This function splits the argument into those two parts, sets \a element, and \a name, and returns true. If either of the parts isn't found, a debug message is output and false is returned. */ -bool CppCodeParser::splitQmlArg(const Doc& doc, - const QString& arg, - QString& element, - QString& name) +bool CppCodeParser::splitQmlMethodArg(const Doc& doc, + const QString& arg, + QString& type, + QString& element) { QStringList colonSplit(arg.split("::")); if (colonSplit.size() > 1) { - element = colonSplit[0]; - name = colonSplit[1]; + QStringList blankSplit = colonSplit[0].split(" "); + if (blankSplit.size() > 1) { + type = blankSplit[0]; + element = blankSplit[1]; + } + else { + type = QString(""); + element = colonSplit[0]; + } return true; } else - doc.location().warning(tr("Missing QML element name or signal/method name")); + doc.location().warning(tr("Missing parent QML element or method signature")); return false; } /*! Process the topic \a command group with arguments \a args. - Currently, this function is called only for \e{qmlproperty}. + Currently, this function is called only for \e{qmlproperty} + and \e{qmlattachedproperty}. */ Node *CppCodeParser::processTopicCommandGroup(const Doc& doc, const QString& command, const QStringList& args) { QmlPropGroupNode* qmlPropGroup = 0; - if (command == COMMAND_QMLPROPERTY) { + if ((command == COMMAND_QMLPROPERTY) || + (command == COMMAND_QMLATTACHEDPROPERTY)) { QString type; QString element; QString property; + bool attached = (command == COMMAND_QMLATTACHEDPROPERTY); QStringList::ConstIterator arg = args.begin(); if (splitQmlPropertyArg(doc,(*arg),type,element,property)) { Node* n = tre->findNode(QStringList(element),Node::Fake); if (n && n->subType() == Node::QmlClass) { QmlClassNode* qmlClass = static_cast<QmlClassNode*>(n); if (qmlClass) - qmlPropGroup = new QmlPropGroupNode(qmlClass,property); + qmlPropGroup = new QmlPropGroupNode(qmlClass, + property, + attached); } } if (qmlPropGroup) { - new QmlPropertyNode(qmlPropGroup,property,type); + const ClassNode *correspondingClass = static_cast<const QmlClassNode*>(qmlPropGroup->parent())->classNode(); + PropertyNode *correspondingProperty = 0; + if (correspondingClass) + correspondingProperty = static_cast<PropertyNode*>((Node*)correspondingClass->findNode(property, Node::Property)); + QmlPropertyNode *qmlPropNode = new QmlPropertyNode(qmlPropGroup,property,type,attached); + if (correspondingProperty) { + bool writableList = type.startsWith("list") && correspondingProperty->dataType().endsWith('*'); + qmlPropNode->setWritable(writableList || correspondingProperty->isWritable()); + } ++arg; while (arg != args.end()) { if (splitQmlPropertyArg(doc,(*arg),type,element,property)) { - new QmlPropertyNode(qmlPropGroup,property,type); + QmlPropertyNode* qmlPropNode = new QmlPropertyNode(qmlPropGroup, + property, + type, + attached); + if (correspondingProperty) { + bool writableList = type.startsWith("list") && correspondingProperty->dataType().endsWith('*'); + qmlPropNode->setWritable(writableList || correspondingProperty->isWritable()); + } } ++arg; } @@ -1231,7 +1272,9 @@ bool CppCodeParser::matchParameter(FunctionNode *func) bool CppCodeParser::matchFunctionDecl(InnerNode *parent, QStringList *parentPathPtr, FunctionNode **funcPtr, - const QString &templateStuff) + const QString &templateStuff, + Node::Type type, + bool attached) { CodeChunk returnType; QStringList parentPath; @@ -1261,8 +1304,9 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, if (tokenizer->parsingFnOrMacro() && (match(Tok_Q_DECLARE_FLAGS) || match(Tok_Q_PROPERTY))) returnType = CodeChunk(previousLexeme()); - else + else { return false; + } } if (returnType.toString() == "QBool") @@ -1292,8 +1336,9 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, readToken(); } } - if (tok != Tok_LeftParen) + if (tok != Tok_LeftParen) { return false; + } } else if (tok == Tok_LeftParen) { // constructor or destructor @@ -1339,8 +1384,9 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, returnType.append(lexeme()); readToken(); } - if (tok != Tok_Semicolon) + if (tok != Tok_Semicolon) { return false; + } } else if (tok == Tok_Colon) { returnType.appendHotspot(); @@ -1349,8 +1395,9 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, returnType.append(lexeme()); readToken(); } - if (tok != Tok_Semicolon) + if (tok != Tok_Semicolon) { return false; + } } VariableNode *var = new VariableNode(parent, name); @@ -1363,12 +1410,13 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, var->setStatic(sta); return false; } - if (tok != Tok_LeftParen) + if (tok != Tok_LeftParen) { return false; + } } readToken(); - FunctionNode *func = new FunctionNode(parent, name); + FunctionNode *func = new FunctionNode(type, parent, name, attached); func->setAccess(access); func->setLocation(location()); func->setReturnType(returnType.toString()); @@ -1389,12 +1437,14 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, if (tok != Tok_RightParen) { do { - if (!matchParameter(func)) + if (!matchParameter(func)) { return false; + } } while (match(Tok_Comma)); } - if (!match(Tok_RightParen)) + if (!match(Tok_RightParen)) { return false; + } func->setConst(match(Tok_const)); @@ -1410,8 +1460,9 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, if (!match(Tok_Semicolon) && tok != Tok_Eoi) { int braceDepth0 = tokenizer->braceDepth(); - if (!match(Tok_LeftBrace)) + if (!match(Tok_LeftBrace)) { return false; + } while (tokenizer->braceDepth() >= braceDepth0 && tok != Tok_Eoi) readToken(); match(Tok_RightBrace); @@ -1729,15 +1780,15 @@ bool CppCodeParser::matchProperty(InnerNode *parent) if (key == "READ") tre->addPropertyFunction(property, value, PropertyNode::Getter); - else if (key == "WRITE") + else if (key == "WRITE") { tre->addPropertyFunction(property, value, PropertyNode::Setter); - else if (key == "STORED") + property->setWritable(true); + } else if (key == "STORED") property->setStored(value.toLower() == "true"); else if (key == "DESIGNABLE") property->setDesignable(value.toLower() == "true"); else if (key == "RESET") tre->addPropertyFunction(property, value, PropertyNode::Resetter); - else if (key == "NOTIFY") { tre->addPropertyFunction(property, value, PropertyNode::Notifier); } @@ -1969,7 +2020,8 @@ bool CppCodeParser::matchDocsAndStuff() There is a topic command. Process it. */ #ifdef QDOC_QML - if (topic == COMMAND_QMLPROPERTY) { + if ((topic == COMMAND_QMLPROPERTY) || + (topic == COMMAND_QMLATTACHEDPROPERTY)) { Doc nodeDoc = doc; Node *node = processTopicCommandGroup(nodeDoc,topic,args); if (node != 0) { @@ -2057,7 +2109,9 @@ bool CppCodeParser::matchDocsAndStuff() bool CppCodeParser::makeFunctionNode(const QString& synopsis, QStringList *parentPathPtr, FunctionNode **funcPtr, - InnerNode *root) + InnerNode *root, + Node::Type type, + bool attached) { Tokenizer *outerTokenizer = tokenizer; int outerTok = tok; @@ -2069,15 +2123,39 @@ bool CppCodeParser::makeFunctionNode(const QString& synopsis, tokenizer = &stringTokenizer; readToken(); - bool ok = matchFunctionDecl(root, parentPathPtr, funcPtr); + bool ok = matchFunctionDecl(root, parentPathPtr, funcPtr, QString(), type, attached); // potential memory leak with funcPtr tokenizer = outerTokenizer; tok = outerTok; - return ok; } +/*! + Create a new FunctionNode for a QML method or signal, as + specified by \a type, as a child of \a parent. \a sig is + the complete signature, and if \a attached is true, the + method or signal is "attached". \a qdoctag is the text of + the \a type. + */ +FunctionNode* CppCodeParser::makeFunctionNode(const Doc& doc, + const QString& sig, + InnerNode* parent, + Node::Type type, + bool attached, + QString qdoctag) +{ + QStringList pp; + FunctionNode* fn = 0; + if (!makeFunctionNode(sig,&pp,&fn,parent,type,attached) && + !makeFunctionNode("void "+sig,&pp,&fn,parent,type,attached)) { + doc.location().warning(tr("Invalid syntax in '\\%1'").arg(qdoctag)); + } + if (fn) + return fn; + return 0; +} + void CppCodeParser::parseQiteratorDotH(const Location &location, const QString &filePath) { diff --git a/tools/qdoc3/cppcodeparser.h b/tools/qdoc3/cppcodeparser.h index 233ac09..e2e9d55 100644 --- a/tools/qdoc3/cppcodeparser.h +++ b/tools/qdoc3/cppcodeparser.h @@ -99,11 +99,11 @@ class CppCodeParser : public CodeParser const QString& arg, QString& type, QString& element, - QString& property); - bool splitQmlArg(const Doc& doc, - const QString& arg, - QString& element, - QString& name); + QString& name); + bool splitQmlMethodArg(const Doc& doc, + const QString& arg, + QString& type, + QString& element); #endif virtual QSet<QString> otherMetaCommands(); virtual void processOtherMetaCommand(const Doc& doc, @@ -127,7 +127,9 @@ class CppCodeParser : public CodeParser bool matchFunctionDecl(InnerNode *parent, QStringList *parentPathPtr = 0, FunctionNode **funcPtr = 0, - const QString &templateStuff = QString()); + const QString &templateStuff = QString(), + Node::Type type = Node::Function, + bool attached = false); bool matchBaseSpecifier(ClassNode *classe, bool isClass); bool matchBaseList(ClassNode *classe, bool isClass); bool matchClassDecl(InnerNode *parent, @@ -143,7 +145,15 @@ class CppCodeParser : public CodeParser bool makeFunctionNode(const QString &synopsis, QStringList *parentPathPtr, FunctionNode **funcPtr, - InnerNode *root = 0); + InnerNode *root = 0, + Node::Type type = Node::Function, + bool attached = false); + FunctionNode* makeFunctionNode(const Doc& doc, + const QString& sig, + InnerNode* parent, + Node::Type type, + bool attached, + QString qdoctag); void parseQiteratorDotH(const Location &location, const QString &filePath); void instantiateIteratorMacro(const QString &container, const QString &includeFile, diff --git a/tools/qdoc3/doc.cpp b/tools/qdoc3/doc.cpp index 748390f..f4931b8 100644 --- a/tools/qdoc3/doc.cpp +++ b/tools/qdoc3/doc.cpp @@ -2841,6 +2841,10 @@ void Doc::initialize(const Config& config) DocParser::sourceDirs = config.getStringList(CONFIG_SOURCEDIRS); DocParser::quoting = config.getBool(CONFIG_QUOTINGINFORMATION); +#ifdef QDOC_QML + QmlClassNode::qmlOnly = config.getBool(CONFIG_QMLONLY); +#endif + QStringMap reverseAliasMap; QSet<QString> commands = config.subVars(CONFIG_ALIAS); diff --git a/tools/qdoc3/helpprojectwriter.cpp b/tools/qdoc3/helpprojectwriter.cpp index 4973387..52f54c0 100644 --- a/tools/qdoc3/helpprojectwriter.cpp +++ b/tools/qdoc3/helpprojectwriter.cpp @@ -187,8 +187,16 @@ QStringList HelpProjectWriter::keywordDetails(const Node *node) const details << node->parent()->name()+"::"+node->name(); } else if (node->type() == Node::Fake) { const FakeNode *fake = static_cast<const FakeNode *>(node); - details << fake->fullTitle(); - details << fake->fullTitle(); +#ifdef QDOC_QML + if (fake->subType() == Node::QmlClass) { + details << (QmlClassNode::qmlOnly ? fake->name() : fake->fullTitle()); + details << "QML." + fake->name(); + } else +#endif + { + details << fake->fullTitle(); + details << fake->fullTitle(); + } } else { details << node->name(); details << node->name(); diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index c02dc2e..8711c6b 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -1240,7 +1240,7 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner, generateHeader(title, inner, marker, true); generateTitle(title, subtitleText, SmallSubTitle, inner, marker); -#ifdef QDOC_QML +#ifdef QDOC_QML if (classe && !classe->qmlElement().isEmpty()) { generateInstantiatedBy(classe,marker); } @@ -2300,7 +2300,8 @@ void HtmlGenerator::generateCompactList(const Node *relative, << " </b>"; } out() << "</td>\n"; - + + out() << "<td>"; if ((currentParagraphNo[i] < NumParagraphs) && !paragraphName[currentParagraphNo[i]].isEmpty()) { NodeMap::Iterator it; @@ -2308,7 +2309,6 @@ void HtmlGenerator::generateCompactList(const Node *relative, for (j = 0; j < currentOffsetInParagraph[i]; j++) ++it; - out() << "<td>"; // Previously, we used generateFullName() for this, but we // require some special formatting. out() << "<a href=\"" @@ -2322,8 +2322,8 @@ void HtmlGenerator::generateCompactList(const Node *relative, generateFullName(it.value()->parent(), relative, marker); out() << ")"; } - out() << "</td>\n"; - } + } + out() << "</td>\n"; currentOffset[i]++; currentOffsetInParagraph[i]++; @@ -3467,13 +3467,16 @@ QString HtmlGenerator::refForNode(const Node *node) ref += "-" + QString::number(func->overloadNumber()); } break; - case Node::Property: #ifdef QDOC_QML + case Node::Fake: + if (node->subType() != Node::QmlPropertyGroup) + break; case Node::QmlProperty: #endif + case Node::Property: ref = node->name() + "-prop"; break; -#ifdef QDOC_QML +#ifdef QDOC_QML case Node::QmlSignal: ref = node->name() + "-signal"; break; @@ -3512,9 +3515,9 @@ QString HtmlGenerator::linkForNode(const Node *node, const Node *relative) // ### reintroduce this test, without breaking .dcf files if (fn != outFileName()) #endif - link += fn; + link += fn; - if (!node->isInnerNode()) { + if (!node->isInnerNode() || node->subType() == Node::QmlPropertyGroup) { ref = refForNode(node); if (relative && fn == fileName(relative) && ref == refForNode(relative)) return QString(); @@ -4077,7 +4080,7 @@ void HtmlGenerator::generateMacRef(const Node *node, CodeMarker *marker) QStringList macRefs = marker->macRefsForNode(node); foreach (const QString &macRef, macRefs) - out() << "<a name=\"" << "//apple_ref/" << macRef << "\" />\n"; + out() << "<a name=\"" << "//apple_ref/" << macRef << "\"></a>\n"; } void HtmlGenerator::beginLink(const QString &link, @@ -4189,13 +4192,15 @@ void HtmlGenerator::generateDetailedQmlMember(const Node *node, const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node); NodeList::ConstIterator p = qpgn->childNodes().begin(); out() << "<div class=\"qmlproto\">"; - out() << "<table class=\"qmlname\">"; + out() << "<table width=\"100%\" class=\"qmlname\">"; while (p != qpgn->childNodes().end()) { if ((*p)->type() == Node::QmlProperty) { qpn = static_cast<const QmlPropertyNode*>(*p); out() << "<tr><td>"; out() << "<a name=\"" + refForNode(qpn) + "\"></a>"; + if (!qpn->isWritable()) + out() << "<span class=\"qmlreadonly\">read-only</span>"; generateQmlItem(qpn, relative, marker, false); out() << "</td></tr>"; if (qpgn->isDefault()) { @@ -4214,23 +4219,24 @@ void HtmlGenerator::generateDetailedQmlMember(const Node *node, out() << "</div>"; } else if (node->type() == Node::QmlSignal) { - const QmlSignalNode* qsn = static_cast<const QmlSignalNode*>(node); + const FunctionNode* qsn = static_cast<const FunctionNode*>(node); out() << "<div class=\"qmlproto\">"; out() << "<table class=\"qmlname\">"; out() << "<tr><td>"; out() << "<a name=\"" + refForNode(qsn) + "\"></a>"; - generateQmlItem(qsn,relative,marker,false); + generateSynopsis(qsn,relative,marker,CodeMarker::Detailed,false); + //generateQmlItem(qsn,relative,marker,false); out() << "</td></tr>"; out() << "</table>"; out() << "</div>"; } else if (node->type() == Node::QmlMethod) { - const QmlMethodNode* qmn = static_cast<const QmlMethodNode*>(node); + const FunctionNode* qmn = static_cast<const FunctionNode*>(node); out() << "<div class=\"qmlproto\">"; out() << "<table class=\"qmlname\">"; out() << "<tr><td>"; out() << "<a name=\"" + refForNode(qmn) + "\"></a>"; - generateQmlItem(qmn,relative,marker,false); + generateSynopsis(qmn,relative,marker,CodeMarker::Detailed,false); out() << "</td></tr>"; out() << "</table>"; out() << "</div>"; @@ -4276,7 +4282,7 @@ void HtmlGenerator::generateQmlInherits(const QmlClassNode* cn, } /*! - Output the "[Xxx instantiates the C++ class QFxXxx]" + Output the "[Xxx instantiates the C++ class QmlGraphicsXxx]" line for the QML element, if there should be one. If there is no class node, or if the class node status @@ -4306,7 +4312,7 @@ void HtmlGenerator::generateQmlInstantiates(const QmlClassNode* qcn, } /*! - Output the "[QFxXxx is instantiated by QML element Xxx]" + Output the "[QmlGraphicsXxx is instantiated by QML element Xxx]" line for the class, if there should be one. If there is no QML element, or if the class node status diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp index 558808f..373002c 100644 --- a/tools/qdoc3/node.cpp +++ b/tools/qdoc3/node.cpp @@ -218,6 +218,7 @@ Node *InnerNode::findNode(const QString& name, Type type) } /*! + Find the function node in this node for the function named \a name. */ FunctionNode *InnerNode::findFunctionNode(const QString& name) { @@ -225,6 +226,7 @@ FunctionNode *InnerNode::findFunctionNode(const QString& name) } /*! + Find the function node in this node that has the same name as \a clone. */ FunctionNode *InnerNode::findFunctionNode(const FunctionNode *clone) { @@ -248,6 +250,34 @@ FunctionNode *InnerNode::findFunctionNode(const FunctionNode *clone) } /*! + Returns the list of keys from the primary function map. + */ +QStringList InnerNode::primaryKeys() +{ + QStringList t; + QMap<QString, Node*>::iterator i = primaryFunctionMap.begin(); + while (i != primaryFunctionMap.end()) { + t.append(i.key()); + ++i; + } + return t; +} + +/*! + Returns the list of keys from the secondary function map. + */ +QStringList InnerNode::secondaryKeys() +{ + QStringList t; + QMap<QString, NodeList>::iterator i = secondaryFunctionMap.begin(); + while (i != secondaryFunctionMap.end()) { + t.append(i.key()); + ++i; + } + return t; +} + +/*! */ void InnerNode::setOverload(const FunctionNode *func, bool overlode) { @@ -392,6 +422,7 @@ const Node *InnerNode::findNode(const QString& name, Type type) const } /*! + Find the function node in this node that has the given \a name. */ const FunctionNode *InnerNode::findFunctionNode(const QString& name) const { @@ -400,9 +431,9 @@ const FunctionNode *InnerNode::findFunctionNode(const QString& name) const } /*! + Find the function node in this node that has the same name as \a clone. */ -const FunctionNode *InnerNode::findFunctionNode( - const FunctionNode *clone) const +const FunctionNode *InnerNode::findFunctionNode(const FunctionNode *clone) const { InnerNode *that = (InnerNode *) this; return that->findFunctionNode(clone); @@ -520,7 +551,7 @@ bool InnerNode::isSameSignature(const FunctionNode *f1, const FunctionNode *f2) void InnerNode::addChild(Node *child) { children.append(child); - if (child->type() == Function) { + if ((child->type() == Function) || (child->type() == QmlMethod)) { FunctionNode *func = (FunctionNode *) child; if (!primaryFunctionMap.contains(func->name())) { primaryFunctionMap.insert(func->name(), func); @@ -896,11 +927,40 @@ QString Parameter::reconstruct(bool value) const */ /*! + Construct a function node for a C++ function. It's parent + is \a parent, and it's name is \a name. */ FunctionNode::FunctionNode(InnerNode *parent, const QString& name) - : LeafNode(Function, parent, name), met(Plain), vir(NonVirtual), - con(false), sta(false), ove(false), rf(0), ap(0) + : LeafNode(Function, parent, name), + met(Plain), + vir(NonVirtual), + con(false), + sta(false), + ove(false), + att(false), + rf(0), + ap(0) +{ + // nothing. +} + +/*! + Construct a function node for a QML method or signal, specified + by \a type. It's parent is \a parent, and it's name is \a name. + If \a attached is true, it is an attached method or signal. + */ +FunctionNode::FunctionNode(Type type, InnerNode *parent, const QString& name, bool attached) + : LeafNode(type, parent, name), + met(Plain), + vir(NonVirtual), + con(false), + sta(false), + ove(false), + att(attached), + rf(0), + ap(0) { + // nothing. } /*! @@ -1034,6 +1094,13 @@ QString FunctionNode::signature(bool values) const return s; } +/*! + Print some debugging stuff. + */ +void FunctionNode::debug() const +{ + qDebug() << "QML METHOD" << name() << "rt" << rt << "pp" << pp; +} /*! \class PropertyNode @@ -1127,6 +1194,8 @@ bool TargetNode::isInnerNode() const } #ifdef QDOC_QML +bool QmlClassNode::qmlOnly = false; + /*! Constructor for the Qml class node. */ @@ -1135,7 +1204,7 @@ QmlClassNode::QmlClassNode(InnerNode *parent, const ClassNode* cn) : FakeNode(parent, name, QmlClass), cnode(cn) { - setTitle("QML " + name + " Element Reference"); + setTitle((qmlOnly ? "" : "QML ") + name + " Element Reference"); } /*! @@ -1158,8 +1227,12 @@ QString QmlClassNode::fileBase() const Constructor for the Qml property group node. \a parent is always a QmlClassNode. */ -QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent, const QString& name) - : FakeNode(parent, name, QmlPropertyGroup), isdefault(false) +QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent, + const QString& name, + bool attached) + : FakeNode(parent, name, QmlPropertyGroup), + isdefault(false), + att(attached) { // nothing. } @@ -1169,11 +1242,13 @@ QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent, const QString& name) */ QmlPropertyNode::QmlPropertyNode(QmlPropGroupNode *parent, const QString& name, - const QString& type) + const QString& type, + bool attached) : LeafNode(QmlProperty, parent, name), dt(type), sto(Trool_Default), - des(Trool_Default) + des(Trool_Default), + att(attached) { // nothing. } @@ -1200,24 +1275,6 @@ bool QmlPropertyNode::fromTrool(Trool troolean, bool defaultValue) return defaultValue; } } - -/*! - Constructor for the QML signal node. - */ -QmlSignalNode::QmlSignalNode(QmlClassNode *parent, const QString& name) - : LeafNode(QmlSignal, parent, name) -{ - // nothing. -} - -/*! - Constructor for the QML method node. - */ -QmlMethodNode::QmlMethodNode(QmlClassNode *parent, const QString& name) - : LeafNode(QmlMethod, parent, name) -{ - // nothing. -} #endif QT_END_NAMESPACE diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h index f933270..dbdc174 100644 --- a/tools/qdoc3/node.h +++ b/tools/qdoc3/node.h @@ -151,6 +151,7 @@ class Node virtual bool isInnerNode() const = 0; virtual bool isReimp() const { return false; } + virtual bool isFunction() const { return false; } Type type() const { return typ; } virtual SubType subType() const { return NoSubType; } InnerNode *parent() const { return par; } @@ -239,6 +240,9 @@ class InnerNode : public Node NodeList overloads(const QString &funcName) const; const QStringList& includes() const { return inc; } + QStringList primaryKeys(); + QStringList secondaryKeys(); + protected: InnerNode(Type type, InnerNode *parent, const QString& name); @@ -362,6 +366,8 @@ class QmlClassNode : public FakeNode const ClassNode* classNode() const { return cnode; } virtual QString fileBase() const; + static bool qmlOnly; + private: const ClassNode* cnode; }; @@ -369,15 +375,19 @@ class QmlClassNode : public FakeNode class QmlPropGroupNode : public FakeNode { public: - QmlPropGroupNode(QmlClassNode* parent, const QString& name); + QmlPropGroupNode(QmlClassNode* parent, + const QString& name, + bool attached); virtual ~QmlPropGroupNode() { } - const QString& element() const { return name(); } + const QString& element() const { return parent()->name(); } void setDefault() { isdefault = true; } bool isDefault() const { return isdefault; } + bool isAttached() const { return att; } private: bool isdefault; + bool att; }; class QmlPropertyNode : public LeafNode @@ -385,19 +395,23 @@ class QmlPropertyNode : public LeafNode public: QmlPropertyNode(QmlPropGroupNode* parent, const QString& name, - const QString& type); + const QString& type, + bool attached); virtual ~QmlPropertyNode() { } void setDataType(const QString& dataType) { dt = dataType; } void setStored(bool stored) { sto = toTrool(stored); } void setDesignable(bool designable) { des = toTrool(designable); } + void setWritable(bool writable) { wri = toTrool(writable); } const QString &dataType() const { return dt; } QString qualifiedDataType() const { return dt; } bool isStored() const { return fromTrool(sto,true); } bool isDesignable() const { return fromTrool(des,false); } + bool isWritable() const { return fromTrool(wri,true); } + bool isAttached() const { return att; } - const QString& element() const { return parent()->name(); } + const QString& element() const { return static_cast<QmlPropGroupNode*>(parent())->element(); } private: enum Trool { Trool_True, Trool_False, Trool_Default }; @@ -408,24 +422,8 @@ class QmlPropertyNode : public LeafNode QString dt; Trool sto; Trool des; -}; - -class QmlSignalNode : public LeafNode -{ - public: - QmlSignalNode(QmlClassNode* parent, const QString& name); - virtual ~QmlSignalNode() { } - - const QString& element() const { return parent()->name(); } -}; - -class QmlMethodNode : public LeafNode -{ - public: - QmlMethodNode(QmlClassNode* parent, const QString& name); - virtual ~QmlMethodNode() { } - - const QString& element() const { return parent()->name(); } + Trool wri; + bool att; }; #endif @@ -540,6 +538,7 @@ class FunctionNode : public LeafNode enum Virtualness { NonVirtual, ImpureVirtual, PureVirtual }; FunctionNode(InnerNode *parent, const QString &name); + FunctionNode(Type type, InnerNode *parent, const QString &name, bool attached); virtual ~FunctionNode() { } void setReturnType(const QString& returnType) { rt = returnType; } @@ -565,6 +564,7 @@ class FunctionNode : public LeafNode bool isStatic() const { return sta; } bool isOverload() const { return ove; } bool isReimp() const { return reimp; } + bool isFunction() const { return true; } int overloadNumber() const; int numOverloads() const; const QList<Parameter>& parameters() const { return params; } @@ -576,6 +576,10 @@ class FunctionNode : public LeafNode QStringList reconstructParams(bool values = false) const; QString signature(bool values = false) const; + const QString& element() const { return parent()->name(); } + bool isAttached() const { return att; } + + void debug() const; private: void setAssociatedProperty(PropertyNode *property); @@ -596,6 +600,7 @@ class FunctionNode : public LeafNode bool sta : 1; bool ove : 1; bool reimp: 1; + bool att: 1; QList<Parameter> params; const FunctionNode *rf; const PropertyNode *ap; @@ -616,6 +621,7 @@ class PropertyNode : public LeafNode void addSignal(FunctionNode *function, FunctionRole role); void setStored(bool stored) { sto = toTrool(stored); } void setDesignable(bool designable) { des = toTrool(designable); } + void setWritable(bool writable) { wri = toTrool(writable); } void setOverriddenFrom(const PropertyNode *baseProperty); const QString &dataType() const { return dt; } @@ -628,6 +634,7 @@ class PropertyNode : public LeafNode NodeList notifiers() const { return functions(Notifier); } bool isStored() const { return fromTrool(sto, storedDefault()); } bool isDesignable() const { return fromTrool(des, designableDefault()); } + bool isWritable() const { return fromTrool(wri, writableDefault()); } const PropertyNode *overriddenFrom() const { return overrides; } private: @@ -638,11 +645,13 @@ class PropertyNode : public LeafNode bool storedDefault() const { return true; } bool designableDefault() const { return !setters().isEmpty(); } + bool writableDefault() const { return !setters().isEmpty(); } QString dt; NodeList funcs[NumFunctionRoles]; Trool sto; Trool des; + Trool wri; const PropertyNode *overrides; }; diff --git a/tools/qdoc3/pagegenerator.cpp b/tools/qdoc3/pagegenerator.cpp index 83ea561..7d9fbee 100644 --- a/tools/qdoc3/pagegenerator.cpp +++ b/tools/qdoc3/pagegenerator.cpp @@ -81,14 +81,13 @@ QString PageGenerator::fileBase(const Node *node) { if (node->relates()) node = node->relates(); - else if (!node->isInnerNode()) { + else if (!node->isInnerNode()) node = node->parent(); #ifdef QDOC_QML - if (node->subType() == Node::QmlPropertyGroup) { - node = node->parent(); - } -#endif + if (node->subType() == Node::QmlPropertyGroup) { + node = node->parent(); } +#endif QString base = node->doc().baseName(); if (!base.isEmpty()) @@ -97,6 +96,7 @@ QString PageGenerator::fileBase(const Node *node) const Node *p = node; forever { + const Node *pp = p->parent(); base.prepend(p->name()); #ifdef QDOC_QML /* @@ -104,15 +104,10 @@ QString PageGenerator::fileBase(const Node *node) we prepend "qml-" to the file name of QML element doc files. */ - if ((p->subType() == Node::QmlClass) || - (p->subType() == Node::QmlPropertyGroup)) - base.prepend("qml-"); - else if ((p->type() == Node::QmlProperty) || - (p->type() == Node::QmlSignal) || - (p->type() == Node::QmlMethod)) + if (p->subType() == Node::QmlClass) { base.prepend("qml-"); + } #endif - const Node *pp = p->parent(); if (!pp || pp->name().isEmpty() || pp->type() == Node::Fake) break; base.prepend(QLatin1Char('-')); diff --git a/tools/qdoc3/test/classic.css b/tools/qdoc3/test/classic.css index 320da66..b8cae8e 100644 --- a/tools/qdoc3/test/classic.css +++ b/tools/qdoc3/test/classic.css @@ -268,10 +268,15 @@ span.string,span.char border-style: solid; border-color: #ddd; font-weight: bold; - padding: 6px 0px 6px 10px; + padding: 6px 10px 6px 10px; margin: 42px 0px 0px 0px; } +.qmlreadonly { + float: right; + color: red +} + .qmldoc { } diff --git a/tools/qdoc3/test/qt-api-only-with-xcode.qdocconf b/tools/qdoc3/test/qt-api-only-with-xcode.qdocconf deleted file mode 100644 index 0d78cda..0000000 --- a/tools/qdoc3/test/qt-api-only-with-xcode.qdocconf +++ /dev/null @@ -1,29 +0,0 @@ -include(qt-build-docs-with-xcode.qdocconf) - -# Ensures that the generated index contains a URL that can be used by the -# tools documentation (assistant.qdocconf, designer.qdocconf, linguist.qdocconf, -# qmake.qdocconf). - -url = ./ - -# Ensures that the documentation for the tools is not included in the generated -# .qhp file. - -qhp.Qt.excluded = $QT_SOURCE_TREE/doc/src/development/assistant-manual.qdoc \ - $QT_SOURCE_TREE/doc/src/examples/simpletextviewer.qdoc \ - $QT_SOURCE_TREE/doc/src/development/designer-manual.qdoc \ - $QT_SOURCE_TREE/doc/src/examples/calculatorbuilder.qdoc \ - $QT_SOURCE_TREE/doc/src/examples/calculatorform.qdoc \ - $QT_SOURCE_TREE/doc/src/examples/customwidgetplugin.qdoc \ - $QT_SOURCE_TREE/doc/src/examples/taskmenuextension.qdoc \ - $QT_SOURCE_TREE/doc/src/examples/containerextension.qdoc \ - $QT_SOURCE_TREE/doc/src/examples/worldtimeclockbuilder.qdoc \ - $QT_SOURCE_TREE/doc/src/examples/worldtimeclockplugin.qdoc \ - $QT_SOURCE_TREE/doc/src/internationalization/linguist-manual.qdoc \ - $QT_SOURCE_TREE/doc/src/examples/hellotr.qdoc \ - $QT_SOURCE_TREE/doc/src/examples/arrowpad.qdoc \ - $QT_SOURCE_TREE/doc/src/examples/trollprint.qdoc \ - $QT_SOURCE_TREE/doc/src/development/qmake-manual.qdoc - -outputdir = $QT_BUILD_TREE/doc-build/html-qt -base = file:$QT_BUILD_TREE/doc-build/html-qt diff --git a/tools/qdoc3/test/qt-build-docs-with-xcode.qdocconf b/tools/qdoc3/test/qt-build-docs-with-xcode.qdocconf deleted file mode 100644 index e4be476..0000000 --- a/tools/qdoc3/test/qt-build-docs-with-xcode.qdocconf +++ /dev/null @@ -1,3 +0,0 @@ -include( qt-build-docs.qdocconf ) - -HTML.generatemacrefs = "true" diff --git a/tools/qdoc3/test/qt-build-docs.qdocconf b/tools/qdoc3/test/qt-build-docs.qdocconf index 8da7442..d1733e5 100644 --- a/tools/qdoc3/test/qt-build-docs.qdocconf +++ b/tools/qdoc3/test/qt-build-docs.qdocconf @@ -8,7 +8,7 @@ project = Qt description = Qt Reference Documentation url = http://qt.nokia.com/doc/4.6 -edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript QtSql QtSvg \ +edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript QtScriptTools QtSql QtSvg \ QtWebKit QtXml QtXmlPatterns Qt3Support QtHelp \ QtDesigner QtAssistant QAxContainer Phonon \ QAxServer QtUiTools QtTest QtDBus diff --git a/tools/qdoc3/test/qt-cpp-ignore.qdocconf b/tools/qdoc3/test/qt-cpp-ignore.qdocconf index 1efc215..dcf33dc 100644 --- a/tools/qdoc3/test/qt-cpp-ignore.qdocconf +++ b/tools/qdoc3/test/qt-cpp-ignore.qdocconf @@ -69,6 +69,7 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \ QT_END_NAMESPACE \ QT_END_INCLUDE_NAMESPACE \ PHONON_EXPORT \ + Q_DECLARATIVE_EXPORT \ Q_GADGET \ QWEBKIT_EXPORT Cpp.ignoredirectives = Q_DECLARE_HANDLE \ diff --git a/tools/qdoc3/test/qt-html-templates.qdocconf b/tools/qdoc3/test/qt-html-templates.qdocconf index 7ceacb2..8c039eb 100644 --- a/tools/qdoc3/test/qt-html-templates.qdocconf +++ b/tools/qdoc3/test/qt-html-templates.qdocconf @@ -35,7 +35,7 @@ HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \ \ "<script type=\"text/javascript\" src=\"http://www.google.com/jsapi\"></script>" \ "<script type=\"text/javascript\">google.load(\"elements\", \"1\", {packages: \"transliteration\"});</script>" \ - "<script type=\"text/javascript\" src=\"http://www.google.com/coop/cse/t13n?form=cse-search-box&t13n_langs=en\"></script>" \ + "<script type=\"text/javascript\" src=\"http://www.google.com/coop/cse/t13n?form=cse-search-box&t13n_langs=en\"></script>" \ \ - "<script type=\"text/javascript\" src=\"http://www.google.com/coop/cse/brand?form=cse-search-box&lang=en\"></script>"\ + "<script type=\"text/javascript\" src=\"http://www.google.com/coop/cse/brand?form=cse-search-box&lang=en\"></script>"\ "</tr></table></div></address>" diff --git a/tools/qdoc3/test/qt-inc.qdocconf b/tools/qdoc3/test/qt-inc.qdocconf deleted file mode 100644 index 2ff5682..0000000 --- a/tools/qdoc3/test/qt-inc.qdocconf +++ /dev/null @@ -1,149 +0,0 @@ -include(compat.qdocconf) -include(macros.qdocconf) - -project = Qt -description = Qt Reference Documentation -url = http://qt.nokia.com/doc/4.6 - -edition.Desktop = QtCore QtGui QtNetwork QtOpenGL QtSql QtSvg QtXml QtScript \ - QtDesigner QtAssistant Qt3Support QAxContainer \ - QAxServer QtUiTools QtTest QtDBus -edition.DesktopLight = QtCore QtGui Qt3SupportLight QtTest - -language = Cpp - -norecursion = true -sources.fileextensions = "*.cpp *.qdoc" -sourcedirs = $QDOC_CURRENT_DIR -headerdirs = $QDOC_CURRENT_DIR -exampledirs = $QTDIR/doc/src \ - $QTDIR/examples \ - $QTDIR \ - $QTDIR/qmake/examples \ - $QTDIR/src/3rdparty/webkit/WebKit/qt/docs -imagedirs = $QTDIR/doc/src/images \ - $QTDIR/examples -outputdir = $QTDIR/doc/html -indexdir = $QTDIR/doc/indexes -indexes = $QDOC_INPUT_INDEXES -outputindex = $QDOC_OUTPUT_INDEX -base = file:$QTDIR/doc/html -versionsym = QT_VERSION_STR -defines = Q_QDOC \ - QT_.*_SUPPORT \ - QT_.*_LIB \ - QT_COMPAT \ - QT_KEYPAD_NAVIGATION \ - QT3_SUPPORT \ - Q_WS_.* \ - Q_OS_.* \ - Q_BYTE_ORDER \ - __cplusplus - -codeindent = 1 -extraimages.HTML = qt-logo \ - trolltech-logo - -Cpp.ignoretokens = QAXFACTORY_EXPORT \ - QDESIGNER_COMPONENTS_LIBRARY \ - QDESIGNER_EXTENSION_LIBRARY \ - QDESIGNER_SDK_LIBRARY \ - QDESIGNER_SHARED_LIBRARY \ - QDESIGNER_UILIB_LIBRARY \ - QM_EXPORT_CANVAS \ - QM_EXPORT_DNS \ - QM_EXPORT_DOM \ - QM_EXPORT_FTP \ - QM_EXPORT_HTTP \ - QM_EXPORT_ICONVIEW \ - QM_EXPORT_NETWORK \ - QM_EXPORT_OPENGL \ - QM_EXPORT_SQL \ - QM_EXPORT_TABLE \ - QM_EXPORT_WORKSPACE \ - QM_EXPORT_XML \ - QT_ASCII_CAST_WARN \ - QT_BEGIN_HEADER \ - QT_DESIGNER_STATIC \ - QT_END_HEADER \ - QT_WIDGET_PLUGIN_EXPORT \ - Q_COMPAT_EXPORT \ - Q_CORE_EXPORT \ - Q_EXPLICIT \ - Q_EXPORT \ - Q_EXPORT_CODECS_CN \ - Q_EXPORT_CODECS_JP \ - Q_EXPORT_CODECS_KR \ - Q_EXPORT_PLUGIN \ - Q_GFX_INLINE \ - Q_GUI_EXPORT \ - Q_GUI_EXPORT_INLINE \ - Q_GUI_EXPORT_STYLE_CDE \ - Q_GUI_EXPORT_STYLE_COMPACT \ - Q_GUI_EXPORT_STYLE_MAC \ - Q_GUI_EXPORT_STYLE_MOTIF \ - Q_GUI_EXPORT_STYLE_MOTIFPLUS \ - Q_GUI_EXPORT_STYLE_PLATINUM \ - Q_GUI_EXPORT_STYLE_POCKETPC \ - Q_GUI_EXPORT_STYLE_SGI \ - Q_GUI_EXPORT_STYLE_WINDOWS \ - Q_GUI_EXPORT_STYLE_WINDOWSXP \ - Q_INLINE_TEMPLATE \ - Q_NETWORK_EXPORT \ - Q_OPENGL_EXPORT \ - Q_OUTOFLINE_TEMPLATE \ - Q_SQL_EXPORT \ - Q_SVG_EXPORT \ - Q_SCRIPT_EXPORT \ - Q_TESTLIB_EXPORT \ - Q_TYPENAME \ - Q_XML_EXPORT \ - QDBUS_EXPORT \ - Q_GADGET \ - QWEBKIT_EXPORT -Cpp.ignoredirectives = Q_DECLARE_HANDLE \ - Q_DECLARE_INTERFACE \ - Q_DECLARE_METATYPE \ - Q_DECLARE_OPERATORS_FOR_FLAGS \ - Q_DECLARE_PRIVATE \ - Q_DECLARE_PUBLIC \ - Q_DECLARE_SHARED \ - Q_DECLARE_TR_FUNCTIONS \ - Q_DECLARE_TYPEINFO \ - Q_DISABLE_COPY \ - Q_DUMMY_COMPARISON_OPERATOR \ - Q_ENUMS \ - Q_FLAGS \ - Q_INTERFACES \ - Q_OS_SYMBIAN \ - __attribute__ - -HTML.stylesheets = $QTDIR/util/qdoc3/test/classic.css -HTML.postheader = "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n" \ - "<tr>\n" \ - "<td align=\"left\" valign=\"top\" width=\"32\">" \ - "<a href=\"http://qt.nokia.com/\"><img src=\"images/qt-logo.png\" align=\"left\" width=\"32\" height=\"32\" border=\"0\" /></a>" \ - "</td>\n" \ - "<td width=\"1\"> </td>" \ - "<td class=\"postheader\" valign=\"center\">" \ - "<a href=\"index.html\">" \ - "<font color=\"#004faf\">Home</font></a> ·" \ - " <a href=\"classes.html\">" \ - "<font color=\"#004faf\">All Classes</font></a> ·" \ - " <a href=\"mainclasses.html\">" \ - "<font color=\"#004faf\">Main Classes</font></a> ·" \ - " <a href=\"groups.html\">" \ - "<font color=\"#004faf\">Grouped Classes</font></a> ·" \ - " <a href=\"modules.html\">" \ - "<font color=\"#004faf\">Modules</font></a> ·" \ - " <a href=\"functions.html\">" \ - "<font color=\"#004faf\">Functions</font></a>" \ - "</td>\n" \ - "<td align=\"right\" valign=\"top\" width=\"230\"><a href=\"http://qt.nokia.com\"><img src=\"images/trolltech-logo.png\" align=\"right\" width=\"203\" height=\"32\" border=\"0\" /></a></td></tr></table>" - -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 © 2009 Nokia Corporation and/or its subsidiary(-ies)</td>\n" \ - "<td width=\"40%\" align=\"center\"><a href=\"trademarks.html\">Trademarks</a></td>\n" \ - "<td width=\"30%\" align=\"right\"><div align=\"right\">Qt \\version</div></td>\n" \ - "</tr></table></div></address>" diff --git a/tools/qdoc3/test/qt-with-xcode.qdocconf b/tools/qdoc3/test/qt-with-xcode.qdocconf deleted file mode 100644 index 932f6d9..0000000 --- a/tools/qdoc3/test/qt-with-xcode.qdocconf +++ /dev/null @@ -1,3 +0,0 @@ -include( qt.qdocconf ) - -HTML.generatemacrefs = "true" diff --git a/tools/qdoc3/tree.cpp b/tools/qdoc3/tree.cpp index bcd9709..4d401de 100644 --- a/tools/qdoc3/tree.cpp +++ b/tools/qdoc3/tree.cpp @@ -225,6 +225,7 @@ const FunctionNode *Tree::findFunctionNode(const QStringList &path, { if (!relative) relative = root(); + do { const Node *node = relative; int i; @@ -244,8 +245,7 @@ const FunctionNode *Tree::findFunctionNode(const QStringList &path, NodeList baseClasses = allBaseClasses(static_cast<const ClassNode *>(node)); foreach (const Node *baseClass, baseClasses) { if (i == path.size() - 1) - next = static_cast<const InnerNode *>(baseClass)-> - findFunctionNode(path.at(i)); + next = static_cast<const InnerNode *>(baseClass)->findFunctionNode(path.at(i)); else next = static_cast<const InnerNode *>(baseClass)->findNode(path.at(i)); @@ -256,11 +256,10 @@ const FunctionNode *Tree::findFunctionNode(const QStringList &path, node = next; } - if (node && i == path.size() && node->type() == Node::Function) { + if (node && i == path.size() && node->isFunction()) { // CppCodeParser::processOtherMetaCommand ensures that reimplemented // functions are private. const FunctionNode *func = static_cast<const FunctionNode*>(node); - while (func->access() == Node::Private) { const FunctionNode *from = func->reimplementedFrom(); if (from != 0) { @@ -268,7 +267,8 @@ const FunctionNode *Tree::findFunctionNode(const QStringList &path, return from; else func = from; - } else + } + else break; } return func; @@ -303,7 +303,8 @@ const FunctionNode *Tree::findFunctionNode(const QStringList &parentPath, const Node *parent = findNode(parentPath, relative, findFlags); if (parent == 0 || !parent->isInnerNode()) { return 0; - } else { + } + else { return ((InnerNode *)parent)->findFunctionNode(clone); } } diff --git a/tools/qtestlib/wince/cetest/main.cpp b/tools/qtestlib/wince/cetest/main.cpp index 9df70e7..763439a 100644 --- a/tools/qtestlib/wince/cetest/main.cpp +++ b/tools/qtestlib/wince/cetest/main.cpp @@ -129,6 +129,7 @@ void usage() " -conf : Specify location of qt.conf file\n" " -f <file> : Specify project file\n" " -cache <file> : Specify .qmake.cache file to use\n" + " -d : Increase qmake debugging \n" " -timeout <value> : Specify a timeout value after which the test will be terminated\n" " -1 specifies waiting forever (default)\n" " 0 specifies starting the process detached\n" @@ -216,6 +217,8 @@ int main(int argc, char **argv) return -1; } cacheFile = arguments.at(i); + } else if (arguments.at(i).toLower() == QLatin1String("-d")) { + Option::debug_level++; } else if (arguments.at(i).toLower() == QLatin1String("-timeout")) { if (++i == arguments.size()) { cout << "Error: No timeout value specified!" << endl; @@ -235,11 +238,22 @@ int main(int argc, char **argv) return -1; } debugOutput(QString::fromLatin1("Using Project File:").append(proFile),1); + }else { + if (!QFileInfo(proFile).exists()) { + cout << "Error: Project file does not exist " << qPrintable(proFile) << endl; + return -1; + } } - // read target and deployment rules - int qmakeArgc = 1; - char* qmakeArgv[] = { "qmake.exe" }; + Option::before_user_vars.append("CONFIG+=build_pass"); + + // read target and deployment rules passing the .pro to use instead of + // relying on qmake guessing the .pro to use + int qmakeArgc = 2; + QByteArray ba(QFile::encodeName(proFile)); + char* proFileEncodedName = ba.data(); + char* qmakeArgv[2] = { "qmake.exe", proFileEncodedName }; + Option::qmake_mode = Option::QMAKE_GENERATE_NOTHING; Option::output_dir = qmake_getpwd(); if (!cacheFile.isEmpty()) @@ -265,6 +279,24 @@ int main(int argc, char **argv) else TestConfiguration::testDebug = false; + // determine what is the real mkspec to use if the default mkspec is being used + if (Option::mkfile::qmakespec.endsWith("/default")) + project.values("QMAKESPEC") = project.values("QMAKESPEC_ORIGINAL"); + else + project.values("QMAKESPEC") = QStringList() << Option::mkfile::qmakespec; + + // ensure that QMAKESPEC is non-empty .. to meet requirements of QList::at() + if (project.values("QMAKESPEC").isEmpty()){ + cout << "Error: QMAKESPEC not set after parsing " << qPrintable(proFile) << endl; + return -1; + } + + // ensure that QT_CE_C_RUNTIME is non-empty .. to meet requirements of QList::at() + if (project.values("QT_CE_C_RUNTIME").isEmpty()){ + cout << "Error: QT_CE_C_RUNTIME not defined in mkspec/qconfig.pri " << qPrintable(project.values("QMAKESPEC").join(" ")); + return -1; + } + QString destDir = project.values("DESTDIR").join(" "); if (!destDir.isEmpty()) { if (QDir::isRelativePath(destDir)) { diff --git a/tools/qttracereplay/main.cpp b/tools/qttracereplay/main.cpp index 1d21a21..4760c43 100644 --- a/tools/qttracereplay/main.cpp +++ b/tools/qttracereplay/main.cpp @@ -56,7 +56,7 @@ public: public slots: void updateRect(); -private: +public: QList<QRegion> updates; QPaintBuffer buffer; @@ -70,7 +70,8 @@ private: void ReplayWidget::updateRect() { - update(updates.at(currentFrame)); + if (!updates.isEmpty()) + update(updates.at(currentFrame)); } void ReplayWidget::paintEvent(QPaintEvent *) @@ -138,12 +139,25 @@ ReplayWidget::ReplayWidget(const QString &filename_) QFile file(filename); QRect bounds; - if (file.open(QIODevice::ReadOnly)) { - QDataStream in(&file); - in >> buffer >> updates; + if (!file.open(QIODevice::ReadOnly)) { + printf("Failed to load input file '%s'\n", qPrintable(filename_)); + return; } - qDebug() << "Read paint buffer with" << buffer.numFrames() << "frames"; + QDataStream in(&file); + + char *data; + uint size; + in.readBytes(data, size); + bool isTraceFile = size == 7 && qstrncmp(data, "qttrace", 7) == 0; + delete [] data; + if (!isTraceFile) { + printf("File '%s' is not a trace file\n", qPrintable(filename_)); + return; + } + + in >> buffer >> updates; + printf("Read paint buffer with %d frames\n", buffer.numFrames()); resize(buffer.boundingRect().size().toSize()); @@ -157,14 +171,24 @@ int main(int argc, char **argv) { QApplication app(argc, argv); - if (argc <= 1) { - printf("Usage: %s filename\n", argv[0]); + if (argc <= 1 || qstrcmp(argv[1], "-h") == 0 || qstrcmp(argv[1], "--help") == 0) { + printf("Replays a tracefile generated with '-graphicssystem trace'\n"); + printf("Usage:\n > %s [traceFile]\n", argv[0]); + return 1; + } + + QFile file(argv[1]); + if (!file.exists()) { + printf("%s does not exist\n", argv[1]); return 1; } ReplayWidget *widget = new ReplayWidget(argv[1]); - widget->show(); - return app.exec(); + if (!widget->updates.isEmpty()) { + widget->show(); + return app.exec(); + } + } #include "main.moc" diff --git a/tools/qttracereplay/qttracereplay.pro b/tools/qttracereplay/qttracereplay.pro index 766ed04..cc5b98d 100644 --- a/tools/qttracereplay/qttracereplay.pro +++ b/tools/qttracereplay/qttracereplay.pro @@ -11,3 +11,5 @@ SOURCES += main.cpp target.path=$$[QT_INSTALL_BINS] INSTALLS += target + +CONFIG += console diff --git a/tools/qvfb/config.ui b/tools/qvfb/config.ui index ad9c39e..b74bef7 100644 --- a/tools/qvfb/config.ui +++ b/tools/qvfb/config.ui @@ -47,7 +47,7 @@ <x>0</x> <y>0</y> <width>600</width> - <height>665</height> + <height>690</height> </rect> </property> <property name="windowTitle"> @@ -118,6 +118,13 @@ </widget> </item> <item> + <widget class="QRadioButton" name="size_800_480"> + <property name="text"> + <string>800x480</string> + </property> + </widget> + </item> + <item> <widget class="QRadioButton" name="size_800_600"> <property name="text"> <string>800x600</string> diff --git a/tools/qvfb/qvfb.cpp b/tools/qvfb/qvfb.cpp index 59e8dae..09692b7 100644 --- a/tools/qvfb/qvfb.cpp +++ b/tools/qvfb/qvfb.cpp @@ -669,6 +669,8 @@ void QVFb::configure() w=320; h=240; } else if ( config->size_640_480->isChecked() ) { w=640; h=480; + } else if ( config->size_800_480->isChecked() ) { + w=800; h=480; } else if ( config->size_800_600->isChecked() ) { w=800; h=600; } else if ( config->size_1024_768->isChecked() ) { @@ -748,6 +750,7 @@ void QVFb::chooseSize(const QSize& sz) config->size_240_320->setChecked(sz == QSize(240,320)); config->size_320_240->setChecked(sz == QSize(320,240)); config->size_640_480->setChecked(sz == QSize(640,480)); + config->size_800_480->setChecked(sz == QSize(800,480)); config->size_800_600->setChecked(sz == QSize(800,600)); config->size_1024_768->setChecked(sz == QSize(1024,768)); } diff --git a/tools/qvfb/qvfbview.cpp b/tools/qvfb/qvfbview.cpp index 8cab641..69817bd 100644 --- a/tools/qvfb/qvfbview.cpp +++ b/tools/qvfb/qvfbview.cpp @@ -596,7 +596,7 @@ QImage QVFbView::getBuffer(const QRect &r, int &leading) const r.width(), r.height(), mView->linestep(), QImage::Format_Indexed8); img.setColorTable(mView->clut()); - if (img.numColors() <= 0) + if (img.colorCount() <= 0) img = QImage(); break; } @@ -613,10 +613,10 @@ QImage QVFbView::getBuffer(const QRect &r, int &leading) const if ( img.format() != QImage::Format_ARGB32_Premultiplied ) img = img.convertToFormat(QImage::Format_RGB32); - // NOTE: calling bits() may change numBytes(), so do not + // NOTE: calling bits() may change byteCount(), so do not // pass them as parameters (which are evaluated right-to-left). QRgb *b = (QRgb*)img.bits(); - int n = img.numBytes()/4; + int n = img.byteCount()/4; dim(b,n,brightness); } } diff --git a/tools/tools.pro b/tools/tools.pro index f079357..e7c6701 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -26,6 +26,7 @@ mac { embedded:SUBDIRS += kmap2qmap +contains(QT_CONFIG, declarative):SUBDIRS += qmlviewer qmldebugger contains(QT_CONFIG, dbus):SUBDIRS += qdbus !wince*:contains(QT_CONFIG, xmlpatterns): SUBDIRS += xmlpatterns xmlpatternsvalidator embedded: SUBDIRS += makeqpf diff --git a/tools/xmlpatterns/xmlpatterns.pro b/tools/xmlpatterns/xmlpatterns.pro index 1c5ab2c..47f5a48 100644 --- a/tools/xmlpatterns/xmlpatterns.pro +++ b/tools/xmlpatterns/xmlpatterns.pro @@ -27,3 +27,6 @@ HEADERS = main.h \ qapplicationargumentparser.cpp \ qcoloringmessagehandler_p.h \ qcoloroutput_p.h + +symbian: TARGET.UID3 = 0xA000D7C9 + diff --git a/tools/xmlpatternsvalidator/xmlpatternsvalidator.pro b/tools/xmlpatternsvalidator/xmlpatternsvalidator.pro index 8491129..17fc465 100644 --- a/tools/xmlpatternsvalidator/xmlpatternsvalidator.pro +++ b/tools/xmlpatternsvalidator/xmlpatternsvalidator.pro @@ -15,3 +15,5 @@ CONFIG -= app_bundle SOURCES = main.cpp HEADERS = main.h + +symbian: TARGET.UID3 = 0xA000D7CA |