/****************************************************************************
**
** 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() << "
"; } break; case Atom::ImageText: break; case Atom::LegaleseLeft: 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 QmlGraphicsXxx]" 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 "[QmlGraphicsXxx is instantiated by QML element Xxx]" line for the class, if there should be one. If there is no QML element, or if the class node status 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