diff options
author | Jason Barron <jbarron@trolltech.com> | 2009-08-04 08:33:52 (GMT) |
---|---|---|
committer | Jason Barron <jbarron@trolltech.com> | 2009-08-04 09:02:17 (GMT) |
commit | 4aafbd6222e7aeafd59a4a4356ba8c53b2bfa1d1 (patch) | |
tree | b34985c5716d98f01b9f36fd4a98f2ac9710099f /tools | |
parent | a0df97c03f26a38af17a42fb44ad6910536c8857 (diff) | |
parent | 2076f150995e541308b1d8da936b3e12ab68b886 (diff) | |
download | Qt-4aafbd6222e7aeafd59a4a4356ba8c53b2bfa1d1.zip Qt-4aafbd6222e7aeafd59a4a4356ba8c53b2bfa1d1.tar.gz Qt-4aafbd6222e7aeafd59a4a4356ba8c53b2bfa1d1.tar.bz2 |
Merge commit 'qt/master-stable'
Conflicts:
config.tests/unix/openssl/openssl.pri
demos/embedded/embedded.pro
examples/itemviews/chart/chart.pro
examples/network/network.pro
examples/painting/painterpaths/painterpaths.pro
examples/threads/mandelbrot/mandelbrot.pro
qmake/project.cpp
src/3rdparty/libtiff/libtiff/tif_config.h
src/corelib/arch/arch.pri
src/corelib/global/qglobal.cpp
src/corelib/kernel/kernel.pri
src/corelib/kernel/qcore_unix_p.h
src/corelib/kernel/qobject.cpp
src/corelib/thread/qthread_unix.cpp
src/corelib/tools/qsharedpointer_impl.h
src/corelib/tools/tools.pri
src/gui/kernel/qaction.h
src/gui/kernel/qapplication.cpp
src/gui/painting/qregion.h
src/gui/widgets/qlineedit.cpp
src/gui/widgets/qlineedit_p.h
src/network/socket/qnativesocketengine_unix.cpp
tests/auto/qdir/tst_qdir.cpp
tests/auto/qdiriterator/tst_qdiriterator.cpp
tests/auto/qhttp/qhttp.pro
tests/auto/qline/qline.pro
tests/auto/qnetworkreply/tst_qnetworkreply.cpp
tests/auto/qresourceengine/qresourceengine.pro
tests/auto/qsharedpointer/qsharedpointer.pro
tests/auto/qstring/qstring.pro
tests/auto/qtcpsocket/qtcpsocket.pro
tests/auto/qtcpsocket/tst_qtcpsocket.cpp
Diffstat (limited to 'tools')
36 files changed, 1640 insertions, 377 deletions
diff --git a/tools/assistant/lib/qhelpprojectdata.cpp b/tools/assistant/lib/qhelpprojectdata.cpp index 55b4ea7..9412f1c 100644 --- a/tools/assistant/lib/qhelpprojectdata.cpp +++ b/tools/assistant/lib/qhelpprojectdata.cpp @@ -45,6 +45,7 @@ #include <QtCore/QFileInfo> #include <QtCore/QStack> #include <QtCore/QMap> +#include <QtCore/QRegExp> #include <QtCore/QVariant> #include <QtXml/QXmlStreamReader> @@ -75,6 +76,8 @@ private: void readFiles(); void raiseUnknownTokenError(); void addMatchingFiles(const QString &pattern); + + QMap<QString, QStringList> dirEntriesCache; }; void QHelpProjectDataPrivate::raiseUnknownTokenError() @@ -265,14 +268,40 @@ void QHelpProjectDataPrivate::readFiles() // meaningful warning later. void QHelpProjectDataPrivate::addMatchingFiles(const QString &pattern) { + // The pattern matching is expensive, so we skip it if no + // wildcard symbols occur in the string. + if (!pattern.contains('?') && !pattern.contains('*') + && !pattern.contains('[') && !pattern.contains(']')) { + filterSectionList.last().addFile(pattern); + return; + } + QFileInfo fileInfo(rootPath + '/' + pattern); - const QStringList &matches = - fileInfo.dir().entryList(QStringList(fileInfo.fileName())); - for (QStringList::ConstIterator it = matches.constBegin(); - it != matches.constEnd(); - ++it) - filterSectionList.last().addFile(QFileInfo(pattern).dir().path() + '/' + *it); - if (matches.empty()) + const QDir &dir = fileInfo.dir(); + const QString &path = dir.canonicalPath(); + + // QDir::entryList() is expensive, so we cache the results. + QMap<QString, QStringList>::ConstIterator it = dirEntriesCache.find(path); + const QStringList &entries = it != dirEntriesCache.constEnd() ? + it.value() : dir.entryList(QDir::Files); + if (it == dirEntriesCache.constEnd()) + dirEntriesCache.insert(path, entries); + + bool matchFound = false; +#ifdef Q_OS_WIN + Qt::CaseSensitivity cs = Qt::CaseInsensitive; +#else + Qt::CaseSensitivity cs = Qt::CaseSensitive; +#endif + QRegExp regExp(fileInfo.fileName(), cs, QRegExp::Wildcard); + foreach (const QString &file, entries) { + if (regExp.exactMatch(file)) { + matchFound = true; + filterSectionList.last(). + addFile(QFileInfo(pattern).dir().path() + '/' + file); + } + } + if (!matchFound) filterSectionList.last().addFile(pattern); } diff --git a/tools/assistant/tools/assistant/assistant.qch b/tools/assistant/tools/assistant/assistant.qch Binary files differindex 99687ed..3e66bd9 100644 --- a/tools/assistant/tools/assistant/assistant.qch +++ b/tools/assistant/tools/assistant/assistant.qch diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp index a384544..23562db 100644 --- a/tools/assistant/tools/assistant/centralwidget.cpp +++ b/tools/assistant/tools/assistant/centralwidget.cpp @@ -43,6 +43,7 @@ #include "helpviewer.h" #include "searchwidget.h" #include "mainwindow.h" +#include "preferencesdialog.h" #include <QtCore/QDir> #include <QtCore/QEvent> @@ -423,6 +424,27 @@ void CentralWidget::setSource(const QUrl &url) tabWidget->setTabText(lastTabPage, quoteTabTitle(viewer->documentTitle())); } +void CentralWidget::setupWidget() +{ + int option = helpEngine->customValue(QLatin1String("StartOption"), + ShowLastPages).toInt(); + + if (option != ShowLastPages) { + QString homePage; + if (option == ShowHomePage) { + homePage = helpEngine->customValue(QLatin1String("defaultHomepage"), + QLatin1String("help")).toString(); + homePage = helpEngine->customValue(QLatin1String("homepage"), + homePage).toString(); + } + if (option == ShowBlankPage) + homePage = QLatin1String("about:blank"); + setSource(homePage); + } else { + setLastShownPages(); + } +} + void CentralWidget::setLastShownPages() { const QLatin1String key("LastShownPages"); @@ -739,8 +761,10 @@ void CentralWidget::setTabTitle(const QUrl &url) QTabBar *tabBar = qFindChild<QTabBar*>(tabWidget); for (int tab = 0; tab < tabBar->count(); ++tab) { HelpViewer *viewer = qobject_cast<HelpViewer*>(tabWidget->widget(tab)); - if (viewer) - tabWidget->setTabText(tab, viewer->documentTitle().trimmed()); + if (viewer) { + tabWidget->setTabText(tab, + quoteTabTitle(viewer->documentTitle().trimmed())); + } } #else HelpViewer *viewer = currentHelpViewer(); diff --git a/tools/assistant/tools/assistant/centralwidget.h b/tools/assistant/tools/assistant/centralwidget.h index ca9caaf..f7ce1d5 100644 --- a/tools/assistant/tools/assistant/centralwidget.h +++ b/tools/assistant/tools/assistant/centralwidget.h @@ -111,7 +111,7 @@ public: CentralWidget(QHelpEngine *engine, MainWindow *parent); ~CentralWidget(); - void setLastShownPages(); + void setupWidget(); bool hasSelection() const; QUrl currentSource() const; QString currentTitle() const; @@ -188,6 +188,7 @@ private: void initPrinter(); QString quoteTabTitle(const QString &title) const; void highlightSearchTerms(); + void setLastShownPages(); private: int lastTabPage; diff --git a/tools/assistant/tools/assistant/doc/assistant.qhp b/tools/assistant/tools/assistant/doc/assistant.qhp index 7a26101..7ea4cdd 100644 --- a/tools/assistant/tools/assistant/doc/assistant.qhp +++ b/tools/assistant/tools/assistant/doc/assistant.qhp @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <QtHelpProject version="1.0"> <virtualFolder>assistant</virtualFolder> - <namespace>com.trolltech.com.assistantinternal_1.0.0</namespace> + <namespace>com.trolltech.com.assistantinternal-1.0.0</namespace> <filterSection> <files> <file>assistant.html</file> diff --git a/tools/assistant/tools/assistant/helpviewer.cpp b/tools/assistant/tools/assistant/helpviewer.cpp index 6799db3..5422bf46 100644 --- a/tools/assistant/tools/assistant/helpviewer.cpp +++ b/tools/assistant/tools/assistant/helpviewer.cpp @@ -306,7 +306,7 @@ void HelpViewer::setSource(const QUrl &url) loadFinished = false; if (url.toString() == QLatin1String("help")) { load(QUrl(QLatin1String("qthelp://com.trolltech.com." - "assistantinternal_1.0.0/assistant/assistant.html"))); + "assistantinternal-1.0.0/assistant/assistant.html"))); } else { load(url); } @@ -425,7 +425,7 @@ void HelpViewer::setSource(const QUrl &url) if (help) { QTextBrowser::setSource(QUrl(QLatin1String("qthelp://com.trolltech.com." - "assistantinternal_1.0.0/assistant/assistant.html"))); + "assistantinternal-1.0.0/assistant/assistant.html"))); } else { QTextBrowser::setSource(url); setHtml(tr("<title>Error 404...</title><div align=\"center\"><br><br>" diff --git a/tools/assistant/tools/assistant/main.cpp b/tools/assistant/tools/assistant/main.cpp index 05355d9..a0a5a0d 100644 --- a/tools/assistant/tools/assistant/main.cpp +++ b/tools/assistant/tools/assistant/main.cpp @@ -306,7 +306,7 @@ int main(int argc, char *argv[]) } } - QLatin1String intern("com.trolltech.com.assistantinternal_"); + QLatin1String intern("com.trolltech.com.assistantinternal-"); foreach (const QString &doc, userDocs) { if (!callerDocs.contains(doc) && !doc.startsWith(intern)) user.unregisterDocumentation(doc); diff --git a/tools/assistant/tools/assistant/mainwindow.cpp b/tools/assistant/tools/assistant/mainwindow.cpp index 7926020..bc73b80 100644 --- a/tools/assistant/tools/assistant/mainwindow.cpp +++ b/tools/assistant/tools/assistant/mainwindow.cpp @@ -274,7 +274,7 @@ bool MainWindow::initHelpDB() return false; bool assistantInternalDocRegistered = false; - QString intern(QLatin1String("com.trolltech.com.assistantinternal_")); + QString intern(QLatin1String("com.trolltech.com.assistantinternal-")); foreach (const QString &ns, m_helpEngine->registeredDocumentations()) { if (ns.startsWith(intern)) { intern = ns; @@ -407,7 +407,7 @@ void MainWindow::insertLastPages() if (m_cmdLine->url().isValid()) m_centralWidget->setSource(m_cmdLine->url()); else - m_centralWidget->setLastShownPages(); + m_centralWidget->setupWidget(); if (m_cmdLine->search() == CmdLineParser::Activate) showSearch(); diff --git a/tools/assistant/tools/assistant/preferencesdialog.cpp b/tools/assistant/tools/assistant/preferencesdialog.cpp index fa70196..2b58c64 100644 --- a/tools/assistant/tools/assistant/preferencesdialog.cpp +++ b/tools/assistant/tools/assistant/preferencesdialog.cpp @@ -146,10 +146,13 @@ PreferencesDialog::~PreferencesDialog() emit updateBrowserFont(); } - if (!m_ui.homePageLineEdit->text().isEmpty()) { - key = QLatin1String("homepage"); - m_helpEngine->setCustomValue(key, m_ui.homePageLineEdit->text()); - } + QString homePage = m_ui.homePageLineEdit->text(); + if (homePage.isEmpty()) + homePage = QLatin1String("help"); + m_helpEngine->setCustomValue(QLatin1String("homepage"), homePage); + + int option = m_ui.helpStartComboBox->currentIndex(); + m_helpEngine->setCustomValue(QLatin1String("StartOption"), option); } void PreferencesDialog::showDialog() @@ -379,6 +382,8 @@ void PreferencesDialog::applyChanges() CentralWidget* widget = CentralWidget::instance(); for (int i = m_TabsToClose.count(); --i >= 0;) widget->closeTabAt(m_TabsToClose.at(i)); + if (widget->availableHelpViewer()== 0) + widget->setSource(QUrl(QLatin1String("about:blank"))); if (m_unregDocs.count()) { foreach (const QString &doc, m_unregDocs) @@ -483,22 +488,23 @@ void PreferencesDialog::updateOptionsPage() homepage = m_helpEngine->customValue(QLatin1String("defaultHomepage"), QLatin1String("help")).toString(); } - m_ui.homePageLineEdit->setText(homepage); - connect(m_ui.currentPageButton, SIGNAL(pressed()), this, - SLOT(currentHomepageChanged())); - connect(m_ui.restoreDefaultHomePageButton, SIGNAL(pressed()), this, - SLOT(restoreDefaultHomepage())); + + int option = m_helpEngine->customValue(QLatin1String("StartOption"), + ShowLastPages).toInt(); + m_ui.helpStartComboBox->setCurrentIndex(option); + + connect(m_ui.blankPageButton, SIGNAL(clicked()), this, SLOT(setBlankPage())); + connect(m_ui.currentPageButton, SIGNAL(clicked()), this, SLOT(setCurrentPage())); + connect(m_ui.defaultPageButton, SIGNAL(clicked()), this, SLOT(setDefaultPage())); } -void PreferencesDialog::restoreDefaultHomepage() +void PreferencesDialog::setBlankPage() { - QString homepage = m_helpEngine->customValue(QLatin1String("defaultHomepage"), - QLatin1String("help")).toString(); - m_ui.homePageLineEdit->setText(homepage); + m_ui.homePageLineEdit->setText(QLatin1String("about:blank")); } -void PreferencesDialog::currentHomepageChanged() +void PreferencesDialog::setCurrentPage() { QString homepage = CentralWidget::instance()->currentSource().toString(); if (homepage.isEmpty()) @@ -507,4 +513,11 @@ void PreferencesDialog::currentHomepageChanged() m_ui.homePageLineEdit->setText(homepage); } +void PreferencesDialog::setDefaultPage() +{ + QString homepage = m_helpEngine->customValue(QLatin1String("defaultHomepage"), + QLatin1String("help")).toString(); + m_ui.homePageLineEdit->setText(homepage); +} + QT_END_NAMESPACE diff --git a/tools/assistant/tools/assistant/preferencesdialog.h b/tools/assistant/tools/assistant/preferencesdialog.h index 5b8ffe8..4471b5f 100644 --- a/tools/assistant/tools/assistant/preferencesdialog.h +++ b/tools/assistant/tools/assistant/preferencesdialog.h @@ -50,6 +50,12 @@ QT_BEGIN_NAMESPACE class FontPanel; class QHelpEngineCore; +enum { + ShowHomePage = 0, + ShowBlankPage = 1, + ShowLastPages = 2 +}; + class PreferencesDialog : public QDialog { Q_OBJECT @@ -72,8 +78,10 @@ private slots: void appFontSettingChanged(int index); void browserFontSettingToggled(bool on); void browserFontSettingChanged(int index); - void restoreDefaultHomepage(); - void currentHomepageChanged(); + + void setBlankPage(); + void setCurrentPage(); + void setDefaultPage(); signals: void updateBrowserFont(); diff --git a/tools/assistant/tools/assistant/preferencesdialog.ui b/tools/assistant/tools/assistant/preferencesdialog.ui index d848b49..279084d 100644 --- a/tools/assistant/tools/assistant/preferencesdialog.ui +++ b/tools/assistant/tools/assistant/preferencesdialog.ui @@ -6,7 +6,7 @@ <rect> <x>0</x> <y>0</y> - <width>359</width> + <width>375</width> <height>266</height> </rect> </property> @@ -187,19 +187,90 @@ <attribute name="title"> <string>Options</string> </attribute> - <layout class="QVBoxLayout" name="verticalLayout_3"> + <layout class="QVBoxLayout" name="verticalLayout_2"> <item> - <widget class="QGroupBox" name="groupBox"> + <widget class="QGroupBox" name="groupBox_2"> <property name="title"> - <string>Homepage</string> + <string/> </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> + <layout class="QHBoxLayout" name="horizontalLayout_3"> <item> - <widget class="QLineEdit" name="homePageLineEdit"/> + <widget class="QLabel" name="label_5"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>On help start:</string> + </property> + </widget> </item> <item> + <widget class="QComboBox" name="helpStartComboBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <item> + <property name="text"> + <string>Show my home page</string> + </property> + </item> + <item> + <property name="text"> + <string>Show a blank page</string> + </property> + </item> + <item> + <property name="text"> + <string>Show my tabs from last session</string> + </property> + </item> + </widget> + </item> + <item> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>54</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </widget> + </item> + <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string/> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> <layout class="QHBoxLayout" name="horizontalLayout_2"> <item> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>Homepage</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="homePageLineEdit"/> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> <spacer name="horizontalSpacer"> <property name="orientation"> <enum>Qt::Horizontal</enum> @@ -213,22 +284,25 @@ </spacer> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QPushButton" name="currentPageButton"> - <property name="text"> - <string>Current Page</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="restoreDefaultHomePageButton"> - <property name="text"> - <string>Restore to default</string> - </property> - </widget> - </item> - </layout> + <widget class="QPushButton" name="currentPageButton"> + <property name="text"> + <string>Current Page</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="blankPageButton"> + <property name="text"> + <string>Blank Page</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="defaultPageButton"> + <property name="text"> + <string>Restore to default</string> + </property> + </widget> </item> </layout> </item> diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index dedee59..510e366 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -2201,8 +2201,6 @@ void Configure::generateBuildKey() QStringList build_options; if (!dictionary["QCONFIG"].isEmpty()) build_options += dictionary["QCONFIG"] + "-config "; - if (dictionary["STL"] == "no") - build_options += "no-stl"; build_options.sort(); // Sorted defines that start with QT_NO_ diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp index 58e094b..21b230e 100644 --- a/tools/linguist/lupdate/cpp.cpp +++ b/tools/linguist/lupdate/cpp.cpp @@ -1676,7 +1676,9 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions) case Tok_trid: if (!results->tor) goto case_default; - if (!sourcetext.isEmpty()) { + 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); diff --git a/tools/linguist/shared/po.cpp b/tools/linguist/shared/po.cpp index 796d012..a6795cb 100644 --- a/tools/linguist/shared/po.cpp +++ b/tools/linguist/shared/po.cpp @@ -359,7 +359,7 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd) const QChar quote = QLatin1Char('"'); const QChar newline = QLatin1Char('\n'); QTextStream in(&dev); - in.setCodec(cd.m_codecForSource.isEmpty() ? "UTF-8" : cd.m_codecForSource); + in.setCodec(cd.m_codecForSource.isEmpty() ? QByteArray("UTF-8") : cd.m_codecForSource); bool error = false; // format of a .po file entry: @@ -555,7 +555,7 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd) { bool ok = true; QTextStream out(&dev); - out.setCodec(cd.m_outputCodec.isEmpty() ? "UTF-8" : cd.m_outputCodec); + out.setCodec(cd.m_outputCodec.isEmpty() ? QByteArray("UTF-8") : cd.m_outputCodec); bool first = true; if (translator.messages().isEmpty() || !translator.messages().first().sourceText().isEmpty()) { diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp index 638e997..dc681f5 100644 --- a/tools/linguist/shared/qm.cpp +++ b/tools/linguist/shared/qm.cpp @@ -553,7 +553,7 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd) //qDebug() << "NUMITEMS: " << numItems; QTextCodec *codec = QTextCodec::codecForName( - cd.m_codecForSource.isEmpty() ? "Latin1" : cd.m_codecForSource); + cd.m_codecForSource.isEmpty() ? QByteArray("Latin1") : cd.m_codecForSource); QTextCodec *utf8Codec = 0; if (codec->name() != "UTF-8") utf8Codec = QTextCodec::codecForName("UTF-8"); diff --git a/tools/qdoc3/codemarker.cpp b/tools/qdoc3/codemarker.cpp index e95153d..4c018d1 100644 --- a/tools/qdoc3/codemarker.cpp +++ b/tools/qdoc3/codemarker.cpp @@ -168,7 +168,8 @@ const Node *CodeMarker::nodeForString(const QString& string) { if (sizeof(const Node *) == sizeof(uint)) { return reinterpret_cast<const Node *>(string.toUInt()); - } else { + } + else { return reinterpret_cast<const Node *>(string.toULongLong()); } } @@ -177,7 +178,8 @@ QString CodeMarker::stringForNode(const Node *node) { if (sizeof(const Node *) == sizeof(ulong)) { return QString::number(reinterpret_cast<ulong>(node)); - } else { + } + else { return QString::number(reinterpret_cast<qulonglong>(node)); } } @@ -220,7 +222,8 @@ QString CodeMarker::typified(const QString &string) || ch.digitValue() >= 0 || ch == QLatin1Char('_') || ch == QLatin1Char(':')) { pendingWord += ch; - } else { + } + else { if (!pendingWord.isEmpty()) { bool isProbablyType = (pendingWord != QLatin1String("const")); if (isProbablyType) @@ -251,7 +254,7 @@ QString CodeMarker::typified(const QString &string) return result; } -QString CodeMarker::taggedNode(const Node *node) +QString CodeMarker::taggedNode(const Node* node) { QString tag; @@ -276,10 +279,34 @@ QString CodeMarker::taggedNode(const Node *node) break; default: tag = QLatin1String("@unknown"); + break; + } + return QLatin1Char('<') + tag + QLatin1Char('>') + protect(node->name()) + + QLatin1String("</") + tag + QLatin1Char('>'); +} + +#ifdef QDOC_QML +QString CodeMarker::taggedQmlNode(const Node* node) +{ + QString tag; + switch (node->type()) { + case Node::QmlProperty: + tag = QLatin1String("@property"); + break; + case Node::QmlSignal: + tag = QLatin1String("@signal"); + break; + case Node::QmlMethod: + tag = QLatin1String("@method"); + break; + default: + tag = QLatin1String("@unknown"); + break; } return QLatin1Char('<') + tag + QLatin1Char('>') + protect(node->name()) + QLatin1String("</") + tag + QLatin1Char('>'); } +#endif QString CodeMarker::linkTag(const Node *node, const QString& body) { @@ -308,9 +335,11 @@ QString CodeMarker::sortName(const Node *node) QString sortNo; if (func->metaness() == FunctionNode::Ctor) { sortNo = QLatin1String("C"); - } else if (func->metaness() == FunctionNode::Dtor) { + } + else if (func->metaness() == FunctionNode::Dtor) { sortNo = QLatin1String("D"); - } else { + } + else { if (nodeName.startsWith(QLatin1String("operator")) && nodeName.length() > 8 && !nodeName[8].isLetterOrNumber()) @@ -336,9 +365,14 @@ void CodeMarker::insert(FastSection &fastSection, SynopsisStyle style, Status status) { - bool inheritedMember = (!node->relates() && - (node->parent() != (const InnerNode *)fastSection.innerNode)); bool irrelevant = false; + bool inheritedMember = false; + if (!node->relates()) { + if (node->parent() != (const InnerNode*)fastSection.innerNode) { + if (node->type() != Node::QmlProperty) + inheritedMember = true; + } + } if (node->access() == Node::Private) { irrelevant = true; @@ -462,7 +496,8 @@ QStringList CodeMarker::macRefsForNode(const Node *node) #if 0 if (!classe->templateStuff().isEmpty()) { result += QLatin1String("tmplt/"); - } else + } + else #endif { result += QLatin1String("cl/"); @@ -499,14 +534,18 @@ QStringList CodeMarker::macRefsForNode(const Node *node) result += QLatin1String("macro/"); isMacro = true; #if 0 - } else if (!func->templateStuff().isEmpty()) { + } + else if (!func->templateStuff().isEmpty()) { result += QLatin1String("ftmplt/"); #endif - } else if (func->isStatic()) { + } + else if (func->isStatic()) { result += QLatin1String("clm/"); - } else if (!func->parent()->name().isEmpty()) { + } + else if (!func->parent()->name().isEmpty()) { result += QLatin1String("instm/"); - } else { + } + else { result += QLatin1String("func/"); } @@ -520,7 +559,8 @@ QStringList CodeMarker::macRefsForNode(const Node *node) result += "/" + QLatin1String(QMetaObject::normalizedSignature(func->returnType().toLatin1().constData())) + "/("; const QList<Parameter> ¶ms = func->parameters(); for (int i = 0; i < params.count(); ++i) { - QString type = params.at(i).leftType() + params.at(i).rightType(); + QString type = params.at(i).leftType() + + params.at(i).rightType(); type = QLatin1String(QMetaObject::normalizedSignature(type.toLatin1().constData())); if (i != 0) result += ","; @@ -563,10 +603,21 @@ QString CodeMarker::macName(const Node *node, const QString &name) if (node->name().isEmpty()) { return QLatin1Char('/') + myName; - } else { + } + else { return plainFullName(node) + QLatin1Char('/') + myName; } } +#ifdef QDOC_QML +/*! + Get the list of documentation sections for the children of + the specified QmlClassNode. + */ +QList<Section> CodeMarker::qmlSections(const QmlClassNode* , SynopsisStyle ) +{ + return QList<Section>(); +} +#endif QT_END_NAMESPACE diff --git a/tools/qdoc3/codemarker.h b/tools/qdoc3/codemarker.h index 67b1064..91dc8b0 100644 --- a/tools/qdoc3/codemarker.h +++ b/tools/qdoc3/codemarker.h @@ -121,6 +121,9 @@ class CodeMarker virtual QString markedUpSynopsis(const Node *node, const Node *relative, SynopsisStyle style) = 0; +#ifdef QDOC_QML + virtual QString markedUpQmlItem(const Node* , bool) { return QString(); } +#endif virtual QString markedUpName(const Node *node) = 0; virtual QString markedUpFullName(const Node *node, const Node *relative = 0) = 0; @@ -132,6 +135,10 @@ class CodeMarker virtual QList<Section> sections(const InnerNode *inner, SynopsisStyle style, Status status) = 0; +#ifdef QDOC_QML + virtual QList<Section> qmlSections(const QmlClassNode* qmlClassNode, + SynopsisStyle style); +#endif virtual const Node *resolveTarget(const QString& target, const Tree *tree, const Node *relative) = 0; @@ -151,7 +158,10 @@ class CodeMarker virtual QString sortName(const Node *node); QString protect(const QString &string); QString typified(const QString &string); - QString taggedNode(const Node *node); + QString taggedNode(const Node* node); +#ifdef QDOC_QML + QString taggedQmlNode(const Node* node); +#endif QString linkTag(const Node *node, const QString& body); void insert(FastSection &fastSection, Node *node, diff --git a/tools/qdoc3/command.cpp b/tools/qdoc3/command.cpp index e51e235..bce262b 100644 --- a/tools/qdoc3/command.cpp +++ b/tools/qdoc3/command.cpp @@ -49,44 +49,46 @@ QT_BEGIN_NAMESPACE -void executeCommand( const Location& location, const QString& format, - const QStringList& args ) +void executeCommand(const Location& location, + const QString& format, + const QStringList& args) { QString actualCommand; - for ( int i = 0; i < (int) format.length(); i++ ) { + for (int i = 0; i < (int) format.length(); i++) { int ch = format[i].unicode(); - if ( ch > 0 && ch < 8 ) { + if (ch > 0 && ch < 8) { actualCommand += args[ch - 1]; - } else { + } + else { actualCommand += format[i]; } } QString toolName = actualCommand; - int space = toolName.indexOf( QLatin1Char(' ') ); - if ( space != -1 ) - toolName.truncate( space ); + int space = toolName.indexOf(QLatin1Char(' ')); + if (space != -1) + toolName.truncate(space); QProcess process; process.start(QLatin1String("sh"), - QStringList() << QLatin1String("-c") << actualCommand ); + QStringList() << QLatin1String("-c") << actualCommand); process.waitForFinished(); if (process.exitCode() == 127) - location.fatal( tr("Couldn't launch the '%1' tool") - .arg(toolName), - tr("Make sure the tool is installed and in the" - " path.") ); + location.fatal(tr("Couldn't launch the '%1' tool") + .arg(toolName), + tr("Make sure the tool is installed and in the" + " path.")); QString errors = QString::fromLocal8Bit(process.readAllStandardError()); - while ( errors.endsWith(QLatin1Char('\n')) ) - errors.truncate( errors.length() - 1 ); - if ( !errors.isEmpty() ) - location.fatal( tr("The '%1' tool encountered some problems") - .arg(toolName), - tr("The tool was invoked like this:\n%1\n" - "It emitted these errors:\n%2") - .arg(actualCommand).arg(errors) ); + while (errors.endsWith(QLatin1Char('\n'))) + errors.truncate(errors.length() - 1); + if (!errors.isEmpty()) + location.fatal(tr("The '%1' tool encountered some problems") + .arg(toolName), + tr("The tool was invoked like this:\n%1\n" + "It emitted these errors:\n%2") + .arg(actualCommand).arg(errors)); } QT_END_NAMESPACE diff --git a/tools/qdoc3/config.h b/tools/qdoc3/config.h index 4e97d9f..22cb671 100644 --- a/tools/qdoc3/config.h +++ b/tools/qdoc3/config.h @@ -140,6 +140,7 @@ class Config #define CONFIG_INDEXES "indexes" #define CONFIG_LANGUAGE "language" #define CONFIG_MACRO "macro" +#define CONFIG_OBSOLETELINKS "obsoletelinks" #define CONFIG_OUTPUTDIR "outputdir" #define CONFIG_OUTPUTLANGUAGE "outputlanguage" #define CONFIG_OUTPUTFORMATS "outputformats" diff --git a/tools/qdoc3/cppcodemarker.cpp b/tools/qdoc3/cppcodemarker.cpp index f807609..0f8d1b7 100644 --- a/tools/qdoc3/cppcodemarker.cpp +++ b/tools/qdoc3/cppcodemarker.cpp @@ -284,7 +284,7 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node, } else { for (int i = 0; i < documentedItems.size(); ++i) { - if (i < MaxEnumValues - 2 || i == documentedItems.size() - 1) { + if (i < MaxEnumValues-2 || i == documentedItems.size()-1) { if (i != 0) synopsis += ", "; synopsis += documentedItems.at(i); @@ -345,6 +345,43 @@ QString CppCodeMarker::markedUpSynopsis(const Node *node, return synopsis + extra; } +#ifdef QDOC_QML +/*! + */ +QString CppCodeMarker::markedUpQmlItem(const Node* node, bool summary) +{ + QString name = taggedQmlNode(node); + if (summary) { + name = linkTag(node,name); + } + name = "<@name>" + name + "</@name>"; + QString synopsis = name; + if (node->type() == Node::QmlProperty) { + const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(node); + synopsis += " : " + typified(pn->dataType()); + } + + QString extra; + if (summary) { + if (node->status() == Node::Preliminary) { + extra += " (preliminary)"; + } + else if (node->status() == Node::Deprecated) { + extra += " (deprecated)"; + } + else if (node->status() == Node::Obsolete) { + extra += " (obsolete)"; + } + } + + if (!extra.isEmpty()) { + extra.prepend("<@extra>"); + extra.append("</@extra>"); + } + return synopsis + extra; +} +#endif + QString CppCodeMarker::markedUpName(const Node *node) { QString name = linkTag(node, taggedNode(node)); @@ -537,7 +574,7 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner, else if (isStatic) { if ((*c)->type() != Node::Variable || !(*c)->doc().isEmpty()) - insert(staticPublicMembers, *c, style, status); + insert(staticPublicMembers,*c,style,status); } else if ((*c)->type() == Node::Property) { insert(properties, *c, style, status); @@ -561,11 +598,11 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner, else if (isStatic) { if ((*c)->type() != Node::Variable || !(*c)->doc().isEmpty()) - insert(staticProtectedMembers, *c, style, status); + insert(staticProtectedMembers,*c,style,status); } else if ((*c)->type() == Node::Variable) { if (!(*c)->doc().isEmpty()) - insert(protectedVariables, *c, style, status); + insert(protectedVariables,*c,style,status); } else if ((*c)->type() == Node::Function) { if (!insertReimpFunc(protectedFunctions,*c,status)) @@ -582,14 +619,14 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner, else if (isStatic) { if ((*c)->type() != Node::Variable || !(*c)->doc().isEmpty()) - insert(staticPrivateMembers, *c, style, status); + insert(staticPrivateMembers,*c,style,status); } else if ((*c)->type() == Node::Function) { if (!insertReimpFunc(privateFunctions,*c,status)) insert(privateFunctions, *c, style, status); } else { - insert(privateTypes, *c, style, status); + insert(privateTypes,*c,style,status); } } ++c; @@ -706,17 +743,23 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner, "Namespaces", "namespace", "namespaces"); - FastSection classes(inner, "Classes", "class", "classes"); + FastSection classes(inner, + "Classes", + "class", + "classes"); FastSection types(inner, - style == Summary ? "Types" : "Type Documentation", + style == Summary ? + "Types" : "Type Documentation", "type", "types"); FastSection functions(inner, - style == Summary ? "Functions" : "Function Documentation", + style == Summary ? + "Functions" : "Function Documentation", "function", "functions"); FastSection macros(inner, - style == Summary ? "Macros" : "Macro Documentation", + style == Summary ? + "Macros" : "Macro Documentation", "macro", "macros"); @@ -1051,4 +1094,82 @@ QString CppCodeMarker::addMarkUp(const QString& protectedCode, return result; } +#ifdef QDOC_QML +/*! + This function is for documenting QML properties. It returns + the list of documentation sections for the children of the + \a qmlClassNode. + + Currently, it only handles QML property groups. + */ +QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode, + SynopsisStyle style) +{ + QList<Section> sections; + if (qmlClassNode) { + if (style == Summary) { + FastSection qmlproperties(qmlClassNode, + "QML Properties", + "property", + "properties"); + FastSection qmlsignals(qmlClassNode, + "QML Signals", + "signal", + "signals"); + FastSection qmlmethods(qmlClassNode, + "QML Methods", + "method", + "methods"); + + NodeList::ConstIterator c = qmlClassNode->childNodes().begin(); + while (c != qmlClassNode->childNodes().end()) { + if ((*c)->subType() == Node::QmlPropertyGroup) { + const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(*c); + NodeList::ConstIterator p = qpgn->childNodes().begin(); + while (p != qpgn->childNodes().end()) { + if ((*p)->type() == Node::QmlProperty) { + insert(qmlproperties,*p,style,Okay); + } + ++p; + } + } + else if ((*c)->type() == Node::QmlSignal) { + insert(qmlsignals,*c,style,Okay); + } + else if ((*c)->type() == Node::QmlMethod) { + insert(qmlmethods,*c,style,Okay); + } + ++c; + } + append(sections,qmlproperties); + append(sections,qmlsignals); + append(sections,qmlmethods); + } + else if (style == Detailed) { + FastSection qmlproperties(qmlClassNode,"QML Property Documentation"); + FastSection qmlsignals(qmlClassNode,"QML Signal Documentation"); + FastSection qmlmethods(qmlClassNode,"QML Method Documentation"); + NodeList::ConstIterator c = qmlClassNode->childNodes().begin(); + while (c != qmlClassNode->childNodes().end()) { + if ((*c)->subType() == Node::QmlPropertyGroup) { + insert(qmlproperties,*c,style,Okay); + } + else if ((*c)->type() == Node::QmlSignal) { + insert(qmlsignals,*c,style,Okay); + } + else if ((*c)->type() == Node::QmlMethod) { + insert(qmlmethods,*c,style,Okay); + } + ++c; + } + append(sections,qmlproperties); + append(sections,qmlsignals); + append(sections,qmlmethods); + } + } + + return sections; +} +#endif + QT_END_NAMESPACE diff --git a/tools/qdoc3/cppcodemarker.h b/tools/qdoc3/cppcodemarker.h index 2967dfe..fa3cb78 100644 --- a/tools/qdoc3/cppcodemarker.h +++ b/tools/qdoc3/cppcodemarker.h @@ -67,6 +67,9 @@ class CppCodeMarker : public CodeMarker QString markedUpSynopsis(const Node *node, const Node *relative, SynopsisStyle style); +#ifdef QDOC_QML + QString markedUpQmlItem(const Node *node, bool summary); +#endif QString markedUpName(const Node *node); QString markedUpFullName(const Node *node, const Node *relative); QString markedUpEnumValue(const QString &enumValue, const Node *relative); @@ -76,6 +79,8 @@ class CppCodeMarker : public CodeMarker QList<Section> sections(const InnerNode *innerNode, SynopsisStyle style, Status status); + QList<Section> qmlSections(const QmlClassNode* qmlClassNode, + SynopsisStyle style); const Node *resolveTarget(const QString& target, const Tree *tree, const Node *relative); diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp index dd10c1c..4563f65 100644 --- a/tools/qdoc3/cppcodeparser.cpp +++ b/tools/qdoc3/cppcodeparser.cpp @@ -87,6 +87,10 @@ QT_BEGIN_NAMESPACE #ifdef QDOC_QML #define COMMAND_QMLCLASS Doc::alias("qmlclass") #define COMMAND_QMLPROPERTY Doc::alias("qmlproperty") +#define COMMAND_QMLINHERITS Doc::alias("inherits") +#define COMMAND_QMLSIGNAL Doc::alias("qmlsignal") +#define COMMAND_QMLMETHOD Doc::alias("qmlmethod") +#define COMMAND_QMLDEFAULT Doc::alias("default") #endif QStringList CppCodeParser::exampleFiles; @@ -109,7 +113,8 @@ static void extractPageLinkAndDesc(const QString &arg, if (arg.contains(".html") && spaceAt != -1) { *link = arg.left(spaceAt).trimmed(); *desc = arg.mid(spaceAt).trimmed(); - } else { + } + else { *link = arg; *desc = arg; } @@ -202,11 +207,6 @@ void CppCodeParser::initializeParser(const Config &config) nodeTypeMap.insert(COMMAND_PROPERTY, Node::Property); nodeTypeMap.insert(COMMAND_VARIABLE, Node::Variable); -#ifdef QDOC_QML - // nodeTypeMap.insert(COMMAND_QMLCLASS, Node::Class); - nodeTypeMap.insert(COMMAND_QMLPROPERTY, Node::Property); -#endif - exampleFiles = config.getStringList(CONFIG_EXAMPLES); exampleDirs = config.getStringList(CONFIG_EXAMPLEDIRS); QStringList exampleFilePatterns = config.getStringList( @@ -477,13 +477,15 @@ QSet<QString> CppCodeParser::topicCommands() << COMMAND_PROPERTY << COMMAND_SERVICE << COMMAND_TYPEDEF -#ifdef QDOC_QML +#ifdef QDOC_QML << COMMAND_VARIABLE << COMMAND_QMLCLASS - << COMMAND_QMLPROPERTY; -#else + << COMMAND_QMLPROPERTY + << COMMAND_QMLSIGNAL + << COMMAND_QMLMETHOD; +#else << COMMAND_VARIABLE; -#endif +#endif } /*! @@ -587,7 +589,7 @@ Node *CppCodeParser::processTopicCommand(const Doc& doc, The command was neither "fn" nor "macro" . */ // ### split(" ") hack is there to support header file syntax - QStringList paths = arg.split(" "); + QStringList paths = arg.split(" "); QStringList path = paths[0].split("::"); Node *node = 0; if (!usedNamespaces.isEmpty()) { @@ -627,49 +629,169 @@ Node *CppCodeParser::processTopicCommand(const Doc& doc, } } + if (command == COMMAND_CLASS) { + if (paths.size() > 1) { + if (!paths[1].endsWith(".h")) { + ClassNode*cnode = static_cast<ClassNode*>(node); + cnode->setQmlElement(paths[1]); + } + } + } return node; } else if (command == COMMAND_EXAMPLE) { - FakeNode *fake = new FakeNode(tre->root(), arg, FakeNode::Example); + FakeNode *fake = new FakeNode(tre->root(), arg, Node::Example); createExampleFileNodes(fake); return fake; } else if (command == COMMAND_EXTERNALPAGE) { - return new FakeNode(tre->root(), arg, FakeNode::ExternalPage); + return new FakeNode(tre->root(), arg, Node::ExternalPage); } else if (command == COMMAND_FILE) { - return new FakeNode(tre->root(), arg, FakeNode::File); + return new FakeNode(tre->root(), arg, Node::File); } else if (command == COMMAND_GROUP) { - return new FakeNode(tre->root(), arg, FakeNode::Group); + return new FakeNode(tre->root(), arg, Node::Group); } else if (command == COMMAND_HEADERFILE) { - return new FakeNode(tre->root(), arg, FakeNode::HeaderFile); + return new FakeNode(tre->root(), arg, Node::HeaderFile); } else if (command == COMMAND_MODULE) { - return new FakeNode(tre->root(), arg, FakeNode::Module); + return new FakeNode(tre->root(), arg, Node::Module); } else if (command == COMMAND_PAGE) { - return new FakeNode(tre->root(), arg, FakeNode::Page); + return new FakeNode(tre->root(), arg, Node::Page); } -#ifdef QDOC_QML +#ifdef QDOC_QML else if (command == COMMAND_QMLCLASS) { const ClassNode* classNode = 0; - QStringList names = arg.split(" "); - //qDebug() << "QMLCLASS" << names; + QStringList names = arg.split(" "); if (names.size() > 1) { Node* n = tre->findNode(names[1].split("::"),Node::Class); - if (n) { + if (n) classNode = static_cast<const ClassNode*>(n); - //qDebug() << "FOUND IT!" << classNode->name(); + } + return new QmlClassNode(tre->root(), names[0], classNode); + } + else if ((command == COMMAND_QMLSIGNAL) || + (command == COMMAND_QMLMETHOD)) { + QString element; + QString name; + QmlClassNode* qmlClass = 0; + if (splitQmlArg(doc,arg,element,name)) { + 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); + else + return new QmlMethodNode(qmlClass,name); } } - return new QmlNode(tre->root(), names[0], classNode); } -#endif +#endif return 0; } +#ifdef QDOC_QML + +/*! + A QML property argument has the form... + + <type> <element>::<name> + + This function splits the argument into those three + parts, sets \a type, \a element, and \a property, + and returns true. If any of the parts isn't found, + a debug message is output and false is returned. + */ +bool CppCodeParser::splitQmlPropertyArg(const Doc& doc, + const QString& arg, + QString& type, + QString& element, + QString& property) +{ + QStringList blankSplit = arg.split(" "); + if (blankSplit.size() > 1) { + type = blankSplit[0]; + QStringList colonSplit(blankSplit[1].split("::")); + if (colonSplit.size() > 1) { + element = colonSplit[0]; + property = colonSplit[1]; + return true; + } + else + doc.location().warning(tr("Missing QML element name or property name")); + } + else + doc.location().warning(tr("Missing QML property type or property path")); + return false; +} + +/*! + A QML signal or method argument has the form... + + <element>::<name> + + 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) +{ + QStringList colonSplit(arg.split("::")); + if (colonSplit.size() > 1) { + element = colonSplit[0]; + name = colonSplit[1]; + return true; + } + else + doc.location().warning(tr("Missing QML element name or signal/method name")); + return false; +} + +/*! + Process the topic \a command group with arguments \a args. + + Currently, this function is called only for \e{qmlproperty}. + */ +Node *CppCodeParser::processTopicCommandGroup(const Doc& doc, + const QString& command, + const QStringList& args) +{ + QmlPropGroupNode* qmlPropGroup = 0; + if (command == COMMAND_QMLPROPERTY) { + QString type; + QString element; + QString property; + 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); + } + } + if (qmlPropGroup) { + new QmlPropertyNode(qmlPropGroup,property,type); + ++arg; + while (arg != args.end()) { + if (splitQmlPropertyArg(doc,(*arg),type,element,property)) { + new QmlPropertyNode(qmlPropGroup,property,type); + } + ++arg; + } + } + } + return qmlPropGroup; +} +#endif + /*! Returns the set of strings representing the common metacommands plus some other metacommands. @@ -684,7 +806,13 @@ QSet<QString> CppCodeParser::otherMetaCommands() << COMMAND_NEXTPAGE << COMMAND_PREVIOUSPAGE << COMMAND_INDEXPAGE +#ifdef QDOC_QML + << COMMAND_STARTPAGE + << COMMAND_QMLINHERITS + << COMMAND_QMLDEFAULT; +#else << COMMAND_STARTPAGE; +#endif } /*! @@ -759,14 +887,19 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc, else if (command == COMMAND_RELATES) { InnerNode *pseudoParent; if (arg.startsWith("<") || arg.startsWith("\"")) { - pseudoParent = static_cast<InnerNode *>(tre->findNode(QStringList(arg), Node::Fake)); + pseudoParent = + static_cast<InnerNode *>(tre->findNode(QStringList(arg), + Node::Fake)); } else { QStringList newPath = arg.split("::"); - pseudoParent = static_cast<InnerNode *>(tre->findNode(QStringList(newPath), Node::Class)); + pseudoParent = + static_cast<InnerNode*>(tre->findNode(QStringList(newPath), + Node::Class)); if (!pseudoParent) - pseudoParent = static_cast<InnerNode *>(tre->findNode(QStringList(newPath), - Node::Namespace)); + pseudoParent = + static_cast<InnerNode*>(tre->findNode(QStringList(newPath), + Node::Namespace)); } if (!pseudoParent) { doc.location().warning(tr("Cannot find '%1' in '\\%2'") @@ -791,6 +924,15 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc, else if (command == COMMAND_STARTPAGE) { setLink(node, Node::StartLink, arg); } +#ifdef QDOC_QML + else if (command == COMMAND_QMLINHERITS) { + setLink(node, Node::InheritsLink, arg); + } + else if (command == COMMAND_QMLDEFAULT) { + QmlPropGroupNode* qpgn = static_cast<QmlPropGroupNode*>(node); + qpgn->setDefault(); + } +#endif else { processCommonMetaCommand(doc.location(),command,arg,node,tre); } @@ -870,9 +1012,8 @@ bool CppCodeParser::match(int target) readToken(); return true; } - else { + else return false; - } } /*! @@ -907,11 +1048,14 @@ bool CppCodeParser::matchTemplateAngles(CodeChunk *dataType) do { if (tok == Tok_LeftAngle) { leftAngleDepth++; - } else if (tok == Tok_RightAngle) { + } + else if (tok == Tok_RightAngle) { leftAngleDepth--; - } else if (tok == Tok_LeftParen || tok == Tok_LeftBrace) { + } + else if (tok == Tok_LeftParen || tok == Tok_LeftBrace) { ++parenAndBraceDepth; - } else if (tok == Tok_RightParen || tok == Tok_RightBrace) { + } + else if (tok == Tok_RightParen || tok == Tok_RightBrace) { if (--parenAndBraceDepth < 0) return false; } @@ -974,7 +1118,8 @@ bool CppCodeParser::matchDataType(CodeChunk *dataType, QString *var) dataType->append(previousLexeme()); else return false; - } else if (match(Tok_int) || match(Tok_char) || match(Tok_double)) { + } + else if (match(Tok_int) || match(Tok_char) || match(Tok_double)) { dataType->append(previousLexeme()); } @@ -1074,8 +1219,10 @@ bool CppCodeParser::matchParameter(FunctionNode *func) readToken(); } } - func->addParameter(Parameter(dataType.toString(), "", name, - defaultValue.toString())); // ### + func->addParameter(Parameter(dataType.toString(), + "", + name, + defaultValue.toString())); // ### return true; } @@ -1123,7 +1270,8 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, compat = true; if (tok == Tok_operator && - (returnType.toString().isEmpty() || returnType.toString().endsWith("::"))) { + (returnType.toString().isEmpty() || + returnType.toString().endsWith("::"))) { // 'QString::operator const char *()' parentPath = returnType.toString().split(sep); parentPath.removeAll(QString()); @@ -1159,11 +1307,10 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, name = previousLexeme(); matchTemplateAngles(); - if (match(Tok_Gulbrandsen)) { + if (match(Tok_Gulbrandsen)) parentPath.append(name); - } else { + else break; - } } if (tok == Tok_operator) { @@ -1176,7 +1323,9 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, break; } } - if (parent && (tok == Tok_Semicolon || tok == Tok_LeftBracket || tok == Tok_Colon) + if (parent && (tok == Tok_Semicolon || + tok == Tok_LeftBracket || + tok == Tok_Colon) && access != Node::Private) { if (tok == Tok_LeftBracket) { returnType.appendHotspot(); @@ -1190,7 +1339,8 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent, } if (tok != Tok_Semicolon) return false; - } else if (tok == Tok_Colon) { + } + else if (tok == Tok_Colon) { returnType.appendHotspot(); while (tok != Tok_Semicolon && tok != Tok_Eoi) { @@ -1382,7 +1532,7 @@ bool CppCodeParser::matchNamespaceDecl(InnerNode *parent) QString namespaceName = previousLexeme(); NamespaceNode *namespasse = 0; if (parent) - namespasse = static_cast<NamespaceNode *>(parent->findNode(namespaceName, Node::Namespace)); + namespasse = static_cast<NamespaceNode*>(parent->findNode(namespaceName, Node::Namespace)); if (!namespasse) { namespasse = new NamespaceNode(parent, namespaceName); namespasse->setAccess(access); @@ -1448,7 +1598,8 @@ bool CppCodeParser::matchEnumItem(InnerNode *parent, EnumNode *enume) if (strVal.isEmpty()) { if (enume->items().isEmpty()) { strVal = "0"; - } else { + } + else { QString last = enume->items().last().value(); bool ok; int n = last.toInt(&ok); @@ -1458,15 +1609,16 @@ bool CppCodeParser::matchEnumItem(InnerNode *parent, EnumNode *enume) strVal = last.left(2) + QString::number(n + 1, 16); else strVal = "0" + QString::number(n + 1, 8); - } else { - strVal = QString::number(n + 1); } + else + strVal = QString::number(n + 1); } } } enume->addItem(EnumItem(name, strVal)); - } else { + } + else { VariableNode *var = new VariableNode(parent, name); var->setAccess(access); var->setLocation(location()); @@ -1554,7 +1706,8 @@ bool CppCodeParser::matchProperty(InnerNode *parent) if (match(Tok_Ident)) { value = previousLexeme(); - } else if (match(Tok_LeftParen)) { + } + else if (match(Tok_LeftParen)) { int depth = 1; while (tok != Tok_Eoi) { if (tok == Tok_LeftParen) { @@ -1807,6 +1960,28 @@ bool CppCodeParser::matchDocsAndStuff() /* There is a topic command. Process it. */ +#ifdef QDOC_QML + if (topic == COMMAND_QMLPROPERTY) { + Doc nodeDoc = doc; + Node *node = processTopicCommandGroup(nodeDoc,topic,args); + if (node != 0) { + nodes.append(node); + docs.append(nodeDoc); + } + } + else { + QStringList::ConstIterator a = args.begin(); + while (a != args.end()) { + Doc nodeDoc = doc; + Node *node = processTopicCommand(nodeDoc,topic,*a); + if (node != 0) { + nodes.append(node); + docs.append(nodeDoc); + } + ++a; + } + } +#else QStringList::ConstIterator a = args.begin(); while (a != args.end()) { Doc nodeDoc = doc; @@ -1817,6 +1992,7 @@ bool CppCodeParser::matchDocsAndStuff() } ++a; } +#endif } NodeList::Iterator n = nodes.begin(); @@ -1824,7 +2000,8 @@ bool CppCodeParser::matchDocsAndStuff() while (n != nodes.end()) { processOtherMetaCommands(*d, *n); (*n)->setDoc(*d); - if ((*n)->isInnerNode() && ((InnerNode *)*n)->includes().isEmpty()) { + if ((*n)->isInnerNode() && + ((InnerNode *)*n)->includes().isEmpty()) { InnerNode *m = static_cast<InnerNode *>(*n); while (m->parent() != tre->root()) m = m->parent(); @@ -1912,7 +2089,8 @@ void CppCodeParser::parseQiteratorDotH(const Location &location, mutableSequentialIteratorDefinition = lines[1]; associativeIteratorDefinition = lines[2]; mutableAssociativeIteratorDefinition = lines[3]; - } else { + } + else { location.warning(tr("The qiterator.h hack failed")); } } @@ -1994,7 +2172,7 @@ void CppCodeParser::createExampleFileNodes(FakeNode *fake) foreach (const QString &exampleFile, exampleFiles) (void) new FakeNode(fake, exampleFile.mid(sizeOfBoringPartOfName), - FakeNode::File); + Node::File); } QT_END_NAMESPACE diff --git a/tools/qdoc3/cppcodeparser.h b/tools/qdoc3/cppcodeparser.h index 1f41318..cbb0149 100644 --- a/tools/qdoc3/cppcodeparser.h +++ b/tools/qdoc3/cppcodeparser.h @@ -90,6 +90,21 @@ class CppCodeParser : public CodeParser virtual Node *processTopicCommand(const Doc& doc, const QString& command, const QString& arg); +#ifdef QDOC_QML + // might need to implement this in QsCodeParser as well. + virtual Node *processTopicCommandGroup(const Doc& doc, + const QString& command, + const QStringList& args); + bool splitQmlPropertyArg(const Doc& doc, + const QString& arg, + QString& type, + QString& element, + QString& property); + bool splitQmlArg(const Doc& doc, + const QString& arg, + QString& element, + QString& name); +#endif virtual QSet<QString> otherMetaCommands(); virtual void processOtherMetaCommand(const Doc& doc, const QString& command, diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp index e97b7f2..e92f53b 100644 --- a/tools/qdoc3/generator.cpp +++ b/tools/qdoc3/generator.cpp @@ -42,7 +42,7 @@ /* generator.cpp */ - +#include <QtCore> #include <qdir.h> #include <qdebug.h> #include "codemarker.h" @@ -77,7 +77,11 @@ static void singularPlural(Text& text, const NodeList& nodes) } Generator::Generator() - : amp("&"), lt("<"), gt(">"), quot("""), tag("</?@[^>]*>") + : amp("&"), + lt("<"), + gt(">"), + quot("""), + tag("</?@[^>]*>") { generators.prepend(this); } @@ -125,7 +129,8 @@ void Generator::initialize(const Config &config) QSet<QString> formats = config.subVars(imagesDotFileExtensions); QSet<QString>::ConstIterator f = formats.begin(); while (f != formats.end()) { - imgFileExts[*f] = config.getStringList(imagesDotFileExtensions + Config::dot + *f); + imgFileExts[*f] = config.getStringList(imagesDotFileExtensions + + Config::dot + *f); ++f; } @@ -133,16 +138,22 @@ void Generator::initialize(const Config &config) while (g != generators.end()) { if (outputFormats.contains((*g)->format())) { (*g)->initializeGenerator(config); - QStringList extraImages = config.getStringList(CONFIG_EXTRAIMAGES + Config::dot - + (*g)->format()); + QStringList extraImages = config.getStringList(CONFIG_EXTRAIMAGES + + Config::dot + + (*g)->format()); QStringList::ConstIterator e = extraImages.begin(); while (e != extraImages.end()) { QString userFriendlyFilePath; - QString filePath = Config::findFile(config.lastLocation(), imageFiles, imageDirs, *e, - imgFileExts[(*g)->format()], userFriendlyFilePath); + QString filePath = Config::findFile(config.lastLocation(), + imageFiles, imageDirs, *e, + imgFileExts[(*g)->format()], + userFriendlyFilePath); if (!filePath.isEmpty()) - Config::copyFile(config.lastLocation(), filePath, userFriendlyFilePath, - (*g)->outputDir() + "/images"); + Config::copyFile(config.lastLocation(), + filePath, + userFriendlyFilePath, + (*g)->outputDir() + + "/images"); ++e; } } @@ -158,20 +169,23 @@ void Generator::initialize(const Config &config) QSet<QString> formats = config.subVars(formattingDotName); QSet<QString>::ConstIterator f = formats.begin(); while (f != formats.end()) { - QString def = config.getString(formattingDotName + Config::dot + - *f); + QString def = config.getString(formattingDotName + + Config::dot + *f); if (!def.isEmpty()) { int numParams = Config::numParams(def); int numOccs = def.count("\1"); if (numParams != 1) { - config.lastLocation().warning(tr("Formatting '%1' must have exactly one" - " parameter (found %2)") - .arg(*n).arg(numParams)); + config.lastLocation().warning(tr("Formatting '%1' must " + "have exactly one " + "parameter (found %2)") + .arg(*n).arg(numParams)); } else if (numOccs > 1) { - config.lastLocation().fatal(tr("Formatting '%1' must contain exactly one" - " occurrence of '\\1' (found %2)") + config.lastLocation().fatal(tr("Formatting '%1' must " + "contain exactly one " + "occurrence of '\\1' " + "(found %2)") .arg(*n).arg(numOccs)); } else { @@ -262,9 +276,14 @@ bool Generator::generateText(const Text& text, } #ifdef QDOC_QML +/*! + Extract sections of markup text surrounded by \e qmltext + and \e endqmltext and output them. + */ bool Generator::generateQmlText(const Text& text, const Node *relative, - CodeMarker *marker) + CodeMarker *marker, + const QString& qmlName) { const Atom* atom = text.firstAtom(); if (atom == 0) @@ -301,9 +320,9 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) } else if (node->type() == Node::Fake) { const FakeNode *fake = static_cast<const FakeNode *>(node); - if (fake->subType() == FakeNode::Example) + if (fake->subType() == Node::Example) generateExampleFiles(fake, marker); - else if (fake->subType() == FakeNode::File) + else if (fake->subType() == Node::File) quiet = true; } @@ -395,7 +414,8 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) FunctionNode *primaryFunc = func->parent()->findFunctionNode(func->name()); if (primaryFunc) { - foreach (const Parameter ¶m, primaryFunc->parameters()) { + foreach (const Parameter ¶m, + primaryFunc->parameters()) { if (param.name() == *a) { needWarning = false; break; @@ -405,7 +425,8 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) } if (needWarning && !func->isReimp()) node->doc().location().warning( - tr("Undocumented parameter '%1' in %2").arg(*a).arg(marker->plainFullName(node))); + tr("Undocumented parameter '%1' in %2") + .arg(*a).arg(marker->plainFullName(node))); } ++a; } @@ -427,7 +448,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker) if (node->type() == Node::Fake) { const FakeNode *fake = static_cast<const FakeNode *>(node); - if (fake->subType() == FakeNode::File) { + if (fake->subType() == Node::File) { Text text; Quoter quoter; Doc::quoteFromFile(fake->doc().location(), quoter, fake->name()); @@ -474,7 +495,8 @@ void Generator::generateInherits(const ClassNode *classe, CodeMarker *marker) if ((*r).access == Node::Protected) { text << " (protected)"; - } else if ((*r).access == Node::Private) { + } + else if ((*r).access == Node::Private) { text << " (private)"; } text << separator(index++, classe->baseClasses().count()); @@ -485,6 +507,15 @@ void Generator::generateInherits(const ClassNode *classe, CodeMarker *marker) } } +#ifdef QDOC_QML +/*! + */ +void Generator::generateQmlInherits(const QmlClassNode* , CodeMarker* ) +{ + // stub. +} +#endif + void Generator::generateInheritedBy(const ClassNode *classe, CodeMarker *marker) { @@ -512,18 +543,21 @@ void Generator::generateExampleFiles(const FakeNode *fake, CodeMarker *marker) QString exampleFile = child->name(); openedList.next(); text << Atom(Atom::ListItemNumber, openedList.numberString()) - << Atom(Atom::ListItemLeft, openedList.styleString()) << Atom::ParaLeft + << Atom(Atom::ListItemLeft, openedList.styleString()) + << Atom::ParaLeft << Atom(Atom::Link, exampleFile) << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK) << exampleFile << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK) - << Atom::ParaRight << Atom(Atom::ListItemRight, openedList.styleString()); + << Atom::ParaRight + << Atom(Atom::ListItemRight, openedList.styleString()); } text << Atom(Atom::ListRight, openedList.styleString()); generateText(text, fake, marker); } -void Generator::generateModuleWarning(const ClassNode *classe, CodeMarker *marker) +void Generator::generateModuleWarning(const ClassNode *classe, + CodeMarker *marker) { QString module = classe->moduleName(); if (!module.isEmpty()) { @@ -544,8 +578,10 @@ void Generator::generateModuleWarning(const ClassNode *classe, CodeMarker *marke << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << Atom::ParaRight; } - else if (module == "Qt3Support" && Tokenizer::isTrue("defined(opensourceedition)")) { - text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) + else if (module == "Qt3Support" && + Tokenizer::isTrue("defined(opensourceedition)")) { + text << Atom::ParaLeft + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) << "Note to Qt Desktop Light Edition users:" << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << " This class is only available in the " @@ -573,10 +609,12 @@ QString Generator::indent(int level, const QString& markedCode) if (markedCode.at(i - 1) == QLatin1Char('>')) break; } - } else { + } + else { if (markedCode.at(i) == QLatin1Char('\n')) { column = 0; - } else { + } + else { if (column == 0) { for (int j = 0; j < level; j++) t += QLatin1Char(' '); @@ -645,7 +683,7 @@ void Generator::setImageFileExtensions(const QStringList& extensions) void Generator::unknownAtom(const Atom *atom) { Location::internalError(tr("unknown atom type '%1' in %2 generator") - .arg(atom->typeString()).arg(format())); + .arg(atom->typeString()).arg(format())); } bool Generator::matchAhead(const Atom *atom, Atom::Type expectedAtomType) @@ -674,7 +712,8 @@ void Generator::supplementAlsoList(const Node *node, QList<Text> &alsoList) alternateFunc = func->parent()->findFunctionNode(alternateName); } } - } else if (!func->name().isEmpty()) { + } + else if (!func->name().isEmpty()) { alternateName = "set"; alternateName += func->name()[0].toUpper(); alternateName += func->name().mid(1); @@ -730,9 +769,13 @@ void Generator::generateStatus(const Node *node, CodeMarker *marker) case Node::Main: break; case Node::Preliminary: - text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) << "This " - << typeString(node) << " is under development and is subject to change." - << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << Atom::ParaRight; + text << Atom::ParaLeft + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) + << "This " + << typeString(node) + << " is under development and is subject to change." + << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) + << Atom::ParaRight; break; case Node::Deprecated: text << Atom::ParaLeft; @@ -750,16 +793,21 @@ void Generator::generateStatus(const Node *node, CodeMarker *marker) text << "This " << typeString(node) << " is obsolete."; if (node->isInnerNode()) text << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD); - text << " It is provided to keep old source code working. We strongly advise against " + text << " It is provided to keep old source code working. " + << "We strongly advise against " << "using it in new code." << Atom::ParaRight; break; case Node::Compat: // reimplemented in HtmlGenerator subclass if (node->isInnerNode()) { - text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) << "This " - << typeString(node) << " is part of the Qt 3 compatibility layer." + text << Atom::ParaLeft + << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) + << "This " + << typeString(node) + << " is part of the Qt 3 compatibility layer." << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) - << " It is provided to keep old source code working. We strongly advise against " + << " It is provided to keep old source code working. " + << "We strongly advise against " << "using it in new code. See " << Atom(Atom::AutoLink, "Porting to Qt 4") << " for more information." @@ -915,7 +963,9 @@ void Generator::generateSince(const Node *node, CodeMarker *marker) { if (!node->since().isEmpty()) { Text text; - text << Atom::ParaLeft << "This " << typeString(node) + text << Atom::ParaLeft + << "This " + << typeString(node) << " was introduced in "; if (project.isEmpty()) text << "version"; @@ -945,7 +995,8 @@ void Generator::generateReimplementedFrom(const FunctionNode *func, { if (func->reimplementedFrom() != 0) { const FunctionNode *from = func->reimplementedFrom(); - if (from->access() != Node::Private && from->parent()->access() != Node::Private) { + if (from->access() != Node::Private && + from->parent()->access() != Node::Private) { Text text; text << Atom::ParaLeft << "Reimplemented from "; QString fullName = from->parent()->name() + "::" + from->name() + "()"; @@ -987,8 +1038,8 @@ const Atom *Generator::generateAtomList(const Atom *atom, if (atom->type() == Atom::FormatEndif) { if (generate && numAtoms0 == numAtoms) { - relative->location().warning(tr("Output format %1 not handled"). - arg(format())); + relative->location().warning(tr("Output format %1 not handled") + .arg(format())); Atom unhandledFormatAtom(Atom::UnhandledFormat, format()); generateAtomList(&unhandledFormatAtom, relative, @@ -999,7 +1050,8 @@ const Atom *Generator::generateAtomList(const Atom *atom, atom = atom->next(); } } - else if (atom->type() == Atom::FormatElse || atom->type() == Atom::FormatEndif) { + else if (atom->type() == Atom::FormatElse || + atom->type() == Atom::FormatEndif) { return atom; } else { @@ -1067,7 +1119,8 @@ void Generator::appendSortedNames(Text& text, r = classes.begin(); while (r != classes.end()) { - if ((*r).node->access() == Node::Public && (*r).node->status() != Node::Internal + if ((*r).node->access() == Node::Public && + (*r).node->status() != Node::Internal && !(*r).node->doc().isEmpty()) { Text className; appendFullName(className, (*r).node, classe, marker); diff --git a/tools/qdoc3/generator.h b/tools/qdoc3/generator.h index cdc4c29..8e3c57e 100644 --- a/tools/qdoc3/generator.h +++ b/tools/qdoc3/generator.h @@ -99,7 +99,10 @@ class Generator #ifdef QDOC_QML virtual bool generateQmlText(const Text& text, const Node *relative, - CodeMarker *marker); + CodeMarker *marker, + const QString& qmlName); + virtual void generateQmlInherits(const QmlClassNode* cn, + CodeMarker* marker); #endif virtual void generateBody(const Node *node, CodeMarker *marker); virtual void generateAlsoList(const Node *node, CodeMarker *marker); diff --git a/tools/qdoc3/helpprojectwriter.cpp b/tools/qdoc3/helpprojectwriter.cpp index cf7c618..f862e55 100644 --- a/tools/qdoc3/helpprojectwriter.cpp +++ b/tools/qdoc3/helpprojectwriter.cpp @@ -118,16 +118,19 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList typeHash["variable"] = Node::Variable; typeHash["target"] = Node::Target; - QHash<QString, FakeNode::SubType> subTypeHash; - subTypeHash["example"] = FakeNode::Example; - subTypeHash["headerfile"] = FakeNode::HeaderFile; - subTypeHash["file"] = FakeNode::File; - subTypeHash["group"] = FakeNode::Group; - subTypeHash["module"] = FakeNode::Module; - subTypeHash["page"] = FakeNode::Page; - subTypeHash["externalpage"] = FakeNode::ExternalPage; - - QSet<FakeNode::SubType> allSubTypes = QSet<FakeNode::SubType>::fromList(subTypeHash.values()); + QHash<QString, Node::SubType> subTypeHash; + subTypeHash["example"] = Node::Example; + subTypeHash["headerfile"] = Node::HeaderFile; + subTypeHash["file"] = Node::File; + subTypeHash["group"] = Node::Group; + subTypeHash["module"] = Node::Module; + subTypeHash["page"] = Node::Page; + subTypeHash["externalpage"] = Node::ExternalPage; +#ifdef QDOC_QML + subTypeHash["qmlclass"] = Node::QmlClass; +#endif + + QSet<Node::SubType> allSubTypes = QSet<Node::SubType>::fromList(subTypeHash.values()); foreach (const QString &selector, selectors) { QStringList pieces = selector.split(":"); @@ -139,7 +142,7 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList QString lower = pieces[0].toLower(); pieces = pieces[1].split(","); if (typeHash.contains(lower)) { - QSet<FakeNode::SubType> subTypes; + QSet<Node::SubType> subTypes; for (int i = 0; i < pieces.size(); ++i) { QString lower = pieces[i].toLower(); if (subTypeHash.contains(lower)) @@ -235,7 +238,7 @@ bool HelpProjectWriter::generateSection(HelpProject &project, // mask. const FakeNode *fakeNode = static_cast<const FakeNode *>(node); if (subproject.selectors[node->type()].contains(fakeNode->subType()) && - fakeNode->subType() != FakeNode::ExternalPage && + fakeNode->subType() != Node::ExternalPage && !fakeNode->fullTitle().isEmpty()) project.subprojects[name].nodes[objName] = node; @@ -324,10 +327,10 @@ bool HelpProjectWriter::generateSection(HelpProject &project, // attributes. case Node::Fake: { const FakeNode *fakeNode = static_cast<const FakeNode*>(node); - if (fakeNode->subType() != FakeNode::ExternalPage && + if (fakeNode->subType() != Node::ExternalPage && !fakeNode->fullTitle().isEmpty()) { - if (fakeNode->subType() != FakeNode::File) { + if (fakeNode->subType() != Node::File) { if (fakeNode->doc().hasKeywords()) { foreach (const Atom *keyword, fakeNode->doc().keywords()) { if (!keyword->string().isEmpty()) { @@ -485,7 +488,7 @@ void HelpProjectWriter::writeNode(HelpProject &project, QXmlStreamWriter &writer writer.writeAttribute("title", fakeNode->fullTitle()); // qDebug() << "Title:" << fakeNode->fullTitle(); - if (fakeNode->subType() == FakeNode::HeaderFile) { + if (fakeNode->subType() == Node::HeaderFile) { // Write subsections for all members, obsolete members and Qt 3 // members. @@ -609,7 +612,7 @@ void HelpProjectWriter::generateProject(HelpProject &project) while (nextPage) { writeNode(project, writer, nextPage); nextTitle = nextPage->links().value(Node::NextLink).first; - if (nextTitle.isEmpty()) + if(nextTitle.isEmpty()) break; nextPage = const_cast<FakeNode *>(tree->findFakeNodeByTitle(nextTitle)); } diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index f92391e..6590114 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -186,7 +186,7 @@ HtmlGenerator::HtmlGenerator() : helpProjectWriter(0), inLink(false), inContents(false), inSectionHeading(false), inTableHeader(false), numTableRows(0), threeColumnEnumValueTable(true), funcLeftParen("\\S(\\()"), - tre(0), slow(false) + tre(0), slow(false), obsoleteLinks(false) { } @@ -215,6 +215,7 @@ void HtmlGenerator::initializeGenerator(const Config &config) }; Generator::initializeGenerator(config); + obsoleteLinks = config.getBool(QLatin1String(CONFIG_OBSOLETELINKS)); setImageFileExtensions(QStringList() << "png" << "jpg" << "jpeg" << "gif"); int i = 0; while (defaults[i].key) { @@ -223,11 +224,21 @@ void HtmlGenerator::initializeGenerator(const Config &config) i++; } - style = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_STYLE); - postHeader = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_POSTHEADER); - footer = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_FOOTER); - address = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_ADDRESS); - pleaseGenerateMacRef = config.getBool(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_GENERATEMACREFS); + style = config.getString(HtmlGenerator::format() + + Config::dot + + HTMLGENERATOR_STYLE); + postHeader = config.getString(HtmlGenerator::format() + + Config::dot + + HTMLGENERATOR_POSTHEADER); + footer = config.getString(HtmlGenerator::format() + + Config::dot + + HTMLGENERATOR_FOOTER); + address = config.getString(HtmlGenerator::format() + + Config::dot + + HTMLGENERATOR_ADDRESS); + pleaseGenerateMacRef = config.getBool(HtmlGenerator::format() + + Config::dot + + HTMLGENERATOR_GENERATEMACREFS); project = config.getString(CONFIG_PROJECT); @@ -241,10 +252,16 @@ void HtmlGenerator::initializeGenerator(const Config &config) QSet<QString>::ConstIterator edition = editionNames.begin(); while (edition != editionNames.end()) { QString editionName = *edition; - QStringList editionModules = config.getStringList( - CONFIG_EDITION + Config::dot + editionName + Config::dot + "modules"); - QStringList editionGroups = config.getStringList( - CONFIG_EDITION + Config::dot + editionName + Config::dot + "groups"); + QStringList editionModules = config.getStringList(CONFIG_EDITION + + Config::dot + + editionName + + Config::dot + + "modules"); + QStringList editionGroups = config.getStringList(CONFIG_EDITION + + Config::dot + + editionName + + Config::dot + + "groups"); if (!editionModules.isEmpty()) editionModuleMap[editionName] = editionModules; @@ -256,11 +273,17 @@ void HtmlGenerator::initializeGenerator(const Config &config) slow = config.getBool(CONFIG_SLOW); - stylesheets = config.getStringList(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_STYLESHEETS); - customHeadElements = config.getStringList(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_CUSTOMHEADELEMENTS); + stylesheets = config.getStringList(HtmlGenerator::format() + + Config::dot + + HTMLGENERATOR_STYLESHEETS); + customHeadElements = config.getStringList(HtmlGenerator::format() + + Config::dot + + HTMLGENERATOR_CUSTOMHEADELEMENTS); codeIndent = config.getInt(CONFIG_CODEINDENT); - helpProjectWriter = new HelpProjectWriter(config, project.toLower() + ".qhp"); + helpProjectWriter = new HelpProjectWriter(config, + project.toLower() + + ".qhp"); } void HtmlGenerator::terminateGenerator() @@ -304,9 +327,9 @@ void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker) findAllFunctions(tree->root()); findAllLegaleseTexts(tree->root()); findAllNamespaces(tree->root()); -#ifdef ZZZ_QDOC_QML +#ifdef ZZZ_QDOC_QML findAllQmlClasses(tree->root()); -#endif +#endif PageGenerator::generateTree(tree, marker); @@ -410,7 +433,8 @@ int HtmlGenerator::generateAtom(const Atom *atom, QString str; atom = atom->next(); while (atom != 0 && atom->type() != Atom::BriefRight) { - if (atom->type() == Atom::String || atom->type() == Atom::AutoLink) + if (atom->type() == Atom::String || + atom->type() == Atom::AutoLink) str += atom->string(); skipAhead++; atom = atom->next(); @@ -453,14 +477,14 @@ int HtmlGenerator::generateAtom(const Atom *atom, marker,relative)) << "</pre>\n"; break; -#ifdef QDOC_QML +#ifdef QDOC_QML case Atom::Qml: out() << "<pre>" << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()), marker,relative)) << "</pre>\n"; break; -#endif +#endif case Atom::CodeNew: out() << "<p>you can rewrite it as</p>\n" << "<pre>" @@ -976,7 +1000,7 @@ int HtmlGenerator::generateAtom(const Atom *atom, case Atom::EndQmlText: // don't do anything with these. They are just tags. break; -#endif +#endif default: unknownAtom(atom); } @@ -1042,6 +1066,12 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner, generateHeader(title, inner, marker, true); generateTitle(title, subtitleText, SmallSubTitle, inner, marker); +#ifdef QDOC_QML + if (classe && !classe->qmlElement().isEmpty()) { + generateInstantiatedBy(classe,marker); + } +#endif + generateBrief(inner, marker); generateIncludes(inner, marker); generateStatus(inner, marker); @@ -1225,16 +1255,19 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) QList<Section>::const_iterator s; QString htmlTitle = fake->fullTitle(); - if (fake->subType() == FakeNode::File && !fake->subTitle().isEmpty()) { + if (fake->subType() == Node::File && !fake->subTitle().isEmpty()) { subTitleSize = SmallSubTitle; htmlTitle += " (" + fake->subTitle() + ")"; } generateHeader(htmlTitle, fake, marker, true); - generateTitle(fake->fullTitle(), Text() << fake->subTitle(), subTitleSize, - fake, marker); + generateTitle(fake->fullTitle(), + Text() << fake->subTitle(), + subTitleSize, + fake, + marker); - if (fake->subType() == FakeNode::Module) { + if (fake->subType() == Node::Module) { // Generate brief text and status for modules. generateBrief(fake, marker); generateStatus(fake, marker); @@ -1248,7 +1281,7 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) generateAnnotatedList(fake, marker, moduleClassMap[fake->name()]); } } - else if (fake->subType() == FakeNode::HeaderFile) { + else if (fake->subType() == Node::HeaderFile) { // Generate brief text and status for modules. generateBrief(fake, marker); generateStatus(fake, marker); @@ -1295,7 +1328,49 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) appendDcfSubSection(&fakeSection, compatSection); } } +#ifdef QDOC_QML + else if (fake->subType() == Node::QmlClass) { + const QmlClassNode* qml_cn = static_cast<const QmlClassNode*>(fake); + const ClassNode* cn = qml_cn->classNode(); + generateQmlInherits(qml_cn, marker); + generateQmlInstantiates(qml_cn, marker); + generateBrief(qml_cn, marker); + sections = marker->qmlSections(qml_cn,CodeMarker::Summary); + s = sections.begin(); + while (s != sections.end()) { + out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n"; + out() << "<h2>" << protect((*s).name) << "</h2>\n"; + generateQmlSummary(*s,fake,marker); + ++s; + } + out() << "<a name=\"" << registerRef("details") << "\"></a>\n"; + out() << "<h2>" << "Detailed Description" << "</h2>\n"; + generateBody(fake, marker); + if (cn) + generateQmlText(cn->doc().body(), cn, marker, fake->name()); + generateAlsoList(fake, marker); + out() << "<hr />\n"; + + sections = marker->qmlSections(qml_cn,CodeMarker::Detailed); + s = sections.begin(); + while (s != sections.end()) { + out() << "<h2>" << protect((*s).name) << "</h2>\n"; + NodeList::ConstIterator m = (*s).members.begin(); + while (m != (*s).members.end()) { + generateDetailedQmlMember(*m, fake, marker); + out() << "<br />\n"; + fakeSection.keywords += qMakePair((*m)->name(), + linkForNode(*m,0)); + ++m; + } + ++s; + } + generateFooter(fake); + return; + } +#endif + sections = marker->sections(fake, CodeMarker::Summary, CodeMarker::Okay); s = sections.begin(); while (s != sections.end()) { @@ -1306,24 +1381,12 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) } Text brief = fake->doc().briefText(); - if (fake->subType() == FakeNode::Module && !brief.isEmpty()) { + if (fake->subType() == Node::Module && !brief.isEmpty()) { out() << "<a name=\"" << registerRef("details") << "\"></a>\n"; out() << "<h2>" << "Detailed Description" << "</h2>\n"; } generateBody(fake, marker); -#ifdef QDOC_QML - if (fake->subType() == FakeNode::QmlClass) { - //qDebug() << "generateFakeNode(): QML CLASS" << fake->name(); - const QmlNode* qmlNode = static_cast<const QmlNode*>(fake); - const ClassNode* cn = qmlNode->classNode(); - if (cn) { - //qDebug() << " CPP CLASS" << cn->name(); - generateQmlText(cn->doc().body(), cn, marker); - } - } -#endif - generateAlsoList(fake, marker); if (!fake->groupMembers().isEmpty()) { @@ -1353,10 +1416,10 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) } generateFooter(fake); - if (fake->subType() == FakeNode::Example) { + if (fake->subType() == Node::Example) { appendDcfSubSection(&dcfExamplesRoot, fakeSection); } - else if (fake->subType() != FakeNode::File) { + else if (fake->subType() != Node::File) { QString contentsPage = fake->links().value(Node::ContentsLink).first; if (contentsPage == "Qt Designer Manual") { @@ -1643,7 +1706,10 @@ void HtmlGenerator::generateTableOfContents(const Node *node, columnSize = 0; } out() << "<li>"; - out() << "<a href=\"" << nodeName << "#" << Doc::canonicalTitle(headingText.toString()) + out() << "<a href=\"" + << nodeName + << "#" + << Doc::canonicalTitle(headingText.toString()) << "\">"; generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms); out() << "</a></li>\n"; @@ -1693,7 +1759,8 @@ void HtmlGenerator::generateNavigationBar(const NavigationBar& bar, } #endif -QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner, CodeMarker *marker) +QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner, + CodeMarker *marker) { QList<Section> sections; QList<Section>::ConstIterator s; @@ -1744,7 +1811,8 @@ QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner, if (status == CodeMarker::Compat) { title = "Qt 3 Support Members for " + inner->name(); fileName = fileBase(inner) + "-qt3." + fileExtension(inner); - } else { + } + else { title = "Obsolete Members for " + inner->name(); fileName = fileBase(inner) + "-obsolete." + fileExtension(inner); } @@ -1758,10 +1826,11 @@ QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner, "<a href=\"qt3support.html\">Qt 3 support layer</a>.</b> " "They are provided to help you port old code to Qt 4. We advise against " "using them in new code.</p>\n"; - } else { - out() << "<p><b>The following class members are obsolete.</b> They are provided to keep " - "old source code working. We strongly advise against using them in new " - "code.</p>\n"; + } + else { + out() << "<p><b>The following class members are obsolete.</b> " + << "They are provided to keep old source code working. " + << "We strongly advise against using them in new code.</p>\n"; } out() << "<p><ul><li><a href=\"" @@ -1816,8 +1885,10 @@ void HtmlGenerator::generateClassHierarchy(const Node *relative, if (stack.top().isEmpty()) { stack.pop(); out() << "</ul>\n"; - } else { - const ClassNode *child = static_cast<const ClassNode *>(*stack.top().begin()); + } + else { + const ClassNode *child = + static_cast<const ClassNode *>(*stack.top().begin()); out() << "<li>"; generateFullName(child, relative, marker); out() << "</li>\n"; @@ -1836,10 +1907,9 @@ void HtmlGenerator::generateClassHierarchy(const Node *relative, } } -void -HtmlGenerator::generateAnnotatedList(const Node *relative, - CodeMarker *marker, - const QMap<QString,const Node *>&nodeMap) +void HtmlGenerator::generateAnnotatedList(const Node *relative, + CodeMarker *marker, + const QMap<QString, const Node *> &nodeMap) { out() << "<p><table width=\"100%\" class=\"annotated\" cellpadding=\"2\" " << "cellspacing=\"1\" border=\"0\">\n"; @@ -1866,7 +1936,8 @@ HtmlGenerator::generateAnnotatedList(const Node *relative, generateText(brief, node, marker); out() << "</td>"; } - } else { + } + else { out() << "<td>"; out() << protect(node->doc().briefText().toString()); out() << "</td>"; @@ -1876,10 +1947,9 @@ HtmlGenerator::generateAnnotatedList(const Node *relative, out() << "</table></p>\n"; } -void -HtmlGenerator::generateCompactList(const Node *relative, - CodeMarker *marker, - const QMap<QString,const Node*> &classMap) +void HtmlGenerator::generateCompactList(const Node *relative, + CodeMarker *marker, + const QMap<QString, const Node *> &classMap) { const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_' const int NumColumns = 4; // number of columns in the result @@ -1922,8 +1992,9 @@ HtmlGenerator::generateCompactList(const Node *relative, last = classMap.begin().key(); if (classMap.size() > 1) { - while (commonPrefixLen < first.length() + 1 && commonPrefixLen < last.length() + 1 - && first[commonPrefixLen] == last[commonPrefixLen]) + while (commonPrefixLen < first.length() + 1 && + commonPrefixLen < last.length() + 1 && + first[commonPrefixLen] == last[commonPrefixLen]) ++commonPrefixLen; } @@ -1952,7 +2023,8 @@ HtmlGenerator::generateCompactList(const Node *relative, if (key[0].digitValue() != -1) { paragraphNo = key[0].digitValue(); - } else if (key[0] >= QLatin1Char('a') && key[0] <= QLatin1Char('z')) { + } + else if (key[0] >= QLatin1Char('a') && key[0] <= QLatin1Char('z')) { paragraphNo = 10 + key[0].unicode() - 'a'; } @@ -2105,7 +2177,8 @@ void HtmlGenerator::generateFunctionIndex(const Node *relative, #endif } -void HtmlGenerator::generateLegaleseList(const Node *relative, CodeMarker *marker) +void HtmlGenerator::generateLegaleseList(const Node *relative, + CodeMarker *marker) { QMap<Text, const Node *>::ConstIterator it = legaleseTexts.begin(); while (it != legaleseTexts.end()) { @@ -2123,6 +2196,77 @@ void HtmlGenerator::generateLegaleseList(const Node *relative, CodeMarker *marke } } +/*void HtmlGenerator::generateSynopsis(const Node *node, + const Node *relative, + CodeMarker *marker, + CodeMarker::SynopsisStyle style) +{ + QString marked = marker->markedUpSynopsis(node, relative, style); + QRegExp templateTag("(<[^@>]*>)"); + if (marked.indexOf(templateTag) != -1) { + QString contents = protect(marked.mid(templateTag.pos(1), + templateTag.cap(1).length())); + marked.replace(templateTag.pos(1), templateTag.cap(1).length(), + contents); + } + marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"), + "<i>\\1<sub>\\2</sub></i>"); + marked.replace("<@param>", "<i>"); + marked.replace("</@param>", "</i>"); + + if (style == CodeMarker::Summary) + marked.replace("@name>", "b>"); + + if (style == CodeMarker::SeparateList) { + QRegExp extraRegExp("<@extra>.*</@extra>"); + extraRegExp.setMinimal(true); + marked.replace(extraRegExp, ""); + } + else { + marked.replace("<@extra>", " <tt>"); + marked.replace("</@extra>", "</tt>"); + } + + if (style != CodeMarker::Detailed) { + marked.replace("<@type>", ""); + marked.replace("</@type>", ""); + } + out() << highlightedCode(marked, marker, relative); +}*/ + +#ifdef QDOC_QML +void HtmlGenerator::generateQmlItem(const Node *node, + const Node *relative, + CodeMarker *marker, + bool summary) +{ + QString marked = marker->markedUpQmlItem(node,summary); + QRegExp templateTag("(<[^@>]*>)"); + if (marked.indexOf(templateTag) != -1) { + QString contents = protect(marked.mid(templateTag.pos(1), + templateTag.cap(1).length())); + marked.replace(templateTag.pos(1), templateTag.cap(1).length(), + contents); + } + marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"), + "<i>\\1<sub>\\2</sub></i>"); + marked.replace("<@param>", "<i>"); + marked.replace("</@param>", "</i>"); + + if (summary) + marked.replace("@name>", "b>"); + + marked.replace("<@extra>", " <tt>"); + marked.replace("</@extra>", "</tt>"); + + if (summary) { + marked.replace("<@type>", ""); + marked.replace("</@type>", ""); + } + out() << highlightedCode(marked, marker, relative); +} +#endif + void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* marker */) { QMap<const FakeNode *, QMap<QString, FakeNode *> > fakeNodeMap; @@ -2145,7 +2289,7 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m } // there are too many examples; they would clutter the list - if (fakeNode->subType() == FakeNode::Example) + if (fakeNode->subType() == Node::Example) continue; // not interested either in individual (Qt Designer etc.) manual chapters @@ -2153,7 +2297,7 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m continue; // Discard external nodes. - if (fakeNode->subType() == FakeNode::ExternalPage) + if (fakeNode->subType() == Node::ExternalPage) continue; QString sortKey = fakeNode->fullTitle().toLower(); @@ -2178,7 +2322,8 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m groupTitlesMap[fakeNode->fullTitle()] = const_cast<const FakeNode *>(fakeNode); } } - } else if (!isGroupPage) { + } + else if (!isGroupPage) { // If we encounter a page that belongs to a group then // we add that page to the list for that group. const FakeNode *groupNode = static_cast<const FakeNode *>(tre->root()->findNode(group, Node::Fake)); @@ -2737,8 +2882,8 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, if (src.at(i) == charLangle && src.at(i + 1) == charAt) { i += 2; if (parseArg(src, linkTag, &i, n, &arg, &par1)) { - QString link = linkForNode( - CodeMarker::nodeForString(par1.toString()), relative); + const Node* node = CodeMarker::nodeForString(par1.toString()); + QString link = linkForNode(node, relative); addLink(link, arg, &html); } else { @@ -2751,7 +2896,6 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, } } - if (slow) { // is this block ever used at all? // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)" @@ -3076,10 +3220,9 @@ QString HtmlGenerator::fileBase(const Node *node, QString HtmlGenerator::fileName(const Node *node) { if (node->type() == Node::Fake) { - if (static_cast<const FakeNode *>(node)->subType() == FakeNode::ExternalPage) + if (static_cast<const FakeNode *>(node)->subType() == Node::ExternalPage) return node->name(); } - return PageGenerator::fileName(node); } @@ -3101,7 +3244,8 @@ QString HtmlGenerator::refForNode(const Node *node) typedeffe = static_cast<const TypedefNode *>(node); if (typedeffe->associatedEnum()) { return refForNode(typedeffe->associatedEnum()); - } else { + } + else { ref = node->name() + "-typedef"; } break; @@ -3109,15 +3253,27 @@ QString HtmlGenerator::refForNode(const Node *node) func = static_cast<const FunctionNode *>(node); if (func->associatedProperty()) { return refForNode(func->associatedProperty()); - } else { + } + else { ref = func->name(); if (func->overloadNumber() != 1) ref += "-" + QString::number(func->overloadNumber()); } break; case Node::Property: +#ifdef QDOC_QML + case Node::QmlProperty: +#endif ref = node->name() + "-prop"; break; +#ifdef QDOC_QML + case Node::QmlSignal: + ref = node->name() + "-signal"; + break; + case Node::QmlMethod: + ref = node->name() + "-method"; + break; +#endif case Node::Variable: ref = node->name() + "-var"; break; @@ -3166,9 +3322,11 @@ QString HtmlGenerator::refForAtom(Atom *atom, const Node * /* node */) { if (atom->type() == Atom::SectionLeft) { return Doc::canonicalTitle(Text::sectionHeading(atom).toString()); - } else if (atom->type() == Atom::Target) { + } + else if (atom->type() == Atom::Target) { return Doc::canonicalTitle(atom->string()); - } else { + } + else { return QString(); } } @@ -3212,7 +3370,10 @@ void HtmlGenerator::generateDetailedMember(const Node *node, out() << "<a name=\"" + refForNode(node) + "\"></a>"; generateSynopsis(enume, relative, marker, CodeMarker::Detailed); out() << "<br />"; - generateSynopsis(enume->flagsType(), relative, marker, CodeMarker::Detailed); + generateSynopsis(enume->flagsType(), + relative, + marker, + CodeMarker::Detailed); out() << "</h3>\n"; } else { @@ -3364,7 +3525,7 @@ void HtmlGenerator::findAllNamespaces(const InnerNode *node) } } -#ifdef ZZZ_QDOC_QML +#ifdef ZZZ_QDOC_QML /*! This function finds all the qml element nodes and stores them in a map for later use. @@ -3375,24 +3536,16 @@ void HtmlGenerator::findAllQmlClasses(const InnerNode *node) while (c != node->childNodes().constEnd()) { if ((*c)->type() == Node::Fake) { const FakeNode* fakeNode = static_cast<const FakeNode *>(*c); - if (fakeNode->subType() == FakeNode::QmlClass) { - const QmlNode* qmlNode = static_cast<const QmlNode*>(fakeNode); - //qDebug() << "HtmlGenerator: QML CLASS" << qmlNode->name(); + if (fakeNode->subType() == Node::QmlClass) { + const QmlClassNode* qmlNode = + static_cast<const QmlClassNode*>(fakeNode); const Node* n = qmlNode->classNode(); - if (n) - //qDebug() << " FOUND IT!" << n->name(); } qmlClasses.insert(fakeNode->name(),*c); } ++c; } } -#endif - -#if 0 - else if ((*c)->isInnerNode()) { - findAllClasses(static_cast<InnerNode *>(*c)); - } #endif int HtmlGenerator::hOffset(const Node *node) @@ -3534,9 +3687,11 @@ QString HtmlGenerator::getLink(const Atom *atom, } QString name = marker->plainFullName(relative); if (!porting && !name.startsWith("Q3")) { - relative->doc().location().warning(tr("Link to obsolete item '%1' in %2") - .arg(atom->string()) - .arg(name)); + if (obsoleteLinks) { + relative->doc().location().warning(tr("Link to obsolete item '%1' in %2") + .arg(atom->string()) + .arg(name)); + } inObsoleteLink = true; } #if 0 @@ -3705,3 +3860,214 @@ void HtmlGenerator::endLink() } QT_END_NAMESPACE + +#ifdef QDOC_QML + +/*! + Generates the summary for for the \a section. Only used for + sections of QML element documentation. + + Currently handles only the QML property group. + */ +void HtmlGenerator::generateQmlSummary(const Section& section, + const Node *relative, + CodeMarker *marker) +{ + if (!section.members.isEmpty()) { + NodeList::ConstIterator m; + int count = section.members.size(); + bool twoColumn = false; + if (section.members.first()->type() == Node::QmlProperty) { + twoColumn = (count >= 5); + } + if (twoColumn) + out() << "<p><table width=\"100%\" border=\"0\" cellpadding=\"0\"" + " cellspacing=\"0\">\n" + << "<tr><td width=\"45%\" valign=\"top\">"; + out() << "<ul>\n"; + + int row = 0; + m = section.members.begin(); + while (m != section.members.end()) { + if (twoColumn && row == (int) (count + 1) / 2) + out() << "</ul></td><td valign=\"top\"><ul>\n"; + out() << "<li><div class=\"fn\"></div>"; + generateQmlItem(*m,relative,marker,true); + out() << "</li>\n"; + row++; + ++m; + } + out() << "</ul>\n"; + if (twoColumn) + out() << "</td></tr>\n</table></p>\n"; + } +} + +/*! + Outputs the html detailed documentation for a section + on a QML element reference page. + */ +void HtmlGenerator::generateDetailedQmlMember(const Node *node, + const InnerNode *relative, + CodeMarker *marker) +{ + const QmlPropertyNode* qpn = 0; + generateMacRef(node, marker); + out() << "<div class=\"qmlitem\">"; + if (node->subType() == Node::QmlPropertyGroup) { + const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node); + NodeList::ConstIterator p = qpgn->childNodes().begin(); + out() << "<div class=\"qmlproto\">"; + out() << "<table 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>"; + generateQmlItem(qpn, relative, marker, false); + out() << "</td></tr>"; + if (qpgn->isDefault()) { + out() << "</table>" + << "</div></div>" + << "<div class=\"qmlitem\">" + << "<div class=\"qmlproto\">" + << "<table class=\"qmlname\">" + << "<tr><td><font color=\"green\">" + << "default</font></td></tr>"; + } + } + ++p; + } + out() << "</table>"; + out() << "</div>"; + } + else if (node->type() == Node::QmlSignal) { + const QmlSignalNode* qsn = static_cast<const QmlSignalNode*>(node); + out() << "<div class=\"qmlproto\">"; + out() << "<table class=\"qmlname\">"; + out() << "<tr><td>"; + out() << "<a name=\"" + refForNode(qsn) + "\"></a>"; + 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); + out() << "<div class=\"qmlproto\">"; + out() << "<table class=\"qmlname\">"; + out() << "<tr><td>"; + out() << "<a name=\"" + refForNode(qmn) + "\"></a>"; + generateQmlItem(qmn,relative,marker,false); + out() << "</td></tr>"; + out() << "</table>"; + out() << "</div>"; + } + out() << "<div class=\"qmldoc\">"; + generateStatus(node, marker); + generateBody(node, marker); + generateThreadSafeness(node, marker); + generateSince(node, marker); + generateAlsoList(node, marker); + out() << "</div>"; + out() << "</div>"; +} + +/*! + Output the "Inherits" line for the QML element, + if there should be one. + */ +void HtmlGenerator::generateQmlInherits(const QmlClassNode* cn, + CodeMarker* marker) +{ + if (cn && !cn->links().empty()) { + if (cn->links().contains(Node::InheritsLink)) { + QPair<QString,QString> linkPair; + linkPair = cn->links()[Node::InheritsLink]; + QStringList strList(linkPair.first); + const Node* n = tre->findNode(strList,Node::Fake); + if (n && n->subType() == Node::QmlClass) { + const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n); + out() << "<p style=\"text-align: center\">"; + Text text; + text << "[Inherits "; + text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn)); + text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); + text << Atom(Atom::String, linkPair.second); + text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); + text << "]"; + generateText(text, cn, marker); + out() << "</p>"; + } +// else +// qDebug() << "generateQmlInherits(): " +// << "Inherited element not documented -->" +// << linkPair.first; + } + } +} + +/*! + Output the "[Xxx instantiates the C++ class QFxXxx]" + line for the QML element, if there should be one. + + If there is no class node, or if the class node status + is set to Node::Internal, do nothing. + */ +void HtmlGenerator::generateQmlInstantiates(const QmlClassNode* qcn, + CodeMarker* marker) +{ + const ClassNode* cn = qcn->classNode(); + if (cn && (cn->status() != Node::Internal)) { + out() << "<p style=\"text-align: center\">"; + Text text; + text << "["; + text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn)); + text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); + text << Atom(Atom::String, qcn->name()); + text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); + text << " instantiates the C++ class "; + text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn)); + text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); + text << Atom(Atom::String, cn->name()); + text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); + text << "]"; + generateText(text, qcn, marker); + out() << "</p>"; + } +} + +/*! + Output the "[QFxXxx 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 + is set to Node::Internal, do nothing. + */ +void HtmlGenerator::generateInstantiatedBy(const ClassNode* cn, + CodeMarker* marker) +{ + if (cn && cn->status() != Node::Internal && !cn->qmlElement().isEmpty()) { + const Node* n = tre->root()->findNode(cn->qmlElement(),Node::Fake); + if (n && n->subType() == Node::QmlClass) { + out() << "<p style=\"text-align: center\">"; + Text text; + text << "["; + text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn)); + text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); + text << Atom(Atom::String, cn->name()); + text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); + text << " is instantiated by QML element "; + text << Atom(Atom::LinkNode,CodeMarker::stringForNode(n)); + text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK); + text << Atom(Atom::String, n->name()); + text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK); + text << "]"; + generateText(text, cn, marker); + out() << "</p>"; + } + } +} + +#endif diff --git a/tools/qdoc3/htmlgenerator.h b/tools/qdoc3/htmlgenerator.h index a7632cd..c22fe20 100644 --- a/tools/qdoc3/htmlgenerator.h +++ b/tools/qdoc3/htmlgenerator.h @@ -145,6 +145,21 @@ class HtmlGenerator : public PageGenerator const Node *relative, CodeMarker *marker, CodeMarker::SynopsisStyle style); +#ifdef QDOC_QML + void generateQmlSummary(const Section& section, + const Node *relative, + CodeMarker *marker); + void generateQmlItem(const Node *node, + const Node *relative, + CodeMarker *marker, + bool summary); + void generateDetailedQmlMember(const Node *node, + const InnerNode *relative, + CodeMarker *marker); + void generateQmlInherits(const QmlClassNode* cn, CodeMarker* marker); + void generateQmlInstantiates(const QmlClassNode* qcn, CodeMarker* marker); + void generateInstantiatedBy(const ClassNode* cn, CodeMarker* marker); +#endif #ifdef QDOC_NAME_ALIGNMENT void generateSection(const NodeList& nl, const Node *relative, @@ -180,8 +195,12 @@ class HtmlGenerator : public PageGenerator const Node *relative, CodeMarker *marker, const Node *actualNode = 0); - void generateDetailedMember(const Node *node, const InnerNode *relative, CodeMarker *marker); - void generateLink(const Atom *atom, const Node *relative, CodeMarker *marker); + void generateDetailedMember(const Node *node, + const InnerNode *relative, + CodeMarker *marker); + void generateLink(const Atom *atom, + const Node *relative, + CodeMarker *marker); void generateStatus(const Node *node, CodeMarker *marker); QString registerRef(const QString& ref); @@ -252,6 +271,7 @@ class HtmlGenerator : public PageGenerator QStringList customHeadElements; const Tree *tre; bool slow; + bool obsoleteLinks; QMap<QString, QMap<QString, const Node *> > moduleClassMap; QMap<QString, QMap<QString, const Node *> > moduleNamespaceMap; QMap<QString, const Node *> nonCompatClasses; diff --git a/tools/qdoc3/jambiapiparser.cpp b/tools/qdoc3/jambiapiparser.cpp index f981e6d..70e9260 100644 --- a/tools/qdoc3/jambiapiparser.cpp +++ b/tools/qdoc3/jambiapiparser.cpp @@ -234,8 +234,9 @@ void JambiApiParser::doneParsingSourceFiles(Tree * /* tree */) foreach (Node *cppNode, cppTre->root()->childNodes()) { if (cppNode->type() == Node::Fake) { FakeNode *cppFake = static_cast<FakeNode *>(cppNode); - if (cppFake->subType() == FakeNode::Page) { - FakeNode *javaFake = new FakeNode(javaTre->root(), cppFake->name(), + if (cppFake->subType() == Node::Page) { + FakeNode *javaFake = new FakeNode(javaTre->root(), + cppFake->name(), cppFake->subType()); javaFake->setModuleName("com.trolltech.qt"); // ### hard-coded javaFake->setTitle(cppFake->title()); diff --git a/tools/qdoc3/main.cpp b/tools/qdoc3/main.cpp index 6425765..9338203 100644 --- a/tools/qdoc3/main.cpp +++ b/tools/qdoc3/main.cpp @@ -96,6 +96,7 @@ static const struct { static bool slow = false; static bool showInternal = false; +static bool obsoleteLinks = false; static QStringList defines; static QHash<QString, Tree *> trees; @@ -130,7 +131,9 @@ static void printHelp() " -slow " "Turn on features that slow down qdoc\n" " -showinternal " - "Include stuff marked internal") ); + "Include stuff marked internal\n" + " -obsoletelinks " + "Report links from obsolete items to non-obsolete items") ); } /*! @@ -165,6 +168,8 @@ static void processQdocconfFile(const QString &fileName) config.setStringList(CONFIG_SLOW, QStringList(slow ? "true" : "false")); config.setStringList(CONFIG_SHOWINTERNAL, QStringList(showInternal ? "true" : "false")); + config.setStringList(CONFIG_OBSOLETELINKS, + QStringList(obsoleteLinks ? "true" : "false")); /* With the default configuration values in place, load @@ -434,6 +439,9 @@ int main(int argc, char **argv) else if (opt == "-showinternal") { showInternal = true; } + else if (opt == "-obsoletelinks") { + obsoleteLinks = true; + } else { qdocFiles.append(opt); } diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp index b2e53ab..610249d 100644 --- a/tools/qdoc3/node.cpp +++ b/tools/qdoc3/node.cpp @@ -43,6 +43,7 @@ node.cpp */ +#include <QtCore> #include "node.h" QT_BEGIN_NAMESPACE @@ -113,6 +114,9 @@ void Node::setRelates(InnerNode *pseudoParent) } /*! + This function creates a pair that describes a link. + The pair is composed from \a link and \a desc. The + \a linkType is the map index the pair is filed under. */ void Node::setLink(LinkType linkType, const QString &link, const QString &desc) { @@ -623,7 +627,7 @@ void InnerNode::removeRelated(Node *pseudoChild) */ /*! - Returns false because this is an InnerNode. + Returns false because this is a LeafNode. */ bool LeafNode::isInnerNode() const { @@ -713,9 +717,11 @@ void ClassNode::fixBaseClasses() */ /*! + The type of a FakeNode is Fake, and it has a \a subtype, + which specifies the type of FakeNode. */ -FakeNode::FakeNode(InnerNode *parent, const QString& name, SubType subType) - : InnerNode(Fake, parent, name), sub(subType) +FakeNode::FakeNode(InnerNode *parent, const QString& name, SubType subtype) + : InnerNode(Fake, parent, name), sub(subtype) { } @@ -1033,4 +1039,98 @@ bool TargetNode::isInnerNode() const return false; } +#ifdef QDOC_QML +/*! + Constructor for the Qml class node. + */ +QmlClassNode::QmlClassNode(InnerNode *parent, + const QString& name, + const ClassNode* cn) + : FakeNode(parent, name, QmlClass), cnode(cn) +{ + setTitle("QML " + name + " Element Reference"); +} + +/*! + The base file name for this kind of node has "qml_" + prepended to it. + + But not yet. Still testing. + */ +QString QmlClassNode::fileBase() const +{ +#if 0 + if (Node::fileBase() == "item") + qDebug() << "FILEBASE: qmlitem" << name(); + return "qml_" + Node::fileBase(); +#endif + return Node::fileBase(); +} + +/*! + 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) +{ + // nothing. +} + +/*! + Constructor for the QML property node. + */ +QmlPropertyNode::QmlPropertyNode(QmlPropGroupNode *parent, + const QString& name, + const QString& type) + : LeafNode(QmlProperty, parent, name), + dt(type), + sto(Trool_Default), + des(Trool_Default) +{ + // nothing. +} + +/*! + I don't know what this is. + */ +QmlPropertyNode::Trool QmlPropertyNode::toTrool(bool boolean) +{ + return boolean ? Trool_True : Trool_False; +} + +/*! + I don't know what this is either. + */ +bool QmlPropertyNode::fromTrool(Trool troolean, bool defaultValue) +{ + switch (troolean) { + case Trool_True: + return true; + case Trool_False: + return false; + default: + 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 a35bc17..17ec447 100644 --- a/tools/qdoc3/node.h +++ b/tools/qdoc3/node.h @@ -72,7 +72,31 @@ class Node Function, Property, Variable, +#ifdef QDOC_QML + Target, + QmlProperty, + QmlSignal, + QmlMethod +#else Target +#endif + }; + + enum SubType { + NoSubType, + Example, + HeaderFile, + File, + Group, + Module, + Page, +#ifdef QDOC_QML + ExternalPage, + QmlClass, + QmlPropertyGroup +#else + ExternalPage +#endif }; enum Access { Public, Protected, Private }; @@ -99,7 +123,8 @@ class Node NextLink, PreviousLink, ContentsLink, - IndexLink /*, + IndexLink, + InheritsLink /*, GlossaryLink, CopyrightLink, ChapterLink, @@ -125,6 +150,7 @@ class Node virtual bool isInnerNode() const = 0; virtual bool isReimp() const { return false; } Type type() const { return typ; } + virtual SubType subType() const { return NoSubType; } InnerNode *parent() const { return par; } InnerNode *relates() const { return rel; } const QString& name() const { return nam; } @@ -144,7 +170,7 @@ class Node void clearRelated() { rel = 0; } - QString fileBase() const; + virtual QString fileBase() const; protected: Node(Type type, InnerNode *parent, const QString& name); @@ -181,7 +207,7 @@ typedef QList<Node *> NodeList; class InnerNode : public Node { public: - ~InnerNode(); + virtual ~InnerNode(); Node *findNode(const QString& name); Node *findNode(const QString& name, Type type); @@ -203,6 +229,7 @@ class InnerNode : public Node const EnumNode *findEnumNodeForValue(const QString &enumValue) const; const NodeList & childNodes() const { return children; } const NodeList & relatedNodes() const { return related; } + int count() const { return children.size(); } int overloadNumber(const FunctionNode *func) const; int numOverloads(const QString& funcName) const; NodeList overloads(const QString &funcName) const; @@ -232,17 +259,19 @@ class LeafNode : public Node { public: LeafNode(); + virtual ~LeafNode() { } virtual bool isInnerNode() const; protected: - LeafNode(Type type, InnerNode *parent, const QString& name); + LeafNode(Type type, InnerNode* parent, const QString& name); }; class NamespaceNode : public InnerNode { public: NamespaceNode(InnerNode *parent, const QString& name); + virtual ~NamespaceNode() { } }; class ClassNode; @@ -266,6 +295,7 @@ class ClassNode : public InnerNode { public: ClassNode(InnerNode *parent, const QString& name); + virtual ~ClassNode() { } void addBaseClass(Access access, ClassNode *node, @@ -280,29 +310,23 @@ class ClassNode : public InnerNode QString serviceName() const { return sname; } void setServiceName(const QString& value) { sname = value; } + QString qmlElement() const { return qmlelement; } + void setQmlElement(const QString& value) { qmlelement = value; } private: QList<RelatedClass> bas; QList<RelatedClass> der; bool hidden; QString sname; + QString qmlelement; }; class FakeNode : public InnerNode { public: - enum SubType { - Example, - HeaderFile, - File, - Group, - Module, - Page, - ExternalPage, - QmlClass - }; FakeNode(InnerNode *parent, const QString& name, SubType subType); + virtual ~FakeNode() { } void setTitle(const QString &title) { tle = title; } void setSubTitle(const QString &subTitle) { stle = subTitle; } @@ -321,18 +345,85 @@ class FakeNode : public InnerNode NodeList gr; }; -class QmlNode : public FakeNode +#ifdef QDOC_QML +class QmlClassNode : public FakeNode { public: - QmlNode(InnerNode *parent, const QString& name, const ClassNode* cn) - : FakeNode(parent, name, QmlClass), cnode(cn) { } + QmlClassNode(InnerNode *parent, + const QString& name, + const ClassNode* cn); + virtual ~QmlClassNode() { } const ClassNode* classNode() const { return cnode; } + virtual QString fileBase() const; private: const ClassNode* cnode; }; +class QmlPropGroupNode : public FakeNode +{ + public: + QmlPropGroupNode(QmlClassNode* parent, const QString& name); + virtual ~QmlPropGroupNode() { } + + const QString& element() const { return name(); } + void setDefault() { isdefault = true; } + bool isDefault() const { return isdefault; } + + private: + bool isdefault; +}; + +class QmlPropertyNode : public LeafNode +{ + public: + QmlPropertyNode(QmlPropGroupNode* parent, + const QString& name, + const QString& type); + virtual ~QmlPropertyNode() { } + + void setDataType(const QString& dataType) { dt = dataType; } + void setStored(bool stored) { sto = toTrool(stored); } + void setDesignable(bool designable) { des = toTrool(designable); } + + 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); } + + const QString& element() const { return parent()->name(); } + + private: + enum Trool { Trool_True, Trool_False, Trool_Default }; + + static Trool toTrool(bool boolean); + static bool fromTrool(Trool troolean, bool defaultValue); + + 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(); } +}; +#endif + class EnumItem { public: @@ -358,6 +449,7 @@ class EnumNode : public LeafNode { public: EnumNode(InnerNode *parent, const QString& name); + virtual ~EnumNode() { } void addItem(const EnumItem& item); void setFlagsType(TypedefNode *typedeff); @@ -378,6 +470,7 @@ class TypedefNode : public LeafNode { public: TypedefNode(InnerNode *parent, const QString& name); + virtual ~TypedefNode() { } const EnumNode *associatedEnum() const { return ae; } @@ -438,6 +531,7 @@ class FunctionNode : public LeafNode enum Virtualness { NonVirtual, ImpureVirtual, PureVirtual }; FunctionNode(InnerNode *parent, const QString &name); + virtual ~FunctionNode() { } void setReturnType(const QString& returnType) { rt = returnType; } void setMetaness(Metaness metaness) { met = metaness; } @@ -500,6 +594,7 @@ class PropertyNode : public LeafNode enum { NumFunctionRoles = Resetter + 1 }; PropertyNode(InnerNode *parent, const QString& name); + virtual ~PropertyNode() { } void setDataType(const QString& dataType) { dt = dataType; } void addFunction(FunctionNode *function, FunctionRole role); @@ -557,6 +652,7 @@ class VariableNode : public LeafNode { public: VariableNode(InnerNode *parent, const QString &name); + virtual ~VariableNode() { } void setLeftType(const QString &leftType) { lt = leftType; } void setRightType(const QString &rightType) { rt = rightType; } @@ -582,6 +678,7 @@ class TargetNode : public LeafNode { public: TargetNode(InnerNode *parent, const QString& name); + virtual ~TargetNode() { } virtual bool isInnerNode() const; }; diff --git a/tools/qdoc3/pagegenerator.cpp b/tools/qdoc3/pagegenerator.cpp index 06ff398..8715f4a 100644 --- a/tools/qdoc3/pagegenerator.cpp +++ b/tools/qdoc3/pagegenerator.cpp @@ -81,30 +81,50 @@ 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 + } QString base = node->doc().baseName(); if (!base.isEmpty()) return base; - const Node *p = node; - - forever { - base.prepend(p->name()); + const Node *p = node; + + forever { + base.prepend(p->name()); +#ifdef QDOC_QML + /* + To avoid file name conflicts in the html directory, + 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)) + base.prepend("qml-"); +#endif const Node *pp = p->parent(); if (!pp || pp->name().isEmpty() || pp->type() == Node::Fake) - break; + break; base.prepend(QLatin1Char('-')); p = pp; - } - - if (node->type() == Node::Fake) { + } + + if (node->type() == Node::Fake) { #ifdef QDOC2_COMPAT - if (base.endsWith(".html")) - base.truncate(base.length() - 5); + if (base.endsWith(".html")) + base.truncate(base.length() - 5); #endif - } + } // the code below is effectively equivalent to: // base.replace(QRegExp("[^A-Za-z0-9]+"), " "); @@ -126,7 +146,8 @@ QString PageGenerator::fileBase(const Node *node) if ((u >= 'a' && u <= 'z') || (u >= '0' && u <= '9')) { res += QLatin1Char(u); begun = true; - } else if (begun) { + } + else if (begun) { res += QLatin1Char('-'); begun = false; } @@ -187,8 +208,12 @@ void PageGenerator::generateInnerNode(const InnerNode *node, if (node->type() == Node::Fake) { const FakeNode *fakeNode = static_cast<const FakeNode *>(node); - if (fakeNode->subType() == FakeNode::ExternalPage) + if (fakeNode->subType() == Node::ExternalPage) + return; +#ifdef QDOC_QML + if (fakeNode->subType() == Node::QmlPropertyGroup) return; +#endif } if (node->parent() != 0) { @@ -197,12 +222,6 @@ void PageGenerator::generateInnerNode(const InnerNode *node, generateClassLikeNode(node, marker); } else if (node->type() == Node::Fake) { - const FakeNode* fakeNode = static_cast<const FakeNode *>(node); -#ifdef QDOC_QML - if (fakeNode->subType() == FakeNode::QmlClass) { - //qDebug() << "FILENAME:" << fileName(node); - } -#endif generateFakeNode(static_cast<const FakeNode *>(node), marker); } endSubPage(); diff --git a/tools/qdoc3/test/classic.css b/tools/qdoc3/test/classic.css index 3816164..4225a1b 100644 --- a/tools/qdoc3/test/classic.css +++ b/tools/qdoc3/test/classic.css @@ -225,3 +225,52 @@ span.string,span.char { font-size: 0.65em } + +.qmlitem { + padding: 0; +} + +.qmlname { + white-space: nowrap; + font-weight: bold; + font-size: 125%; +} + +.qmltype { + font-weight: bold; + font-size: 125%; +} + +.qmlproto, .qmldoc { + // border-top: 1px solid #84b0c7; +} + +.qmlproto { + padding: 0; + //background-color: #e4e4e4;//#d5e1e8; + //font-weight: bold; + //-webkit-border-top-left-radius: 8px; + //-webkit-border-top-right-radius: 8px; + //-moz-border-radius-topleft: 8px; + //-moz-border-radius-topright: 8px; +} + +.qmldoc { + border-top: 1px solid #e4e4e4; + //padding: 2px 5px; + //background-color: #eef3f5; + //border-top-width: 0; + //-webkit-border-bottom-left-radius: 8px; + //-webkit-border-bottom-right-radius: 8px; + //-moz-border-radius-bottomleft: 8px; + //-moz-border-radius-bottomright: 8px; +} + +.qmldoc p, .qmldoc dl, .qmldoc ul { + //margin: 6px 0; +} + +*.qmlitem p { + //margin-top: 0px; + //margin-bottom: 0px; +} diff --git a/tools/qdoc3/tree.cpp b/tools/qdoc3/tree.cpp index 308ba0e..e6dd084 100644 --- a/tools/qdoc3/tree.cpp +++ b/tools/qdoc3/tree.cpp @@ -176,6 +176,8 @@ const Node *Tree::findNode(const QStringList &path, } /*! + Find the node with the specified \a path name of the + specified \a type. */ Node *Tree::findNode(const QStringList &path, Node::Type type, @@ -189,6 +191,8 @@ Node *Tree::findNode(const QStringList &path, } /*! + Find the node with the specified \a path name of the + specified \a type. */ const Node *Tree::findNode(const QStringList &path, Node::Type type, @@ -208,7 +212,9 @@ FunctionNode *Tree::findFunctionNode(const QStringList& path, int findFlags) { return const_cast<FunctionNode *>( - const_cast<const Tree *>(this)->findFunctionNode(path, relative, findFlags)); + const_cast<const Tree *>(this)->findFunctionNode(path, + relative, + findFlags)); } /*! @@ -233,7 +239,8 @@ const FunctionNode *Tree::findFunctionNode(const QStringList &path, else next = ((InnerNode *) node)->findNode(path.at(i)); - if (!next && node->type() == Node::Class && (findFlags & SearchBaseClasses)) { + if (!next && node->type() == Node::Class && + (findFlags & SearchBaseClasses)) { NodeList baseClasses = allBaseClasses(static_cast<const ClassNode *>(node)); foreach (const Node *baseClass, baseClasses) { if (i == path.size() - 1) @@ -563,7 +570,7 @@ void Tree::resolveGroups() FakeNode *fake = static_cast<FakeNode*>(findNode(QStringList(i.key()),Node::Fake)); - if (fake && fake->subType() == FakeNode::Group) { + if (fake && fake->subType() == Node::Group) { fake->addGroupMember(i.value()); } else { @@ -770,21 +777,21 @@ void Tree::readIndexSection(const QDomElement &element, } else if (element.nodeName() == "page") { - FakeNode::SubType subtype; + Node::SubType subtype; if (element.attribute("subtype") == "example") - subtype = FakeNode::Example; + subtype = Node::Example; else if (element.attribute("subtype") == "header") - subtype = FakeNode::HeaderFile; + subtype = Node::HeaderFile; else if (element.attribute("subtype") == "file") - subtype = FakeNode::File; + subtype = Node::File; else if (element.attribute("subtype") == "group") - subtype = FakeNode::Group; + subtype = Node::Group; else if (element.attribute("subtype") == "module") - subtype = FakeNode::Module; + subtype = Node::Module; else if (element.attribute("subtype") == "page") - subtype = FakeNode::Page; + subtype = Node::Page; else if (element.attribute("subtype") == "externalpage") - subtype = FakeNode::ExternalPage; + subtype = Node::ExternalPage; else return; @@ -1226,25 +1233,25 @@ bool Tree::generateIndexSection(QXmlStreamWriter &writer, const FakeNode *fakeNode = static_cast<const FakeNode*>(node); switch (fakeNode->subType()) { - case FakeNode::Example: + case Node::Example: writer.writeAttribute("subtype", "example"); break; - case FakeNode::HeaderFile: + case Node::HeaderFile: writer.writeAttribute("subtype", "header"); break; - case FakeNode::File: + case Node::File: writer.writeAttribute("subtype", "file"); break; - case FakeNode::Group: + case Node::Group: writer.writeAttribute("subtype", "group"); break; - case FakeNode::Module: + case Node::Module: writer.writeAttribute("subtype", "module"); break; - case FakeNode::Page: + case Node::Page: writer.writeAttribute("subtype", "page"); break; - case FakeNode::ExternalPage: + case Node::ExternalPage: writer.writeAttribute("subtype", "externalpage"); break; default: @@ -1383,7 +1390,7 @@ bool Tree::generateIndexSection(QXmlStreamWriter &writer, bool external = false; if (inner->type() == Node::Fake) { const FakeNode *fakeNode = static_cast<const FakeNode *>(inner); - if (fakeNode->subType() == FakeNode::ExternalPage) + if (fakeNode->subType() == Node::ExternalPage) external = true; } @@ -1863,7 +1870,7 @@ void Tree::generateTagFile(const QString &fileName) const */ void Tree::addExternalLink(const QString &url, const Node *relative) { - FakeNode *fakeNode = new FakeNode(root(), url, FakeNode::ExternalPage); + FakeNode *fakeNode = new FakeNode(root(), url, Node::ExternalPage); fakeNode->setAccess(Node::Public); // Create some content for the node. @@ -1898,6 +1905,11 @@ QString Tree::fullDocumentLocation(const Node *node) const return ""; } else if (node->type() == Node::Fake) { +#ifdef QDOC_QML + if (node->subType() == Node::QmlClass) + return "qml-" + node->fileBase() + ".html"; + else +#endif parentName = node->fileBase() + ".html"; } else if (node->fileBase().isEmpty()) diff --git a/tools/qdoc3/webxmlgenerator.cpp b/tools/qdoc3/webxmlgenerator.cpp index c5209b8..e87e812 100644 --- a/tools/qdoc3/webxmlgenerator.cpp +++ b/tools/qdoc3/webxmlgenerator.cpp @@ -191,7 +191,7 @@ void WebXMLGenerator::generateIndexSections(QXmlStreamWriter &writer, generateRelations(writer, node, marker); - if (fake->subType() == FakeNode::Module) { + if (fake->subType() == Node::Module) { writer.writeStartElement("generatedlist"); writer.writeAttribute("contents", "classesbymodule"); @@ -264,7 +264,7 @@ void WebXMLGenerator::generateInnerNode(const InnerNode *node, CodeMarker *marke if (node->type() == Node::Fake) { const FakeNode *fakeNode = static_cast<const FakeNode *>(node); - if (fakeNode->subType() == FakeNode::ExternalPage) + if (fakeNode->subType() == Node::ExternalPage) return; } |