Move qdoc into qtbase and bootstrap it

We need qdoc in qtbase to be able to properly
modularize our documentation and build it
when building the different Qt modules.

qdoc does contain a copy of the qml parser from
qmldevtools, but this is the lesser evil compared
to how we are currently forced to genereate our
docs (and the fact that no developer can run
qdoc and check the docs for their module).

Change-Id: I9f748459382a11cf5d5153d1ee611d7a5d3f4ac1
Reviewed-by: Casper van Donderen <casper.vandonderen@nokia.com>
Reviewed-by: Martin Smith <martin.smith@nokia.com>
bb10
Lars Knoll 2012-03-05 15:34:40 +01:00 committed by Qt by Nokia
parent 6c612c9338
commit 448a3cfe17
136 changed files with 65916 additions and 2 deletions

2
configure vendored
View File

@ -7169,7 +7169,7 @@ for file in .projects .projects.3; do
fi
SPEC=$XQMAKESPEC ;;
*/qmake/qmake.pro) continue ;;
*tools/bootstrap*|*tools/moc*|*tools/rcc*|*tools/uic*) SPEC=$QMAKESPEC ;;
*tools/bootstrap*|*tools/moc*|*tools/rcc*|*tools/uic*|*tools/qdoc*) SPEC=$QMAKESPEC ;;
*) if [ "$CFG_NOPROCESS" = "yes" ]; then
continue
else

87
src/tools/qdoc/TODO.txt Normal file
View File

@ -0,0 +1,87 @@
* fix QWSPointerCalibrationData::devPoints and qwsServer
* Fix QMenu::addAction(QAction *) overload, "using" etc.
* fix space between two tables using <p></p>
* qpixmap-qt3.html; remove 8 public functions inherited from QPaintDevice
* \variable array
* Added support for parameterless macros (e.g. \macro Q_OBJECT).
* Made qdoc stricter regarding the data types (e.g. can't use \enum to document a typedef).
* Parse QT_MODULE() macro and generate proper warnings for the various editions.
* Fix parsing of \image following \value (e.g. qt.html).
* Don't turn X11 and similar names into links.
* Added automatic links from getters to setters and vice versa.
* Support \module and show which module each class is from.
* Fix occasional crash caused by misuse of const_cast().
* Provide clearer error messages when resolves fail.
CHECK:
* Identify editions
* Automatic \sa getter setter
* \macro Q_OBJECT
MUST HAVES:
* resolve [gs]etters for \sa using base class
* fix \overload when one is a signal and the other a normal function
* use "project" for .dcf files
* functions.html: include the types from QtGlobal as well as the functions (whatever that means)
* nice template function/class syntax
* spellchecker: built-in vs. builtin
* verbose mode for functions that don't exist
* No links to Porting Guide sections (e.g. QStringList)
* link toggled(bool)
* autolink foo(1)
* handle using correctly
* QObject "reentrant" list: duplicates
* operator<< \overload
* \compat \overload
* qWarning() link
* operator<<() autolink
* get rid of spurious 'global' functions
* Make automatic links in code work
* Fix encoding bug (see Important email from Simon Hausmann)
* Make links to QFoo::bar().baz() work
* Fix automatic links in \sectionX (e.g. qt4-getting-started.html)
* Provide a "List of all properties" page.
* expand QObjectList -> QList<QObject *>
* warning for unnamed parameters in property access functions
* \center...\endcenter
LINKS:
* explanation following nonstandard wording warning
* omit \overload in operator<< and operator>>
* make operator-() unary and binary independent functions (no \overload)
* fix \overload
* fix \legalese
* remove warning for undocumented enum item like QLocale::LastLanguage
* improve the \a warnings for overloads; if one overload documents a para, fine
* implement \sidebar
* implement \legalesefile
* show in which module each class is
* list namespaces, list header files
NICE FEATURES:
* implement inheritance tree for each class (as a PNG)
* avoid <p>...</p> in table/item cells without relying on horrible kludge
* prevent macros from having same name as commands
* be smart about enum types Foo::Bar vs. Bar when comparing functions
* be smart about const & non-const when comparing functions
OTHER:
* make qdoc run faster
* make sure \headerfile works even if specified after \relates

387
src/tools/qdoc/atom.cpp Normal file
View File

@ -0,0 +1,387 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <qregexp.h>
#include "atom.h"
#include "location.h"
#include <stdio.h>
QT_BEGIN_NAMESPACE
QLatin1String Atom::BOLD_ ("bold");
QLatin1String Atom::INDEX_ ("index");
QLatin1String Atom::ITALIC_ ("italic");
QLatin1String Atom::LINK_ ("link");
QLatin1String Atom::PARAMETER_ ("parameter");
QLatin1String Atom::SPAN_ ("span");
QLatin1String Atom::SUBSCRIPT_ ("subscript");
QLatin1String Atom::SUPERSCRIPT_ ("superscript");
QLatin1String Atom::TELETYPE_ ("teletype");
QLatin1String Atom::UNDERLINE_ ("underline");
QLatin1String Atom::BULLET_ ("bullet");
QLatin1String Atom::TAG_ ("tag");
QLatin1String Atom::VALUE_ ("value");
QLatin1String Atom::LOWERALPHA_ ("loweralpha");
QLatin1String Atom::LOWERROMAN_ ("lowerroman");
QLatin1String Atom::NUMERIC_ ("numeric");
QLatin1String Atom::UPPERALPHA_ ("upperalpha");
QLatin1String Atom::UPPERROMAN_ ("upperroman");
/*! \class Atom
\brief The Atom class is the fundamental unit for representing
documents internally.
Atoms have a \i type and are completed by a \i string whose
meaning depends on the \i type. For example, the string
\quotation
\i italic text looks nicer than \bold bold text
\endquotation
is represented by the following atoms:
\quotation
(FormattingLeft, ATOM_FORMATTING_ITALIC)
(String, "italic")
(FormattingRight, ATOM_FORMATTING_ITALIC)
(String, " text is more attractive than ")
(FormattingLeft, ATOM_FORMATTING_BOLD)
(String, "bold")
(FormattingRight, ATOM_FORMATTING_BOLD)
(String, " text")
\endquotation
\also Text
*/
/*! \enum Atom::Type
\value AbstractLeft
\value AbstractRight
\value AnnotatedList
\value AutoLink
\value BaseName
\value BriefLeft
\value BriefRight
\value C
\value CaptionLeft
\value CaptionRight
\value Code
\value CodeBad
\value CodeNew
\value CodeOld
\value CodeQuoteArgument
\value CodeQuoteCommand
\value DivLeft
\value DivRight
\value EndQmlText
\value FormatElse
\value FormatEndif
\value FormatIf
\value FootnoteLeft
\value FootnoteRight
\value FormattingLeft
\value FormattingRight
\value GeneratedList
\value Image
\value ImageText
\value ImportantNote
\value InlineImage
\value LineBreak
\value Link
\value LinkNode
\value ListLeft
\value ListItemNumber
\value ListTagLeft
\value ListTagRight
\value ListItemLeft
\value ListItemRight
\value ListRight
\value Nop
\value Note
\value ParaLeft
\value ParaRight
\value Qml
\value QmlText
\value QuotationLeft
\value QuotationRight
\value RawString
\value SectionLeft
\value SectionRight
\value SectionHeadingLeft
\value SectionHeadingRight
\value SidebarLeft
\value SidebarRight
\value SinceList
\value String
\value TableLeft
\value TableRight
\value TableHeaderLeft
\value TableHeaderRight
\value TableRowLeft
\value TableRowRight
\value TableItemLeft
\value TableItemRight
\value TableOfContents
\value Target
\value UnhandledFormat
\value UnknownCommand
*/
static const struct {
const char *english;
int no;
} atms[] = {
{ "AbstractLeft", Atom::AbstractLeft },
{ "AbstractRight", Atom::AbstractRight },
{ "AnnotatedList", Atom::AnnotatedList },
{ "AutoLink", Atom::AutoLink },
{ "BaseName", Atom::BaseName },
{ "BriefLeft", Atom::BriefLeft },
{ "BriefRight", Atom::BriefRight },
{ "C", Atom::C },
{ "CaptionLeft", Atom::CaptionLeft },
{ "CaptionRight", Atom::CaptionRight },
{ "Code", Atom::Code },
{ "CodeBad", Atom::CodeBad },
{ "CodeNew", Atom::CodeNew },
{ "CodeOld", Atom::CodeOld },
{ "CodeQuoteArgument", Atom::CodeQuoteArgument },
{ "CodeQuoteCommand", Atom::CodeQuoteCommand },
{ "DivLeft", Atom::DivLeft },
{ "DivRight", Atom::DivRight },
{ "EndQmlText", Atom::EndQmlText },
{ "FootnoteLeft", Atom::FootnoteLeft },
{ "FootnoteRight", Atom::FootnoteRight },
{ "FormatElse", Atom::FormatElse },
{ "FormatEndif", Atom::FormatEndif },
{ "FormatIf", Atom::FormatIf },
{ "FormattingLeft", Atom::FormattingLeft },
{ "FormattingRight", Atom::FormattingRight },
{ "GeneratedList", Atom::GeneratedList },
{ "GuidLink", Atom::GuidLink},
{ "Image", Atom::Image },
{ "ImageText", Atom::ImageText },
{ "ImportantLeft", Atom::ImportantLeft },
{ "ImportantRight", Atom::ImportantRight },
{ "InlineImage", Atom::InlineImage },
{ "JavaScript", Atom::JavaScript },
{ "EndJavaScript", Atom::EndJavaScript },
{ "LegaleseLeft", Atom::LegaleseLeft },
{ "LegaleseRight", Atom::LegaleseRight },
{ "LineBreak", Atom::LineBreak },
{ "Link", Atom::Link },
{ "LinkNode", Atom::LinkNode },
{ "ListLeft", Atom::ListLeft },
{ "ListItemNumber", Atom::ListItemNumber },
{ "ListTagLeft", Atom::ListTagLeft },
{ "ListTagRight", Atom::ListTagRight },
{ "ListItemLeft", Atom::ListItemLeft },
{ "ListItemRight", Atom::ListItemRight },
{ "ListRight", Atom::ListRight },
{ "Nop", Atom::Nop },
{ "NoteLeft", Atom::NoteLeft },
{ "NoteRight", Atom::NoteRight },
{ "ParaLeft", Atom::ParaLeft },
{ "ParaRight", Atom::ParaRight },
{ "Qml", Atom::Qml},
{ "QmlText", Atom::QmlText },
{ "QuotationLeft", Atom::QuotationLeft },
{ "QuotationRight", Atom::QuotationRight },
{ "RawString", Atom::RawString },
{ "SectionLeft", Atom::SectionLeft },
{ "SectionRight", Atom::SectionRight },
{ "SectionHeadingLeft", Atom::SectionHeadingLeft },
{ "SectionHeadingRight", Atom::SectionHeadingRight },
{ "SidebarLeft", Atom::SidebarLeft },
{ "SidebarRight", Atom::SidebarRight },
{ "SinceList", Atom::SinceList },
{ "SnippetCommand", Atom::SnippetCommand },
{ "SnippetIdentifier", Atom::SnippetIdentifier },
{ "SnippetLocation", Atom::SnippetLocation },
{ "String", Atom::String },
{ "TableLeft", Atom::TableLeft },
{ "TableRight", Atom::TableRight },
{ "TableHeaderLeft", Atom::TableHeaderLeft },
{ "TableHeaderRight", Atom::TableHeaderRight },
{ "TableRowLeft", Atom::TableRowLeft },
{ "TableRowRight", Atom::TableRowRight },
{ "TableItemLeft", Atom::TableItemLeft },
{ "TableItemRight", Atom::TableItemRight },
{ "TableOfContents", Atom::TableOfContents },
{ "Target", Atom::Target },
{ "UnhandledFormat", Atom::UnhandledFormat },
{ "UnknownCommand", Atom::UnknownCommand },
{ 0, 0 }
};
/*! \fn Atom::Atom(Type type, const QString& string)
Constructs an atom of the specified \a type with the single
parameter \a string and does not put the new atom in a list.
*/
/*! \fn Atom::Atom(Type type, const QString& p1, const QString& p2)
Constructs an atom of the specified \a type with the two
parameters \a p1 and \a p2 and does not put the new atom
in a list.
*/
/*! \fn Atom(Atom *previous, Type type, const QString& string)
Constructs an atom of the specified \a type with the single
parameter \a string and inserts the new atom into the list
after the \a previous atom.
*/
/*! \fn Atom::Atom(Atom* previous, Type type, const QString& p1, const QString& p2)
Constructs an atom of the specified \a type with the two
parameters \a p1 and \a p2 and inserts the new atom into
the list after the \a previous atom.
*/
/*! \fn void Atom::appendChar(QChar ch)
Appends \a ch to the string parameter of this atom.
\also string()
*/
/*! \fn void Atom::appendString(const QString& string)
Appends \a string to the string parameter of this atom.
\also string()
*/
/*! \fn void Atom::chopString()
\also string()
*/
/*! \fn Atom *Atom::next()
Return the next atom in the atom list.
\also type(), string()
*/
/*!
Return the next Atom in the list if it is of Type \a t.
Otherwise return 0.
*/
const Atom* Atom::next(Type t) const
{
return (next_ && (next_->type() == t)) ? next_ : 0;
}
/*!
Return the next Atom in the list if it is of Type \a t
and its string part is \a s. Otherwise return 0.
*/
const Atom* Atom::next(Type t, const QString& s) const
{
return (next_ && (next_->type() == t) && (next_->string() == s)) ? next_ : 0;
}
/*! \fn const Atom *Atom::next() const
Return the next atom in the atom list.
\also type(), string()
*/
/*! \fn Type Atom::type() const
Return the type of this atom.
\also string(), next()
*/
/*!
Return the type of this atom as a string. Return "Invalid" if
type() returns an impossible value.
This is only useful for debugging.
\also type()
*/
QString Atom::typeString() const
{
static bool deja = false;
if (!deja) {
int i = 0;
while (atms[i].english != 0) {
if (atms[i].no != i)
Location::internalError(tr("atom %1 missing").arg(i));
i++;
}
deja = true;
}
int i = (int) type();
if (i < 0 || i > (int) Last)
return QLatin1String("Invalid");
return QLatin1String(atms[i].english);
}
/*! \fn const QString& Atom::string() const
Returns the string parameter that together with the type
characterizes this atom.
\also type(), next()
*/
/*!
Dumps this Atom to stderr in printer friendly form.
*/
void Atom::dump() const
{
QString str = string();
str.replace(QLatin1String("\\"), QLatin1String("\\\\"));
str.replace(QLatin1String("\""), QLatin1String("\\\""));
str.replace(QLatin1String("\n"), QLatin1String("\\n"));
str.replace(QRegExp(QLatin1String("[^\x20-\x7e]")), QLatin1String("?"));
if (!str.isEmpty())
str = QLatin1String(" \"") + str + QLatin1String("\"");
fprintf(stderr,
" %-15s%s\n",
typeString().toLatin1().data(),
str.toLatin1().data());
}
QT_END_NAMESPACE

237
src/tools/qdoc/atom.h Normal file
View File

@ -0,0 +1,237 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
atom.h
*/
#ifndef ATOM_H
#define ATOM_H
#include <qstringlist.h>
#define QDOC_QML
QT_BEGIN_NAMESPACE
class Atom
{
public:
enum Type {
AbstractLeft,
AbstractRight,
AnnotatedList,
AutoLink,
BaseName,
BriefLeft,
BriefRight,
C,
CaptionLeft,
CaptionRight,
Code,
CodeBad,
CodeNew,
CodeOld,
CodeQuoteArgument,
CodeQuoteCommand,
DivLeft,
DivRight,
EndQmlText,
FootnoteLeft,
FootnoteRight,
FormatElse,
FormatEndif,
FormatIf,
FormattingLeft,
FormattingRight,
GeneratedList,
GuidLink,
Image,
ImageText,
ImportantLeft,
ImportantRight,
InlineImage,
JavaScript,
EndJavaScript,
LegaleseLeft,
LegaleseRight,
LineBreak,
Link,
LinkNode,
ListLeft,
ListItemNumber,
ListTagLeft,
ListTagRight,
ListItemLeft,
ListItemRight,
ListRight,
Nop,
NoteLeft,
NoteRight,
ParaLeft,
ParaRight,
Qml,
QmlText,
QuotationLeft,
QuotationRight,
RawString,
SectionLeft,
SectionRight,
SectionHeadingLeft,
SectionHeadingRight,
SidebarLeft,
SidebarRight,
SinceList,
SnippetCommand,
SnippetIdentifier,
SnippetLocation,
String,
TableLeft,
TableRight,
TableHeaderLeft,
TableHeaderRight,
TableRowLeft,
TableRowRight,
TableItemLeft,
TableItemRight,
TableOfContents,
Target,
UnhandledFormat,
UnknownCommand,
Last = UnknownCommand
};
Atom(Type type, const QString& string = "")
: next_(0), type_(type)
{
strs << string;
}
Atom(Type type, const QString& p1, const QString& p2)
: next_(0), type_(type)
{
strs << p1;
if (!p2.isEmpty())
strs << p2;
}
Atom(Atom* previous, Type type, const QString& string = "")
: next_(previous->next_), type_(type)
{
strs << string;
previous->next_ = this;
}
Atom(Atom* previous, Type type, const QString& p1, const QString& p2)
: next_(previous->next_), type_(type)
{
strs << p1;
if (!p2.isEmpty())
strs << p2;
previous->next_ = this;
}
void appendChar(QChar ch) { strs[0] += ch; }
void appendString(const QString& string) { strs[0] += string; }
void chopString() { strs[0].chop(1); }
void setString(const QString& string) { strs[0] = string; }
Atom* next() { return next_; }
void setNext(Atom* newNext) { next_ = newNext; }
const Atom* next() const { return next_; }
const Atom* next(Type t) const;
const Atom* next(Type t, const QString& s) const;
Type type() const { return type_; }
QString typeString() const;
const QString& string() const { return strs[0]; }
const QString& string(int i) const { return strs[i]; }
int count() const { return strs.size(); }
void dump() const;
static QLatin1String BOLD_;
static QLatin1String INDEX_;
static QLatin1String ITALIC_;
static QLatin1String LINK_;
static QLatin1String PARAMETER_;
static QLatin1String SPAN_;
static QLatin1String SUBSCRIPT_;
static QLatin1String SUPERSCRIPT_;
static QLatin1String TELETYPE_;
static QLatin1String UNDERLINE_;
static QLatin1String BULLET_;
static QLatin1String TAG_;
static QLatin1String VALUE_;
static QLatin1String LOWERALPHA_;
static QLatin1String LOWERROMAN_;
static QLatin1String NUMERIC_;
static QLatin1String UPPERALPHA_;
static QLatin1String UPPERROMAN_;
private:
Atom* next_;
Type type_;
QStringList strs;
};
#define ATOM_FORMATTING_BOLD "bold"
#define ATOM_FORMATTING_INDEX "index"
#define ATOM_FORMATTING_ITALIC "italic"
#define ATOM_FORMATTING_LINK "link"
#define ATOM_FORMATTING_PARAMETER "parameter"
#define ATOM_FORMATTING_SPAN "span "
#define ATOM_FORMATTING_SUBSCRIPT "subscript"
#define ATOM_FORMATTING_SUPERSCRIPT "superscript"
#define ATOM_FORMATTING_TELETYPE "teletype"
#define ATOM_FORMATTING_UNDERLINE "underline"
#define ATOM_LIST_BULLET "bullet"
#define ATOM_LIST_TAG "tag"
#define ATOM_LIST_VALUE "value"
#define ATOM_LIST_LOWERALPHA "loweralpha"
#define ATOM_LIST_LOWERROMAN "lowerroman"
#define ATOM_LIST_NUMERIC "numeric"
#define ATOM_LIST_UPPERALPHA "upperalpha"
#define ATOM_LIST_UPPERROMAN "upperroman"
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,150 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
codechunk.cpp
*/
#include <qregexp.h>
#include <qstringlist.h>
#include "codechunk.h"
QT_BEGIN_NAMESPACE
enum { Other, Alnum, Gizmo, Comma, LParen, RParen, RAngle, Colon };
// entries 128 and above are Other
static const int charCategory[256] = {
Other, Other, Other, Other, Other, Other, Other, Other,
Other, Other, Other, Other, Other, Other, Other, Other,
Other, Other, Other, Other, Other, Other, Other, Other,
Other, Other, Other, Other, Other, Other, Other, Other,
// ! " # $ % & '
Other, Other, Other, Other, Other, Gizmo, Gizmo, Other,
// ( ) * + , - . /
LParen, RParen, Gizmo, Gizmo, Comma, Other, Other, Gizmo,
// 0 1 2 3 4 5 6 7
Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum,
// 8 9 : ; < = > ?
Alnum, Alnum, Colon, Other, Other, Gizmo, RAngle, Gizmo,
// @ A B C D E F G
Other, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum,
// H I J K L M N O
Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum,
// P Q R S T U V W
Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum,
// X Y Z [ \ ] ^ _
Alnum, Alnum, Alnum, Other, Other, Other, Gizmo, Alnum,
// ` a b c d e f g
Other, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum,
// h i j k l m n o
Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum,
// p q r s t u v w
Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum, Alnum,
// x y z { | } ~
Alnum, Alnum, Alnum, LParen, Gizmo, RParen, Other, Other
};
static const bool needSpace[8][8] = {
/* [ a + , ( ) > : */
/* [ */ { false, false, false, false, false, true, false, false },
/* a */ { false, true, true, false, false, true, false, false },
/* + */ { false, true, false, false, false, true, false, true },
/* , */ { true, true, true, true, true, true, true, true },
/* ( */ { true, true, true, false, true, false, true, true },
/* ) */ { true, true, true, false, true, true, true, true },
/* > */ { true, true, true, false, true, true, true, false },
/* : */ { false, false, true, true, true, true, true, false }
};
static int category( QChar ch )
{
return charCategory[(int)ch.toLatin1()];
}
CodeChunk::CodeChunk()
: hotspot( -1 )
{
}
CodeChunk::CodeChunk( const QString& str )
: s( str ), hotspot( -1 )
{
}
void CodeChunk::append( const QString& lexeme )
{
if ( !s.isEmpty() && !lexeme.isEmpty() ) {
/*
Should there be a space or not between the code chunk so far and the
new lexeme?
*/
int cat1 = category(s.at(s.size() - 1));
int cat2 = category(lexeme[0]);
if ( needSpace[cat1][cat2] )
s += QLatin1Char( ' ' );
}
s += lexeme;
}
void CodeChunk::appendHotspot()
{
/*
The first hotspot is the right one.
*/
if ( hotspot == -1 )
hotspot = s.length();
}
QString CodeChunk::toString() const
{
return s;
}
QStringList CodeChunk::toPath() const
{
QString t = s;
t.remove(QRegExp(QLatin1String("<([^<>]|<([^<>]|<[^<>]*>)*>)*>")));
return t.split(QLatin1String("::"));
}
QT_END_NAMESPACE

123
src/tools/qdoc/codechunk.h Normal file
View File

@ -0,0 +1,123 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
codechunk.h
*/
#ifndef CODECHUNK_H
#define CODECHUNK_H
#include <qstring.h>
QT_BEGIN_NAMESPACE
// ### get rid of that class
/*
The CodeChunk class represents a tiny piece of C++ code.
The class provides conversion between a list of lexemes and a string. It adds
spaces at the right place for consistent style. The tiny pieces of code it
represents are data types, enum values, and default parameter values.
Apart from the piece of code itself, there are two bits of metainformation
stored in CodeChunk: the base and the hotspot. The base is the part of the
piece that may be a hypertext link. The base of
QMap<QString, QString>
is QMap.
The hotspot is the place the variable name should be inserted in the case of a
variable (or parameter) declaration. The base of
char * []
is between '*' and '[]'.
*/
class CodeChunk
{
public:
CodeChunk();
CodeChunk( const QString& str );
void append( const QString& lexeme );
void appendHotspot();
bool isEmpty() const { return s.isEmpty(); }
QString toString() const;
QStringList toPath() const;
QString left() const { return s.left(hotspot == -1 ? s.length() : hotspot); }
QString right() const { return s.mid(hotspot == -1 ? s.length() : hotspot); }
private:
QString s;
int hotspot;
};
inline bool operator==( const CodeChunk& c, const CodeChunk& d ) {
return c.toString() == d.toString();
}
inline bool operator!=( const CodeChunk& c, const CodeChunk& d ) {
return !( c == d );
}
inline bool operator<( const CodeChunk& c, const CodeChunk& d ) {
return c.toString() < d.toString();
}
inline bool operator>( const CodeChunk& c, const CodeChunk& d ) {
return d < c;
}
inline bool operator<=( const CodeChunk& c, const CodeChunk& d ) {
return !( c > d );
}
inline bool operator>=( const CodeChunk& c, const CodeChunk& d ) {
return !( c < d );
}
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,682 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QMetaObject>
#include "codemarker.h"
#include "config.h"
#include "node.h"
#include <qdebug.h>
#include <stdio.h>
QT_BEGIN_NAMESPACE
QString CodeMarker::defaultLang;
QList<CodeMarker *> CodeMarker::markers;
/*!
When a code marker constructs itself, it puts itself into
the static list of code markers. All the code markers in
the static list get initialized in initialize(), which is
not called until after the qdoc configuration file has
been read.
*/
CodeMarker::CodeMarker()
{
markers.prepend(this);
}
/*!
When a code marker destroys itself, it removes itself from
the static list of code markers.
*/
CodeMarker::~CodeMarker()
{
markers.removeAll(this);
}
/*!
A code market performs no initialization by default. Marker-specific
initialization is performed in subclasses.
*/
void CodeMarker::initializeMarker(const Config& ) // config
{
}
/*!
Terminating a code marker is trivial.
*/
void CodeMarker::terminateMarker()
{
// nothing.
}
/*!
All the code markers in the static list are initialized
here, after the qdoc configuration file has been loaded.
*/
void CodeMarker::initialize(const Config& config)
{
defaultLang = config.getString(QLatin1String(CONFIG_LANGUAGE));
QList<CodeMarker *>::ConstIterator m = markers.begin();
while (m != markers.end()) {
(*m)->initializeMarker(config);
++m;
}
}
/*!
All the code markers in the static list are terminated here.
*/
void CodeMarker::terminate()
{
QList<CodeMarker *>::ConstIterator m = markers.begin();
while (m != markers.end()) {
(*m)->terminateMarker();
++m;
}
}
CodeMarker *CodeMarker::markerForCode(const QString& code)
{
CodeMarker *defaultMarker = markerForLanguage(defaultLang);
if (defaultMarker != 0 && defaultMarker->recognizeCode(code))
return defaultMarker;
QList<CodeMarker *>::ConstIterator m = markers.begin();
while (m != markers.end()) {
if ((*m)->recognizeCode(code))
return *m;
++m;
}
return defaultMarker;
}
CodeMarker *CodeMarker::markerForFileName(const QString& fileName)
{
CodeMarker *defaultMarker = markerForLanguage(defaultLang);
int dot = -1;
while ((dot = fileName.lastIndexOf(QLatin1Char('.'), dot)) != -1) {
QString ext = fileName.mid(dot + 1);
if (defaultMarker != 0 && defaultMarker->recognizeExtension(ext))
return defaultMarker;
QList<CodeMarker *>::ConstIterator m = markers.begin();
while (m != markers.end()) {
if ((*m)->recognizeExtension(ext))
return *m;
++m;
}
--dot;
}
return defaultMarker;
}
CodeMarker *CodeMarker::markerForLanguage(const QString& lang)
{
QList<CodeMarker *>::ConstIterator m = markers.begin();
while (m != markers.end()) {
if ((*m)->recognizeLanguage(lang))
return *m;
++m;
}
return 0;
}
const Node *CodeMarker::nodeForString(const QString& string)
{
if (sizeof(const Node *) == sizeof(uint)) {
return reinterpret_cast<const Node *>(string.toUInt());
}
else {
return reinterpret_cast<const Node *>(string.toULongLong());
}
}
QString CodeMarker::stringForNode(const Node *node)
{
if (sizeof(const Node *) == sizeof(ulong)) {
return QString::number(reinterpret_cast<quintptr>(node));
}
else {
return QString::number(reinterpret_cast<qulonglong>(node));
}
}
static const QString samp = QLatin1String("&amp;");
static const QString slt = QLatin1String("&lt;");
static const QString sgt = QLatin1String("&gt;");
static const QString squot = QLatin1String("&quot;");
QString CodeMarker::protect(const QString& str)
{
int n = str.length();
QString marked;
marked.reserve(n * 2 + 30);
const QChar *data = str.constData();
for (int i = 0; i != n; ++i) {
switch (data[i].unicode()) {
case '&': marked += samp; break;
case '<': marked += slt; break;
case '>': marked += sgt; break;
case '"': marked += squot; break;
default : marked += data[i];
}
}
return marked;
}
QString CodeMarker::typified(const QString &string)
{
QString result;
QString pendingWord;
for (int i = 0; i <= string.size(); ++i) {
QChar ch;
if (i != string.size())
ch = string.at(i);
QChar lower = ch.toLower();
if ((lower >= QLatin1Char('a') && lower <= QLatin1Char('z'))
|| ch.digitValue() >= 0 || ch == QLatin1Char('_')
|| ch == QLatin1Char(':')) {
pendingWord += ch;
}
else {
if (!pendingWord.isEmpty()) {
bool isProbablyType = (pendingWord != QLatin1String("const"));
if (isProbablyType)
result += QLatin1String("<@type>");
result += pendingWord;
if (isProbablyType)
result += QLatin1String("</@type>");
}
pendingWord.clear();
switch (ch.unicode()) {
case '\0':
break;
case '&':
result += QLatin1String("&amp;");
break;
case '<':
result += QLatin1String("&lt;");
break;
case '>':
result += QLatin1String("&gt;");
break;
default:
result += ch;
}
}
}
return result;
}
QString CodeMarker::taggedNode(const Node* node)
{
QString tag;
QString name = node->name();
switch (node->type()) {
case Node::Namespace:
tag = QLatin1String("@namespace");
break;
case Node::Class:
tag = QLatin1String("@class");
break;
case Node::Enum:
tag = QLatin1String("@enum");
break;
case Node::Typedef:
tag = QLatin1String("@typedef");
break;
case Node::Function:
tag = QLatin1String("@function");
break;
case Node::Property:
tag = QLatin1String("@property");
break;
case Node::Fake:
/*
Remove the "QML:" prefix, if present.
There shouldn't be any of these "QML:"
prefixes in the documentation sources
after the switch to using QML module
qualifiers, but this code is kept to
be backward compatible.
*/
if (node->subType() == Node::QmlClass) {
if (node->name().startsWith(QLatin1String("QML:")))
name = name.mid(4);
}
tag = QLatin1String("@property");
break;
default:
tag = QLatin1String("@unknown");
break;
}
return QLatin1Char('<') + tag + QLatin1Char('>') + protect(name)
+ QLatin1String("</") + tag + QLatin1Char('>');
}
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::QmlSignalHandler:
tag = QLatin1String("@signalhandler");
break;
case Node::QmlMethod:
tag = QLatin1String("@method");
break;
default:
tag = QLatin1String("@unknown");
break;
}
return QLatin1Char('<') + tag + QLatin1Char('>') + protect(node->name())
+ QLatin1String("</") + tag + QLatin1Char('>');
}
QString CodeMarker::linkTag(const Node *node, const QString& body)
{
return QLatin1String("<@link node=\"") + stringForNode(node)
+ QLatin1String("\">") + body + QLatin1String("</@link>");
}
QString CodeMarker::sortName(const Node *node, const QString* name)
{
QString nodeName;
if (name != 0)
nodeName = *name;
else
nodeName = node->name();
int numDigits = 0;
for (int i = nodeName.size() - 1; i > 0; --i) {
if (nodeName.at(i).digitValue() == -1)
break;
++numDigits;
}
// we want 'qint8' to appear before 'qint16'
if (numDigits > 0) {
for (int i = 0; i < 4 - numDigits; ++i)
nodeName.insert(nodeName.size()-numDigits-1, QLatin1Char('0'));
}
if (node->type() == Node::Function) {
const FunctionNode *func = static_cast<const FunctionNode *>(node);
QString sortNo;
if (func->metaness() == FunctionNode::Ctor) {
sortNo = QLatin1String("C");
}
else if (func->metaness() == FunctionNode::Dtor) {
sortNo = QLatin1String("D");
}
else {
if (nodeName.startsWith(QLatin1String("operator"))
&& nodeName.length() > 8
&& !nodeName[8].isLetterOrNumber())
sortNo = QLatin1String("F");
else
sortNo = QLatin1String("E");
}
return sortNo + nodeName + QLatin1Char(' ')
+ QString::number(func->overloadNumber(), 36);
}
if (node->type() == Node::Class)
return QLatin1Char('A') + nodeName;
if (node->type() == Node::Property || node->type() == Node::Variable)
return QLatin1Char('E') + nodeName;
return QLatin1Char('B') + nodeName;
}
void CodeMarker::insert(FastSection &fastSection,
Node *node,
SynopsisStyle style,
Status status)
{
bool irrelevant = false;
bool inheritedMember = false;
if (!node->relates()) {
if (node->parent() != (const InnerNode*)fastSection.innerNode && !node->parent()->isAbstract()) {
if (node->type() != Node::QmlProperty)
inheritedMember = true;
}
}
if (node->access() == Node::Private) {
irrelevant = true;
}
else if (node->type() == Node::Function) {
FunctionNode *func = (FunctionNode *) node;
irrelevant = (inheritedMember
&& (func->metaness() == FunctionNode::Ctor ||
func->metaness() == FunctionNode::Dtor));
}
else if (node->type() == Node::Class || node->type() == Node::Enum
|| node->type() == Node::Typedef) {
irrelevant = (inheritedMember && style != Subpage);
if (!irrelevant && style == Detailed && node->type() == Node::Typedef) {
const TypedefNode* typedeffe = static_cast<const TypedefNode*>(node);
if (typedeffe->associatedEnum())
irrelevant = true;
}
}
if (!irrelevant) {
if (status == Compat) {
irrelevant = (node->status() != Node::Compat);
}
else if (status == Obsolete) {
irrelevant = (node->status() != Node::Obsolete);
}
else {
irrelevant = (node->status() == Node::Compat ||
node->status() == Node::Obsolete);
}
}
if (!irrelevant) {
if (!inheritedMember || style == Subpage) {
QString key = sortName(node);
if (!fastSection.memberMap.contains(key))
fastSection.memberMap.insert(key, node);
}
else {
if (node->parent()->type() == Node::Class) {
if (fastSection.inherited.isEmpty()
|| fastSection.inherited.last().first != node->parent()) {
QPair<InnerNode *, int> p(node->parent(), 0);
fastSection.inherited.append(p);
}
fastSection.inherited.last().second++;
}
}
}
}
void CodeMarker::insert(FastSection& fastSection,
Node* node,
SynopsisStyle style,
bool /* includeClassName */)
{
if (node->status() == Node::Compat || node->status() == Node::Obsolete)
return;
bool inheritedMember = false;
InnerNode* parent = node->parent();
if (parent && (parent->type() == Node::Fake) &&
(parent->subType() == Node::QmlPropertyGroup)) {
parent = parent->parent();
}
inheritedMember = (parent != (const InnerNode*)fastSection.innerNode);
if (!inheritedMember || style == Subpage) {
QString key = sortName(node);
if (!fastSection.memberMap.contains(key))
fastSection.memberMap.insert(key, node);
}
else {
if ((parent->type() == Node::Fake) && (parent->subType() == Node::QmlClass)) {
if (fastSection.inherited.isEmpty()
|| fastSection.inherited.last().first != parent) {
QPair<InnerNode*, int> p(parent, 0);
fastSection.inherited.append(p);
}
fastSection.inherited.last().second++;
}
}
}
/*!
Returns true if \a node represents a reimplemented member function.
If it is, then it is inserted in the reimplemented member map in the
section \a fs. And, the test is only performed if \a status is \e OK.
Otherwise, false is returned.
*/
bool CodeMarker::insertReimpFunc(FastSection& fs, Node* node, Status status)
{
if (node->access() == Node::Private)
return false;
const FunctionNode* fn = static_cast<const FunctionNode*>(node);
if ((fn->reimplementedFrom() != 0) && (status == Okay)) {
bool inherited = (!fn->relates() && (fn->parent() != (const InnerNode*)fs.innerNode));
if (!inherited) {
QString key = sortName(fn);
if (!fs.reimpMemberMap.contains(key)) {
fs.reimpMemberMap.insert(key,node);
return true;
}
}
}
return false;
}
/*!
If \a fs is not empty, convert it to a Section and append
the new Section to \a sectionList.
*/
void CodeMarker::append(QList<Section>& sectionList, const FastSection& fs, bool includeKeys)
{
if (!fs.isEmpty()) {
Section section(fs.name,fs.divClass,fs.singularMember,fs.pluralMember);
if (includeKeys) {
section.keys = fs.memberMap.keys();
}
section.members = fs.memberMap.values();
section.reimpMembers = fs.reimpMemberMap.values();
section.inherited = fs.inherited;
sectionList.append(section);
}
}
static QString encode(const QString &string)
{
#if 0
QString result = string;
for (int i = string.size() - 1; i >= 0; --i) {
uint ch = string.at(i).unicode();
if (ch > 0xFF)
ch = '?';
if ((ch - '0') >= 10 && (ch - 'a') >= 26 && (ch - 'A') >= 26
&& ch != '/' && ch != '(' && ch != ')' && ch != ',' && ch != '*'
&& ch != '&' && ch != '_' && ch != '<' && ch != '>' && ch != ':'
&& ch != '~')
result.replace(i, 1, QString("%") + QString("%1").arg(ch, 2, 16));
}
return result;
#else
return string;
#endif
}
QStringList CodeMarker::macRefsForNode(Node *node)
{
QString result = QLatin1String("cpp/");
switch (node->type()) {
case Node::Class:
{
const ClassNode *classe = static_cast<const ClassNode *>(node);
#if 0
if (!classe->templateStuff().isEmpty()) {
result += QLatin1String("tmplt/");
}
else
#endif
{
result += QLatin1String("cl/");
}
result += macName(classe); // ### Maybe plainName?
}
break;
case Node::Enum:
{
QStringList stringList;
stringList << encode(result + QLatin1String("tag/") +
macName(node));
foreach (const QString &enumName, node->doc().enumItemNames()) {
// ### Write a plainEnumValue() and use it here
stringList << encode(result + QLatin1String("econst/") +
macName(node->parent(), enumName));
}
return stringList;
}
case Node::Typedef:
result += QLatin1String("tdef/") + macName(node);
break;
case Node::Function:
{
bool isMacro = false;
Q_UNUSED(isMacro)
const FunctionNode *func = static_cast<const FunctionNode *>(node);
// overloads are too clever for the Xcode documentation browser
if (func->isOverload())
return QStringList();
if (func->metaness() == FunctionNode::MacroWithParams
|| func->metaness() == FunctionNode::MacroWithoutParams) {
result += QLatin1String("macro/");
#if 0
}
else if (!func->templateStuff().isEmpty()) {
result += QLatin1String("ftmplt/");
#endif
}
else if (func->isStatic()) {
result += QLatin1String("clm/");
}
else if (!func->parent()->name().isEmpty()) {
result += QLatin1String("instm/");
}
else {
result += QLatin1String("func/");
}
result += macName(func);
if (result.endsWith(QLatin1String("()")))
result.chop(2);
#if 0
// this code is too clever for the Xcode documentation
// browser and/or pbhelpindexer
if (!isMacro) {
result += QLatin1Char('/') + QLatin1String(QMetaObject::normalizedSignature(func->returnType().toLatin1().constData())) + "/(";
const QList<Parameter> &params = func->parameters();
for (int i = 0; i < params.count(); ++i) {
QString type = params.at(i).leftType() +
params.at(i).rightType();
type = QLatin1String(QMetaObject::normalizedSignature(type.toLatin1().constData()));
if (i != 0)
result += QLatin1Char(',');
result += type;
}
result += QLatin1Char(')');
}
#endif
}
break;
case Node::Variable:
result += QLatin1String("data/") + macName(node);
break;
case Node::Property:
{
NodeList list = static_cast<const PropertyNode*>(node)->functions();
QStringList stringList;
foreach (Node* node, list) {
stringList += macRefsForNode(node);
}
return stringList;
}
case Node::Namespace:
case Node::Fake:
case Node::Target:
default:
return QStringList();
}
return QStringList(encode(result));
}
QString CodeMarker::macName(const Node *node, const QString &name)
{
QString myName = name;
if (myName.isEmpty()) {
myName = node->name();
node = node->parent();
}
if (node->name().isEmpty()) {
return QLatin1Char('/') + protect(myName);
}
else {
return plainFullName(node) + QLatin1Char('/') + protect(myName);
}
}
/*!
Get the list of documentation sections for the children of
the specified QmlClassNode.
*/
QList<Section> CodeMarker::qmlSections(const QmlClassNode* ,
SynopsisStyle )
{
return QList<Section>();
}
const Node* CodeMarker::resolveTarget(const QString& ,
const Tree* ,
const Node* ,
const Node* )
{
return 0;
}
QT_END_NAMESPACE

192
src/tools/qdoc/codemarker.h Normal file
View File

@ -0,0 +1,192 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
codemarker.h
*/
#ifndef CODEMARKER_H
#define CODEMARKER_H
#include <qpair.h>
#include "atom.h"
#include "node.h"
QT_BEGIN_NAMESPACE
class Config;
class Tree;
struct Section
{
QString name;
QString divClass;
QString singularMember;
QString pluralMember;
QStringList keys;
NodeList members;
NodeList reimpMembers;
QList<QPair<InnerNode *, int> > inherited;
Section() { }
Section(const QString& name0,
const QString& divClass0,
const QString& singularMember0,
const QString& pluralMember0)
: name(name0),
divClass(divClass0),
singularMember(singularMember0),
pluralMember(pluralMember0) { }
void appendMember(Node* node) { members.append(node); }
void appendReimpMember(Node* node) { reimpMembers.append(node); }
};
struct FastSection
{
const InnerNode *innerNode;
QString name;
QString divClass;
QString singularMember;
QString pluralMember;
QMap<QString, Node *> memberMap;
QMap<QString, Node *> reimpMemberMap;
QList<QPair<InnerNode *, int> > inherited;
FastSection(const InnerNode *innerNode0,
const QString& name0,
const QString& divClass0,
const QString& singularMember0,
const QString& pluralMember0)
: innerNode(innerNode0),
name(name0),
divClass(divClass0),
singularMember(singularMember0),
pluralMember(pluralMember0) { }
bool isEmpty() const {
return (memberMap.isEmpty() &&
inherited.isEmpty() &&
reimpMemberMap.isEmpty());
}
};
class CodeMarker
{
public:
enum SynopsisStyle { Summary, Detailed, Subpage, Accessors };
enum Status { Compat, Obsolete, Okay };
CodeMarker();
virtual ~CodeMarker();
virtual void initializeMarker(const Config& config);
virtual void terminateMarker();
virtual bool recognizeCode(const QString& code) = 0;
virtual bool recognizeExtension(const QString& ext) = 0;
virtual bool recognizeLanguage(const QString& lang) = 0;
virtual Atom::Type atomType() const = 0;
virtual QString plainName(const Node *node) = 0;
virtual QString plainFullName(const Node *node,
const Node *relative = 0) = 0;
virtual QString markedUpCode(const QString& code,
const Node *relative,
const Location &location) = 0;
virtual QString markedUpSynopsis(const Node *node,
const Node *relative,
SynopsisStyle style) = 0;
virtual QString markedUpQmlItem(const Node* , bool) { return QString(); }
virtual QString markedUpName(const Node *node) = 0;
virtual QString markedUpFullName(const Node *node,
const Node *relative = 0) = 0;
virtual QString markedUpEnumValue(const QString &enumValue,
const Node *relative) = 0;
virtual QString markedUpIncludes(const QStringList& includes) = 0;
virtual QString functionBeginRegExp(const QString& funcName) = 0;
virtual QString functionEndRegExp(const QString& funcName) = 0;
virtual QList<Section> sections(const InnerNode *inner,
SynopsisStyle style,
Status status) = 0;
virtual QList<Section> qmlSections(const QmlClassNode* qmlClassNode,
SynopsisStyle style);
virtual const Node* resolveTarget(const QString& target,
const Tree* tree,
const Node* relative,
const Node* self = 0);
virtual QStringList macRefsForNode(Node* node);
static void initialize(const Config& config);
static void terminate();
static CodeMarker *markerForCode(const QString& code);
static CodeMarker *markerForFileName(const QString& fileName);
static CodeMarker *markerForLanguage(const QString& lang);
static const Node *nodeForString(const QString& string);
static QString stringForNode(const Node *node);
QString typified(const QString &string);
protected:
virtual QString sortName(const Node *node, const QString* name = 0);
QString protect(const QString &string);
QString taggedNode(const Node* node);
QString taggedQmlNode(const Node* node);
QString linkTag(const Node *node, const QString& body);
void insert(FastSection &fastSection,
Node *node,
SynopsisStyle style,
Status status);
void insert(FastSection& fastSection,
Node* node,
SynopsisStyle style,
bool includeClassName = false);
bool insertReimpFunc(FastSection& fs, Node* node, Status status);
void append(QList<Section>& sectionList, const FastSection& fastSection, bool includeKeys = false);
private:
QString macName(const Node *parent, const QString &name = QString());
static QString defaultLang;
static QList<CodeMarker *> markers;
};
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,409 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
codeparser.cpp
*/
#include "codeparser.h"
#include "node.h"
#include "tree.h"
#include "config.h"
#include "generator.h"
#include <qdebug.h>
QT_BEGIN_NAMESPACE
#define COMMAND_COMPAT Doc::alias(QLatin1String("compat"))
#define COMMAND_DEPRECATED Doc::alias(QLatin1String("deprecated")) // ### don't document
#define COMMAND_INGROUP Doc::alias(QLatin1String("ingroup"))
#define COMMAND_INMODULE Doc::alias(QLatin1String("inmodule")) // ### don't document
#define COMMAND_INQMLMODULE Doc::alias(QLatin1String("inqmlmodule"))
#define COMMAND_INTERNAL Doc::alias(QLatin1String("internal"))
#define COMMAND_MAINCLASS Doc::alias(QLatin1String("mainclass"))
#define COMMAND_NONREENTRANT Doc::alias(QLatin1String("nonreentrant"))
#define COMMAND_OBSOLETE Doc::alias(QLatin1String("obsolete"))
#define COMMAND_PAGEKEYWORDS Doc::alias(QLatin1String("pagekeywords"))
#define COMMAND_PRELIMINARY Doc::alias(QLatin1String("preliminary"))
#define COMMAND_INPUBLICGROUP Doc::alias(QLatin1String("inpublicgroup"))
#define COMMAND_REENTRANT Doc::alias(QLatin1String("reentrant"))
#define COMMAND_SINCE Doc::alias(QLatin1String("since"))
#define COMMAND_SUBTITLE Doc::alias(QLatin1String("subtitle"))
#define COMMAND_THREADSAFE Doc::alias(QLatin1String("threadsafe"))
#define COMMAND_TITLE Doc::alias(QLatin1String("title"))
QString CodeParser::currentSubDir_;
QList<CodeParser *> CodeParser::parsers;
bool CodeParser::showInternal = false;
QMap<QString,QString> CodeParser::nameToTitle;
/*!
The constructor adds this code parser to the static
list of code parsers.
*/
CodeParser::CodeParser()
{
parsers.prepend(this);
}
/*!
The destructor removes this code parser from the static
list of code parsers.
*/
CodeParser::~CodeParser()
{
parsers.removeAll(this);
}
/*!
Initialize the code parser base class.
*/
void CodeParser::initializeParser(const Config& config)
{
showInternal = config.getBool(QLatin1String(CONFIG_SHOWINTERNAL));
}
/*!
Terminating a code parser is trivial.
*/
void CodeParser::terminateParser()
{
// nothing.
}
QStringList CodeParser::headerFileNameFilter()
{
return sourceFileNameFilter();
}
void CodeParser::parseHeaderFile(const Location& location,
const QString& filePath,
Tree *tree)
{
parseSourceFile(location, filePath, tree);
}
void CodeParser::doneParsingHeaderFiles(Tree *tree)
{
doneParsingSourceFiles(tree);
}
/*!
All the code parsers in the static list are initialized here,
after the qdoc configuration variables have been set.
*/
void CodeParser::initialize(const Config& config)
{
QList<CodeParser *>::ConstIterator p = parsers.begin();
while (p != parsers.end()) {
(*p)->initializeParser(config);
++p;
}
}
/*!
All the code parsers in the static list are terminated here.
*/
void CodeParser::terminate()
{
QList<CodeParser *>::ConstIterator p = parsers.begin();
while (p != parsers.end()) {
(*p)->terminateParser();
++p;
}
}
CodeParser *CodeParser::parserForLanguage(const QString& language)
{
QList<CodeParser *>::ConstIterator p = parsers.begin();
while (p != parsers.end()) {
if ((*p)->language() == language)
return *p;
++p;
}
return 0;
}
CodeParser *CodeParser::parserForHeaderFile(const QString &filePath)
{
QString fileName = QFileInfo(filePath).fileName();
QList<CodeParser *>::ConstIterator p = parsers.begin();
while (p != parsers.end()) {
QStringList headerPatterns = (*p)->headerFileNameFilter();
foreach (QString pattern, headerPatterns) {
QRegExp re(pattern, Qt::CaseInsensitive, QRegExp::Wildcard);
if (re.exactMatch(fileName))
return *p;
}
++p;
}
return 0;
}
CodeParser *CodeParser::parserForSourceFile(const QString &filePath)
{
QString fileName = QFileInfo(filePath).fileName();
QList<CodeParser *>::ConstIterator p = parsers.begin();
while (p != parsers.end()) {
QStringList sourcePatterns = (*p)->sourceFileNameFilter();
foreach (QString pattern, sourcePatterns) {
QRegExp re(pattern, Qt::CaseInsensitive, QRegExp::Wildcard);
if (re.exactMatch(fileName))
return *p;
}
++p;
}
return 0;
}
/*!
Returns the set of strings representing the common metacommands.
*/
QSet<QString> CodeParser::commonMetaCommands()
{
return QSet<QString>() << COMMAND_COMPAT
<< COMMAND_DEPRECATED
<< COMMAND_INGROUP
<< COMMAND_INMODULE
<< COMMAND_INQMLMODULE
<< COMMAND_INTERNAL
<< COMMAND_MAINCLASS
<< COMMAND_NONREENTRANT
<< COMMAND_OBSOLETE
<< COMMAND_PAGEKEYWORDS
<< COMMAND_PRELIMINARY
<< COMMAND_INPUBLICGROUP
<< COMMAND_REENTRANT
<< COMMAND_SINCE
<< COMMAND_SUBTITLE
<< COMMAND_THREADSAFE
<< COMMAND_TITLE;
}
/*!
The topic command has been processed. Now process the other
metacommands that were found. These are not the text markup
commands.
*/
void CodeParser::processCommonMetaCommand(const Location& location,
const QString& command,
const QString& arg,
Node* node,
Tree* tree)
{
if (command == COMMAND_COMPAT) {
location.warning(tr("\\compat command used, but Qt3 compatibility is no longer supported"));
node->setStatus(Node::Compat);
}
else if (command == COMMAND_DEPRECATED) {
node->setStatus(Node::Deprecated);
}
else if (command == COMMAND_INGROUP) {
tree->addToGroup(node, arg);
}
else if (command == COMMAND_INPUBLICGROUP) {
tree->addToPublicGroup(node, arg);
}
else if (command == COMMAND_INMODULE) {
node->setModuleName(arg);
}
else if (command == COMMAND_INQMLMODULE) {
node->setQmlModuleName(arg);
tree->addToQmlModule(node,arg);
QString qmid = node->qmlModuleIdentifier();
QmlClassNode* qcn = static_cast<QmlClassNode*>(node);
QmlClassNode::moduleMap.insert(qmid + QLatin1String("::") + node->name(), qcn);
}
else if (command == COMMAND_MAINCLASS) {
node->setStatus(Node::Main);
}
else if (command == COMMAND_OBSOLETE) {
if (node->status() != Node::Compat)
node->setStatus(Node::Obsolete);
}
else if (command == COMMAND_NONREENTRANT) {
node->setThreadSafeness(Node::NonReentrant);
}
else if (command == COMMAND_PRELIMINARY) {
node->setStatus(Node::Preliminary);
}
else if (command == COMMAND_INTERNAL) {
if (!showInternal) {
node->setAccess(Node::Private);
node->setStatus(Node::Internal);
}
}
else if (command == COMMAND_REENTRANT) {
node->setThreadSafeness(Node::Reentrant);
}
else if (command == COMMAND_SINCE) {
node->setSince(arg);
}
else if (command == COMMAND_PAGEKEYWORDS) {
node->addPageKeywords(arg);
}
else if (command == COMMAND_SUBTITLE) {
if (node->type() == Node::Fake) {
FakeNode *fake = static_cast<FakeNode *>(node);
fake->setSubTitle(arg);
}
else
location.warning(tr("Ignored '\\%1'").arg(COMMAND_SUBTITLE));
}
else if (command == COMMAND_THREADSAFE) {
node->setThreadSafeness(Node::ThreadSafe);
}
else if (command == COMMAND_TITLE) {
if (node->type() == Node::Fake) {
FakeNode *fake = static_cast<FakeNode *>(node);
fake->setTitle(arg);
if (fake->subType() == Node::Example) {
ExampleNode::exampleNodeMap.insert(fake->title(),static_cast<ExampleNode*>(fake));
}
nameToTitle.insert(fake->name(),arg);
}
else
location.warning(tr("Ignored '\\%1'").arg(COMMAND_TITLE));
}
}
/*!
Find the page title given the page \a name and return it.
*/
const QString CodeParser::titleFromName(const QString& name)
{
const QString t = nameToTitle.value(name);
return t;
}
/*!
\internal
*/
void CodeParser::extractPageLinkAndDesc(const QString& arg,
QString* link,
QString* desc)
{
QRegExp bracedRegExp(QLatin1String("\\{([^{}]*)\\}(?:\\{([^{}]*)\\})?"));
if (bracedRegExp.exactMatch(arg)) {
*link = bracedRegExp.cap(1);
*desc = bracedRegExp.cap(2);
if (desc->isEmpty())
*desc = *link;
}
else {
int spaceAt = arg.indexOf(QLatin1Char(' '));
if (arg.contains(QLatin1String(".html")) && spaceAt != -1) {
*link = arg.left(spaceAt).trimmed();
*desc = arg.mid(spaceAt).trimmed();
}
else {
*link = arg;
*desc = arg;
}
}
}
/*!
\internal
*/
void CodeParser::setLink(Node* node, Node::LinkType linkType, const QString& arg)
{
QString link;
QString desc;
extractPageLinkAndDesc(arg, &link, &desc);
node->setLink(linkType, link, desc);
}
/*!
If the \e {basedir} variable is not set in the qdocconf
file, do nothing.
Otherwise, search for the basedir string string in the
\a filePath. It must be found, or else a warning message
is output. Extract the subdirectory name that follows the
basedir name and create a subdirectory using that name
in the output director.
*/
void CodeParser::createOutputSubdirectory(const Location& location,
const QString& filePath)
{
QString bd = Generator::baseDir();
if (!bd.isEmpty()) {
int baseIdx = filePath.indexOf(bd);
if (baseIdx == -1)
location.warning(tr("File path: '%1' does not contain bundle base dir: '%2'")
.arg(filePath).arg(bd));
else {
int subDirIdx = filePath.indexOf(QLatin1Char('/'),baseIdx);
if (subDirIdx == -1)
location.warning(tr("File path: '%1' has no sub dir after bundle base dir: '%2'")
.arg(filePath).arg(bd));
else {
++subDirIdx;
int fileNameIdx = filePath.indexOf(QLatin1Char('/'),subDirIdx);
if (fileNameIdx == -1)
location.warning(tr("File path: '%1' has no file name after sub dir: '%2/'")
.arg(filePath).arg(filePath.mid(subDirIdx)));
else {
currentSubDir_ = filePath.mid(subDirIdx,fileNameIdx-subDirIdx);
if (currentSubDir_.isEmpty())
location.warning(tr("File path: '%1' has no sub dir after bundle base dir: '%2'")
.arg(filePath).arg(bd));
else {
QString subDirPath = Generator::outputDir() + QLatin1Char('/') + currentSubDir_;
QDir dirInfo;
if (!dirInfo.exists(subDirPath)) {
if (!dirInfo.mkpath(subDirPath))
location.fatal(tr("Cannot create output sub-directory '%1'").arg(currentSubDir_));
}
}
}
}
}
}
}
QT_END_NAMESPACE

107
src/tools/qdoc/codeparser.h Normal file
View File

@ -0,0 +1,107 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
codeparser.h
*/
#ifndef CODEPARSER_H
#define CODEPARSER_H
#include <QSet>
#include "node.h"
QT_BEGIN_NAMESPACE
class Config;
class Node;
class QString;
class Tree;
class CodeParser
{
public:
CodeParser();
virtual ~CodeParser();
virtual void initializeParser(const Config& config);
virtual void terminateParser();
virtual QString language() = 0;
virtual QStringList headerFileNameFilter();
virtual QStringList sourceFileNameFilter() = 0;
virtual void parseHeaderFile(const Location& location,
const QString& filePath, Tree *tree);
virtual void parseSourceFile(const Location& location,
const QString& filePath, Tree *tree) = 0;
virtual void doneParsingHeaderFiles(Tree *tree);
virtual void doneParsingSourceFiles(Tree *tree) = 0;
void createOutputSubdirectory(const Location& location, const QString& filePath);
static void initialize(const Config& config);
static void terminate();
static CodeParser *parserForLanguage(const QString& language);
static CodeParser *parserForHeaderFile(const QString &filePath);
static CodeParser *parserForSourceFile(const QString &filePath);
static const QString titleFromName(const QString& name);
static void setLink(Node* node, Node::LinkType linkType, const QString& arg);
static const QString& currentOutputSubdirectory() { return currentSubDir_; }
protected:
QSet<QString> commonMetaCommands();
void processCommonMetaCommand(const Location& location,
const QString& command, const QString& arg,
Node *node, Tree *tree);
static void extractPageLinkAndDesc(const QString& arg,
QString* link,
QString* desc);
private:
static QString currentSubDir_;
static QList<CodeParser *> parsers;
static bool showInternal;
static QMap<QString,QString> nameToTitle;
};
QT_END_NAMESPACE
#endif

978
src/tools/qdoc/config.cpp Normal file
View File

@ -0,0 +1,978 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
config.cpp
*/
#include <QDir>
#include <QVariant>
#include <QFile>
#include <QTemporaryFile>
#include <QTextStream>
#include <qdebug.h>
#include "config.h"
#include <stdlib.h>
QT_BEGIN_NAMESPACE
/*
An entry on the MetaStack.
*/
class MetaStackEntry
{
public:
void open();
void close();
QStringList accum;
QStringList next;
};
/*
*/
void MetaStackEntry::open()
{
next.append(QString());
}
/*
*/
void MetaStackEntry::close()
{
accum += next;
next.clear();
}
/*
###
*/
class MetaStack : private QStack<MetaStackEntry>
{
public:
MetaStack();
void process(QChar ch, const Location& location);
QStringList getExpanded(const Location& location);
};
MetaStack::MetaStack()
{
push(MetaStackEntry());
top().open();
}
void MetaStack::process(QChar ch, const Location& location)
{
if (ch == QLatin1Char('{')) {
push(MetaStackEntry());
top().open();
}
else if (ch == QLatin1Char('}')) {
if (count() == 1)
location.fatal(tr("Unexpected '}'"));
top().close();
QStringList suffixes = pop().accum;
QStringList prefixes = top().next;
top().next.clear();
QStringList::ConstIterator pre = prefixes.begin();
while (pre != prefixes.end()) {
QStringList::ConstIterator suf = suffixes.begin();
while (suf != suffixes.end()) {
top().next << (*pre + *suf);
++suf;
}
++pre;
}
}
else if (ch == QLatin1Char(',') && count() > 1) {
top().close();
top().open();
}
else {
QStringList::Iterator pre = top().next.begin();
while (pre != top().next.end()) {
*pre += ch;
++pre;
}
}
}
QStringList MetaStack::getExpanded(const Location& location)
{
if (count() > 1)
location.fatal(tr("Missing '}'"));
top().close();
return top().accum;
}
QT_STATIC_CONST_IMPL QString Config::dot = QLatin1String(".");
QString Config::overrideOutputDir;
QSet<QString> Config::overrideOutputFormats;
QMap<QString, QString> Config::extractedDirs;
int Config::numInstances;
/*!
\class Config
\brief The Config class contains the configuration variables
for controlling how qdoc produces documentation.
Its load() function, reads, parses, and processes a qdocconf file.
*/
/*!
The constructor sets the \a programName and initializes all
internal state variables to empty values.
*/
Config::Config(const QString& programName)
: prog(programName)
{
loc = Location::null;
lastLoc = Location::null;
locMap.clear();
stringValueMap.clear();
stringListValueMap.clear();
numInstances++;
}
/*!
The destructor has nothing special to do.
*/
Config::~Config()
{
}
/*!
Loads and parses the qdoc configuration file \a fileName.
This function calls the other load() function, which does
the loading, parsing, and processing of the configuration
file.
Intializes the location variables returned by location()
and lastLocation().
*/
void Config::load(const QString& fileName)
{
load(Location::null, fileName);
if (loc.isEmpty()) {
loc = Location(fileName);
}
else {
loc.setEtc(true);
}
lastLoc = Location::null;
}
/*!
Writes the qdoc configuration data to the named file.
The previous contents of the file are overwritten.
*/
void Config::unload(const QString& fileName)
{
QStringMultiMap::ConstIterator v = stringValueMap.begin();
while (v != stringValueMap.end()) {
qDebug() << v.key() << " = " << v.value();
#if 0
if (v.key().startsWith(varDot)) {
QString subVar = v.key().mid(varDot.length());
int dot = subVar.indexOf(QLatin1Char('.'));
if (dot != -1)
subVar.truncate(dot);
t.insert(subVar,v.value());
}
#endif
++v;
}
qDebug() << "fileName:" << fileName;
}
/*!
Joins all the strings in \a values into a single string with the
individual \a values separated by ' '. Then it inserts the result
into the string list map with \a var as the key.
It also inserts the \a values string list into a separate map,
also with \a var as the key.
*/
void Config::setStringList(const QString& var, const QStringList& values)
{
stringValueMap[var] = values.join(QLatin1String(" "));
stringListValueMap[var] = values;
}
/*!
Looks up the configuarion variable \a var in the string
map and returns the boolean value.
*/
bool Config::getBool(const QString& var) const
{
return QVariant(getString(var)).toBool();
}
/*!
Looks up the configuration variable \a var in the string list
map. Iterates through the string list found, interpreting each
string in the list as an integer and adding it to a total sum.
Returns the sum.
*/
int Config::getInt(const QString& var) const
{
QStringList strs = getStringList(var);
QStringList::ConstIterator s = strs.begin();
int sum = 0;
while (s != strs.end()) {
sum += (*s).toInt();
++s;
}
return sum;
}
/*!
Function to return the correct outputdir.
outputdir can be set using the qdocconf or the command-line
variable -outputdir.
*/
QString Config::getOutputDir() const
{
if (overrideOutputDir.isNull())
return getString(QLatin1String(CONFIG_OUTPUTDIR));
else
return overrideOutputDir;
}
/*!
Function to return the correct outputformats.
outputformats can be set using the qdocconf or the command-line
variable -outputformat.
*/
QSet<QString> Config::getOutputFormats() const
{
if (overrideOutputFormats.isEmpty())
return getStringSet(QLatin1String(CONFIG_OUTPUTFORMATS));
else
return overrideOutputFormats;
}
/*!
First, this function looks up the configuration variable \a var
in the location map and, if found, sets the internal variable
\c{lastLoc} to the Location that \a var maps to.
Then it looks up the configuration variable \a var in the string
map, and returns the string that \a var maps to.
*/
QString Config::getString(const QString& var) const
{
if (!locMap[var].isEmpty())
(Location&) lastLoc = locMap[var];
return stringValueMap[var];
}
/*!
Looks up the configuration variable \a var in the string
list map, converts the string list it maps to into a set
of strings, and returns the set.
*/
QSet<QString> Config::getStringSet(const QString& var) const
{
return QSet<QString>::fromList(getStringList(var));
}
/*!
First, this function looks up the configuration variable \a var
in the location map and, if found, sets the internal variable
\c{lastLoc} the Location that \a var maps to.
Then it looks up the configuration variable \a var in the string
list map, and returns the string list that \a var maps to.
*/
QStringList Config::getStringList(const QString& var) const
{
if (!locMap[var].isEmpty())
(Location&) lastLoc = locMap[var];
return stringListValueMap[var];
}
/*!
This function should only be called when the configuration
variable \a var maps to a string list that contains file paths.
It cleans the paths with QDir::cleanPath() before returning
them.
First, this function looks up the configuration variable \a var
in the location map and, if found, sets the internal variable
\c{lastLoc} the Location that \a var maps to.
Then it looks up the configuration variable \a var in the string
list map, which maps to a string list that contains file paths.
These paths might not be clean, so QDir::cleanPath() is called
for each one. The string list returned contains cleaned paths.
*/
QStringList Config::getCleanPathList(const QString& var) const
{
if (!locMap[var].isEmpty())
(Location&) lastLoc = locMap[var];
QStringList t;
QMap<QString,QStringList>::const_iterator it = stringListValueMap.find(var);
if (it != stringListValueMap.end()) {
const QStringList& sl = it.value();
if (!sl.isEmpty()) {
t.reserve(sl.size());
for (int i=0; i<sl.size(); ++i) {
t.append(QDir::cleanPath(sl[i]));
}
}
}
return t;
}
/*!
Calls getRegExpList() with the control variable \a var and
iterates through the resulting list of regular expressions,
concatening them with some extras characters to form a single
QRegExp, which is returned/
\sa getRegExpList()
*/
QRegExp Config::getRegExp(const QString& var) const
{
QString pattern;
QList<QRegExp> subRegExps = getRegExpList(var);
QList<QRegExp>::ConstIterator s = subRegExps.begin();
while (s != subRegExps.end()) {
if (!(*s).isValid())
return *s;
if (!pattern.isEmpty())
pattern += QLatin1Char('|');
pattern += QLatin1String("(?:") + (*s).pattern() + QLatin1Char(')');
++s;
}
if (pattern.isEmpty())
pattern = QLatin1String("$x"); // cannot match
return QRegExp(pattern);
}
/*!
Looks up the configuration variable \a var in the string list
map, converts the string list to a list of regular expressions,
and returns it.
*/
QList<QRegExp> Config::getRegExpList(const QString& var) const
{
QStringList strs = getStringList(var);
QStringList::ConstIterator s = strs.begin();
QList<QRegExp> regExps;
while (s != strs.end()) {
regExps += QRegExp(*s);
++s;
}
return regExps;
}
/*!
This function is slower than it could be. What it does is
find all the keys that begin with \a var + dot and return
the matching keys in a set, stripped of the matching prefix
and dot.
*/
QSet<QString> Config::subVars(const QString& var) const
{
QSet<QString> result;
QString varDot = var + QLatin1Char('.');
QStringMultiMap::ConstIterator v = stringValueMap.begin();
while (v != stringValueMap.end()) {
if (v.key().startsWith(varDot)) {
QString subVar = v.key().mid(varDot.length());
int dot = subVar.indexOf(QLatin1Char('.'));
if (dot != -1)
subVar.truncate(dot);
result.insert(subVar);
}
++v;
}
return result;
}
/*!
Same as subVars(), but in this case we return a string map
with the matching keys (stripped of the prefix \a var and
mapped to their values. The pairs are inserted into \a t
*/
void Config::subVarsAndValues(const QString& var, QStringMultiMap& t) const
{
QString varDot = var + QLatin1Char('.');
QStringMultiMap::ConstIterator v = stringValueMap.begin();
while (v != stringValueMap.end()) {
if (v.key().startsWith(varDot)) {
QString subVar = v.key().mid(varDot.length());
int dot = subVar.indexOf(QLatin1Char('.'));
if (dot != -1)
subVar.truncate(dot);
t.insert(subVar,v.value());
}
++v;
}
}
/*!
Builds and returns a list of file pathnames for the file
type specified by \a filesVar (e.g. "headers" or "sources").
The files are found in the directories specified by
\a dirsVar, and they are filtered by \a defaultNameFilter
if a better filter can't be constructed from \a filesVar.
The directories in \a excludedDirs are avoided. The files
in \a excludedFiles are not included in the return list.
*/
QStringList Config::getAllFiles(const QString &filesVar,
const QString &dirsVar,
const QSet<QString> &excludedDirs,
const QSet<QString> &excludedFiles)
{
QStringList result = getStringList(filesVar);
QStringList dirs = getStringList(dirsVar);
QString nameFilter = getString(filesVar + dot + QLatin1String(CONFIG_FILEEXTENSIONS));
QStringList::ConstIterator d = dirs.begin();
while (d != dirs.end()) {
result += getFilesHere(*d, nameFilter, excludedDirs, excludedFiles);
++d;
}
return result;
}
/*!
\a fileName is the path of the file to find.
\a files and \a dirs are the lists where we must find the
components of \a fileName.
\a location is used for obtaining the file and line numbers
for report qdoc errors.
*/
QString Config::findFile(const Location& location,
const QStringList& files,
const QStringList& dirs,
const QString& fileName,
QString& userFriendlyFilePath)
{
if (fileName.isEmpty() || fileName.startsWith(QLatin1Char('/'))) {
userFriendlyFilePath = fileName;
return fileName;
}
QFileInfo fileInfo;
QStringList components = fileName.split(QLatin1Char('?'));
QString firstComponent = components.first();
QStringList::ConstIterator f = files.begin();
while (f != files.end()) {
if (*f == firstComponent ||
(*f).endsWith(QLatin1Char('/') + firstComponent)) {
fileInfo.setFile(*f);
if (!fileInfo.exists())
location.fatal(tr("File '%1' does not exist").arg(*f));
break;
}
++f;
}
if (fileInfo.fileName().isEmpty()) {
QStringList::ConstIterator d = dirs.begin();
while (d != dirs.end()) {
fileInfo.setFile(QDir(*d), firstComponent);
if (fileInfo.exists()) {
break;
}
++d;
}
}
userFriendlyFilePath = QString();
if (!fileInfo.exists())
return QString();
QStringList::ConstIterator c = components.begin();
for (;;) {
bool isArchive = (c != components.end() - 1);
QString userFriendly = *c;
userFriendlyFilePath += userFriendly;
if (isArchive) {
QString extracted = extractedDirs[fileInfo.filePath()];
++c;
fileInfo.setFile(QDir(extracted), *c);
}
else
break;
userFriendlyFilePath += QLatin1Char('?');
}
return fileInfo.filePath();
}
/*!
*/
QString Config::findFile(const Location& location,
const QStringList& files,
const QStringList& dirs,
const QString& fileBase,
const QStringList& fileExtensions,
QString& userFriendlyFilePath)
{
QStringList::ConstIterator e = fileExtensions.begin();
while (e != fileExtensions.end()) {
QString filePath = findFile(location,
files,
dirs,
fileBase + QLatin1Char('.') + *e,
userFriendlyFilePath);
if (!filePath.isEmpty())
return filePath;
++e;
}
return findFile(location, files, dirs, fileBase, userFriendlyFilePath);
}
/*!
Copies the \a sourceFilePath to the file name constructed by
concatenating \a targetDirPath and \a userFriendlySourceFilePath.
\a location is for identifying the file and line number where
a qdoc error occurred. The constructed output file name is
returned.
*/
QString Config::copyFile(const Location& location,
const QString& sourceFilePath,
const QString& userFriendlySourceFilePath,
const QString& targetDirPath)
{
QFile inFile(sourceFilePath);
if (!inFile.open(QFile::ReadOnly)) {
location.fatal(tr("Cannot open input file '%1': %2")
.arg(sourceFilePath).arg(inFile.errorString()));
return QString();
}
QString outFileName = userFriendlySourceFilePath;
int slash = outFileName.lastIndexOf(QLatin1Char('/'));
if (slash != -1)
outFileName = outFileName.mid(slash);
QFile outFile(targetDirPath + QLatin1Char('/') + outFileName);
if (!outFile.open(QFile::WriteOnly)) {
location.fatal(tr("Cannot open output file '%1': %2")
.arg(outFile.fileName()).arg(outFile.errorString()));
return QString();
}
char buffer[1024];
int len;
while ((len = inFile.read(buffer, sizeof(buffer))) > 0) {
outFile.write(buffer, len);
}
return outFileName;
}
/*!
Finds the largest unicode digit in \a value in the range
1..7 and returns it.
*/
int Config::numParams(const QString& value)
{
int max = 0;
for (int i = 0; i != value.length(); i++) {
uint c = value[i].unicode();
if (c > 0 && c < 8)
max = qMax(max, (int)c);
}
return max;
}
/*!
Removes everything from \a dir. This function is recursive.
It doesn't remove \a dir itself, but if it was called
recursively, then the caller will remove \a dir.
*/
bool Config::removeDirContents(const QString& dir)
{
QDir dirInfo(dir);
QFileInfoList entries = dirInfo.entryInfoList();
bool ok = true;
QFileInfoList::Iterator it = entries.begin();
while (it != entries.end()) {
if ((*it).isFile()) {
if (!dirInfo.remove((*it).fileName()))
ok = false;
}
else if ((*it).isDir()) {
if ((*it).fileName() != QLatin1String(".") && (*it).fileName() != QLatin1String("..")) {
if (removeDirContents((*it).absoluteFilePath())) {
if (!dirInfo.rmdir((*it).fileName()))
ok = false;
}
else {
ok = false;
}
}
}
++it;
}
return ok;
}
/*!
Returns true if \a ch is a letter, number, '_', '.',
'{', '}', or ','.
*/
bool Config::isMetaKeyChar(QChar ch)
{
return ch.isLetterOrNumber()
|| ch == QLatin1Char('_')
|| ch == QLatin1Char('.')
|| ch == QLatin1Char('{')
|| ch == QLatin1Char('}')
|| ch == QLatin1Char(',');
}
/*!
Load, parse, and process a qdoc configuration file. This
function is only called by the other load() function, but
this one is recursive, i.e., it calls itself when it sees
an \c{include} statement in the qdoc configuration file.
*/
void Config::load(Location location, const QString& fileName)
{
QRegExp keySyntax(QLatin1String("\\w+(?:\\.\\w+)*"));
#define SKIP_CHAR() \
do { \
location.advance(c); \
++i; \
c = text.at(i); \
cc = c.unicode(); \
} while (0)
#define SKIP_SPACES() \
while (c.isSpace() && cc != '\n') \
SKIP_CHAR()
#define PUT_CHAR() \
word += c; \
SKIP_CHAR();
if (location.depth() > 16)
location.fatal(tr("Too many nested includes"));
QFile fin(fileName);
if (!fin.open(QFile::ReadOnly | QFile::Text)) {
fin.setFileName(fileName + QLatin1String(".qdoc"));
if (!fin.open(QFile::ReadOnly | QFile::Text))
location.fatal(tr("Cannot open file '%1': %2").arg(fileName).arg(fin.errorString()));
}
QTextStream stream(&fin);
stream.setCodec("UTF-8");
QString text = stream.readAll();
text += QLatin1String("\n\n");
text += QLatin1Char('\0');
fin.close();
location.push(fileName);
location.start();
int i = 0;
QChar c = text.at(0);
uint cc = c.unicode();
while (i < (int) text.length()) {
if (cc == 0)
++i;
else if (c.isSpace()) {
SKIP_CHAR();
}
else if (cc == '#') {
do {
SKIP_CHAR();
} while (cc != '\n');
}
else if (isMetaKeyChar(c)) {
Location keyLoc = location;
bool plus = false;
QString stringValue;
QStringList stringListValue;
QString word;
bool inQuote = false;
bool prevWordQuoted = true;
bool metWord = false;
MetaStack stack;
do {
stack.process(c, location);
SKIP_CHAR();
} while (isMetaKeyChar(c));
QStringList keys = stack.getExpanded(location);
SKIP_SPACES();
if (keys.count() == 1 && keys.first() == QLatin1String("include")) {
QString includeFile;
if (cc != '(')
location.fatal(tr("Bad include syntax"));
SKIP_CHAR();
SKIP_SPACES();
while (!c.isSpace() && cc != '#' && cc != ')') {
if (cc == '$') {
QString var;
SKIP_CHAR();
while (c.isLetterOrNumber() || cc == '_') {
var += c;
SKIP_CHAR();
}
if (!var.isEmpty()) {
char *val = getenv(var.toLatin1().data());
if (val == 0) {
location.fatal(tr("Environment variable '%1' undefined").arg(var));
}
else {
includeFile += QString::fromLatin1(val);
}
}
} else {
includeFile += c;
SKIP_CHAR();
}
}
SKIP_SPACES();
if (cc != ')')
location.fatal(tr("Bad include syntax"));
SKIP_CHAR();
SKIP_SPACES();
if (cc != '#' && cc != '\n')
location.fatal(tr("Trailing garbage"));
/*
Here is the recursive call.
*/
load(location,
QFileInfo(QFileInfo(fileName).dir(), includeFile)
.filePath());
}
else {
/*
It wasn't an include statement, so it's something else.
*/
if (cc == '+') {
plus = true;
SKIP_CHAR();
}
if (cc != '=')
location.fatal(tr("Expected '=' or '+=' after key"));
SKIP_CHAR();
SKIP_SPACES();
for (;;) {
if (cc == '\\') {
int metaCharPos;
SKIP_CHAR();
if (cc == '\n') {
SKIP_CHAR();
}
else if (cc > '0' && cc < '8') {
word += QChar(c.digitValue());
SKIP_CHAR();
}
else if ((metaCharPos = QString::fromLatin1("abfnrtv").indexOf(c)) != -1) {
word += QLatin1Char("\a\b\f\n\r\t\v"[metaCharPos]);
SKIP_CHAR();
}
else {
PUT_CHAR();
}
}
else if (c.isSpace() || cc == '#') {
if (inQuote) {
if (cc == '\n')
location.fatal(tr("Unterminated string"));
PUT_CHAR();
}
else {
if (!word.isEmpty()) {
if (metWord)
stringValue += QLatin1Char(' ');
stringValue += word;
stringListValue << word;
metWord = true;
word.clear();
prevWordQuoted = false;
}
if (cc == '\n' || cc == '#')
break;
SKIP_SPACES();
}
}
else if (cc == '"') {
if (inQuote) {
if (!prevWordQuoted)
stringValue += QLatin1Char(' ');
stringValue += word;
if (!word.isEmpty())
stringListValue << word;
metWord = true;
word.clear();
prevWordQuoted = true;
}
inQuote = !inQuote;
SKIP_CHAR();
}
else if (cc == '$') {
QString var;
SKIP_CHAR();
while (c.isLetterOrNumber() || cc == '_') {
var += c;
SKIP_CHAR();
}
if (!var.isEmpty()) {
char *val = getenv(var.toLatin1().data());
if (val == 0) {
location.fatal(tr("Environment variable '%1' undefined").arg(var));
}
else {
word += QString::fromLatin1(val);
}
}
}
else {
if (!inQuote && cc == '=')
location.fatal(tr("Unexpected '='"));
PUT_CHAR();
}
}
QStringList::ConstIterator key = keys.begin();
while (key != keys.end()) {
if (!keySyntax.exactMatch(*key))
keyLoc.fatal(tr("Invalid key '%1'").arg(*key));
if (plus) {
if (locMap[*key].isEmpty()) {
locMap[*key] = keyLoc;
}
else {
locMap[*key].setEtc(true);
}
if (stringValueMap[*key].isEmpty()) {
stringValueMap[*key] = stringValue;
}
else {
stringValueMap[*key] +=
QLatin1Char(' ') + stringValue;
}
stringListValueMap[*key] += stringListValue;
}
else {
locMap[*key] = keyLoc;
stringValueMap[*key] = stringValue;
stringListValueMap[*key] = stringListValue;
}
++key;
}
}
}
else {
location.fatal(tr("Unexpected character '%1' at beginning of line")
.arg(c));
}
}
}
QStringList Config::getFilesHere(const QString& dir,
const QString& nameFilter,
const QSet<QString> &excludedDirs,
const QSet<QString> &excludedFiles)
{
QStringList result;
if (excludedDirs.contains(dir))
return result;
QDir dirInfo(dir);
QStringList fileNames;
QStringList::const_iterator fn;
dirInfo.setNameFilters(nameFilter.split(QLatin1Char(' ')));
dirInfo.setSorting(QDir::Name);
dirInfo.setFilter(QDir::Files);
fileNames = dirInfo.entryList();
fn = fileNames.constBegin();
while (fn != fileNames.constEnd()) {
if (!fn->startsWith(QLatin1Char('~'))) {
QString s = dirInfo.filePath(*fn);
QString c = QDir::cleanPath(s);
if (!excludedFiles.contains(c)) {
result.append(c);
}
}
++fn;
}
dirInfo.setNameFilters(QStringList(QLatin1String("*")));
dirInfo.setFilter(QDir::Dirs|QDir::NoDotAndDotDot);
fileNames = dirInfo.entryList();
fn = fileNames.constBegin();
while (fn != fileNames.constEnd()) {
result += getFilesHere(dirInfo.filePath(*fn), nameFilter, excludedDirs, excludedFiles);
++fn;
}
return result;
}
QT_END_NAMESPACE

199
src/tools/qdoc/config.h Normal file
View File

@ -0,0 +1,199 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
config.h
*/
#ifndef CONFIG_H
#define CONFIG_H
#include <QMap>
#include <QSet>
#include <QStringList>
#include "location.h"
QT_BEGIN_NAMESPACE
typedef QMultiMap<QString, QString> QStringMultiMap;
class Config
{
public:
Config(const QString& programName);
~Config();
void load(const QString& fileName);
void unload(const QString& fileName);
void setStringList(const QString& var, const QStringList& values);
const QString& programName() const { return prog; }
const Location& location() const { return loc; }
const Location& lastLocation() const { return lastLoc; }
bool getBool(const QString& var) const;
int getInt(const QString& var) const;
QString getOutputDir() const;
QSet<QString> getOutputFormats() const;
QString getString(const QString& var) const;
QSet<QString> getStringSet(const QString& var) const;
QStringList getStringList(const QString& var) const;
QStringList getCleanPathList(const QString& var) const;
QRegExp getRegExp(const QString& var) const;
QList<QRegExp> getRegExpList(const QString& var) const;
QSet<QString> subVars(const QString& var) const;
void subVarsAndValues(const QString& var, QStringMultiMap& t) const;
QStringList getAllFiles(const QString& filesVar,
const QString& dirsVar,
const QSet<QString> &excludedDirs = QSet<QString>(),
const QSet<QString> &excludedFiles = QSet<QString>());
static QStringList getFilesHere(const QString& dir,
const QString& nameFilter,
const QSet<QString> &excludedDirs = QSet<QString>(),
const QSet<QString> &excludedFiles = QSet<QString>());
static QString findFile(const Location& location,
const QStringList &files,
const QStringList& dirs,
const QString& fileName,
QString& userFriendlyFilePath);
static QString findFile(const Location &location,
const QStringList &files,
const QStringList &dirs,
const QString &fileBase,
const QStringList &fileExtensions,
QString &userFriendlyFilePath);
static QString copyFile(const Location& location,
const QString& sourceFilePath,
const QString& userFriendlySourceFilePath,
const QString& targetDirPath);
static int numParams(const QString& value);
static bool removeDirContents(const QString& dir);
QT_STATIC_CONST QString dot;
static QString overrideOutputDir;
static QSet<QString> overrideOutputFormats;
private:
static bool isMetaKeyChar(QChar ch);
void load(Location location, const QString& fileName);
QString prog;
Location loc;
Location lastLoc;
QMap<QString, Location> locMap;
QMap<QString, QStringList> stringListValueMap;
QMap<QString, QString> stringValueMap;
static QMap<QString, QString> uncompressedFiles;
static QMap<QString, QString> extractedDirs;
static int numInstances;
};
#define CONFIG_ALIAS "alias"
#define CONFIG_BASE "base" // ### don't document for now
#define CONFIG_BASEDIR "basedir"
#define CONFIG_CODEINDENT "codeindent"
#define CONFIG_DEFINES "defines"
#define CONFIG_DESCRIPTION "description"
#define CONFIG_EDITION "edition"
#define CONFIG_ENDHEADER "endheader"
#define CONFIG_EXAMPLEDIRS "exampledirs"
#define CONFIG_EXAMPLES "examples"
#define CONFIG_EXCLUDEDIRS "excludedirs"
#define CONFIG_EXCLUDEFILES "excludefiles"
#define CONFIG_EXTRAIMAGES "extraimages"
#define CONFIG_FALSEHOODS "falsehoods"
#define CONFIG_FORMATTING "formatting"
#define CONFIG_GENERATEINDEX "generateindex"
#define CONFIG_HEADERDIRS "headerdirs"
#define CONFIG_HEADERS "headers"
#define CONFIG_HEADERSCRIPTS "headerscripts"
#define CONFIG_HEADERSTYLES "headerstyles"
#define CONFIG_IGNOREDIRECTIVES "ignoredirectives"
#define CONFIG_IGNORETOKENS "ignoretokens"
#define CONFIG_IMAGEDIRS "imagedirs"
#define CONFIG_IMAGES "images"
#define CONFIG_INDEXES "indexes"
#define CONFIG_LANGUAGE "language"
#define CONFIG_MACRO "macro"
#define CONFIG_NATURALLANGUAGE "naturallanguage"
#define CONFIG_OBSOLETELINKS "obsoletelinks"
#define CONFIG_OUTPUTDIR "outputdir"
#define CONFIG_OUTPUTENCODING "outputencoding"
#define CONFIG_OUTPUTLANGUAGE "outputlanguage"
#define CONFIG_OUTPUTFORMATS "outputformats"
#define CONFIG_OUTPUTPREFIXES "outputprefixes"
#define CONFIG_PROJECT "project"
#define CONFIG_QHP "qhp"
#define CONFIG_QUOTINGINFORMATION "quotinginformation"
#define CONFIG_SCRIPTDIRS "scriptdirs"
#define CONFIG_SCRIPTS "scripts"
#define CONFIG_SHOWINTERNAL "showinternal"
#define CONFIG_SOURCEDIRS "sourcedirs"
#define CONFIG_SOURCEENCODING "sourceencoding"
#define CONFIG_SOURCEMODULES "sourcemodules"
#define CONFIG_SOURCES "sources"
#define CONFIG_SPURIOUS "spurious"
#define CONFIG_STYLEDIRS "styledirs"
#define CONFIG_STYLE "style"
#define CONFIG_STYLES "styles"
#define CONFIG_STYLESHEETS "stylesheets"
#define CONFIG_SYNTAXHIGHLIGHTING "syntaxhighlighting"
#define CONFIG_TEMPLATEDIR "templatedir"
#define CONFIG_TABSIZE "tabsize"
#define CONFIG_TAGFILE "tagfile"
#define CONFIG_TRANSLATORS "translators" // ### don't document for now
#define CONFIG_URL "url"
#define CONFIG_VERSION "version"
#define CONFIG_VERSIONSYM "versionsym"
#define CONFIG_FILEEXTENSIONS "fileextensions"
#define CONFIG_IMAGEEXTENSIONS "imageextensions"
#ifdef QDOC_QML
#define CONFIG_QMLONLY "qmlonly"
#endif
QT_END_NAMESPACE
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,96 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
cppcodemarker.h
*/
#ifndef CPPCODEMARKER_H
#define CPPCODEMARKER_H
#include "codemarker.h"
QT_BEGIN_NAMESPACE
class CppCodeMarker : public CodeMarker
{
public:
CppCodeMarker();
~CppCodeMarker();
virtual bool recognizeCode(const QString& code);
virtual bool recognizeExtension(const QString& ext);
virtual bool recognizeLanguage(const QString& lang);
virtual Atom::Type atomType() const;
virtual QString plainName(const Node *node);
virtual QString plainFullName(const Node *node, const Node *relative);
virtual QString markedUpCode(const QString& code,
const Node *relative,
const Location &location);
virtual QString markedUpSynopsis(const Node *node,
const Node *relative,
SynopsisStyle style);
virtual QString markedUpQmlItem(const Node *node, bool summary);
virtual QString markedUpName(const Node *node);
virtual QString markedUpFullName(const Node *node, const Node *relative);
virtual QString markedUpEnumValue(const QString &enumValue, const Node *relative);
virtual QString markedUpIncludes(const QStringList& includes);
virtual QString functionBeginRegExp(const QString& funcName);
virtual QString functionEndRegExp(const QString& funcName);
virtual QList<Section> sections(const InnerNode *innerNode,
SynopsisStyle style,
Status status);
virtual QList<Section> qmlSections(const QmlClassNode* qmlClassNode,
SynopsisStyle style);
virtual const Node* resolveTarget(const QString& target,
const Tree* tree,
const Node* relative,
const Node* self = 0);
private:
QString addMarkUp(const QString& protectedCode,
const Node *relative,
const Location &location);
};
QT_END_NAMESPACE
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,196 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
cppcodeparser.h
*/
#ifndef CPPCODEPARSER_H
#define CPPCODEPARSER_H
#include <qregexp.h>
#include "codeparser.h"
QT_BEGIN_NAMESPACE
class ClassNode;
class CodeChunk;
class CppCodeParserPrivate;
class FunctionNode;
class InnerNode;
class Tokenizer;
class CppCodeParser : public CodeParser
{
public:
CppCodeParser();
~CppCodeParser();
virtual void initializeParser(const Config& config);
virtual void terminateParser();
virtual QString language();
virtual QStringList headerFileNameFilter();
virtual QStringList sourceFileNameFilter();
virtual void parseHeaderFile(const Location& location,
const QString& filePath,
Tree *tree);
virtual void parseSourceFile(const Location& location,
const QString& filePath,
Tree *tree);
virtual void doneParsingHeaderFiles(Tree *tree);
virtual void doneParsingSourceFiles(Tree *tree);
const FunctionNode *findFunctionNode(const QString& synopsis,
Tree *tree,
Node *relative = 0,
bool fuzzy = false);
protected:
virtual QSet<QString> topicCommands();
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& module,
QString& element,
QString& name);
bool splitQmlMethodArg(const Doc& doc,
const QString& arg,
QString& type,
QString& module,
QString& element);
#endif
virtual QSet<QString> otherMetaCommands();
virtual void processOtherMetaCommand(const Doc& doc,
const QString& command,
const QString& arg,
Node *node);
void processOtherMetaCommands(const Doc& doc, Node *node);
private:
void reset(Tree *tree);
void readToken();
const Location& location();
QString previousLexeme();
QString lexeme();
bool match(int target);
bool skipTo(int target);
bool matchCompat();
bool matchModuleQualifier(QString& name);
bool matchTemplateAngles(CodeChunk *type = 0);
bool matchTemplateHeader();
bool matchDataType(CodeChunk *type, QString *var = 0);
bool matchParameter(FunctionNode *func);
bool matchFunctionDecl(InnerNode *parent,
QStringList *parentPathPtr = 0,
FunctionNode **funcPtr = 0,
const QString &templateStuff = QString(),
Node::Type type = Node::Function,
bool attached = false);
bool matchBaseSpecifier(ClassNode *classe, bool isClass);
bool matchBaseList(ClassNode *classe, bool isClass);
bool matchClassDecl(InnerNode *parent,
const QString &templateStuff = QString());
bool matchNamespaceDecl(InnerNode *parent);
bool matchUsingDecl();
bool matchEnumItem(InnerNode *parent, EnumNode *enume);
bool matchEnumDecl(InnerNode *parent);
bool matchTypedefDecl(InnerNode *parent);
bool matchProperty(InnerNode *parent);
bool matchDeclList(InnerNode *parent);
bool matchDocsAndStuff();
bool makeFunctionNode(const QString &synopsis,
QStringList *parentPathPtr,
FunctionNode **funcPtr,
InnerNode *root = 0,
Node::Type type = Node::Function,
bool attached = false);
FunctionNode* makeFunctionNode(const Doc& doc,
const QString& sig,
InnerNode* parent,
Node::Type type,
bool attached,
QString qdoctag);
void parseQiteratorDotH(const Location &location, const QString &filePath);
void instantiateIteratorMacro(const QString &container,
const QString &includeFile,
const QString &macroDef,
Tree *tree);
void createExampleFileNodes(FakeNode *fake);
QMap<QString, Node::Type> nodeTypeMap;
Tree *tre;
Tokenizer *tokenizer;
int tok;
Node::Access access;
FunctionNode::Metaness metaness;
QString moduleName;
QStringList lastPath;
QRegExp varComment;
QRegExp sep;
QString sequentialIteratorDefinition;
QString mutableSequentialIteratorDefinition;
QString associativeIteratorDefinition;
QString mutableAssociativeIteratorDefinition;
QSet<QString> usedNamespaces;
QMap<QString, QString> sequentialIteratorClasses;
QMap<QString, QString> mutableSequentialIteratorClasses;
QMap<QString, QString> associativeIteratorClasses;
QMap<QString, QString> mutableAssociativeIteratorClasses;
static QStringList exampleFiles;
static QStringList exampleDirs;
QString exampleNameFilter;
QString exampleImageFilter;
};
QT_END_NAMESPACE
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,543 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef DITAXMLGENERATOR_H
#define DITAXMLGENERATOR_H
#include <qmap.h>
#include <qregexp.h>
#include <QXmlStreamWriter>
#include "codemarker.h"
#include "config.h"
#include "pagegenerator.h"
QT_BEGIN_NAMESPACE
typedef QMap<QString, QString> GuidMap;
typedef QMap<QString, GuidMap*> GuidMaps;
class DitaXmlGenerator : public PageGenerator
{
public:
enum SinceType {
Namespace,
Class,
MemberFunction,
NamespaceFunction,
GlobalFunction,
Macro,
Enum,
Typedef,
Property,
Variable,
QmlClass,
QmlProperty,
QmlSignal,
QmlSignalHandler,
QmlMethod,
LastSinceType
};
enum DitaTag {
DT_NONE,
DT_alt,
DT_apiDesc,
DT_APIMap,
DT_apiName,
DT_apiRelation,
DT_audience,
DT_author,
DT_b,
DT_body,
DT_bodydiv,
DT_brand,
DT_category,
DT_codeblock,
DT_comment,
DT_component,
DT_copyrholder,
DT_copyright,
DT_copyryear,
DT_created,
DT_critdates,
DT_cxxAPIMap,
DT_cxxClass,
DT_cxxClassAbstract,
DT_cxxClassAccessSpecifier,
DT_cxxClassAPIItemLocation,
DT_cxxClassBaseClass,
DT_cxxClassDeclarationFile,
DT_cxxClassDeclarationFileLine,
DT_cxxClassDeclarationFileLineStart,
DT_cxxClassDeclarationFileLineEnd,
DT_cxxClassDefinition,
DT_cxxClassDerivation,
DT_cxxClassDerivationAccessSpecifier,
DT_cxxClassDerivations,
DT_cxxClassDetail,
DT_cxxClassNested,
DT_cxxClassNestedClass,
DT_cxxClassNestedDetail,
DT_cxxDefine,
DT_cxxDefineAccessSpecifier,
DT_cxxDefineAPIItemLocation,
DT_cxxDefineDeclarationFile,
DT_cxxDefineDeclarationFileLine,
DT_cxxDefineDefinition,
DT_cxxDefineDetail,
DT_cxxDefineNameLookup,
DT_cxxDefineParameter,
DT_cxxDefineParameterDeclarationName,
DT_cxxDefineParameters,
DT_cxxDefinePrototype,
DT_cxxDefineReimplemented,
DT_cxxEnumeration,
DT_cxxEnumerationAccessSpecifier,
DT_cxxEnumerationAPIItemLocation,
DT_cxxEnumerationDeclarationFile,
DT_cxxEnumerationDeclarationFileLine,
DT_cxxEnumerationDeclarationFileLineStart,
DT_cxxEnumerationDeclarationFileLineEnd,
DT_cxxEnumerationDefinition,
DT_cxxEnumerationDetail,
DT_cxxEnumerationNameLookup,
DT_cxxEnumerationPrototype,
DT_cxxEnumerationScopedName,
DT_cxxEnumerator,
DT_cxxEnumeratorInitialiser,
DT_cxxEnumeratorNameLookup,
DT_cxxEnumeratorPrototype,
DT_cxxEnumerators,
DT_cxxEnumeratorScopedName,
DT_cxxFunction,
DT_cxxFunctionAccessSpecifier,
DT_cxxFunctionAPIItemLocation,
DT_cxxFunctionConst,
DT_cxxFunctionConstructor,
DT_cxxFunctionDeclarationFile,
DT_cxxFunctionDeclarationFileLine,
DT_cxxFunctionDeclaredType,
DT_cxxFunctionDefinition,
DT_cxxFunctionDestructor,
DT_cxxFunctionDetail,
DT_cxxFunctionNameLookup,
DT_cxxFunctionParameter,
DT_cxxFunctionParameterDeclarationName,
DT_cxxFunctionParameterDeclaredType,
DT_cxxFunctionParameterDefaultValue,
DT_cxxFunctionParameters,
DT_cxxFunctionPrototype,
DT_cxxFunctionPureVirtual,
DT_cxxFunctionReimplemented,
DT_cxxFunctionScopedName,
DT_cxxFunctionStorageClassSpecifierStatic,
DT_cxxFunctionVirtual,
DT_cxxTypedef,
DT_cxxTypedefAccessSpecifier,
DT_cxxTypedefAPIItemLocation,
DT_cxxTypedefDeclarationFile,
DT_cxxTypedefDeclarationFileLine,
DT_cxxTypedefDefinition,
DT_cxxTypedefDetail,
DT_cxxTypedefNameLookup,
DT_cxxTypedefScopedName,
DT_cxxVariable,
DT_cxxVariableAccessSpecifier,
DT_cxxVariableAPIItemLocation,
DT_cxxVariableDeclarationFile,
DT_cxxVariableDeclarationFileLine,
DT_cxxVariableDeclaredType,
DT_cxxVariableDefinition,
DT_cxxVariableDetail,
DT_cxxVariableNameLookup,
DT_cxxVariablePrototype,
DT_cxxVariableReimplemented,
DT_cxxVariableScopedName,
DT_cxxVariableStorageClassSpecifierStatic,
DT_data,
DT_dataabout,
DT_dd,
DT_dl,
DT_dlentry,
DT_dt,
DT_entry,
DT_fig,
DT_i,
DT_image,
DT_keyword,
DT_keywords,
DT_li,
DT_link,
DT_linktext,
DT_lq,
DT_map,
DT_mapref,
DT_metadata,
DT_note,
DT_ol,
DT_othermeta,
DT_p,
DT_parameter,
DT_permissions,
DT_ph,
DT_platform,
DT_pre,
DT_prodinfo,
DT_prodname,
DT_prolog,
DT_publisher,
DT_relatedLinks,
DT_resourceid,
DT_revised,
DT_row,
DT_section,
DT_sectiondiv,
DT_shortdesc,
DT_simpletable,
DT_source,
DT_stentry,
DT_sthead,
DT_strow,
DT_sub,
DT_sup,
DT_table,
DT_tbody,
DT_tgroup,
DT_thead,
DT_title,
DT_tm,
DT_topic,
DT_topicmeta,
DT_topicref,
DT_tt,
DT_u,
DT_ul,
DT_unknown,
DT_vrm,
DT_vrmlist,
DT_xref,
DT_LAST
};
public:
DitaXmlGenerator();
~DitaXmlGenerator();
virtual void initializeGenerator(const Config& config);
virtual void terminateGenerator();
virtual QString format();
virtual bool canHandleFormat(const QString& format);
virtual void generateTree(const Tree *tree);
virtual void generateDisambiguationPages() { }
QString protectEnc(const QString& string);
static QString protect(const QString& string, const QString& encoding = "ISO-8859-1");
static QString cleanRef(const QString& ref);
static QString sinceTitle(int i) { return sinceTitles[i]; }
protected:
virtual void startText(const Node* relative, CodeMarker* marker);
virtual int generateAtom(const Atom* atom,
const Node* relative,
CodeMarker* marker);
virtual void generateClassLikeNode(const InnerNode* inner, CodeMarker* marker);
virtual void generateFakeNode(const FakeNode* fake, CodeMarker* marker);
virtual QString fileExtension(const Node* node) const;
virtual QString guidForNode(const Node* node);
virtual QString linkForNode(const Node* node, const Node* relative);
virtual QString refForAtom(Atom* atom, const Node* node);
void writeXrefListItem(const QString& link, const QString& text);
QString fullQualification(const Node* n);
void writeCharacters(const QString& text);
void writeDerivations(const ClassNode* cn, CodeMarker* marker);
void writeLocation(const Node* n);
void writeFunctions(const Section& s,
const InnerNode* parent,
CodeMarker* marker,
const QString& attribute = QString());
void writeNestedClasses(const Section& s, const Node* n);
void replaceTypesWithLinks(const Node* n,
const InnerNode* parent,
CodeMarker* marker,
QString& src);
void writeParameters(const FunctionNode* fn, const InnerNode* parent, CodeMarker* marker);
void writeEnumerations(const Section& s,
CodeMarker* marker,
const QString& attribute = QString());
void writeTypedefs(const Section& s,
CodeMarker* marker,
const QString& attribute = QString());
void writeDataMembers(const Section& s,
CodeMarker* marker,
const QString& attribute = QString());
void writeProperties(const Section& s,
CodeMarker* marker,
const QString& attribute = QString());
void writeMacros(const Section& s,
CodeMarker* marker,
const QString& attribute = QString());
void writePropertyParameter(const QString& tag, const NodeList& nlist);
void writeRelatedLinks(const FakeNode* fake, CodeMarker* marker);
void writeLink(const Node* node, const QString& tex, const QString& role);
void writeProlog(const InnerNode* inner);
bool writeMetadataElement(const InnerNode* inner,
DitaXmlGenerator::DitaTag t,
bool force=true);
bool writeMetadataElements(const InnerNode* inner, DitaXmlGenerator::DitaTag t);
void writeHrefAttribute(const QString& href);
QString getMetadataElement(const InnerNode* inner, DitaXmlGenerator::DitaTag t);
QStringList getMetadataElements(const InnerNode* inner, DitaXmlGenerator::DitaTag t);
private:
enum SubTitleSize { SmallSubTitle, LargeSubTitle };
const QPair<QString,QString> anchorForNode(const Node* node);
const Node* findNodeForTarget(const QString& target,
const Node* relative,
CodeMarker* marker,
const Atom* atom = 0);
void generateHeader(const Node* node,
const QString& name,
bool subpage = false);
void generateBrief(const Node* node, CodeMarker* marker);
void generateIncludes(const InnerNode* inner, CodeMarker* marker);
void generateTableOfContents(const Node* node,
CodeMarker* marker,
Doc::Sections sectioningUnit,
int numColumns,
const Node* relative = 0);
void generateTableOfContents(const Node* node,
CodeMarker* marker,
QList<Section>* sections = 0);
void generateLowStatusMembers(const InnerNode* inner,
CodeMarker* marker,
CodeMarker::Status status);
QString generateLowStatusMemberFile(const InnerNode* inner,
CodeMarker* marker,
CodeMarker::Status status);
void generateClassHierarchy(const Node* relative,
CodeMarker* marker,
const NodeMap& classMap);
void generateAnnotatedList(const Node* relative,
CodeMarker* marker,
const NodeMap& nodeMap);
void generateCompactList(const Node* relative,
CodeMarker* marker,
const NodeMap& classMap,
bool includeAlphabet,
QString commonPrefix = QString());
void generateFunctionIndex(const Node* relative, CodeMarker* marker);
void generateLegaleseList(const Node* relative, CodeMarker* marker);
void generateOverviewList(const Node* relative, CodeMarker* marker);
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* qcn, CodeMarker* marker);
void generateQmlInheritedBy(const QmlClassNode* qcn, CodeMarker* marker);
void generateQmlInstantiates(const QmlClassNode* qcn, CodeMarker* marker);
void generateInstantiatedBy(const ClassNode* cn, CodeMarker* marker);
void generateSection(const NodeList& nl,
const Node* relative,
CodeMarker* marker,
CodeMarker::SynopsisStyle style);
QString getMarkedUpSynopsis(const Node* node,
const Node* relative,
CodeMarker* marker,
CodeMarker::SynopsisStyle style);
void generateSectionInheritedList(const Section& section,
const Node* relative,
CodeMarker* marker);
void writeText(const QString& markedCode,
CodeMarker* marker,
const Node* relative);
void generateFullName(const Node* apparentNode,
const Node* relative,
CodeMarker* marker,
const Node* actualNode = 0);
void generateLink(const Atom* atom,
const Node* relative,
CodeMarker* marker);
void generateStatus(const Node* node, CodeMarker* marker);
QString registerRef(const QString& ref);
virtual QString fileBase(const Node *node) const;
QString fileName(const Node *node);
void findAllClasses(const InnerNode *node);
void findAllFunctions(const InnerNode *node);
void findAllLegaleseTexts(const InnerNode *node);
void findAllNamespaces(const InnerNode *node);
static int hOffset(const Node *node);
static bool isThreeColumnEnumValueTable(const Atom *atom);
QString getLink(const Atom *atom,
const Node *relative,
CodeMarker *marker,
const Node **node);
QString getDisambiguationLink(const Atom* atom, CodeMarker* marker);
virtual void generateIndex(const QString& fileBase,
const QString& url,
const QString& title);
#ifdef GENERATE_MAC_REFS
void generateMacRef(const Node* node, CodeMarker* marker);
#endif
void beginLink(const QString& link);
void endLink();
QString writeGuidAttribute(QString text);
void writeGuidAttribute(Node* node);
QString lookupGuid(QString text);
QString lookupGuid(const QString& fileName, const QString& text);
GuidMap* lookupGuidMap(const QString& fileName);
virtual void beginSubPage(const InnerNode* node, const QString& fileName);
virtual void endSubPage();
virtual void generateInnerNode(const InnerNode* node);
QXmlStreamWriter& xmlWriter();
void writeApiDesc(const Node* node, CodeMarker* marker, const QString& title);
void addLink(const QString& href, const QStringRef& text, DitaTag t = DT_xref);
void writeDitaMap(const Tree* tree);
void writeDitaMap(const DitaMapNode* node);
void writeStartTag(DitaTag t);
void writeEndTag(DitaTag t=DT_NONE);
DitaTag currentTag();
void clearSectionNesting() { sectionNestingLevel = 0; }
int enterApiDesc(const QString& outputclass, const QString& title);
int enterSection(const QString& outputclass, const QString& title);
int leaveSection();
bool inSection() const { return (sectionNestingLevel > 0); }
int currentSectionNestingLevel() const { return sectionNestingLevel; }
QString metadataDefault(DitaTag t) const;
QString stripMarkup(const QString& src) const;
void collectNodesByTypeAndSubtype(const InnerNode* parent);
void writeDitaRefs(const DitaRefList& ditarefs);
void writeTopicrefs(NodeMultiMap* nmm, const QString& navtitle);
bool isDuplicate(NodeMultiMap* nmm, const QString& key, Node* node);
private:
/*
These flags indicate which elements the generator
is currently outputting.
*/
bool inContents;
bool inDetailedDescription;
bool inLegaleseText;
bool inLink;
bool inObsoleteLink;
bool inSectionHeading;
bool inTableHeader;
bool inTableBody;
bool noLinks;
bool obsoleteLinks;
bool offlineDocs;
bool threeColumnEnumValueTable;
int codeIndent;
int numTableRows;
int divNestingLevel;
int sectionNestingLevel;
int tableColumnCount;
QString link;
QStringList sectionNumber;
QRegExp funcLeftParen;
QString style;
QString postHeader;
QString postPostHeader;
QString footer;
QString address;
bool pleaseGenerateMacRef;
QString project;
QString projectDescription;
QString projectUrl;
QString navigationLinks;
QString version;
QStringList vrm;
QStringList stylesheets;
QStringList customHeadElements;
const Tree* tree_;
QMap<QString, QString> refMap;
QMap<QString, QString> name2guidMap;
GuidMaps guidMaps;
QMap<QString, NodeMap > moduleClassMap;
QMap<QString, NodeMap > moduleNamespaceMap;
NodeMap nonCompatClasses;
NodeMap mainClasses;
NodeMap compatClasses;
NodeMap obsoleteClasses;
NodeMap namespaceIndex;
NodeMap serviceClasses;
#ifdef QDOC_QML
NodeMap qmlClasses;
#endif
QMap<QString, NodeMap > funcIndex;
QMap<Text, const Node*> legaleseTexts;
static int id;
static QString ditaTags[];
QStack<QXmlStreamWriter*> xmlWriterStack;
QStack<DitaTag> tagStack;
QStringMultiMap metadataDefaults;
QVector<NodeMultiMap*> nodeTypeMaps;
QVector<NodeMultiMap*> nodeSubtypeMaps;
QVector<NodeMultiMap*> pageTypeMaps;
};
#define DITAXMLGENERATOR_ADDRESS "address"
#define DITAXMLGENERATOR_FOOTER "footer"
#define DITAXMLGENERATOR_GENERATEMACREFS "generatemacrefs" // ### document me
#define DITAXMLGENERATOR_POSTHEADER "postheader"
#define DITAXMLGENERATOR_POSTPOSTHEADER "postpostheader"
#define DITAXMLGENERATOR_STYLE "style"
#define DITAXMLGENERATOR_STYLESHEETS "stylesheets"
#define DITAXMLGENERATOR_CUSTOMHEADELEMENTS "customheadelements"
QT_END_NAMESPACE
#endif

3393
src/tools/qdoc/doc.cpp Normal file

File diff suppressed because it is too large Load Diff

198
src/tools/qdoc/doc.h Normal file
View File

@ -0,0 +1,198 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
doc.h
*/
#ifndef DOC_H
#define DOC_H
#include <QSet>
#include <QString>
#include <QMap>
#include "location.h"
QT_BEGIN_NAMESPACE
class Atom;
class CodeMarker;
class Config;
class DocPrivate;
class Quoter;
class Text;
class FakeNode;
class DitaRef;
typedef QMap<QString, QStringList> QCommandMap;
typedef QMap<QString, QString> QStringMap;
typedef QMultiMap<QString, QString> QStringMultiMap;
struct Topic
{
QString topic;
QString args;
Topic(QString& t, QString a) : topic(t), args(a) { }
};
typedef QList<Topic> TopicList;
typedef QList<DitaRef*> DitaRefList;
class DitaRef
{
public:
DitaRef() { }
virtual ~DitaRef() { }
const QString& navtitle() const { return navtitle_; }
const QString& href() const { return href_; }
void setNavtitle(const QString& t) { navtitle_ = t; }
void setHref(const QString& t) { href_ = t; }
virtual bool isMapRef() const = 0;
virtual const DitaRefList* subrefs() const { return 0; }
virtual void appendSubref(DitaRef* ) { }
private:
QString navtitle_;
QString href_;
};
class TopicRef : public DitaRef
{
public:
TopicRef() { }
~TopicRef();
virtual bool isMapRef() const { return false; }
virtual const DitaRefList* subrefs() const { return &subrefs_; }
virtual void appendSubref(DitaRef* t) { subrefs_.append(t); }
private:
DitaRefList subrefs_;
};
class MapRef : public DitaRef
{
public:
MapRef() { }
~MapRef() { }
virtual bool isMapRef() const { return true; }
};
class Doc
{
public:
// the order is important
enum Sections {
NoSection = -2,
Part = -1,
Chapter = 1,
Section1 = 1,
Section2 = 2,
Section3 = 3,
Section4 = 4
};
Doc() : priv(0) {}
Doc(const Location &start_loc,
const Location &end_loc,
const QString &source,
const QSet<QString> &metaCommandSet);
Doc(const Location& start_loc,
const Location& end_loc,
const QString& source,
const QSet<QString>& metaCommandSet,
const QSet<QString>& topics);
Doc(const Doc &doc);
~Doc();
Doc& operator=( const Doc& doc );
void renameParameters(const QStringList &oldNames,
const QStringList &newNames);
void simplifyEnumDoc();
void setBody(const Text &body);
const DitaRefList& ditamap() const;
const Location &location() const;
bool isEmpty() const;
const QString& source() const;
const Text& body() const;
Text briefText(bool inclusive = false) const;
Text trimmedBriefText(const QString &className) const;
Text legaleseText() const;
const QString& baseName() const;
Sections granularity() const;
const QSet<QString> &parameterNames() const;
const QStringList &enumItemNames() const;
const QStringList &omitEnumItemNames() const;
const QSet<QString> &metaCommandsUsed() const;
const TopicList& topicsUsed() const;
QStringList metaCommandArgs( const QString& metaCommand ) const;
const QList<Text> &alsoList() const;
bool hasTableOfContents() const;
bool hasKeywords() const;
bool hasTargets() const;
const QList<Atom *> &tableOfContents() const;
const QList<int> &tableOfContentsLevels() const;
const QList<Atom *> &keywords() const;
const QList<Atom *> &targets() const;
const QStringMultiMap &metaTagMap() const;
static void initialize( const Config &config );
static void terminate();
static QString alias( const QString &english );
static void trimCStyleComment( Location& location, QString& str );
static CodeMarker *quoteFromFile(const Location &location,
Quoter &quoter,
const QString &fileName);
static QString canonicalTitle(const QString &title);
private:
void detach();
DocPrivate *priv;
};
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,31 @@
alias.i = e
alias.include = input
macro.0 = "\\\\0"
macro.b = "\\\\b"
macro.n = "\\\\n"
macro.r = "\\\\r"
macro.i = "\\o"
macro.i11 = "\\o{1,1}"
macro.i12 = "\\o{1,2}"
macro.i13 = "\\o{1,3}"
macro.i14 = "\\o{1,4}"
macro.i15 = "\\o{1,5}"
macro.i16 = "\\o{1,6}"
macro.i17 = "\\o{1,7}"
macro.i18 = "\\o{1,8}"
macro.i19 = "\\o{1,9}"
macro.i21 = "\\o{2,1}"
macro.i31 = "\\o{3,1}"
macro.i41 = "\\o{4,1}"
macro.i51 = "\\o{5,1}"
macro.i61 = "\\o{6,1}"
macro.i71 = "\\o{7,1}"
macro.i81 = "\\o{8,1}"
macro.i91 = "\\o{9,1}"
macro.img = "\\image"
macro.endquote = "\\endquotation"
macro.relatesto = "\\relates"
spurious = "Missing comma in .*" \
"Missing pattern .*"

View File

@ -0,0 +1,13 @@
SOURCES = config.pro \
compat.qdocconf \
qdoc-online.qdocconf \
qt-defines.qdocconf \
qt-html-templates.qdocconf \
qdoc-project.qdocconf \
qt-html-default-styles.qdocconf \
qdoc.qdocconf \
qt-html-online-styles.qdocconf \
macros.qdocconf \
qt-cpp-ignore.qdocconf \
qt-html-templates-online.qdocconf

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -0,0 +1,40 @@
macro.aacute.HTML = "&aacute;"
macro.Aring.HTML = "&Aring;"
macro.aring.HTML = "&aring;"
macro.Auml.HTML = "&Auml;"
macro.author = "\\bold{Author:}"
macro.br.HTML = "<br />"
macro.BR.HTML = "<br />"
macro.copyright.HTML = "&copy;"
macro.eacute.HTML = "&eacute;"
macro.gui = "\\bold"
macro.hr.HTML = "<hr />"
macro.iacute.HTML = "&iacute;"
macro.key = "\\bold"
macro.menu = "\\bold"
macro.note = "\\bold{Note:}"
macro.oslash.HTML = "&oslash;"
macro.ouml.HTML = "&ouml;"
macro.QA = "\\e{Qt Assistant}"
macro.QD = "\\e{Qt Designer}"
macro.QL = "\\e{Qt Linguist}"
macro.QQV = "\\e{Qt QML Viewer}"
macro.param = "\\e"
macro.raisedaster.HTML = "<sup>*</sup>"
macro.rarrow.HTML = "&rarr;"
macro.reg.HTML = "<sup>&reg;</sup>"
macro.return = "Returns"
macro.starslash = "\\c{*/}"
macro.begincomment = "\\c{/*}"
macro.endcomment = "\\c{*/}"
macro.uuml.HTML = "&uuml;"
macro.mdash.HTML = "&mdash;"
macro.pi.HTML = "&Pi;"
macro.beginqdoc.HTML = "/*!"
macro.endqdoc.HTML = "*/"
macro.beginfloatleft.HTML = "<div style=\"float: left; margin-right: 2em\">"
macro.beginfloatright.HTML = "<div style=\"float: right; margin-left: 2em\">"
macro.endfloat.HTML = "</div>"
macro.clearfloat.HTML = "<br style=\"clear: both\" />"
macro.emptyspan.HTML = "<span></span>"

View File

@ -0,0 +1,2 @@
include(qdoc-project.qdocconf)
include(qt-html-templates-online.qdocconf)

View File

@ -0,0 +1,48 @@
include(compat.qdocconf)
include(macros.qdocconf)
include(qt-cpp-ignore.qdocconf)
include(qt-defines.qdocconf)
indexes = $$MODULE_BUILD_TREE/doc/html/qt.index
sourceencoding = UTF-8
outputencoding = UTF-8
naturallanguage = en_US
project = QDoc
description = QDoc3 Manual
url = http://doc.qt.nokia.com/qdoc
sources.fileextensions = "*.cpp *.qdoc *.mm *.qml"
headers.fileextensions = "*.h *.ch *.h++ *.hh *.hpp *.hxx"
examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp *.qml *.qdoc *.qdocconf *.qdocinc"
examples.imageextensions = "*.png *.jpeg *.jpg *.gif *.mng"
sourcedirs = ..
exampledirs = .. \
../examples \
../../../../examples \
config
imagedirs = ../../../doc/src/templates/images \
images
outputdir = $$MODULE_BUILD_TREE/tools/qdoc3/doc/html
tagfile = $$MODULE_BUILD_TREE/tools/qdoc3/doc/html/qdoc.tags
qhp.projects = QDoc
qhp.QDoc.file = qdoc.qhp
qhp.QDoc.namespace = com.trolltech.qdoc
qhp.QDoc.virtualFolder = qdoc
qhp.QDoc.indexTitle = QDoc Manual - Table of Contents
qhp.QDoc.indexRoot =
qhp.QDoc.filterAttributes = qdoc qtrefdoc
qhp.QDoc.customFilters.QDoc.name = QDoc
qhp.QDoc.customFilters.QDoc.filterAttributes = qdoc
qhp.QDoc.subprojects = overviews
qhp.QDoc.subprojects.overviews.title = Overviews
qhp.QDoc.subprojects.overviews.indexTitle = All Overviews and HOWTOs
qhp.QDoc.subprojects.overviews.selectors = fake:page,group,module

View File

@ -0,0 +1,2 @@
include(qdoc-project.qdocconf)
include(qt-html-templates.qdocconf)

View File

@ -0,0 +1,98 @@
Cpp.ignoretokens = QAXFACTORY_EXPORT \
QDESIGNER_COMPONENTS_LIBRARY \
QDESIGNER_EXTENSION_LIBRARY \
QDESIGNER_SDK_LIBRARY \
QDESIGNER_SHARED_LIBRARY \
QDESIGNER_UILIB_LIBRARY \
QM_EXPORT_CANVAS \
QM_EXPORT_DNS \
QM_EXPORT_DOM \
QM_EXPORT_FTP \
QM_EXPORT_HTTP \
QM_EXPORT_ICONVIEW \
QM_EXPORT_NETWORK \
QM_EXPORT_OPENGL \
QM_EXPORT_OPENVG \
QM_EXPORT_SQL \
QM_EXPORT_TABLE \
QM_EXPORT_WORKSPACE \
QM_EXPORT_XML \
QT_ASCII_CAST_WARN \
QT_ASCII_CAST_WARN_CONSTRUCTOR \
QT_BEGIN_HEADER \
QT_DESIGNER_STATIC \
QT_END_HEADER \
QT_FASTCALL \
QT_WIDGET_PLUGIN_EXPORT \
Q_COMPAT_EXPORT \
Q_CORE_EXPORT \
Q_CORE_EXPORT_INLINE \
Q_EXPLICIT \
Q_EXPORT \
Q_EXPORT_CODECS_CN \
Q_EXPORT_CODECS_JP \
Q_EXPORT_CODECS_KR \
Q_EXPORT_PLUGIN \
Q_GFX_INLINE \
Q_AUTOTEST_EXPORT \
Q_GUI_EXPORT \
Q_GUI_EXPORT_INLINE \
Q_GUI_EXPORT_STYLE_CDE \
Q_GUI_EXPORT_STYLE_COMPACT \
Q_GUI_EXPORT_STYLE_MAC \
Q_GUI_EXPORT_STYLE_MOTIF \
Q_GUI_EXPORT_STYLE_MOTIFPLUS \
Q_GUI_EXPORT_STYLE_PLATINUM \
Q_GUI_EXPORT_STYLE_POCKETPC \
Q_GUI_EXPORT_STYLE_SGI \
Q_GUI_EXPORT_STYLE_WINDOWS \
Q_GUI_EXPORT_STYLE_WINDOWSXP \
QHELP_EXPORT \
Q_INLINE_TEMPLATE \
Q_INTERNAL_WIN_NO_THROW \
Q_LOCATION_EXPORT \
Q_NETWORK_EXPORT \
Q_OPENGL_EXPORT \
Q_OPENVG_EXPORT \
Q_OUTOFLINE_TEMPLATE \
Q_SQL_EXPORT \
Q_SVG_EXPORT \
Q_SCRIPT_EXPORT \
Q_SCRIPTTOOLS_EXPORT \
Q_TESTLIB_EXPORT \
Q_XML_EXPORT \
Q_XMLSTREAM_EXPORT \
Q_XMLPATTERNS_EXPORT \
QDBUS_EXPORT \
Q_DBUS_EXPORT \
QT_BEGIN_NAMESPACE \
QT_BEGIN_INCLUDE_NAMESPACE \
QT_END_NAMESPACE \
QT_END_INCLUDE_NAMESPACE \
PHONON_EXPORT \
Q_DECLARATIVE_EXPORT \
Q_GADGET \
QWEBKIT_EXPORT \
Q_INVOKABLE
Cpp.ignoredirectives = Q_DECLARE_HANDLE \
Q_DECLARE_INTERFACE \
Q_DECLARE_METATYPE \
Q_DECLARE_OPERATORS_FOR_FLAGS \
Q_DECLARE_PRIVATE \
Q_DECLARE_PUBLIC \
Q_DECLARE_SHARED \
Q_DECLARE_TR_FUNCTIONS \
Q_DECLARE_TYPEINFO \
Q_DISABLE_COPY \
QT_FORWARD_DECLARE_CLASS \
Q_DUMMY_COMPARISON_OPERATOR \
Q_ENUMS \
Q_FLAGS \
Q_INTERFACES \
__attribute__ \
K_DECLARE_PRIVATE \
PHONON_OBJECT \
PHONON_HEIR \
Q_PRIVATE_PROPERTY \
Q_DECLARE_PRIVATE_D \
Q_CLASSINFO

View File

@ -0,0 +1,17 @@
defines = Q_QDOC \
QT_.*_SUPPORT \
QT_.*_LIB \
QT_COMPAT \
QT_KEYPAD_NAVIGATION \
QT_NO_EGL \
QT3_SUPPORT \
Q_WS_.* \
Q_OS_.* \
Q_BYTE_ORDER \
QT_DEPRECATED \
Q_NO_USING_KEYWORD \
__cplusplus
versionsym = QT_VERSION_STR
codeindent = 1

View File

@ -0,0 +1,32 @@
# Define the location of the templates to use. Style sheets and scripts are
# specified relative to the template directory and will be copied into
# subdirectories of the output directory.
HTML.templatedir = .
HTML.stylesheets = style/offline.css
HTML.scripts =
# Files not referenced in any qdoc file (last four needed by qtdemo)
# See also qhp.Qt.extraFiles
extraimages.HTML = qt-logo.png \
arrow_down.png \
breadcrumb.png \
bullet_gt.png \
bullet_dn.png \
bullet_sq.png \
bullet_up.png \
horBar.png \
sprites-combined.png
# Include the style sheets and scripts used.
HTML.headerstyles = \
" <link rel=\"stylesheet\" type=\"text/css\" href=\"style/offline.css\" />\n"
HTML.headerscripts =
HTML.endheader = \
"</head>\n" \
"<body>\n"

View File

@ -0,0 +1,72 @@
# Define the location of the templates to use. Style sheets and scripts are
# specified relative to the template directory and will be copied into
# subdirectories of the output directory.
HTML.templatedir = .
HTML.stylesheets = style/narrow.css \
style/style.css \
style/style_ie6.css \
style/style_ie7.css \
style/style_ie8.css \
style/superfish.css
# Adding jquery and functions - providing online tools and search features
HTML.scripts = scripts/functions.js \
scripts/narrow.js \
scripts/superfish.js \
scripts/jquery.js
# Files not referenced in any qdoc file.
# See also qhp.Qt.extraFiles
extraimages.HTML = qt-logo.png \
bg_l.png \
bg_l_blank.png \
bg_ll_blank.png \
bg_ul_blank.png \
header_bg.png \
bg_r.png \
box_bg.png \
breadcrumb.png \
bullet_gt.png \
bullet_dn.png \
bullet_sq.png \
bullet_up.png \
arrow_down.png \
feedbackground.png \
horBar.png \
page.png \
page_bg.png \
sprites-combined.png \
spinner.gif
# Include the style sheets and scripts used.
HTML.headerstyles = \
" <link rel=\"stylesheet\" type=\"text/css\" href=\"style/style.css\" />\n" \
" <script src=\"scripts/jquery.js\" type=\"text/javascript\"></script>\n" \
" <script src=\"scripts/functions.js\" type=\"text/javascript\"></script>\n" \
" <link rel=\"stylesheet\" type=\"text/css\" href=\"style/superfish.css\" />\n" \
" <link rel=\"stylesheet\" type=\"text/css\" href=\"style/narrow.css\" />\n" \
" <!--[if IE]>\n" \
"<meta name=\"MSSmartTagsPreventParsing\" content=\"true\">\n" \
"<meta http-equiv=\"imagetoolbar\" content=\"no\">\n" \
"<![endif]-->\n" \
"<!--[if lt IE 7]>\n" \
"<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie6.css\">\n" \
"<![endif]-->\n" \
"<!--[if IE 7]>\n" \
"<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie7.css\">\n" \
"<![endif]-->\n" \
"<!--[if IE 8]>\n" \
"<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie8.css\">\n" \
"<![endif]-->\n\n"
HTML.headerscripts = \
"<script src=\"scripts/superfish.js\" type=\"text/javascript\"></script>\n" \
"<script src=\"scripts/narrow.js\" type=\"text/javascript\"></script>\n\n"
HTML.endheader = \
"</head>\n" \
"<body class=\"\" onload=\"CheckEmptyAndLoadList();\">\n"

View File

@ -0,0 +1,115 @@
include(qt-html-online-styles.qdocconf)
HTML.postheader = \
" <div class=\"header\" id=\"qtdocheader\">\n" \
" <div class=\"content\"> \n" \
" <div id=\"nav-logo\">\n" \
" <a href=\"index.html\">Home</a></div>\n" \
" <a href=\"index.html\" class=\"qtref\"><span>QDoc Reference Documentation</span></a>\n" \
" <div id=\"narrowsearch\"></div>\n" \
" <div id=\"nav-topright\">\n" \
" <ul>\n" \
" <li class=\"nav-topright-home\"><a href=\"http://qt.nokia.com/\">Qt HOME</a></li>\n" \
" <li class=\"nav-topright-dev\"><a href=\"http://developer.qt.nokia.com/\">DEV</a></li>\n" \
" <li class=\"nav-topright-labs\"><a href=\"http://labs.qt.nokia.com/blogs/\">LABS</a></li>\n" \
" <li class=\"nav-topright-doc nav-topright-doc-active\"><a href=\"http://doc.qt.nokia.com/\">\n" \
" DOC</a></li>\n" \
" <li class=\"nav-topright-blog\"><a href=\"http://blog.qt.nokia.com/\">BLOG</a></li>\n" \
" </ul>\n" \
" </div>\n" \
" <div id=\"shortCut\">\n" \
" <ul>\n" \
" <li class=\"shortCut-topleft-inactive\"><span><a href=\"index.html\">Qt 4.7</a></span></li>\n" \
" <li class=\"shortCut-topleft-active\"><a href=\"http://doc.qt.nokia.com\">ALL VERSIONS" \
" </a></li>\n" \
" </ul>\n" \
" </div>\n" \
" </div>\n" \
" </div>\n" \
" <div class=\"wrapper\">\n" \
" <div class=\"hd\">\n" \
" <span></span>\n" \
" </div>\n" \
" <div class=\"bd group\">\n" \
" <div class=\"wrap\">\n" \
" <div class=\"toolbar\">\n" \
" <div class=\"breadcrumb toolblock\">\n" \
" <ul>\n" \
" <li class=\"first\"><a href=\"index.html\">Home</a></li>\n" \
" <!-- Breadcrumbs go here -->\n"
HTML.postpostheader = \
" </ul>\n" \
" </div>\n" \
" <div class=\"toolbuttons toolblock\">\n" \
" <ul>\n" \
" <li id=\"smallA\" class=\"t_button\">A</li>\n" \
" <li id=\"medA\" class=\"t_button active\">A</li>\n" \
" <li id=\"bigA\" class=\"t_button\">A</li>\n" \
" <li id=\"print\" class=\"t_button\"><a href=\"javascript:this.print();\">\n" \
" <span>Print</span></a></li>\n" \
" </ul>\n" \
" </div>\n" \
" </div>\n" \
" <div class=\"content mainContent\">\n"
HTML.footer = \
" </div>\n" \
" </div>\n" \
" </div> \n" \
" <div class=\"ft\">\n" \
" <span></span>\n" \
" </div>\n" \
" </div> \n" \
" <div class=\"footer\">\n" \
" <p>\n" \
" <acronym title=\"Copyright\">&copy;</acronym> 2012 Nokia Corporation and/or its\n" \
" subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation \n" \
" in Finland and/or other countries worldwide.</p>\n" \
" <p>\n" \
" All other trademarks are property of their respective owners. <a title=\"Privacy Policy\"\n" \
" href=\"http://qt.nokia.com/about/privacy-policy\">Privacy Policy</a></p>\n" \
" <br />\n" \
" <p>\n" \
" Licensees holding valid Qt Commercial licenses may use this document in accordance with the" \
" Qt Commercial License Agreement provided with the Software or, alternatively, in accordance" \
" with the terms contained in a written agreement between you and Nokia.</p>\n" \
" <p>\n" \
" Alternatively, this document may be used under the terms of the <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU\n" \
" Free Documentation License version 1.3</a>\n" \
" as published by the Free Software Foundation.</p>\n" \
" </div>\n"
# Files not referenced in any qdoc file.
# See also extraimages.HTML
qhp.QDoc.extraFiles = index.html \
images/bg_l.png \
images/bg_l_blank.png \
images/bg_ll_blank.png \
images/bg_ul_blank.png \
images/header_bg.png \
images/bg_r.png \
images/box_bg.png \
images/breadcrumb.png \
images/bullet_gt.png \
images/bullet_dn.png \
images/bullet_sq.png \
images/bullet_up.png \
images/arrow_down.png \
images/feedbackground.png \
images/horBar.png \
images/page.png \
images/page_bg.png \
images/sprites-combined.png \
images/spinner.gif \
scripts/functions.js \
scripts/jquery.js \
scripts/narrow.js \
scripts/superfish.js \
style/narrow.css \
style/superfish.css \
style/style_ie6.css \
style/style_ie7.css \
style/style_ie8.css \
style/style.css

View File

@ -0,0 +1,54 @@
include(qt-html-default-styles.qdocconf)
HTML.postheader = \
"<div class=\"header\" id=\"qtdocheader\">\n" \
" <div class=\"content\"> \n" \
" <a href=\"index.html\" class=\"qtref\"><span>QDoc Reference Documentation</span></a>\n" \
" </div>\n" \
" <div class=\"breadcrumb toolblock\">\n" \
" <ul>\n" \
" <li class=\"first\"><a href=\"index.html\">Home</a></li>\n" \
" <!-- Breadcrumbs go here -->\n"
HTML.postpostheader = \
" </ul>\n" \
" </div>\n" \
"</div>\n" \
"<div class=\"content mainContent\">\n"
HTML.footer = \
" <div class=\"ft\">\n" \
" <span></span>\n" \
" </div>\n" \
"</div> \n" \
"<div class=\"footer\">\n" \
" <p>\n" \
" <acronym title=\"Copyright\">&copy;</acronym> 2012 Nokia Corporation and/or its\n" \
" subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation \n" \
" in Finland and/or other countries worldwide.</p>\n" \
" <p>\n" \
" All other trademarks are property of their respective owners. <a title=\"Privacy Policy\"\n" \
" href=\"http://qt.nokia.com/about/privacy-policy\">Privacy Policy</a></p>\n" \
" <br />\n" \
" <p>\n" \
" Licensees holding valid Qt Commercial licenses may use this document in accordance with the" \
" Qt Commercial License Agreement provided with the Software or, alternatively, in accordance" \
" with the terms contained in a written agreement between you and Nokia.</p>\n" \
" <p>\n" \
" Alternatively, this document may be used under the terms of the <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU\n" \
" Free Documentation License version 1.3</a>\n" \
" as published by the Free Software Foundation.</p>\n" \
"</div>\n" \
# Files not referenced in any qdoc file.
# See also extraimages.HTML
qhp.QDoc.extraFiles = index.html \
images/arrow_down.png \
images/breadcrumb.png \
images/bullet_gt.png \
images/bullet_dn.png \
images/bullet_sq.png \
images/bullet_up.png \
images/horBar.png \
images/sprites-combined.png \
style/offline.css

View File

@ -0,0 +1,673 @@
@media screen
{
/* basic elements */
html
{
color: #000000;
background: #FFFFFF;
}
table
{
border-collapse: collapse;
border-spacing: 0;
}
fieldset, img
{
border: 0;
max-width:100%;
}
address, caption, cite, code, dfn, em, strong, th, var, optgroup
{
font-style: inherit;
font-weight: inherit;
}
del, ins
{
text-decoration: none;
}
li
{
list-style: none;
}
ol li
{
list-style: decimal;
}
caption, th
{
text-align: left;
}
h1, h2, h3, h4, h5, h6
{
font-size: 100%;
}
q:before, q:after
{
content: '';
}
abbr, acronym
{
border: 0;
font-variant: normal;
}
sup, sub
{
vertical-align: baseline;
}
tt, .qmlreadonly span, .qmldefault span
{
word-spacing:0.5em;
}
legend
{
color: #000000;
}
strong
{
font-weight: bold;
}
em
{
font-style: italic;
}
body
{
margin-left: 0.5em;
margin-right: 0.5em;
}
a
{
color: #00732F;
text-decoration: none;
}
hr
{
background-color: #E6E6E6;
border: 1px solid #E6E6E6;
height: 1px;
width: 100%;
text-align: left;
margin: 1.5em 0 1.5em 0;
}
pre
{
border: 1px solid #DDDDDD;
-moz-border-radius: 0.7em 0.7em 0.7em 0.7em;
-webkit-border-radius: 0.7em 0.7em 0.7em 0.7em;
border-radius: 0.7em 0.7em 0.7em 0.7em;
margin: 0 1.5em 1em 1em;
padding: 1em 1em 1em 1em;
overflow-x: auto;
}
table, pre
{
-moz-border-radius: 0.7em 0.7em 0.7em 0.7em;
-webkit-border-radius: 0.7em 0.7em 0.7em 0.7em;
border-radius: 0.7em 0.7em 0.7em 0.7em;
background-color: #F6F6F6;
border: 1px solid #E6E6E6;
border-collapse: separate;
margin-bottom: 2.5em;
}
pre {
font-size: 90%;
display: block;
overflow:hidden;
}
thead
{
margin-top: 0.5em;
font-weight: bold
}
th
{
padding: 0.5em 1.5em 0.5em 1.5em;
background-color: #E1E1E1;
border-left: 1px solid #E6E6E6;
}
td
{
padding: 0.25em 1.5em 0.25em 2em;
}
td.rightAlign
{
padding: 0.25em 0.5em 0.25em 1em;
}
table tr.odd
{
border-left: 1px solid #E6E6E6;
background-color: #F6F6F6;
color: #66666E;
}
table tr.even
{
border-left: 1px solid #E6E6E6;
background-color: #ffffff;
color: #66666E;
}
div.float-left
{
float: left; margin-right: 2em
}
div.float-right
{
float: right; margin-left: 2em
}
span.comment
{
color: #008B00;
font-style: italic
}
span.string, span.char
{
color: #000084;
}
span.number
{
color: #a46200;
}
span.operator
{
color: #202020;
}
span.keyword
{
color: #840000;
}
span.name
{
color: black
}
span.type
{
font-weight: bold
}
span.type a:visited
{
color: #0F5300;
}
span.preprocessor
{
color: #404040
}
/* end basic elements */
/* font style elements */
.heading
{
font-weight: bold;
font-size: 125%;
}
.subtitle
{
font-size: 110%
}
.small-subtitle
{
font-size: 100%
}
.red
{
color:red;
}
/* end font style elements */
/* global settings*/
.header, .footer
{
display: block;
clear: both;
overflow: hidden;
}
/* end global settings*/
/* header elements */
.header .qtref
{
color: #00732F;
font-weight: bold;
font-size: 130%;
}
.header .content
{
margin-bottom: 0.5em
}
.naviNextPrevious
{
display: none
}
.header .breadcrumb
{
font-size: 90%;
padding: 0.5em 0 0.5em 1em;
margin: 0;
background-color: #fafafa;
height: 1.35em;
border-bottom: 1px solid #d1d1d1;
}
.header .breadcrumb ul
{
margin: 0;
padding: 0;
}
.header .content
{
word-wrap: break-word;
}
.header .breadcrumb ul li
{
float: left;
background: url(../images/breadcrumb.png) no-repeat 0 3px;
padding-left: 1.5em;
margin-left: 1.5em;
}
.header .breadcrumb ul li.last
{
font-weight: normal;
}
.header .breadcrumb ul li a
{
color: #00732F;
}
.header .breadcrumb ul li.first
{
background-image: none;
padding-left: 0;
margin-left: 0;
}
.header .content ol li {
background: none;
margin-bottom: 1.0em;
margin-left: 1.2em;
padding-left: 0
}
.header .content li
{
background: url(../images/bullet_sq.png) no-repeat 0 5px;
margin-bottom: 1em;
padding-left: 1.2em;
}
/* end header elements */
/* content elements */
.content h1
{
font-weight: bold;
font-size: 150%
}
.content h2
{
font-weight: bold;
font-size: 135%;
width: 100%;
}
.content h3
{
font-weight: bold;
font-size: 120%;
width: 100%;
}
.content table p
{
margin: 0
}
.content ul
{
padding-left: 2.5em;
}
.content li
{
padding-top: 0.25em;
padding-bottom: 0.25em;
}
.content ul img {
vertical-align: middle;
}
.content a:visited
{
color: #4c0033;
text-decoration: none;
}
.content a:visited:hover
{
color: #4c0033;
text-decoration: underline;
}
a:hover
{
color: #4c0033;
text-decoration: underline;
}
descr p a
{
text-decoration: underline;
}
.descr p a:visited
{
text-decoration: underline;
}
.alphaChar{
width:95%;
background-color:#F6F6F6;
border:1px solid #E6E6E6;
-moz-border-radius: 7px 7px 7px 7px;
border-radius: 7px 7px 7px 7px;
-webkit-border-radius: 7px 7px 7px 7px;
font-size:12pt;
padding-left:10px;
margin-top:10px;
margin-bottom:10px;
}
.flowList{
/*vertical-align:top;*/
/*margin:20px auto;*/
column-count:3;
-webkit-column-count:3;
-moz-column-count:3;
/*
column-width:100%;
-webkit-column-width:200px;
-col-column-width:200px;
*/
column-gap:41px;
-webkit-column-gap:41px;
-moz-column-gap:41px;
column-rule: 1px dashed #ccc;
-webkit-column-rule: 1px dashed #ccc;
-moz-column-rule: 1px dashed #ccc;
}
.flowList dl{
}
.flowList dd{
/*display:inline-block;*/
margin-left:10px;
min-width:250px;
line-height: 1.5;
min-width:100%;
min-height:15px;
}
.flowList dd a{
}
.content .flowList p{
padding:0px;
}
.content .alignedsummary
{
margin: 15px;
}
.qmltype
{
text-align: center;
font-size: 120%;
}
.qmlreadonly
{
padding-left: 5px;
float: right;
color: #254117;
}
.qmldefault
{
padding-left: 5px;
float: right;
color: red;
}
.qmldoc
{
}
.generic .alphaChar{
margin-top:5px;
}
.generic .odd .alphaChar{
background-color: #F6F6F6;
}
.generic .even .alphaChar{
background-color: #FFFFFF;
}
.memItemRight{
padding: 0.25em 1.5em 0.25em 0;
}
.highlightedCode
{
margin: 1.0em;
}
.annotated td {
padding: 0.25em 0.5em 0.25em 0.5em;
}
.header .content .toc ul
{
padding-left: 0px;
}
.content .toc h3 {
border-bottom: 0px;
margin-top: 0px;
}
.content .toc h3 a:hover {
color: #00732F;
text-decoration: none;
}
.content .toc .level2
{
margin-left: 1.5em;
}
.content .toc .level3
{
margin-left: 3.0em;
}
.content ul li
{
background: url(../images/bullet_sq.png) no-repeat 0 0.7em;
padding-left: 1em
}
.content .toc li
{
background: url(../images/bullet_dn.png) no-repeat 0 5px;
padding-left: 1em
}
.relpage
{
-moz-border-radius: 7px 7px 7px 7px;
-webkit-border-radius: 7px 7px 7px 7px;
border-radius: 7px 7px 7px 7px;
border: 1px solid #DDDDDD;
padding: 25px 25px;
clear: both;
}
.relpage ul
{
float: none;
padding: 1.5em;
}
h3.fn, span.fn
{
-moz-border-radius:7px 7px 7px 7px;
-webkit-border-radius:7px 7px 7px 7px;
border-radius:7px 7px 7px 7px;
background-color: #F6F6F6;
border-width: 1px;
border-style: solid;
border-color: #E6E6E6;
font-weight: bold;
word-spacing:3px;
padding:3px 5px;
}
.functionIndex {
font-size:12pt;
word-spacing:10px;
margin-bottom:10px;
background-color: #F6F6F6;
border-width: 1px;
border-style: solid;
border-color: #E6E6E6;
-moz-border-radius: 7px 7px 7px 7px;
-webkit-border-radius: 7px 7px 7px 7px;
border-radius: 7px 7px 7px 7px;
width:100%;
}
.centerAlign
{
text-align:center;
}
.rightAlign
{
text-align:right;
}
.leftAlign
{
text-align:left;
}
.topAlign{
vertical-align:top
}
.functionIndex a{
display:inline-block;
}
/* end content elements */
/* footer elements */
.footer
{
color: #393735;
font-size: 0.75em;
text-align: center;
padding-top: 1.5em;
padding-bottom: 1em;
background-color: #E6E7E8;
margin: 0;
}
.footer p
{
margin: 0.25em
}
.small
{
font-size: 0.5em;
}
/* end footer elements */
.item {
float: left;
position: relative;
width: 100%;
overflow: hidden;
}
.item .primary {
margin-right: 220px;
position: relative;
}
.item hr {
margin-left: -220px;
}
.item .secondary {
float: right;
width: 200px;
position: relative;
}
.item .cols {
clear: both;
display: block;
}
.item .cols .col {
float: left;
margin-left: 1.5%;
}
.item .cols .col.first {
margin-left: 0;
}
.item .cols.two .col {
width: 45%;
}
.item .box {
margin: 0 0 10px 0;
}
.item .box h3 {
margin: 0 0 10px 0;
}
.cols.unclear {
clear:none;
}
}
/* end of screen media */
/* start of print media */
@media print
{
input, textarea, .header, .footer, .toolbar, .feedback, .wrapper .hd, .wrapper .bd .sidebar, .wrapper .ft, #feedbackBox, #blurpage, .toc, .breadcrumb, .toolbar, .floatingResult
{
display: none;
background: none;
}
.content
{
background: none;
display: block;
width: 100%; margin: 0; float: none;
}
}
/* end of print media */

View File

@ -0,0 +1,35 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** GNU Free Documentation License
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms
** and conditions contained in a signed written agreement between you
** and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\page corefeatures.html
\title Core Features
\input examples/signalandslots.qdocinc
\input examples/objectmodel.qdocinc
\input examples/layoutmanagement.qdocinc
*/

View File

@ -0,0 +1,135 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 1.0
/*!
\qmlclass ProgressBar
\inqmlmodule UIComponents 1.0
\brief A component that shows the progress of an event
A ProgressBar shows the linear progress of an event as its \l value.
The range is specified using the \l {minimum} and the \l{maximum} values.
The ProgressBar component is part of the \l {UI Components} module.
This documentation is part of the \l{componentset}{UIComponents} example.
*/
Item {
id: progressbar
/*!
The minumum value of the ProgressBar range.
The \l value must not be less than this value.
*/
property int minimum: 0
/*!
The maximum value of the ProgressBar range.
The \l value must not be more than this value.
*/
property int maximum: 100
/*!
The value of the progress.
*/
property int value: 0
/*!
\qmlproperty color ProgressBar::color
The color of the ProgressBar's gradient. Must bind to a color type.
\omit
The "\qmlproperty <type> <property name>" is needed because
property alias need to have their types manually entered.
QDoc will not publish the documentation within omit and endomit.
\endomit
\sa secondcolor
*/
property alias color: gradient1.color
/*!
\qmlproperty color ProgressBar::secondcolor
The second color of the ProgressBar's gradient.
Must bind to a color type.
\omit
The "\qmlproperty <type> <property name>" is needed because
property alias need to have their types manually entered.
QDoc will not publish the documentation within omit and endomit.
\endomit
\sa color
*/
property alias secondColor: gradient2.color
width: 250; height: 23
clip: true
Rectangle {
id: highlight
/*!
An internal documentation comment. The widthDest property is not
a public API and therefore will not be exposed.
*/
property int widthDest: ((progressbar.width * (value - minimum)) / (maximum - minimum) - 6)
width: highlight.widthDest
Behavior on width { SmoothedAnimation { velocity: 1200 } }
anchors { left: parent.left; top: parent.top; bottom: parent.bottom; margins: 3 }
radius: 1
gradient: Gradient {
GradientStop { id: gradient1; position: 0.0 }
GradientStop { id: gradient2; position: 1.0 }
}
}
Text {
anchors { right: highlight.right; rightMargin: 6; verticalCenter: parent.verticalCenter }
color: "white"
font.bold: true
text: Math.floor((value - minimum) / (maximum - minimum) * 100) + '%'
}
}

View File

@ -0,0 +1,142 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 1.0
/*!
\qmlclass ToggleSwitch
\inqmlmodule UIComponents 1.0
\brief A component that can be turned on or off
A toggle switch has two states: an \c on and an \c off state. The \c off
state is when the \l on property is set to \c false.
The ToggleSwitch component is part of the \l {UI Components} module.
This documentation is part of the \l{componentset}{UIComponents} example.
*/
Item {
id: toggleswitch
width: background.width; height: background.height
/*!
Indicates the state of the switch. If \c false, then the switch is in
the \c off state.
\omit
The \qmlproperty <type> <propertyname> is not necessary as QDoc
will associate this property to the ToggleSwitch
QDoc will not publish the documentation within omit and endomit.
\endomit
*/
property bool on: false
/*!
A method to toggle the switch. If the switch is \c on, the toggling it
will turn it \c off. Toggling a switch in the \c off position will
turn it \c on.
*/
function toggle() {
if (toggleswitch.state == "on")
toggleswitch.state = "off";
else
toggleswitch.state = "on";
}
/*!
\internal
An internal function to synchronize the switch's internals. This
function is not for public access. The \internal command will
prevent QDoc from publishing this comment in the public API.
*/
function releaseSwitch() {
if (knob.x == 1) {
if (toggleswitch.state == "off") return;
}
if (knob.x == 78) {
if (toggleswitch.state == "on") return;
}
toggle();
}
Rectangle {
id: background
width: 130; height: 48
radius: 48
color: "lightsteelblue"
MouseArea { anchors.fill: parent; onClicked: toggle() }
}
Rectangle {
id: knob
width: 48; height: 48
radius: width
color: "lightblue"
MouseArea {
anchors.fill: parent
drag.target: knob; drag.axis: Drag.XAxis; drag.minimumX: 1; drag.maximumX: 78
onClicked: toggle()
onReleased: releaseSwitch()
}
}
states: [
State {
name: "on"
PropertyChanges { target: knob; x: 78 }
PropertyChanges { target: toggleswitch; on: true }
},
State {
name: "off"
PropertyChanges { target: knob; x: 1 }
PropertyChanges { target: toggleswitch; on: false }
}
]
transitions: Transition {
NumberAnimation { properties: "x"; easing.type: Easing.InOutQuad; duration: 200 }
}
}

View File

@ -0,0 +1,183 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
** the names of its contributors may be used to endorse or promote
** products derived from this software without specific prior written
** permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
import QtQuick 1.0
/*!
\qmlclass TabWidget
\inqmlmodule UIComponents 1.0
\brief A widget that places its children as tabs
A TabWidget places its children as tabs in a view. Selecting
a tab involves selecting the tab at the top.
The TabWidget component is part of the \l {UI Components} module.
This documentation is part of the \l{componentset}{UIComponents} example.
\section1 Adding Tabs
To add a tab, declare the tab as a child of the TabWidget.
\code
TabWidget {
id: tabwidget
Rectangle {
id: tab1
color: "red"
//... omitted
}
Rectangle {
id: tab2
color: "blue"
//... omitted
}
}
\endcode
*/
Item {
id: tabWidget
/*!
\internal
Setting the default property to stack.children means any child items
of the TabWidget are actually added to the 'stack' item's children.
See the \l{"Property Binding in QML"}
documentation for details on default properties.
This is an implementation detail, not meant for public knowledge. Putting
the \internal command at the beginning will cause QDoc to not publish this
documentation in the public API page.
Normally, a property alias needs to have a
"\qmlproperty <type> <propertyname>" to assign the alias a type.
*/
default property alias content: stack.children
/*!
The currently active tab in the TabWidget.
*/
property int current: 0
/*!
A sample \c{read-only} property.
A contrived property to demonstrate QDoc's ability to detect
read-only properties.
The signature is:
\code
readonly property int sampleReadOnlyProperty: 0
\endcode
Note that the property must be initialized to a value.
*/
readonly property int sampleReadOnlyProperty: 0
/*!
\internal
This handler is an implementation
detail. The \c{\internal} command will prevent QDoc from publishing this
documentation on the public API.
*/
onCurrentChanged: setOpacities()
Component.onCompleted: setOpacities()
/*!
\internal
An internal function to set the opacity.
The \internal command will prevent QDoc from publishing this
documentation on the public API.
*/
function setOpacities() {
for (var i = 0; i < stack.children.length; ++i) {
stack.children[i].opacity = (i == current ? 1 : 0)
}
}
Row {
id: header
Repeater {
model: stack.children.length
delegate: Rectangle {
width: tabWidget.width / stack.children.length; height: 36
Rectangle {
width: parent.width; height: 1
anchors { bottom: parent.bottom; bottomMargin: 1 }
color: "#acb2c2"
}
BorderImage {
anchors { fill: parent; leftMargin: 2; topMargin: 5; rightMargin: 1 }
border { left: 7; right: 7 }
source: "tab.png"
visible: tabWidget.current == index
}
Text {
horizontalAlignment: Qt.AlignHCenter; verticalAlignment: Qt.AlignVCenter
anchors.fill: parent
text: stack.children[index].title
elide: Text.ElideRight
font.bold: tabWidget.current == index
}
MouseArea {
anchors.fill: parent
onClicked: tabWidget.current = index
}
}
}
}
Item {
id: stack
width: tabWidget.width
anchors.top: header.bottom; anchors.bottom: tabWidget.bottom
}
}

View File

@ -0,0 +1,5 @@
SOURCES = componentset.pro \
ProgressBar.qml \
Switch.qml \
TabWidget.qml \
uicomponents.qdoc

View File

@ -0,0 +1,37 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** GNU Free Documentation License
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms
** and conditions contained in a signed written agreement between you
** and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\qmlmodule UIComponents 1.0
\title UI Components
\brief Basic set of QML Components
This is a listing of a list of QML components. These files are available
for general import and they are based off the \l{Qt Quick Code Samples}.
This module is part of the \l{componentset}{UIComponents} example.
*/

View File

@ -0,0 +1,84 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** GNU Free Documentation License
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms
** and conditions contained in a signed written agreement between you
** and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\example componentset
\title QML Documentation Example
This example demonstrates one of the ways to document QML components.
In particular, there are sample components that are documented with QDoc
commands comments. There are documentation comments for the QML components
and their public interfaces. The components are grouped into a module, the
\l {UI Components} module.
The \l{componentset/uicomponents.qdoc}{uicomponents.qdoc} file generates
the overview page for the \l {UI Components} module page.
The generated documentation is available in the \l {UI Components} module.
\section1 QML Class
The components use the \l{qmlclass-command}{\\qmlclass} to document the
component. In addition, they have the \l{inmodule-command}{\\inmodule}
command in order for QDoc to associate them to the \c UIComponents module.
QDoc uses the \l{brief-command}{\\brief} command to place a basic
description when listing the component.
\section1 Properties, Signals, Handlers, and Methods
The components have their properties, signals, handlers, and methods
defined in their respective QML files. QDoc associates the properties and
methods to the components, therefore, you only need to place the
documentation above the property, method, or signal.
To document the type of a \e {property alias}, you must use the
\l{qmlproperty-command}{\\qmlproperty} command to specify the data type.
\code
\qmlproperty int anAliasedProperty
An aliased property of type int.
\endcode
\section2 Internal Documentation
You may declare that a documentation is for internal use by placing the
\l{internal-command}{\\internal} command after the beginning QDoc comment
\begincomment. QDoc will prevent the internal documentation from appearing
in the public API.
If you wish to omit certain parts of the documentation, you may use the
\l{omit-command}{\\omit} and \l{omit-command}{\\endomit} command.
\section1 Components with C++ Implementation
This example only demonstrates the documentation for components in QML
files, but the regular \l{qml-documentation}{QML commands} may be placed
inside C++ classes to define the public API of the component.
*/

View File

@ -0,0 +1,13 @@
\section1 Layout Classes
The Qt layout system provides a simple and powerful way of specifying
the layout of child widgets.
By specifying the logical layout once, you get the following benefits:
\list
\o Positioning of child widgets.
\o Sensible default sizes for windows.
\o Sensible minimum sizes for windows.
\o ...
\endlist

View File

@ -0,0 +1,54 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QApplication>
#include <QPushButton>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QPushButton hello("Hello world!");
hello.resize(100, 30);
hello.show();
return app.exec();
}

View File

@ -0,0 +1,42 @@
# QDoc is a tool that constantly evolves to suit our needs,
# and there are some compatibility issues between old and new
# practices. For that reason, any QDoc configuration file needs to
# include compat.qdocconf.
#include(compat.qdocconf)
# The outputdir variable specifies the directory
# where QDoc will put the generated documentation.
outputdir = html
# The headerdirs variable specifies the directories
# containing the header files associated
# with the .cpp source files used in the documentation.
headerdirs = .
# The sourcedirs variable specifies the
# directories containing the .cpp or .qdoc
# files used in the documentation.
#sourcedirs = .
# The exampledirs variable specifies the directories containing
# the source code of the example files.
exampledirs = .
# The imagedirs variable specifies the
# directories containing the images used in the documentation.
imagedirs = ./images

View File

@ -0,0 +1,11 @@
\section1 Qt Object Model
The standard C++ object model provides very efficient runtime support
for the object paradigm. But its static nature is inflexibile in
certain problem domains. Graphical user interface programming is a
domain that requires both runtime efficiency and a high level of
flexibility. Qt provides this, by combining the speed of C++ with the
flexibility of the Qt Object Model.
...

View File

@ -0,0 +1,109 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** GNU Free Documentation License
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms
** and conditions contained in a signed written agreement between you
** and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
//! [qvector3d-class]
/*!
\class QVector3D
\brief The QVector3D class represents a vector or vertex in 3D space.
\since 4.6
\ingroup painting-3D
Vectors are one of the main building blocks of 3D representation and
drawing. They consist of three coordinates, traditionally called
x, y, and z.
The QVector3D class can also be used to represent vertices in 3D space.
We therefore do not need to provide a separate vertex class.
\bold{Note:} By design values in the QVector3D instance are stored as \c float.
This means that on platforms where the \c qreal arguments to QVector3D
functions are represented by \c double values, it is possible to
lose precision.
\sa QVector2D, QVector4D, QQuaternion
*/
//! [qvector3d-class]
//! [qvector3d-function]
/*!
\fn QVector3D::QVector3D(const QPoint& point)
Constructs a vector with x and y coordinates from a 2D \a point, and a
z coordinate of 0.
*/
//! [qvector3d-function]
//! [sample-page]
/*!
\page generic-guide.html
\title Generic QDoc Guide
\nextpage Creating QDoc Configuration Files
There are three essential materials for generating documentation with qdoc:
\list
\o \c qdoc binary
\o \c qdocconf configuration files
\o \c Documentation in \c C++, \c QML, and \c .qdoc files
\endlist
*/
//! [sample-page]
//! [sample-faq]
/*!
\page altruism-faq.html faq
\title Altruism Frequently Asked Questions
\brief All the questions about altruism, answered.
...
*/
//! [sample-faq]
//! [sample-example]
/*!
\title UI Components: Tab Widget Example
\example declarative/ui-components/tabwidget
This example shows how to create a tab widget. It also demonstrates how
\l {Property aliases}{property aliases} and
\l {Introduction to the QML Language#Default Properties}{default properties} can be used to collect and
assemble the child items declared within an \l Item.
\image qml-tabwidget-example.png
*/
//! [sample-example]
//! [sample-overview]
/*!
\page overview-qt-technology.html overview
\title Overview of a Qt Technology
\brief provides a technology never seen before.
*/
//! [sample-overview]

View File

@ -0,0 +1,9 @@
\section1 Signals and Slots
Signals and slots are used for communication between objects. The signals and
slots mechanism is a central feature of Qt and probably the part that differs
most from the features provided by other frameworks.
\section2 Introduction
In GUI programming, when we ...

View File

@ -0,0 +1,12 @@
alias.include = input
macro.0 = "\\\\0"
macro.b = "\\\\b"
macro.n = "\\\\n"
macro.r = "\\\\r"
macro.img = "\\image"
macro.endquote = "\\endquotation"
macro.relatesto = "\\relates"
spurious = "Missing comma in .*" \
"Missing pattern .*"

View File

@ -0,0 +1,115 @@
include(compat.qdocconf)
include(macros.qdocconf)
include(qt-cpp-ignore.qdocconf)
include(qt-html-templates.qdocconf)
include(qt-defines.qdocconf)
project = Qt
versionsym =
version = %VERSION%
description = Qt Reference Documentation
url = http://qt.nokia.com/doc/4.7
edition.Console.modules = QtCore QtDBus QtNetwork QtScript QtSql QtXml \
QtXmlPatterns QtTest
edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript QtScriptTools QtSql QtSvg \
QtWebKit QtXml QtXmlPatterns Qt3Support QtHelp \
QtDesigner QtAssistant QAxContainer Phonon \
QAxServer QtUiTools QtTest QtDBus
edition.DesktopLight.modules = QtCore QtDBus QtGui Qt3SupportLight QtTest
edition.DesktopLight.groups = -graphicsview-api
qhp.projects = Qt
qhp.Qt.file = qt.qhp
qhp.Qt.namespace = com.trolltech.qt.474
qhp.Qt.virtualFolder = qdoc
qhp.Qt.indexTitle = Qt Reference Documentation
qhp.Qt.indexRoot =
# Files not referenced in any qdoc file (last four are needed by qtdemo)
# See also extraimages.HTML
qhp.Qt.extraFiles = classic.css \
images/qt-logo.png \
images/taskmenuextension-example.png \
images/coloreditorfactoryimage.png \
images/dynamiclayouts-example.png \
images/stylesheet-coffee-plastique.png
qhp.Qt.filterAttributes = qt 4.7.4 qtrefdoc
qhp.Qt.customFilters.Qt.name = Qt 4.7.4
qhp.Qt.customFilters.Qt.filterAttributes = qt 4.7.4
qhp.Qt.subprojects = classes overviews examples
qhp.Qt.subprojects.classes.title = Classes
qhp.Qt.subprojects.classes.indexTitle = Qt's Classes
qhp.Qt.subprojects.classes.selectors = class fake:headerfile
qhp.Qt.subprojects.classes.sortPages = true
qhp.Qt.subprojects.overviews.title = Overviews
qhp.Qt.subprojects.overviews.indexTitle = All Overviews and HOWTOs
qhp.Qt.subprojects.overviews.selectors = fake:page,group,module
qhp.Qt.subprojects.examples.title = Tutorials and Examples
qhp.Qt.subprojects.examples.indexTitle = Qt Examples
qhp.Qt.subprojects.examples.selectors = fake:example
language = Cpp
headerdirs = $QTDIR/src \
$QTDIR/extensions/activeqt \
$QTDIR/tools/assistant/lib \
$QTDIR/tools/assistant/compat/lib \
$QTDIR/tools/designer/src/uitools \
$QTDIR/tools/designer/src/lib/extension \
$QTDIR/tools/designer/src/lib/sdk \
$QTDIR/tools/designer/src/lib/uilib \
$QTDIR/tools/qtestlib/src \
$QTDIR/tools/qdbus/src
sourcedirs = $QTDIR/src \
$QTDIR/doc/src \
$QTDIR/extensions/activeqt \
$QTDIR/tools/assistant/lib \
$QTDIR/tools/assistant/compat/lib \
$QTDIR/tools/designer/src/uitools \
$QTDIR/tools/designer/src/lib/extension \
$QTDIR/tools/designer/src/lib/sdk \
$QTDIR/tools/designer/src/lib/uilib \
$QTDIR/tools/qtestlib/src \
$QTDIR/tools/qdbus
excludedirs = $QTDIR/src/3rdparty/clucene \
$QTDIR/src/3rdparty/des \
$QTDIR/src/3rdparty/freetype \
$QTDIR/src/3rdparty/harfbuzz \
$QTDIR/src/3rdparty/kdebase \
$QTDIR/src/3rdparty/libjpeg \
$QTDIR/src/3rdparty/libmng \
$QTDIR/src/3rdparty/libpng \
$QTDIR/src/3rdparty/libtiff \
$QTDIR/src/3rdparty/md4 \
$QTDIR/src/3rdparty/md5 \
$QTDIR/src/3rdparty/patches \
$QTDIR/src/3rdparty/sha1 \
$QTDIR/src/3rdparty/sqlite \
$QTDIR/src/3rdparty/webkit/JavaScriptCore \
$QTDIR/src/3rdparty/webkit/WebCore \
$QTDIR/src/3rdparty/wintab \
$QTDIR/src/3rdparty/zlib \
$QTDIR/doc/src/snippets \
$QTDIR/src/3rdparty/phonon/gstreamer \
$QTDIR/src/3rdparty/phonon/ds9 \
$QTDIR/src/3rdparty/phonon/qt7 \
$QTDIR/src/3rdparty/phonon/waveout
sources.fileextensions = "*.cpp *.qdoc *.mm"
examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp"
exampledirs = $QTDIR/doc/src \
$QTDIR/examples \
$QTDIR/examples/tutorials \
$QTDIR \
$QTDIR/qmake/examples \
$QTDIR/src/3rdparty/webkit/WebKit/qt/docs
imagedirs = $QTDIR/doc/src/images \
$QTDIR/examples
outputdir = $QTDIR/doc/html
tagfile = $QTDIR/doc/html/qt.tags
base = file:$QTDIR/doc/html

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

View File

@ -0,0 +1,671 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** GNU Free Documentation License
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms
** and conditions contained in a signed written agreement between you
** and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\page qdoc-guide.html
\title Getting Started with QDoc
\nextpage Creating QDoc Configuration Files
Qt uses QDoc to generate its documentation set into HTML and DITA XML
formats. QDoc uses a set of configuration files to generate documentation
from QDoc comments. The comments have types called
\l{writing-topic-commands}{topics} that determine whether a comment is a
class documentation or a property documentation. A comment may also have
\l{writing-markup}{mark up} to enhance the layout and formatting of the
final output.
There are three essential materials for generating documentation with qdoc:
\list
\o \c QDoc binary
\o \c qdocconf configuration files
\o \c Documentation in \c C++, \c QML, and \c .qdoc files
\endlist
This section intends to cover the basic necessities for creating a
documentation set. Additionally, the guide presents special considerations
and options to documenting non-C++ API documentation as well as QML
documentation. Finally, the guide will provide a sample project
documentation and a QML component documentation.
For specific QDoc information, consult the
\l{Table of Contents}{QDoc Manual}.
\section1 Chapters
\list 1
\o \l{Creating QDoc Configuration Files}
\o \l{Writing Documentation}
\o \l{Categories of Documentation}
\o \l{Configuration File Example}
\o \l{QML Documentation Example}
\endlist
*/
/*!
\page qdoc-guide-conf.html
\title Creating QDoc Configuration Files
\previouspage Getting Started with QDoc
\nextpage Writing Documentation
To generate documentation, QDoc uses configuration files, with the
\c qdocconf extension, to store configuration settings.
The \l{The QDoc Configuration File} article covers the various configuration
variables in greater detail.
\section1 QDoc Configuration Files
QDoc's configuration settings can reside in a single \e qdocconf file, but
can also be in other qdocconf files. The \c {include(<filepath>)} command
allows configuration files to include other configuration files.
QDoc has two outputs, HTML documentation and documentation in DITA XML
format. The main distinction between the two outputs is that HTML
documentation needs to have its HTML styling information in the
configuration files. DITA XML documentation does not, and a separate process
can style the documentation in DITA at a later time. DITA XML is therefore
more flexible in allowing different styles to apply to the same information.
To run qdoc, the project configuration file is supplied as an argument.
\code
qdoc3 project.qdocconf
\endcode
The project configuration contains information that qdoc uses to create the
documentation.
\section2 Project Information
QDoc uses the \c project information to generate the documentation.
\code
project = QDoc Project
description = Sample QDoc project
\endcode
\target qdoc-input-output-dir
\section2 Input and Output Directories
Specifying the path to the source directories allow QDoc to find sources and
generate documentation.
\code
sourcedirs = <path to source code>
exampledirs = <path to examples directory>
imagedirs = <path to image directory>
sources.fileextensions = "*.cpp *.qdoc *.mm *.qml"
headers.fileextensions = "*.h *.ch *.h++ *.hh *.hpp *.hxx"
examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp *.qml"
examples.imageextensions = "*.png *.jpeg *.jpg *.gif *.mng"
\endcode
QDoc will process headers and sources from the ones specified in the
\c fileextensions variable.
Likewise, QDoc needs the path to the output directory. The \c outputformats
variable determines the type of documentation. These variables should be
in separate configuration files to modularize the documentation build.
\code
outputdir = $SAMPLE_PROJECT/doc/html
outputformats = HTML
\endcode
QDoc can resolve the paths relative to the qdocconf file as well as
environment variables.
\note During each QDoc run, the output directory is deleted.
\section2 Extra Files
QDoc will output generated documentation into the directory specified in
the \l{Input and Output Directories}{output} directory. It is also possible
to specify extra files that QDoc should export.
\code
extraimages.HTML = extraImage.png \
extraImage2.png
\endcode
The \c extraImage.png and the \c extraImage2.png files will be copied to the
HTML output directory.
\section2 Qt Help Framework Configuration
QDoc will also export a \l{Qt Help Project} file, in a \c qhp file.
The qhp file is then used by the \c qhelpgenerator to package the
documentation into a \c qch file. Qt Creator and Qt Assistant reads the qch
file to display the documentation.
The \l {Creating Help Project Files} article covers the configuration
options.
\section2 HTML Configuration
QDoc has an HTML generator that will export a set of documentation into
HTML files using various configuration settings. QDoc will place the
generated documentation into the directory specified by the \c outputdir
variable.
\code
outputformats = HTML
outputdir = <path to output directory>
\endcode
QDoc needs to know where the styles and templates for generating HTML
are located. Typically, the templates directory contains a \c scripts,
\c images, and a \c style directory, containing scripts and CSS files.
\code
HTML.templatedir = <path to templates>
\endcode
The main configuration variables are:
\code
HTML.postheader
HTML.postpostheader
HTML.postheader
HTML.footer
HTML.headerstyles
HTML.stylesheets = style.css \
style1.css
HTML.scripts = script.js
\endcode
The \c{HTML.headerstyles} variable inserts the style information into the
HTML file and the \c{HTML.stylesheets} specifies which files QDoc should
copy into the output directory. As well, QDoc will embed the string
in the \c postheader, \c footer, and related variables into each HTML file.
The \l {HTML Specific Configuration Variables} article outlines the usage
of each variable.
\section2 DITA XML Configuration
DITA XML output is enabled using the \c outputformats variable. Unlike HTML
documentation, QDoc does not need HTML style templates for generating
documentation in DITA XML format.
\code
outputformats = DITAXML
outputdir
\endcode
\section2 Qt Index Reference
Documentation projects can link to Qt APIs and other articles by specifying
the path to the \c qt.index file. When qdoc generates the Qt Reference
Documentation, it will also generate an index file, containing the URLs to
the articles. Other projects can use the links in the index file so that
they can link to other articles and API documentation within Qt.
\code
indexes = $QT_INSTALL_DOCS/html/qt.index $OTHER_PROJECT/html/qt.index
\endcode
It is possible to specify multiple index files from several projects.
\section1 Macros and Other Configurations
Macros for substituting HTML characters exist and are helpful for generating
specific HTML-valid characters.
\code
macro.pi.HTML = "&Pi;"
\endcode
The snippet code will replace any instances of \c{\\pi} with \c &Pi; in the
HTML file, which will appear as the Greek \pi symbol when viewed in
browsers.
There is quite a long list of macros for inserting text and
\l{alias-variable}{aliases} available.
\section2 QML Additions
QDoc is able to parse QML files for QDoc comments. QDoc will parse files
with the QML extension, \c{.qml}, if the extension type is included in the
\l{Input and Output Directories}{fileextensions} variable.
Also, the generated HTML files can have a prefix, specified in the QDoc
configuration file.
\code
outputprefixes = QML
outputprefixes.QML = qml-components-
\endcode
The outputprefixes will, for example, prefix QML components HTML filenames.
\code
files:
qml-components-button.html
qml-components-scrollbar.html
\endcode
*/
/*!
\page qdoc-guide-writing.html
\title Writing Documentation
\previouspage Creating QDoc Configuration Files
\nextpage Categories of Documentation
\section1 QDoc Comments
Documentation is contained within qdoc \e comments, delimited by
\beginqdoc and \endqdoc comments. Note that these are valid comments
in C++, QML, and JavaScript.
QDoc will parse C++ and QML files to look for qdoc comments. To explicitly
omit a certain file type, omit it from the
\l{Input and Output Directories}{configuration} file.
\section1 QDoc Commands
QDoc uses \e commands to retrieve information about the documentation. \c
Topic commands determine the type of documentation element, the \c context
commands provide hints and information about a topic, and \c markup commands
provide information on how QDoc should format a piece of documentation.
\target writing-topic-commands
\section2 QDoc Topics
Each qdoc comment must have a \e topic type. A topic distinguishes it from
other topics. To specify a topic type, use one of the several
\l{Topic Commands}{topic commands}.
QDoc will collect similar topics and create a page for each one. For
example, all the enumerations, properties, functions, and class description
of a particular C++ class will reside in one page. A generic page is
specified using the \l{page-command}{\\page} command and the filename is the
argument.
Example of topic commands:
\list
\o \l{enum-command}{\\enum} - for enumeration documentation
\o \l{class-command}{\\class} - for C++ class documentation
\o \l{qmlclass-command}{\\qmlclass} - for QML component documentation
\o \l{page-command}{\\page} - for creating a page.
\endlist
The \l{page-command}{\\page} command is for creating articles that are not
part of source documentation. The command can also accept two arguments: the
file name of the article and the documentation type. The possible types are:
\list
\o \c howto
\o \c overview
\o \c tutorial
\o \c faq
\o \c article - \e default when there is no type
\endlist
\snippet examples/samples.qdocinc sample-faq
The \l{Topic Commands} page has information on all of the available topic
commands.
\target writing-context
\section2 Topic Contexts
Context commands give QDoc a hint about the \e context of the topic. For
example, if a C++ function is obsolete, then it should be marked obsolete
with the \l{obsolete-command}{\\obsolete} command. Likewise,
\l{nextpage-command}{page navigation} and \l{title-command}{page title} 
give extra page information to QDoc.
QDoc will create additional links or pages for these contexts. For example,
a group is created using the \l{group-command}{\\group} command and the
members have the \l{ingroup-command}{\\ingroup} command. The group name is
supplied as an argument.
The \l{Context Commands} page has a listing of all the available context
commands.
\target writing-markup
\section2 Documentation Markup
QDoc can provide \e markup to content similar to other markup or
documentation tools. QDoc can mark a section of text in \bold{bold} when
the text is marked up with the \l{bold-command}{\\bold} command.
\code
\bold{This} text will be in \bold{bold}.
\endcode
The \l{Markup Commands} page has a full listing of the available markup
commands.
\section1 Anatomy of Documentation
Essentially, for QDoc to create a page, there must be some essential
ingredients present.
\list
\o Assign a topic to a QDoc comment - A comment could be a page, a
property documentation, a class documentation, or any of the available
\l{Topic Commands}{topic commands}.
\o Give the topic a context - QDoc can associate certain topics to other
pages such as associating obsolete functions when the documentation is
marked with \l{obsolete-command}{\\obsolete}.
\o Mark sections of the document with
\l{Markup Commands}{markup commands} - QDoc can create layouts and
format the documentation for the documentation.
\endlist
In Qt, the \l{QVector3D} class was documented with the following QDoc
comment:
\snippet examples/samples.qdocinc qvector3d-class
It has a constructor, \l{QVector3D::QVector3D()}, which was documented with
the following QDoc comment:
\snippet examples/samples.qdocinc qvector3d-function
The different comments may reside in different files and QDoc will collect
them depending on their topic and their context. The resulting documentation
from the snippets are generated into the \l{QVector3D} class documentation.
Note that if the documentation immediately precedes the function or class
in the source code, then it does not need to have a topic. QDoc will assume
that the documentation above the code is the documentation for that code.
An article is created using \l{page-command}{\\page} command. The first
argument is the HTML file that QDoc will create. The topic is supplemented
with context commands, the \l{title-command}{\\title} and
\l{nextpage-command}{\\nextpage} commands. There are several other
QDoc commands such as the \l{list-command}{\\list} command.
\snippet examples/samples.qdocinc sample-page
The section on \l{QDoc Topics}{topic commands} gives an overview on several
other topic types.
*/
/*!
\page qdoc-categories.html
\title Categories of Documentation
\previouspage Writing Documentation
\nextpage Configuration File Example
\brief Describes the different types such as How-To's, Tutorials, Overviews,
Examples, and Class Documentation.
There are several types of predefined documentation \e categories or
\e types:
\list
\o How-To's
\o Tutorial
\o Overview
\o Article
\o FAQ (Frequently Asked Questions)
\o C++ API Documentation
\o QML Component Documentation
\o Code Example
\endlist
QDoc has the ability to format a page depending on the type. Further,
stylesheets can provide additional control on the display of each category.
\section1 API Documentation
QDoc excels in the creation of API documentation given a set of source code
and documentation in QDoc comments. Specifically, QDoc is aware of Qt's
architecture and can validate the existence of Qt C++ class, function, or
property documentation. QDoc gives warnings and errors if it cannot
associate a documentation with a code entity or if a code entity does not
have documentation.
In general, every Qt code entity such as properties, classes, methods,
signals, and enumerations have a corresponding
\l{qdoc-topics}{topic command}. QDoc will associate the documentation to the
source using C++ naming rules.
QDoc will parse the header files (typically \c .h files) to build a tree of
the class structures. Then QDoc will parse the source files and
documentation files to attach documentation to the class structure.
Afterwards, QDoc will generate a page for the class.
\note QDoc uses the header files to inform itself about the class and will
not properly process QDoc comments in header files.
\keyword qml-documentation
\section2 Documenting QML Components
In the world of \l{Qt Quick}{QML}, there are additional entities we need to
document such as QML signals, attached properties, and QML methods.
Internally, they use Qt technologies, however, QML API documentation
requires different layout and naming conventions from the Qt C++ API
documentation.
A list of QML related QDoc commands:
\list
\o \l{qmlattachedproperty-command}{\\qmlattachedproperty}
\o \l{qmlattachedsignal-command}{\\qmlattachedsignal}
\o \l{qmlbasictype-command}{\\qmlbasictype}
\o \l{qmlclass-command}{\\qmlclass} - creates a QML component documentation
\o \l{qmlmethod-command}{\\qmlmethod}
\o \l{qmlproperty-command}{\\qmlproperty}
\o \l{qmlsignal-command}{\\qmlsignal}
\o \l{inherits-command}{\\inherits}
\o \l{qmlmodule-command}{\\qmlmodule}
\o \l{inqmlmodule-command}{\\inqmlmodule}
\endlist
\note Remember to enable QML parsing by including the \c{*.qml} filetype in
the \l{qdoc-input-output-dir}{fileextension} variable.
Essentially, to create an API documentation of a QML component, create
a QDoc comment with a \l{qmlclass-command}{\\qmlclass} command. Similar to
C++ API documentation, QML API are documented using their corresponding QDoc
commands.
\section3 QML Parser
You may either document a QML component rom a C++ class or from a QML file.
QDoc supports both types and can parse both C++ and QML files.
In a QML file, you may simply place the QDoc comment above the property,
signal, handler, or method. QDoc will collect the comments and form the API
documentation. Additionally, QDoc can detect
\l{qml-property-aliases}{property-aliases}, but the property type must be
manually declared using the \l{qmlproperty-command}{\\qmlproperty} command.
QML components in C++ classes have their documentation above their property
or method documentation. However, the QML commands must be used instead of
the C++ documentation topic commands. Instead of the \c {\\class}
command, use the \l{qmlclass-command}{\\qmlclass} command.
\section3 QML Modules
A component belongs to a component \e set or a \e module. The module
may include all the related components for a platform or contain a certain
version of \l{Qt Quick}. For example, the Qt Quick 2 \l{QML Elements} belong
to the QtQuick2 module while there is also a QtQuick1 module for the older
elements introduced in Qt 4.
Modules affect the way Qdoc link and relate the components. The
\l{qmlclass-command}{\\qmlclass} topic command must have an
\l{inqmlmodule-command}{\\inqmlmodule} context command to relate the
component to a module. Similarly, a \l{qmlmodule-command}{\\qmlmodule} topic
command must exist in a separate \c .qdoc file to create the overview page
for the module. The overview page will list the related components.
The links to the components, must therefore, also contain the module name.
For example, if a component called \c TabWidget is in the \c UIComponents
module, it must be linked as \c {UIComponents::TabWidget}.
The \l{componentset}{UIComponents} example demonstrates proper usage of
QDoc commands to document QML components and QML modules.
\section3 Read-only and Internal QML Properties
QDoc detects QML properties that are marked as \c readonly. Note that the
property must be initialized with a value.
\code
readonly property int sampleReadOnlyProperty: 0
\endcode
For example, the example \l{TabWidget} component has a fictitious read-only
property \c sampleReadOnlyProperty. Its declaration has the \c readonly
identifier and it has an initial value.
Properties and signals that are not meant for the public interface may
be marked with the \l{internal-command}{\\internal} command. QDoc will not
publish the documentation in the generated outputs.
\section1 Articles & Overviews
Articles and overviews are a style of writing best used for providing
summary detail on a topic or concept. It may introduce a technology or
discuss how a concept may be applied, but without discussing exact steps
in too much detail. However, this type of content could provide the entry
point for readers to find instructional and reference materials that do,
such as tutorials, examples and class documentation. An example of an
overview might be a product page, such as a top level discussion of
QtQuick, individual modules, design principles, or tools.
To signify that a document is an article, you append the article keyword
to the \\page command:
\snippet examples/samples.qdocinc sample-overview
The \l{writing-topic-commands}{writing topic commands} section has a listing
of the available \\page command arguments.
\section1 Tutorials, How-To's, FAQ's
Tutorials, How-To's, and FAQ's are all instructional material, in that they
instruct or prescribe to the reader. Tutorials are content designed to guide
the reader along a progressive learning path for a concept or technology.
How-To's and FAQ's (\e{Frequently Asked Questions}) provide guidance by
presenting material in the form of answers to commonly asked topics.
How-To's and FAQ's are designed for easy reference and are not necessarily
presented in a linear progression.
To create these types, mark the pages by providing a \c type argument to the
\l{page-command}{\\page} command. The \c type argument is the second
argument, with the file name being the first.
\snippet examples/samples.qdocinc sample-faq
The \l{writing-topic-commands}{writing topic commands} section has a listing
of the available \\page command arguments.
\section1 Code Examples
Examples are an effective way to demonstrate practical usage of a given
technology or concept. When it comes to middleware this is usually in the
form of an application using simple code and clear explanations of what the
code is doing. Any module, API, project, pattern etc. should have at least
one good example.
An example may have an accompanying tutorial. The tutorial instructs and
describes the code, while the code example is the code content that users
may study. Code examples may have accompanying text that are not in the
tutorial.
QDoc will create a page containing the example code with a description
using the \l{example-command}{\\example} command.
\snippet examples/samples.qdocinc sample-example
QDoc will use the directory specified in the input
\l{Input and Output Directories}{exampledirs} variable to find the Qt
Project (\c .pro) file to generate the example files. The generated HTML
will have the filename, \c {declarative-ui-components-tabwidget.html}. QDoc
will also list all of the example code. For reference, view QDoc's generated
page for the \l{UI Components: Tab Widget Example}{Tab Widget} example.
\note The example's project file must be the same as the
directory name.
*/
/*!
\example config
\title Configuration File Example
\previouspage Categories of Documentation
\brief configuration files for the QDoc Manual and QDoc Guide
The QDoc Manual uses these \c qdocconf files to generate the QDoc Guide and
the \l{Table of Contents}{QDoc Manual}.
\note The configuration files are similar to the Qt Reference Documentation
and the QDoc Manual do not use all of the variables. The variables are
included to demonstrate a full project scenario.
\section1 Macros and other Definitions
\list
\o \l{config/compat.qdocconf}
\o \l{config/macros.qdocconf}
\o \l{config/qt-cpp-ignore.qdocconf}
\o \l{config/qt-defines.qdocconf}
\endlist
QDoc allows macros to help with aliasing and for inputting special HTML
characters within the documentation. Macros are a form of workarounds if
QDoc is unable to resolve formatting issues such as when QDoc should
disregard QDoc comments in documentation paragraphs.
QDoc is also aware of the common C++ and Qt preprocessors and can decide
which documentation to generate according to the definitions in the
configuration files.
\section1 Project Information
\list
\o \l{config/qdoc-online.qdocconf}
\o \l{config/qdoc.qdocconf}
\o \l{config/qdoc-project.qdocconf}
\endlist
These configuration files dictate how QDoc will generate the project.
Depending which configuration file QDoc processes, the formatting and the
information about the project will be different. If QDoc processes
\c{qdoc-online.qdocconf}, QDoc will generate the HTML version of the manual
will have the style suitable for online viewing.
Additionally, the settings for creating the
\l{The Qt Help Framework}{Qt Help File} is in the configuration.
\note The project file uses variables used during Qt's
\l{Configuration Options for Qt}{configuration} step.
\section1 HTML Styles
\list
\o \l{config/qt-html-default-styles.qdocconf}
\o \l{config/qt-html-online-styles.qdocconf}
\o \l{config/qt-html-templates-online.qdocconf}
\o \l{config/qt-html-templates.qdocconf}
\endlist
These files indicate which styles QDoc should use for the HTML formats.
Typically, there are two templates, one for online viewing and one for
offline. Qt Creator is able to fit more content in a page with the offline
template. The templates store HTML information as strings and QDoc will copy
the template to each HTML page.
\section1 Project File
\list
\o \l{config/config.pro}
\endlist
Every example page (such as this one) needs a Qt project file. QDoc will
use the project file to determine which files are part of the example. QDoc
will then create a page listing all the files that are part of the example.
\note the directory name of the example and the name of the project file
must match. The example directory is found using the
\l{qdoc-input-output-dir}{exampledirs} variable.
*/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,114 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
editdistance.cpp
*/
#include "editdistance.h"
QT_BEGIN_NAMESPACE
int editDistance( const QString& s, const QString& t )
{
#define D( i, j ) d[(i) * n + (j)]
int i;
int j;
int m = s.length() + 1;
int n = t.length() + 1;
int *d = new int[m * n];
int result;
for ( i = 0; i < m; i++ )
D( i, 0 ) = i;
for ( j = 0; j < n; j++ )
D( 0, j ) = j;
for ( i = 1; i < m; i++ ) {
for ( j = 1; j < n; j++ ) {
if ( s[i - 1] == t[j - 1] ) {
D( i, j ) = D( i - 1, j - 1 );
} else {
int x = D( i - 1, j );
int y = D( i - 1, j - 1 );
int z = D( i, j - 1 );
D( i, j ) = 1 + qMin( qMin(x, y), z );
}
}
}
result = D( m - 1, n - 1 );
delete[] d;
return result;
#undef D
}
QString nearestName( const QString& actual, const QSet<QString>& candidates )
{
if (actual.isEmpty())
return "";
int deltaBest = 10000;
int numBest = 0;
QString best;
QSet<QString>::ConstIterator c = candidates.begin();
while ( c != candidates.end() ) {
if ( (*c)[0] == actual[0] ) {
int delta = editDistance( actual, *c );
if ( delta < deltaBest ) {
deltaBest = delta;
numBest = 1;
best = *c;
} else if ( delta == deltaBest ) {
numBest++;
}
}
++c;
}
if ( numBest == 1 && deltaBest <= 2 &&
actual.length() + best.length() >= 5 ) {
return best;
} else {
return "";
}
}
QT_END_NAMESPACE

View File

@ -0,0 +1,59 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
editdistance.h
*/
#ifndef EDITDISTANCE_H
#define EDITDISTANCE_H
#include <QSet>
#include <QString>
QT_BEGIN_NAMESPACE
int editDistance( const QString& s, const QString& t );
QString nearestName( const QString& actual, const QSet<QString>& candidates );
QT_END_NAMESPACE
#endif

1495
src/tools/qdoc/generator.cpp Normal file

File diff suppressed because it is too large Load Diff

221
src/tools/qdoc/generator.h Normal file
View File

@ -0,0 +1,221 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
generator.h
*/
#ifndef GENERATOR_H
#define GENERATOR_H
#include <qlist.h>
#include <qmap.h>
#include <qregexp.h>
#include <qstring.h>
#include <qstringlist.h>
#include "node.h"
#include "text.h"
QT_BEGIN_NAMESPACE
typedef QMap<QString, const Node*> NodeMap;
typedef QMultiMap<QString, Node*> NodeMultiMap;
typedef QMap<QString, NodeMultiMap> NewSinceMaps;
typedef QMap<Node*, NodeMultiMap> ParentMaps;
typedef QMap<QString, NodeMap> NewClassMaps;
class ClassNode;
class Config;
class CodeMarker;
class FakeNode;
class FunctionNode;
class InnerNode;
class Location;
class NamespaceNode;
class Node;
class Tree;
class Generator
{
public:
Generator();
virtual ~Generator();
virtual void initializeGenerator(const Config &config);
virtual void terminateGenerator();
virtual QString format() = 0;
virtual bool canHandleFormat(const QString &format) { return format == this->format(); }
virtual void generateTree(const Tree *tree) = 0;
static void initialize(const Config& config);
static void terminate();
static Generator *generatorForFormat(const QString& format);
static const QString& outputDir() { return outDir_; }
static const QString& baseDir() { return baseDir_; }
protected:
virtual void startText(const Node *relative, CodeMarker *marker);
virtual void endText(const Node *relative, CodeMarker *marker);
virtual int generateAtom(const Atom *atom,
const Node *relative,
CodeMarker *marker);
virtual void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker);
virtual void generateFakeNode(const FakeNode *fake, CodeMarker *marker);
virtual bool generateText(const Text& text,
const Node *relative,
CodeMarker *marker);
virtual bool generateQmlText(const Text& text,
const Node *relative,
CodeMarker *marker,
const QString& qmlName);
virtual void generateQmlInherits(const QmlClassNode* qcn, CodeMarker* marker);
virtual void generateBody(const Node *node, CodeMarker *marker);
virtual void generateAlsoList(const Node *node, CodeMarker *marker);
virtual void generateMaintainerList(const InnerNode* node, CodeMarker* marker);
virtual void generateInherits(const ClassNode *classe,
CodeMarker *marker);
virtual void generateInheritedBy(const ClassNode *classe,
CodeMarker *marker);
void generateThreadSafeness(const Node *node, CodeMarker *marker);
void generateSince(const Node *node, CodeMarker *marker);
void generateStatus(const Node *node, CodeMarker *marker);
const Atom* generateAtomList(const Atom *atom,
const Node *relative,
CodeMarker *marker,
bool generate,
int& numGeneratedAtoms);
void generateFileList(const FakeNode* fake,
CodeMarker* marker,
Node::SubType subtype,
const QString& tag);
void generateExampleFiles(const FakeNode *fake, CodeMarker *marker);
virtual int skipAtoms(const Atom *atom, Atom::Type type) const;
virtual QString fullName(const Node *node,
const Node *relative,
CodeMarker *marker) const;
virtual QString outFileName() { return QString(); }
QString indent(int level, const QString& markedCode);
QString plainCode(const QString& markedCode);
virtual QString typeString(const Node *node);
virtual QString imageFileName(const Node *relative, const QString& fileBase);
void setImageFileExtensions(const QStringList& extensions);
void unknownAtom(const Atom *atom);
QMap<QString, QString> &formattingLeftMap();
QMap<QString, QString> &formattingRightMap();
QMap<QString, QStringList> editionModuleMap;
QMap<QString, QStringList> editionGroupMap;
static QString trimmedTrailing(const QString &string);
static bool matchAhead(const Atom *atom, Atom::Type expectedAtomType);
static void supplementAlsoList(const Node *node, QList<Text> &alsoList);
static QString outputPrefix(const QString &nodeType);
QString getMetadataElement(const InnerNode* inner, const QString& t);
QStringList getMetadataElements(const InnerNode* inner, const QString& t);
void findAllSince(const InnerNode *node);
private:
void generateReimplementedFrom(const FunctionNode *func,
CodeMarker *marker);
void appendFullName(Text& text,
const Node *apparentNode,
const Node *relative,
CodeMarker *marker,
const Node *actualNode = 0);
void appendFullName(Text& text,
const Node *apparentNode,
const QString& fullName,
const Node *actualNode);
void appendFullNames(Text& text,
const NodeList& nodes,
const Node* relative,
CodeMarker* marker);
void appendSortedNames(Text& text,
const ClassNode *classe,
const QList<RelatedClass> &classes,
CodeMarker *marker);
protected:
void appendSortedQmlNames(Text& text,
const Node* base,
const NodeList& subs,
CodeMarker *marker);
static QString sinceTitles[];
NewSinceMaps newSinceMaps;
NewClassMaps newClassMaps;
NewClassMaps newQmlClassMaps;
private:
QString amp;
QString lt;
QString gt;
QString quot;
QRegExp tag;
static QList<Generator *> generators;
static QMap<QString, QMap<QString, QString> > fmtLeftMaps;
static QMap<QString, QMap<QString, QString> > fmtRightMaps;
static QMap<QString, QStringList> imgFileExts;
static QSet<QString> outputFormats;
static QStringList imageFiles;
static QStringList imageDirs;
static QStringList exampleDirs;
static QStringList exampleImgExts;
static QStringList scriptFiles;
static QStringList scriptDirs;
static QStringList styleFiles;
static QStringList styleDirs;
static QString outDir_;
static QString baseDir_;
static QString project;
static QHash<QString, QString> outputPrefixes;
};
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,772 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QHash>
#include <QMap>
#include "atom.h"
#include "helpprojectwriter.h"
#include "htmlgenerator.h"
#include "config.h"
#include "node.h"
#include "tree.h"
#include <qdebug.h>
QT_BEGIN_NAMESPACE
HelpProjectWriter::HelpProjectWriter(const Config &config, const QString &defaultFileName)
{
// The output directory should already have been checked by the calling
// generator.
outputDir = config.getOutputDir();
QStringList names = config.getStringList(CONFIG_QHP + Config::dot + "projects");
foreach (const QString &projectName, names) {
HelpProject project;
project.name = projectName;
QString prefix = CONFIG_QHP + Config::dot + projectName + Config::dot;
project.helpNamespace = config.getString(prefix + "namespace");
project.virtualFolder = config.getString(prefix + "virtualFolder");
project.fileName = config.getString(prefix + "file");
if (project.fileName.isEmpty())
project.fileName = defaultFileName;
project.extraFiles = config.getStringSet(prefix + "extraFiles");
project.indexTitle = config.getString(prefix + "indexTitle");
project.indexRoot = config.getString(prefix + "indexRoot");
project.filterAttributes = config.getStringList(prefix + "filterAttributes").toSet();
QSet<QString> customFilterNames = config.subVars(prefix + "customFilters");
foreach (const QString &filterName, customFilterNames) {
QString name = config.getString(prefix + "customFilters" + Config::dot + filterName + Config::dot + "name");
QSet<QString> filters = config.getStringList(prefix + "customFilters" + Config::dot + filterName + Config::dot + "filterAttributes").toSet();
project.customFilters[name] = filters;
}
//customFilters = config.defs.
foreach (QString name, config.getStringSet(prefix + "excluded"))
project.excluded.insert(name.replace("\\", "/"));
foreach (const QString &name, config.getStringList(prefix + "subprojects")) {
SubProject subproject;
QString subprefix = prefix + "subprojects" + Config::dot + name + Config::dot;
subproject.title = config.getString(subprefix + "title");
subproject.indexTitle = config.getString(subprefix + "indexTitle");
subproject.sortPages = config.getBool(subprefix + "sortPages");
subproject.type = config.getString(subprefix + "type");
readSelectors(subproject, config.getStringList(subprefix + "selectors"));
project.subprojects[name] = subproject;
}
if (project.subprojects.isEmpty()) {
SubProject subproject;
readSelectors(subproject, config.getStringList(prefix + "selectors"));
project.subprojects[""] = subproject;
}
projects.append(project);
}
}
void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList &selectors)
{
QHash<QString, Node::Type> typeHash;
typeHash["namespace"] = Node::Namespace;
typeHash["class"] = Node::Class;
typeHash["fake"] = Node::Fake;
typeHash["enum"] = Node::Enum;
typeHash["typedef"] = Node::Typedef;
typeHash["function"] = Node::Function;
typeHash["property"] = Node::Property;
typeHash["variable"] = Node::Variable;
typeHash["target"] = Node::Target;
#ifdef QDOC_QML
typeHash["qmlproperty"] = Node::QmlProperty;
typeHash["qmlsignal"] = Node::QmlSignal;
typeHash["qmlsignalhandler"] = Node::QmlSignalHandler;
typeHash["qmlmethod"] = Node::QmlMethod;
#endif
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;
subTypeHash["qmlpropertygroup"] = Node::QmlPropertyGroup;
subTypeHash["qmlbasictype"] = Node::QmlBasicType;
#endif
QSet<Node::SubType> allSubTypes = QSet<Node::SubType>::fromList(subTypeHash.values());
foreach (const QString &selector, selectors) {
QStringList pieces = selector.split(QLatin1Char(':'));
if (pieces.size() == 1) {
QString lower = selector.toLower();
if (typeHash.contains(lower))
subproject.selectors[typeHash[lower]] = allSubTypes;
} else if (pieces.size() >= 2) {
QString lower = pieces[0].toLower();
pieces = pieces[1].split(QLatin1Char(','));
if (typeHash.contains(lower)) {
QSet<Node::SubType> subTypes;
for (int i = 0; i < pieces.size(); ++i) {
QString lower = pieces[i].toLower();
if (subTypeHash.contains(lower))
subTypes.insert(subTypeHash[lower]);
}
subproject.selectors[typeHash[lower]] = subTypes;
}
}
}
}
void HelpProjectWriter::addExtraFile(const QString &file)
{
for (int i = 0; i < projects.size(); ++i)
projects[i].extraFiles.insert(file);
}
void HelpProjectWriter::addExtraFiles(const QSet<QString> &files)
{
for (int i = 0; i < projects.size(); ++i)
projects[i].extraFiles.unite(files);
}
/*
Returns a list of strings describing the keyword details for a given node.
The first string is the human-readable name to be shown in Assistant.
The second string is a unique identifier.
The third string is the location of the documentation for the keyword.
*/
QStringList HelpProjectWriter::keywordDetails(const Node *node) const
{
QStringList details;
if (node->type() == Node::QmlProperty) {
// "name"
details << node->name();
// "id"
details << node->parent()->parent()->name()+"::"+node->name();
}
else if (node->parent() && !node->parent()->name().isEmpty()) {
// "name"
if (node->type() == Node::Enum || node->type() == Node::Typedef)
details << node->parent()->name()+"::"+node->name();
else
details << node->name();
// "id"
details << node->parent()->name()+"::"+node->name();
}
else if (node->type() == Node::Fake) {
const FakeNode *fake = static_cast<const FakeNode *>(node);
if (fake->subType() == Node::QmlClass) {
details << (QmlClassNode::qmlOnly ? fake->name() : fake->fullTitle());
details << "QML." + fake->name();
}
else {
details << fake->fullTitle();
details << fake->fullTitle();
}
}
else {
details << node->name();
details << node->name();
}
details << HtmlGenerator::fullDocumentLocation(node,true);
return details;
}
bool HelpProjectWriter::generateSection(HelpProject &project,
QXmlStreamWriter & /* writer */,
const Node *node)
{
if (!node->url().isEmpty())
return false;
if (node->access() == Node::Private || node->status() == Node::Internal)
return false;
if (node->name().isEmpty())
return true;
QString docPath = node->doc().location().filePath();
if (!docPath.isEmpty() && project.excluded.contains(docPath))
return false;
QString objName;
if (node->type() == Node::Fake) {
const FakeNode *fake = static_cast<const FakeNode *>(node);
objName = fake->fullTitle();
}
else
objName = node->fullDocumentName();
// Only add nodes to the set for each subproject if they match a selector.
// Those that match will be listed in the table of contents.
foreach (const QString &name, project.subprojects.keys()) {
SubProject subproject = project.subprojects[name];
// No selectors: accept all nodes.
if (subproject.selectors.isEmpty()) {
project.subprojects[name].nodes[objName] = node;
}
else if (subproject.selectors.contains(node->type())) {
// Accept only the node types in the selectors hash.
if (node->type() != Node::Fake)
project.subprojects[name].nodes[objName] = node;
else {
// Accept only fake nodes with subtypes contained in the selector's
// mask.
const FakeNode *fakeNode = static_cast<const FakeNode *>(node);
if (subproject.selectors[node->type()].contains(fakeNode->subType()) &&
fakeNode->subType() != Node::ExternalPage &&
!fakeNode->fullTitle().isEmpty()) {
project.subprojects[name].nodes[objName] = node;
}
}
}
}
switch (node->type()) {
case Node::Class:
project.keywords.append(keywordDetails(node));
project.files.insert(HtmlGenerator::fullDocumentLocation(node,true));
break;
case Node::Namespace:
project.keywords.append(keywordDetails(node));
project.files.insert(HtmlGenerator::fullDocumentLocation(node,true));
break;
case Node::Enum:
project.keywords.append(keywordDetails(node));
{
const EnumNode *enumNode = static_cast<const EnumNode*>(node);
foreach (const EnumItem &item, enumNode->items()) {
QStringList details;
if (enumNode->itemAccess(item.name()) == Node::Private)
continue;
if (!node->parent()->name().isEmpty()) {
details << node->parent()->name()+"::"+item.name(); // "name"
details << node->parent()->name()+"::"+item.name(); // "id"
} else {
details << item.name(); // "name"
details << item.name(); // "id"
}
details << HtmlGenerator::fullDocumentLocation(node,true);
project.keywords.append(details);
}
}
break;
case Node::Property:
case Node::QmlProperty:
case Node::QmlSignal:
case Node::QmlSignalHandler:
case Node::QmlMethod:
project.keywords.append(keywordDetails(node));
break;
case Node::Function:
{
const FunctionNode *funcNode = static_cast<const FunctionNode *>(node);
// Only insert keywords for non-constructors. Constructors are covered
// by the classes themselves.
if (funcNode->metaness() != FunctionNode::Ctor)
project.keywords.append(keywordDetails(node));
// Insert member status flags into the entries for the parent
// node of the function, or the node it is related to.
// Since parent nodes should have already been inserted into
// the set of files, we only need to ensure that related nodes
// are inserted.
if (node->relates()) {
project.memberStatus[node->relates()].insert(node->status());
project.files.insert(HtmlGenerator::fullDocumentLocation(node->relates(),true));
} else if (node->parent())
project.memberStatus[node->parent()].insert(node->status());
}
break;
case Node::Typedef:
{
const TypedefNode *typedefNode = static_cast<const TypedefNode *>(node);
QStringList typedefDetails = keywordDetails(node);
const EnumNode *enumNode = typedefNode->associatedEnum();
// Use the location of any associated enum node in preference
// to that of the typedef.
if (enumNode)
typedefDetails[2] = HtmlGenerator::fullDocumentLocation(enumNode,true);
project.keywords.append(typedefDetails);
}
break;
case Node::Variable:
{
QString location = HtmlGenerator::fullDocumentLocation(node,true);
project.files.insert(location.left(location.lastIndexOf(QLatin1Char('#'))));
project.keywords.append(keywordDetails(node));
}
break;
// Fake nodes (such as manual pages) contain subtypes, titles and other
// attributes.
case Node::Fake: {
const FakeNode *fakeNode = static_cast<const FakeNode*>(node);
if (fakeNode->subType() != Node::ExternalPage &&
!fakeNode->fullTitle().isEmpty()) {
if (fakeNode->subType() != Node::File) {
if (fakeNode->doc().hasKeywords()) {
foreach (const Atom *keyword, fakeNode->doc().keywords()) {
if (!keyword->string().isEmpty()) {
QStringList details;
details << keyword->string()
<< keyword->string()
<< HtmlGenerator::fullDocumentLocation(node,true) +
QLatin1Char('#') + Doc::canonicalTitle(keyword->string());
project.keywords.append(details);
} else
fakeNode->doc().location().warning(
tr("Bad keyword in %1").arg(HtmlGenerator::fullDocumentLocation(node,true))
);
}
}
project.keywords.append(keywordDetails(node));
}
/*
if (fakeNode->doc().hasTableOfContents()) {
foreach (const Atom *item, fakeNode->doc().tableOfContents()) {
QString title = Text::sectionHeading(item).toString();
if (!title.isEmpty()) {
QStringList details;
details << title
<< title
<< HtmlGenerator::fullDocumentLocation(node,true) +
QLatin1Char('#') + Doc::canonicalTitle(title);
project.keywords.append(details);
} else
fakeNode->doc().location().warning(
tr("Bad contents item in %1").arg(HtmlGenerator::fullDocumentLocation(node,true)));
}
}
*/
project.files.insert(HtmlGenerator::fullDocumentLocation(node,true));
}
break;
}
default:
;
}
// Add all images referenced in the page to the set of files to include.
const Atom *atom = node->doc().body().firstAtom();
while (atom) {
if (atom->type() == Atom::Image || atom->type() == Atom::InlineImage) {
// Images are all placed within a single directory regardless of
// whether the source images are in a nested directory structure.
QStringList pieces = atom->string().split(QLatin1Char('/'));
project.files.insert("images/" + pieces.last());
}
atom = atom->next();
}
return true;
}
void HelpProjectWriter::generateSections(HelpProject &project,
QXmlStreamWriter &writer, const Node *node)
{
if (!generateSection(project, writer, node))
return;
if (node->isInnerNode()) {
const InnerNode *inner = static_cast<const InnerNode *>(node);
// Ensure that we don't visit nodes more than once.
QMap<QString, const Node*> childMap;
foreach (const Node *node, inner->childNodes()) {
if (node->access() == Node::Private)
continue;
if (node->type() == Node::Fake) {
/*
Don't visit QML property group nodes,
but visit their children, which are all
QML property nodes.
*/
if (node->subType() == Node::QmlPropertyGroup) {
const InnerNode* inner = static_cast<const InnerNode*>(node);
foreach (const Node* n, inner->childNodes()) {
if (n->access() == Node::Private)
continue;
childMap[n->fullDocumentName()] = n;
}
}
else
childMap[static_cast<const FakeNode *>(node)->fullTitle()] = node;
}
else {
if (node->type() == Node::Function) {
const FunctionNode *funcNode = static_cast<const FunctionNode *>(node);
if (funcNode->isOverload())
continue;
}
childMap[node->fullDocumentName()] = node;
}
}
foreach (const Node *child, childMap)
generateSections(project, writer, child);
}
}
void HelpProjectWriter::generate(const Tree *tre)
{
this->tree = tre;
for (int i = 0; i < projects.size(); ++i)
generateProject(projects[i]);
}
void HelpProjectWriter::writeNode(HelpProject &project, QXmlStreamWriter &writer,
const Node *node)
{
QString href = HtmlGenerator::fullDocumentLocation(node,true);
QString objName = node->name();
switch (node->type()) {
case Node::Class:
writer.writeStartElement("section");
writer.writeAttribute("ref", href);
if (node->parent() && !node->parent()->name().isEmpty())
writer.writeAttribute("title", tr("%1::%2 Class Reference").arg(node->parent()->name()).arg(objName));
else
writer.writeAttribute("title", tr("%1 Class Reference").arg(objName));
// Write subsections for all members, obsolete members and Qt 3
// members.
if (!project.memberStatus[node].isEmpty()) {
QString membersPath = href.left(href.size()-5) + "-members.html";
writer.writeStartElement("section");
writer.writeAttribute("ref", membersPath);
writer.writeAttribute("title", tr("List of all members"));
writer.writeEndElement(); // section
project.files.insert(membersPath);
}
if (project.memberStatus[node].contains(Node::Compat)) {
QString compatPath = href.left(href.size()-5) + "-qt3.html";
writer.writeStartElement("section");
writer.writeAttribute("ref", compatPath);
writer.writeAttribute("title", tr("Qt 3 support members"));
writer.writeEndElement(); // section
project.files.insert(compatPath);
}
if (project.memberStatus[node].contains(Node::Obsolete)) {
QString obsoletePath = href.left(href.size()-5) + "-obsolete.html";
writer.writeStartElement("section");
writer.writeAttribute("ref", obsoletePath);
writer.writeAttribute("title", tr("Obsolete members"));
writer.writeEndElement(); // section
project.files.insert(obsoletePath);
}
writer.writeEndElement(); // section
break;
case Node::Namespace:
writer.writeStartElement("section");
writer.writeAttribute("ref", href);
writer.writeAttribute("title", objName);
writer.writeEndElement(); // section
break;
case Node::Fake: {
// Fake nodes (such as manual pages) contain subtypes, titles and other
// attributes.
const FakeNode *fakeNode = static_cast<const FakeNode*>(node);
writer.writeStartElement("section");
writer.writeAttribute("ref", href);
writer.writeAttribute("title", fakeNode->fullTitle());
if ((fakeNode->subType() == Node::HeaderFile) || (fakeNode->subType() == Node::QmlClass)) {
// Write subsections for all members, obsolete members and Qt 3
// members.
if (!project.memberStatus[node].isEmpty() || (fakeNode->subType() == Node::QmlClass)) {
QString membersPath = href.left(href.size()-5) + "-members.html";
writer.writeStartElement("section");
writer.writeAttribute("ref", membersPath);
writer.writeAttribute("title", tr("List of all members"));
writer.writeEndElement(); // section
project.files.insert(membersPath);
}
if (project.memberStatus[node].contains(Node::Compat)) {
QString compatPath = href.left(href.size()-5) + "-qt3.html";
writer.writeStartElement("section");
writer.writeAttribute("ref", compatPath);
writer.writeAttribute("title", tr("Qt 3 support members"));
writer.writeEndElement(); // section
project.files.insert(compatPath);
}
if (project.memberStatus[node].contains(Node::Obsolete)) {
QString obsoletePath = href.left(href.size()-5) + "-obsolete.html";
writer.writeStartElement("section");
writer.writeAttribute("ref", obsoletePath);
writer.writeAttribute("title", tr("Obsolete members"));
writer.writeEndElement(); // section
project.files.insert(obsoletePath);
}
}
writer.writeEndElement(); // section
}
break;
default:
;
}
}
void HelpProjectWriter::generateProject(HelpProject &project)
{
const Node *rootNode;
if (!project.indexRoot.isEmpty())
rootNode = tree->findFakeNodeByTitle(project.indexRoot);
else
rootNode = tree->root();
if (!rootNode)
return;
project.files.clear();
project.keywords.clear();
QFile file(outputDir + QDir::separator() + project.fileName);
if (!file.open(QFile::WriteOnly | QFile::Text))
return;
QXmlStreamWriter writer(&file);
writer.setAutoFormatting(true);
writer.writeStartDocument();
writer.writeStartElement("QtHelpProject");
writer.writeAttribute("version", "1.0");
// Write metaData, virtualFolder and namespace elements.
writer.writeTextElement("namespace", project.helpNamespace);
writer.writeTextElement("virtualFolder", project.virtualFolder);
// Write customFilter elements.
QHash<QString, QSet<QString> >::ConstIterator it;
for (it = project.customFilters.begin(); it != project.customFilters.end(); ++it) {
writer.writeStartElement("customFilter");
writer.writeAttribute("name", it.key());
foreach (const QString &filter, it.value())
writer.writeTextElement("filterAttribute", filter);
writer.writeEndElement(); // customFilter
}
// Start the filterSection.
writer.writeStartElement("filterSection");
// Write filterAttribute elements.
foreach (const QString &filterName, project.filterAttributes)
writer.writeTextElement("filterAttribute", filterName);
writer.writeStartElement("toc");
writer.writeStartElement("section");
const Node* node = tree->findFakeNodeByTitle(project.indexTitle);
if (node == 0)
node = tree->findNode(QStringList("index.html"));
QString indexPath;
if (node)
indexPath = HtmlGenerator::fullDocumentLocation(node,true);
else
indexPath = "index.html";
writer.writeAttribute("ref", indexPath);
writer.writeAttribute("title", project.indexTitle);
project.files.insert(HtmlGenerator::fullDocumentLocation(rootNode));
generateSections(project, writer, rootNode);
foreach (const QString &name, project.subprojects.keys()) {
SubProject subproject = project.subprojects[name];
if (subproject.type == QLatin1String("manual")) {
const FakeNode *indexPage = tree->findFakeNodeByTitle(subproject.indexTitle);
if (indexPage) {
Text indexBody = indexPage->doc().body();
const Atom *atom = indexBody.firstAtom();
QStack<int> sectionStack;
bool inItem = false;
while (atom) {
switch (atom->type()) {
case Atom::ListLeft:
sectionStack.push(0);
break;
case Atom::ListRight:
if (sectionStack.pop() > 0)
writer.writeEndElement(); // section
break;
case Atom::ListItemLeft:
inItem = true;
break;
case Atom::ListItemRight:
inItem = false;
break;
case Atom::Link:
if (inItem) {
if (sectionStack.top() > 0)
writer.writeEndElement(); // section
const FakeNode *page = tree->findFakeNodeByTitle(atom->string());
writer.writeStartElement("section");
QString indexPath = HtmlGenerator::fullDocumentLocation(page,true);
writer.writeAttribute("ref", indexPath);
writer.writeAttribute("title", atom->string());
project.files.insert(indexPath);
sectionStack.top() += 1;
}
break;
default:
;
}
if (atom == indexBody.lastAtom())
break;
atom = atom->next();
}
} else
rootNode->doc().location().warning(
tr("Failed to find index: %1").arg(subproject.indexTitle)
);
} else {
if (!name.isEmpty()) {
writer.writeStartElement("section");
QString indexPath = HtmlGenerator::fullDocumentLocation(tree->findFakeNodeByTitle(subproject.indexTitle),true);
writer.writeAttribute("ref", indexPath);
writer.writeAttribute("title", subproject.title);
project.files.insert(indexPath);
}
if (subproject.sortPages) {
QStringList titles = subproject.nodes.keys();
titles.sort();
foreach (const QString &title, titles) {
writeNode(project, writer, subproject.nodes[title]);
}
} else {
// Find a contents node and navigate from there, using the NextLink values.
QSet<QString> visited;
foreach (const Node *node, subproject.nodes) {
QString nextTitle = node->links().value(Node::NextLink).first;
if (!nextTitle.isEmpty() &&
node->links().value(Node::ContentsLink).first.isEmpty()) {
FakeNode *nextPage = const_cast<FakeNode *>(tree->findFakeNodeByTitle(nextTitle));
// Write the contents node.
writeNode(project, writer, node);
while (nextPage) {
writeNode(project, writer, nextPage);
nextTitle = nextPage->links().value(Node::NextLink).first;
if (nextTitle.isEmpty() || visited.contains(nextTitle))
break;
nextPage = const_cast<FakeNode *>(tree->findFakeNodeByTitle(nextTitle));
visited.insert(nextTitle);
}
break;
}
}
}
if (!name.isEmpty())
writer.writeEndElement(); // section
}
}
writer.writeEndElement(); // section
writer.writeEndElement(); // toc
writer.writeStartElement("keywords");
foreach (const QStringList &details, project.keywords) {
writer.writeStartElement("keyword");
writer.writeAttribute("name", details[0]);
writer.writeAttribute("id", details[1]);
writer.writeAttribute("ref", details[2]);
writer.writeEndElement(); //keyword
}
writer.writeEndElement(); // keywords
writer.writeStartElement("files");
foreach (const QString &usedFile, project.files) {
if (!usedFile.isEmpty())
writer.writeTextElement("file", usedFile);
}
foreach (const QString &usedFile, project.extraFiles)
writer.writeTextElement("file", usedFile);
writer.writeEndElement(); // files
writer.writeEndElement(); // filterSection
writer.writeEndElement(); // QtHelpProject
writer.writeEndDocument();
file.close();
}
QT_END_NAMESPACE

View File

@ -0,0 +1,111 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef HELPPROJECTWRITER_H
#define HELPPROJECTWRITER_H
#include <QString>
#include <QXmlStreamReader>
#include <QXmlStreamWriter>
#include "config.h"
#include "node.h"
QT_BEGIN_NAMESPACE
class Tree;
typedef QPair<QString, const Node*> QStringNodePair;
struct SubProject
{
QString title;
QString indexTitle;
QHash<Node::Type, QSet<FakeNode::SubType> > selectors;
bool sortPages;
QString type;
QHash<QString, const Node *> nodes;
};
struct HelpProject
{
QString name;
QString helpNamespace;
QString virtualFolder;
QString fileName;
QString indexRoot;
QString indexTitle;
QList<QStringList> keywords;
QSet<QString> files;
QSet<QString> extraFiles;
QSet<QString> filterAttributes;
QHash<QString, QSet<QString> > customFilters;
QSet<QString> excluded;
QMap<QString, SubProject> subprojects;
QHash<const Node *, QSet<Node::Status> > memberStatus;
};
class HelpProjectWriter
{
public:
HelpProjectWriter(const Config &config, const QString &defaultFileName);
void addExtraFile(const QString &file);
void addExtraFiles(const QSet<QString> &files);
void generate(const Tree *tre);
private:
void generateProject(HelpProject &project);
void generateSections(HelpProject &project, QXmlStreamWriter &writer,
const Node *node);
bool generateSection(HelpProject &project, QXmlStreamWriter &writer,
const Node *node);
QStringList keywordDetails(const Node *node) const;
void writeNode(HelpProject &project, QXmlStreamWriter &writer, const Node *node);
void readSelectors(SubProject &subproject, const QStringList &selectors);
const Tree *tree;
QString outputDir;
QList<HelpProject> projects;
};
QT_END_NAMESPACE
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,319 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
htmlgenerator.h
*/
#ifndef HTMLGENERATOR_H
#define HTMLGENERATOR_H
#include <qmap.h>
#include <qregexp.h>
#include <QXmlStreamWriter>
#include "codemarker.h"
#include "config.h"
#include "pagegenerator.h"
QT_BEGIN_NAMESPACE
class HelpProjectWriter;
class HtmlGenerator : public PageGenerator
{
public:
enum SinceType {
Namespace,
Class,
MemberFunction,
NamespaceFunction,
GlobalFunction,
Macro,
Enum,
Typedef,
Property,
Variable,
QmlClass,
QmlProperty,
QmlSignal,
QmlSignalHandler,
QmlMethod,
LastSinceType
};
public:
HtmlGenerator();
~HtmlGenerator();
virtual void initializeGenerator(const Config& config);
virtual void terminateGenerator();
virtual QString format();
virtual void generateTree(const Tree *tree);
virtual void generateDisambiguationPages();
void generateManifestFiles();
QString protectEnc(const QString &string);
static QString protect(const QString &string, const QString &encoding = "ISO-8859-1");
static QString cleanRef(const QString& ref);
static QString sinceTitle(int i) { return sinceTitles[i]; }
static QString fullDocumentLocation(const Node *node, bool subdir = false);
protected:
virtual void startText(const Node *relative, CodeMarker *marker);
virtual int generateAtom(const Atom *atom,
const Node *relative,
CodeMarker *marker);
virtual void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker);
virtual void generateFakeNode(const FakeNode *fake, CodeMarker *marker);
virtual QString fileExtension(const Node *node) const;
virtual QString refForNode(const Node *node);
virtual QString linkForNode(const Node *node, const Node *relative);
virtual QString refForAtom(Atom *atom, const Node *node);
void generateManifestFile(QString manifest, QString element);
private:
enum SubTitleSize { SmallSubTitle, LargeSubTitle };
enum ExtractionMarkType {
BriefMark,
DetailedDescriptionMark,
MemberMark,
EndMark
};
const QPair<QString,QString> anchorForNode(const Node *node);
const Node *findNodeForTarget(const QString &target,
const Node *relative,
CodeMarker *marker,
const Atom *atom = 0);
void generateBreadCrumbs(const QString& title,
const Node *node,
CodeMarker *marker);
void generateHeader(const QString& title,
const Node *node = 0,
CodeMarker *marker = 0);
void generateTitle(const QString& title,
const Text &subTitle,
SubTitleSize subTitleSize,
const Node *relative,
CodeMarker *marker);
void generateFooter(const Node *node = 0);
void generateBrief(const Node *node,
CodeMarker *marker,
const Node *relative = 0);
void generateIncludes(const InnerNode *inner, CodeMarker *marker);
void generateTableOfContents(const Node *node,
CodeMarker *marker,
QList<Section>* sections = 0);
QString generateListOfAllMemberFile(const InnerNode *inner,
CodeMarker *marker);
QString generateAllQmlMembersFile(const QmlClassNode* qml_cn,
CodeMarker* marker);
QString generateLowStatusMemberFile(const InnerNode *inner,
CodeMarker *marker,
CodeMarker::Status status);
void generateClassHierarchy(const Node *relative,
CodeMarker *marker,
const NodeMap &classMap);
void generateAnnotatedList(const Node *relative,
CodeMarker *marker,
const NodeMap &nodeMap,
bool allOdd = false);
void generateCompactList(const Node *relative,
CodeMarker *marker,
const NodeMap &classMap,
bool includeAlphabet,
QString commonPrefix = QString());
void generateFunctionIndex(const Node *relative, CodeMarker *marker);
void generateLegaleseList(const Node *relative, CodeMarker *marker);
void generateOverviewList(const Node *relative, CodeMarker *marker);
void generateSectionList(const Section& section,
const Node *relative,
CodeMarker *marker,
CodeMarker::SynopsisStyle style);
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* qcn, CodeMarker* marker);
void generateQmlInheritedBy(const QmlClassNode* qcn, CodeMarker* marker);
void generateQmlInstantiates(const QmlClassNode* qcn, CodeMarker* marker);
void generateInstantiatedBy(const ClassNode* cn, CodeMarker* marker);
void generateSection(const NodeList& nl,
const Node *relative,
CodeMarker *marker,
CodeMarker::SynopsisStyle style);
void generateSynopsis(const Node *node,
const Node *relative,
CodeMarker *marker,
CodeMarker::SynopsisStyle style,
bool alignNames = false,
const QString* prefix = 0);
void generateSectionInheritedList(const Section& section,
const Node *relative,
CodeMarker *marker);
QString highlightedCode(const QString& markedCode,
CodeMarker* marker,
const Node* relative,
bool alignNames = false,
const Node* self = 0);
void generateFullName(const Node *apparentNode,
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 generateStatus(const Node *node, CodeMarker *marker);
QString registerRef(const QString& ref);
virtual QString fileBase(const Node *node) const;
QString fileName(const Node *node);
void findAllClasses(const InnerNode *node);
void findAllFunctions(const InnerNode *node);
void findAllLegaleseTexts(const InnerNode *node);
void findAllNamespaces(const InnerNode *node);
static int hOffset(const Node *node);
static bool isThreeColumnEnumValueTable(const Atom *atom);
QString getLink(const Atom *atom,
const Node *relative,
CodeMarker *marker,
const Node** node);
QString getDisambiguationLink(const Atom* atom, CodeMarker* marker);
virtual void generateIndex(const QString &fileBase,
const QString &url,
const QString &title);
#ifdef GENERATE_MAC_REFS
void generateMacRef(const Node *node, CodeMarker *marker);
#endif
void beginLink(const QString &link,
const Node *node,
const Node *relative,
CodeMarker *marker);
void endLink();
bool generatePageElement(QXmlStreamWriter& writer,
const Node* node,
CodeMarker* marker) const;
void generatePageElements(QXmlStreamWriter& writer,
const Node* node,
CodeMarker* marker) const;
void generatePageIndex(const QString& fileName) const;
void generateExtractionMark(const Node *node, ExtractionMarkType markType);
void reportOrphans(const InnerNode* parent);
void beginDitamapPage(const InnerNode* node, const QString& fileName);
void endDitamapPage();
void writeDitaMap(const DitaMapNode* node);
void writeDitaRefs(const DitaRefList& ditarefs);
QXmlStreamWriter& xmlWriter();
QMap<QString, QString> refMap;
int codeIndent;
HelpProjectWriter *helpProjectWriter;
bool inLink;
bool inObsoleteLink;
bool inContents;
bool inSectionHeading;
bool inTableHeader;
int numTableRows;
bool threeColumnEnumValueTable;
QString link;
QStringList sectionNumber;
QRegExp funcLeftParen;
QString style;
QString headerScripts;
QString headerStyles;
QString endHeader;
QString postHeader;
QString postPostHeader;
QString footer;
QString address;
bool pleaseGenerateMacRef;
bool noBreadCrumbs;
QString project;
QString projectDescription;
QString projectUrl;
QString navigationLinks;
QString manifestDir;
QStringList stylesheets;
QStringList customHeadElements;
const Tree *myTree;
bool obsoleteLinks;
QMap<QString, NodeMap > moduleClassMap;
QMap<QString, NodeMap > moduleNamespaceMap;
NodeMap nonCompatClasses;
NodeMap mainClasses;
NodeMap compatClasses;
NodeMap obsoleteClasses;
NodeMap namespaceIndex;
NodeMap serviceClasses;
NodeMap qmlClasses;
QMap<QString, NodeMap > funcIndex;
QMap<Text, const Node *> legaleseTexts;
QStack<QXmlStreamWriter*> xmlWriterStack;
static int id;
public:
static bool debugging_on;
static QString divNavTop;
};
#define HTMLGENERATOR_ADDRESS "address"
#define HTMLGENERATOR_FOOTER "footer"
#define HTMLGENERATOR_GENERATEMACREFS "generatemacrefs" // ### document me
#define HTMLGENERATOR_POSTHEADER "postheader"
#define HTMLGENERATOR_POSTPOSTHEADER "postpostheader"
#define HTMLGENERATOR_NOBREADCRUMBS "nobreadcrumbs"
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,148 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
jscodemarker.cpp
*/
#include "qqmljsast_p.h"
#include "qqmljsengine_p.h"
#include "qqmljslexer_p.h"
#include "qqmljsparser_p.h"
#include "atom.h"
#include "node.h"
#include "jscodemarker.h"
#include "qmlmarkupvisitor.h"
#include "text.h"
#include "tree.h"
QT_BEGIN_NAMESPACE
JsCodeMarker::JsCodeMarker()
{
}
JsCodeMarker::~JsCodeMarker()
{
}
/*!
Returns true if the \a code is recognized by the parser.
*/
bool JsCodeMarker::recognizeCode(const QString &code)
{
QQmlJS::Engine engine;
QQmlJS::Lexer lexer(&engine);
QQmlJS::Parser parser(&engine);
QString newCode = code;
QList<QQmlJS::AST::SourceLocation> pragmas = extractPragmas(newCode);
lexer.setCode(newCode, 1);
return parser.parseProgram();
}
/*!
Returns true if \a ext is any of a list of file extensions
for the QML language.
*/
bool JsCodeMarker::recognizeExtension(const QString &ext)
{
return ext == "js" || ext == "json";
}
/*!
Returns true if the \a language is recognized. We recognize JavaScript,
ECMAScript and JSON.
*/
bool JsCodeMarker::recognizeLanguage(const QString &language)
{
return language == "JavaScript" || language == "ECMAScript" || language == "JSON";
}
/*!
Returns the type of atom used to represent JavaScript code in the documentation.
*/
Atom::Type JsCodeMarker::atomType() const
{
return Atom::JavaScript;
}
QString JsCodeMarker::markedUpCode(const QString &code,
const Node *relative,
const Location &location)
{
return addMarkUp(code, relative, location);
}
QString JsCodeMarker::addMarkUp(const QString &code,
const Node * /* relative */,
const Location &location)
{
QQmlJS::Engine engine;
QQmlJS::Lexer lexer(&engine);
QString newCode = code;
QList<QQmlJS::AST::SourceLocation> pragmas = extractPragmas(newCode);
lexer.setCode(newCode, 1);
QQmlJS::Parser parser(&engine);
QString output;
if (parser.parseProgram()) {
QQmlJS::AST::Node *ast = parser.rootNode();
// Pass the unmodified code to the visitor so that pragmas and other
// unhandled source text can be output.
QmlMarkupVisitor visitor(code, pragmas, &engine);
QQmlJS::AST::Node::accept(ast, &visitor);
output = visitor.markedUpCode();
} else {
location.warning(tr("Unable to parse JavaScript: \"%1\" at line %2, column %3").arg(
parser.errorMessage()).arg(parser.errorLineNumber()).arg(
parser.errorColumnNumber()));
output = protect(code);
}
return output;
}
QT_END_NAMESPACE

View File

@ -0,0 +1,75 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
jscodemarker.h
*/
#ifndef JSCODEMARKER_H
#define JSCODEMARKER_H
#include "qmlcodemarker.h"
QT_BEGIN_NAMESPACE
class JsCodeMarker : public QmlCodeMarker
{
public:
JsCodeMarker();
~JsCodeMarker();
virtual bool recognizeCode(const QString &code);
virtual bool recognizeExtension(const QString &ext);
virtual bool recognizeLanguage(const QString &language);
virtual Atom::Type atomType() const;
virtual QString markedUpCode(const QString &code,
const Node *relative,
const Location &location);
private:
QString addMarkUp(const QString &code, const Node *relative,
const Location &location);
};
QT_END_NAMESPACE
#endif

398
src/tools/qdoc/location.cpp Normal file
View File

@ -0,0 +1,398 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtDebug>
#include "config.h"
#include "location.h"
#include <qregexp.h>
#include <stdlib.h>
#include <limits.h>
#include <stdio.h>
QT_BEGIN_NAMESPACE
QT_STATIC_CONST_IMPL Location Location::null;
int Location::tabSize;
QString Location::programName;
QRegExp *Location::spuriousRegExp = 0;
/*!
\class Location
\brief The Location class keeps track of where we are in a file.
It maintains a stack of file positions. A file position
consists of the file path, line number, and column number.
The location is used for printing error messages that are
tied to a location in a file.
*/
/*!
Constructs an empty location.
*/
Location::Location()
: stk(0), stkTop(&stkBottom), stkDepth(0), etcetera(false)
{
// nothing.
}
/*!
Constructs a location with (fileName, 1, 1) on its file
position stack.
*/
Location::Location(const QString& fileName)
: stk(0), stkTop(&stkBottom), stkDepth(0), etcetera(false)
{
push(fileName);
}
/*!
The copy constructor copies the contents of \a other into
this Location using the assignment operator.
*/
Location::Location(const Location& other)
: stk(0), stkTop(&stkBottom), stkDepth(0), etcetera(false)
{
*this = other;
}
/*!
The assignment operator does a deep copy of the entire
state of \a other into this Location.
*/
Location& Location::operator=(const Location& other)
{
QStack<StackEntry> *oldStk = stk;
stkBottom = other.stkBottom;
if (other.stk == 0) {
stk = 0;
stkTop = &stkBottom;
}
else {
stk = new QStack<StackEntry>(*other.stk);
stkTop = &stk->top();
}
stkDepth = other.stkDepth;
etcetera = other.etcetera;
delete oldStk;
return *this;
}
/*!
If the file position on top of the stack has a line number
less than 1, set its line number to 1 and its column number
to 1. Otherwise, do nothing.
*/
void Location::start()
{
if (stkTop->lineNo < 1) {
stkTop->lineNo = 1;
stkTop->columnNo = 1;
}
}
/*!
Advance the current file position, using \a ch to decide how to do
that. If \a ch is a \c{'\\n'}, increment the current line number and
set the column number to 1. If \ch is a \c{'\\t'}, increment to the
next tab column. Otherwise, increment the column number by 1.
The current file position is the one on top of the position stack.
*/
void Location::advance(QChar ch)
{
if (ch == QLatin1Char('\n')) {
stkTop->lineNo++;
stkTop->columnNo = 1;
}
else if (ch == QLatin1Char('\t')) {
stkTop->columnNo =
1 + tabSize * (stkTop->columnNo + tabSize-1) / tabSize;
}
else {
stkTop->columnNo++;
}
}
/*!
Pushes \a filePath onto the file position stack. The current
file position becomes (\a filePath, 1, 1).
\sa pop()
*/
void Location::push(const QString& filePath)
{
if (stkDepth++ >= 1) {
if (stk == 0)
stk = new QStack<StackEntry>;
stk->push(StackEntry());
stkTop = &stk->top();
}
stkTop->filePath = filePath;
stkTop->lineNo = INT_MIN;
stkTop->columnNo = 1;
}
/*!
Pops the top of the internal stack. The current file position
becomes the next one in the new top of stack.
\sa push()
*/
void Location::pop()
{
if (--stkDepth == 0) {
stkBottom = StackEntry();
}
else {
stk->pop();
if (stk->isEmpty()) {
delete stk;
stk = 0;
stkTop = &stkBottom;
}
else {
stkTop = &stk->top();
}
}
}
/*! \fn bool Location::isEmpty() const
Returns true if there is no file name set yet; returns false
otherwise. The functions filePath(), lineNo() and columnNo()
must not be called on an empty Location object.
*/
/*! \fn const QString& Location::filePath() const
Returns the current path and file name.
Must not be called on an empty Location object.
\sa lineNo(), columnNo()
*/
/*!
Returns the file name part of the file path, ie the
current file. Must not be called on an empty Location
object.
*/
QString Location::fileName() const
{
QString fp = filePath();
return fp.mid(fp.lastIndexOf('/') + 1);
}
/*! \fn int Location::lineNo() const
Returns the current line number.
Must not be called on an empty Location object.
\sa filePath(), columnNo()
*/
/*! \fn int Location::columnNo() const
Returns the current column number.
Must not be called on an empty Location object.
\sa filePath(), lineNo()
*/
/*!
Writes \a message and \a detals to stderr as a formatted
warning message.
*/
void Location::warning(const QString& message, const QString& details) const
{
emitMessage(Warning, message, details);
}
/*!
Writes \a message and \a detals to stderr as a formatted
error message.
*/
void Location::error(const QString& message, const QString& details) const
{
emitMessage(Error, message, details);
}
/*!
Writes \a message and \a detals to stderr as a formatted
error message and then exits the program.
*/
void Location::fatal(const QString& message, const QString& details) const
{
emitMessage(Error, message, details);
information(message);
information(details);
information("Aborting");
exit(EXIT_FAILURE);
}
/*!
Gets several parameters from the \a config, including
tab size, program name, and a regular expression that
appears to be used for matching certain error messages
so that emitMessage() can avoid printing them.
*/
void Location::initialize(const Config& config)
{
tabSize = config.getInt(CONFIG_TABSIZE);
programName = config.programName();
QRegExp regExp = config.getRegExp(CONFIG_SPURIOUS);
if (regExp.isValid()) {
spuriousRegExp = new QRegExp(regExp);
}
else {
config.lastLocation().warning(tr("Invalid regular expression '%1'")
.arg(regExp.pattern()));
}
}
/*!
Apparently, all this does is delete the regular expression
used for intercepting certain error messages that should
not be emitted by emitMessage().
*/
void Location::terminate()
{
delete spuriousRegExp;
spuriousRegExp = 0;
}
/*!
Prints \a message to \c stdout followed by a \c{'\n'}.
*/
void Location::information(const QString& message)
{
printf("%s\n", message.toLatin1().data());
fflush(stdout);
}
/*!
Report a program bug, including the \a hint.
*/
void Location::internalError(const QString& hint)
{
Location::null.fatal(tr("Internal error (%1)").arg(hint),
tr("There is a bug in %1. Seek advice from your local"
" %2 guru.")
.arg(programName).arg(programName));
}
/*!
Formats \a message and \a details into a single string
and outputs that string to \c stderr. \a type specifies
whether the \a message is an error or a warning.
*/
void Location::emitMessage(MessageType type,
const QString& message,
const QString& details) const
{
if (type == Warning &&
spuriousRegExp != 0 &&
spuriousRegExp->exactMatch(message))
return;
QString result = message;
if (!details.isEmpty())
result += "\n[" + details + QLatin1Char(']');
result.replace("\n", "\n ");
if (type == Error)
result.prepend(tr("error: "));
result.prepend(toString());
fprintf(stderr, "%s\n", result.toLatin1().data());
fflush(stderr);
}
/*!
Converts the location to a string to be prepended to error
messages.
*/
QString Location::toString() const
{
QString str;
if (isEmpty()) {
str = programName;
}
else {
Location loc2 = *this;
loc2.setEtc(false);
loc2.pop();
if (!loc2.isEmpty()) {
QString blah = tr("In file included from ");
for (;;) {
str += blah;
str += loc2.top();
loc2.pop();
if (loc2.isEmpty())
break;
str += tr(",");
str += QLatin1Char('\n');
blah.fill(' ');
}
str += tr(":");
str += QLatin1Char('\n');
}
str += top();
}
str += QLatin1String(": ");
return str;
}
QString Location::top() const
{
QString str = filePath();
if (lineNo() >= 1) {
str += QLatin1Char(':');
str += QString::number(lineNo());
}
if (etc())
str += QLatin1String(" (etc.)");
return str;
}
QT_END_NAMESPACE

131
src/tools/qdoc/location.h Normal file
View File

@ -0,0 +1,131 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
location.h
*/
#ifndef LOCATION_H
#define LOCATION_H
#include <qstack.h>
#include "tr.h"
#define QDOC_QML
QT_BEGIN_NAMESPACE
class Config;
class QRegExp;
class Location
{
public:
Location();
Location(const QString& filePath);
Location(const Location& other);
~Location() { delete stk; }
Location& operator=(const Location& other);
void start();
void advance(QChar ch);
void advanceLines(int n) { stkTop->lineNo += n; stkTop->columnNo = 1; }
void push(const QString& filePath);
void pop();
void setEtc(bool etc) { etcetera = etc; }
void setLineNo(int no) { stkTop->lineNo = no; }
void setColumnNo(int no) { stkTop->columnNo = no; }
bool isEmpty() const { return stkDepth == 0; }
int depth() const { return stkDepth; }
const QString& filePath() const { return stkTop->filePath; }
QString fileName() const;
int lineNo() const { return stkTop->lineNo; }
int columnNo() const { return stkTop->columnNo; }
bool etc() const { return etcetera; }
void warning(const QString& message,
const QString& details = QString()) const;
void error(const QString& message,
const QString& details = QString()) const;
void fatal(const QString& message,
const QString& details = QString()) const;
QT_STATIC_CONST Location null;
static void initialize(const Config& config);
static void terminate();
static void information(const QString& message);
static void internalError(const QString& hint);
private:
enum MessageType { Warning, Error };
struct StackEntry
{
QString filePath;
int lineNo;
int columnNo;
};
void emitMessage(MessageType type,
const QString& message,
const QString& details) const;
QString toString() const;
QString top() const;
private:
StackEntry stkBottom;
QStack<StackEntry> *stk;
StackEntry *stkTop;
int stkDepth;
bool etcetera;
static int tabSize;
static QString programName;
static QRegExp *spuriousRegExp;
};
QT_END_NAMESPACE
#endif

481
src/tools/qdoc/main.cpp Normal file
View File

@ -0,0 +1,481 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
main.cpp
*/
#include <qglobal.h>
#include <stdlib.h>
#include "codemarker.h"
#include "codeparser.h"
#include "config.h"
#include "cppcodemarker.h"
#include "cppcodeparser.h"
#include "ditaxmlgenerator.h"
#include "doc.h"
#include "htmlgenerator.h"
#include "plaincodemarker.h"
#include "puredocparser.h"
#include "tokenizer.h"
#include "tree.h"
#ifdef HAVE_DECLARATIVE
#include "jscodemarker.h"
#include "qmlcodemarker.h"
#include "qmlcodeparser.h"
#endif
#include <qdebug.h>
#include "qtranslator.h"
#ifndef QT_BOOTSTRAPPED
# include "qcoreapplication.h"
#endif
QT_BEGIN_NAMESPACE
/*
The default indent for code is 4.
The default value for false is 0.
The default language is c++.
The default output format is html.
The default tab size is 8.
And those are all the default values for configuration variables.
*/
static const struct {
const char *key;
const char *value;
} defaults[] = {
{ CONFIG_CODEINDENT, "4" },
{ CONFIG_FALSEHOODS, "0" },
{ CONFIG_LANGUAGE, "Cpp" },
{ CONFIG_OUTPUTFORMATS, "HTML" },
{ CONFIG_TABSIZE, "8" },
{ 0, 0 }
};
static bool highlighting = false;
static bool showInternal = false;
static bool obsoleteLinks = false;
static QStringList defines;
static QHash<QString, Tree *> trees;
/*!
Print the help message to \c stdout.
*/
static void printHelp()
{
Location::information(tr("Usage: qdoc [options] file1.qdocconf ...\n"
"Options:\n"
" -help "
"Display this information and exit\n"
" -version "
"Display version of qdoc and exit\n"
" -D<name> "
"Define <name> as a macro while parsing sources\n"
" -highlighting "
"Turn on syntax highlighting (makes qdoc run slower)\n"
" -showinternal "
"Include stuff marked internal\n"
" -obsoletelinks "
"Report links from obsolete items to non-obsolete items\n"
" -outputdir "
"Specify output directory, overrides setting in qdocconf file\n"
" -outputformat "
"Specify output format, overrides setting in qdocconf file") );
}
/*!
Prints the qdoc version number to stdout.
*/
static void printVersion()
{
QString s = tr("qdoc version %1").arg(QT_VERSION_STR);
Location::information(s);
}
/*!
Processes the qdoc config file \a fileName. This is the
controller for all of qdoc.
*/
static void processQdocconfFile(const QString &fileName)
{
#ifndef QT_NO_TRANSLATION
QList<QTranslator *> translators;
#endif
/*
The Config instance represents the configuration data for qdoc.
All the other classes are initialized with the config. Here we
initialize the configuration with some default values.
*/
Config config(tr("qdoc"));
int i = 0;
while (defaults[i].key) {
config.setStringList(defaults[i].key,
QStringList() << defaults[i].value);
++i;
}
config.setStringList(CONFIG_SYNTAXHIGHLIGHTING, QStringList(highlighting ? "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
the qdoc configuration file. Note that the configuration
file may include other configuration files.
The Location class keeps track of the current location
in the file being processed, mainly for error reporting
purposes.
*/
Location::initialize(config);
config.load(fileName);
QStringList sourceModules;
sourceModules = config.getStringList(CONFIG_SOURCEMODULES);
Location sourceModulesLocation = config.lastLocation();
if (!sourceModules.isEmpty()) {
Location::information(tr("qdoc will generate documentation for the modules found in the sourcemodules variable."));
foreach (const QString& sourceModule, sourceModules) {
QString qdocconf = sourceModule;
if (!qdocconf.endsWith(".qdocconf"))
qdocconf += "/doc/config/module.qdocconf";
QFile f(qdocconf);
if (!f.exists()) {
sourceModulesLocation.warning(tr("Can't find module's qdoc config file '%1'").arg(qdocconf));
}
else {
Location::information(tr(" Including: %1").arg(qdocconf));
config.load(qdocconf);
}
}
}
/*
Add the defines to the configuration variables.
*/
QStringList defs = defines + config.getStringList(CONFIG_DEFINES);
config.setStringList(CONFIG_DEFINES,defs);
Location::terminate();
QString prevCurrentDir = QDir::currentPath();
QString dir = QFileInfo(fileName).path();
if (!dir.isEmpty())
QDir::setCurrent(dir);
/*
Initialize all the classes and data structures with the
qdoc configuration.
*/
Location::initialize(config);
Tokenizer::initialize(config);
Doc::initialize(config);
CodeMarker::initialize(config);
CodeParser::initialize(config);
Generator::initialize(config);
#ifndef QT_NO_TRANSLATION
/*
Load the language translators, if the configuration specifies any.
*/
QStringList fileNames = config.getStringList(CONFIG_TRANSLATORS);
QStringList::Iterator fn = fileNames.begin();
while (fn != fileNames.end()) {
QTranslator *translator = new QTranslator(0);
if (!translator->load(*fn))
config.lastLocation().error(tr("Cannot load translator '%1'")
.arg(*fn));
QCoreApplication::instance()->installTranslator(translator);
translators.append(translator);
++fn;
}
#endif
//QSet<QString> outputLanguages = config.getStringSet(CONFIG_OUTPUTLANGUAGES);
/*
Get the source language (Cpp) from the configuration
and the location in the configuration file where the
source language was set.
*/
QString lang = config.getString(CONFIG_LANGUAGE);
Location langLocation = config.lastLocation();
/*
Initialize the tree where all the parsed sources will be stored.
The tree gets built as the source files are parsed, and then the
documentation output is generated by traversing the tree.
*/
Tree *tree = new Tree;
tree->setVersion(config.getString(CONFIG_VERSION));
/*
By default, the only output format is HTML.
*/
QSet<QString> outputFormats = config.getOutputFormats();
Location outputFormatsLocation = config.lastLocation();
/*
Read some XML indexes containing definitions from other documentation sets.
*/
QStringList indexFiles = config.getStringList(CONFIG_INDEXES);
tree->readIndexes(indexFiles);
QSet<QString> excludedDirs;
QSet<QString> excludedFiles;
QSet<QString> headers;
QSet<QString> sources;
QStringList headerList;
QStringList sourceList;
QStringList excludedDirsList;
QStringList excludedFilesList;
excludedDirsList = config.getCleanPathList(CONFIG_EXCLUDEDIRS);
foreach (const QString &excludeDir, excludedDirsList) {
QString p = QDir::fromNativeSeparators(excludeDir);
excludedDirs.insert(p);
}
excludedFilesList = config.getCleanPathList(CONFIG_EXCLUDEFILES);
foreach (const QString& excludeFile, excludedFilesList) {
QString p = QDir::fromNativeSeparators(excludeFile);
excludedFiles.insert(p);
}
headerList = config.getAllFiles(CONFIG_HEADERS,CONFIG_HEADERDIRS,excludedDirs,excludedFiles);
headers = QSet<QString>::fromList(headerList);
sourceList = config.getAllFiles(CONFIG_SOURCES,CONFIG_SOURCEDIRS,excludedDirs,excludedFiles);
sources = QSet<QString>::fromList(sourceList);
/*
Parse each header file in the set using the appropriate parser and add it
to the big tree.
*/
QSet<CodeParser *> usedParsers;
QSet<QString>::ConstIterator h = headers.begin();
while (h != headers.end()) {
CodeParser *codeParser = CodeParser::parserForHeaderFile(*h);
if (codeParser) {
codeParser->parseHeaderFile(config.location(), *h, tree);
usedParsers.insert(codeParser);
}
++h;
}
foreach (CodeParser *codeParser, usedParsers)
codeParser->doneParsingHeaderFiles(tree);
usedParsers.clear();
/*
Parse each source text file in the set using the appropriate parser and
add it to the big tree.
*/
QSet<QString>::ConstIterator s = sources.begin();
while (s != sources.end()) {
CodeParser *codeParser = CodeParser::parserForSourceFile(*s);
if (codeParser) {
codeParser->parseSourceFile(config.location(), *s, tree);
usedParsers.insert(codeParser);
}
++s;
}
foreach (CodeParser *codeParser, usedParsers)
codeParser->doneParsingSourceFiles(tree);
/*
Now the big tree has been built from all the header and
source files. Resolve all the class names, function names,
targets, URLs, links, and other stuff that needs resolving.
*/
tree->resolveGroups();
tree->resolveQmlModules();
tree->resolveTargets(tree->root());
tree->resolveCppToQmlLinks();
tree->resolveQmlInheritance();
/*
The tree is built and all the stuff that needed resolving
has been resolved. Now traverse the tree and generate the
documentation output. More than one output format can be
requested. The tree is traversed for each one.
*/
QSet<QString>::ConstIterator of = outputFormats.begin();
while (of != outputFormats.end()) {
Generator* generator = Generator::generatorForFormat(*of);
if (generator == 0)
outputFormatsLocation.fatal(tr("Unknown output format '%1'").arg(*of));
generator->generateTree(tree);
++of;
}
/*
Generate the XML tag file, if it was requested.
*/
QString tagFile = config.getString(CONFIG_TAGFILE);
if (!tagFile.isEmpty()) {
tree->generateTagFile(tagFile);
}
tree->setVersion("");
Generator::terminate();
CodeParser::terminate();
CodeMarker::terminate();
Doc::terminate();
Tokenizer::terminate();
Location::terminate();
QDir::setCurrent(prevCurrentDir);
#ifndef QT_NO_TRANSLATION
qDeleteAll(translators);
#endif
#ifdef DEBUG_SHUTDOWN_CRASH
qDebug() << "main(): Delete tree";
#endif
delete tree;
#ifdef DEBUG_SHUTDOWN_CRASH
qDebug() << "main(): Tree deleted";
#endif
}
QT_END_NAMESPACE
int main(int argc, char **argv)
{
QT_USE_NAMESPACE
#ifndef QT_BOOTSTRAPPED
QCoreApplication app(argc, argv);
#endif
/*
Create code parsers for the languages to be parsed,
and create a tree for C++.
*/
CppCodeParser cppParser;
#ifdef HAVE_DECLARATIVE
QmlCodeParser qmlParser;
#endif
PureDocParser docParser;
/*
Create code markers for plain text, C++,
javascript, and QML.
*/
PlainCodeMarker plainMarker;
CppCodeMarker cppMarker;
#ifdef HAVE_DECLARATIVE
JsCodeMarker jsMarker;
QmlCodeMarker qmlMarker;
#endif
HtmlGenerator htmlGenerator;
DitaXmlGenerator ditaxmlGenerator;
QStringList qdocFiles;
QString opt;
int i = 1;
while (i < argc) {
opt = argv[i++];
if (opt == "-help") {
printHelp();
return EXIT_SUCCESS;
}
else if (opt == "-version") {
printVersion();
return EXIT_SUCCESS;
}
else if (opt == "--") {
while (i < argc)
qdocFiles.append(argv[i++]);
}
else if (opt.startsWith("-D")) {
QString define = opt.mid(2);
defines += define;
}
else if (opt == "-highlighting") {
highlighting = true;
}
else if (opt == "-showinternal") {
showInternal = true;
}
else if (opt == "-obsoletelinks") {
obsoleteLinks = true;
}
else if (opt == "-outputdir") {
Config::overrideOutputDir = argv[i];
i++;
}
else if (opt == "-outputformat") {
Config::overrideOutputFormats.insert(argv[i]);
i++;
}
else {
qdocFiles.append(opt);
}
}
if (qdocFiles.isEmpty()) {
printHelp();
return EXIT_FAILURE;
}
/*
Main loop.
*/
foreach (QString qf, qdocFiles) {
//qDebug() << "PROCESSING:" << qf;
processQdocconfFile(qf);
}
qDeleteAll(trees);
return EXIT_SUCCESS;
}

2780
src/tools/qdoc/node.cpp Normal file

File diff suppressed because it is too large Load Diff

958
src/tools/qdoc/node.h Normal file
View File

@ -0,0 +1,958 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
node.h
*/
#ifndef NODE_H
#define NODE_H
#include <qdir.h>
#include <qmap.h>
#include <qpair.h>
#include <qstringlist.h>
#include "codechunk.h"
#include "doc.h"
#include "location.h"
#include "text.h"
QT_BEGIN_NAMESPACE
class Node;
class ClassNode;
class InnerNode;
class ClassNode;
class ExampleNode;
class QmlClassNode;
class Tree;
typedef QMap<QString, const Node*> NodeMap;
typedef QMultiMap<QString, Node*> NodeMultiMap;
typedef QMultiMap<QString, const ExampleNode*> ExampleNodeMap;
typedef QList<QPair<QString,QString> > ImportList;
class Node
{
public:
enum Type {
Namespace,
Class,
Fake,
Enum,
Typedef,
Function,
Property,
Variable,
Target,
QmlProperty,
QmlSignal,
QmlSignalHandler,
QmlMethod,
LastType
};
enum SubType {
NoSubType,
Example,
HeaderFile,
File,
Image,
Group,
Module,
Page,
ExternalPage,
QmlClass,
QmlPropertyGroup,
QmlBasicType,
QmlModule,
DitaMap,
Collision,
LastSubtype
};
enum Access { Public, Protected, Private };
enum Status {
Compat,
Obsolete,
Deprecated,
Preliminary,
Commendable,
Main,
Internal
}; // don't reorder this enum
enum ThreadSafeness {
UnspecifiedSafeness,
NonReentrant,
Reentrant,
ThreadSafe
};
enum LinkType {
StartLink,
NextLink,
PreviousLink,
ContentsLink,
IndexLink,
InheritsLink /*,
GlossaryLink,
CopyrightLink,
ChapterLink,
SectionLink,
SubsectionLink,
AppendixLink */
};
enum PageType {
NoPageType,
ApiPage,
ArticlePage,
ExamplePage,
HowToPage,
OverviewPage,
TutorialPage,
FAQPage,
DitaMapPage,
OnBeyondZebra
};
virtual ~Node();
void setAccess(Access access) { access_ = access; }
void setLocation(const Location& location) { loc = location; }
void setDoc(const Doc& doc, bool replace = false);
void setStatus(Status status) { status_ = status; }
void setThreadSafeness(ThreadSafeness safeness) { safeness_ = safeness; }
void setSince(const QString &since);
void setRelates(InnerNode* pseudoParent);
void setModuleName(const QString &module) { mod = module; }
void setLink(LinkType linkType, const QString &link, const QString &desc);
void setUrl(const QString &url);
void setTemplateStuff(const QString &templateStuff) { templateStuff_ = templateStuff; }
void setPageType(PageType t) { pageType_ = t; }
void setPageType(const QString& t);
void setParent(InnerNode* n) { parent_ = n; }
virtual bool isInnerNode() const = 0;
virtual bool isReimp() const { return false; }
virtual bool isFunction() const { return false; }
virtual bool isQmlNode() const { return false; }
virtual bool isInternal() const { return false; }
virtual bool isQtQuickNode() const { return false; }
virtual bool isAbstract() const { return false; }
virtual void setAbstract(bool ) { }
virtual QString title() const { return QString(); }
Type type() const { return nodeType_; }
virtual SubType subType() const { return NoSubType; }
InnerNode* parent() const { return parent_; }
InnerNode* relates() const { return relatesTo_; }
const QString& name() const { return name_; }
QMap<LinkType, QPair<QString,QString> > links() const { return linkMap; }
QString moduleName() const;
QString url() const;
virtual QString nameForLists() const { return name_; }
Access access() const { return access_; }
QString accessString() const;
const Location& location() const { return loc; }
const Doc& doc() const { return d; }
Status status() const { return status_; }
Status inheritedStatus() const;
ThreadSafeness threadSafeness() const;
ThreadSafeness inheritedThreadSafeness() const;
QString since() const { return sinc; }
QString templateStuff() const { return templateStuff_; }
PageType pageType() const { return pageType_; }
QString pageTypeString() const;
QString nodeTypeString() const;
QString nodeSubtypeString() const;
virtual void addPageKeywords(const QString& ) { }
void clearRelated() { relatesTo_ = 0; }
virtual QString fileBase() const;
QString guid() const;
QString ditaXmlHref();
QString extractClassName(const QString &string) const;
virtual QString qmlModuleName() const { return qmlModuleName_; }
virtual QString qmlModuleVersion() const { return qmlModuleVersion_; }
virtual QString qmlModuleIdentifier() const { return qmlModuleName_ + qmlModuleVersion_; }
virtual void setQmlModuleName(const QString& );
virtual const ClassNode* classNode() const { return 0; }
virtual void clearCurrentChild() { }
virtual const ImportList* importList() const { return 0; }
virtual void setImportList(const ImportList& ) { }
virtual const Node* applyModuleIdentifier(const Node* ) const { return 0; }
const QmlClassNode* qmlClassNode() const;
const ClassNode* declarativeCppNode() const;
const QString& outputSubdirectory() const { return outSubDir_; }
QString fullDocumentName() const;
static QString cleanId(QString str);
QString idForNode() const;
static QString pageTypeString(unsigned t);
static QString nodeTypeString(unsigned t);
static QString nodeSubtypeString(unsigned t);
protected:
Node(Type type, InnerNode* parent, const QString& name);
private:
#ifdef Q_WS_WIN
Type nodeType_;
Access access_;
ThreadSafeness safeness_;
PageType pageType_;
Status status_;
#else
Type nodeType_ : 4;
Access access_ : 2;
ThreadSafeness safeness_ : 2;
PageType pageType_ : 4;
Status status_ : 3;
#endif
InnerNode* parent_;
InnerNode* relatesTo_;
QString name_;
Location loc;
Doc d;
QMap<LinkType, QPair<QString, QString> > linkMap;
QString mod;
QString url_;
QString sinc;
QString templateStuff_;
mutable QString uuid;
QString outSubDir_;
QString qmlModuleName_;
QString qmlModuleVersion_;
static QStringMap operators_;
};
class FunctionNode;
class EnumNode;
class NameCollisionNode;
typedef QList<Node*> NodeList;
typedef QMap<QString, const Node*> NodeMap;
typedef QMultiMap<QString, Node*> NodeMultiMap;
class InnerNode : public Node
{
public:
virtual ~InnerNode();
Node* findNode(const QString& name);
Node* findNode(const QString& name, bool qml);
Node* findNode(const QString& name, Type type);
void findNodes(const QString& name, QList<Node*>& n);
FunctionNode* findFunctionNode(const QString& name);
FunctionNode* findFunctionNode(const FunctionNode* clone);
void addInclude(const QString &include);
void setIncludes(const QStringList &includes);
void setOverload(const FunctionNode* func, bool overlode);
void normalizeOverloads();
void makeUndocumentedChildrenInternal();
void clearCurrentChildPointers();
void deleteChildren();
void removeFromRelated();
virtual bool isInnerNode() const { return true; }
const Node* findNode(const QString& name) const;
const Node* findNode(const QString& name, bool qml) const;
const Node* findNode(const QString& name, Type type) const;
const FunctionNode* findFunctionNode(const QString& name) const;
const FunctionNode* findFunctionNode(const FunctionNode* clone) const;
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;
const QStringList& includes() const { return inc; }
QStringList primaryKeys();
QStringList secondaryKeys();
const QStringList& pageKeywords() const { return pageKeywds; }
virtual void addPageKeywords(const QString& t) { pageKeywds << t; }
virtual void setCurrentChild() { }
virtual void setCurrentChild(InnerNode* ) { }
protected:
InnerNode(Type type, InnerNode* parent, const QString& name);
private:
friend class Node;
friend class NameCollisionNode;
static bool isSameSignature(const FunctionNode* f1, const FunctionNode* f2);
void addChild(Node* child);
void removeRelated(Node* pseudoChild);
void removeChild(Node* child);
QStringList pageKeywds;
QStringList inc;
NodeList children;
NodeList enumChildren;
NodeList related_;
QMap<QString, Node*> childMap;
QMap<QString, Node*> primaryFunctionMap;
QMap<QString, NodeList> secondaryFunctionMap;
};
class LeafNode : public Node
{
public:
LeafNode();
virtual ~LeafNode() { }
virtual bool isInnerNode() const;
protected:
LeafNode(Type type, InnerNode* parent, const QString& name);
LeafNode(InnerNode* parent, Type type, const QString& name);
};
class NamespaceNode : public InnerNode
{
public:
NamespaceNode(InnerNode* parent, const QString& name);
virtual ~NamespaceNode() { }
};
class ClassNode;
struct RelatedClass
{
RelatedClass() { }
RelatedClass(Node::Access access0,
ClassNode* node0,
const QString& dataTypeWithTemplateArgs0 = "")
: access(access0),
node(node0),
dataTypeWithTemplateArgs(dataTypeWithTemplateArgs0) { }
QString accessString() const;
Node::Access access;
ClassNode* node;
QString dataTypeWithTemplateArgs;
};
class PropertyNode;
class ClassNode : public InnerNode
{
public:
ClassNode(InnerNode* parent, const QString& name);
virtual ~ClassNode() { }
void addBaseClass(Access access,
ClassNode* node,
const QString &dataTypeWithTemplateArgs = "");
void fixBaseClasses();
const QList<RelatedClass> &baseClasses() const { return bases; }
const QList<RelatedClass> &derivedClasses() const { return derived; }
const QList<RelatedClass> &ignoredBaseClasses() const { return ignoredBases; }
bool hideFromMainList() const { return hidden; }
void setHideFromMainList(bool value) { hidden = value; }
QString serviceName() const { return sname; }
void setServiceName(const QString& value) { sname = value; }
const QmlClassNode* qmlElement() const { return qmlelement; }
void setQmlElement(QmlClassNode* qcn) { qmlelement = qcn; }
virtual bool isAbstract() const { return abstract; }
virtual void setAbstract(bool b) { abstract = b; }
const PropertyNode* findPropertyNode(const QString& name) const;
const QmlClassNode* findQmlBaseNode() const;
private:
QList<RelatedClass> bases;
QList<RelatedClass> derived;
QList<RelatedClass> ignoredBases;
bool hidden;
bool abstract;
QString sname;
QmlClassNode* qmlelement;
};
class FakeNode : public InnerNode
{
public:
FakeNode(InnerNode* parent,
const QString& name,
SubType subType,
PageType ptype);
virtual ~FakeNode() { }
void setTitle(const QString &title) { title_ = title; }
void setSubTitle(const QString &subTitle) { subtitle_ = subTitle; }
void addGroupMember(Node* node) { nodeList.append(node); }
void addQmlModuleMember(Node* node) { nodeList.append(node); }
SubType subType() const { return nodeSubtype_; }
virtual QString title() const;
virtual QString fullTitle() const;
virtual QString subTitle() const;
virtual QString imageFileName() const { return QString(); }
const NodeList& groupMembers() const { return nodeList; }
const NodeList& qmlModuleMembers() const { return nodeList; }
virtual QString nameForLists() const { return title(); }
virtual void setImageFileName(const QString& ) { }
protected:
SubType nodeSubtype_;
QString title_;
QString subtitle_;
NodeList nodeList; // used for groups and QML modules.
};
class NameCollisionNode : public FakeNode
{
public:
NameCollisionNode(InnerNode* child);
~NameCollisionNode();
const InnerNode* currentChild() const { return current; }
virtual void setCurrentChild(InnerNode* child) { current = child; }
virtual void clearCurrentChild() { current = 0; }
virtual bool isQmlNode() const;
virtual const Node* applyModuleIdentifier(const Node* origin) const;
const InnerNode* findAny(Node::Type t, Node::SubType st) const;
void addCollision(InnerNode* child);
const QMap<QString,QString>& linkTargets() const { return targets; }
void addLinkTarget(const QString& t, const QString& v) { targets.insert(t,v); }
private:
InnerNode* current;
QMap<QString,QString> targets;
};
class ExampleNode : public FakeNode
{
public:
ExampleNode(InnerNode* parent, const QString& name);
virtual ~ExampleNode() { }
virtual QString imageFileName() const { return imageFileName_; }
virtual void setImageFileName(const QString& ifn) { imageFileName_ = ifn; }
static void terminate() { exampleNodeMap.clear(); }
public:
static ExampleNodeMap exampleNodeMap;
private:
QString imageFileName_;
};
class QmlClassNode : public FakeNode
{
public:
QmlClassNode(InnerNode* parent,
const QString& name,
const ClassNode* cn);
virtual ~QmlClassNode();
virtual bool isQmlNode() const { return true; }
virtual bool isQtQuickNode() const { return (qmlModuleName() == QLatin1String("QtQuick")); }
virtual const ClassNode* classNode() const { return cnode_; }
virtual QString fileBase() const;
virtual void setCurrentChild();
virtual void clearCurrentChild();
virtual const ImportList* importList() const { return &importList_; }
virtual void setImportList(const ImportList& il) { importList_ = il; }
virtual bool isAbstract() const { return abstract; }
virtual void setAbstract(bool b) { abstract = b; }
const FakeNode* qmlBase() const { return base_; }
void resolveInheritance(const Tree* tree);
static void addInheritedBy(const QString& base, Node* sub);
static void subclasses(const QString& base, NodeList& subs);
static void terminate();
public:
static bool qmlOnly;
static QMultiMap<QString,Node*> inheritedBy;
static QMap<QString, QmlClassNode*> moduleMap;
private:
bool abstract;
const ClassNode* cnode_;
const FakeNode* base_;
ImportList importList_;
};
class QmlBasicTypeNode : public FakeNode
{
public:
QmlBasicTypeNode(InnerNode* parent,
const QString& name);
virtual ~QmlBasicTypeNode() { }
virtual bool isQmlNode() const { return true; }
};
class QmlPropGroupNode : public FakeNode
{
public:
QmlPropGroupNode(QmlClassNode* parent,
const QString& name,
bool attached);
virtual ~QmlPropGroupNode() { }
virtual bool isQmlNode() const { return true; }
virtual bool isQtQuickNode() const { return parent()->isQtQuickNode(); }
virtual QString qmlModuleName() const { return parent()->qmlModuleName(); }
virtual QString qmlModuleVersion() const { return parent()->qmlModuleVersion(); }
virtual QString qmlModuleIdentifier() const { return parent()->qmlModuleIdentifier(); }
const QString& element() const { return parent()->name(); }
void setDefault() { isdefault_ = true; }
void setReadOnly(int ro) { readOnly_ = ro; }
int getReadOnly() const { return readOnly_; }
bool isDefault() const { return isdefault_; }
bool isAttached() const { return attached_; }
bool isReadOnly() const { return (readOnly_ > 0); }
private:
bool isdefault_;
bool attached_;
int readOnly_;
};
class QmlPropertyNode;
class QmlPropertyNode : public LeafNode
{
public:
QmlPropertyNode(QmlClassNode *parent,
const QString& name,
const QString& type,
bool attached);
QmlPropertyNode(QmlPropGroupNode* parent,
const QString& name,
const QString& type,
bool attached);
QmlPropertyNode(QmlPropertyNode* parent,
const QString& name,
const QString& type,
bool attached);
virtual ~QmlPropertyNode() { }
void setDataType(const QString& dataType) { type_ = dataType; }
void setStored(bool stored) { sto = toTrool(stored); }
void setDesignable(bool designable) { des = toTrool(designable); }
void setWritable(bool writable) { wri = toTrool(writable); }
const QString &dataType() const { return type_; }
QString qualifiedDataType() const { return type_; }
void setDefault() { isdefault_ = true; }
void setReadOnly(int ro) { readOnly_ = ro; }
int getReadOnly() const { return readOnly_; }
bool isDefault() const { return isdefault_; }
bool isStored() const { return fromTrool(sto,true); }
bool isDesignable() const { return fromTrool(des,false); }
bool isWritable(const Tree* tree) const;
bool isAttached() const { return attached_; }
bool isReadOnly() const { return (readOnly_ > 0); }
virtual bool isQmlNode() const { return true; }
virtual bool isQtQuickNode() const { return parent()->isQtQuickNode(); }
virtual QString qmlModuleName() const { return parent()->qmlModuleName(); }
virtual QString qmlModuleVersion() const { return parent()->qmlModuleVersion(); }
virtual QString qmlModuleIdentifier() const { return parent()->qmlModuleIdentifier(); }
const PropertyNode *correspondingProperty(const Tree *tree) const;
const QString& element() const { return static_cast<QmlPropGroupNode*>(parent())->element(); }
void appendQmlPropNode(QmlPropertyNode* p) { qmlPropNodes_.append(p); }
const NodeList& qmlPropNodes() const { return qmlPropNodes_; }
private:
enum Trool { Trool_True, Trool_False, Trool_Default };
static Trool toTrool(bool boolean);
static bool fromTrool(Trool troolean, bool defaultValue);
QString type_;
Trool sto;
Trool des;
Trool wri;
bool isdefault_;
bool attached_;
int readOnly_;
NodeList qmlPropNodes_;
};
class EnumItem
{
public:
EnumItem() { }
EnumItem(const QString& name, const QString& value)
: nam(name), val(value) { }
EnumItem(const QString& name, const QString& value, const Text &txt)
: nam(name), val(value), txt(txt) { }
const QString& name() const { return nam; }
const QString& value() const { return val; }
const Text &text() const { return txt; }
private:
QString nam;
QString val;
Text txt;
};
class TypedefNode;
class EnumNode : public LeafNode
{
public:
EnumNode(InnerNode* parent, const QString& name);
virtual ~EnumNode() { }
void addItem(const EnumItem& item);
void setFlagsType(TypedefNode* typedeff);
bool hasItem(const QString &name) const { return names.contains(name); }
const QList<EnumItem>& items() const { return itms; }
Access itemAccess(const QString& name) const;
const TypedefNode* flagsType() const { return ft; }
QString itemValue(const QString &name) const;
private:
QList<EnumItem> itms;
QSet<QString> names;
const TypedefNode* ft;
};
class TypedefNode : public LeafNode
{
public:
TypedefNode(InnerNode* parent, const QString& name);
virtual ~TypedefNode() { }
const EnumNode* associatedEnum() const { return ae; }
private:
void setAssociatedEnum(const EnumNode* enume);
friend class EnumNode;
const EnumNode* ae;
};
inline void EnumNode::setFlagsType(TypedefNode* typedeff)
{
ft = typedeff;
typedeff->setAssociatedEnum(this);
}
class Parameter
{
public:
Parameter() {}
Parameter(const QString& leftType,
const QString& rightType = "",
const QString& name = "",
const QString& defaultValue = "");
Parameter(const Parameter& p);
Parameter& operator=(const Parameter& p);
void setName(const QString& name) { nam = name; }
bool hasType() const { return lef.length() + rig.length() > 0; }
const QString& leftType() const { return lef; }
const QString& rightType() const { return rig; }
const QString& name() const { return nam; }
const QString& defaultValue() const { return def; }
QString reconstruct(bool value = false) const;
private:
QString lef;
QString rig;
QString nam;
QString def;
};
class PropertyNode;
class FunctionNode : public LeafNode
{
public:
enum Metaness {
Plain,
Signal,
Slot,
Ctor,
Dtor,
MacroWithParams,
MacroWithoutParams,
Native };
enum Virtualness { NonVirtual, ImpureVirtual, PureVirtual };
FunctionNode(InnerNode* parent, const QString &name);
FunctionNode(Type type, InnerNode* parent, const QString &name, bool attached);
virtual ~FunctionNode() { }
void setReturnType(const QString& returnType) { rt = returnType; }
void setParentPath(const QStringList& parentPath) { pp = parentPath; }
void setMetaness(Metaness metaness) { met = metaness; }
void setVirtualness(Virtualness virtualness);
void setConst(bool conste) { con = conste; }
void setStatic(bool statique) { sta = statique; }
void setOverload(bool overlode);
void setReimp(bool r);
void addParameter(const Parameter& parameter);
inline void setParameters(const QList<Parameter>& parameters);
void borrowParameterNames(const FunctionNode* source);
void setReimplementedFrom(FunctionNode* from);
const QString& returnType() const { return rt; }
Metaness metaness() const { return met; }
bool isMacro() const {
return met == MacroWithParams || met == MacroWithoutParams;
}
Virtualness virtualness() const { return vir; }
bool isConst() const { return con; }
bool isStatic() const { return sta; }
bool isOverload() const { return ove; }
bool isReimp() const { return reimp; }
bool isFunction() const { return true; }
int overloadNumber() const;
int numOverloads() const;
const QList<Parameter>& parameters() const { return params; }
QStringList parameterNames() const;
QString rawParameters(bool names = false, bool values = false) const;
const FunctionNode* reimplementedFrom() const { return rf; }
const QList<FunctionNode*> &reimplementedBy() const { return rb; }
const PropertyNode* associatedProperty() const { return ap; }
const QStringList& parentPath() const { return pp; }
QStringList reconstructParams(bool values = false) const;
QString signature(bool values = false) const;
const QString& element() const { return parent()->name(); }
bool isAttached() const { return attached_; }
virtual bool isInternal() const;
virtual bool isQmlNode() const {
return ((type() == QmlSignal) ||
(type() == QmlMethod) ||
(type() == QmlSignalHandler));
}
virtual bool isQtQuickNode() const { return parent()->isQtQuickNode(); }
virtual QString qmlModuleName() const { return parent()->qmlModuleName(); }
virtual QString qmlModuleVersion() const { return parent()->qmlModuleVersion(); }
virtual QString qmlModuleIdentifier() const { return parent()->qmlModuleIdentifier(); }
void debug() const;
private:
void setAssociatedProperty(PropertyNode* property);
friend class InnerNode;
friend class PropertyNode;
QString rt;
QStringList pp;
#ifdef Q_WS_WIN
Metaness met;
Virtualness vir;
#else
Metaness met : 4;
Virtualness vir : 2;
#endif
bool con : 1;
bool sta : 1;
bool ove : 1;
bool reimp: 1;
bool attached_: 1;
QList<Parameter> params;
const FunctionNode* rf;
const PropertyNode* ap;
QList<FunctionNode*> rb;
};
class PropertyNode : public LeafNode
{
public:
enum FunctionRole { Getter, Setter, Resetter, Notifier };
enum { NumFunctionRoles = Notifier + 1 };
PropertyNode(InnerNode* parent, const QString& name);
virtual ~PropertyNode() { }
void setDataType(const QString& dataType) { type_ = dataType; }
void addFunction(FunctionNode* function, FunctionRole role);
void addSignal(FunctionNode* function, FunctionRole role);
void setStored(bool stored) { sto = toTrool(stored); }
void setDesignable(bool designable) { des = toTrool(designable); }
void setScriptable(bool scriptable) { scr = toTrool(scriptable); }
void setWritable(bool writable) { wri = toTrool(writable); }
void setUser(bool user) { usr = toTrool(user); }
void setOverriddenFrom(const PropertyNode* baseProperty);
void setRuntimeDesFunc(const QString& rdf) { runtimeDesFunc = rdf; }
void setRuntimeScrFunc(const QString& scrf) { runtimeScrFunc = scrf; }
void setConstant() { cst = true; }
void setFinal() { fnl = true; }
void setRevision(int revision) { rev = revision; }
const QString &dataType() const { return type_; }
QString qualifiedDataType() const;
NodeList functions() const;
NodeList functions(FunctionRole role) const { return funcs[(int)role]; }
NodeList getters() const { return functions(Getter); }
NodeList setters() const { return functions(Setter); }
NodeList resetters() const { return functions(Resetter); }
NodeList notifiers() const { return functions(Notifier); }
bool isStored() const { return fromTrool(sto, storedDefault()); }
bool isDesignable() const { return fromTrool(des, designableDefault()); }
bool isScriptable() const { return fromTrool(scr, scriptableDefault()); }
const QString& runtimeDesignabilityFunction() const { return runtimeDesFunc; }
const QString& runtimeScriptabilityFunction() const { return runtimeScrFunc; }
bool isWritable() const { return fromTrool(wri, writableDefault()); }
bool isUser() const { return fromTrool(usr, userDefault()); }
bool isConstant() const { return cst; }
bool isFinal() const { return fnl; }
const PropertyNode* overriddenFrom() const { return overrides; }
bool storedDefault() const { return true; }
bool userDefault() const { return false; }
bool designableDefault() const { return !setters().isEmpty(); }
bool scriptableDefault() const { return true; }
bool writableDefault() const { return !setters().isEmpty(); }
private:
enum Trool { Trool_True, Trool_False, Trool_Default };
static Trool toTrool(bool boolean);
static bool fromTrool(Trool troolean, bool defaultValue);
QString type_;
QString runtimeDesFunc;
QString runtimeScrFunc;
NodeList funcs[NumFunctionRoles];
Trool sto;
Trool des;
Trool scr;
Trool wri;
Trool usr;
bool cst;
bool fnl;
int rev;
const PropertyNode* overrides;
};
inline void FunctionNode::setParameters(const QList<Parameter> &parameters)
{
params = parameters;
}
inline void PropertyNode::addFunction(FunctionNode* function, FunctionRole role)
{
funcs[(int)role].append(function);
function->setAssociatedProperty(this);
}
inline void PropertyNode::addSignal(FunctionNode* function, FunctionRole role)
{
funcs[(int)role].append(function);
}
inline NodeList PropertyNode::functions() const
{
NodeList list;
for (int i = 0; i < NumFunctionRoles; ++i)
list += funcs[i];
return list;
}
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; }
void setStatic(bool statique) { sta = statique; }
const QString &leftType() const { return lt; }
const QString &rightType() const { return rt; }
QString dataType() const { return lt + rt; }
bool isStatic() const { return sta; }
private:
QString lt;
QString rt;
bool sta;
};
inline VariableNode::VariableNode(InnerNode* parent, const QString &name)
: LeafNode(Variable, parent, name), sta(false)
{
// nothing.
}
class TargetNode : public LeafNode
{
public:
TargetNode(InnerNode* parent, const QString& name);
virtual ~TargetNode() { }
virtual bool isInnerNode() const;
};
class DitaMapNode : public FakeNode
{
public:
DitaMapNode(InnerNode* parent, const QString& name)
: FakeNode(parent, name, Node::Page, Node::DitaMapPage) { }
virtual ~DitaMapNode() { }
const DitaRefList& map() const { return doc().ditamap(); }
};
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,228 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
openedlist.cpp
*/
#include <qregexp.h>
#include "atom.h"
#include "openedlist.h"
QT_BEGIN_NAMESPACE
static const char roman[] = "m\2d\5c\2l\5x\2v\5i";
OpenedList::OpenedList( Style style )
: sty( style ), ini( 1 ), nex( 0 )
{
}
OpenedList::OpenedList( const Location& location, const QString& hint )
: sty( Bullet ), ini( 1 )
{
QRegExp hintSyntax( "(\\W*)([0-9]+|[A-Z]+|[a-z]+)(\\W*)" );
if ( hintSyntax.exactMatch(hint) ) {
bool ok;
int asNumeric = hint.toInt( &ok );
int asRoman = fromRoman( hintSyntax.cap(2) );
int asAlpha = fromAlpha( hintSyntax.cap(2) );
if ( ok ) {
sty = Numeric;
ini = asNumeric;
} else if ( asRoman > 0 && asRoman != 100 && asRoman != 500 ) {
sty = ( hint == hint.toLower() ) ? LowerRoman : UpperRoman;
ini = asRoman;
} else {
sty = ( hint == hint.toLower() ) ? LowerAlpha : UpperAlpha;
ini = asAlpha;
}
pref = hintSyntax.cap( 1 );
suff = hintSyntax.cap( 3 );
} else if ( !hint.isEmpty() ) {
location.warning( tr("Unrecognized list style '%1'").arg(hint) );
}
nex = ini - 1;
}
QString OpenedList::styleString() const
{
switch ( style() ) {
case Bullet:
default:
return ATOM_LIST_BULLET;
case Tag:
return ATOM_LIST_TAG;
case Value:
return ATOM_LIST_VALUE;
case Numeric:
return ATOM_LIST_NUMERIC;
case UpperAlpha:
return ATOM_LIST_UPPERALPHA;
case LowerAlpha:
return ATOM_LIST_LOWERALPHA;
case UpperRoman:
return ATOM_LIST_UPPERROMAN;
case LowerRoman:
return ATOM_LIST_LOWERROMAN;
}
}
QString OpenedList::numberString() const
{
return QString::number( number() );
/*
switch ( style() ) {
case Numeric:
return QString::number( number() );
case UpperAlpha:
return toAlpha( number() ).toUpper();
case LowerAlpha:
return toAlpha( number() );
case UpperRoman:
return toRoman( number() ).toUpper();
case LowerRoman:
return toRoman( number() );
case Bullet:
default:
return "*";
}*/
}
QString OpenedList::toAlpha( int n )
{
QString str;
while ( n > 0 ) {
n--;
str.prepend( (n % 26) + 'a' );
n /= 26;
}
return str;
}
int OpenedList::fromAlpha( const QString& str )
{
int n = 0;
int u;
for ( int i = 0; i < (int) str.length(); i++ ) {
u = str[i].toLower().unicode();
if ( u >= 'a' && u <= 'z' ) {
n *= 26;
n += u - 'a' + 1;
} else {
return 0;
}
}
return n;
}
QString OpenedList::toRoman( int n )
{
/*
See p. 30 of Donald E. Knuth's "TeX: The Program".
*/
QString str;
int j = 0;
int k;
int u;
int v = 1000;
for ( ;; ) {
while ( n >= v ) {
str += roman[j];
n -= v;
}
if ( n <= 0 )
break;
k = j + 2;
u = v / roman[k - 1];
if ( roman[k - 1] == 2 ) {
k += 2;
u /= 5;
}
if ( n + u >= v ) {
str += roman[k];
n += u;
} else {
j += 2;
v /= roman[j - 1];
}
}
return str;
}
int OpenedList::fromRoman( const QString& str )
{
int n = 0;
int j;
int u;
int v = 0;
for ( int i = str.length() - 1; i >= 0; i-- ) {
j = 0;
u = 1000;
while ( roman[j] != 'i' && roman[j] != str[i].toLower() ) {
j += 2;
u /= roman[j - 1];
}
if ( u < v ) {
n -= u;
} else {
n += u;
}
v = u;
}
if ( str.toLower() == toRoman(n) ) {
return n;
} else {
return 0;
}
}
QT_END_NAMESPACE

View File

@ -0,0 +1,91 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
openedlist.h
*/
#ifndef OPENEDLIST_H
#define OPENEDLIST_H
#include <qstring.h>
#include "location.h"
QT_BEGIN_NAMESPACE
class OpenedList
{
public:
enum Style { Bullet, Tag, Value, Numeric, UpperAlpha, LowerAlpha,
UpperRoman, LowerRoman };
OpenedList()
: sty( Bullet ), ini( 1 ), nex( 0 ) { }
OpenedList( Style style );
OpenedList( const Location& location, const QString& hint );
void next() { nex++; }
bool isStarted() const { return nex >= ini; }
Style style() const { return sty; }
QString styleString() const;
int number() const { return nex; }
QString numberString() const;
QString prefix() const { return pref; }
QString suffix() const { return suff; }
private:
static QString toAlpha( int n );
static int fromAlpha( const QString& str );
static QString toRoman( int n );
static int fromRoman( const QString& str );
Style sty;
int ini;
int nex;
QString pref;
QString suff;
};
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,388 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
pagegenerator.cpp
*/
#include <qfile.h>
#include <qfileinfo.h>
#include <qdebug.h>
#include "codemarker.h"
#include "pagegenerator.h"
#include "tree.h"
QT_BEGIN_NAMESPACE
/*!
Nothing to do in the constructor.
*/
PageGenerator::PageGenerator()
: outputCodec(0)
{
// nothing.
}
/*!
The destructor
*/
PageGenerator::~PageGenerator()
{
while (!outStreamStack.isEmpty())
endSubPage();
}
bool PageGenerator::parseArg(const QString& src,
const QString& tag,
int* pos,
int n,
QStringRef* contents,
QStringRef* par1,
bool debug)
{
#define SKIP_CHAR(c) \
if (debug) \
qDebug() << "looking for " << c << " at " << QString(src.data() + i, n - i); \
if (i >= n || src[i] != c) { \
if (debug) \
qDebug() << " char '" << c << "' not found"; \
return false; \
} \
++i;
#define SKIP_SPACE \
while (i < n && src[i] == ' ') \
++i;
int i = *pos;
int j = i;
// assume "<@" has been parsed outside
//SKIP_CHAR('<');
//SKIP_CHAR('@');
if (tag != QStringRef(&src, i, tag.length())) {
if (0 && debug)
qDebug() << "tag " << tag << " not found at " << i;
return false;
}
if (debug)
qDebug() << "haystack:" << src << "needle:" << tag << "i:" <<i;
// skip tag
i += tag.length();
// parse stuff like: linkTag("(<@link node=\"([^\"]+)\">).*(</@link>)");
if (par1) {
SKIP_SPACE;
// read parameter name
j = i;
while (i < n && src[i].isLetter())
++i;
if (src[i] == '=') {
if (debug)
qDebug() << "read parameter" << QString(src.data() + j, i - j);
SKIP_CHAR('=');
SKIP_CHAR('"');
// skip parameter name
j = i;
while (i < n && src[i] != '"')
++i;
*par1 = QStringRef(&src, j, i - j);
SKIP_CHAR('"');
SKIP_SPACE;
} else {
if (debug)
qDebug() << "no optional parameter found";
}
}
SKIP_SPACE;
SKIP_CHAR('>');
// find contents up to closing "</@tag>
j = i;
for (; true; ++i) {
if (i + 4 + tag.length() > n)
return false;
if (src[i] != '<')
continue;
if (src[i + 1] != '/')
continue;
if (src[i + 2] != '@')
continue;
if (tag != QStringRef(&src, i + 3, tag.length()))
continue;
if (src[i + 3 + tag.length()] != '>')
continue;
break;
}
*contents = QStringRef(&src, j, i - j);
i += tag.length() + 4;
*pos = i;
if (debug)
qDebug() << " tag " << tag << " found: pos now: " << i;
return true;
#undef SKIP_CHAR
}
/*!
This function is recursive.
*/
void PageGenerator::generateTree(const Tree *tree)
{
generateInnerNode(tree->root());
}
QString PageGenerator::fileBase(const Node *node) const
{
if (node->relates())
node = node->relates();
else if (!node->isInnerNode())
node = node->parent();
if (node->subType() == Node::QmlPropertyGroup) {
node = node->parent();
}
QString base = node->doc().baseName();
if (!base.isEmpty())
return base;
const Node *p = node;
forever {
const Node *pp = p->parent();
base.prepend(p->name());
if (!p->qmlModuleIdentifier().isEmpty())
base.prepend(p->qmlModuleIdentifier()+QChar('-'));
/*
To avoid file name conflicts in the html directory,
we prepend a prefix (by default, "qml-") to the file name of QML
element doc files.
*/
if ((p->subType() == Node::QmlClass) ||
(p->subType() == Node::QmlBasicType)) {
base.prepend(outputPrefix(QLatin1String("QML")));
}
if (!pp || pp->name().isEmpty() || pp->type() == Node::Fake)
break;
base.prepend(QLatin1Char('-'));
p = pp;
}
if (node->type() == Node::Fake) {
if (node->subType() == Node::Collision) {
const NameCollisionNode* ncn = static_cast<const NameCollisionNode*>(node);
if (ncn->currentChild())
return fileBase(ncn->currentChild());
base.prepend("collision-");
}
#ifdef QDOC2_COMPAT
if (base.endsWith(".html"))
base.truncate(base.length() - 5);
#endif
}
// the code below is effectively equivalent to:
// base.replace(QRegExp("[^A-Za-z0-9]+"), " ");
// base = base.trimmed();
// base.replace(QLatin1Char(' '), QLatin1Char('-'));
// base = base.toLower();
// as this function accounted for ~8% of total running time
// we optimize a bit...
QString res;
// +5 prevents realloc in fileName() below
res.reserve(base.size() + 5);
bool begun = false;
for (int i = 0; i != base.size(); ++i) {
QChar c = base.at(i);
uint u = c.unicode();
if (u >= 'A' && u <= 'Z')
u -= 'A' - 'a';
if ((u >= 'a' && u <= 'z') || (u >= '0' && u <= '9')) {
res += QLatin1Char(u);
begun = true;
}
else if (begun) {
res += QLatin1Char('-');
begun = false;
}
}
while (res.endsWith(QLatin1Char('-')))
res.chop(1);
return res;
}
/*!
If the \a node has a URL, return the URL as the file name.
Otherwise, construct the file name from the fileBase() and
the fileExtension(), and return the constructed name.
*/
QString PageGenerator::fileName(const Node* node) const
{
if (!node->url().isEmpty())
return node->url();
QString name = fileBase(node);
name += QLatin1Char('.');
name += fileExtension(node);
return name;
}
/*!
Return the current output file name.
*/
QString PageGenerator::outFileName()
{
return QFileInfo(static_cast<QFile*>(out().device())->fileName()).fileName();
}
/*!
Creates the file named \a fileName in the output directory.
Attaches a QTextStream to the created file, which is written
to all over the place using out().
*/
void PageGenerator::beginSubPage(const InnerNode* node, const QString& fileName)
{
QString path = outputDir() + QLatin1Char('/');
if (!node->outputSubdirectory().isEmpty())
path += node->outputSubdirectory() + QLatin1Char('/');
path += fileName;
QFile* outFile = new QFile(path);
if (!outFile->open(QFile::WriteOnly))
node->location().fatal(tr("Cannot open output file '%1'").arg(outFile->fileName()));
QTextStream* out = new QTextStream(outFile);
if (outputCodec)
out->setCodec(outputCodec);
outStreamStack.push(out);
}
/*!
Flush the text stream associated with the subpage, and
then pop it off the text stream stack and delete it.
This terminates output of the subpage.
*/
void PageGenerator::endSubPage()
{
outStreamStack.top()->flush();
delete outStreamStack.top()->device();
delete outStreamStack.pop();
}
/*!
Used for writing to the current output stream. Returns a
reference to the crrent output stream, which is then used
with the \c {<<} operator for writing.
*/
QTextStream &PageGenerator::out()
{
return *outStreamStack.top();
}
/*!
Recursive writing of HTML files from the root \a node.
\note NameCollisionNodes are skipped here and processed
later. See HtmlGenerator::generateDisambiguationPages()
for more on this.
*/
void
PageGenerator::generateInnerNode(const InnerNode* node)
{
if (!node->url().isNull())
return;
if (node->type() == Node::Fake) {
const FakeNode *fakeNode = static_cast<const FakeNode *>(node);
if (fakeNode->subType() == Node::ExternalPage)
return;
if (fakeNode->subType() == Node::Image)
return;
if (fakeNode->subType() == Node::QmlPropertyGroup)
return;
if (fakeNode->subType() == Node::Page) {
if (node->count() > 0)
qDebug("PAGE %s HAS CHILDREN", qPrintable(fakeNode->title()));
}
}
/*
Obtain a code marker for the source file.
*/
CodeMarker *marker = CodeMarker::markerForFileName(node->location().filePath());
if (node->parent() != 0) {
/*
Skip name collision nodes here and process them
later in generateDisambiguationPages(). Each one
is appended to a list for later.
*/
if ((node->type() == Node::Fake) && (node->subType() == Node::Collision)) {
const NameCollisionNode* ncn = static_cast<const NameCollisionNode*>(node);
collisionNodes.append(const_cast<NameCollisionNode*>(ncn));
}
else {
beginSubPage(node, fileName(node));
if (node->type() == Node::Namespace || node->type() == Node::Class) {
generateClassLikeNode(node, marker);
}
else if (node->type() == Node::Fake) {
generateFakeNode(static_cast<const FakeNode *>(node), marker);
}
endSubPage();
}
}
NodeList::ConstIterator c = node->childNodes().begin();
while (c != node->childNodes().end()) {
if ((*c)->isInnerNode() && (*c)->access() != Node::Private) {
generateInnerNode((const InnerNode *) *c);
}
++c;
}
}
QT_END_NAMESPACE

View File

@ -0,0 +1,99 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
pagegenerator.h
*/
#ifndef PAGEGENERATOR_H
#define PAGEGENERATOR_H
#include <QStack>
#include <qtextstream.h>
#include "generator.h"
#include "location.h"
QT_BEGIN_NAMESPACE
class QTextCodec;
class ClassNode;
class InnerNode;
class NamespaceNode;
class NameCollisionNode;
class PageGenerator : public Generator
{
public:
PageGenerator();
~PageGenerator();
virtual void generateTree(const Tree *tree);
virtual void generateDisambiguationPages() { }
protected:
virtual QString fileBase(const Node* node) const;
virtual QString fileExtension(const Node* node) const = 0;
QString fileName(const Node* node) const;
QString outFileName();
virtual void beginSubPage(const InnerNode* node, const QString& fileName);
virtual void endSubPage();
virtual void generateInnerNode(const InnerNode *node);
QTextStream& out();
QString naturalLanguage;
QString outputEncoding;
QTextCodec* outputCodec;
bool parseArg(const QString& src,
const QString& tag,
int* pos,
int n,
QStringRef* contents,
QStringRef* par1 = 0,
bool debug = false);
protected:
QStack<QTextStream*> outStreamStack;
QList<NameCollisionNode*> collisionNodes;
};
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,137 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "plaincodemarker.h"
QT_BEGIN_NAMESPACE
PlainCodeMarker::PlainCodeMarker()
{
}
PlainCodeMarker::~PlainCodeMarker()
{
}
bool PlainCodeMarker::recognizeCode( const QString& /* code */ )
{
return true;
}
bool PlainCodeMarker::recognizeExtension( const QString& /* ext */ )
{
return true;
}
bool PlainCodeMarker::recognizeLanguage( const QString& /* lang */ )
{
return false;
}
Atom::Type PlainCodeMarker::atomType() const
{
return Atom::Code;
}
QString PlainCodeMarker::plainName( const Node * /* node */ )
{
return "";
}
QString PlainCodeMarker::plainFullName(const Node * /* node */, const Node * /* relative */)
{
return "";
}
QString PlainCodeMarker::markedUpCode( const QString& code,
const Node * /* relative */,
const Location & /* location */ )
{
return protect( code );
}
QString PlainCodeMarker::markedUpSynopsis( const Node * /* node */,
const Node * /* relative */,
SynopsisStyle /* style */ )
{
return "foo";
}
QString PlainCodeMarker::markedUpName( const Node * /* node */ )
{
return "";
}
QString PlainCodeMarker::markedUpFullName( const Node * /* node */,
const Node * /* relative */ )
{
return "";
}
QString PlainCodeMarker::markedUpEnumValue(const QString & /* enumValue */,
const Node * /* relative */)
{
return "";
}
QString PlainCodeMarker::markedUpIncludes( const QStringList& /* includes */ )
{
return "";
}
QString PlainCodeMarker::functionBeginRegExp( const QString& /* funcName */ )
{
return "";
}
QString PlainCodeMarker::functionEndRegExp( const QString& /* funcName */ )
{
return "";
}
QList<Section> PlainCodeMarker::sections(const InnerNode * /* innerNode */,
SynopsisStyle /* style */,
Status /* status */)
{
return QList<Section>();
}
QT_END_NAMESPACE

View File

@ -0,0 +1,79 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
plaincodemarker.h
*/
#ifndef PLAINCODEMARKER_H
#define PLAINCODEMARKER_H
#include "codemarker.h"
QT_BEGIN_NAMESPACE
class PlainCodeMarker : public CodeMarker
{
public:
PlainCodeMarker();
~PlainCodeMarker();
bool recognizeCode( const QString& code );
bool recognizeExtension( const QString& ext );
bool recognizeLanguage( const QString& lang );
Atom::Type atomType() const;
QString plainName( const Node *node );
QString plainFullName( const Node *node, const Node *relative );
QString markedUpCode( const QString& code, const Node *relative, const Location &location );
QString markedUpSynopsis( const Node *node, const Node *relative,
SynopsisStyle style );
QString markedUpName( const Node *node );
QString markedUpFullName( const Node *node, const Node *relative );
QString markedUpEnumValue(const QString &enumValue, const Node *relative);
QString markedUpIncludes( const QStringList& includes );
QString functionBeginRegExp( const QString& funcName );
QString functionEndRegExp( const QString& funcName );
QList<Section> sections(const InnerNode *innerNode, SynopsisStyle style, Status status);
};
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,63 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
puredocparser.cpp
*/
#include "puredocparser.h"
QT_BEGIN_NAMESPACE
PureDocParser::PureDocParser()
{
}
PureDocParser::~PureDocParser()
{
}
QStringList PureDocParser::sourceFileNameFilter()
{
return QStringList("*.qdoc");
}
QT_END_NAMESPACE

View File

@ -0,0 +1,72 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
puredocparser.h
*/
#ifndef PUREDOCPARSER_H
#define PUREDOCPARSER_H
#include <QSet>
#include "cppcodeparser.h"
#include "location.h"
QT_BEGIN_NAMESPACE
class Config;
class Node;
class QString;
class Tree;
class PureDocParser : public CppCodeParser
{
public:
PureDocParser();
virtual ~PureDocParser();
virtual QStringList sourceFileNameFilter();
};
QT_END_NAMESPACE
#endif

114
src/tools/qdoc/qdoc.pro Normal file
View File

@ -0,0 +1,114 @@
TEMPLATE = app
TARGET = qdoc
DESTDIR = ../../../bin
DEFINES += QDOC2_COMPAT
include(../bootstrap/bootstrap.pri)
DEFINES -= QT_NO_CAST_FROM_ASCII
DEFINES += QT_NO_TRANSLATION
INCLUDEPATH += $$QT_SOURCE_TREE/src/tools/qdoc \
$$QT_SOURCE_TREE/src/tools/qdoc/qmlparser
DEPENDPATH += $$QT_SOURCE_TREE/src/tools/qdoc \
$$QT_SOURCE_TREE/src/tools/qdoc/qmlparser
# Increase the stack size on MSVC to 4M to avoid a stack overflow
win32-msvc*:{
QMAKE_LFLAGS += /STACK:4194304
}
HEADERS += atom.h \
codechunk.h \
codemarker.h \
codeparser.h \
config.h \
cppcodemarker.h \
cppcodeparser.h \
ditaxmlgenerator.h \
doc.h \
editdistance.h \
generator.h \
helpprojectwriter.h \
htmlgenerator.h \
location.h \
node.h \
openedlist.h \
pagegenerator.h \
plaincodemarker.h \
puredocparser.h \
quoter.h \
separator.h \
text.h \
tokenizer.h \
tr.h \
tree.h
SOURCES += atom.cpp \
codechunk.cpp \
codemarker.cpp \
codeparser.cpp \
config.cpp \
cppcodemarker.cpp \
cppcodeparser.cpp \
ditaxmlgenerator.cpp \
doc.cpp \
editdistance.cpp \
generator.cpp \
helpprojectwriter.cpp \
htmlgenerator.cpp \
location.cpp \
main.cpp \
node.cpp \
openedlist.cpp \
pagegenerator.cpp \
plaincodemarker.cpp \
puredocparser.cpp \
quoter.cpp \
separator.cpp \
text.cpp \
tokenizer.cpp \
tree.cpp \
yyindent.cpp
### QML/JS Parser ###
DEFINES += HAVE_DECLARATIVE
include(qmlparser/qmlparser.pri)
HEADERS += jscodemarker.h \
qmlcodemarker.h \
qmlcodeparser.h \
qmlmarkupvisitor.h \
qmlvisitor.h
SOURCES += jscodemarker.cpp \
qmlcodemarker.cpp \
qmlcodeparser.cpp \
qmlmarkupvisitor.cpp \
qmlvisitor.cpp
### Documentation for qdoc3 ###
qtPrepareTool(QDOC, qdoc3)
qtPrepareTool(QHELPGENERATOR, qhelpgenerator)
equals(QMAKE_DIR_SEP, /) {
QDOC = QT_BUILD_TREE=$$QT_BUILD_TREE QT_SOURCE_TREE=$$QT_SOURCE_TREE $$QDOC
} else {
QDOC = set QT_BUILD_TREE=$$QT_BUILD_TREE&& set QT_SOURCE_TREE=$$QT_SOURCE_TREE&& $$QDOC
QDOC = $$replace(QDOC, "/", "\\")
}
html-docs.commands = cd \"$$QT_BUILD_TREE/doc\" && $$QDOC $$QT_SOURCE_TREE/tools/qdoc3/doc/config/qdoc.qdocconf
html-docs.files = $$QT_BUILD_TREE/doc/html
qch-docs.commands = cd \"$$QT_BUILD_TREE/doc\" && $$QHELPGENERATOR $$QT_BUILD_TREE/tools/qdoc3/doc/html/qdoc.qhp -o $$QT_BUILD_TREE/tools/qdoc3/doc/qch/qdoc.qch
qch-docs.files = $$QT_BUILD_TREE/tools/qdoc3/doc/qch
qch-docs.path = $$[QT_INSTALL_DOCS]
qch-docs.CONFIG += no_check_exist directory
QMAKE_EXTRA_TARGETS += html-docs qch-docs
target.path = $$[QT_HOST_BINS]
INSTALLS += target
load(qt_targets)

View File

@ -0,0 +1,302 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
qmlcodemarker.cpp
*/
#include "qqmljsast_p.h"
#include "qqmljsastfwd_p.h"
#include "qqmljsengine_p.h"
#include "qqmljslexer_p.h"
#include "qqmljsparser_p.h"
#include "atom.h"
#include "node.h"
#include "qmlcodemarker.h"
#include "qmlmarkupvisitor.h"
#include "text.h"
#include "tree.h"
QT_BEGIN_NAMESPACE
QmlCodeMarker::QmlCodeMarker()
{
}
QmlCodeMarker::~QmlCodeMarker()
{
}
/*!
Returns true if the \a code is recognized by the parser.
*/
bool QmlCodeMarker::recognizeCode(const QString &code)
{
QQmlJS::Engine engine;
QQmlJS::Lexer lexer(&engine);
QQmlJS::Parser parser(&engine);
QString newCode = code;
extractPragmas(newCode);
lexer.setCode(newCode, 1);
return parser.parse();
}
/*!
Returns true if \a ext is any of a list of file extensions
for the QML language.
*/
bool QmlCodeMarker::recognizeExtension(const QString &ext)
{
return ext == "qml";
}
/*!
Returns true if the \a language is recognized. Only "QML" is
recognized by this marker.
*/
bool QmlCodeMarker::recognizeLanguage(const QString &language)
{
return language == "QML";
}
/*!
Returns the type of atom used to represent QML code in the documentation.
*/
Atom::Type QmlCodeMarker::atomType() const
{
return Atom::Qml;
}
/*!
Returns the name of the \a node. Method names include are returned with a
trailing set of parentheses.
*/
QString QmlCodeMarker::plainName(const Node *node)
{
QString name = node->name();
if (node->type() == Node::QmlMethod)
name += "()";
return name;
}
QString QmlCodeMarker::plainFullName(const Node *node, const Node *relative)
{
if (node->name().isEmpty()) {
return "global";
}
else {
QString fullName;
while (node) {
fullName.prepend(plainName(node));
if (node->parent() == relative ||
node->parent()->subType() == Node::Collision ||
node->parent()->name().isEmpty())
break;
fullName.prepend("::");
node = node->parent();
}
return fullName;
}
}
QString QmlCodeMarker::markedUpCode(const QString &code,
const Node *relative,
const Location &location)
{
return addMarkUp(code, relative, location);
}
QString QmlCodeMarker::markedUpName(const Node *node)
{
QString name = linkTag(node, taggedNode(node));
if (node->type() == Node::QmlMethod)
name += "()";
return name;
}
QString QmlCodeMarker::markedUpFullName(const Node *node, const Node *relative)
{
if (node->name().isEmpty()) {
return "global";
}
else {
QString fullName;
for (;;) {
fullName.prepend(markedUpName(node));
if (node->parent() == relative || node->parent()->name().isEmpty())
break;
fullName.prepend("<@op>::</@op>");
node = node->parent();
}
return fullName;
}
}
QString QmlCodeMarker::markedUpIncludes(const QStringList& includes)
{
QString code;
QStringList::ConstIterator inc = includes.begin();
while (inc != includes.end()) {
code += "import " + *inc + QLatin1Char('\n');
++inc;
}
Location location;
return addMarkUp(code, 0, location);
}
QString QmlCodeMarker::functionBeginRegExp(const QString& funcName)
{
return "^" + QRegExp::escape("function " + funcName) + "$";
}
QString QmlCodeMarker::functionEndRegExp(const QString& /* funcName */)
{
return "^\\}$";
}
QString QmlCodeMarker::addMarkUp(const QString &code,
const Node * /* relative */,
const Location &location)
{
QQmlJS::Engine engine;
QQmlJS::Lexer lexer(&engine);
QString newCode = code;
QList<QQmlJS::AST::SourceLocation> pragmas = extractPragmas(newCode);
lexer.setCode(newCode, 1);
QQmlJS::Parser parser(&engine);
QString output;
if (parser.parse()) {
QQmlJS::AST::UiProgram *ast = parser.ast();
// Pass the unmodified code to the visitor so that pragmas and other
// unhandled source text can be output.
QmlMarkupVisitor visitor(code, pragmas, &engine);
QQmlJS::AST::Node::accept(ast, &visitor);
output = visitor.markedUpCode();
} else {
location.warning(tr("Unable to parse QML snippet: \"%1\" at line %2, column %3").arg(
parser.errorMessage()).arg(parser.errorLineNumber()).arg(
parser.errorColumnNumber()));
output = protect(code);
}
return output;
}
/*
Copied and pasted from
src/declarative/qml/qqmlscriptparser.cpp.
*/
static void replaceWithSpace(QString &str, int idx, int n)
{
QChar *data = str.data() + idx;
const QChar space(QLatin1Char(' '));
for (int ii = 0; ii < n; ++ii)
*data++ = space;
}
/*
Copied and pasted from
src/declarative/qml/qqmlscriptparser.cpp then modified to
return a list of removed pragmas.
Searches for ".pragma <value>" declarations within \a script.
Currently supported pragmas are: library
*/
QList<QQmlJS::AST::SourceLocation> QmlCodeMarker::extractPragmas(QString &script)
{
const QString pragma(QLatin1String("pragma"));
const QString library(QLatin1String("library"));
QList<QQmlJS::AST::SourceLocation> removed;
QQmlJS::Lexer l(0);
l.setCode(script, 0);
int token = l.lex();
while (true) {
if (token != QQmlJSGrammar::T_DOT)
return removed;
int startOffset = l.tokenOffset();
int startLine = l.tokenStartLine();
int startColumn = l.tokenStartColumn();
token = l.lex();
if (token != QQmlJSGrammar::T_IDENTIFIER ||
l.tokenStartLine() != startLine ||
script.mid(l.tokenOffset(), l.tokenLength()) != pragma)
return removed;
token = l.lex();
if (token != QQmlJSGrammar::T_IDENTIFIER ||
l.tokenStartLine() != startLine)
return removed;
QString pragmaValue = script.mid(l.tokenOffset(), l.tokenLength());
int endOffset = l.tokenLength() + l.tokenOffset();
token = l.lex();
if (l.tokenStartLine() == startLine)
return removed;
if (pragmaValue == QLatin1String("library")) {
replaceWithSpace(script, startOffset, endOffset - startOffset);
removed.append(
QQmlJS::AST::SourceLocation(
startOffset, endOffset - startOffset,
startLine, startColumn));
} else
return removed;
}
return removed;
}
QT_END_NAMESPACE

View File

@ -0,0 +1,86 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
qmlcodemarker.h
*/
#ifndef QMLCODEMARKER_H
#define QMLCODEMARKER_H
#include "qqmljsastfwd_p.h"
#include "cppcodemarker.h"
QT_BEGIN_NAMESPACE
class QmlCodeMarker : public CppCodeMarker
{
public:
QmlCodeMarker();
~QmlCodeMarker();
virtual bool recognizeCode(const QString &code);
virtual bool recognizeExtension(const QString &ext);
virtual bool recognizeLanguage(const QString &language);
virtual Atom::Type atomType() const;
virtual QString plainName(const Node *node);
virtual QString plainFullName(const Node *node, const Node *relative);
virtual QString markedUpCode(const QString &code,
const Node *relative,
const Location &location);
virtual QString markedUpName(const Node *node);
virtual QString markedUpFullName(const Node *node, const Node *relative);
virtual QString markedUpIncludes(const QStringList &includes);
virtual QString functionBeginRegExp(const QString &funcName);
virtual QString functionEndRegExp(const QString &funcName);
/* Copied from src/declarative/qml/qdeclarativescriptparser.cpp */
QList<QQmlJS::AST::SourceLocation> extractPragmas(QString &script);
private:
QString addMarkUp(const QString &code, const Node *relative,
const Location &location);
};
QT_END_NAMESPACE
#endif

View File

@ -0,0 +1,291 @@
/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the tools applications of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** 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.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
/*
qmlcodeparser.cpp
*/
#include "qqmljsast_p.h"
#include "qqmljsastvisitor_p.h"
#include "qmlcodeparser.h"
#include "node.h"
#include "tree.h"
#include "config.h"
#include "qmlvisitor.h"
#include <qdebug.h>
QT_BEGIN_NAMESPACE
#define COMMAND_STARTPAGE Doc::alias("startpage")
#define COMMAND_VARIABLE Doc::alias("variable")
#define COMMAND_DEPRECATED Doc::alias("deprecated")
#define COMMAND_INGROUP Doc::alias("ingroup")
#define COMMAND_INTERNAL Doc::alias("internal")
#define COMMAND_OBSOLETE Doc::alias("obsolete")
#define COMMAND_PAGEKEYWORDS Doc::alias("pagekeywords")
#define COMMAND_PRELIMINARY Doc::alias("preliminary")
#define COMMAND_SINCE Doc::alias("since")
#define COMMAND_QMLABSTRACT Doc::alias("qmlabstract")
#define COMMAND_QMLCLASS Doc::alias("qmlclass")
#define COMMAND_QMLMODULE Doc::alias("qmlmodule")
#define COMMAND_QMLPROPERTY Doc::alias("qmlproperty")
#define COMMAND_QMLATTACHEDPROPERTY Doc::alias("qmlattachedproperty")
#define COMMAND_QMLINHERITS Doc::alias("inherits")
#define COMMAND_INQMLMODULE Doc::alias("inqmlmodule")
#define COMMAND_QMLSIGNAL Doc::alias("qmlsignal")
#define COMMAND_QMLATTACHEDSIGNAL Doc::alias("qmlattachedsignal")
#define COMMAND_QMLMETHOD Doc::alias("qmlmethod")
#define COMMAND_QMLATTACHEDMETHOD Doc::alias("qmlattachedmethod")
#define COMMAND_QMLDEFAULT Doc::alias("default")
#define COMMAND_QMLREADONLY Doc::alias("readonly")
#define COMMAND_QMLBASICTYPE Doc::alias("qmlbasictype")
#define COMMAND_QMLMODULE Doc::alias("qmlmodule")
QmlCodeParser::QmlCodeParser()
{
}
QmlCodeParser::~QmlCodeParser()
{
}
/*!
Initializes the code parser base class. The \a config argument
is passed to the initialization functions in the base class.
Also creates a lexer and parser from QQmlJS.
*/
void QmlCodeParser::initializeParser(const Config &config)
{
CodeParser::initializeParser(config);
lexer = new QQmlJS::Lexer(&engine);
parser = new QQmlJS::Parser(&engine);
}
/*!
Deletes the lexer and parser created by the constructor.
*/
void QmlCodeParser::terminateParser()
{
delete lexer;
delete parser;
}
/*!
Returns "QML".
*/
QString QmlCodeParser::language()
{
return "QML";
}
/*!
Returns a filter string of "*.qml".
*/
QStringList QmlCodeParser::sourceFileNameFilter()
{
return QStringList("*.qml");
}
/*!
Parses the source file at \a filePath, creating nodes as
needed and inserting them into the \a tree. \a location is
used for error reporting.
If it can't open the file at \a filePath, it reports an
error and returns without doing anything.
*/
void QmlCodeParser::parseSourceFile(const Location& location,
const QString& filePath,
Tree *tree)
{
QFile in(filePath);
if (!in.open(QIODevice::ReadOnly)) {
location.error(tr("Cannot open QML file '%1'").arg(filePath));
return;
}
createOutputSubdirectory(location, filePath);
QString document = in.readAll();
in.close();
Location fileLocation(filePath);
QString newCode = document;
extractPragmas(newCode);
lexer->setCode(newCode, 1);
QSet<QString> topicCommandsAllowed = topicCommands();
QSet<QString> otherMetacommandsAllowed = otherMetaCommands();
QSet<QString> metacommandsAllowed = topicCommandsAllowed + otherMetacommandsAllowed;
if (parser->parse()) {
QQmlJS::AST::UiProgram *ast = parser->ast();
QmlDocVisitor visitor(filePath,
newCode,
&engine,
tree,
metacommandsAllowed,
topicCommandsAllowed);
QQmlJS::AST::Node::accept(ast, &visitor);
}
foreach (const QQmlJS::DiagnosticMessage &msg, parser->diagnosticMessages()) {
qDebug().nospace() << qPrintable(filePath) << ':' << msg.loc.startLine
<< ": QML syntax error at col " << msg.loc.startColumn
<< ": " << qPrintable(msg.message);
}
}
/*!
This function is called when the parser finishes parsing
the file, but in this case the function does nothing.
*/
void QmlCodeParser::doneParsingSourceFiles(Tree *)
{
}
/*!
Returns the set of strings representing the topic commands.
*/
QSet<QString> QmlCodeParser::topicCommands()
{
return QSet<QString>() << COMMAND_VARIABLE
<< COMMAND_QMLCLASS
<< COMMAND_QMLPROPERTY
<< COMMAND_QMLATTACHEDPROPERTY
<< COMMAND_QMLSIGNAL
<< COMMAND_QMLATTACHEDSIGNAL
<< COMMAND_QMLMETHOD
<< COMMAND_QMLATTACHEDMETHOD
<< COMMAND_QMLBASICTYPE;
}
/*!
Returns the set of strings representing the common metacommands
plus some other metacommands.
*/
QSet<QString> QmlCodeParser::otherMetaCommands()
{
return commonMetaCommands() << COMMAND_STARTPAGE
<< COMMAND_QMLINHERITS
<< COMMAND_QMLDEFAULT
<< COMMAND_QMLREADONLY
<< COMMAND_DEPRECATED
<< COMMAND_INGROUP
<< COMMAND_INTERNAL
<< COMMAND_OBSOLETE
<< COMMAND_PRELIMINARY
<< COMMAND_SINCE
<< COMMAND_QMLABSTRACT
<< COMMAND_INQMLMODULE;
}
/*!
Copy and paste from src/declarative/qml/qdeclarativescriptparser.cpp.
This function blanks out the section of the \a str beginning at \a idx
and running for \a n characters.
*/
static void replaceWithSpace(QString &str, int idx, int n)
{
QChar *data = str.data() + idx;
const QChar space(QLatin1Char(' '));
for (int ii = 0; ii < n; ++ii)
*data++ = space;
}
/*!
Copy & paste from src/declarative/qml/qdeclarativescriptparser.cpp,
then modified to return no values.
Searches for ".pragma <value>" declarations within \a script.
Currently supported pragmas are: library
*/
void QmlCodeParser::extractPragmas(QString &script)
{
const QString pragma(QLatin1String("pragma"));
const QString library(QLatin1String("library"));
QQmlJS::Lexer l(0);
l.setCode(script, 0);
int token = l.lex();
while (true) {
if (token != QQmlJSGrammar::T_DOT)
return;
int startOffset = l.tokenOffset();
int startLine = l.tokenStartLine();
token = l.lex();
if (token != QQmlJSGrammar::T_IDENTIFIER ||
l.tokenStartLine() != startLine ||
script.mid(l.tokenOffset(), l.tokenLength()) != pragma)
return;
token = l.lex();
if (token != QQmlJSGrammar::T_IDENTIFIER ||
l.tokenStartLine() != startLine)
return;
QString pragmaValue = script.mid(l.tokenOffset(), l.tokenLength());
int endOffset = l.tokenLength() + l.tokenOffset();
token = l.lex();
if (l.tokenStartLine() == startLine)
return;
if (pragmaValue == QLatin1String("library"))
replaceWithSpace(script, startOffset, endOffset - startOffset);
else
return;
}
return;
}
QT_END_NAMESPACE

Some files were not shown because too many files have changed in this diff Show More