diff -r 000000000000 -r 1918ee327afb tools/qdoc3/htmlgenerator.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/qdoc3/htmlgenerator.cpp Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,4340 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ htmlgenerator.cpp
+*/
+
+#include "codemarker.h"
+#include "helpprojectwriter.h"
+#include "htmlgenerator.h"
+#include "node.h"
+#include "separator.h"
+#include "tree.h"
+#include ";
+ if (relative->type() == Node::Property ||
+ relative->type() == Node::Variable) {
+ QString str;
+ atom = atom->next();
+ while (atom != 0 && atom->type() != Atom::BriefRight) {
+ if (atom->type() == Atom::String ||
+ atom->type() == Atom::AutoLink)
+ str += atom->string();
+ skipAhead++;
+ atom = atom->next();
+ }
+ str[0] = str[0].toLower();
+ if (str.right(1) == ".")
+ str.truncate(str.length() - 1);
+ out() << "This ";
+ if (relative->type() == Node::Property)
+ out() << "property";
+ else
+ out() << "variable";
+ QStringList words = str.split(" ");
+ if (!(words.first() == "contains" || words.first() == "specifies"
+ || words.first() == "describes" || words.first() == "defines"
+ || words.first() == "holds" || words.first() == "determines"))
+ out() << " holds ";
+ else
+ out() << " ";
+ out() << str << ".";
+ }
+ break;
+ case Atom::BriefRight:
+ if (relative->type() != Node::Fake)
+ out() << " you can rewrite it as For example, if you have code like"
+ << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
+ marker,relative))
+ << "
\n";
+ break;
+#ifdef QDOC_QML
+ case Atom::Qml:
+ out() << ""
+ << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
+ marker,relative))
+ << "
\n";
+ break;
+#endif
+ case Atom::CodeNew:
+ out() << ""
+ << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
+ marker,relative))
+ << "
\n";
+ break;
+ case Atom::CodeOld:
+ out() << ""
+ << trimmedTrailing(protect(plainCode(indent(codeIndent,atom->string()))))
+ << "
\n";
+ break;
+ case Atom::FootnoteLeft:
+ // ### For now
+ if (in_para) {
+ out() << "
Class "; + + out() << ""; + QStringList pieces = fullName(pmap.key(), 0, marker).split("::"); + out() << protect(pieces.last()); + out() << "" << ":
\n"; + + generateSection(nlist, 0, marker, CodeMarker::Summary); + out() << "";
+ if (fileName.isEmpty()) {
+ out() << "[Missing image "
+ << protect(atom->string()) << "]";
+ }
+ else {
+ out() << "";
+ helpProjectWriter->addExtraFile(fileName);
+ }
+ if (atom->type() == Atom::Image)
+ out() << "
Constant | " + << "Value | " + << "Description |
---|
Constant | Value | |
---|---|---|
" + << protect(plainCode(marker->markedUpEnumValue(atom->next()->string(), + relative))) + << " | ";
+
+ QString itemValue;
+ if (relative->type() == Node::Enum) {
+ const EnumNode *enume = static_cast | ";
+ if (matchAhead(atom, Atom::ListItemRight))
+ out() << " ";
+ }
+ }
+ else {
+ out() << " |
"; + in_para = true; + break; + case Atom::ParaRight: + endLink(); + if (in_para) { + out() << "
\n"; + in_para = false; + } + //if (!matchAhead(atom, Atom::ListItemRight) && !matchAhead(atom, Atom::TableItemRight)) + // out() << "\n"; + break; + case Atom::QuotationLeft: + out() << ""; + break; + case Atom::QuotationRight: + out() << "\n"; + break; + case Atom::RawString: + out() << atom->string(); + break; + case Atom::SectionLeft: +#if 0 + { + int nextLevel = atom->string().toInt(); + if (sectionNumber.size() < nextLevel) { + do { + sectionNumber.append("1"); + } while (sectionNumber.size() < nextLevel); + } + else { + while (sectionNumber.size() > nextLevel) { + sectionNumber.removeLast(); + } + sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1); + } + out() << "\n"; + } +#else + out() << "\n"; +#endif + break; + case Atom::SectionRight: + break; + case Atom::SectionHeadingLeft: + out() << "
\\" << protect(atom->string())
+ << "
";
+ break;
+#ifdef QDOC_QML
+ case Atom::QmlText:
+ case Atom::EndQmlText:
+ // don't do anything with these. They are just tags.
+ break;
+#endif
+ default:
+ unknownAtom(atom);
+ }
+ return skipAhead;
+}
+
+void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
+ CodeMarker *marker)
+{
+ QList\n" << navigationLinks << "
\n"; +} + +void HtmlGenerator::generateTitle(const QString& title, + const Text &subTitle, + SubTitleSize subTitleSize, + const Node *relative, + CodeMarker *marker) +{ + out() << "\n" << navigationLinks << "
\n"; + + out() << QString(footer).replace("\\" + COMMAND_VERSION, myTree->version()) + << QString(address).replace("\\" + COMMAND_VERSION, myTree->version()) + << "\n" + "\n"; +} + +void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker, + const Node *relative) +{ + Text brief = node->doc().briefText(); + if (!brief.isEmpty()) { + out() << ""; + generateText(brief, node, marker); + if (!relative || node == relative) + out() << " More...
\n"; + } +} + +void HtmlGenerator::generateIncludes(const InnerNode *inner, CodeMarker *marker) +{ + if (!inner->includes().isEmpty()) { + out() << "" + << trimmedTrailing(highlightedCode(indent(codeIndent, + marker->markedUpIncludes(inner->includes())), + marker,inner)) + << ""; + } +} + +void HtmlGenerator::generateTableOfContents(const Node *node, + CodeMarker *marker, + Doc::SectioningUnit sectioningUnit, + int numColumns, + const Node *relative) + +{ + if (!node->doc().hasTableOfContents()) + return; + QList
"; + if (bar.prev.begin() != 0) { +#if 0 + out() << "[Prev: "; + generateText(section.previousHeading(), node, marker); + out() << "]\n"; +#endif + } + if (bar.current.begin() != 0) { + out() << "[Home]\n"; + } + if (bar.next.begin() != 0) { + out() << "[Next: "; + generateText(Text::sectionHeading(bar.next.begin()), node, marker); + out() << "]\n"; + } + out() << "
\n"; + } +} +#endif + +QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner, + CodeMarker *marker) +{ + QListThis is the complete list of members for "; + generateFullName(inner, 0, marker); + out() << ", including inherited members.
\n"; + + Section section = sections.first(); + generateSectionList(section, 0, marker, CodeMarker::SeparateList); + + generateFooter(); + endSubPage(); + return fileName; +} + +QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner, + CodeMarker *marker, + CodeMarker::Status status) +{ + QListThe following class members are part of the " + "Qt 3 support layer. " + "They are provided to help you port old code to Qt 4. We advise against " + "using them in new code.
\n"; + } + else { + out() << "The following class members are obsolete. " + << "They are provided to keep old source code working. " + << "We strongly advise against using them in new code.
\n"; + } + + out() << "\n"; + + for (i = 0; i < sections.size(); ++i) { + out() << ""; + generateFullName(node, relative, marker); + out() << " | "; + + if (!(node->type() == Node::Fake)) { + Text brief = node->doc().trimmedBriefText(name); + if (!brief.isEmpty()) { + out() << ""; + generateText(brief, node, marker); + out() << " | "; + } + } + else { + out() << ""; + out() << protect(node->doc().briefText().toString()); + out() << " | "; + } + out() << "
---|
\n | \n"; + } + else { + while ((currentParagraphNo[i] < NumParagraphs) && + (currentOffsetInParagraph[i] == paragraph[currentParagraphNo[i]].count())) { + ++currentParagraphNo[i]; + currentOffsetInParagraph[i] = 0; + } +#if 0 + if (currentParagraphNo[i] >= NumParagraphs) { + qDebug() << "### Internal error ###" << __FILE__ << __LINE__ + << currentParagraphNo[i] << NumParagraphs; + currentParagraphNo[i] = NumParagraphs - 1; + } +#endif + out() << ""; + if (currentOffsetInParagraph[i] == 0) { + // start a new paragraph + out() << "" + << paragraphName[currentParagraphNo[i]] + << " "; + } + out() << " | \n"; + + if ((currentParagraphNo[i] < NumParagraphs) && + !paragraphName[currentParagraphNo[i]].isEmpty()) { + NodeMap::Iterator it; + it = paragraph[currentParagraphNo[i]].begin(); + for (j = 0; j < currentOffsetInParagraph[i]; j++) + ++it; + + out() << ""; + // Previously, we used generateFullName() for this, but we + // require some special formatting. + out() << ""; + QStringList pieces = fullName(it.value(), relative, marker).split("::"); + out() << protect(pieces.last()); + out() << ""; + if (pieces.size() > 1) { + out() << " ("; + generateFullName(it.value()->parent(), relative, marker); + out() << ")"; + } + out() << " | \n"; + } + + currentOffset[i]++; + currentOffsetInParagraph[i]++; + } + } + out() << "
"; + for (int i = 0; i < 26; i++) { + QChar ch('a' + i); + out() << QString("%2 ").arg(ch).arg(ch.toUpper()); + } + out() << "
\n"; + + char nextLetter = 'a'; + char currentLetter; + +#if 1 + out() << ""; +#endif + out() << protect(f.key()) << ":"; + + currentLetter = f.key()[0].unicode(); + while (islower(currentLetter) && currentLetter >= nextLetter) { + out() << QString("").arg(nextLetter); + nextLetter++; + } + + NodeMap::ConstIterator s = (*f).begin(); + while (s != (*f).end()) { + out() << " "; + generateFullName((*s)->parent(), relative, marker, *s); + ++s; + } +#if 1 + out() << "
";
+ out() << "
";
+ }
+ else {
+ if (twoColumn && i == (int) (nl.count() + 1) / 2)
+ out() << " |
|
";
+ out() << "
";
+ }
+ else {
+ if (twoColumn && i == (int) (section.members.count() + 1) / 2)
+ out() << " |
|
";
+ out() << "
|
|
Access functions:
\n"; + generateSectionList(section, node, marker, CodeMarker::Accessors); + } + + Section notifiers; + notifiers.members += property->notifiers(); + + if (!notifiers.members.isEmpty()) { + out() << "Notifier signal:
\n"; + //out() << "This signal is emitted when the property value is changed.
\n"; + generateSectionList(notifiers, node, marker, CodeMarker::Accessors); + } + } + else if (node->type() == Node::Enum) { + const EnumNode *enume = static_castThe " << protect(enume->flagsType()->name()) + << " type is a typedef for " + << "QFlags<" + << protect(enume->name()) + << ">. It stores an OR combination of " + << protect(enume->name()) + << " values.
\n"; + } + } + generateAlsoList(node, marker); +} + +void HtmlGenerator::findAllClasses(const InnerNode *node) +{ + NodeList::const_iterator c = node->childNodes().constBegin(); + while (c != node->childNodes().constEnd()) { + if ((*c)->access() != Node::Private && (*c)->url().isEmpty()) { + if ((*c)->type() == Node::Class && !(*c)->doc().isEmpty()) { + QString className = (*c)->name(); + if ((*c)->parent() && + (*c)->parent()->type() == Node::Namespace && + !(*c)->parent()->name().isEmpty()) + className = (*c)->parent()->name()+"::"+className; + + if (!(static_cast";
+ out() << "
|
|
" + << "default |
"; + out() << ""; + generateQmlItem(qsn,relative,marker,false); + out() << " |
"; + out() << ""; + generateQmlItem(qmn,relative,marker,false); + out() << " |
"; + 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() << "
"; + } + } + } +} + +/*! + 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() << ""; + 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() << "
"; + } +} + +/*! + 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 = myTree->root()->findNode(cn->qmlElement(),Node::Fake); + if (n && n->subType() == Node::QmlClass) { + out() << ""; + 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() << "
"; + } + } +} + +#endif