Changeset 561 for trunk/tools/qdoc3


Ignore:
Timestamp:
Feb 11, 2010, 11:19:06 PM (15 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.6.1 sources.

Location:
trunk
Files:
5 deleted
107 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/tools/qdoc3/JAVATODO.txt

    r2 r561  
    11  * index page on "O" and downwards?
    22  * flag types, e.g. QTextStream::NumberFlags
    3   * example references doc.trolltech.com etc.
     3  * example references qt.nokia.com/doc etc.
    44
    55  * fix enum value table (e.g. QCoreApplication.Encoding.html)
  • trunk/tools/qdoc3/apigenerator.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/apigenerator.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/archiveextractor.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/archiveextractor.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/atom.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    9494  \value AbstractLeft
    9595  \value AbstractRight
     96  \value AnnotatedList
    9697  \value AutoLink
    9798  \value BaseName
     
    143144  \value SidebarLeft
    144145  \value SidebarRight
     146  \value SinceList
    145147  \value String
    146148  \value TableLeft
     
    164166    { "AbstractLeft", Atom::AbstractLeft },
    165167    { "AbstractRight", Atom::AbstractRight },
     168    { "AnnotatedList", Atom::AnnotatedList },
    166169    { "AutoLink", Atom::AutoLink },
    167170    { "BaseName", Atom::BaseName },
     
    219222    { "SidebarLeft", Atom::SidebarLeft },
    220223    { "SidebarRight", Atom::SidebarRight },
     224    { "SinceList", Atom::SinceList },
    221225    { "SnippetCommand", Atom::SnippetCommand },
    222226    { "SnippetIdentifier", Atom::SnippetIdentifier },
  • trunk/tools/qdoc3/atom.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5959        AbstractLeft,
    6060        AbstractRight,
     61        AnnotatedList,
    6162        AutoLink,
    6263        BaseName,
     
    112113        SectionHeadingLeft,
    113114        SectionHeadingRight,
    114         SidebarLeft, SidebarRight,
     115        SidebarLeft,
     116        SidebarRight,
     117        SinceList,
    115118        SnippetCommand,
    116119        SnippetIdentifier,
  • trunk/tools/qdoc3/bookgenerator.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/bookgenerator.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/ccodeparser.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/ccodeparser.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/codechunk.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/codechunk.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/codemarker.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    169169    if (sizeof(const Node *) == sizeof(uint)) {
    170170        return reinterpret_cast<const Node *>(string.toUInt());
    171     } else {
     171    }
     172    else {
    172173        return reinterpret_cast<const Node *>(string.toULongLong());
    173174    }
     
    178179    if (sizeof(const Node *) == sizeof(ulong)) {
    179180        return QString::number(reinterpret_cast<ulong>(node));
    180     } else {
     181    }
     182    else {
    181183        return QString::number(reinterpret_cast<qulonglong>(node));
    182184    }
     
    221223                || ch == QLatin1Char(':')) {
    222224            pendingWord += ch;
    223         } else {
     225        }
     226        else {
    224227            if (!pendingWord.isEmpty()) {
    225228                bool isProbablyType = (pendingWord != QLatin1String("const"));
     
    252255}
    253256
    254 QString CodeMarker::taggedNode(const Node *node)
     257QString CodeMarker::taggedNode(const Node* node)
    255258{
    256259    QString tag;
     
    277280    default:
    278281        tag = QLatin1String("@unknown");
     282        break;
    279283    }
    280284    return QLatin1Char('<') + tag + QLatin1Char('>') + protect(node->name())
    281285        + QLatin1String("</") + tag + QLatin1Char('>');
    282286}
     287
     288#ifdef QDOC_QML
     289QString CodeMarker::taggedQmlNode(const Node* node)
     290{
     291    QString tag;
     292    switch (node->type()) {
     293    case Node::QmlProperty:
     294        tag = QLatin1String("@property");
     295        break;
     296    case Node::QmlSignal:
     297        tag = QLatin1String("@signal");
     298        break;
     299    case Node::QmlMethod:
     300        tag = QLatin1String("@method");
     301        break;
     302    default:
     303        tag = QLatin1String("@unknown");
     304        break;
     305    }
     306    return QLatin1Char('<') + tag + QLatin1Char('>') + protect(node->name())
     307        + QLatin1String("</") + tag + QLatin1Char('>');
     308}
     309#endif
    283310
    284311QString CodeMarker::linkTag(const Node *node, const QString& body)
     
    309336        if (func->metaness() == FunctionNode::Ctor) {
    310337            sortNo = QLatin1String("C");
    311         } else if (func->metaness() == FunctionNode::Dtor) {
     338        }
     339        else if (func->metaness() == FunctionNode::Dtor) {
    312340            sortNo = QLatin1String("D");
    313         } else {
     341        }
     342        else {
    314343            if (nodeName.startsWith(QLatin1String("operator"))
    315344                    && nodeName.length() > 8
     
    332361}
    333362
    334 void CodeMarker::insert(FastSection &fastSection, Node *node, SynopsisStyle style, Status status)
    335 {
    336     bool inheritedMember = (!node->relates() &&
    337                             (node->parent() != (const InnerNode *)fastSection.innerNode));
     363void CodeMarker::insert(FastSection &fastSection,
     364                        Node *node,
     365                        SynopsisStyle style,
     366                        Status status)
     367{
    338368    bool irrelevant = false;
     369    bool inheritedMember = false;
     370    if (!node->relates()) {
     371        if (node->parent() != (const InnerNode*)fastSection.innerNode) {
     372            if (node->type() != Node::QmlProperty)
     373                inheritedMember = true;
     374        }
     375    }
    339376
    340377    if (node->access() == Node::Private) {
    341378        irrelevant = true;
    342     } else if (node->type() == Node::Function) {
     379    }
     380    else if (node->type() == Node::Function) {
    343381        FunctionNode *func = (FunctionNode *) node;
    344382        irrelevant = (inheritedMember
    345383                      && (func->metaness() == FunctionNode::Ctor ||
    346384                          func->metaness() == FunctionNode::Dtor));
    347     } else if (node->type() == Node::Class || node->type() == Node::Enum
     385    }
     386    else if (node->type() == Node::Class || node->type() == Node::Enum
    348387                    || node->type() == Node::Typedef) {
    349388        irrelevant = (inheritedMember && style != SeparateList);
     
    358397        if (status == Compat) {
    359398            irrelevant = (node->status() != Node::Compat);
    360         } else if (status == Obsolete) {
     399        }
     400        else if (status == Obsolete) {
    361401            irrelevant = (node->status() != Node::Obsolete);
    362         } else {
     402        }
     403        else {
    363404            irrelevant = (node->status() == Node::Compat ||
    364405                          node->status() == Node::Obsolete);
     
    371412            if (!fastSection.memberMap.contains(key))
    372413                fastSection.memberMap.insert(key, node);
    373         } else {
     414        }
     415        else {
    374416            if (node->parent()->type() == Node::Class) {
    375417                if (fastSection.inherited.isEmpty()
     
    384426}
    385427
    386 void CodeMarker::append(QList<Section>& sectionList,
    387                         const FastSection& fastSection)
    388 {
    389     if (!fastSection.memberMap.isEmpty() ||
    390          !fastSection.inherited.isEmpty()) {
    391         Section section(fastSection.name,
    392                         fastSection.singularMember,
    393                         fastSection.pluralMember);
    394         section.members = fastSection.memberMap.values();
    395         section.inherited = fastSection.inherited;
     428/*!
     429  Returns true if \a node represents a reimplemented member function.
     430  If it is, then it is inserted in the reimplemented member map in the
     431  section \a fs. And, the test is only performed if \a status is \e OK.
     432  Otherwise, false is returned.
     433 */
     434bool CodeMarker::insertReimpFunc(FastSection& fs, Node* node, Status status)
     435{
     436    if (node->access() == Node::Private)
     437        return false;
     438
     439    const FunctionNode* fn = static_cast<const FunctionNode*>(node);
     440    if ((fn->reimplementedFrom() != 0) && (status == Okay)) {
     441        bool inherited = (!fn->relates() && (fn->parent() != (const InnerNode*)fs.innerNode));
     442        if (!inherited) {
     443            QString key = sortName(fn);
     444            if (!fs.reimpMemberMap.contains(key)) {
     445                fs.reimpMemberMap.insert(key,node);
     446                return true;
     447            }
     448        }
     449    }
     450    return false;
     451 }
     452
     453/*!
     454  If \a fs is not empty, convert it to a Section and append
     455  the new Section to \a sectionList.
     456 */
     457void CodeMarker::append(QList<Section>& sectionList, const FastSection& fs)
     458{
     459    if (!fs.isEmpty()) {
     460        Section section(fs.name,fs.singularMember,fs.pluralMember);
     461        section.members = fs.memberMap.values();
     462        section.reimpMembers = fs.reimpMemberMap.values();
     463        section.inherited = fs.inherited;
    396464        sectionList.append(section);
    397465    }
     
    429497            if (!classe->templateStuff().isEmpty()) {
    430498                 result += QLatin1String("tmplt/");
    431             } else
     499            }
     500            else
    432501#endif
    433502            {
     
    466535                isMacro = true;
    467536#if 0
    468             } else if (!func->templateStuff().isEmpty()) {
     537            }
     538            else if (!func->templateStuff().isEmpty()) {
    469539                result += QLatin1String("ftmplt/");
    470540#endif
    471             } else if (func->isStatic()) {
     541            }
     542            else if (func->isStatic()) {
    472543                result += QLatin1String("clm/");
    473             } else if (!func->parent()->name().isEmpty()) {
     544            }
     545            else if (!func->parent()->name().isEmpty()) {
    474546                result += QLatin1String("instm/");
    475             } else {
     547            }
     548            else {
    476549                result += QLatin1String("func/");
    477550            }
     
    487560                const QList<Parameter> &params = func->parameters();
    488561                for (int i = 0; i < params.count(); ++i) {
    489                     QString type = params.at(i).leftType() + params.at(i).rightType();
     562                    QString type = params.at(i).leftType() +
     563                        params.at(i).rightType();
    490564                    type = QLatin1String(QMetaObject::normalizedSignature(type.toLatin1().constData()));
    491565                    if (i != 0)
     
    529603
    530604    if (node->name().isEmpty()) {
    531         return QLatin1Char('/') + myName;
    532     } else {
    533         return plainFullName(node) + QLatin1Char('/') + myName;
    534     }
    535 }
    536 
     605        return QLatin1Char('/') + protect(myName);
     606    }
     607    else {
     608        return plainFullName(node) + QLatin1Char('/') + protect(myName);
     609    }
     610}
     611
     612#ifdef QDOC_QML
     613/*!
     614  Get the list of documentation sections for the children of
     615  the specified QmlClassNode.
     616 */
     617QList<Section> CodeMarker::qmlSections(const QmlClassNode* , SynopsisStyle )
     618{
     619    return QList<Section>();
     620}
     621#endif
    537622
    538623QT_END_NAMESPACE
  • trunk/tools/qdoc3/codemarker.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6262    QString pluralMember;
    6363    NodeList members;
     64    NodeList reimpMembers;
    6465    QList<QPair<ClassNode *, int> > inherited;
    6566
     
    7172          singularMember(singularMember0),
    7273          pluralMember(pluralMember0) { }
     74    void appendMember(Node* node) { members.append(node); }
     75    void appendReimpMember(Node* node) { reimpMembers.append(node); }
    7376};
    7477
     
    8083    QString pluralMember;
    8184    QMap<QString, Node *> memberMap;
     85    QMap<QString, Node *> reimpMemberMap;
    8286    QList<QPair<ClassNode *, int> > inherited;
    8387
     
    9094          singularMember(singularMember0),
    9195          pluralMember(pluralMember0) { }
     96    bool isEmpty() const {
     97        return (memberMap.isEmpty() && inherited.isEmpty() &&
     98                reimpMemberMap.isEmpty());
     99    }
     100
    92101};
    93102
     
    115124                                     const Node *relative,
    116125                                     SynopsisStyle style) = 0;
     126#ifdef QDOC_QML
     127    virtual QString markedUpQmlItem(const Node* , bool) { return QString(); }
     128#endif
    117129    virtual QString markedUpName(const Node *node) = 0;
    118130    virtual QString markedUpFullName(const Node *node,
     
    126138                                    SynopsisStyle style,
    127139                                    Status status) = 0;
     140#ifdef QDOC_QML
     141    virtual QList<Section> qmlSections(const QmlClassNode* qmlClassNode,
     142                                       SynopsisStyle style);
     143#endif
    128144    virtual const Node *resolveTarget(const QString& target,
    129145                                      const Tree *tree,
     
    145161    QString protect(const QString &string);
    146162    QString typified(const QString &string);
    147     QString taggedNode(const Node *node);
     163    QString taggedNode(const Node* node);
     164#ifdef QDOC_QML
     165    QString taggedQmlNode(const Node* node);
     166#endif
    148167    QString linkTag(const Node *node, const QString& body);
    149168    void insert(FastSection &fastSection,
     
    151170                SynopsisStyle style,
    152171                Status status);
     172    bool insertReimpFunc(FastSection& fs, Node* node, Status status);
    153173    void append(QList<Section>& sectionList, const FastSection& fastSection);
    154174
  • trunk/tools/qdoc3/codeparser.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4848#include "node.h"
    4949#include "tree.h"
     50#include "config.h"
    5051
    5152QT_BEGIN_NAMESPACE
     
    6869
    6970QList<CodeParser *> CodeParser::parsers;
     71bool CodeParser::showInternal = false;
    7072
    7173/*!
     
    8890
    8991/*!
    90   Initializing a code parser is trivial.
    91  */
    92 void CodeParser::initializeParser(const Config & /* config */)
    93 {
    94     // nothing.
     92  Initialize the code parser base class.
     93 */
     94void CodeParser::initializeParser(const Config& config)
     95{
     96    showInternal = config.getBool(QLatin1String(CONFIG_SHOWINTERNAL));
    9597}
    9698
     
    218220    }
    219221    else if (command == COMMAND_INTERNAL) {
    220         node->setAccess(Node::Private);
    221         node->setStatus(Node::Internal);
     222        if (!showInternal) {
     223            node->setAccess(Node::Private);
     224            node->setStatus(Node::Internal);
     225        }
    222226    }
    223227    else if (command == COMMAND_REENTRANT) {
     
    242246            FakeNode *fake = static_cast<FakeNode *>(node);
    243247            fake->setTitle(arg);
    244 #ifdef QDOC2DOX           
    245             /* qdoc -> doxygen.
    246                I think this must be done here, because there can be multiple
    247                "\externalpage" and "\title" metacommands in a single qdoc
    248                comment, which means, among other things, that the "\title"
    249                commands are not inserted into the metacommand map used by
    250                the Doc class. I'm sure there4 is a better way to do this in
    251                the DoxWriter class using the information in the FakeNode,
    252                but I don't have time to figure it out right now.
    253              */
    254             if (DoxWriter::isDoxPass(1))
    255                 DoxWriter::insertTitle(fake,arg);
    256 #endif           
    257248        }
    258249        else
  • trunk/tools/qdoc3/codeparser.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    8888 private:
    8989    static QList<CodeParser *> parsers;
     90    static bool showInternal;
    9091};
    9192
  • trunk/tools/qdoc3/command.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5050QT_BEGIN_NAMESPACE
    5151
    52 void executeCommand( const Location& location, const QString& format,
    53                      const QStringList& args )
     52void executeCommand(const Location& location,
     53                    const QString& format,
     54                    const QStringList& args)
    5455{
    5556    QString actualCommand;
    56     for ( int i = 0; i < (int) format.length(); i++ ) {
     57    for (int i = 0; i < (int) format.length(); i++) {
    5758        int ch = format[i].unicode();
    58         if ( ch > 0 && ch < 8 ) {
     59        if (ch > 0 && ch < 8) {
    5960            actualCommand += args[ch - 1];
    60         } else {
     61        }
     62        else {
    6163            actualCommand += format[i];
    6264        }
     
    6466
    6567    QString toolName = actualCommand;
    66     int space = toolName.indexOf( QLatin1Char(' ') );
    67     if ( space != -1 )
    68         toolName.truncate( space );
     68    int space = toolName.indexOf(QLatin1Char(' '));
     69    if (space != -1)
     70        toolName.truncate(space);
    6971
    7072    QProcess process;
    7173    process.start(QLatin1String("sh"),
    72         QStringList() << QLatin1String("-c") << actualCommand );
     74        QStringList() << QLatin1String("-c") << actualCommand);
    7375    process.waitForFinished();
    7476
    7577    if (process.exitCode() == 127)
    76         location.fatal( tr("Couldn't launch the '%1' tool")
    77                         .arg(toolName),
    78                         tr("Make sure the tool is installed and in the"
    79                            " path.") );
     78        location.fatal(tr("Couldn't launch the '%1' tool")
     79                       .arg(toolName),
     80                       tr("Make sure the tool is installed and in the"
     81                          " path."));
    8082
    8183    QString errors = QString::fromLocal8Bit(process.readAllStandardError());
    82     while ( errors.endsWith(QLatin1Char('\n')) )
    83         errors.truncate( errors.length() - 1 );
    84     if ( !errors.isEmpty() )
    85         location.fatal( tr("The '%1' tool encountered some problems")
    86                         .arg(toolName),
    87                         tr("The tool was invoked like this:\n%1\n"
    88                            "It emitted these errors:\n%2")
    89                         .arg(actualCommand).arg(errors) );
     84    while (errors.endsWith(QLatin1Char('\n')))
     85        errors.truncate(errors.length() - 1);
     86    if (!errors.isEmpty())
     87        location.fatal(tr("The '%1' tool encountered some problems")
     88                       .arg(toolName),
     89                       tr("The tool was invoked like this:\n%1\n"
     90                          "It emitted these errors:\n%2")
     91                       .arg(actualCommand).arg(errors));
    9092}
    9193
  • trunk/tools/qdoc3/command.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/config.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    400400
    401401/*!
     402  \a fileName is the path of the file to find.
     403
     404  \a files and \a dirs are the lists where we must find the
     405  components of \a fileName.
     406 
     407  \a location is used for obtaining the file and line numbers
     408  for report qdoc errors.
    402409 */
    403410QString Config::findFile(const Location& location,
     
    528535
    529536/*!
     537  Copies the \a sourceFilePath to the file name constructed by
     538  concatenating \a targetDirPath and \a userFriendlySourceFilePath.
     539  \a location is for identifying the file and line number where
     540  a qdoc error occurred. The constructed output file name is
     541  returned.
    530542 */
    531543QString Config::copyFile(const Location& location,
     
    752764                            SKIP_CHAR();
    753765                        }
    754                         else if ((metaCharPos = QString(QLatin1String("abfnrtv")).indexOf(c)) != -1) {
     766                        else if ((metaCharPos = QString::fromLatin1("abfnrtv").indexOf(c)) != -1) {
    755767                            word += "\a\b\f\n\r\t\v"[metaCharPos];
    756768                            SKIP_CHAR();
  • trunk/tools/qdoc3/config.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    141141#define CONFIG_LANGUAGE                 "language"
    142142#define CONFIG_MACRO                    "macro"
     143#define CONFIG_OBSOLETELINKS            "obsoletelinks"
    143144#define CONFIG_OUTPUTDIR                "outputdir"
    144145#define CONFIG_OUTPUTLANGUAGE           "outputlanguage"
     
    148149#define CONFIG_QUOTINGINFORMATION       "quotinginformation"
    149150#define CONFIG_SLOW                     "slow"
     151#define CONFIG_SHOWINTERNAL             "showinternal"
    150152#define CONFIG_SOURCEDIRS               "sourcedirs"
    151153#define CONFIG_SOURCES                  "sources"
     
    160162
    161163#define CONFIG_FILEEXTENSIONS           "fileextensions"
     164#define CONFIG_IMAGEEXTENSIONS          "imageextensions"
     165
     166#ifdef QDOC_QML
     167#define CONFIG_QMLONLY                  "qmlonly"
     168#endif
    162169
    163170QT_END_NAMESPACE
  • trunk/tools/qdoc3/cppcodemarker.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4444*/
    4545
     46#include <qdebug.h>
    4647#include "atom.h"
    4748#include "cppcodemarker.h"
     
    194195        break;
    195196    case Node::Function:
     197    case Node::QmlSignal:
     198    case Node::QmlMethod:
    196199        func = (const FunctionNode *) node;
    197200        if (style != SeparateList && !func->returnType().isEmpty())
     
    284287            else {
    285288                for (int i = 0; i < documentedItems.size(); ++i) {
    286                     if (i < MaxEnumValues - 2 || i == documentedItems.size() - 1) {
     289                    if (i < MaxEnumValues-2 || i == documentedItems.size()-1) {
    287290                        if (i != 0)
    288291                            synopsis += ", ";
     
    345348}
    346349
     350#ifdef QDOC_QML
     351/*!
     352 */
     353QString CppCodeMarker::markedUpQmlItem(const Node* node, bool summary)
     354{
     355    QString name = taggedQmlNode(node);
     356    if (summary) {
     357        name = linkTag(node,name);
     358    } else if (node->type() == Node::QmlProperty) {
     359        const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(node);
     360        if (pn->isAttached())
     361            name.prepend(pn->element() + QLatin1Char('.'));
     362    }
     363    name = "<@name>" + name + "</@name>";
     364    QString synopsis = name;
     365    if (node->type() == Node::QmlProperty) {
     366        const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(node);
     367        synopsis += " : " + typified(pn->dataType());
     368    }
     369
     370    QString extra;
     371    if (summary) {
     372        if (node->status() == Node::Preliminary) {
     373            extra += " (preliminary)";
     374        }
     375        else if (node->status() == Node::Deprecated) {
     376            extra += " (deprecated)";
     377        }
     378        else if (node->status() == Node::Obsolete) {
     379            extra += " (obsolete)";
     380        }
     381    }
     382
     383    if (!extra.isEmpty()) {
     384        extra.prepend("<@extra>");
     385        extra.append("</@extra>");
     386    }
     387    return synopsis + extra;
     388}
     389#endif
     390
    347391QString CppCodeMarker::markedUpName(const Node *node)
    348392{
     
    412456}
    413457
     458#if 0
     459            FastSection privateReimpFuncs(classe,
     460                                          "Private Reimplemented Functions",
     461                                          "private reimplemented function",
     462                                          "private reimplemented functions");
     463            FastSection protectedReimpFuncs(classe,
     464                                            "Protected Reimplemented Functions",
     465                                            "protected reimplemented function",
     466                                            "protected reimplemented functions");
     467            FastSection publicReimpFuncs(classe,
     468                                         "Public Reimplemented Functions",
     469                                         "public reimplemented function",
     470                                         "public reimplemented functions");
     471#endif
     472
    414473QList<Section> CppCodeMarker::sections(const InnerNode *inner,
    415474                                       SynopsisStyle style,
     
    422481
    423482        if (style == Summary) {
    424             FastSection privateFunctions(classe, "Private Functions", "private function",
     483            FastSection privateFunctions(classe,
     484                                         "Private Functions",
     485                                         "private function",
    425486                                         "private functions");
    426487            FastSection privateSlots(classe, "Private Slots", "private slot", "private slots");
    427488            FastSection privateTypes(classe, "Private Types", "private type", "private types");
    428             FastSection protectedFunctions(classe, "Protected Functions", "protected function",
     489            FastSection protectedFunctions(classe,
     490                                           "Protected Functions",
     491                                           "protected function",
    429492                                           "protected functions");
    430             FastSection protectedSlots(classe, "Protected Slots", "protected slot", "protected slots");
    431             FastSection protectedTypes(classe, "Protected Types", "protected type", "protected types");
    432             FastSection protectedVariables(classe, "Protected Variables", "protected type", "protected variables");
    433             FastSection publicFunctions(classe, "Public Functions", "public function",
    434                                         "public functions");
     493            FastSection protectedSlots(classe,
     494                                       "Protected Slots",
     495                                       "protected slot",
     496                                       "protected slots");
     497            FastSection protectedTypes(classe,
     498                                       "Protected Types",
     499                                       "protected type",
     500                                       "protected types");
     501            FastSection protectedVariables(classe,
     502                                           "Protected Variables",
     503                                           "protected type",
     504                                           "protected variables");
     505            FastSection publicFunctions(classe,
     506                                        "Public Functions",
     507                                        "public function",
     508                                        "public functions");
    435509            FastSection publicSignals(classe, "Signals", "signal", "signals");
    436510            FastSection publicSlots(classe, "Public Slots", "public slot", "public slots");
    437511            FastSection publicTypes(classe, "Public Types", "public type", "public types");
    438             FastSection publicVariables(classe, "Public Variables", "public type", "public variables");
     512            FastSection publicVariables(classe,
     513                                        "Public Variables",
     514                                        "public type",
     515                                        "public variables");
    439516            FastSection properties(classe, "Properties", "property", "properties");
    440             FastSection relatedNonMembers(classe, "Related Non-Members", "related non-member",
     517            FastSection relatedNonMembers(classe,
     518                                          "Related Non-Members",
     519                                          "related non-member",
    441520                                          "related non-members");
    442             FastSection staticPrivateMembers(classe, "Static Private Members", "static private member",
     521            FastSection staticPrivateMembers(classe,
     522                                             "Static Private Members",
     523                                             "static private member",
    443524                                             "static private members");
    444             FastSection staticProtectedMembers(classe, "Static Protected Members",
    445                                                "static protected member", "static protected members");
    446             FastSection staticPublicMembers(classe, "Static Public Members", "static public member",
     525            FastSection staticProtectedMembers(classe,
     526                                               "Static Protected Members",
     527                                               "static protected member",
     528                                               "static protected members");
     529            FastSection staticPublicMembers(classe,
     530                                            "Static Public Members",
     531                                            "static public member",
    447532                                            "static public members");
    448533            FastSection macros(inner, "Macros", "macro", "macros");
     
    496581                            if ((*c)->type() != Node::Variable
    497582                                    || !(*c)->doc().isEmpty())
    498                                 insert(staticPublicMembers, *c, style, status);
     583                                insert(staticPublicMembers,*c,style,status);
    499584                        }
    500585                        else if ((*c)->type() == Node::Property) {
     
    506591                        }
    507592                        else if ((*c)->type() == Node::Function) {
    508                             insert(publicFunctions, *c, style, status);
     593                            if (!insertReimpFunc(publicFunctions,*c,status))
     594                                insert(publicFunctions, *c, style, status);
    509595                        }
    510596                        else {
     
    519605                            if ((*c)->type() != Node::Variable
    520606                                    || !(*c)->doc().isEmpty())
    521                                 insert(staticProtectedMembers, *c, style, status);
     607                                insert(staticProtectedMembers,*c,style,status);
    522608                        }
    523609                        else if ((*c)->type() == Node::Variable) {
    524610                            if (!(*c)->doc().isEmpty())
    525                                 insert(protectedVariables, *c, style, status);
     611                                insert(protectedVariables,*c,style,status);
    526612                        }
    527613                        else if ((*c)->type() == Node::Function) {
    528                             insert(protectedFunctions, *c, style, status);
     614                            if (!insertReimpFunc(protectedFunctions,*c,status))
     615                                insert(protectedFunctions, *c, style, status);
    529616                        }
    530617                        else {
     
    539626                            if ((*c)->type() != Node::Variable
    540627                                    || !(*c)->doc().isEmpty())
    541                                 insert(staticPrivateMembers, *c, style, status);
     628                                insert(staticPrivateMembers,*c,style,status);
    542629                        }
    543630                        else if ((*c)->type() == Node::Function) {
    544                             insert(privateFunctions, *c, style, status);
     631                            if (!insertReimpFunc(privateFunctions,*c,status))
     632                                insert(privateFunctions, *c, style, status);
    545633                        }
    546634                        else {
    547                             insert(privateTypes, *c, style, status);
     635                            insert(privateTypes,*c,style,status);
    548636                        }
    549637                    }
     
    662750                                   "namespace",
    663751                                   "namespaces");
    664             FastSection classes(inner, "Classes", "class", "classes");
     752            FastSection classes(inner,
     753                                "Classes",
     754                                "class",
     755                                "classes");
    665756            FastSection types(inner,
    666                               style == Summary ? "Types" : "Type Documentation",
     757                              style == Summary ?
     758                              "Types" : "Type Documentation",
    667759                              "type",
    668760                              "types");
    669761            FastSection functions(inner,
    670                                   style == Summary ? "Functions" : "Function Documentation",
     762                                  style == Summary ?
     763                                  "Functions" : "Function Documentation",
    671764                                  "function",
    672765                                  "functions");
    673766            FastSection macros(inner,
    674                                style == Summary ? "Macros" : "Macro Documentation",
     767                               style == Summary ?
     768                               "Macros" : "Macro Documentation",
    675769                               "macro",
    676770                               "macros");
     
    10071101}
    10081102
     1103#ifdef QDOC_QML
     1104/*!
     1105  This function is for documenting QML properties. It returns
     1106  the list of documentation sections for the children of the
     1107  \a qmlClassNode.
     1108
     1109  Currently, it only handles QML property groups.
     1110 */
     1111QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode,
     1112                                          SynopsisStyle style)
     1113{
     1114    QList<Section> sections;
     1115    if (qmlClassNode) {
     1116        if (style == Summary) {
     1117            FastSection qmlproperties(qmlClassNode,
     1118                                      "Properties",
     1119                                      "property",
     1120                                      "properties");
     1121            FastSection qmlattachedproperties(qmlClassNode,
     1122                                              "Attached Properties",
     1123                                              "property",
     1124                                              "properties");
     1125            FastSection qmlsignals(qmlClassNode,
     1126                                "Signals",
     1127                                "signal",
     1128                                "signals");
     1129            FastSection qmlattachedsignals(qmlClassNode,
     1130                                           "QML Attached Signals",
     1131                                           "signal",
     1132                                           "signals");
     1133            FastSection qmlmethods(qmlClassNode,
     1134                                   "Methods",
     1135                                   "method",
     1136                                   "methods");
     1137            FastSection qmlattachedmethods(qmlClassNode,
     1138                                           "QML Attached Methods",
     1139                                           "method",
     1140                                           "methods");
     1141
     1142            NodeList::ConstIterator c = qmlClassNode->childNodes().begin();
     1143            while (c != qmlClassNode->childNodes().end()) {
     1144                if ((*c)->subType() == Node::QmlPropertyGroup) {
     1145                    const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(*c);
     1146                    NodeList::ConstIterator p = qpgn->childNodes().begin();
     1147                    while (p != qpgn->childNodes().end()) {
     1148                        if ((*p)->type() == Node::QmlProperty) {
     1149                            const QmlPropertyNode* pn = static_cast<const QmlPropertyNode*>(*p);
     1150                            if (pn->isAttached())
     1151                                insert(qmlattachedproperties,*p,style,Okay);
     1152                            else
     1153                                insert(qmlproperties,*p,style,Okay);
     1154                        }
     1155                        ++p;
     1156                    }
     1157                }
     1158                else if ((*c)->type() == Node::QmlSignal) {
     1159                    const FunctionNode* sn = static_cast<const FunctionNode*>(*c);
     1160                    if (sn->isAttached())
     1161                        insert(qmlattachedsignals,*c,style,Okay);
     1162                    else
     1163                        insert(qmlsignals,*c,style,Okay);
     1164                }
     1165                else if ((*c)->type() == Node::QmlMethod) {
     1166                    const FunctionNode* mn = static_cast<const FunctionNode*>(*c);
     1167                    if (mn->isAttached())
     1168                        insert(qmlattachedmethods,*c,style,Okay);
     1169                    else
     1170                        insert(qmlmethods,*c,style,Okay);
     1171                }
     1172                ++c;
     1173            }
     1174            append(sections,qmlproperties);
     1175            append(sections,qmlattachedproperties);
     1176            append(sections,qmlsignals);
     1177            append(sections,qmlattachedsignals);
     1178            append(sections,qmlmethods);
     1179            append(sections,qmlattachedmethods);
     1180        }
     1181        else if (style == Detailed) {
     1182            FastSection qmlproperties(qmlClassNode, "Property Documentation");
     1183            FastSection qmlattachedproperties(qmlClassNode,"Attached Property Documentation");
     1184            FastSection qmlsignals(qmlClassNode,"Signal Documentation");
     1185            FastSection qmlattachedsignals(qmlClassNode,"Attached Signal Documentation");
     1186            FastSection qmlmethods(qmlClassNode,"Method Documentation");
     1187            FastSection qmlattachedmethods(qmlClassNode,"Attached Method Documentation");
     1188            NodeList::ConstIterator c = qmlClassNode->childNodes().begin();
     1189            while (c != qmlClassNode->childNodes().end()) {
     1190                if ((*c)->subType() == Node::QmlPropertyGroup) {
     1191                    const QmlPropGroupNode* pgn = static_cast<const QmlPropGroupNode*>(*c);
     1192                    if (pgn->isAttached())
     1193                        insert(qmlattachedproperties,*c,style,Okay);
     1194                    else
     1195                        insert(qmlproperties,*c,style,Okay);
     1196                }
     1197                else if ((*c)->type() == Node::QmlSignal) {
     1198                    const FunctionNode* sn = static_cast<const FunctionNode*>(*c);
     1199                    if (sn->isAttached())
     1200                        insert(qmlattachedsignals,*c,style,Okay);
     1201                    else
     1202                        insert(qmlsignals,*c,style,Okay);
     1203                }
     1204                else if ((*c)->type() == Node::QmlMethod) {
     1205                    const FunctionNode* mn = static_cast<const FunctionNode*>(*c);
     1206                    if (mn->isAttached())
     1207                        insert(qmlattachedmethods,*c,style,Okay);
     1208                    else
     1209                        insert(qmlmethods,*c,style,Okay);
     1210                }
     1211                ++c;
     1212            }
     1213            append(sections,qmlproperties);
     1214            append(sections,qmlattachedproperties);
     1215            append(sections,qmlsignals);
     1216            append(sections,qmlattachedsignals);
     1217            append(sections,qmlmethods);
     1218            append(sections,qmlattachedmethods);
     1219        }
     1220    }
     1221
     1222    return sections;
     1223}
     1224#endif
     1225
    10091226QT_END_NAMESPACE
  • trunk/tools/qdoc3/cppcodemarker.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6868                             const Node *relative,
    6969                             SynopsisStyle style);
     70#ifdef QDOC_QML
     71    QString markedUpQmlItem(const Node *node, bool summary);
     72#endif
    7073    QString markedUpName(const Node *node);
    7174    QString markedUpFullName(const Node *node, const Node *relative);
     
    7780                            SynopsisStyle style,
    7881                            Status status);
     82    QList<Section> qmlSections(const QmlClassNode* qmlClassNode,
     83                               SynopsisStyle style);
    7984    const Node *resolveTarget(const QString& target,
    8085                              const Tree *tree,
  • trunk/tools/qdoc3/cppcodeparser.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4848
    4949#include <stdio.h>
     50#include <errno.h>
    5051
    5152#include "codechunk.h"
     
    8889#define COMMAND_QMLCLASS                Doc::alias("qmlclass")
    8990#define COMMAND_QMLPROPERTY             Doc::alias("qmlproperty")
     91#define COMMAND_QMLATTACHEDPROPERTY     Doc::alias("qmlattachedproperty")
     92#define COMMAND_QMLINHERITS             Doc::alias("inherits")
     93#define COMMAND_QMLSIGNAL               Doc::alias("qmlsignal")
     94#define COMMAND_QMLATTACHEDSIGNAL       Doc::alias("qmlattachedsignal")
     95#define COMMAND_QMLMETHOD               Doc::alias("qmlmethod")
     96#define COMMAND_QMLATTACHEDMETHOD       Doc::alias("qmlattachedmethod")
     97#define COMMAND_QMLDEFAULT              Doc::alias("default")
    9098#endif
    9199
     
    110118            *link = arg.left(spaceAt).trimmed();
    111119            *desc = arg.mid(spaceAt).trimmed();
    112         } else {
     120        }
     121        else {
    113122            *link = arg;
    114123            *desc = arg;
     
    189198CppCodeParser::~CppCodeParser()
    190199{
    191 }
    192 
     200    // nothing.
     201}
     202
     203/*!
     204  The constructor initializes a map of special node types
     205  for identifying important nodes. And it initializes
     206  some filters for identifying certain kinds of files.
     207 */
    193208void CppCodeParser::initializeParser(const Config &config)
    194209{
     
    203218    nodeTypeMap.insert(COMMAND_VARIABLE, Node::Variable);
    204219
    205 #ifdef QDOC_QML
    206     //    nodeTypeMap.insert(COMMAND_QMLCLASS, Node::Class);
    207     nodeTypeMap.insert(COMMAND_QMLPROPERTY, Node::Property);
    208 #endif   
    209    
    210220    exampleFiles = config.getStringList(CONFIG_EXAMPLES);
    211221    exampleDirs = config.getStringList(CONFIG_EXAMPLEDIRS);
     
    217227    else
    218228        exampleNameFilter = "*.cpp *.h *.js *.xq *.svg *.xml *.ui";
    219 }
    220 
     229
     230    QStringList exampleImagePatterns = config.getStringList(
     231        CONFIG_EXAMPLES + Config::dot + CONFIG_IMAGEEXTENSIONS);
     232
     233    if (!exampleImagePatterns.isEmpty())
     234        exampleImageFilter = exampleImagePatterns.join(" ");
     235    else
     236        exampleImageFilter = "*.png";
     237}
     238
     239/*!
     240  Clear the map of common node types and call
     241  the same function in the base class.
     242 */
    221243void CppCodeParser::terminateParser()
    222244{
     
    225247}
    226248
     249/*!
     250  Returns "Cpp".
     251 */
    227252QString CppCodeParser::language()
    228253{
     
    230255}
    231256
     257/*!
     258  Returns a list of extensions for header files.
     259 */
    232260QString CppCodeParser::headerFileNameFilter()
    233261{
     
    235263}
    236264
     265/*!
     266  Returns a list of extensions for source files, i.e. not
     267  header files.
     268 */
    237269QString CppCodeParser::sourceFileNameFilter()
    238270{
     
    282314    FILE *in = fopen(QFile::encodeName(filePath), "r");
    283315    if (!in) {
    284         location.error(tr("Cannot open C++ source file '%1'").arg(filePath));
     316        location.error(tr("Cannot open C++ source file '%1' (%2)").arg(filePath).arg(strerror(errno)));
    285317        return;
    286318    }
     
    296328}
    297329
     330/*!
     331  This is called after all the header files have been parsed.
     332  I think the most important thing it does is resolve class
     333  inheritance links in the tree. But it also initializes a
     334  bunch of stuff.
     335 */
    298336void CppCodeParser::doneParsingHeaderFiles(Tree *tree)
    299337{
     
    342380}
    343381
     382/*!
     383  This is called after all the source files (i.e., not the
     384  header files) have been parsed. It traverses the tree to
     385  resolve property links, normalize overload signatures, and
     386  do other housekeeping of the tree.
     387 */
    344388void CppCodeParser::doneParsingSourceFiles(Tree *tree)
    345389{
     
    350394}
    351395
     396/*!
     397  This function searches the \a tree to find a FunctionNode
     398  for a function with the signature \a synopsis. If the
     399  \a relative node is provided, the search begins there. If
     400  \a fuzzy is true, base classes are searched. The function
     401  node is returned, if found.
     402 */
    352403const FunctionNode *CppCodeParser::findFunctionNode(const QString& synopsis,
    353404                                                    Tree *tree,
     
    478529                           << COMMAND_SERVICE
    479530                           << COMMAND_TYPEDEF
    480 #ifdef QDOC_QML       
     531#ifdef QDOC_QML
    481532                           << COMMAND_VARIABLE
    482533                           << COMMAND_QMLCLASS
    483                            << COMMAND_QMLPROPERTY;
    484 #else   
     534                           << COMMAND_QMLPROPERTY
     535                           << COMMAND_QMLATTACHEDPROPERTY
     536                           << COMMAND_QMLSIGNAL
     537                           << COMMAND_QMLATTACHEDSIGNAL
     538                           << COMMAND_QMLMETHOD
     539                           << COMMAND_QMLATTACHEDMETHOD;
     540#else
    485541                           << COMMAND_VARIABLE;
    486 #endif   
     542#endif
    487543}
    488544
     
    539595                lastPath = parentPath;
    540596            }
    541 
    542             if (func)
     597            if (func) {
    543598                func->borrowParameterNames(clone);
     599                func->setParentPath(clone->parentPath());
     600            }
    544601            delete clone;
    545602        }
     
    588645         */
    589646        // ### split(" ") hack is there to support header file syntax
    590         QStringList paths = arg.split(" "); 
     647        QStringList paths = arg.split(" ");
    591648        QStringList path = paths[0].split("::");
    592        
    593 #if QDOC2DOX       
    594         // qdoc -> doxygen.
    595         if (Doc::isDoxPass(1)) {
    596             if (command == COMMAND_PROPERTY) {
    597                 Doc::insertProperty(path);
    598             }
    599             else if (command == COMMAND_VARIABLE) {
    600                 Doc::insertVariable(path);
    601             }
    602             else if (command == COMMAND_ENUM) {
    603                 // zzz
    604             }
    605         }
    606 #endif
    607 
    608649        Node *node = 0;
    609650        if (!usedNamespaces.isEmpty()) {
     
    644685        }
    645686
     687        if (command == COMMAND_CLASS) {
     688            if (paths.size() > 1) {
     689                if (!paths[1].endsWith(".h")) {
     690                    ClassNode*cnode = static_cast<ClassNode*>(node);
     691                    cnode->setQmlElement(paths[1]);
     692                }
     693            }
     694        }
    646695        return node;
    647696    }
    648697    else if (command == COMMAND_EXAMPLE) {
    649         FakeNode *fake = new FakeNode(tre->root(), arg, FakeNode::Example);
     698        FakeNode *fake = new FakeNode(tre->root(), arg, Node::Example);
    650699        createExampleFileNodes(fake);
    651700        return fake;
    652701    }
    653702    else if (command == COMMAND_EXTERNALPAGE) {
    654         return new FakeNode(tre->root(), arg, FakeNode::ExternalPage);
     703        return new FakeNode(tre->root(), arg, Node::ExternalPage);
    655704    }
    656705    else if (command == COMMAND_FILE) {
    657         return new FakeNode(tre->root(), arg, FakeNode::File);
     706        return new FakeNode(tre->root(), arg, Node::File);
    658707    }
    659708    else if (command == COMMAND_GROUP) {
    660         return new FakeNode(tre->root(), arg, FakeNode::Group);
     709        return new FakeNode(tre->root(), arg, Node::Group);
    661710    }
    662711    else if (command == COMMAND_HEADERFILE) {
    663         return new FakeNode(tre->root(), arg, FakeNode::HeaderFile);
     712        return new FakeNode(tre->root(), arg, Node::HeaderFile);
    664713    }
    665714    else if (command == COMMAND_MODULE) {
    666         return new FakeNode(tre->root(), arg, FakeNode::Module);
     715        return new FakeNode(tre->root(), arg, Node::Module);
    667716    }
    668717    else if (command == COMMAND_PAGE) {
    669         return new FakeNode(tre->root(), arg, FakeNode::Page);
    670     }
    671 #ifdef QDOC_QML   
     718        return new FakeNode(tre->root(), arg, Node::Page);
     719    }
     720#ifdef QDOC_QML
    672721    else if (command == COMMAND_QMLCLASS) {
    673722        const ClassNode* classNode = 0;
    674         QStringList names = arg.split(" ");
    675         //qDebug() << "QMLCLASS" << names;
     723        QStringList names = arg.split(" ");
    676724        if (names.size() > 1) {
    677725            Node* n = tre->findNode(names[1].split("::"),Node::Class);
    678             if (n) {
     726            if (n)
    679727                classNode = static_cast<const ClassNode*>(n);
    680                 //qDebug() << "FOUND IT!" << classNode->name();
    681             }
    682         }
    683         return new QmlNode(tre->root(), names[0], classNode);
    684     }
    685 #endif   
     728        }
     729        return new QmlClassNode(tre->root(), names[0], classNode);
     730    }
     731    else if ((command == COMMAND_QMLSIGNAL) ||
     732             (command == COMMAND_QMLMETHOD) ||
     733             (command == COMMAND_QMLATTACHEDSIGNAL) ||
     734             (command == COMMAND_QMLATTACHEDMETHOD)) {
     735        QString element;
     736        QString type;
     737        QmlClassNode* qmlClass = 0;
     738        if (splitQmlMethodArg(doc,arg,type,element)) {
     739            Node* n = tre->findNode(QStringList(element),Node::Fake);
     740            if (n && n->subType() == Node::QmlClass) {
     741                qmlClass = static_cast<QmlClassNode*>(n);
     742                if (command == COMMAND_QMLSIGNAL)
     743                    return makeFunctionNode(doc,arg,qmlClass,Node::QmlSignal,false,COMMAND_QMLSIGNAL);
     744                else if (command == COMMAND_QMLATTACHEDSIGNAL)
     745                    return makeFunctionNode(doc,arg,qmlClass,Node::QmlSignal,true,COMMAND_QMLATTACHEDSIGNAL);
     746                else if (command == COMMAND_QMLMETHOD)
     747                    return makeFunctionNode(doc,arg,qmlClass,Node::QmlMethod,false,COMMAND_QMLMETHOD);
     748                else if (command == COMMAND_QMLATTACHEDMETHOD)
     749                    return makeFunctionNode(doc,arg,qmlClass,Node::QmlMethod,true,COMMAND_QMLATTACHEDMETHOD);
     750                else
     751                    return 0; // never get here.
     752            }
     753        }
     754    }
     755#endif
    686756    return 0;
    687757}
     758
     759#ifdef QDOC_QML
     760
     761/*!
     762  A QML property argument has the form...
     763
     764  <type> <element>::<name>
     765
     766  This function splits the argument into those three
     767  parts, sets \a type, \a element, and \a name,
     768  and returns true. If any of the parts isn't found,
     769  a qdoc warning is output and false is returned.
     770 */
     771bool CppCodeParser::splitQmlPropertyArg(const Doc& doc,
     772                                        const QString& arg,
     773                                        QString& type,
     774                                        QString& element,
     775                                        QString& name)
     776{
     777    QStringList blankSplit = arg.split(" ");
     778    if (blankSplit.size() > 1) {
     779        type = blankSplit[0];
     780        QStringList colonSplit(blankSplit[1].split("::"));
     781        if (colonSplit.size() > 1) {
     782            element = colonSplit[0];
     783            name = colonSplit[1];
     784            return true;
     785        }
     786        else
     787            doc.location().warning(tr("Missing parent QML element name"));
     788    }
     789    else
     790        doc.location().warning(tr("Missing property type"));
     791    return false;
     792}
     793
     794/*!
     795  A QML signal or method argument has the form...
     796
     797  <type> <element>::<name>(<param>, <param>, ...)
     798
     799  This function splits the argument into those two
     800  parts, sets \a element, and \a name, and returns
     801  true. If either of the parts isn't found, a debug
     802  message is output and false is returned.
     803 */
     804bool CppCodeParser::splitQmlMethodArg(const Doc& doc,
     805                                      const QString& arg,
     806                                      QString& type,
     807                                      QString& element)
     808{
     809    QStringList colonSplit(arg.split("::"));
     810    if (colonSplit.size() > 1) {
     811        QStringList blankSplit = colonSplit[0].split(" ");
     812        if (blankSplit.size() > 1) {
     813            type = blankSplit[0];
     814            element = blankSplit[1];
     815        }
     816        else {
     817            type = QString("");
     818            element = colonSplit[0];
     819        }
     820        return true;
     821    }
     822    else
     823        doc.location().warning(tr("Missing parent QML element or method signature"));
     824    return false;
     825}
     826
     827/*!
     828  Process the topic \a command group with arguments \a args.
     829
     830  Currently, this function is called only for \e{qmlproperty}
     831  and \e{qmlattachedproperty}.
     832 */
     833Node *CppCodeParser::processTopicCommandGroup(const Doc& doc,
     834                                              const QString& command,
     835                                              const QStringList& args)
     836{
     837    QmlPropGroupNode* qmlPropGroup = 0;
     838    if ((command == COMMAND_QMLPROPERTY) ||
     839        (command == COMMAND_QMLATTACHEDPROPERTY)) {
     840        QString type;
     841        QString element;
     842        QString property;
     843        bool attached = (command == COMMAND_QMLATTACHEDPROPERTY);
     844        QStringList::ConstIterator arg = args.begin();
     845        if (splitQmlPropertyArg(doc,(*arg),type,element,property)) {
     846            Node* n = tre->findNode(QStringList(element),Node::Fake);
     847            if (n && n->subType() == Node::QmlClass) {
     848                QmlClassNode* qmlClass = static_cast<QmlClassNode*>(n);
     849                if (qmlClass)
     850                    qmlPropGroup = new QmlPropGroupNode(qmlClass,
     851                                                        property,
     852                                                        attached);
     853            }
     854        }
     855        if (qmlPropGroup) {
     856            const ClassNode *correspondingClass = static_cast<const QmlClassNode*>(qmlPropGroup->parent())->classNode();
     857            PropertyNode *correspondingProperty = 0;
     858            if (correspondingClass)
     859                correspondingProperty = static_cast<PropertyNode*>((Node*)correspondingClass->findNode(property, Node::Property));
     860            QmlPropertyNode *qmlPropNode = new QmlPropertyNode(qmlPropGroup,property,type,attached);
     861            if (correspondingProperty) {
     862                bool writableList = type.startsWith("list") && correspondingProperty->dataType().endsWith('*');
     863                qmlPropNode->setWritable(writableList || correspondingProperty->isWritable());
     864            }
     865            ++arg;
     866            while (arg != args.end()) {
     867                if (splitQmlPropertyArg(doc,(*arg),type,element,property)) {
     868                    QmlPropertyNode* qmlPropNode = new QmlPropertyNode(qmlPropGroup,
     869                                                                       property,
     870                                                                       type,
     871                                                                       attached);
     872                    if (correspondingProperty) {
     873                        bool writableList = type.startsWith("list") && correspondingProperty->dataType().endsWith('*');
     874                        qmlPropNode->setWritable(writableList || correspondingProperty->isWritable());
     875                    }
     876                }
     877                ++arg;
     878            }
     879        }
     880    }
     881    return qmlPropGroup;
     882}
     883#endif
    688884
    689885/*!
     
    701897                                << COMMAND_PREVIOUSPAGE
    702898                                << COMMAND_INDEXPAGE
     899#ifdef QDOC_QML       
     900                                << COMMAND_STARTPAGE
     901                                << COMMAND_QMLINHERITS
     902                                << COMMAND_QMLDEFAULT;
     903#else   
    703904                                << COMMAND_STARTPAGE;
     905#endif   
    704906}
    705907
     
    743945                       "with the same signature or it exists but isn't virtual."));
    744946            }
    745 #if 0 // Ideally, we would enable this check to warn whenever \reimp is used
    746       // incorrectly, and only make the node internal if the function is a
    747       // reimplementation of another function in a base class.
     947            /*
     948              Ideally, we would enable this check to warn whenever
     949              \reimp is used incorrectly, and only make the node
     950              internal if the function is a reimplementation of
     951              another function in a base class.
     952            */
    748953            else if (from->access() == Node::Private
    749954                     || from->parent()->access() == Node::Private) {
    750                 doc.location().warning(
    751                     tr("Base function for '\\%1' in %2() is private or internal")
     955                doc.location().warning(tr("'\\%1' in %2() should be '\\internal' because its base function is private or internal")
    752956                    .arg(COMMAND_REIMP).arg(node->name()));
    753957            }
    754 #endif
    755             // Note: Setting the access to Private hides the documentation,
    756             // but setting the status to Internal makes the node available
    757             // in the XML output when the WebXMLGenerator is used.
     958
     959#if 0
     960            // Reimplemented functions now reported in separate sections.
     961            /*
     962              Note: Setting the access to Private hides the documentation,
     963              but setting the status to Internal makes the node available
     964              in the XML output when the WebXMLGenerator is used.
     965            */
    758966            func->setAccess(Node::Private);
    759967            func->setStatus(Node::Internal);
     968#endif
     969            func->setReimp(true);
    760970        }
    761971        else {
     
    768978        InnerNode *pseudoParent;
    769979        if (arg.startsWith("<") || arg.startsWith("\"")) {
    770             pseudoParent = static_cast<InnerNode *>(tre->findNode(QStringList(arg), Node::Fake));
     980            pseudoParent =
     981                static_cast<InnerNode *>(tre->findNode(QStringList(arg),
     982                                                       Node::Fake));
    771983        }
    772984        else {
    773985            QStringList newPath = arg.split("::");
    774             pseudoParent = static_cast<InnerNode *>(tre->findNode(QStringList(newPath), Node::Class));
     986            pseudoParent =
     987                static_cast<InnerNode*>(tre->findNode(QStringList(newPath),
     988                                                      Node::Class));
    775989            if (!pseudoParent)
    776                 pseudoParent = static_cast<InnerNode *>(tre->findNode(QStringList(newPath),
    777                                                         Node::Namespace));
     990                pseudoParent =
     991                    static_cast<InnerNode*>(tre->findNode(QStringList(newPath),
     992                                                          Node::Namespace));
    778993        }
    779994        if (!pseudoParent) {
     
    8001015        setLink(node, Node::StartLink, arg);
    8011016    }
     1017#ifdef QDOC_QML
     1018    else if (command == COMMAND_QMLINHERITS) {
     1019        setLink(node, Node::InheritsLink, arg);
     1020    }
     1021    else if (command == COMMAND_QMLDEFAULT) {
     1022        QmlPropGroupNode* qpgn = static_cast<QmlPropGroupNode*>(node);
     1023        qpgn->setDefault();
     1024    }
     1025#endif
    8021026    else {
    8031027        processCommonMetaCommand(doc.location(),command,arg,node,tre);
     
    8791103        return true;
    8801104    }
    881     else {
     1105    else
    8821106        return false;
    883     }
    8841107}
    8851108
     
    9161139            if (tok == Tok_LeftAngle) {
    9171140                leftAngleDepth++;
    918             } else if (tok == Tok_RightAngle) {
     1141            }
     1142            else if (tok == Tok_RightAngle) {
    9191143                leftAngleDepth--;
    920             } else if (tok == Tok_LeftParen || tok == Tok_LeftBrace) {
     1144            }
     1145            else if (tok == Tok_LeftParen || tok == Tok_LeftBrace) {
    9211146                ++parenAndBraceDepth;
    922             } else if (tok == Tok_RightParen || tok == Tok_RightBrace) {
     1147            }
     1148            else if (tok == Tok_RightParen || tok == Tok_RightBrace) {
    9231149                if (--parenAndBraceDepth < 0)
    9241150                    return false;
     
    9831209            else
    9841210                return false;
    985         } else if (match(Tok_int) || match(Tok_char) || match(Tok_double)) {
     1211        }
     1212        else if (match(Tok_int) || match(Tok_char) || match(Tok_double)) {
    9861213            dataType->append(previousLexeme());
    9871214        }
     
    10831310        }
    10841311    }
    1085     func->addParameter(Parameter(dataType.toString(), "", name,
    1086                                   defaultValue.toString())); // ###
     1312    func->addParameter(Parameter(dataType.toString(),
     1313                                 "",
     1314                                 name,
     1315                                 defaultValue.toString())); // ###
    10871316    return true;
    10881317}
     
    10911320                                      QStringList *parentPathPtr,
    10921321                                      FunctionNode **funcPtr,
    1093                                       const QString &templateStuff)
     1322                                      const QString &templateStuff,
     1323                                      Node::Type type,
     1324                                      bool attached)
    10941325{
    10951326    CodeChunk returnType;
     
    11211352                && (match(Tok_Q_DECLARE_FLAGS) || match(Tok_Q_PROPERTY)))
    11221353            returnType = CodeChunk(previousLexeme());
    1123         else
     1354        else {
    11241355            return false;
     1356        }
    11251357    }
    11261358
     
    11321364
    11331365    if (tok == Tok_operator &&
    1134          (returnType.toString().isEmpty() || returnType.toString().endsWith("::"))) {
     1366         (returnType.toString().isEmpty() ||
     1367          returnType.toString().endsWith("::"))) {
    11351368        // 'QString::operator const char *()'
    11361369        parentPath = returnType.toString().split(sep);
     
    11511384            }
    11521385        }
    1153         if (tok != Tok_LeftParen)
     1386        if (tok != Tok_LeftParen) {
    11541387            return false;
     1388        }
    11551389    }
    11561390    else if (tok == Tok_LeftParen) {
     
    11681402            matchTemplateAngles();
    11691403
    1170             if (match(Tok_Gulbrandsen)) {
     1404            if (match(Tok_Gulbrandsen))
    11711405                parentPath.append(name);
    1172             } else {
     1406            else
    11731407                break;
    1174             }
    11751408        }
    11761409
     
    11851418            }
    11861419        }
    1187         if (parent && (tok == Tok_Semicolon || tok == Tok_LeftBracket || tok == Tok_Colon)
     1420        if (parent && (tok == Tok_Semicolon ||
     1421                       tok == Tok_LeftBracket ||
     1422                       tok == Tok_Colon)
    11881423                && access != Node::Private) {
    11891424            if (tok == Tok_LeftBracket) {
     
    11971432                    readToken();
    11981433                }
    1199                 if (tok != Tok_Semicolon)
     1434                if (tok != Tok_Semicolon) {
    12001435                    return false;
    1201             } else if (tok == Tok_Colon) {
     1436                }
     1437            }
     1438            else if (tok == Tok_Colon) {
    12021439                returnType.appendHotspot();
    12031440
     
    12061443                    readToken();
    12071444                }
    1208                 if (tok != Tok_Semicolon)
     1445                if (tok != Tok_Semicolon) {
    12091446                    return false;
     1447                }
    12101448            }
    12111449
     
    12201458            return false;
    12211459        }
    1222         if (tok != Tok_LeftParen)
     1460        if (tok != Tok_LeftParen) {
    12231461            return false;
     1462        }
    12241463    }
    12251464    readToken();
    12261465
    1227     FunctionNode *func = new FunctionNode(parent, name);
     1466    FunctionNode *func = new FunctionNode(type, parent, name, attached);
    12281467    func->setAccess(access);
    12291468    func->setLocation(location());
    12301469    func->setReturnType(returnType.toString());
     1470    func->setParentPath(parentPath);
    12311471    func->setTemplateStuff(templateStuff);
    12321472    if (compat)
     
    12451485    if (tok != Tok_RightParen) {
    12461486        do {
    1247             if (!matchParameter(func))
     1487            if (!matchParameter(func)) {
    12481488                return false;
     1489            }
    12491490        } while (match(Tok_Comma));
    12501491    }
    1251     if (!match(Tok_RightParen))
     1492    if (!match(Tok_RightParen)) {
    12521493        return false;
     1494    }
    12531495
    12541496    func->setConst(match(Tok_const));
     
    12661508        int braceDepth0 = tokenizer->braceDepth();
    12671509
    1268         if (!match(Tok_LeftBrace))
     1510        if (!match(Tok_LeftBrace)) {
    12691511            return false;
     1512        }
    12701513        while (tokenizer->braceDepth() >= braceDepth0 && tok != Tok_Eoi)
    12711514            readToken();
     
    13911634    NamespaceNode *namespasse = 0;
    13921635    if (parent)
    1393         namespasse = static_cast<NamespaceNode *>(parent->findNode(namespaceName, Node::Namespace));
     1636        namespasse = static_cast<NamespaceNode*>(parent->findNode(namespaceName, Node::Namespace));
    13941637    if (!namespasse) {
    13951638        namespasse = new NamespaceNode(parent, namespaceName);
     
    14571700            if (enume->items().isEmpty()) {
    14581701                strVal = "0";
    1459             } else {
     1702            }
     1703            else {
    14601704                QString last = enume->items().last().value();
    14611705                bool ok;
     
    14671711                        else
    14681712                            strVal = "0" + QString::number(n + 1, 8);
    1469                     } else {
     1713                    }
     1714                    else
    14701715                        strVal = QString::number(n + 1);
    1471                     }
    14721716                }
    14731717            }
     
    14751719
    14761720        enume->addItem(EnumItem(name, strVal));
    1477     } else {
     1721    }
     1722    else {
    14781723        VariableNode *var = new VariableNode(parent, name);
    14791724        var->setAccess(access);
     
    15631808        if (match(Tok_Ident)) {
    15641809            value = previousLexeme();
    1565         } else if (match(Tok_LeftParen)) {
     1810        }
     1811        else if (match(Tok_LeftParen)) {
    15661812            int depth = 1;
    15671813            while (tok != Tok_Eoi) {
     
    15821828        if (key == "READ")
    15831829            tre->addPropertyFunction(property, value, PropertyNode::Getter);
    1584         else if (key == "WRITE")
     1830        else if (key == "WRITE") {
    15851831            tre->addPropertyFunction(property, value, PropertyNode::Setter);
    1586         else if (key == "STORED")
     1832            property->setWritable(true);
     1833        } else if (key == "STORED")
    15871834            property->setStored(value.toLower() == "true");
    15881835        else if (key == "DESIGNABLE")
     
    15901837        else if (key == "RESET")
    15911838            tre->addPropertyFunction(property, value, PropertyNode::Resetter);
     1839        else if (key == "NOTIFY") {
     1840            tre->addPropertyFunction(property, value, PropertyNode::Notifier);
     1841        }
     1842
    15921843    }
    15931844    match(Tok_RightParen);
     
    17542005
    17552006            Doc::trimCStyleComment(start_loc,comment);
    1756             /*
    1757               qdoc --> doxygen
    1758               We must also remember the location of the end
    1759               of the comment, so we can construct a diff for
    1760               it.
    1761             */
    17622007            Location end_loc(location());
    17632008
     
    18222067                  There is a topic command. Process it.
    18232068                 */
     2069#ifdef QDOC_QML
     2070                if ((topic == COMMAND_QMLPROPERTY) ||
     2071                    (topic == COMMAND_QMLATTACHEDPROPERTY)) {
     2072                    Doc nodeDoc = doc;
     2073                    Node *node = processTopicCommandGroup(nodeDoc,topic,args);
     2074                    if (node != 0) {
     2075                        nodes.append(node);
     2076                        docs.append(nodeDoc);
     2077                    }
     2078                }
     2079                else {
     2080                    QStringList::ConstIterator a = args.begin();
     2081                    while (a != args.end()) {
     2082                        Doc nodeDoc = doc;
     2083                        Node *node = processTopicCommand(nodeDoc,topic,*a);
     2084                        if (node != 0) {
     2085                            nodes.append(node);
     2086                            docs.append(nodeDoc);
     2087                        }
     2088                        ++a;
     2089                    }
     2090                }
     2091#else
    18242092                QStringList::ConstIterator a = args.begin();
    18252093                while (a != args.end()) {
     
    18322100                    ++a;
    18332101                }
     2102#endif               
    18342103            }
    18352104
     
    18392108                processOtherMetaCommands(*d, *n);
    18402109                (*n)->setDoc(*d);
    1841                 if ((*n)->isInnerNode() && ((InnerNode *)*n)->includes().isEmpty()) {
     2110                if ((*n)->isInnerNode() &&
     2111                    ((InnerNode *)*n)->includes().isEmpty()) {
    18422112                    InnerNode *m = static_cast<InnerNode *>(*n);
    18432113                    while (m->parent() != tre->root())
     
    18872157                                     QStringList *parentPathPtr,
    18882158                                     FunctionNode **funcPtr,
    1889                                      InnerNode *root)
     2159                                     InnerNode *root,
     2160                                     Node::Type type,
     2161                                     bool attached)
    18902162{
    18912163    Tokenizer *outerTokenizer = tokenizer;
     
    18992171    readToken();
    19002172
    1901     bool ok = matchFunctionDecl(root, parentPathPtr, funcPtr);
     2173    bool ok = matchFunctionDecl(root, parentPathPtr, funcPtr, QString(), type, attached);
    19022174    // potential memory leak with funcPtr
    19032175
    19042176    tokenizer = outerTokenizer;
    19052177    tok = outerTok;
    1906 
    19072178    return ok;
     2179}
     2180
     2181/*!
     2182  Create a new FunctionNode for a QML method or signal, as
     2183  specified by \a type, as a child of \a parent. \a sig is
     2184  the complete signature, and if \a attached is true, the
     2185  method or signal is "attached". \a qdoctag is the text of
     2186  the \a type.
     2187 */
     2188FunctionNode* CppCodeParser::makeFunctionNode(const Doc& doc,
     2189                                              const QString& sig,
     2190                                              InnerNode* parent,
     2191                                              Node::Type type,
     2192                                              bool attached,
     2193                                              QString qdoctag)
     2194{
     2195    QStringList pp;
     2196    FunctionNode* fn = 0;
     2197    if (!makeFunctionNode(sig,&pp,&fn,parent,type,attached) &&
     2198        !makeFunctionNode("void "+sig,&pp,&fn,parent,type,attached)) {
     2199        doc.location().warning(tr("Invalid syntax in '\\%1'").arg(qdoctag));
     2200    }
     2201    if (fn)
     2202        return fn;
     2203    return 0;
    19082204}
    19092205
     
    19272223        associativeIteratorDefinition = lines[2];
    19282224        mutableAssociativeIteratorDefinition = lines[3];
    1929     } else {
     2225    }
     2226    else {
    19302227        location.warning(tr("The qiterator.h hack failed"));
    19312228    }
     
    19632260                                        proFileName,
    19642261                                        userFriendlyFilePath);
     2262   
    19652263    if (fullPath.isEmpty()) {
    19662264        QString tmp = proFileName;
     
    19822280    fullPath.truncate(fullPath.lastIndexOf('/'));
    19832281
    1984     QStringList exampleFiles = Config::getFilesHere(fullPath,
    1985                                                     exampleNameFilter);
     2282    QStringList exampleFiles = Config::getFilesHere(fullPath,exampleNameFilter);
     2283    QString imagesPath = fullPath + "/images";
     2284    QStringList imageFiles = Config::getFilesHere(imagesPath,exampleImageFilter);
     2285
     2286#if 0   
     2287    qDebug() << "examplePath:" << examplePath;
     2288    qDebug() << " exampleFiles" <<  exampleFiles;
     2289    qDebug() << "imagesPath:" << imagesPath;
     2290    qDebug() << "fullPath:" << fullPath;
     2291    qDebug() << " imageFiles" <<  imageFiles;
     2292#endif   
     2293
    19862294    if (!exampleFiles.isEmpty()) {
    19872295        // move main.cpp and to the end, if it exists
     
    20092317        (void) new FakeNode(fake,
    20102318                            exampleFile.mid(sizeOfBoringPartOfName),
    2011                             FakeNode::File);
     2319                            Node::File);
     2320    foreach (const QString &imageFile, imageFiles) {
     2321        new FakeNode(fake,
     2322                     imageFile.mid(sizeOfBoringPartOfName),
     2323                     Node::Image);
     2324    }
    20122325}
    20132326
  • trunk/tools/qdoc3/cppcodeparser.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    9191                                      const QString& command,
    9292                                      const QString& arg);
     93#ifdef QDOC_QML   
     94    // might need to implement this in QsCodeParser as well.
     95    virtual Node *processTopicCommandGroup(const Doc& doc,
     96                                           const QString& command,
     97                                           const QStringList& args);
     98    bool splitQmlPropertyArg(const Doc& doc,
     99                             const QString& arg,
     100                             QString& type,
     101                             QString& element,
     102                             QString& name);
     103    bool splitQmlMethodArg(const Doc& doc,
     104                           const QString& arg,
     105                           QString& type,
     106                           QString& element);
     107#endif
    93108    virtual QSet<QString> otherMetaCommands();
    94109    virtual void processOtherMetaCommand(const Doc& doc,
     
    113128                           QStringList *parentPathPtr = 0,
    114129                           FunctionNode **funcPtr = 0,
    115                            const QString &templateStuff = QString());
     130                           const QString &templateStuff = QString(),
     131                           Node::Type type = Node::Function,
     132                           bool attached = false);
    116133    bool matchBaseSpecifier(ClassNode *classe, bool isClass);
    117134    bool matchBaseList(ClassNode *classe, bool isClass);
     
    129146                          QStringList *parentPathPtr,
    130147                          FunctionNode **funcPtr,
    131                           InnerNode *root = 0);
     148                          InnerNode *root = 0,
     149                          Node::Type type = Node::Function,
     150                          bool attached = false);
     151    FunctionNode* makeFunctionNode(const Doc& doc,
     152                                   const QString& sig,
     153                                   InnerNode* parent,
     154                                   Node::Type type,
     155                                   bool attached,
     156                                   QString qdoctag);
    132157    void parseQiteratorDotH(const Location &location, const QString &filePath);
    133158    void instantiateIteratorMacro(const QString &container,
     
    161186    static QStringList exampleDirs;
    162187    QString exampleNameFilter;
     188    QString exampleImageFilter;
    163189};
    164190
  • trunk/tools/qdoc3/cpptoqsconverter.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/cpptoqsconverter.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/dcfsection.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/dcfsection.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/doc.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7474
    7575enum {
    76     CMD_A, CMD_ABSTRACT, CMD_BADCODE, CMD_BASENAME, CMD_BOLD,
    77     CMD_BRIEF, CMD_C, CMD_CAPTION, CMD_CHAPTER, CMD_CODE,
    78     CMD_CODELINE, CMD_DOTS, CMD_ELSE, CMD_ENDABSTRACT,
    79     CMD_ENDCHAPTER, CMD_ENDCODE, CMD_ENDFOOTNOTE, CMD_ENDIF,
    80     CMD_ENDLEGALESE, CMD_ENDLINK, CMD_ENDLIST, CMD_ENDOMIT,
    81     CMD_ENDPART, CMD_ENDQUOTATION, CMD_ENDRAW, CMD_ENDSECTION1,
    82     CMD_ENDSECTION2, CMD_ENDSECTION3, CMD_ENDSECTION4,
    83     CMD_ENDSIDEBAR, CMD_ENDTABLE, CMD_EXPIRE, CMD_FOOTNOTE,
    84     CMD_GENERATELIST, CMD_GRANULARITY, CMD_HEADER, CMD_I,
    85     CMD_IF, CMD_IMAGE, CMD_INCLUDE, CMD_INLINEIMAGE, CMD_INDEX,
    86     CMD_KEYWORD, CMD_L, CMD_LEGALESE, CMD_LINK, CMD_LIST,
    87     CMD_META, CMD_NEWCODE, CMD_O, CMD_OLDCODE, CMD_OMIT,
    88     CMD_OMITVALUE, CMD_OVERLOAD,
    89     CMD_PART, CMD_PRINTLINE, CMD_PRINTTO,
     76    CMD_A, CMD_ABSTRACT, CMD_ANNOTATEDLIST, CMD_BADCODE,
     77    CMD_BASENAME, CMD_BOLD, CMD_BRIEF, CMD_C, CMD_CAPTION,
     78    CMD_CHAPTER, CMD_CODE, CMD_CODELINE, CMD_DOTS, CMD_ELSE,
     79    CMD_ENDABSTRACT, CMD_ENDCHAPTER, CMD_ENDCODE,
     80    CMD_ENDFOOTNOTE, CMD_ENDIF, CMD_ENDLEGALESE, CMD_ENDLINK,
     81    CMD_ENDLIST, CMD_ENDOMIT, CMD_ENDPART, CMD_ENDQUOTATION,
     82    CMD_ENDRAW, CMD_ENDSECTION1, CMD_ENDSECTION2,
     83    CMD_ENDSECTION3, CMD_ENDSECTION4, CMD_ENDSIDEBAR,
     84    CMD_ENDTABLE, CMD_EXPIRE, CMD_FOOTNOTE, CMD_GENERATELIST,
     85    CMD_GRANULARITY, CMD_HEADER, CMD_I, CMD_IF, CMD_IMAGE,
     86    CMD_INCLUDE, CMD_INLINEIMAGE, CMD_INDEX, CMD_KEYWORD,
     87    CMD_L, CMD_LEGALESE, CMD_LINK, CMD_LIST, CMD_META,
     88    CMD_NEWCODE, CMD_O, CMD_OLDCODE, CMD_OMIT, CMD_OMITVALUE,
     89    CMD_OVERLOAD, CMD_PART, CMD_PRINTLINE, CMD_PRINTTO,
    9090    CMD_PRINTUNTIL, CMD_QUOTATION, CMD_QUOTEFILE,
    9191    CMD_QUOTEFROMFILE, CMD_QUOTEFUNCTION, CMD_RAW, CMD_ROW,
    9292    CMD_SA, CMD_SECTION1, CMD_SECTION2, CMD_SECTION3,
    93     CMD_SECTION4, CMD_SIDEBAR, CMD_SKIPLINE, CMD_SKIPTO,
    94     CMD_SKIPUNTIL, CMD_SNIPPET, CMD_SUB, CMD_SUP, CMD_TABLE,
    95     CMD_TABLEOFCONTENTS, CMD_TARGET, CMD_TT, CMD_UNDERLINE,
    96     CMD_UNICODE, CMD_VALUE, CMD_WARNING,
     93    CMD_SECTION4, CMD_SIDEBAR, CMD_SINCELIST, CMD_SKIPLINE,
     94    CMD_SKIPTO, CMD_SKIPUNTIL, CMD_SNIPPET, CMD_SUB, CMD_SUP,
     95    CMD_TABLE, CMD_TABLEOFCONTENTS, CMD_TARGET, CMD_TT,
     96    CMD_UNDERLINE, CMD_UNICODE, CMD_VALUE, CMD_WARNING,
    9797#ifdef QDOC_QML   
    9898    CMD_QML, CMD_ENDQML, CMD_CPP, CMD_ENDCPP, CMD_QMLTEXT,
     
    109109    { "a", CMD_A, 0 },
    110110    { "abstract", CMD_ABSTRACT, 0 },
     111    { "annotatedlist", CMD_ANNOTATEDLIST, 0 },
    111112    { "badcode", CMD_BADCODE, 0 },
    112113    { "basename", CMD_BASENAME, 0 }, // ### don't document for now
     
    177178    { "section4", CMD_SECTION4, 0 },
    178179    { "sidebar", CMD_SIDEBAR, 0 }, // ### don't document for now
     180    { "sincelist", CMD_SINCELIST, 0 },
    179181    { "skipline", CMD_SKIPLINE, 0 },
    180182    { "skipto", CMD_SKIPTO, 0 },
     
    516518                    case CMD_BADCODE:
    517519                        leavePara();
    518 #ifdef QDOC2DOX                       
    519                         if (DoxWriter::isDoxPass())
    520                             append(Atom::CodeBad,getUnmarkedCode(CMD_BADCODE));
    521                         else
    522                             append(Atom::CodeBad,getCode(CMD_BADCODE, marker));
    523 #else
    524520                        append(Atom::CodeBad,getCode(CMD_BADCODE, marker));
    525 #endif                       
    526521                        break;
    527522                    case CMD_BASENAME:
     
    539534                        enterPara();
    540535                        x = untabifyEtc(getArgument(true));
    541 #ifdef QDOC2DOX                       
    542                         if (DoxWriter::isDoxPass())
    543                             append(Atom::C, x);
    544                         else {
    545                             marker = CodeMarker::markerForCode(x);
    546                             append(Atom::C, marker->markedUpCode(x, 0, ""));
    547                         }
    548 #else
    549536                        marker = CodeMarker::markerForCode(x);
    550537                        append(Atom::C, marker->markedUpCode(x, 0, ""));
    551 #endif
    552538                        break;
    553539                    case CMD_CAPTION:
     
    560546                    case CMD_CODE:
    561547                        leavePara();
    562 #ifdef QDOC2DOX                       
    563                         if (DoxWriter::isDoxPass())
    564                             append(Atom::Code, getUnmarkedCode(CMD_CODE));
    565                         else
    566                             append(Atom::Code, getCode(CMD_CODE, marker));
    567 #else
    568548                        append(Atom::Code, getCode(CMD_CODE, marker));
    569 #endif
    570549                        break;
    571550#ifdef QDOC_QML       
     
    580559                    case CMD_CODELINE:
    581560                        {
    582 #ifdef QDOC2DOX                       
    583                             if (!quoting && !DoxWriter::isDoxPass()) {
    584                                 if (priv->text.lastAtom()->type() == Atom::Code
    585                                         && priv->text.lastAtom()->string().endsWith("\n\n"))
    586                                     priv->text.lastAtom()->chopString();
    587                                 appendToCode("\n");
    588                             } lse {
    589                                 append(Atom::CodeQuoteCommand, cmdStr);
    590                                 append(Atom::CodeQuoteArgument, " ");
    591                             }
    592 #else
    593561                            if (!quoting) {
    594562                                if (priv->text.lastAtom()->type() == Atom::Code
     
    601569                                append(Atom::CodeQuoteArgument, " ");
    602570                            }
    603 #endif
    604571                        }
    605572                        break;
    606573                    case CMD_DOTS:
    607574                        {
    608 #ifdef QDOC2DOX                       
    609                             if (DoxWriter::isDoxPass()) {
    610                                 append(Atom::CodeQuoteCommand, cmdStr);
    611                                 append(Atom::CodeQuoteArgument, "    ...");
    612                             }
    613                             else if (!quoting) {
     575                            if (!quoting) {
    614576                                if (priv->text.lastAtom()->type() == Atom::Code
    615577                                        && priv->text.lastAtom()->string().endsWith("\n\n"))
     
    631593                                append(Atom::CodeQuoteArgument, arg);
    632594                            }
    633 #else
    634                             if (!quoting) {
    635                                 if (priv->text.lastAtom()->type() == Atom::Code
    636                                         && priv->text.lastAtom()->string().endsWith("\n\n"))
    637                                     priv->text.lastAtom()->chopString();
    638 
    639                                 QString arg = getOptionalArgument();
    640                                 int indent = 4;
    641                                 if (!arg.isEmpty())
    642                                     indent = arg.toInt();
    643                                 for (int i = 0; i < indent; ++i)
    644                                     appendToCode(" ");
    645                                 appendToCode("...\n");
    646                             }
    647                             else {
    648                                 append(Atom::CodeQuoteCommand, cmdStr);
    649                                 QString arg = getOptionalArgument();
    650                                 if (arg.isEmpty())
    651                                     arg = "4";
    652                                 append(Atom::CodeQuoteArgument, arg);
    653                             }
    654 #endif
    655595                        }
    656596                        break;
     
    785725                            paraState = OutsidePara; // ###
    786726                        }
     727                        break;
     728                    case CMD_ANNOTATEDLIST:
     729                        append(Atom::AnnotatedList, getArgument());
     730                        break;
     731                    case CMD_SINCELIST:
     732                        append(Atom::SinceList, getArgument());
    787733                        break;
    788734                    case CMD_GENERATELIST:
     
    954900                    case CMD_OLDCODE:
    955901                        leavePara();
    956 #ifdef QDOC2DOX                       
    957                         if (DoxWriter::isDoxPass()) {
    958                             append(Atom::CodeOld, getUnmarkedCode(CMD_OLDCODE));
    959                             append(Atom::CodeNew, getUnmarkedCode(CMD_NEWCODE));
    960                         }
    961                         else {
    962                             append(Atom::CodeOld, getCode(CMD_OLDCODE, marker));
    963                             append(Atom::CodeNew, getCode(CMD_NEWCODE, marker));
    964                         }
    965 #else
    966902                        append(Atom::CodeOld, getCode(CMD_OLDCODE, marker));
    967903                        append(Atom::CodeNew, getCode(CMD_NEWCODE, marker));
    968 #endif
    969904                        break;
    970905                    case CMD_OMIT:
     
    11481083                            QString snippet = getArgument();
    11491084                            QString identifier = getRestOfLine();
    1150 #ifdef QDOC2DOX                       
    1151                             if (quoting || DoxWriter::isDoxPass()) {
    1152                                 append(Atom::SnippetCommand, cmdStr);
    1153                                 append(Atom::SnippetLocation, snippet);
    1154                                 append(Atom::SnippetIdentifier, identifier);
    1155                             }
    1156                             else {
    1157                                 Doc::quoteFromFile(location(),quoter,snippet);
    1158                                 appendToCode(quoter.quoteSnippet(location(),
    1159                                                                  identifier));
    1160                             }
    1161 #else
    11621085                            if (quoting) {
    11631086                                append(Atom::SnippetCommand, cmdStr);
     
    11701093                                                                 identifier));
    11711094                            }
    1172 #endif
    11731095                        }
    11741096                        break;
     
    12521174                        append(Atom::String, " ");
    12531175                        break;
    1254                     case CMD_OVERLOAD: // qdoc --> doxygen
     1176                    case CMD_OVERLOAD:
    12551177                        priv->metacommandsUsed.insert(cmdStr);
    12561178                        x.clear();
     
    12661188                        else {
    12671189                            append(Atom::ParaLeft);
    1268                             append(Atom::String,
    1269                                    "This is an overloaded member function, "
    1270                                    "provided for convenience.");
     1190                            append(Atom::String,"This is an overloaded function.");
    12711191                            append(Atom::ParaRight);
    12721192                            x = getMetaCommandArgument(cmdStr);
     
    17661686
    17671687    if (currentSectioningUnit == Doc::Book) {
     1688#if 0
     1689        // mws didn't think this was necessary.
    17681690        if (unit > Doc::Section1)
    17691691            location().warning(tr("Unexpected '\\%1' without '\\%2'")
    17701692                                .arg(cmdName(cmd))
    17711693                                .arg(cmdName(CMD_SECTION1)));
     1694#endif       
    17721695        currentSectioningUnit = (Doc::SectioningUnit) (unit - 1);
    17731696        priv->constructExtra();
     
    23462269
    23472270/*!
    2348   Used only for generating doxygen output.
     2271  Was used only for generating doxygen output.
    23492272 */
    23502273QString DocParser::getUnmarkedCode(int cmd)
     
    25822505#endif
    25832506
    2584 #ifdef QDOC2DOX                       
    2585 #define DOXYGEN_INDENT 2
    2586 #define DOXYGEN_TAB_SIZE 4
    2587 #define DOXYGEN_INDENT_STRING "  "
    2588 #define DOXYGEN_TAB_STRING "    "
    2589 
    2590 static QRegExp ws_rx("\\s");
    2591 static QRegExp not_ws_rx("\\S");
    2592 
    2593 int DoxWriter::doxPass = 0;
    2594 QString DoxWriter::currentClass;
    2595 QSet<QString> DoxWriter::anchors;
    2596 QStringMap DoxWriter::exampleTitles;
    2597 QStringMap DoxWriter::headerFileTitles;
    2598 QStringMap DoxWriter::fileTitles;
    2599 QStringMap DoxWriter::groupTitles;
    2600 QStringMap DoxWriter::moduleTitles;
    2601 QStringMap DoxWriter::pageTitles;
    2602 QStringMap DoxWriter::externalPageTitles;
    2603 QStringMap DoxWriter::exampleTitlesInverse;
    2604 QStringMap DoxWriter::headerFileTitlesInverse;
    2605 QStringMap DoxWriter::fileTitlesInverse;
    2606 QStringMap DoxWriter::groupTitlesInverse;
    2607 QStringMap DoxWriter::moduleTitlesInverse;
    2608 QStringMap DoxWriter::pageTitlesInverse;
    2609 QStringMap DoxWriter::externalPageTitlesInverse;
    2610 QStringMultiMap DoxWriter::variables;
    2611 QStringMultiMap DoxWriter::properties;
    2612 QStringMultiMap DoxWriter::enums;
    2613 #endif
    26142507
    26152508Doc::Doc(const Location& start_loc,
     
    26212514    DocParser parser;
    26222515    parser.parse(source,priv,metaCommandSet);
    2623 #ifdef QDOC2DOX                       
    2624     if (DoxWriter::isDoxPass()) {
    2625         DoxWriter doxWriter(source,priv);
    2626         if (DoxWriter::isDoxPass(1))
    2627             doxWriter.pass1();
    2628         else
    2629             doxWriter.pass2();
    2630     }
    2631 #endif
    26322516}
    26332517
     
    27582642
    27592643        /*
    2760             This code is really ugly. The entire \brief business
    2761             should be rethought.
     2644          This code is really ugly. The entire \brief business
     2645          should be rethought.
    27622646        */
    2763         while (atom && (atom->type() == Atom::AutoLink || atom->type() == Atom::String)) {
    2764             briefStr += atom->string();
     2647        while (atom) {
     2648            if (atom->type() == Atom::AutoLink || atom->type() == Atom::String) {
     2649                briefStr += atom->string();
     2650            }
    27652651            atom = atom->next();
    27662652        }
    27672653
    27682654        QStringList w = briefStr.split(" ");
    2769         if (!w.isEmpty() && w.first() == "The")
    2770             w.removeFirst();
     2655        if (!w.isEmpty() && w.first() == "Returns") {
     2656        }
    27712657        else {
    2772             location().warning(
    2773                 tr("Nonstandard wording in '\\%1' text for '%2' (expected 'The')")
    2774                 .arg(COMMAND_BRIEF).arg(className));
    2775             standardWording = false;
     2658            if (!w.isEmpty() && w.first() == "The")
     2659                w.removeFirst();
     2660            else {
     2661                location().warning(
     2662                  tr("Nonstandard wording in '\\%1' text for '%2' (expected 'The')")
     2663                  .arg(COMMAND_BRIEF).arg(className));
     2664                standardWording = false;
     2665            }
     2666
     2667            if (!w.isEmpty() && (w.first() == className || w.first() == classNameOnly))
     2668                w.removeFirst();
     2669            else {
     2670                location().warning(
     2671                  tr("Nonstandard wording in '\\%1' text for '%2' (expected '%3')")
     2672                  .arg(COMMAND_BRIEF).arg(className).arg(className));
     2673                standardWording = false;
     2674            }
     2675
     2676            if (!w.isEmpty() && ((w.first() == "class") ||
     2677                                 (w.first() == "function") ||
     2678                                 (w.first() == "macro") ||
     2679                                 (w.first() == "widget") ||
     2680                                 (w.first() == "namespace") ||
     2681                                 (w.first() == "header")))
     2682                w.removeFirst();
     2683            else {
     2684                location().warning(
     2685                  tr("Nonstandard wording in '\\%1' text for '%2' ("
     2686                     "expected 'class', 'function', 'macro', 'widget', "
     2687                     "'namespace' or 'header')")
     2688                  .arg(COMMAND_BRIEF).arg(className));
     2689                standardWording = false;
     2690            }
     2691
     2692            if (!w.isEmpty() && (w.first() == "is" || w.first() == "provides"))
     2693                w.removeFirst();
     2694
     2695            if (!w.isEmpty() && (w.first() == "a" || w.first() == "an"))
     2696                w.removeFirst();
    27762697        }
    27772698
    2778         if (!w.isEmpty() && (w.first() == className || w.first() == classNameOnly))
    2779             w.removeFirst();
    2780         else {
    2781             location().warning(
    2782                 tr("Nonstandard wording in '\\%1' text for '%2' (expected '%3')")
    2783                 .arg(COMMAND_BRIEF).arg(className).arg(className));
    2784             standardWording = false;
    2785         }
    2786 
    2787         if (!w.isEmpty() && (w.first() == "class" || w.first() == "widget"
    2788                              || w.first() == "namespace" || w.first() == "header"))
    2789             w.removeFirst();
    2790         else {
    2791             location().warning(
    2792                 tr("Nonstandard wording in '\\%1' text for '%2' ("
    2793                    "expected 'class', 'widget', 'namespace' or 'header')")
    2794                 .arg(COMMAND_BRIEF).arg(className));
    2795             standardWording = false;
    2796         }
    2797 
    2798         if (!w.isEmpty() && (w.first() == "is" || w.first() == "provides"))
    2799             w.removeFirst();
    2800 
    2801         if (!w.isEmpty() && (w.first() == "a" || w.first() == "an"))
    2802             w.removeFirst();
    2803 
    28042699        whats = w.join(" ");
     2700       
    28052701        if (whats.endsWith("."))
    28062702            whats.truncate(whats.length() - 1);
     
    29452841    DocParser::sourceDirs = config.getStringList(CONFIG_SOURCEDIRS);
    29462842    DocParser::quoting = config.getBool(CONFIG_QUOTINGINFORMATION);
     2843
     2844#ifdef QDOC_QML
     2845    QmlClassNode::qmlOnly = config.getBool(CONFIG_QMLONLY);
     2846#endif
    29472847
    29482848    QStringMap reverseAliasMap;
     
    31833083}
    31843084
    3185 #ifdef QDOC2DOX                       
    3186 /*!
    3187   Sets the doxygen writer pass to \a pass. You can use
    3188   isDoxPass(), with or without a parameter, to test if
    3189   you are in a doxygen writer run or in a specific pass
    3190   of a doxygen writer run.
    3191 
    3192   This function is only called from main() if either the
    3193   \e doxygen1 or \e doxygen2 flag is passed to qdoc3 on
    3194   the command line.
    3195  */
    3196 void DoxWriter::setDoxPass(int pass)
    3197 {
    3198     qDebug() << "SETTING doxygen pass to " << pass
    3199              << " in DoxWriter::setDoxPass()";
    3200     doxPass = pass;
    3201 }
    3202 
    3203 /*!
    3204   Returns true if the doxygen pass is set to \a pass,
    3205   which means we are in the specified \a pass of a doxygen
    3206   writer run of qdoc3.
    3207  */
    3208 bool DoxWriter::isDoxPass(int pass) { return (doxPass == pass); }
    3209 
    3210 /*!
    3211   Returns true if the doxygen pass is 1 or 2, which
    3212   means this is a doxygen writer run to transform qdoc
    3213   comments into doxygen comments.
    3214  */
    3215 bool DoxWriter::isDoxPass() { return (doxPass > 0); }
    3216 
    3217 bool DoxWriter::conversionRequired() const
    3218 {
    3219     /*
    3220       Loop through all the topic commands searching for
    3221       one that must be transformed to doxygen format. If
    3222       one is found, return true.
    3223      */
    3224     QCommandMap::const_iterator i;
    3225     i = priv->metaCommandMap.constBegin();
    3226     while (i != priv->metaCommandMap.constEnd()) {
    3227         QString s = i.key();
    3228         if (s == "enum")
    3229             return true;
    3230         else if (s == "example")
    3231             return true;
    3232         else if (s == "externalpage")
    3233             return true;
    3234         else if (s == "group")
    3235             return true;
    3236         else if (s == "headerfile")
    3237             return true;
    3238         else if (s == "module")
    3239             return true;
    3240         else if (s == "page")
    3241             return true;
    3242         else if (s == "property")
    3243             return true;
    3244         else if (s == "typedef")
    3245             return true;
    3246         else if (s == "variable")
    3247             return true;
    3248         else if (s == "overload")
    3249             return true;
    3250         else if (s == "reimp")
    3251             return true;
    3252         else if (s == "relates")
    3253             return true;
    3254         else if (s == "macro")
    3255             return true;
    3256         else {
    3257 #if 0           
    3258             if (s == "class")
    3259             else if (s == "namespace")
    3260             else if (s == "service")
    3261             else if (s == "inheaderfile")
    3262             else if (s == "file")
    3263             else if (s == "fn")
    3264             else if (s == "contentspage")
    3265             else if (s == "nextpage")
    3266             else if (s == "previous")
    3267             else if (s == "indexpage")
    3268             else if (s == "startpage")
    3269 #endif           
    3270         }
    3271         ++i;
    3272     }
    3273    
    3274     /*
    3275       Loop through all the qdoc atoms searching for one
    3276       that must be transformed to doxygen format. If one
    3277       is found, return true.
    3278      */
    3279     const Atom* next = priv->text.firstAtom();
    3280     while (next != 0) {
    3281         Atom::Type atomType = next->type();
    3282         switch (atomType) {
    3283             case Atom::C:
    3284             case Atom::CaptionLeft:
    3285             case Atom::Code:
    3286             case Atom::CodeBad:
    3287             case Atom::CodeNew:
    3288             case Atom::CodeOld:
    3289             case Atom::CodeQuoteArgument:
    3290             case Atom::CodeQuoteCommand:
    3291             case Atom::FootnoteLeft:
    3292             case Atom::FormatElse:
    3293             case Atom::FormatEndif:
    3294             case Atom::FormatIf:
    3295             case Atom::GeneratedList:
    3296             case Atom::Image:
    3297             case Atom::ImageText:
    3298             case Atom::InlineImage:
    3299             case Atom::LegaleseLeft:
    3300             case Atom::LineBreak:
    3301             case Atom::Link:
    3302             case Atom::LinkNode:
    3303             case Atom::ListLeft:
    3304             case Atom::ListItemNumber:
    3305             case Atom::ListTagLeft:
    3306             case Atom::ListItemLeft:
    3307             case Atom::QuotationLeft:
    3308             case Atom::RawString:
    3309             case Atom::SectionLeft:
    3310             case Atom::SectionHeadingLeft:
    3311             case Atom::SidebarLeft:
    3312             case Atom::SnippetCommand:
    3313             case Atom::SnippetIdentifier:
    3314             case Atom::SnippetLocation:
    3315             case Atom::TableLeft:
    3316             case Atom::TableHeaderLeft:
    3317             case Atom::TableRowLeft:
    3318             case Atom::TableItemLeft:
    3319             case Atom::TableOfContents:
    3320             case Atom::Target:
    3321                 return true;
    3322             case Atom::AbstractLeft:
    3323             case Atom::AbstractRight:
    3324             case Atom::AutoLink:
    3325             case Atom::BaseName:
    3326             case Atom::BriefLeft:
    3327             case Atom::BriefRight:
    3328             case Atom::CaptionRight:
    3329             case Atom::FormattingLeft:
    3330             case Atom::FormattingRight:
    3331             case Atom::Nop:
    3332             case Atom::ParaLeft:
    3333             case Atom::ParaRight:
    3334             case Atom::FootnoteRight:
    3335             case Atom::LegaleseRight:
    3336             case Atom::ListTagRight:
    3337             case Atom::ListItemRight:
    3338             case Atom::ListRight:
    3339             case Atom::QuotationRight:
    3340             case Atom::SectionRight:
    3341             case Atom::SectionHeadingRight:
    3342             case Atom::SidebarRight:
    3343             case Atom::String:
    3344             case Atom::TableRight:
    3345             case Atom::TableHeaderRight:
    3346             case Atom::TableRowRight:
    3347             case Atom::TableItemRight:
    3348             default:
    3349                 break;
    3350         }
    3351         next = next->next();
    3352     }
    3353     return false;
    3354 }
    3355 
    3356 /*!
    3357   A convenience function to write a qdoc metacommand as a
    3358   doxygen command, without conversion. i.e., some of the
    3359   qdoc metacommands don't require conversion for doxygen.
    3360  */
    3361 void DoxWriter::writeCommand(QCommandMap::const_iterator cmd)
    3362 {
    3363     concatenate("\\" + cmd.key() + " " + cmd.value()[0]);
    3364     newLine();
    3365 }
    3366 
    3367 /*!
    3368   Convert the qdoc commands in the metacommand map to
    3369   doxygen format. This function is called only in pass2().
    3370   The metacommand map contains all the metacommands that
    3371   were found in the qdoc comment that is being converted.
    3372   The metacommands are the ones that begin with the '\'.
    3373   These are not considered part of the text of the comment.
    3374   The text is converted by convertText().
    3375  */
    3376 void DoxWriter::convertMetaCommands()
    3377 {
    3378     QCommandMap& metaCmdMap = priv->metaCommandMap;
    3379     QCommandMap::iterator cmd;
    3380     int c;
    3381 
    3382     currentPage.clear();
    3383     currentFn.clear();
    3384     currentTitle.clear();
    3385     currentEnum.clear();
    3386     currentProperty.clear();
    3387     currentVariable.clear();
    3388     currentClass.clear();
    3389     currentExample.clear();
    3390     currentGroup.clear();
    3391     currentModule.clear();
    3392     currentMacro.clear();
    3393     currentService.clear();
    3394     currentTypedef.clear();
    3395     currentHeaderFile.clear();
    3396     commentType = OtherComment;
    3397 
    3398     if ((cmd = metaCmdMap.find("class")) != metaCmdMap.end()) {
    3399         currentClass = cmd.value()[0];
    3400         if ((c = currentClass.indexOf(' ')) > 0)
    3401             currentClass = currentClass.left(c);
    3402         writeCommand(cmd);
    3403         metaCmdMap.erase(cmd);
    3404         commentType = ClassComment;
    3405     }
    3406     else if ((cmd = metaCmdMap.find("fn")) != metaCmdMap.end()) {
    3407         currentFn = cmd.value()[0];
    3408         writeCommand(cmd);
    3409         metaCmdMap.erase(cmd);
    3410         commentType = FnComment;
    3411     }
    3412     else if ((cmd = metaCmdMap.find("enum")) != metaCmdMap.end()) {
    3413         currentEnum = cmd.value()[0];
    3414         if ((c = currentEnum.lastIndexOf("::")) > 0) {
    3415             currentClass = currentEnum.left(c);
    3416             currentEnum = currentEnum.right(currentEnum.size()-c-2);
    3417             qDebug() << "currentEnum =" << currentEnum;
    3418             qDebug() << "currentClass =" << currentClass;
    3419         }
    3420         writeCommand(cmd);
    3421         metaCmdMap.erase(cmd);
    3422         commentType = EnumComment;
    3423     }
    3424     else if ((cmd = metaCmdMap.find("property")) != metaCmdMap.end()) {
    3425         currentClass = cmd.value()[0];
    3426         if ((c = currentClass.lastIndexOf("::")) > 0) {
    3427             currentProperty = currentClass.right(currentClass.size()-c-2);
    3428             currentClass = currentClass.left(c);
    3429             qDebug() << "currentProperty =" << currentProperty;
    3430             qDebug() << "currentClass =" << currentClass;
    3431         }
    3432         writeCommand(cmd);
    3433         metaCmdMap.erase(cmd);
    3434         commentType = PropertyComment;
    3435     }
    3436     else if ((cmd = metaCmdMap.find("variable")) != metaCmdMap.end()) {
    3437         currentClass = cmd.value()[0];
    3438         if ((c = currentClass.lastIndexOf("::")) > 0) {
    3439             currentVariable = currentClass.right(currentClass.size()-c-2);
    3440             currentClass = currentClass.left(c);
    3441             qDebug() << "currentVariable =" << currentVariable;
    3442             qDebug() << "currentClass =" << currentClass;
    3443         }
    3444         concatenate("\\var " + cmd.value()[0]);
    3445         newLine();
    3446         metaCmdMap.erase(cmd);
    3447         commentType = VariableComment;
    3448     }
    3449 
    3450     if ((cmd = metaCmdMap.find("page")) != metaCmdMap.end()) {
    3451         currentPage = cmd.value()[0];
    3452         QString htmlFile = currentPage;
    3453         const QString* title = getPageTitle(htmlFile);
    3454         QStringList parts = htmlFile.split('.');
    3455         metaCmdMap.erase(cmd);
    3456         if (title) {
    3457             concatenate("\\page " + parts[0] + " " + *title);
    3458             newLine();
    3459         }
    3460         commentType = PageComment;
    3461         qDebug() << "currentPage =" << currentPage;
    3462     }
    3463 
    3464     if ((cmd = metaCmdMap.find("example")) != metaCmdMap.end()) {
    3465         currentExample = cmd.value()[0];
    3466         metaCmdMap.erase(cmd);
    3467         commentType = ExampleComment;
    3468         qDebug() << "currentExample =" << currentExample;
    3469     }
    3470    
    3471     if ((cmd = metaCmdMap.find("macro")) != metaCmdMap.end()) {
    3472         currentMacro = cmd.value()[0];
    3473         metaCmdMap.erase(cmd);
    3474         commentType = MacroComment;
    3475         qDebug() << "currentMacro =" << currentMacro;
    3476     }
    3477    
    3478     if ((cmd = metaCmdMap.find("group")) != metaCmdMap.end()) {
    3479         currentGroup = cmd.value()[0];
    3480         metaCmdMap.erase(cmd);
    3481         commentType = GroupComment;
    3482         qDebug() << "currentGroup =" << currentGroup;
    3483     }
    3484    
    3485     if ((cmd = metaCmdMap.find("module")) != metaCmdMap.end()) {
    3486         currentModule = cmd.value()[0];
    3487         metaCmdMap.erase(cmd);
    3488         commentType = ModuleComment;
    3489         qDebug() << "currentModule =" << currentModule;
    3490     }
    3491    
    3492     if ((cmd = metaCmdMap.find("headerfile")) != metaCmdMap.end()) {
    3493         currentHeaderFile = cmd.value()[0];
    3494         metaCmdMap.erase(cmd);
    3495         commentType = HeaderFileComment;
    3496         qDebug() << "currentHeaderFile =" << currentHeaderFile;
    3497     }
    3498 
    3499     if ((cmd = metaCmdMap.find("typedef")) != metaCmdMap.end()) {
    3500         currentClass = cmd.value()[0];
    3501         if ((c = currentClass.lastIndexOf("::")) > 0) {
    3502             currentTypedef = currentClass.right(currentClass.size()-c-2);
    3503             currentClass = currentClass.left(c);
    3504         }
    3505         metaCmdMap.erase(cmd);
    3506         commentType = TypedefComment;
    3507         qDebug() << "currentTypedef =" << currentTypedef;
    3508         qDebug() << "currentClass =" << currentClass;
    3509     }
    3510    
    3511     cmd = priv->metaCommandMap.begin();
    3512     while (cmd != priv->metaCommandMap.end()) {
    3513         for (int i=0; i<cmd.value().size(); i++) {
    3514             concatenate("\\" + cmd.key() + " " + cmd.value()[i]);
    3515             newLine();
    3516         }
    3517         //qDebug() << "   " << cmd.key() << ": " << cmd.value();
    3518         ++cmd;
    3519     }
    3520 }
    3521 
    3522 /*!
    3523   Convert the qdoc text to doxygen format. The metacommands
    3524   are converted by convertMetaCommands(). This function is
    3525   called in pass2().
    3526  */
    3527 void DoxWriter::convertText()
    3528 {
    3529     const Atom* prev = 0;
    3530     const Atom* next = priv->text.firstAtom();
    3531     while (next != 0) {
    3532         next->dump();
    3533         Atom::Type atomType = next->type();
    3534         switch (atomType) {
    3535             case Atom::AbstractLeft:
    3536                 break;
    3537             case Atom::AbstractRight:
    3538                 break;
    3539             case Atom::AutoLink:
    3540                 concatenate(next->string());
    3541                 break;
    3542             case Atom::BaseName:
    3543                 break;
    3544             case Atom::BriefLeft:
    3545                 concatenate("\\brief ");
    3546                 break;
    3547             case Atom::BriefRight:
    3548                 newLine();
    3549                 break;
    3550             case Atom::C:
    3551                 tt(next);
    3552                 break;
    3553             case Atom::CaptionLeft:
    3554                 unhandled(next);
    3555                 break;
    3556             case Atom::CaptionRight:
    3557                 unhandled(next);
    3558                 break;
    3559             case Atom::Code:
    3560                 code(next);
    3561                 break;
    3562             case Atom::CodeBad:
    3563                 code(next);
    3564                 break;
    3565             case Atom::CodeNew:
    3566                 newLine();
    3567                 concatenate("you can rewrite it as");
    3568                 code(next);
    3569                 break;
    3570             case Atom::CodeOld:
    3571                 newLine();
    3572                 concatenate("For example, if you have code like");
    3573                 code(next);
    3574                 break;
    3575             case Atom::CodeQuoteArgument:
    3576                 unhandled(next);
    3577                 break;
    3578             case Atom::CodeQuoteCommand:
    3579                 next = codeQuoteCommand(next);
    3580                 break;
    3581             case Atom::FootnoteLeft:
    3582                 break;
    3583             case Atom::FootnoteRight:
    3584                 break;
    3585             case Atom::FormatElse:
    3586                 formatElse();
    3587                 break;
    3588             case Atom::FormatEndif:
    3589                 formatEndif();
    3590                 break;
    3591             case Atom::FormatIf:
    3592                 formatIf(next);
    3593                 break;
    3594             case Atom::FormattingLeft:
    3595                 formattingLeft(next,next->next());
    3596                 break;
    3597             case Atom::FormattingRight:
    3598                 formattingRight(next,prev);
    3599                 break;
    3600             case Atom::GeneratedList:
    3601                 break;
    3602             case Atom::Image:
    3603                 break;
    3604             case Atom::ImageText:
    3605                 break;
    3606             case Atom::InlineImage:
    3607                 break;
    3608             case Atom::LegaleseLeft:
    3609                 break;
    3610             case Atom::LegaleseRight:
    3611                 break;
    3612             case Atom::LineBreak:
    3613                 break;
    3614             case Atom::Link:
    3615                 next = link(next);
    3616                 break;
    3617             case Atom::LinkNode:
    3618                 break;
    3619             case Atom::ListLeft:
    3620                 {
    3621                     bool nested = false;
    3622                     if (structs.isEmpty()) {
    3623                         const Atom* i = next->next();
    3624                         while (i->type() != Atom::ListRight) {
    3625                             if ((i->type() == Atom::ListLeft) ||
    3626                                 (i->type() == Atom::TableLeft)) {
    3627                                 nested = true;
    3628                                 break;
    3629                             }
    3630                             i = i->next();
    3631                         }
    3632                     }
    3633                     else
    3634                         nested = true;
    3635                     StructDesc d(BulletList,nested);
    3636                     if (next->string() == "numeric")
    3637                         d.structType = NumericList;
    3638                     else if (next->string() == "value") {
    3639                         d.structType = ValueList;
    3640                     }
    3641                     else if (next->string() != "bullet")
    3642                         qDebug() << "UNKNOWN LIST TYPE" << next->string();
    3643                     structs.push(d);
    3644                     if (nested || (d.structType != BulletList)) {
    3645                         if (d.structType == BulletList)
    3646                             concatenate("<ul>");
    3647                         else if (d.structType == NumericList)
    3648                             concatenate("<ol>");
    3649                         else if (d.structType == ValueList)
    3650                             concatenate("<dl>");
    3651                         newLine();
    3652                     }
    3653                 }
    3654                 break;
    3655             case Atom::ListItemNumber:
    3656                 structs.top().count = next->string().toInt();
    3657                 break;
    3658             case Atom::ListTagLeft:
    3659                 {
    3660                     structs.top().count++;
    3661                     concatenate("<dt>");
    3662                     const Atom* n = next->next();
    3663                     if (n->type() == Atom::String) {
    3664                         qDebug() << "ENUM VALUE" << n->string();
    3665                     }
    3666                     else
    3667                         qDebug() << "NOT EN ENUM";
    3668                 }
    3669                 break;
    3670             case Atom::ListTagRight:
    3671                 concatenate("</dt>");
    3672                 break;
    3673             case Atom::ListItemLeft:
    3674                 {
    3675                     newLine();
    3676                     const StructDesc& d = structs.top();
    3677                     if (d.structType == BulletList) {
    3678                         if (!d.nested)
    3679                             concatenate("\\arg ");
    3680                         else
    3681                             concatenate("<li>");
    3682                     }
    3683                     else if (d.structType == NumericList)
    3684                         concatenate("<li>");
    3685                     else if (d.structType == ValueList)
    3686                         concatenate("<dd>");
    3687                 }
    3688                 break;
    3689             case Atom::ListItemRight:
    3690                 {
    3691                     const StructDesc& d = structs.top();
    3692                     if (d.structType == BulletList) {
    3693                         if (d.nested) {
    3694                             concatenate("</li>");
    3695                             newLine();
    3696                         }
    3697                     }
    3698                     else if (d.structType == NumericList) {
    3699                         concatenate("</li>");
    3700                         newLine();
    3701                     }
    3702                     else if (d.structType == ValueList) {
    3703                         concatenate("</dd>");
    3704                         newLine();
    3705                     }
    3706                 }
    3707                 break;
    3708             case Atom::ListRight:
    3709                 {
    3710                     if (!structs.isEmpty()) {
    3711                         const StructDesc& d = structs.top();
    3712                         if (d.nested || (d.structType != BulletList)) {
    3713                             if (d.structType == BulletList)
    3714                                 concatenate("</ul>");
    3715                             else if (d.structType == NumericList)
    3716                                 concatenate("</ol>");
    3717                             else if (d.structType == ValueList)
    3718                                 concatenate("</dl>");
    3719                             newLine();
    3720                         }
    3721                         structs.pop();
    3722                     }
    3723                 }
    3724                 break;
    3725             case Atom::Nop:
    3726                 // nothing.
    3727                 break;
    3728             case Atom::ParaLeft:
    3729                 if (structs.isEmpty())
    3730                     newLine();
    3731                 break;
    3732             case Atom::ParaRight:
    3733                 {
    3734                     if (structs.isEmpty())
    3735                         newLine();
    3736                     else {
    3737                         const StructDesc& d = structs.top();
    3738                         if (d.nested || (d.structType != BulletList)) {
    3739                             Atom::Type t = next->next()->type();
    3740                             if ((t != Atom::ListItemRight) &&
    3741                                 (t != Atom::TableItemRight))
    3742                                 newLine();
    3743                         }
    3744                         else
    3745                             newLine();
    3746                     }
    3747                 }
    3748                 break;
    3749             case Atom::QuotationLeft:
    3750                 break;
    3751             case Atom::QuotationRight:
    3752                 break;
    3753             case Atom::RawString:
    3754                 concatenate(next->string());
    3755                 break;
    3756             case Atom::SectionLeft:
    3757                 // nothing.
    3758                 break;
    3759             case Atom::SectionRight:
    3760                 // nothing.
    3761                 break;
    3762             case Atom::SectionHeadingLeft:
    3763                 next = sectionHeading(next);
    3764                 break;
    3765             case Atom::SectionHeadingRight:
    3766                 newLine();
    3767                 break;
    3768             case Atom::SidebarLeft:
    3769                 break;
    3770             case Atom::SidebarRight:
    3771                 break;
    3772             case Atom::SnippetCommand:
    3773                 newLine();
    3774                 concatenate("\\snippet ");
    3775                 break;
    3776             case Atom::SnippetIdentifier:
    3777                 newText += next->string();
    3778                 lineLength += next->string().size();
    3779                 newLine();
    3780                 break;
    3781             case Atom::SnippetLocation:
    3782                 newText += next->string() + " ";
    3783                 lineLength += next->string().size() + 1;
    3784                 break;
    3785             case Atom::String:
    3786                 wrap(next->string());
    3787                 break;
    3788             case Atom::TableLeft:
    3789                 {
    3790                     bool nested = false;
    3791                     if (structs.isEmpty()) {
    3792                         const Atom* i = next->next();
    3793                         while (i->type() != Atom::TableRight) {
    3794                             if ((i->type() == Atom::ListLeft) ||
    3795                                 (i->type() == Atom::TableLeft)) {
    3796                                 nested = true;
    3797                                 break;
    3798                             }
    3799                             i = i->next();
    3800                         }
    3801                     }
    3802                     else
    3803                         nested = true;
    3804                     StructDesc d(Table,nested);
    3805                     structs.push(d);
    3806                     if (next->string().isEmpty())
    3807                         concatenate("<table>");
    3808                     else {
    3809                         QString attrs = "width=\"" + next->string() + "\"";
    3810                         attrs += " align=\"center\"";
    3811                         concatenate("<table " + attrs + ">");
    3812                     }
    3813                     newLine();
    3814                 }
    3815                 break;
    3816             case Atom::TableRight:
    3817                 concatenate("</table>");
    3818                 if (!structs.isEmpty())
    3819                     structs.pop();
    3820                 newLine();
    3821                 break;
    3822             case Atom::TableHeaderLeft:
    3823                 concatenate("<tr>");
    3824                 if (!structs.isEmpty())
    3825                     structs.top().inTableHeader = true;
    3826                 newLine();
    3827                 break;
    3828             case Atom::TableHeaderRight:
    3829                 concatenate("</tr>");
    3830                 if (!structs.isEmpty())
    3831                     structs.top().inTableHeader = false;
    3832                 newLine();
    3833                 break;
    3834             case Atom::TableRowLeft:
    3835                 if (!structs.isEmpty()) {
    3836                     structs.top().inTableRow = true;
    3837                     concatenate("<tr valign=\"top\" class=\"");
    3838                     if (structs.top().odd)
    3839                         concatenate("odd\">");
    3840                     else
    3841                         concatenate("even\">");
    3842                     structs.top().odd = !structs.top().odd;
    3843                 }
    3844                 newLine();
    3845                 break;
    3846             case Atom::TableRowRight:
    3847                 concatenate("</tr>");
    3848                 if (!structs.isEmpty())
    3849                     structs.top().inTableRow = false;
    3850                 newLine();
    3851                 break;
    3852             case Atom::TableItemLeft:
    3853                 if (!structs.isEmpty()) {
    3854                     structs.top().inTableItem = true;
    3855                     concatenate("<td>");
    3856                     if (structs.top().inTableHeader)
    3857                         concatenate("<b> ");
    3858                 }
    3859                 break;
    3860             case Atom::TableItemRight:
    3861                 if (!structs.isEmpty()) {
    3862                     structs.top().inTableItem = false;
    3863                     if (structs.top().inTableHeader)
    3864                         concatenate(" </b>");
    3865                     concatenate("</td>");
    3866                 }
    3867                 newLine();
    3868                 break;
    3869             case Atom::TableOfContents:
    3870                 break;
    3871             case Atom::Target:
    3872                 {
    3873                     QString text = next->string();
    3874                     text.remove(ws_rx);
    3875                     newLine();
    3876                     concatenate("\\anchor ");
    3877                     newText += text;
    3878                     lineLength += text.size();
    3879                     newLine();
    3880                 }
    3881                 break;
    3882             case Atom::UnhandledFormat:
    3883                 unhandled(next);
    3884                 break;
    3885             case Atom::UnknownCommand:
    3886                 unhandled(next);
    3887                 break;
    3888             default:
    3889                 //next->dump();
    3890                 break;
    3891         }
    3892         prev = next;
    3893         next = next->next();
    3894     }
    3895 }
    3896 
    3897 /*!
    3898  
    3899   Pass one looks for topic commands and target and section
    3900   commands, and maybe other stuff. These are serialized to
    3901   text files, which are read back in by pass2().
    3902  */
    3903 void DoxWriter::pass1()
    3904 {
    3905     QCommandMap& metaCmdMap = priv->metaCommandMap;
    3906     if (!metaCmdMap.isEmpty()) {
    3907         int c;
    3908         QCommandMap::iterator cmd;
    3909         if ((cmd = metaCmdMap.find("enum")) != metaCmdMap.end()) {
    3910             commentType = EnumComment;
    3911             currentEnum = cmd.value()[0];
    3912             if ((c = currentEnum.lastIndexOf("::")) > 0) {
    3913                 currentClass = currentEnum.left(c);
    3914                 currentEnum = currentEnum.right(currentEnum.size()-c-2);
    3915                 qDebug() << "currentEnum =" << currentEnum;
    3916                 qDebug() << "currentClass =" << currentClass;
    3917                 if (enums.contains(currentEnum,currentClass)) {
    3918                     qWarning() << "DoxWriter::pass1():"
    3919                                << "Duplicate enum:"
    3920                                << currentClass << currentEnum;
    3921                 }
    3922                 else
    3923                     enums.insert(currentEnum,currentClass);
    3924             }
    3925         }
    3926         else if ((cmd = metaCmdMap.find("property")) != metaCmdMap.end()) {
    3927             commentType = PropertyComment;
    3928             currentClass = cmd.value()[0];
    3929             if ((c = currentClass.lastIndexOf("::")) > 0) {
    3930                 currentProperty = currentClass.right(currentClass.size()-c-2);
    3931                 currentClass = currentClass.left(c);
    3932                 qDebug() << "currentProperty =" << currentProperty;
    3933                 qDebug() << "currentClass =" << currentClass;
    3934                 if (properties.contains(currentProperty,currentClass)) {
    3935                     qWarning() << "DoxWriter::pass1():"
    3936                                << "Duplicate property:"
    3937                                << currentClass << currentProperty;
    3938                 }
    3939                 else
    3940                     properties.insert(currentProperty,currentClass);
    3941             }
    3942         }
    3943         else if ((cmd = metaCmdMap.find("variable")) != metaCmdMap.end()) {
    3944             commentType = VariableComment;
    3945             currentClass = cmd.value()[0];
    3946             if ((c = currentClass.lastIndexOf("::")) > 0) {
    3947                 currentVariable = currentClass.right(currentClass.size()-c-2);
    3948                 currentClass = currentClass.left(c);
    3949                 qDebug() << "currentVariable =" << currentVariable;
    3950                 qDebug() << "currentClass =" << currentClass;
    3951                 if (variables.contains(currentVariable,currentClass)) {
    3952                     qWarning() << "DoxWriter::pass1():"
    3953                                << "Duplicate variable:"
    3954                                << currentClass << currentVariable;
    3955                 }
    3956                 else
    3957                     variables.insert(currentVariable,currentClass);
    3958             }
    3959         }
    3960     }
    3961 
    3962     /*
    3963      */
    3964     const Atom* next = priv->text.firstAtom();
    3965     while (next != 0) {
    3966         switch (next->type()) {
    3967             case Atom::SectionHeadingLeft:
    3968                 {
    3969                     QString text;
    3970                     next = next->next();
    3971                     while (next) {
    3972                         if (next->type() == Atom::SectionHeadingRight)
    3973                             break;
    3974                         else
    3975                             text += next->string();
    3976                         next = next->next();
    3977                     }
    3978                     //text.remove(ws_rx);
    3979                     insertAnchor(text);
    3980                 }
    3981                 break;
    3982             case Atom::Target:
    3983                 {
    3984                     QString text = next->string();
    3985                     //text.remove(ws_rx);
    3986                     insertAnchor(text);
    3987                 }
    3988             default:
    3989                 break;
    3990         }
    3991         next = next->next();
    3992     }
    3993 }
    3994 
    3995 /*!
    3996   Output a parsed, tokenized qdoc comment as a doxygen
    3997   comment in diff format for input to the patch command.
    3998  */
    3999 void DoxWriter::pass2()
    4000 {
    4001     if (!conversionRequired()) {
    4002         qDebug() << "NO CONVERSION - FILE:" << priv->start_loc.fileName()
    4003                  << "START:" << priv->start_loc.lineNo()
    4004                  << "END:" << priv->end_loc.lineNo() - 1;
    4005         return;
    4006     }
    4007 
    4008     /*
    4009       Transformation to doxygen required...
    4010      */
    4011     newText = "\n/*! \n";
    4012     convertMetaCommands();
    4013     convertText();
    4014     if (newText[newText.size()-1] == ' ')
    4015         newText.remove(newText.size()-1,1);
    4016     newText += " */\n";
    4017     qDebug() << "CONVERTED COMMENT - FILE:" << priv->start_loc.fileName()
    4018              << "START:" << priv->start_loc.lineNo()
    4019              << "END:" << priv->end_loc.lineNo() - 1;
    4020     qDebug() << newText;
    4021 }
    4022 
    4023 /*!
    4024   Unparse the second parameter of a "\l" command.
    4025  */
    4026 const Atom* DoxWriter::link(const Atom* atom)
    4027 {
    4028     QString first_text = atom->string();
    4029     QString second_text;
    4030     const QString* value = 0;
    4031 
    4032     const Atom* next = atom->next(Atom::FormattingLeft,Atom::LINK_);
    4033     if (next) {
    4034         next->dump();
    4035         while (1) {
    4036             next = next->next();
    4037             next->dump();
    4038             if (next->type() == Atom::FormattingRight) {
    4039                 if (next->string() == Atom::LINK_)
    4040                     break;
    4041                 else {
    4042                     // ignore it.
    4043                 }
    4044             }
    4045             else
    4046                 second_text += next->string();
    4047         }
    4048         int i = first_text.indexOf('#');
    4049         if (i >= 0)
    4050             first_text = first_text.right(first_text.size() - i - 1);
    4051         //newLine();
    4052         if ((value = getExternalPage(first_text))) {
    4053             //qDebug() << "USED AN EXTERNAL PAGE TITLE" << first_text;
    4054             QString href = "<a href=\""+*value+"\">"+first_text+"</a>";
    4055             concatenate(href);
    4056         }
    4057         else if (first_text.startsWith("http:",Qt::CaseInsensitive)) {
    4058             if (first_text == second_text) {
    4059                 concatenate(first_text);
    4060             }
    4061             else {
    4062                 QString href = "<a href=\""+first_text+"\">"+second_text+"</a>";
    4063                 concatenate(href);
    4064             }
    4065         }
    4066         else if ((value = getPageFile(first_text))) {
    4067             //qDebug() << "USED A PAGE TITLE" << first_text;
    4068             QStringList parts = (*value).split('.');
    4069             QString ref = "\\ref " + parts[0] + " \"" + second_text + "\"";
    4070             concatenate(ref);
    4071         }
    4072         else if ((value = getGroup(first_text))) {
    4073             //qDebug() << "USED A GROUP TITLE" << first_text;
    4074             concatenate("\\ref " + *value + " \"" + second_text + "\"");
    4075         }
    4076         else if ((value = getModule(first_text))) {
    4077             //qDebug() << "USED A MODULE TITLE" << first_text;
    4078             concatenate("\\ref " + *value + " \"" + second_text + "\"");
    4079         }
    4080         else if ((value = getExamplePath(first_text))) {
    4081             //qDebug() << "USED AN EXAMPLE TITLE" << first_text;
    4082             first_text.remove(ws_rx);
    4083             QString ref = "\\ref " + first_text + " \"" + second_text + "\"";
    4084             concatenate(ref);
    4085         }
    4086         else if ((value = getFile(first_text))) {
    4087             //qDebug() << "USED A FILE TITLE" << first_text;
    4088             // I think this command is no longer available.
    4089             first_text.remove(ws_rx);
    4090             QString ref = "\\ref " + first_text + " \"" + second_text + "\"";
    4091             concatenate(ref);
    4092         }
    4093         else if ((value = getHeaderFile(first_text))) {
    4094             //qDebug() << "USED A HEADER FILE TITLE" << first_text;
    4095             first_text.remove(ws_rx);
    4096             QString ref = "\\ref " + first_text + " \"" + second_text + "\"";
    4097             concatenate(ref);
    4098         }
    4099         else if (isAnchor(first_text)) {
    4100             //qDebug() << "USED AN ANCHOR" << first_text;
    4101             first_text.remove(ws_rx);
    4102             QString ref = "\\ref " + first_text + " \"" + second_text + "\"";
    4103             concatenate(ref);
    4104         }
    4105         else if ((value = getPageTitle(first_text))) {
    4106             //qDebug() << "USED AN INVERSE PAGE TITLE" << first_text;
    4107             QStringList parts = first_text.split('.');
    4108             QString ref = "\\ref " + parts[0] + " \"" + second_text + "\"";
    4109             concatenate(ref);
    4110         }
    4111         else if ((value = getExampleTitle(first_text))) {
    4112             //qDebug() << "USED AN INVERSE EXAMPLE TITLE" << first_text;
    4113             QString title = *value;
    4114             title.remove(ws_rx);
    4115             QString ref = "\\ref " + title  + " \"" + second_text + "\"";
    4116             concatenate(ref);
    4117         }
    4118         else if ((value = getGroupTitle(first_text))) {
    4119             //qDebug() << "USED AN INVERSE GROUP TITLE" << first_text;
    4120             concatenate("\\ref " + first_text + " \"" + second_text + "\"");
    4121         }
    4122         else if ((value = getModuleTitle(first_text))) {
    4123             //qDebug() << "USED AN INVERSE MODULE TITLE" << first_text;
    4124             concatenate("\\ref " + first_text + " \"" + second_text + "\"");
    4125         }
    4126         else if ((value = getFileTitle(first_text))) {
    4127             qDebug() << "USED AN INVERSE FILE TITLE" << first_text;
    4128         }
    4129         else if ((value = getHeaderFileTitle(first_text))) {
    4130             qDebug() << "USED AN INVERSE HEADER FILE TITLE" << first_text;
    4131         }
    4132         else if ((first_text.indexOf("::") >= 0) ||
    4133                  (first_text.indexOf("()") >= 0) ||
    4134                  (first_text[0] == 'Q')) {
    4135             //qDebug() << "AUTO-LINKABLE" << first_text;
    4136             if (first_text == second_text)
    4137                 concatenate(first_text);
    4138             else {
    4139                 QString link = first_text + " " + second_text;
    4140                 concatenate("\\link " + link + "\\endlink");
    4141             }
    4142         }
    4143         else {
    4144             QString link;
    4145             QStringList propertyClasses;
    4146             QStringList variableClasses;
    4147             QStringList enumClasses;
    4148             bool p = isProperty(first_text,propertyClasses);
    4149             bool v = isVariable(first_text,variableClasses);
    4150             bool e = isEnum(first_text,enumClasses);
    4151             if (e) {
    4152                 if (enumClasses.size() == 1)
    4153                     link = enumClasses[0];
    4154                 else if (enumClasses.contains(currentClass))
    4155                     link = currentClass;
    4156                 else {
    4157                     QString msg = "Unqualified enum name: " + first_text;
    4158                     QString details = "Classes: " + enumClasses.join(", ");
    4159                     priv->start_loc.error(msg,details);
    4160                 }
    4161                 if (!link.isEmpty())
    4162                     qDebug() << "FOUND ENUM" << link << first_text;
    4163             }
    4164             else if (p && v) {
    4165                 if (propertyClasses.size() == 1) {
    4166                     if (variableClasses.size() == 1) {
    4167                         if (propertyClasses[0] == variableClasses[0])
    4168                             link = propertyClasses[0];
    4169                     }
    4170                 }
    4171                 if (link.isEmpty()) {
    4172                     if (propertyClasses.contains(currentClass) ||
    4173                         variableClasses.contains(currentClass))
    4174                         link = currentClass;
    4175                     else {
    4176                         propertyClasses += variableClasses;
    4177                         QString msg = "Unqualified property or variable name: "
    4178                             + first_text;
    4179                         QString details = "Classes: " +
    4180                             propertyClasses.join(", ");
    4181                         priv->start_loc.error(msg,details);
    4182                     }
    4183                 }
    4184             }
    4185             else if (p) {
    4186                 if (propertyClasses.size() == 1)
    4187                     link = propertyClasses[0];
    4188                 else if (propertyClasses.contains(currentClass))
    4189                     link = currentClass;
    4190                 else {
    4191                     QString msg = "Unqualified property name: " + first_text;
    4192                     QString details = "Classes: " + propertyClasses.join(", ");
    4193                     priv->start_loc.error(msg,details);
    4194                 }
    4195             }
    4196             else if (v) {
    4197                 if (variableClasses.size() == 1)
    4198                     link = variableClasses[0];
    4199                 else if (variableClasses.contains(currentClass))
    4200                     link = currentClass;
    4201                 else {
    4202                     QString msg = "Unqualified variable name: " + first_text;
    4203                     QString details = "Classes: " + variableClasses.join(", ");
    4204                     priv->start_loc.error(msg,details);
    4205                 }
    4206             }
    4207             else {
    4208                 qDebug() << "NOT AUTO-LINKABLE" << first_text;
    4209                 QString s = first_text + " " + second_text;
    4210                 concatenate("\\link " + s + "\\endlink");
    4211             }
    4212             if (!link.isEmpty()) {
    4213                 link += "::" + first_text + " " + second_text;
    4214                 concatenate("\\link " + link + "\\endlink");
    4215             }
    4216         }
    4217     }
    4218     else
    4219         qDebug() << "LINK with no second parameter!!!!";
    4220     return next? next : atom;
    4221 }
    4222 
    4223 /*!
    4224   If the current line length is 0, the current line is
    4225   indented according to the context.
    4226  */
    4227 void DoxWriter::indentLine()
    4228 {
    4229     if (lineLength == 0) {
    4230         newText += DOXYGEN_INDENT_STRING;
    4231         lineLength = DOXYGEN_INDENT;
    4232         if (!structs.isEmpty()) {
    4233             for (int i=1; i<structs.size(); ++i) {
    4234                 newText += DOXYGEN_TAB_STRING;
    4235                 lineLength += DOXYGEN_TAB_SIZE;
    4236             }
    4237         }
    4238     }
    4239 }
    4240 
    4241 /*!
    4242   Concatenates a newline to the doxygen text, increments the
    4243   line count, and resets the line length to 0.
    4244  */
    4245 void DoxWriter::newLine()
    4246 {
    4247     newText += "\n";
    4248     ++lineCount;
    4249     lineLength = 0;
    4250 }
    4251 
    4252 static const int maxLineLength = 70;
    4253 
    4254 /*!
    4255   Concatenate the \a text to the doxygen comment currently
    4256   under construction and increment the current line length
    4257   by the size of the \a text.
    4258  
    4259   If incrementing the current line length by the \a text size
    4260   would make the current line length longer than the maximum
    4261   line length, then call newLine() and indentLine() \e before
    4262   concatenating the \a text.
    4263  */
    4264 void DoxWriter::concatenate(QString text)
    4265 {
    4266     if ((lineLength + text.size()) > maxLineLength)
    4267         newLine();
    4268     indentLine();
    4269     newText += text;
    4270     lineLength += text.size();
    4271 }
    4272 
    4273 static bool punctuation(QChar c)
    4274 {
    4275     switch (c.toAscii()) {
    4276     case '.':
    4277     case ',':
    4278     case ':':
    4279     case ';':
    4280     case '/':
    4281     case '+':
    4282     case '-':
    4283     case '?':
    4284     case '!':
    4285     case '\"':
    4286         return true;
    4287     default:
    4288         break;
    4289     }
    4290     return false;
    4291 }
    4292 
    4293 /*!
    4294   Concatenate the \a text string to the doxygen text, doing
    4295   line wrapping where necessary.
    4296  */
    4297 void DoxWriter::wrap(QString text)
    4298 {
    4299     int from = 0;
    4300     int to = -1;
    4301 
    4302     if ((lineLength == 0) || (lineLength >= maxLineLength)) {
    4303         if (!text.isEmpty() && (text[0] == ' '))
    4304             text = text.right(text.size() - 1);
    4305     }
    4306 
    4307     indentLine();
    4308     while (text.size()) {
    4309         int avail = maxLineLength - lineLength;
    4310         from = text.indexOf(' ',from);
    4311         if (from >= 0) {
    4312             if (from < avail)
    4313                 to = from++;
    4314             else if (from == 1 && punctuation(text[0]))
    4315                 to = from++;
    4316             else {
    4317                 if (to >= 0) {
    4318                     newText += text.left(to+1);
    4319                     lineLength += to + 1;
    4320                     text = text.right(text.size() - to - 1);
    4321                 }
    4322                 else {
    4323                     newLine();
    4324                     indentLine();
    4325                     newText += text.left(from+1);
    4326                     lineLength += from + 1;
    4327                     text = text.right(text.size() - from - 1);
    4328                 }
    4329                 from = 0;
    4330                 to = -1;
    4331                 if (text.size() && (lineLength > maxLineLength)) {
    4332                     newLine();
    4333                     indentLine();
    4334                 }
    4335             }
    4336         }
    4337         else
    4338             break;
    4339     }
    4340     if (text.size()) {
    4341         if (lineLength >= maxLineLength) {
    4342             newLine();
    4343             indentLine();
    4344         }
    4345         newText += text;
    4346         lineLength += text.size();
    4347     }
    4348 }
    4349 
    4350 /*!
    4351   This will output something, but it depends on what the
    4352   \a atom string and the \a next atom string are.
    4353  */
    4354 void DoxWriter::formattingLeft(const Atom* atom, const Atom* next)
    4355 {
    4356     if (atom->string() == "parameter") {
    4357         concatenate("\\a ");
    4358         return;
    4359     }
    4360     else if (atom->string() == "underline") {
    4361         concatenate("<u>");
    4362         return;
    4363     }
    4364     else if (atom->string() == "superscript") {
    4365         concatenate("<sup>");
    4366         return;
    4367     }
    4368     else if (atom->string() == "subscript") {
    4369         concatenate("<sub>");
    4370         return;
    4371     }
    4372     int ws = -1;
    4373     if (next)
    4374         ws = next->string().indexOf(ws_rx);
    4375     if (atom->string() == "bold") {
    4376         if (ws < 0)
    4377             concatenate("\\b ");
    4378         else
    4379             concatenate("<b>");
    4380     }
    4381     else if (atom->string() == "italic") {
    4382         if (ws < 0)
    4383             concatenate("\\e ");
    4384         else
    4385             concatenate("<i>");
    4386     }
    4387     else if (atom->string() == "teletype") {
    4388         if (ws < 0)
    4389             concatenate("\\c ");
    4390         else
    4391             concatenate("<tt>");
    4392     }
    4393     else
    4394         qDebug() << "UNHANDLED FormattingLeft: " << atom->string();
    4395 }
    4396 
    4397 /*!
    4398   This will output something, but it depends on what the
    4399   \a atom string and the \a prev atom string are.
    4400  */
    4401 void DoxWriter::formattingRight(const Atom* atom, const Atom* prev)
    4402 {
    4403     if (atom->string() == "parameter")
    4404         return;
    4405     else if (atom->string() == "underline") {
    4406         concatenate("</u>");
    4407         return;
    4408     }
    4409     else if (atom->string() == "superscript") {
    4410         concatenate("</sup>");
    4411         return;
    4412     }
    4413     else if (atom->string() == "subscript") {
    4414         concatenate("</sub>");
    4415         return;
    4416     }
    4417     int ws = -1;
    4418     if (prev)
    4419         ws = prev->string().indexOf(ws_rx);
    4420     if (ws < 0)
    4421         return;
    4422     if (atom->string() == "bold")
    4423         concatenate("</b>");
    4424     else if (atom->string() == "italic")
    4425         concatenate("</i>");
    4426     else if (atom->string() == "teletype")
    4427         concatenate("</tt>");
    4428     else
    4429         qDebug() << "UNHANDLED FormattingRight: " << atom->string();
    4430 }
    4431 
    4432 /*!
    4433   Output a \c or a <tt>...</tt>.
    4434  */
    4435 void DoxWriter::tt(const Atom* atom)
    4436 {
    4437     if (atom->string().indexOf(ws_rx) < 0) {
    4438         concatenate("\\c ");
    4439         concatenate(atom->string());
    4440     }
    4441     else {
    4442         concatenate("<tt>");
    4443         concatenate(atom->string());
    4444         concatenate("</tt>");
    4445     }
    4446 }
    4447 
    4448 /*!
    4449  */
    4450 void DoxWriter::formatIf(const Atom* atom)
    4451 {
    4452     if (atom->string() == "HTML") {
    4453         newLine();
    4454         concatenate("\\htmlonly");
    4455         newLine();
    4456     }
    4457 }
    4458 
    4459 /*!
    4460  */
    4461 void DoxWriter::formatEndif()
    4462 {
    4463     newLine();
    4464     concatenate("\\endhtmlonly");
    4465     newLine();
    4466 }
    4467 
    4468 /*!
    4469  */
    4470 void DoxWriter::formatElse()
    4471 {
    4472     // nothing.
    4473 }
    4474 
    4475 /*!
    4476   Pass 1: Construct a section identifier and insert it into
    4477   the anchor set.
    4478  
    4479   Pass 2: Convert section1, section2, and section3 commands
    4480   to section, subsection, and subsubsection respectively.
    4481   Warn if a section command higher than 3 is seen.
    4482  */
    4483 const Atom* DoxWriter::sectionHeading(const Atom* atom)
    4484 {
    4485     QString heading_level = atom->string();
    4486     QString heading_text;
    4487     const Atom* next = atom->next();
    4488     while (next) {
    4489         next->dump();
    4490         if (next->type() == Atom::SectionHeadingRight) {
    4491             if (next->string() == heading_level)
    4492                 break;
    4493             else {
    4494                 qDebug() << "WRONG SectionHeading number!!!!";
    4495             }
    4496         }
    4497         else
    4498             heading_text += next->string();
    4499         next = next->next();
    4500     }
    4501 
    4502     QString heading_identifier = heading_text;
    4503     heading_identifier.remove(ws_rx);
    4504    
    4505     newLine();
    4506     if (heading_level == "1")
    4507         heading_level = "\\section ";
    4508     else if (heading_level == "2")
    4509         heading_level = "\\subsection ";
    4510     else if (heading_level == "3")
    4511         heading_level = "\\subsubsection ";
    4512     else if (heading_level == "4") {
    4513         heading_level = "\\subsubsection ";
    4514         qDebug() << "WARNING section4 converted to \\subsubsection";
    4515     }
    4516     else {
    4517         heading_level = "\\subsubsection ";
    4518         qDebug() << "WARNING section5 converted to \\subsubsection";
    4519     }
    4520     concatenate(heading_level);
    4521     newText += heading_identifier + " ";
    4522     lineLength += heading_identifier.size() + 1;
    4523     newText += heading_text;
    4524     lineLength += heading_text.size();
    4525     newLine();
    4526     return next? next : atom;
    4527 }
    4528 
    4529 /*!
    4530   Report an unhandled atom.
    4531  */
    4532 void DoxWriter::unhandled(const Atom* atom)
    4533 {
    4534     qDebug() << "UNHANDLED ATOM";
    4535     atom->dump();
    4536 }
    4537 
    4538 /*!
    4539   Output a code/endcode block.
    4540  */
    4541 void DoxWriter::code(const Atom* atom)
    4542 {
    4543     newLine();
    4544     concatenate("\\code");
    4545     writeCode(atom->string());
    4546     concatenate("\\endcode");
    4547     newLine();
    4548 }
    4549 
    4550 /*!
    4551   Output a code/endcode block depending on the
    4552   CodeQuote Command and CodeQuoteArgument parameters.
    4553  */
    4554 const Atom* DoxWriter::codeQuoteCommand(const Atom* atom)
    4555 {
    4556     QString command = atom->string();
    4557     atom = atom->next();
    4558     concatenate("\\code");
    4559     if (command == "codeline") {
    4560         newLine();
    4561         concatenate(atom->string());
    4562         newLine();
    4563     }
    4564     else if (command == "dots") {
    4565         newLine();
    4566         concatenate(atom->string());
    4567         newLine();
    4568     }
    4569     else {
    4570         writeCode(atom->string());
    4571     }
    4572     concatenate("\\endcode");
    4573     return atom;
    4574 }
    4575 
    4576 /*!
    4577   Appends a block of code to the comment.
    4578  */
    4579 void DoxWriter::writeCode(QString text)
    4580 {
    4581     int cr_count = text.count('\n') - 1;
    4582     if (cr_count >= 0) {
    4583         int last_cr = text.lastIndexOf('\n');
    4584         newText += text.left(last_cr);
    4585         lineCount += cr_count;
    4586     }
    4587     else
    4588         newText += text;
    4589     newLine();
    4590 }
    4591 
    4592 /*!
    4593   Inserts \a text into the anchor set. This function is called
    4594   during doxygen pass 1.
    4595  */
    4596 void DoxWriter::insertAnchor(const QString& text)
    4597 {
    4598     anchors.insert(text);
    4599 }
    4600 
    4601 /*!
    4602   Returns true if \a text identifies an anchor, section,
    4603   subsection, subsubsection, or page.
    4604  */
    4605 bool DoxWriter::isAnchor(const QString& text)
    4606 {
    4607     return anchors.contains(text);
    4608 }
    4609 
    4610 /*!
    4611   Write the set of anchors to a file, one per line.
    4612  */
    4613 void DoxWriter::writeAnchors()
    4614 {
    4615     QFile file("anchors.txt");
    4616     if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
    4617         qWarning("Unable to open anchors.txt for writing.");
    4618         return;
    4619     }
    4620    
    4621     QTextStream out(&file);
    4622     QSet<QString>::const_iterator i = anchors.constBegin();
    4623     while (i != anchors.constEnd()) {
    4624         out << *i << "\n";
    4625         ++i;
    4626     }
    4627     file.close();
    4628 }
    4629 
    4630 /*!
    4631   Read the set of anchors from the anchors file, one per line,
    4632   and insert each one into the anchor set.
    4633  */
    4634 void DoxWriter::readAnchors()
    4635 {
    4636     QFile file("anchors.txt");
    4637     if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
    4638         qWarning("Unable to open anchors.txt for reading.");
    4639         return;
    4640     }
    4641    
    4642     QTextStream in(&file);
    4643     while (!in.atEnd()) {
    4644         QString line = in.readLine();
    4645         anchors.insert(line);
    4646     }
    4647     file.close();
    4648 #if 0   
    4649     QSet<QString>::const_iterator i = anchors.constBegin();
    4650     while (i != anchors.constEnd()) {
    4651         qDebug() << *i;
    4652         ++i;
    4653     }
    4654 #endif   
    4655 }
    4656 
    4657 /*!
    4658   Inserts \a title into one of the title maps. \a title is
    4659   mapped to the \a node name. This function is called during
    4660   doxygen pass 1.
    4661  */
    4662 void DoxWriter::insertTitle(FakeNode* node, const QString& title)
    4663 {
    4664     switch (node->subType()) {
    4665     case FakeNode::Example:
    4666         if (exampleTitles.contains(title)) {
    4667             qWarning() << "DoxWriter::insertTitle():"
    4668                        << "Duplicate example title:"
    4669                        << title;
    4670         }
    4671         else {
    4672             exampleTitles[title] = node->name();
    4673             exampleTitlesInverse[node->name()] = title;
    4674         }
    4675         break;
    4676     case FakeNode::HeaderFile:
    4677         if (headerFileTitles.contains(title)) {
    4678             qWarning() << "DoxWriter::insertTitle():"
    4679                        << "Duplicate header file title:"
    4680                        << title;
    4681         }
    4682         else {
    4683             headerFileTitles[title] = node->name();
    4684             headerFileTitlesInverse[node->name()] = title;
    4685         }
    4686         break;
    4687     case FakeNode::File:
    4688         if (fileTitles.contains(title)) {
    4689             qWarning() << "DoxWriter::insertTitle():"
    4690                        << "Duplicate file title:"
    4691                        << title;
    4692         }
    4693         else {
    4694             fileTitles[title] = node->name();
    4695             fileTitlesInverse[node->name()] = title;
    4696         }
    4697         break;
    4698     case FakeNode::Group:
    4699         if (groupTitles.contains(title)) {
    4700             qWarning() << "DoxWriter::insertTitle():"
    4701                        << "Duplicate group title:"
    4702                        << title;
    4703         }
    4704         else {
    4705             groupTitles[title] = node->name();
    4706             groupTitlesInverse[node->name()] = title;
    4707         }
    4708         break;
    4709     case FakeNode::Module:
    4710         if (moduleTitles.contains(title)) {
    4711             qWarning() << "DoxWriter::insertTitle():"
    4712                        << "Duplicate module title:"
    4713                        << title;
    4714         }
    4715         else {
    4716             moduleTitles[title] = node->name();
    4717             moduleTitlesInverse[node->name()] = title;
    4718         }
    4719         break;
    4720     case FakeNode::Page:
    4721         if (pageTitles.contains(title)) {
    4722             qWarning() << "DoxWriter::insertTitle():"
    4723                        << "Duplicate page title:"
    4724                        << title;
    4725         }
    4726         else {
    4727             pageTitles[title] = node->name();
    4728             pageTitlesInverse[node->name()] = title;
    4729         }
    4730         break;
    4731     case FakeNode::ExternalPage:
    4732         if (externalPageTitles.contains(title)) {
    4733             qWarning() << "DoxWriter::insertTitle():"
    4734                        << "Duplicate external page title:"
    4735                        << title;
    4736         }
    4737         else {
    4738             externalPageTitles[title] = node->name();
    4739             externalPageTitlesInverse[node->name()] = title;
    4740         }
    4741         break;
    4742     default:
    4743         break;
    4744     }
    4745 }
    4746 
    4747 /*!
    4748  */
    4749 const QString* DoxWriter::getPageFile(const QString& title)
    4750 {
    4751     QStringMapEntry entry = pageTitles.find(title);
    4752     return (entry == pageTitles.end()) ? 0 : &entry.value();
    4753 }
    4754 
    4755 /*!
    4756  */
    4757 const QString* DoxWriter::getExamplePath(const QString& title)
    4758 {
    4759     QStringMapEntry entry = exampleTitles.find(title);
    4760     return (entry == exampleTitles.end()) ? 0 : &entry.value();
    4761 }
    4762 
    4763 /*!
    4764  */
    4765 const QString* DoxWriter::getFile(const QString& title)
    4766 {
    4767     QStringMapEntry entry = fileTitles.find(title);
    4768     return (entry == fileTitles.end()) ? 0 : &entry.value();
    4769 }
    4770 
    4771 /*!
    4772  */
    4773 const QString* DoxWriter::getHeaderFile(const QString& title)
    4774 {
    4775     QStringMapEntry entry = headerFileTitles.find(title);
    4776     return (entry == headerFileTitles.end()) ? 0 : &entry.value();
    4777 }
    4778 
    4779 /*!
    4780  */
    4781 const QString* DoxWriter::getGroup(const QString& title)
    4782 {
    4783     QStringMapEntry entry = groupTitles.find(title);
    4784     return (entry == groupTitles.end()) ? 0 : &entry.value();
    4785 }
    4786 
    4787 /*!
    4788  */
    4789 const QString* DoxWriter::getModule(const QString& title)
    4790 {
    4791     QStringMapEntry entry = moduleTitles.find(title);
    4792     return (entry == moduleTitles.end()) ? 0 : &entry.value();
    4793 }
    4794 
    4795 /*!
    4796  */
    4797 const QString* DoxWriter::getExternalPage(const QString& title)
    4798 {
    4799     QStringMapEntry entry = externalPageTitles.find(title);
    4800     return (entry == externalPageTitles.end()) ? 0 : &entry.value();
    4801 }
    4802 
    4803 /*!
    4804  */
    4805 const QString* DoxWriter::getPageTitle(const QString& text)
    4806 {
    4807     QStringMapEntry entry = pageTitlesInverse.find(text);
    4808     return (entry == pageTitlesInverse.end()) ? 0 : &entry.value();
    4809 }
    4810 
    4811 /*!
    4812  */
    4813 const QString* DoxWriter::getExampleTitle(const QString& text)
    4814 {
    4815     QStringMapEntry entry = exampleTitlesInverse.find(text);
    4816     return (entry == exampleTitlesInverse.end()) ? 0 : &entry.value();
    4817 }
    4818 
    4819 /*!
    4820  */
    4821 const QString* DoxWriter::getFileTitle(const QString& text)
    4822 {
    4823     QStringMapEntry entry = fileTitlesInverse.find(text);
    4824     return (entry == fileTitlesInverse.end()) ? 0 : &entry.value();
    4825 }
    4826 
    4827 /*!
    4828  */
    4829 const QString* DoxWriter::getHeaderFileTitle(const QString& text)
    4830 {
    4831     QStringMapEntry entry = headerFileTitlesInverse.find(text);
    4832     return (entry == headerFileTitlesInverse.end()) ? 0 : &entry.value();
    4833 }
    4834 
    4835 /*!
    4836  */
    4837 const QString* DoxWriter::getGroupTitle(const QString& text)
    4838 {
    4839     QStringMapEntry entry = groupTitlesInverse.find(text);
    4840     return (entry == groupTitlesInverse.end()) ? 0 : &entry.value();
    4841 }
    4842 
    4843 /*!
    4844  */
    4845 const QString* DoxWriter::getModuleTitle(const QString& text)
    4846 {
    4847     QStringMapEntry entry = moduleTitlesInverse.find(text);
    4848     return (entry == moduleTitlesInverse.end()) ? 0 : &entry.value();
    4849 }
    4850 
    4851 /*!
    4852  */
    4853 const QString* DoxWriter::getExternalPageTitle(const QString& text)
    4854 {
    4855     QStringMapEntry entry = externalPageTitlesInverse.find(text);
    4856     return (entry == externalPageTitlesInverse.end()) ? 0 : &entry.value();
    4857 }
    4858 
    4859 /*!
    4860   Serialize \a map to file \a name.
    4861  */
    4862 void DoxWriter::writeMap(const QStringMap& map, const QString& name)
    4863 {
    4864 
    4865     QFile file(name);
    4866     if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
    4867         qWarning() << "Unable to open" << name << "for writing.";
    4868         return;
    4869     }
    4870    
    4871     QTextStream out(&file);
    4872     QStringMap::const_iterator i = map.constBegin();
    4873     while (i != map.constEnd()) {
    4874         out << i.key() << "\n";
    4875         out << i.value() << "\n";
    4876         ++i;
    4877     }
    4878     file.close();
    4879 }
    4880 
    4881 /*!
    4882   Read file \a name into the \a map.
    4883  */
    4884 void DoxWriter::readMap(QStringMap& map, QStringMap& inverseMap, const QString& name)
    4885 {
    4886     QFile file(name);
    4887     if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
    4888         qWarning() << "Unable to open" << name << "for reading.";
    4889         return;
    4890     }
    4891    
    4892     QTextStream in(&file);
    4893     while (!in.atEnd()) {
    4894         QString title = in.readLine();
    4895         QString value = in.readLine();
    4896         map[title] = value;
    4897         inverseMap[value] = title;
    4898     }
    4899     file.close();
    4900 }
    4901 
    4902 /*!
    4903   Write the sets of titles to text files, one per line.
    4904  */
    4905 void DoxWriter::writeTitles()
    4906 {
    4907     if (!pageTitles.isEmpty())
    4908         writeMap(pageTitles,"pagetitles.txt");
    4909     if (!fileTitles.isEmpty())
    4910         writeMap(fileTitles,"filetitles.txt");
    4911     if (!headerFileTitles.isEmpty())
    4912         writeMap(headerFileTitles,"headerfiletitles.txt");
    4913     if (!exampleTitles.isEmpty())
    4914         writeMap(exampleTitles,"exampletitles.txt");
    4915     if (!moduleTitles.isEmpty())
    4916         writeMap(moduleTitles,"moduletitles.txt");
    4917     if (!groupTitles.isEmpty())
    4918         writeMap(groupTitles,"grouptitles.txt");
    4919     if (!externalPageTitles.isEmpty())
    4920         writeMap(externalPageTitles,"externalpagetitles.txt");
    4921 }
    4922 
    4923 /*!
    4924   Read the sets of titles from the titles files, one per line,
    4925   and insert each one into the appropriate title set.
    4926  */
    4927 void DoxWriter::readTitles()
    4928 {
    4929     readMap(pageTitles,pageTitlesInverse,"pagetitles.txt");
    4930     readMap(fileTitles,fileTitlesInverse,"filetitles.txt");
    4931     readMap(headerFileTitles,headerFileTitlesInverse,"headerfiletitles.txt");
    4932     readMap(exampleTitles,exampleTitlesInverse,"exampletitles.txt");
    4933     readMap(moduleTitles,moduleTitlesInverse,"moduletitles.txt");
    4934     readMap(groupTitles,groupTitlesInverse,"grouptitles.txt");
    4935     readMap(externalPageTitles,
    4936             externalPageTitlesInverse,
    4937             "externalpagetitles.txt");
    4938 }
    4939 
    4940 /*!
    4941   Serialize \a map to file \a name.
    4942  */
    4943 void DoxWriter::writeMultiMap(const QStringMultiMap& map, const QString& name)
    4944 {
    4945 
    4946     QFile file(name);
    4947     if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
    4948         qWarning() << "Unable to open" << name << "for writing.";
    4949         return;
    4950     }
    4951    
    4952     QTextStream out(&file);
    4953     QStringMultiMap::const_iterator i = map.constBegin();
    4954     while (i != map.constEnd()) {
    4955         out << i.key() << "\n";
    4956         out << i.value() << "\n";
    4957         ++i;
    4958     }
    4959     file.close();
    4960 }
    4961 
    4962 /*!
    4963   Write the4 property names and variable names to text files.
    4964  */
    4965 void DoxWriter::writeMembers()
    4966 {
    4967     if (!variables.isEmpty())
    4968         writeMultiMap(variables,"variables.txt");
    4969     if (!properties.isEmpty())
    4970         writeMultiMap(properties,"properties.txt");
    4971     if (!enums.isEmpty())
    4972         writeMultiMap(enums,"enums.txt");
    4973 }
    4974 
    4975 /*!
    4976   Read file \a name into the \a map.
    4977  */
    4978 void DoxWriter::readMultiMap(QStringMultiMap& map, const QString& name)
    4979 {
    4980     QFile file(name);
    4981     if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
    4982         qWarning() << "Unable to open" << name << "for reading.";
    4983         return;
    4984     }
    4985    
    4986     QTextStream in(&file);
    4987     while (!in.atEnd()) {
    4988         QString member = in.readLine();
    4989         QString className = in.readLine();
    4990         map.insert(member,className);
    4991     }
    4992     file.close();
    4993 }
    4994 
    4995 /*!
    4996   Read the property names and variable names from the test files.
    4997  */
    4998 void DoxWriter::readMembers()
    4999 {
    5000     readMultiMap(variables,"variables.txt");
    5001     readMultiMap(properties,"properties.txt");
    5002     readMultiMap(enums,"enums.txt");
    5003 }
    5004 
    5005 /*!
    5006   Return true if \a name is a property. Loads \a classes with
    5007   the names of all the classes in which \a name is a property.
    5008  */
    5009 bool DoxWriter::isProperty(const QString& name, QStringList& classes)
    5010 {
    5011     classes = properties.values(name);
    5012     return !classes.isEmpty();
    5013 }
    5014 
    5015 /*!
    5016   Return true if \a name is a variable. Loads \a classes with
    5017   the names of all the classes in which \a name is a variable.
    5018  */
    5019 bool DoxWriter::isVariable(const QString& name, QStringList& classes)
    5020 {
    5021     classes = variables.values(name);
    5022     return !classes.isEmpty();
    5023 }
    5024 
    5025 /*!
    5026   Return true if \a name is an enum type. Loads \a classes with
    5027   the names of all the classes in which \a name is an enum type.
    5028  */
    5029 bool DoxWriter::isEnum(const QString& name, QStringList& classes)
    5030 {
    5031     classes = enums.values(name);
    5032     return !classes.isEmpty();
    5033 }
    5034 #endif
    5035 
    50363085QT_END_NAMESPACE
  • trunk/tools/qdoc3/doc.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    134134};
    135135
    136 #ifdef QDOC2DOX
    137 
    138 class DoxWriter
    139 {
    140   public:
    141     DoxWriter(const QString& source, DocPrivate* docPrivate)
    142         : commentType(OtherComment),
    143           lineLength(0),
    144           lineCount(0),
    145           priv(docPrivate),
    146           oldText(source) {}
    147     ~DoxWriter() {}
    148 
    149     void pass1();
    150     void pass2();
    151 
    152     static void setDoxPass(int pass);
    153     static bool isDoxPass(int pass);
    154     static bool isDoxPass();
    155     static void insertTitle(FakeNode* node, const QString& title);
    156     static void writeTitles();
    157     static void readTitles();
    158     static void writeMembers();
    159     static void readMembers();
    160     static void writeAnchors();
    161     static void readAnchors();
    162 
    163   private:
    164     void indentLine();
    165     void newLine();
    166     void concatenate(QString text);
    167     void wrap(QString text);
    168     bool conversionRequired() const;
    169     void convertMetaCommands();
    170     void convertText();
    171     const Atom* link(const Atom* atom);
    172     void formattingLeft(const Atom* atom, const Atom* next);
    173     void formattingRight(const Atom* atom, const Atom* prev);
    174     void tt(const Atom* atom);
    175     void formatIf(const Atom* atom);
    176     void formatEndif();
    177     void formatElse();
    178     const Atom* sectionHeading(const Atom* atom);
    179     void unhandled(const Atom* atom);
    180     void code(const Atom* atom);
    181     const Atom* codeQuoteCommand(const Atom* atom);
    182     void writeCode(QString text);
    183     void writeCommand(QCommandMap::const_iterator cmd);
    184 
    185     static void insertAnchor(const QString& text);
    186     static bool isAnchor(const QString& text);
    187 
    188     static const QString* getPageFile(const QString& title);
    189     static const QString* getFile(const QString& title);
    190     static const QString* getExamplePath(const QString& title);
    191     static const QString* getHeaderFile(const QString& title);
    192     static const QString* getGroup(const QString& title);
    193     static const QString* getModule(const QString& title);
    194     static const QString* getExternalPage(const QString& title);
    195     static const QString* getPageTitle(const QString& text);
    196     static const QString* getFileTitle(const QString& text);
    197     static const QString* getExampleTitle(const QString& text);
    198     static const QString* getHeaderFileTitle(const QString& text);
    199     static const QString* getGroupTitle(const QString& text);
    200     static const QString* getModuleTitle(const QString& text);
    201     static const QString* getExternalPageTitle(const QString& text);
    202    
    203     static bool isProperty(const QString& title, QStringList& classes);
    204     static bool isVariable(const QString& title, QStringList& classes);
    205     static bool isEnum(const QString& title, QStringList& classes);
    206 
    207  private:
    208     static void writeMap(const QStringMap& map, const QString& name);
    209     static void readMap(QStringMap& map,
    210                         QStringMap& inverseMap,
    211                         const QString& name);
    212     static void writeMultiMap(const QStringMultiMap& map, const QString& name);
    213     static void readMultiMap(QStringMultiMap& map, const QString& name);
    214 
    215  public: // VS 6, SunCC need this to be public
    216     enum StructType { BulletList, NumericList, ValueList, Table };
    217  private:
    218     struct StructDesc {
    219         StructType      structType;
    220         int             count;
    221         bool            nested;
    222         bool            inTableHeader;
    223         bool            inTableRow;
    224         bool            inTableItem;
    225         bool            odd;
    226 
    227         StructDesc()
    228             : structType(BulletList),
    229               count(0),
    230               nested(false),
    231               inTableHeader(false),
    232               inTableRow(false),
    233               inTableItem(false),
    234               odd(true) { }
    235 
    236         StructDesc(StructType t, bool n)
    237             : structType(t),
    238               count(0),
    239               nested(n),
    240               inTableHeader(false),
    241               inTableRow(false),
    242               inTableItem(false),
    243               odd(true) { }
    244     };
    245 
    246     typedef QStack<StructDesc> StructStack;
    247 
    248     enum CommentType {
    249         ClassComment,
    250         EnumComment,
    251         ExampleComment,
    252         FnComment,
    253         GroupComment,
    254         HeaderFileComment,
    255         MacroComment,
    256         ModuleComment,
    257         PageComment,
    258         PropertyComment,
    259         ServiceComment,
    260         TypedefComment,
    261         VariableComment,
    262         OtherComment
    263     };
    264 
    265   private:
    266     CommentType         commentType;
    267     int                 lineLength;
    268     int                 lineCount;
    269     DocPrivate*         priv;
    270     QString             oldText;
    271     QString             newText;
    272     StructStack         structs;
    273 
    274     QString             currentPage;
    275     QString             currentFn;
    276     QString             currentTitle;
    277     QString             currentEnum;
    278     QString             currentProperty;
    279     QString             currentVariable;
    280     QString             currentExample;
    281     QString             currentGroup;
    282     QString             currentModule;
    283     QString             currentMacro;
    284     QString             currentService;
    285     QString             currentTypedef;
    286     QString             currentHeaderFile;
    287     static QString      currentClass;
    288 
    289     static int          doxPass;
    290     static QSet<QString> anchors;
    291     static QStringMap   exampleTitles;
    292     static QStringMap   headerFileTitles;
    293     static QStringMap   fileTitles;
    294     static QStringMap   groupTitles;
    295     static QStringMap   moduleTitles;
    296     static QStringMap   pageTitles;
    297     static QStringMap   externalPageTitles;
    298     static QStringMap   exampleTitlesInverse;
    299     static QStringMap   headerFileTitlesInverse;
    300     static QStringMap   fileTitlesInverse;
    301     static QStringMap   groupTitlesInverse;
    302     static QStringMap   moduleTitlesInverse;
    303     static QStringMap   pageTitlesInverse;
    304     static QStringMap   externalPageTitlesInverse;
    305 
    306     static QStringMultiMap variables;
    307     static QStringMultiMap properties;
    308     static QStringMultiMap enums;
    309 };
    310 
    311 #endif
    312 
    313136QT_END_NAMESPACE
    314137
  • trunk/tools/qdoc3/editdistance.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/editdistance.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/generator.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4343  generator.cpp
    4444*/
    45 
     45#include <QtCore>
    4646#include <qdir.h>
    47 
     47#include <qdebug.h>
    4848#include "codemarker.h"
    4949#include "config.h"
     
    6666QStringList Generator::imageFiles;
    6767QStringList Generator::imageDirs;
     68QStringList Generator::exampleDirs;
     69QStringList Generator::exampleImgExts;
    6870QString Generator::outDir;
    6971QString Generator::project;
    7072
    71 static Text stockLink(const QString &target)
    72 {
    73     return Text() << Atom(Atom::Link, target) << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
    74                   << target << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
     73static void singularPlural(Text& text, const NodeList& nodes)
     74{
     75    if (nodes.count() == 1)
     76        text << " is";
     77    else
     78        text << " are";
    7579}
    7680
    7781Generator::Generator()
    78     : amp("&amp;"), lt("&lt;"), gt("&gt;"), quot("&quot;"), tag("</?@[^>]*>")
     82    : amp("&amp;"),
     83      lt("&lt;"),
     84      gt("&gt;"),
     85      quot("&quot;"),
     86      tag("</?@[^>]*>")
    7987{
    8088    generators.prepend(this);
     
    115123            config.lastLocation().fatal(tr("Cannot create output directory '%1'")
    116124                                        .arg(outDir + "/images"));
     125        if (!dirInfo.mkdir(outDir + "/images/used-in-examples"))
     126            config.lastLocation().fatal(tr("Cannot create output directory '%1'")
     127                                        .arg(outDir + "/images/used-in-examples"));
    117128    }
    118129
    119130    imageFiles = config.getStringList(CONFIG_IMAGES);
    120131    imageDirs = config.getStringList(CONFIG_IMAGEDIRS);
    121 
    122     QString imagesDotFileExtensions = CONFIG_IMAGES + Config::dot + CONFIG_FILEEXTENSIONS;
     132    exampleDirs = config.getStringList(CONFIG_EXAMPLEDIRS);
     133    exampleImgExts = config.getStringList(CONFIG_EXAMPLES + Config::dot +
     134                                          CONFIG_IMAGEEXTENSIONS);
     135
     136    QString imagesDotFileExtensions =
     137        CONFIG_IMAGES + Config::dot + CONFIG_FILEEXTENSIONS;
    123138    QSet<QString> formats = config.subVars(imagesDotFileExtensions);
    124139    QSet<QString>::ConstIterator f = formats.begin();
    125140    while (f != formats.end()) {
    126         imgFileExts[*f] = config.getStringList(imagesDotFileExtensions + Config::dot + *f);
     141        imgFileExts[*f] = config.getStringList(imagesDotFileExtensions +
     142                                               Config::dot + *f);
    127143        ++f;
    128144    }
     
    132148        if (outputFormats.contains((*g)->format())) {
    133149            (*g)->initializeGenerator(config);
    134             QStringList extraImages = config.getStringList(CONFIG_EXTRAIMAGES + Config::dot
    135                                                            + (*g)->format());
     150            QStringList extraImages =
     151                config.getStringList(CONFIG_EXTRAIMAGES+Config::dot+(*g)->format());
    136152            QStringList::ConstIterator e = extraImages.begin();
    137153            while (e != extraImages.end()) {
    138154                QString userFriendlyFilePath;
    139                 QString filePath = Config::findFile(config.lastLocation(), imageFiles, imageDirs, *e,
    140                                                     imgFileExts[(*g)->format()], userFriendlyFilePath);
     155                QString filePath = Config::findFile(config.lastLocation(),
     156                                                    imageFiles,
     157                                                    imageDirs,
     158                                                    *e,
     159                                                    imgFileExts[(*g)->format()],
     160                                                    userFriendlyFilePath);
    141161                if (!filePath.isEmpty())
    142                     Config::copyFile(config.lastLocation(), filePath, userFriendlyFilePath,
    143                                          (*g)->outputDir() + "/images");
     162                    Config::copyFile(config.lastLocation(),
     163                                     filePath,
     164                                     userFriendlyFilePath,
     165                                     (*g)->outputDir() +
     166                                     "/images");
    144167                ++e;
    145168            }
     
    157180        QSet<QString>::ConstIterator f = formats.begin();
    158181        while (f != formats.end()) {
    159             QString def = config.getString(formattingDotName + Config::dot +
    160                                             *f);
     182            QString def = config.getString(formattingDotName +
     183                                           Config::dot + *f);
    161184            if (!def.isEmpty()) {
    162185                int numParams = Config::numParams(def);
     
    164187
    165188                if (numParams != 1) {
    166                     config.lastLocation().warning(tr("Formatting '%1' must have exactly one"
    167                                                      " parameter (found %2)")
    168                                                  .arg(*n).arg(numParams));
     189                    config.lastLocation().warning(tr("Formatting '%1' must "
     190                                                     "have exactly one "
     191                                                     "parameter (found %2)")
     192                                                  .arg(*n).arg(numParams));
    169193                }
    170194                else if (numOccs > 1) {
    171                     config.lastLocation().fatal(tr("Formatting '%1' must contain exactly one"
    172                                                     " occurrence of '\\1' (found %2)")
     195                    config.lastLocation().fatal(tr("Formatting '%1' must "
     196                                                   "contain exactly one "
     197                                                   "occurrence of '\\1' "
     198                                                   "(found %2)")
    173199                                                .arg(*n).arg(numOccs));
    174200                }
     
    242268}
    243269
    244 void Generator::generateText(const Text& text,
     270bool Generator::generateText(const Text& text,
    245271                             const Node *relative,
    246272                             CodeMarker *marker)
     
    255281                         numAtoms);
    256282        endText(relative, marker);
    257     }
     283        return true;
     284    }
     285    return false;
    258286}
    259287
    260288#ifdef QDOC_QML
    261 void Generator::generateQmlText(const Text& text,
     289/*!
     290  Extract sections of markup text surrounded by \e qmltext
     291  and \e endqmltext and output them.
     292 */
     293bool Generator::generateQmlText(const Text& text,
    262294                                const Node *relative,
    263                                 CodeMarker *marker)
    264 {
    265     if (text.firstAtom() != 0) {
    266         startText(relative, marker);
    267         const Atom *atom = text.firstAtom();
    268         while (atom) {
    269             if (atom->type() != Atom::QmlText)
    270                 atom = atom->next();
    271             else {
    272                 atom = atom->next();
    273                 while (atom && (atom->type() != Atom::EndQmlText)) {
    274                     int n = 1 + generateAtom(atom, relative, marker);
    275                     while (n-- > 0)
    276                         atom = atom->next();
    277                 }
    278             }
    279         }
    280         endText(relative, marker);
    281     }
     295                                CodeMarker *marker,
     296                                const QString& /* qmlName */ )
     297{
     298    const Atom* atom = text.firstAtom();
     299    if (atom == 0)
     300        return false;
     301
     302    startText(relative, marker);
     303    while (atom) {
     304        if (atom->type() != Atom::QmlText)
     305            atom = atom->next();
     306        else {
     307            atom = atom->next();
     308            while (atom && (atom->type() != Atom::EndQmlText)) {
     309                int n = 1 + generateAtom(atom, relative, marker);
     310                while (n-- > 0)
     311                    atom = atom->next();
     312            }
     313        }
     314    }
     315    endText(relative, marker);
     316    return true;
    282317}
    283318#endif
     
    296331    else if (node->type() == Node::Fake) {
    297332        const FakeNode *fake = static_cast<const FakeNode *>(node);
    298         if (fake->subType() == FakeNode::Example)
     333        if (fake->subType() == Node::Example)
    299334            generateExampleFiles(fake, marker);
    300         else if (fake->subType() == FakeNode::File)
     335        else if ((fake->subType() == Node::File) || (fake->subType() == Node::Image))
    301336            quiet = true;
    302337    }
    303338
    304339    if (node->doc().isEmpty()) {
    305         if (!quiet) // ### might be unnecessary
     340        if (!quiet && !node->isReimp()) // ### might be unnecessary
    306341            node->location().warning(tr("No documentation for '%1'")
    307342                            .arg(marker->plainFullName(node)));
    308343    }
    309344    else {
    310         generateText(node->doc().body(), node, marker);
     345        if (node->type() == Node::Function) {
     346            const FunctionNode *func = static_cast<const FunctionNode *>(node);
     347            if (func->reimplementedFrom() != 0)
     348                generateReimplementedFrom(func, marker);
     349        }
     350       
     351        if (!generateText(node->doc().body(), node, marker))
     352            if (node->isReimp())
     353                return;
    311354
    312355        if (node->type() == Node::Enum) {
     
    346389        else if (node->type() == Node::Function) {
    347390            const FunctionNode *func = static_cast<const FunctionNode *>(node);
    348 
    349391            QSet<QString> definedParams;
    350392            QList<Parameter>::ConstIterator p = func->parameters().begin();
     
    383425                                    func->parent()->findFunctionNode(func->name());
    384426                            if (primaryFunc) {
    385                                 foreach (const Parameter &param, primaryFunc->parameters()) {
     427                                foreach (const Parameter &param,
     428                                         primaryFunc->parameters()) {
    386429                                    if (param.name() == *a) {
    387430                                        needWarning = false;
     
    391434                            }
    392435                        }
    393                         if (needWarning)
     436                        if (needWarning && !func->isReimp())
    394437                            node->doc().location().warning(
    395                                 tr("Undocumented parameter '%1' in %2").arg(*a).arg(marker->plainFullName(node)));
     438                                tr("Undocumented parameter '%1' in %2")
     439                                .arg(*a).arg(marker->plainFullName(node)));
    396440                    }
    397441                    ++a;
     
    405449                    node->doc().location().warning(tr("Undocumented return value"));
    406450            }
    407 
     451#if 0
     452            // Now we put this at the top, before the other text.
    408453            if (func->reimplementedFrom() != 0)
    409454                generateReimplementedFrom(func, marker);
     455#endif           
    410456        }
    411457    }
     
    413459    if (node->type() == Node::Fake) {
    414460        const FakeNode *fake = static_cast<const FakeNode *>(node);
    415         if (fake->subType() == FakeNode::File) {
     461        if (fake->subType() == Node::File) {
    416462            Text text;
    417463            Quoter quoter;
     
    460506            if ((*r).access == Node::Protected) {
    461507                text << " (protected)";
    462             } else if ((*r).access == Node::Private) {
     508            }
     509            else if ((*r).access == Node::Private) {
    463510                text << " (private)";
    464511            }
     
    470517    }
    471518}
     519
     520#ifdef QDOC_QML
     521/*!
     522 */
     523void Generator::generateQmlInherits(const QmlClassNode* , CodeMarker* )
     524{
     525    // stub.
     526}
     527#endif
    472528
    473529void Generator::generateInheritedBy(const ClassNode *classe,
     
    484540}
    485541
     542/*!
     543  This function is called when the documentation for an
     544  example is being formatted. It outputs the list of source
     545  files comprising the example, and the list of images used
     546  by the example. The images are copied into a subtree of
     547  \c{...doc/html/images/used-in-examples/...}
     548 */
     549void Generator::generateFileList(const FakeNode* fake,
     550                                 CodeMarker* marker,
     551                                 Node::SubType subtype,
     552                                 const QString& tag)
     553{
     554    int count = 0;
     555    Text text;
     556    OpenedList openedList(OpenedList::Bullet);
     557
     558    text << Atom::ParaLeft << tag << Atom::ParaRight
     559         << Atom(Atom::ListLeft, openedList.styleString());
     560
     561    foreach (const Node* child, fake->childNodes()) {
     562        if (child->subType() == subtype) {
     563            ++count;
     564            QString file = child->name();
     565            if (subtype == Node::Image) {
     566                if (!file.isEmpty()) {
     567                    QDir dirInfo;
     568                    QString userFriendlyFilePath;
     569                    QString srcPath = Config::findFile(fake->location(),
     570                                                       QStringList(),
     571                                                       exampleDirs,
     572                                                       file,
     573                                                       exampleImgExts,
     574                                                       userFriendlyFilePath);
     575                    userFriendlyFilePath.truncate(userFriendlyFilePath.lastIndexOf('/'));
     576
     577                    QString imgOutDir = outDir + "/images/used-in-examples/" + userFriendlyFilePath;
     578                    if (!dirInfo.mkpath(imgOutDir))
     579                        fake->location().fatal(tr("Cannot create output directory '%1'")
     580                                               .arg(imgOutDir));
     581
     582                    QString imgOutName = Config::copyFile(fake->location(),
     583                                                          srcPath,
     584                                                          file,
     585                                                          imgOutDir);
     586                }
     587
     588            }
     589
     590            openedList.next();
     591            text << Atom(Atom::ListItemNumber, openedList.numberString())
     592                 << Atom(Atom::ListItemLeft, openedList.styleString())
     593                 << Atom::ParaLeft
     594                 << Atom(Atom::Link, file)
     595                 << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
     596                 << file
     597                 << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
     598                 << Atom::ParaRight
     599                 << Atom(Atom::ListItemRight, openedList.styleString());
     600        }
     601    }
     602    text << Atom(Atom::ListRight, openedList.styleString());
     603    if (count > 0)
     604        generateText(text, fake, marker);
     605}
     606
    486607void Generator::generateExampleFiles(const FakeNode *fake, CodeMarker *marker)
    487608{
    488609    if (fake->childNodes().isEmpty())
    489610        return;
    490 
    491     OpenedList openedList(OpenedList::Bullet);
    492 
    493     Text text;
    494     text << Atom::ParaLeft << "Files:" << Atom::ParaRight
    495          << Atom(Atom::ListLeft, openedList.styleString());
    496     foreach (const Node *child, fake->childNodes()) {
    497         QString exampleFile = child->name();
    498         openedList.next();
    499         text << Atom(Atom::ListItemNumber, openedList.numberString())
    500              << Atom(Atom::ListItemLeft, openedList.styleString()) << Atom::ParaLeft
    501              << Atom(Atom::Link, exampleFile)
    502              << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
    503              << exampleFile
    504              << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
    505              << Atom::ParaRight << Atom(Atom::ListItemRight, openedList.styleString());
    506     }
    507     text << Atom(Atom::ListRight, openedList.styleString());
    508     generateText(text, fake, marker);
    509 }
    510 
    511 void Generator::generateModuleWarning(const ClassNode *classe, CodeMarker *marker)
     611    generateFileList(fake, marker, Node::File, QString("Files:"));
     612    generateFileList(fake, marker, Node::Image, QString("Images:"));
     613}
     614
     615#if 0
     616    QList<Generator *>::ConstIterator g = generators.begin();
     617    while (g != generators.end()) {
     618        if (outputFormats.contains((*g)->format())) {
     619            (*g)->initializeGenerator(config);
     620            QStringList extraImages =
     621                config.getStringList(CONFIG_EXTRAIMAGES+Config::dot+(*g)->format());
     622            QStringList::ConstIterator e = extraImages.begin();
     623            while (e != extraImages.end()) {
     624                QString userFriendlyFilePath;
     625                QString filePath = Config::findFile(config.lastLocation(),
     626                                                    imageFiles,
     627                                                    imageDirs,
     628                                                    *e,
     629                                                    imgFileExts[(*g)->format()],
     630                                                    userFriendlyFilePath);
     631                if (!filePath.isEmpty())
     632                    Config::copyFile(config.lastLocation(),
     633                                     filePath,
     634                                     userFriendlyFilePath,
     635                                     (*g)->outputDir() +
     636                                     "/images");
     637                ++e;
     638            }
     639        }
     640        ++g;
     641    }
     642#endif
     643
     644void Generator::generateModuleWarning(const ClassNode *classe,
     645                                      CodeMarker *marker)
    512646{
    513647    QString module = classe->moduleName();
    514648    if (!module.isEmpty()) {
    515649        Text text;
    516         if (Tokenizer::isTrue("defined(consoleedition)")
    517                 && !editionModuleMap["Console"].contains(module)) {
     650        if (!editionModuleMap["DesktopLight"].contains(module)) {
    518651            text << Atom::ParaLeft
    519652                 << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD)
    520                  << "This class is not part of the Qt Console Edition."
     653                 << "This class is not part of the Qt GUI Framework Edition."
    521654                 << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
    522655                 << Atom::ParaRight;
    523656        }
    524         else if (Tokenizer::isTrue("defined(desktoplightedition)")
    525                 && !editionModuleMap["DesktopLight"].contains(module)) {
     657        else if (module == "Qt3Support") {
    526658            text << Atom::ParaLeft
    527659                 << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD)
    528                  << "This class is not part of the Qt Desktop Light Edition."
    529                  << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
    530                  << Atom::ParaRight;
    531         }
    532         else if (module == "Qt3Support" && Tokenizer::isTrue("defined(opensourceedition)")) {
    533             text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD)
    534                  << "Note to Qt Desktop Light Edition users:"
     660                 << "Note to Qt GUI Framework Edition users:"
    535661                 << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
    536662                 << " This class is only available in the "
    537                  << Atom(Atom::AutoLink, "Qt Desktop Edition")
     663                 << Atom(Atom::AutoLink, "Qt Full Framework Edition")
    538664                 << "." << Atom::ParaRight;
    539665        }
     
    559685                    break;
    560686            }
    561         } else {
     687        }
     688        else {
    562689            if (markedCode.at(i) == QLatin1Char('\n')) {
    563690                column = 0;
    564             } else {
     691            }
     692            else {
    565693                if (column == 0) {
    566694                    for (int j = 0; j < level; j++)
     
    631759{
    632760    Location::internalError(tr("unknown atom type '%1' in %2 generator")
    633                              .arg(atom->typeString()).arg(format()));
     761                            .arg(atom->typeString()).arg(format()));
    634762}
    635763
     
    660788                    }
    661789                }
    662             } else if (!func->name().isEmpty()) {
     790            }
     791            else if (!func->name().isEmpty()) {
    663792                alternateName = "set";
    664793                alternateName += func->name()[0].toUpper();
     
    716845        break;
    717846    case Node::Preliminary:
    718         text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) << "This "
    719              << typeString(node) << " is under development and is subject to change."
    720              << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << Atom::ParaRight;
     847        text << Atom::ParaLeft
     848             << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD)
     849             << "This "
     850             << typeString(node)
     851             << " is under development and is subject to change."
     852             << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
     853             << Atom::ParaRight;
    721854        break;
    722855    case Node::Deprecated:
     
    736869        if (node->isInnerNode())
    737870            text << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD);
    738         text << " It is provided to keep old source code working. We strongly advise against "
     871        text << " It is provided to keep old source code working. "
     872             << "We strongly advise against "
    739873             << "using it in new code." << Atom::ParaRight;
    740874        break;
     
    742876        // reimplemented in HtmlGenerator subclass
    743877        if (node->isInnerNode()) {
    744             text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) << "This "
    745                  << typeString(node) << " is part of the Qt 3 compatibility layer."
     878            text << Atom::ParaLeft
     879                 << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD)
     880                 << "This "
     881                 << typeString(node)
     882                 << " is part of the Qt 3 compatibility layer."
    746883                 << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
    747                  << " It is provided to keep old source code working. We strongly advise against "
     884                 << " It is provided to keep old source code working. "
     885                 << "We strongly advise against "
    748886                 << "using it in new code. See "
    749887                 << Atom(Atom::AutoLink, "Porting to Qt 4")
     
    763901    Text text;
    764902    Text theStockLink;
    765     Node::ThreadSafeness parent = node->parent()->inheritedThreadSafeness();
    766 
    767     switch (node->threadSafeness()) {
     903    Node::ThreadSafeness threadSafeness = node->threadSafeness();
     904
     905    Text rlink;
     906    rlink << Atom(Atom::Link,"reentrant")
     907          << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
     908          << "reentrant"
     909          << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
     910
     911    Text tlink;
     912    tlink << Atom(Atom::Link,"thread-safe")
     913          << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
     914          << "thread-safe"
     915          << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
     916
     917    switch (threadSafeness) {
    768918    case Node::UnspecifiedSafeness:
    769919        break;
    770920    case Node::NonReentrant:
    771         text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) << "Warning:"
    772              << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << " This "
    773              << typeString(node) << " is not " << stockLink("reentrant") << "." << Atom::ParaRight;
     921        text << Atom::ParaLeft
     922             << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD)
     923             << "Warning:"
     924             << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD)
     925             << " This "
     926             << typeString(node)
     927             << " is not "
     928             << rlink
     929             << "."
     930             << Atom::ParaRight;
    774931        break;
    775932    case Node::Reentrant:
    776933    case Node::ThreadSafe:
    777         text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD);
    778         if (parent == Node::ThreadSafe) {
    779             text << "Warning:";
    780         } else {
    781             text << "Note:";
    782         }
    783         text << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << " ";
    784 
    785         if (node->threadSafeness() == Node::ThreadSafe)
    786             theStockLink = stockLink("thread-safe");
    787         else
    788             theStockLink = stockLink("reentrant");
     934        text << Atom::ParaLeft
     935             << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD)
     936             << "Note:"
     937             << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD)
     938             << " ";
    789939
    790940        if (node->isInnerNode()) {
    791             const InnerNode *innerNode = static_cast<const InnerNode *>(node);
    792             text << "All the functions in this " << typeString(node) << " are "
    793                  << theStockLink;
    794 
    795             NodeList except;
     941            const InnerNode* innerNode = static_cast<const InnerNode*>(node);
     942            text << "All functions in this "
     943                 << typeString(node)
     944                 << " are ";
     945            if (threadSafeness == Node::ThreadSafe)
     946                text << tlink;
     947            else
     948                text << rlink;
     949
     950            bool exceptions = false;
     951            NodeList reentrant;
     952            NodeList threadsafe;
     953            NodeList nonreentrant;
    796954            NodeList::ConstIterator c = innerNode->childNodes().begin();
    797955            while (c != innerNode->childNodes().end()) {
    798                 if ((*c)->threadSafeness() != Node::UnspecifiedSafeness)
    799                     except.append(*c);
     956                switch ((*c)->threadSafeness()) {
     957                case Node::Reentrant:
     958                    reentrant.append(*c);
     959                    if (threadSafeness == Node::ThreadSafe)
     960                        exceptions = true;
     961                    break;
     962                case Node::ThreadSafe:
     963                    threadsafe.append(*c);
     964                    if (threadSafeness == Node::Reentrant)
     965                        exceptions = true;
     966                    break;
     967                case Node::NonReentrant:
     968                    nonreentrant.append(*c);
     969                    exceptions = true;
     970                    break;
     971                default:
     972                    break;
     973                }
    800974                ++c;
    801975            }
    802             if (except.isEmpty()) {
     976            if (!exceptions)
    803977                text << ".";
    804             }
    805             else {
    806                 text << ", except ";
    807 
    808                 NodeList::ConstIterator e = except.begin();
    809                 int index = 0;
    810                 while (e != except.end()) {
    811                     appendFullName(text, *e, innerNode, marker);
    812                     text << separator(index++, except.count());
    813                     ++e;
     978            else if (threadSafeness == Node::Reentrant) {
     979                if (nonreentrant.isEmpty()) {
     980                    if (!threadsafe.isEmpty()) {
     981                        text << ", but ";
     982                        appendFullNames(text,threadsafe,innerNode,marker);
     983                        singularPlural(text,threadsafe);
     984                        text << " also " << tlink << ".";
     985                    }
     986                    else
     987                        text << ".";
     988                }
     989                else {
     990                    text << ", except for ";
     991                    appendFullNames(text,nonreentrant,innerNode,marker);
     992                    text << ", which";
     993                    singularPlural(text,nonreentrant);
     994                    text << " nonreentrant.";
     995                    if (!threadsafe.isEmpty()) {
     996                        text << " ";
     997                        appendFullNames(text,threadsafe,innerNode,marker);
     998                        singularPlural(text,threadsafe);
     999                        text << " " << tlink << ".";
     1000                    }
     1001                }
     1002            }
     1003            else { // thread-safe
     1004                if (!nonreentrant.isEmpty() || !reentrant.isEmpty()) {
     1005                    text << ", except for ";
     1006                    if (!reentrant.isEmpty()) {
     1007                        appendFullNames(text,reentrant,innerNode,marker);
     1008                        text << ", which";
     1009                        singularPlural(text,reentrant);
     1010                        text << " only " << rlink;
     1011                        if (!nonreentrant.isEmpty())
     1012                            text << ", and ";
     1013                    }
     1014                    if (!nonreentrant.isEmpty()) {
     1015                        appendFullNames(text,nonreentrant,innerNode,marker);
     1016                        text << ", which";
     1017                        singularPlural(text,nonreentrant);
     1018                        text << " nonreentrant.";
     1019                    }
     1020                    text << ".";
    8141021                }
    8151022            }
    8161023        }
    8171024        else {
    818             text << "This " << typeString(node) << " is " << theStockLink << ".";
     1025            text << "This " << typeString(node) << " is ";
     1026            if (threadSafeness == Node::ThreadSafe)
     1027                text << tlink;
     1028            else
     1029                text << rlink;
     1030            text << ".";
    8191031        }
    8201032        text << Atom::ParaRight;
    8211033    }
    822     generateText(text, node, marker);
     1034    generateText(text,node,marker);
    8231035}
    8241036
     
    8271039    if (!node->since().isEmpty()) {
    8281040        Text text;
    829         text << Atom::ParaLeft << "This " << typeString(node)
     1041        text << Atom::ParaLeft
     1042             << "This "
     1043             << typeString(node)
    8301044             << " was introduced in ";
    8311045        if (project.isEmpty())
     
    8571071    if (func->reimplementedFrom() != 0) {
    8581072        const FunctionNode *from = func->reimplementedFrom();
    859         if (from->access() != Node::Private && from->parent()->access() != Node::Private) {
     1073        if (from->access() != Node::Private &&
     1074            from->parent()->access() != Node::Private) {
    8601075            Text text;
    8611076            text << Atom::ParaLeft << "Reimplemented from ";
    862             appendFullName(text, from->parent(), func, marker, from);
     1077            QString fullName =  from->parent()->name() + "::" + from->name() + "()";
     1078            appendFullName(text, from->parent(), fullName, from);
    8631079            text << "." << Atom::ParaRight;
    8641080            generateText(text, func, marker);
     
    8981114            if (atom->type() == Atom::FormatEndif) {
    8991115                if (generate && numAtoms0 == numAtoms) {
    900                     relative->location().warning(tr("Output format %1 not handled").
    901                                                  arg(format()));
     1116                    relative->location().warning(tr("Output format %1 not handled")
     1117                                                 .arg(format()));
    9021118                    Atom unhandledFormatAtom(Atom::UnhandledFormat, format());
    9031119                    generateAtomList(&unhandledFormatAtom,
     
    9101126            }
    9111127        }
    912         else if (atom->type() == Atom::FormatElse || atom->type() == Atom::FormatEndif) {
     1128        else if (atom->type() == Atom::FormatElse ||
     1129                 atom->type() == Atom::FormatEndif) {
    9131130            return atom;
    9141131        }
     
    9401157}
    9411158
     1159void Generator::appendFullName(Text& text,
     1160                               const Node *apparentNode,
     1161                               const QString& fullName,
     1162                               const Node *actualNode)
     1163{
     1164    if (actualNode == 0)
     1165        actualNode = apparentNode;
     1166    text << Atom(Atom::LinkNode, CodeMarker::stringForNode(actualNode))
     1167         << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
     1168         << Atom(Atom::String, fullName)
     1169         << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
     1170}
     1171
     1172void Generator::appendFullNames(Text& text,
     1173                                const NodeList& nodes,
     1174                                const Node* relative,
     1175                                CodeMarker* marker)
     1176{
     1177    NodeList::ConstIterator n = nodes.begin();
     1178    int index = 0;
     1179    while (n != nodes.end()) {
     1180        appendFullName(text,*n,relative,marker);
     1181        text << comma(index++,nodes.count());
     1182        ++n;
     1183    }
     1184}
     1185
    9421186void Generator::appendSortedNames(Text& text,
    9431187                                  const ClassNode *classe,
     
    9511195    r = classes.begin();
    9521196    while (r != classes.end()) {
    953         if ((*r).node->access() == Node::Public && (*r).node->status() != Node::Internal
     1197        if ((*r).node->access() == Node::Public &&
     1198            (*r).node->status() != Node::Internal
    9541199            && !(*r).node->doc().isEmpty()) {
    9551200            Text className;
  • trunk/tools/qdoc3/generator.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    9494    virtual void generateFakeNode(const FakeNode *fake, CodeMarker *marker);
    9595
    96     virtual void generateText(const Text& text,
     96    virtual bool generateText(const Text& text,
    9797                              const Node *relative,
    9898                              CodeMarker *marker);
    9999#ifdef QDOC_QML
    100     virtual void generateQmlText(const Text& text,
     100    virtual bool generateQmlText(const Text& text,
    101101                                 const Node *relative,
    102                                  CodeMarker *marker);
     102                                 CodeMarker *marker,
     103                                 const QString& qmlName);
     104    virtual void generateQmlInherits(const QmlClassNode* cn,
     105                                     CodeMarker* marker);
    103106#endif
    104107    virtual void generateBody(const Node *node, CodeMarker *marker);
     
    117120                                 bool generate,
    118121                                 int& numGeneratedAtoms);
     122    void generateFileList(const FakeNode* fake,
     123                          CodeMarker* marker,
     124                          Node::SubType subtype,
     125                          const QString& tag);
    119126    void generateExampleFiles(const FakeNode *fake, CodeMarker *marker);
    120127    void generateModuleWarning(const ClassNode *classe, CodeMarker *marker);
     
    151158                        CodeMarker *marker,
    152159                        const Node *actualNode = 0);
     160    void appendFullName(Text& text,
     161                        const Node *apparentNode,
     162                        const QString& fullName,
     163                        const Node *actualNode);
     164    void appendFullNames(Text& text,
     165                         const NodeList& nodes,
     166                         const Node* relative,
     167                         CodeMarker* marker);
    153168    void appendSortedNames(Text& text,
    154169                           const ClassNode *classe,
     
    169184    static QStringList imageFiles;
    170185    static QStringList imageDirs;
     186    static QStringList exampleDirs;
     187    static QStringList exampleImgExts;
    171188    static QString outDir;
    172189    static QString project;
  • trunk/tools/qdoc3/helpprojectwriter.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    119119    typeHash["target"] = Node::Target;
    120120
    121     QHash<QString, FakeNode::SubType> subTypeHash;
    122     subTypeHash["example"] = FakeNode::Example;
    123     subTypeHash["headerfile"] = FakeNode::HeaderFile;
    124     subTypeHash["file"] = FakeNode::File;
    125     subTypeHash["group"] = FakeNode::Group;
    126     subTypeHash["module"] = FakeNode::Module;
    127     subTypeHash["page"] = FakeNode::Page;
    128     subTypeHash["externalpage"] = FakeNode::ExternalPage;
    129 
    130     QSet<FakeNode::SubType> allSubTypes = QSet<FakeNode::SubType>::fromList(subTypeHash.values());
     121    QHash<QString, Node::SubType> subTypeHash;
     122    subTypeHash["example"] = Node::Example;
     123    subTypeHash["headerfile"] = Node::HeaderFile;
     124    subTypeHash["file"] = Node::File;
     125    subTypeHash["group"] = Node::Group;
     126    subTypeHash["module"] = Node::Module;
     127    subTypeHash["page"] = Node::Page;
     128    subTypeHash["externalpage"] = Node::ExternalPage;
     129#ifdef QDOC_QML
     130    subTypeHash["qmlclass"] = Node::QmlClass;
     131#endif
     132
     133    QSet<Node::SubType> allSubTypes = QSet<Node::SubType>::fromList(subTypeHash.values());
    131134
    132135    foreach (const QString &selector, selectors) {
     
    140143            pieces = pieces[1].split(",");
    141144            if (typeHash.contains(lower)) {
    142                 QSet<FakeNode::SubType> subTypes;
     145                QSet<Node::SubType> subTypes;
    143146                for (int i = 0; i < pieces.size(); ++i) {
    144147                    QString lower = pieces[i].toLower();
     
    185188    } else if (node->type() == Node::Fake) {
    186189        const FakeNode *fake = static_cast<const FakeNode *>(node);
    187         details << fake->fullTitle();
    188         details << fake->fullTitle();
     190#ifdef QDOC_QML
     191        if (fake->subType() == Node::QmlClass) {
     192            details << (QmlClassNode::qmlOnly ? fake->name() : fake->fullTitle());
     193            details << "QML." + fake->name();
     194        } else
     195#endif
     196        {
     197            details << fake->fullTitle();
     198            details << fake->fullTitle();
     199        }
    189200    } else {
    190201        details << node->name();
     
    236247                const FakeNode *fakeNode = static_cast<const FakeNode *>(node);
    237248                if (subproject.selectors[node->type()].contains(fakeNode->subType()) &&
    238                     fakeNode->subType() != FakeNode::ExternalPage &&
     249                    fakeNode->subType() != Node::ExternalPage &&
    239250                    !fakeNode->fullTitle().isEmpty())
    240251
     
    325336        case Node::Fake: {
    326337            const FakeNode *fakeNode = static_cast<const FakeNode*>(node);
    327             if (fakeNode->subType() != FakeNode::ExternalPage &&
     338            if (fakeNode->subType() != Node::ExternalPage &&
    328339                !fakeNode->fullTitle().isEmpty()) {
    329340
    330                 if (fakeNode->subType() != FakeNode::File) {
     341                if (fakeNode->subType() != Node::File) {
    331342                    if (fakeNode->doc().hasKeywords()) {
    332343                        foreach (const Atom *keyword, fakeNode->doc().keywords()) {
     
    486497            //            qDebug() << "Title:" << fakeNode->fullTitle();
    487498           
    488             if (fakeNode->subType() == FakeNode::HeaderFile) {
     499            if (fakeNode->subType() == Node::HeaderFile) {
    489500
    490501                // Write subsections for all members, obsolete members and Qt 3
     
    610621                        writeNode(project, writer, nextPage);
    611622                        nextTitle = nextPage->links().value(Node::NextLink).first;
    612                         if (nextTitle.isEmpty())
     623                        if(nextTitle.isEmpty())
    613624                            break;
    614625                        nextPage = const_cast<FakeNode *>(tree->findFakeNodeByTitle(nextTitle));
  • trunk/tools/qdoc3/helpprojectwriter.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/htmlgenerator.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6060#define COMMAND_VERSION                 Doc::alias("version")
    6161
     62QString HtmlGenerator::sinceTitles[] =
     63    {
     64        "    New Namespaces",
     65        "    New Classes",
     66        "    New Member Functions",
     67        "    New Functions in Namespaces",
     68        "    New Global Functions",
     69        "    New Macros",
     70        "    New Enum Types",
     71        "    New Typedefs",
     72        "    New Properties",
     73        "    New Variables",
     74        "    New Qml Properties",
     75        "    New Qml Signals",
     76        "    New Qml Methods",
     77        ""
     78    };
     79
    6280static bool showBrokenLinks = false;
    63 
    64 HtmlGenerator::HtmlGenerator()
    65     : helpProjectWriter(0), inLink(false), inContents(false),
    66       inSectionHeading(false), inTableHeader(false), numTableRows(0),
    67       threeColumnEnumValueTable(true), funcLeftParen("\\S(\\()"),
    68       tre(0), slow(false)
    69 {
    70 }
    71 
    72 HtmlGenerator::~HtmlGenerator()
    73 {
    74     if (helpProjectWriter)
    75         delete helpProjectWriter;
    76 }
    77 
    78 void HtmlGenerator::initializeGenerator(const Config &config)
    79 {
    80     static const struct {
    81         const char *key;
    82         const char *left;
    83         const char *right;
    84     } defaults[] = {
    85         { ATOM_FORMATTING_BOLD, "<b>", "</b>" },
    86         { ATOM_FORMATTING_INDEX, "<!--", "-->" },
    87         { ATOM_FORMATTING_ITALIC, "<i>", "</i>" },
    88         { ATOM_FORMATTING_PARAMETER, "<i>", "</i>" },
    89         { ATOM_FORMATTING_SUBSCRIPT, "<sub>", "</sub>" },
    90         { ATOM_FORMATTING_SUPERSCRIPT, "<sup>", "</sup>" },
    91         { ATOM_FORMATTING_TELETYPE, "<tt>", "</tt>" },
    92         { ATOM_FORMATTING_UNDERLINE, "<u>", "</u>" },
    93         { 0, 0, 0 }
    94     };
    95 
    96     Generator::initializeGenerator(config);
    97     setImageFileExtensions(QStringList() << "png" << "jpg" << "jpeg" << "gif");
    98     int i = 0;
    99     while (defaults[i].key) {
    100         formattingLeftMap().insert(defaults[i].key, defaults[i].left);
    101         formattingRightMap().insert(defaults[i].key, defaults[i].right);
    102         i++;
    103     }
    104 
    105     style = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_STYLE);
    106     postHeader = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_POSTHEADER);
    107     footer = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_FOOTER);
    108     address = config.getString(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_ADDRESS);
    109     pleaseGenerateMacRef = config.getBool(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_GENERATEMACREFS);
    110 
    111     project = config.getString(CONFIG_PROJECT);
    112 
    113     projectDescription = config.getString(CONFIG_DESCRIPTION);
    114     if (projectDescription.isEmpty() && !project.isEmpty())
    115         projectDescription = project + " Reference Documentation";
    116 
    117     projectUrl = config.getString(CONFIG_URL);
    118 
    119     QSet<QString> editionNames = config.subVars(CONFIG_EDITION);
    120     QSet<QString>::ConstIterator edition = editionNames.begin();
    121     while (edition != editionNames.end()) {
    122         QString editionName = *edition;
    123         QStringList editionModules = config.getStringList(
    124             CONFIG_EDITION + Config::dot + editionName + Config::dot + "modules");
    125         QStringList editionGroups = config.getStringList(
    126             CONFIG_EDITION + Config::dot + editionName + Config::dot + "groups");
    127 
    128         if (!editionModules.isEmpty())
    129             editionModuleMap[editionName] = editionModules;
    130         if (!editionGroups.isEmpty())
    131             editionGroupMap[editionName] = editionGroups;
    132 
    133         ++edition;
    134     }
    135 
    136     slow = config.getBool(CONFIG_SLOW);
    137 
    138     stylesheets = config.getStringList(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_STYLESHEETS);
    139     customHeadElements = config.getStringList(HtmlGenerator::format() + Config::dot + HTMLGENERATOR_CUSTOMHEADELEMENTS);
    140     codeIndent = config.getInt(CONFIG_CODEINDENT);
    141 
    142     helpProjectWriter = new HelpProjectWriter(config, project.toLower() + ".qhp");
    143 }
    144 
    145 void HtmlGenerator::terminateGenerator()
    146 {
    147     Generator::terminateGenerator();
    148 }
    149 
    150 QString HtmlGenerator::format()
    151 {
    152     return "HTML";
    153 }
    154 
    155 /*!
    156   This is where the html files and dcf files are written.
    157   \note The html file generation is done in the base class,
    158   PageGenerator::generateTree().
    159  */
    160 void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker)
    161 {
    162     // Copy the stylesheets from the directory containing the qdocconf file.
    163     // ### This should be changed to use a special directory in doc/src.
    164     QStringList::ConstIterator styleIter = stylesheets.begin();
    165     QDir configPath = QDir::current();
    166     while (styleIter != stylesheets.end()) {
    167         QString filePath = configPath.absoluteFilePath(*styleIter);
    168         Config::copyFile(Location(), filePath, filePath, outputDir());
    169         ++styleIter;
    170     }
    171 
    172     tre = tree;
    173     nonCompatClasses.clear();
    174     mainClasses.clear();
    175     compatClasses.clear();
    176     moduleClassMap.clear();
    177     moduleNamespaceMap.clear();
    178     funcIndex.clear();
    179     legaleseTexts.clear();
    180     serviceClasses.clear();
    181     findAllClasses(tree->root());
    182     findAllFunctions(tree->root());
    183     findAllLegaleseTexts(tree->root());
    184     findAllNamespaces(tree->root());
    185 #ifdef ZZZ_QDOC_QML   
    186     findAllQmlClasses(tree->root());
    187 #endif   
    188 
    189     PageGenerator::generateTree(tree, marker);
    190 
    191     dcfClassesRoot.ref = "classes.html";
    192     dcfClassesRoot.title = "Classes";
    193     qSort(dcfClassesRoot.subsections);
    194 
    195     dcfOverviewsRoot.ref = "overviews.html";
    196     dcfOverviewsRoot.title = "Overviews";
    197     qSort(dcfOverviewsRoot.subsections);
    198 
    199     dcfExamplesRoot.ref = "examples.html";
    200     dcfExamplesRoot.title = "Tutorial & Examples";
    201     qSort(dcfExamplesRoot.subsections);
    202 
    203     DcfSection qtRoot;
    204     appendDcfSubSection(&qtRoot, dcfClassesRoot);
    205     appendDcfSubSection(&qtRoot, dcfOverviewsRoot);
    206     appendDcfSubSection(&qtRoot, dcfExamplesRoot);
    207 
    208     generateDcf(project.toLower().simplified().replace(" ", "-"),
    209                 "index.html",
    210                 projectDescription, qtRoot);
    211     generateDcf("designer",
    212                 "designer-manual.html",
    213                 "Qt Designer Manual",
    214                 dcfDesignerRoot);
    215     generateDcf("linguist",
    216                 "linguist-manual.html",
    217                 "Qt Linguist Manual",
    218                 dcfLinguistRoot);
    219     generateDcf("assistant",
    220                 "assistant-manual.html",
    221                 "Qt Assistant Manual",
    222                 dcfAssistantRoot);
    223     generateDcf("qmake",
    224                 "qmake-manual.html",
    225                 "qmake Manual",
    226                 dcfQmakeRoot);
    227 
    228     generateIndex(project.toLower().simplified().replace(" ", "-"),
    229                   projectUrl,
    230                   projectDescription);
    231 
    232     helpProjectWriter->generate(tre);
    233 }
    234 
    235 void HtmlGenerator::startText(const Node * /* relative */,
    236                               CodeMarker * /* marker */)
    237 {
    238     inLink = false;
    239     inContents = false;
    240     inSectionHeading = false;
    241     inTableHeader = false;
    242     numTableRows = 0;
    243     threeColumnEnumValueTable = true;
    244     link.clear();
    245     sectionNumber.clear();
    246 }
    247 
    248 int HtmlGenerator::generateAtom(const Atom *atom,
    249                                 const Node *relative,
    250                                 CodeMarker *marker)
    251 {
    252     int skipAhead = 0;
    253     static bool in_para = false;
    254 
    255     switch (atom->type()) {
    256     case Atom::AbstractLeft:
    257         break;
    258     case Atom::AbstractRight:
    259         break;
    260     case Atom::AutoLink:
    261         if (!inLink && !inContents && !inSectionHeading) {
    262             const Node *node = 0;
    263             QString link = getLink(atom, relative, marker, node);
    264             if (!link.isEmpty()) {
    265                 beginLink(link, node, relative, marker);
    266                 generateLink(atom, relative, marker);
    267                 endLink();
    268             }
    269             else {
    270                 out() << protect(atom->string());
    271             }
    272         }
    273         else {
    274             out() << protect(atom->string());
    275         }
    276         break;
    277     case Atom::BaseName:
    278         break;
    279     case Atom::BriefLeft:
    280         if (relative->type() == Node::Fake) {
    281             skipAhead = skipAtoms(atom, Atom::BriefRight);
    282             break;
    283         }
    284 
    285         out() << "<p>";
    286         if (relative->type() == Node::Property ||
    287             relative->type() == Node::Variable) {
    288             QString str;
    289             atom = atom->next();
    290             while (atom != 0 && atom->type() != Atom::BriefRight) {
    291                 if (atom->type() == Atom::String || atom->type() == Atom::AutoLink)
    292                     str += atom->string();
    293                 skipAhead++;
    294                 atom = atom->next();
    295             }
    296             str[0] = str[0].toLower();
    297             if (str.right(1) == ".")
    298                 str.truncate(str.length() - 1);
    299             out() << "This ";
    300             if (relative->type() == Node::Property)
    301                 out() << "property";
    302             else
    303                 out() << "variable";
    304             QStringList words = str.split(" ");
    305             if (!(words.first() == "contains" || words.first() == "specifies"
    306                 || words.first() == "describes" || words.first() == "defines"
    307                 || words.first() == "holds" || words.first() == "determines"))
    308                 out() << " holds ";
    309             else
    310                 out() << " ";
    311             out() << str << ".";
    312         }
    313         break;
    314     case Atom::BriefRight:
    315         if (relative->type() != Node::Fake)
    316             out() << "</p>\n";
    317         break;
    318     case Atom::C:
    319         out() << formattingLeftMap()[ATOM_FORMATTING_TELETYPE];
    320         if (inLink) {
    321             out() << protect(plainCode(atom->string()));
    322         }
    323         else {
    324             out() << highlightedCode(atom->string(), marker, relative);
    325         }
    326         out() << formattingRightMap()[ATOM_FORMATTING_TELETYPE];
    327         break;
    328     case Atom::Code:
    329         out() << "<pre>" << trimmedTrailing(highlightedCode(indent(codeIndent, atom->string()),
    330                                                             marker, relative))
    331               << "</pre>\n";
    332         break;
    333 #ifdef QDOC_QML       
    334     case Atom::Qml:
    335         out() << "<pre>" << trimmedTrailing(highlightedCode(indent(codeIndent, atom->string()),
    336                                                             marker, relative))
    337               << "</pre>\n";
    338         break;
    339 #endif       
    340     case Atom::CodeNew:
    341         out() << "<p>you can rewrite it as</p>\n"
    342               << "<pre>" << trimmedTrailing(highlightedCode(indent(codeIndent, atom->string()),
    343                                                             marker, relative))
    344               << "</pre>\n";
    345         break;
    346     case Atom::CodeOld:
    347         out() << "<p>For example, if you have code like</p>\n";
    348         // fallthrough
    349     case Atom::CodeBad:
    350         out() << "<pre><font color=\"#404040\">"
    351               << trimmedTrailing(protect(plainCode(indent(codeIndent, atom->string()))))
    352               << "</font></pre>\n";
    353         break;
    354     case Atom::FootnoteLeft:
    355         // ### For now
    356         if (in_para) {
    357             out() << "</p>\n";
    358             in_para = false;
    359         }
    360         out() << "<!-- ";
    361         break;
    362     case Atom::FootnoteRight:
    363         // ### For now
    364         out() << "-->";
    365         break;
    366     case Atom::FormatElse:
    367     case Atom::FormatEndif:
    368     case Atom::FormatIf:
    369         break;
    370     case Atom::FormattingLeft:
    371         out() << formattingLeftMap()[atom->string()];
    372         if (atom->string() == ATOM_FORMATTING_PARAMETER) {
    373             if (atom->next() != 0 && atom->next()->type() == Atom::String) {
    374                 QRegExp subscriptRegExp("([a-z]+)_([0-9n])");
    375                 if (subscriptRegExp.exactMatch(atom->next()->string())) {
    376                     out() << subscriptRegExp.cap(1) << "<sub>"
    377                           << subscriptRegExp.cap(2) << "</sub>";
    378                     skipAhead = 1;
    379                 }
    380             }
    381         }
    382         break;
    383     case Atom::FormattingRight:
    384         if (atom->string() == ATOM_FORMATTING_LINK) {
    385             endLink();
    386         }
    387         else {
    388             out() << formattingRightMap()[atom->string()];
    389         }
    390         break;
    391     case Atom::GeneratedList:
    392         if (atom->string() == "annotatedclasses") {
    393             generateAnnotatedList(relative, marker, nonCompatClasses);
    394         }
    395         else if (atom->string() == "classes") {
    396             generateCompactList(relative, marker, nonCompatClasses);
    397         }
    398         else if (atom->string().contains("classesbymodule")) {
    399             QString arg = atom->string().trimmed();
    400             QString moduleName = atom->string().mid(atom->string().indexOf(
    401                 "classesbymodule") + 15).trimmed();
    402             if (moduleClassMap.contains(moduleName))
    403                 generateAnnotatedList(relative, marker, moduleClassMap[moduleName]);
    404         }
    405         else if (atom->string().contains("classesbyedition")) {
    406 
    407             QString arg = atom->string().trimmed();
    408             QString editionName = atom->string().mid(atom->string().indexOf(
    409                 "classesbyedition") + 16).trimmed();
    410 
    411             if (editionModuleMap.contains(editionName)) {
    412 
    413                 // Add all classes in the modules listed for that edition.
    414                 QMap<QString, const Node *> editionClasses;
    415                 foreach (const QString &moduleName, editionModuleMap[editionName]) {
    416                     if (moduleClassMap.contains(moduleName))
    417                         editionClasses.unite(moduleClassMap[moduleName]);
    418                 }
    419 
    420                 // Add additional groups and remove groups of classes that
    421                 // should be excluded from the edition.
    422 
    423                 QMultiMap <QString, Node *> groups = tre->groups();
    424                 foreach (const QString &groupName, editionGroupMap[editionName]) {
    425                     QList<Node *> groupClasses;
    426                     if (groupName.startsWith("-")) {
    427                         groupClasses = groups.values(groupName.mid(1));
    428                         foreach (const Node *node, groupClasses)
    429                             editionClasses.remove(node->name());
    430                     }
    431                     else {
    432                         groupClasses = groups.values(groupName);
    433                         foreach (const Node *node, groupClasses)
    434                             editionClasses.insert(node->name(), node);
    435                     }
    436                 }
    437                 generateAnnotatedList(relative, marker, editionClasses);
    438             }
    439         }
    440         else if (atom->string() == "classhierarchy") {
    441             generateClassHierarchy(relative, marker, nonCompatClasses);
    442         }
    443         else if (atom->string() == "compatclasses") {
    444             generateCompactList(relative, marker, compatClasses);
    445         }
    446         else if (atom->string() == "functionindex") {
    447             generateFunctionIndex(relative, marker);
    448         }
    449         else if (atom->string() == "legalese") {
    450             generateLegaleseList(relative, marker);
    451         }
    452         else if (atom->string() == "mainclasses") {
    453             generateCompactList(relative, marker, mainClasses);
    454         }
    455         else if (atom->string() == "services") {
    456             generateCompactList(relative, marker, serviceClasses);
    457         }
    458         else if (atom->string() == "overviews") {
    459             generateOverviewList(relative, marker);
    460         }
    461         else if (atom->string() == "namespaces") {
    462             generateAnnotatedList(relative, marker, namespaceIndex);
    463         }
    464         else if (atom->string() == "related") {
    465             const FakeNode *fake = static_cast<const FakeNode *>(relative);
    466             if (fake && !fake->groupMembers().isEmpty()) {
    467                 QMap<QString, const Node *> groupMembersMap;
    468                 foreach (const Node *node, fake->groupMembers()) {
    469                     if (node->type() == Node::Fake)
    470                         groupMembersMap[fullName(node, relative, marker)] = node;
    471                 }
    472                 generateAnnotatedList(fake, marker, groupMembersMap);
    473             }
    474         }
    475         else if (atom->string() == "relatedinline") {
    476             const FakeNode *fake = static_cast<const FakeNode *>(relative);
    477             if (fake && !fake->groupMembers().isEmpty()) {
    478                 // Reverse the list into the original scan order.
    479                 // Should be sorted.  But on what?  It may not be a
    480                 // regular class or page definition.
    481                 QList<const Node *> list;
    482                 foreach (const Node *node, fake->groupMembers())
    483                     list.prepend(node);
    484                 foreach (const Node *node, list)
    485                     generateBody(node, marker);
    486             }
    487         }
    488         break;
    489     case Atom::Image:
    490     case Atom::InlineImage:
    491         {
    492             QString fileName = imageFileName(relative, atom->string());
    493             QString text;
    494             if (atom->next() != 0)
    495                 text = atom->next()->string();
    496             if (atom->type() == Atom::Image)
    497                 out() << "<p align=\"center\">";
    498             if (fileName.isEmpty()) {
    499                 out() << "<font color=\"red\">[Missing image "
    500                       << protect(atom->string()) << "]</font>";
    501             }
    502             else {
    503                 out() << "<img src=\"" << protect(fileName) << "\"";
    504                 if (!text.isEmpty())
    505                     out() << " alt=\"" << protect(text) << "\"";
    506                 out() << " />";
    507                 helpProjectWriter->addExtraFile(fileName);
    508             }
    509             if (atom->type() == Atom::Image)
    510                 out() << "</p>";
    511         }
    512         break;
    513     case Atom::ImageText:
    514         break;
    515     case Atom::LegaleseLeft:
    516         out() << "<div style=\"padding: 0.5em; background: #e0e0e0; color: black\">";
    517         break;
    518     case Atom::LegaleseRight:
    519         out() << "</div>";
    520         break;
    521     case Atom::LineBreak:
    522         out() << "<br />";
    523         break;
    524     case Atom::Link:
    525         {
    526             const Node *node = 0;
    527             QString myLink = getLink(atom, relative, marker, node);
    528             if (myLink.isEmpty())
    529                 relative->doc().location().warning(tr("Cannot link to '%1' in %2")
    530                         .arg(atom->string())
    531                         .arg(marker->plainFullName(relative)));
    532             beginLink(myLink, node, relative, marker);
    533             skipAhead = 1;
    534         }
    535         break;
    536     case Atom::LinkNode:
    537         {
    538             const Node *node = CodeMarker::nodeForString(atom->string());
    539             beginLink(linkForNode(node, relative), node, relative, marker);
    540             skipAhead = 1;
    541         }
    542         break;
    543     case Atom::ListLeft:
    544         if (in_para) {
    545             out() << "</p>\n";
    546             in_para = false;
    547         }
    548         if (atom->string() == ATOM_LIST_BULLET) {
    549             out() << "<ul>\n";
    550         }
    551         else if (atom->string() == ATOM_LIST_TAG) {
    552             out() << "<dl>\n";
    553         }
    554         else if (atom->string() == ATOM_LIST_VALUE) {
    555             threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom);
    556             if (threeColumnEnumValueTable) {
    557                 out() << "<p><table border=\"1\" cellpadding=\"2\" cellspacing=\"1\" width=\"100%\">\n"
    558                          "<tr><th width=\"25%\">Constant</th><th width=\"15%\">Value</th>"
    559                          "<th width=\"60%\">Description</th></tr>\n";
    560             }
    561             else {
    562                 out() << "<p><table border=\"1\" cellpadding=\"2\" cellspacing=\"1\" width=\"40%\">\n"
    563                       << "<tr><th width=\"60%\">Constant</th><th width=\"40%\">Value</th></tr>\n";
    564             }
    565         }
    566         else {
    567             out() << "<ol type=";
    568             if (atom->string() == ATOM_LIST_UPPERALPHA) {
    569                 out() << "\"A\"";
    570             }
    571             else if (atom->string() == ATOM_LIST_LOWERALPHA) {
    572                 out() << "\"a\"";
    573             }
    574             else if (atom->string() == ATOM_LIST_UPPERROMAN) {
    575                 out() << "\"I\"";
    576             }
    577             else if (atom->string() == ATOM_LIST_LOWERROMAN) {
    578                 out() << "\"i\"";
    579             }
    580             else { // (atom->string() == ATOM_LIST_NUMERIC)
    581                 out() << "\"1\"";
    582             }
    583             if (atom->next() != 0 && atom->next()->string().toInt() != 1)
    584                 out() << " start=\"" << atom->next()->string() << "\"";
    585             out() << ">\n";
    586         }
    587         break;
    588     case Atom::ListItemNumber:
    589         break;
    590     case Atom::ListTagLeft:
    591         if (atom->string() == ATOM_LIST_TAG) {
    592             out() << "<dt>";
    593         }
    594         else { // (atom->string() == ATOM_LIST_VALUE)
    595             // ### Trenton
    596 
    597             out() << "<tr><td valign=\"top\"><tt>"
    598                   << protect(plainCode(marker->markedUpEnumValue(atom->next()->string(),
    599                                                                  relative)))
    600                   << "</tt></td><td align=\"center\" valign=\"top\">";
    601 
    602             QString itemValue;
    603             if (relative->type() == Node::Enum) {
    604                 const EnumNode *enume = static_cast<const EnumNode *>(relative);
    605                 itemValue = enume->itemValue(atom->next()->string());
    606             }
    607 
    608             if (itemValue.isEmpty())
    609                 out() << "?";
    610             else
    611                 out() << "<tt>" << protect(itemValue) << "</tt>";
    612 
    613             skipAhead = 1;
    614         }
    615         break;
    616     case Atom::ListTagRight:
    617         if (atom->string() == ATOM_LIST_TAG)
    618             out() << "</dt>\n";
    619         break;
    620     case Atom::ListItemLeft:
    621         if (atom->string() == ATOM_LIST_TAG) {
    622             out() << "<dd>";
    623         }
    624         else if (atom->string() == ATOM_LIST_VALUE) {
    625             if (threeColumnEnumValueTable) {
    626                 out() << "</td><td valign=\"top\">";
    627                 if (matchAhead(atom, Atom::ListItemRight))
    628                     out() << "&nbsp;";
    629             }
    630         }
    631         else {
    632             out() << "<li>";
    633         }
    634         if (matchAhead(atom, Atom::ParaLeft))
    635             skipAhead = 1;
    636         break;
    637     case Atom::ListItemRight:
    638         if (atom->string() == ATOM_LIST_TAG) {
    639             out() << "</dd>\n";
    640         }
    641         else if (atom->string() == ATOM_LIST_VALUE) {
    642             out() << "</td></tr>\n";
    643         }
    644         else {
    645             out() << "</li>\n";
    646         }
    647         break;
    648     case Atom::ListRight:
    649         if (atom->string() == ATOM_LIST_BULLET) {
    650             out() << "</ul>\n";
    651         }
    652         else if (atom->string() == ATOM_LIST_TAG) {
    653             out() << "</dl>\n";
    654         }
    655         else if (atom->string() == ATOM_LIST_VALUE) {
    656             out() << "</table></p>\n";
    657         }
    658         else {
    659             out() << "</ol>\n";
    660         }
    661         break;
    662     case Atom::Nop:
    663         break;
    664     case Atom::ParaLeft:
    665         out() << "<p>";
    666         in_para = true;
    667         break;
    668     case Atom::ParaRight:
    669         endLink();
    670         if (in_para) {
    671             out() << "</p>\n";
    672             in_para = false;
    673         }
    674         //if (!matchAhead(atom, Atom::ListItemRight) && !matchAhead(atom, Atom::TableItemRight))
    675         //    out() << "</p>\n";
    676         break;
    677     case Atom::QuotationLeft:
    678         out() << "<blockquote>";
    679         break;
    680     case Atom::QuotationRight:
    681         out() << "</blockquote>\n";
    682         break;
    683     case Atom::RawString:
    684         out() << atom->string();
    685         break;
    686     case Atom::SectionLeft:
    687 #if 0
    688         {
    689             int nextLevel = atom->string().toInt();
    690             if (sectionNumber.size() < nextLevel) {
    691                 do {
    692                     sectionNumber.append("1");
    693                 } while (sectionNumber.size() < nextLevel);
    694             }
    695             else {
    696                 while (sectionNumber.size() > nextLevel) {
    697                     sectionNumber.removeLast();
    698                 }
    699                 sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1);
    700             }
    701             out() << "<a name=\"sec-" << sectionNumber.join("-") << "\"></a>\n";
    702         }
    703 #else
    704         out() << "<a name=\"" << Doc::canonicalTitle(Text::sectionHeading(atom).toString())
    705               << "\"></a>\n";
    706 #endif
    707         break;
    708     case Atom::SectionRight:
    709         break;
    710     case Atom::SectionHeadingLeft:
    711         out() << "<h" + QString::number(atom->string().toInt() + hOffset(relative)) + ">";
    712         inSectionHeading = true;
    713         break;
    714     case Atom::SectionHeadingRight:
    715         out() << "</h" + QString::number(atom->string().toInt() + hOffset(relative)) + ">\n";
    716         inSectionHeading = false;
    717         break;
    718     case Atom::SidebarLeft:
    719         break;
    720     case Atom::SidebarRight:
    721         break;
    722     case Atom::String:
    723         if (inLink && !inContents && !inSectionHeading) {
    724             generateLink(atom, relative, marker);
    725         }
    726         else {
    727             out() << protect(atom->string());
    728         }
    729         break;
    730     case Atom::TableLeft:
    731         if (in_para) {
    732             out() << "</p>\n";
    733             in_para = false;
    734         }
    735         if (!atom->string().isEmpty()) {
    736             if (atom->string().contains("%"))
    737                 out() << "<p><table width=\"" << atom->string() << "\" "
    738                       << "align=\"center\" cellpadding=\"2\" "
    739                       << "cellspacing=\"1\" border=\"0\">\n";
    740             else
    741                 out() << "<p><table align=\"center\" cellpadding=\"2\" cellspacing=\"1\" border=\"0\">\n";
    742         }
    743         else {
    744             out() << "<p><table align=\"center\" cellpadding=\"2\" cellspacing=\"1\" border=\"0\">\n";
    745         }
    746         numTableRows = 0;
    747         break;
    748     case Atom::TableRight:
    749         out() << "</table></p>\n";
    750         break;
    751     case Atom::TableHeaderLeft:
    752         out() << "<thead><tr valign=\"top\" class=\"qt-style\">";
    753         inTableHeader = true;
    754         break;
    755     case Atom::TableHeaderRight:
    756         out() << "</tr>";
    757         if (matchAhead(atom, Atom::TableHeaderLeft)) {
    758             skipAhead = 1;
    759             out() << "\n<tr valign=\"top\" class=\"qt-style\">";
    760         }
    761         else {
    762             out() << "</thead>\n";
    763             inTableHeader = false;
    764         }
    765         break;
    766     case Atom::TableRowLeft:
    767         if (++numTableRows % 2 == 1)
    768             out() << "<tr valign=\"top\" class=\"odd\">";
    769         else
    770             out() << "<tr valign=\"top\" class=\"even\">";
    771         break;
    772     case Atom::TableRowRight:
    773         out() << "</tr>\n";
    774         break;
    775     case Atom::TableItemLeft:
    776         {
    777             if (inTableHeader)
    778                 out() << "<th";
    779             else
    780                 out() << "<td";
    781 
    782             QStringList spans = atom->string().split(",");
    783             if (spans.size() == 2) {
    784                 if (spans.at(0) != "1")
    785                     out() << " colspan=\"" << spans.at(0) << "\"";
    786                 if (spans.at(1) != "1")
    787                     out() << " rowspan=\"" << spans.at(1) << "\"";
    788                 out() << ">";
    789             }
    790             if (matchAhead(atom, Atom::ParaLeft))
    791                 skipAhead = 1;
    792         }
    793         break;
    794     case Atom::TableItemRight:
    795         if (inTableHeader)
    796             out() << "</th>";
    797         else
    798             out() << "</td>";
    799         if (matchAhead(atom, Atom::ParaLeft))
    800             skipAhead = 1;
    801         break;
    802     case Atom::TableOfContents:
    803         {
    804             int numColumns = 1;
    805             const Node *node = relative;
    806 
    807             Doc::SectioningUnit sectioningUnit = Doc::Section4;
    808             QStringList params = atom->string().split(",");
    809             QString columnText = params.at(0);
    810             QStringList pieces = columnText.split(" ", QString::SkipEmptyParts);
    811             if (pieces.size() >= 2) {
    812                 columnText = pieces.at(0);
    813                 pieces.pop_front();
    814                 QString path = pieces.join(" ").trimmed();
    815                 node = findNodeForTarget(path, relative, marker, atom);
    816             }
    817 
    818             if (params.size() == 2) {
    819                 numColumns = qMax(columnText.toInt(), numColumns);
    820                 sectioningUnit = (Doc::SectioningUnit)params.at(1).toInt();
    821             }
    822 
    823             if (node)
    824                 generateTableOfContents(node, marker, sectioningUnit, numColumns,
    825                                         relative);
    826         }
    827         break;
    828     case Atom::Target:
    829         out() << "<a name=\"" << Doc::canonicalTitle(atom->string()) << "\"></a>";
    830         break;
    831     case Atom::UnhandledFormat:
    832         out() << "<font color=\"red\"><b>&lt;Missing HTML&gt;</b></font>";
    833         break;
    834     case Atom::UnknownCommand:
    835         out() << "<font color=\"red\"><b><code>\\" << protect(atom->string())
    836               << "</code></b></font>";
    837         break;
    838 #ifdef QDOC_QML
    839     case Atom::QmlText:
    840     case Atom::EndQmlText:
    841         // don't do anything with these. They are just tags.
    842         break;
    843 #endif       
    844     default:
    845         unknownAtom(atom);
    846     }
    847     return skipAhead;
    848 }
    849 
    850 void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
    851                                           CodeMarker *marker)
    852 {
    853     QList<Section> sections;
    854     QList<Section>::ConstIterator s;
    855 
    856     const ClassNode *classe = 0;
    857     const NamespaceNode *namespasse = 0;
    858 
    859     QString title;
    860     QString rawTitle;
    861     QString fullTitle;
    862     if (inner->type() == Node::Namespace) {
    863         namespasse = static_cast<const NamespaceNode *>(inner);
    864         rawTitle = marker->plainName(inner);
    865         fullTitle = marker->plainFullName(inner);
    866         title = rawTitle + " Namespace Reference";
    867     }
    868     else if (inner->type() == Node::Class) {
    869         classe = static_cast<const ClassNode *>(inner);
    870         rawTitle = marker->plainName(inner);
    871         fullTitle = marker->plainFullName(inner);
    872         title = rawTitle + " Class Reference";
    873     }
    874 
    875     DcfSection classSection;
    876     classSection.title = title;
    877     classSection.ref = linkForNode(inner, 0);
    878     classSection.keywords += qMakePair(inner->name(), classSection.ref);
    879 
    880     Text subtitleText;
    881     if (rawTitle != fullTitle)
    882         subtitleText << "(" << Atom(Atom::AutoLink, fullTitle) << ")"
    883                      << Atom(Atom::LineBreak);
    884 
    885     QString fixedModule = inner->moduleName();
    886     if (fixedModule == "Qt3SupportLight")
    887         fixedModule = "Qt3Support";
    888     if (!fixedModule.isEmpty())
    889         subtitleText << "[" << Atom(Atom::AutoLink, fixedModule) << " module]";
    890 
    891     if (fixedModule.isEmpty()) {
    892         QMultiMap<QString, QString> publicGroups = tre->publicGroups();
    893         QList<QString> groupNames = publicGroups.values(inner->name());
    894         if (!groupNames.isEmpty()) {
    895             qSort(groupNames.begin(), groupNames.end());
    896             subtitleText << "[";
    897             for (int j=0; j<groupNames.count(); j++) {
    898                 subtitleText <<  Atom(Atom::AutoLink, groupNames[j]);
    899                 if (j<groupNames.count()-1)
    900                     subtitleText <<", ";
    901             }
    902             subtitleText << "]";
    903         }
    904     }
    905 
    906     generateHeader(title, inner, marker, true);
    907     generateTitle(title, subtitleText, SmallSubTitle, inner, marker);
    908 
    909     generateBrief(inner, marker);
    910     generateIncludes(inner, marker);
    911     generateStatus(inner, marker);
    912     if (classe) {
    913         generateModuleWarning(classe, marker);
    914         generateInherits(classe, marker);
    915         generateInheritedBy(classe, marker);
    916     }
    917     generateThreadSafeness(inner, marker);
    918     generateSince(inner, marker);
    919 
    920     out() << "<ul>\n";
    921 
    922     QString membersLink = generateListOfAllMemberFile(inner, marker);
    923     if (!membersLink.isEmpty())
    924         out() << "<li><a href=\"" << membersLink << "\">"
    925               << "List of all members, including inherited members</a></li>\n";
    926 
    927     QString obsoleteLink = generateLowStatusMemberFile(inner, marker, CodeMarker::Obsolete);
    928     if (!obsoleteLink.isEmpty())
    929         out() << "<li><a href=\"" << obsoleteLink << "\">"
    930               << "Obsolete members</a></li>\n";
    931 
    932     QString compatLink = generateLowStatusMemberFile(inner, marker, CodeMarker::Compat);
    933     if (!compatLink.isEmpty())
    934         out() << "<li><a href=\"" << compatLink << "\">"
    935               << "Qt 3 support members</a></li>\n";
    936 
    937     out() << "</ul>\n";
    938 
    939     bool needOtherSection = false;
    940 
    941     sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
    942     s = sections.begin();
    943     while (s != sections.end()) {
    944         if (s->members.isEmpty()) {
    945             if (!s->inherited.isEmpty())
    946                 needOtherSection = true;
    947         } else {
    948             out() << "<a name=\"" << registerRef((*s).name.toLower()) << "\"></a>\n";
    949             out() << "<h3>" << protect((*s).name) << "</h3>\n";
    950 
    951             generateSectionList(*s, inner, marker, CodeMarker::Summary);
    952         }
    953         ++s;
    954     }
    955 
    956     if (needOtherSection) {
    957         out() << "<h3>Additional Inherited Members</h3>\n"
    958                  "<ul>\n";
    959 
    960         s = sections.begin();
    961         while (s != sections.end()) {
    962             if (s->members.isEmpty() && !s->inherited.isEmpty())
    963                 generateSectionInheritedList(*s, inner, marker);
    964             ++s;
    965         }
    966         out() << "</ul>\n";
    967     }
    968 
    969     out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
    970 
    971     if (!inner->doc().isEmpty()) {
    972         out() << "<hr />\n"
    973               << "<h2>" << "Detailed Description" << "</h2>\n";
    974         generateBody(inner, marker);
    975         generateAlsoList(inner, marker);
    976     }
    977 
    978     sections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay);
    979     s = sections.begin();
    980     while (s != sections.end()) {
    981         out() << "<hr />\n";
    982         out() << "<h2>" << protect((*s).name) << "</h2>\n";
    983 
    984         NodeList::ConstIterator m = (*s).members.begin();
    985         while (m != (*s).members.end()) {
    986             if ((*m)->access() != Node::Private) { // ### check necessary?
    987                 if ((*m)->type() != Node::Class)
    988                     generateDetailedMember(*m, inner, marker);
    989                 else {
    990                     out() << "<h3> class ";
    991                     generateFullName(*m, inner, marker);
    992                     out() << "</h3>";
    993                     generateBrief(*m, marker, inner);
    994                 }
    995 
    996                 QStringList names;
    997                 names << (*m)->name();
    998                 if ((*m)->type() == Node::Function) {
    999                     const FunctionNode *func = reinterpret_cast<const FunctionNode *>(*m);
    1000                     if (func->metaness() == FunctionNode::Ctor || func->metaness() == FunctionNode::Dtor
    1001                             || func->overloadNumber() != 1)
    1002                         names.clear();
    1003                 } else if ((*m)->type() == Node::Property) {
    1004                     const PropertyNode *prop = reinterpret_cast<const PropertyNode *>(*m);
    1005                     if (!prop->getters().isEmpty() && !names.contains(prop->getters().first()->name()))
    1006                         names << prop->getters().first()->name();
    1007                     if (!prop->setters().isEmpty())
    1008                         names << prop->setters().first()->name();
    1009                     if (!prop->resetters().isEmpty())
    1010                         names << prop->resetters().first()->name();
    1011                 } else if ((*m)->type() == Node::Enum) {
    1012                     const EnumNode *enume = reinterpret_cast<const EnumNode *>(*m);
    1013                     if (enume->flagsType())
    1014                         names << enume->flagsType()->name();
    1015 
    1016                     foreach (const QString &enumName,
    1017                              enume->doc().enumItemNames().toSet()
    1018                              - enume->doc().omitEnumItemNames().toSet())
    1019                         names << plainCode(marker->markedUpEnumValue(enumName, enume));
    1020                 }
    1021                 foreach (const QString &name, names)
    1022                     classSection.keywords += qMakePair(name, linkForNode(*m, 0));
    1023             }
    1024             ++m;
    1025         }
    1026         ++s;
    1027     }
    1028     generateFooter(inner);
    1029 
    1030     if (!membersLink.isEmpty()) {
    1031         DcfSection membersSection;
    1032         membersSection.title = "List of all members";
    1033         membersSection.ref = membersLink;
    1034         appendDcfSubSection(&classSection, membersSection);
    1035     }
    1036     if (!obsoleteLink.isEmpty()) {
    1037         DcfSection obsoleteSection;
    1038         obsoleteSection.title = "Obsolete members";
    1039         obsoleteSection.ref = obsoleteLink;
    1040         appendDcfSubSection(&classSection, obsoleteSection);
    1041     }
    1042     if (!compatLink.isEmpty()) {
    1043         DcfSection compatSection;
    1044         compatSection.title = "Qt 3 support members";
    1045         compatSection.ref = compatLink;
    1046         appendDcfSubSection(&classSection, compatSection);
    1047     }
    1048 
    1049     appendDcfSubSection(&dcfClassesRoot, classSection);
    1050 }
    1051 
    1052 void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
    1053 {
    1054     SubTitleSize subTitleSize = LargeSubTitle;
    1055     DcfSection fakeSection;
    1056     fakeSection.title = fake->fullTitle();
    1057     fakeSection.ref = linkForNode(fake, 0);
    1058 
    1059     QList<Section> sections;
    1060     QList<Section>::const_iterator s;
    1061 
    1062     QString htmlTitle = fake->fullTitle();
    1063     if (fake->subType() == FakeNode::File && !fake->subTitle().isEmpty()) {
    1064         subTitleSize = SmallSubTitle;
    1065         htmlTitle += " (" + fake->subTitle() + ")";
    1066     }
    1067 
    1068     generateHeader(htmlTitle, fake, marker, true);
    1069     generateTitle(fake->fullTitle(), Text() << fake->subTitle(), subTitleSize,
    1070                   fake, marker);
    1071 
    1072     if (fake->subType() == FakeNode::Module) {
    1073         // Generate brief text and status for modules.
    1074         generateBrief(fake, marker);
    1075         generateStatus(fake, marker);
    1076 
    1077         if (moduleNamespaceMap.contains(fake->name())) {
    1078             out() << "<h2>Namespaces</h2>\n";
    1079             generateAnnotatedList(fake, marker, moduleNamespaceMap[fake->name()]);
    1080         }
    1081         if (moduleClassMap.contains(fake->name())) {
    1082             out() << "<h2>Classes</h2>\n";
    1083             generateAnnotatedList(fake, marker, moduleClassMap[fake->name()]);
    1084         }
    1085     }
    1086     else if (fake->subType() == FakeNode::HeaderFile) {
    1087         // Generate brief text and status for modules.
    1088         generateBrief(fake, marker);
    1089         generateStatus(fake, marker);
    1090 
    1091         out() << "<ul>\n";
    1092 
    1093         QString membersLink = generateListOfAllMemberFile(fake, marker);
    1094         if (!membersLink.isEmpty())
    1095             out() << "<li><a href=\"" << membersLink << "\">"
    1096                   << "List of all members, including inherited members</a></li>\n";
    1097 
    1098         QString obsoleteLink = generateLowStatusMemberFile(fake, marker, CodeMarker::Obsolete);
    1099         if (!obsoleteLink.isEmpty())
    1100             out() << "<li><a href=\"" << obsoleteLink << "\">"
    1101                   << "Obsolete members</a></li>\n";
    1102 
    1103         QString compatLink = generateLowStatusMemberFile(fake, marker, CodeMarker::Compat);
    1104         if (!compatLink.isEmpty())
    1105             out() << "<li><a href=\"" << compatLink << "\">"
    1106                   << "Qt 3 support members</a></li>\n";
    1107 
    1108         out() << "</ul>\n";
    1109 
    1110         if (!membersLink.isEmpty()) {
    1111             DcfSection membersSection;
    1112             membersSection.title = "List of all members";
    1113             membersSection.ref = membersLink;
    1114             appendDcfSubSection(&fakeSection, membersSection);
    1115         }
    1116         if (!obsoleteLink.isEmpty()) {
    1117             DcfSection obsoleteSection;
    1118             obsoleteSection.title = "Obsolete members";
    1119             obsoleteSection.ref = obsoleteLink;
    1120             appendDcfSubSection(&fakeSection, obsoleteSection);
    1121         }
    1122         if (!compatLink.isEmpty()) {
    1123             DcfSection compatSection;
    1124             compatSection.title = "Qt 3 support members";
    1125             compatSection.ref = compatLink;
    1126             appendDcfSubSection(&fakeSection, compatSection);
    1127         }
    1128     }
    1129 
    1130     sections = marker->sections(fake, CodeMarker::Summary, CodeMarker::Okay);
    1131     s = sections.begin();
    1132     while (s != sections.end()) {
    1133         out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
    1134         out() << "<h3>" << protect((*s).name) << "</h3>\n";
    1135         generateSectionList(*s, fake, marker, CodeMarker::Summary);
    1136         ++s;
    1137     }
    1138 
    1139     Text brief = fake->doc().briefText();
    1140     if (fake->subType() == FakeNode::Module && !brief.isEmpty()) {
    1141         out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
    1142         out() << "<h2>" << "Detailed Description" << "</h2>\n";
    1143     }
    1144 
    1145     generateBody(fake, marker);
    1146 #ifdef QDOC_QML   
    1147     if (fake->subType() == FakeNode::QmlClass) {
    1148         //qDebug() << "generateFakeNode(): QML CLASS" << fake->name();
    1149         const QmlNode* qmlNode = static_cast<const QmlNode*>(fake);
    1150         const ClassNode* cn = qmlNode->classNode();
    1151         if (cn) {
    1152             //qDebug() << "  CPP CLASS" << cn->name();
    1153             generateQmlText(cn->doc().body(), cn, marker);
    1154         }
    1155     }
    1156 #endif   
    1157 
    1158     generateAlsoList(fake, marker);
    1159 
    1160     if (!fake->groupMembers().isEmpty()) {
    1161         QMap<QString, const Node *> groupMembersMap;
    1162         foreach (const Node *node, fake->groupMembers()) {
    1163             if (node->type() == Node::Class || node->type() == Node::Namespace)
    1164                 groupMembersMap[node->name()] = node;
    1165         }
    1166         generateAnnotatedList(fake, marker, groupMembersMap);
    1167     }
    1168 
    1169     fakeSection.keywords += qMakePair(fakeSection.title, fakeSection.ref);
    1170 
    1171     sections = marker->sections(fake, CodeMarker::Detailed, CodeMarker::Okay);
    1172     s = sections.begin();
    1173     while (s != sections.end()) {
    1174         out() << "<hr />\n";
    1175         out() << "<h2>" << protect((*s).name) << "</h2>\n";
    1176 
    1177         NodeList::ConstIterator m = (*s).members.begin();
    1178         while (m != (*s).members.end()) {
    1179             generateDetailedMember(*m, fake, marker);
    1180             fakeSection.keywords += qMakePair((*m)->name(), linkForNode(*m, 0));
    1181             ++m;
    1182         }
    1183         ++s;
    1184     }
    1185     generateFooter(fake);
    1186 
    1187     if (fake->subType() == FakeNode::Example) {
    1188         appendDcfSubSection(&dcfExamplesRoot, fakeSection);
    1189     }
    1190     else if (fake->subType() != FakeNode::File) {
    1191         QString contentsPage = fake->links().value(Node::ContentsLink).first;
    1192 
    1193         if (contentsPage == "Qt Designer Manual") {
    1194             appendDcfSubSection(&dcfDesignerRoot, fakeSection);
    1195         }
    1196         else if (contentsPage == "Qt Linguist Manual") {
    1197             appendDcfSubSection(&dcfLinguistRoot, fakeSection);
    1198         }
    1199         else if (contentsPage == "Qt Assistant Manual") {
    1200             appendDcfSubSection(&dcfAssistantRoot, fakeSection);
    1201         }
    1202         else if (contentsPage == "qmake Manual") {
    1203             appendDcfSubSection(&dcfQmakeRoot, fakeSection);
    1204         }
    1205         else {
    1206             appendDcfSubSection(&dcfOverviewsRoot, fakeSection);
    1207         }
    1208     }
    1209 }
    1210 
    1211 QString HtmlGenerator::fileExtension(const Node * /* node */)
    1212 {
    1213     return "html";
    1214 }
    1215 
    1216 void HtmlGenerator::generateHeader(const QString& title,
    1217                                    const Node *node,
    1218                                    CodeMarker *marker,
    1219                                    bool mainPage)
    1220 {
    1221     out() << "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n";
    1222 
    1223     out() << "<!DOCTYPE html\n"
    1224              "    PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n"
    1225              "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n";
    1226 
    1227     QString shortVersion;
    1228     if ((project != "Qtopia") && (project != "Qt Extended")) {
    1229         shortVersion = project + " " + shortVersion + ": ";
    1230         if (node && !node->doc().location().isEmpty())
    1231             out() << "<!-- " << node->doc().location().filePath() << " -->\n";
    1232 
    1233         shortVersion = tre->version();
    1234         if (shortVersion.count(QChar('.')) == 2)
    1235             shortVersion.truncate(shortVersion.lastIndexOf(QChar('.')));
    1236         if (!shortVersion.isEmpty()) {
    1237             if (project == "QSA")
    1238                 shortVersion = "QSA " + shortVersion + ": ";
    1239             else
    1240                 shortVersion = "Qt " + shortVersion + ": ";
    1241         }
    1242     }
    1243 
    1244     out() << "<head>\n"
    1245              "  <title>" << shortVersion << protect(title) << "</title>\n";
    1246     if (!style.isEmpty())
    1247         out() << "    <style type=\"text/css\">" << style << "</style>\n";
    1248 
    1249     const QMap<QString, QString> &metaMap = node->doc().metaTagMap();
    1250     if (!metaMap.isEmpty()) {
    1251         QMapIterator<QString, QString> i(metaMap);
    1252         while (i.hasNext()) {
    1253             i.next();
    1254             out() << "    <meta name=\"" << protect(i.key()) << "\" contents=\""
    1255                   << protect(i.value()) << "\" />\n";
    1256         }
    1257     }
    1258 
    1259     navigationLinks.clear();
    1260 
    1261     if (node && !node->links().empty()) {
    1262         QPair<QString,QString> linkPair;
    1263         QPair<QString,QString> anchorPair;
    1264         const Node *linkNode;
    1265 
    1266         if (node->links().contains(Node::PreviousLink)) {
    1267             linkPair = node->links()[Node::PreviousLink];
    1268             linkNode = findNodeForTarget(linkPair.first, node, marker);
    1269             if (!linkNode || linkNode == node)
    1270                 anchorPair = linkPair;
    1271             else
    1272                 anchorPair = anchorForNode(linkNode);
    1273 
    1274             out() << "  <link rel=\"prev\" href=\""
    1275                   << anchorPair.first << "\" />\n";
    1276 
    1277             navigationLinks += "[Previous: <a href=\"" + anchorPair.first + "\">";
    1278             if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
    1279                 navigationLinks += protect(anchorPair.second);
    1280             else
    1281                 navigationLinks += protect(linkPair.second);
    1282             navigationLinks += "</a>]\n";
    1283         }
    1284         if (node->links().contains(Node::ContentsLink)) {
    1285             linkPair = node->links()[Node::ContentsLink];
    1286             linkNode = findNodeForTarget(linkPair.first, node, marker);
    1287             if (!linkNode || linkNode == node)
    1288                 anchorPair = linkPair;
    1289             else
    1290                 anchorPair = anchorForNode(linkNode);
    1291 
    1292             out() << "  <link rel=\"contents\" href=\""
    1293                   << anchorPair.first << "\" />\n";
    1294 
    1295             navigationLinks += "[<a href=\"" + anchorPair.first + "\">";
    1296             if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
    1297                 navigationLinks += protect(anchorPair.second);
    1298             else
    1299                 navigationLinks += protect(linkPair.second);
    1300             navigationLinks += "</a>]\n";
    1301         }
    1302         if (node->links().contains(Node::NextLink)) {
    1303             linkPair = node->links()[Node::NextLink];
    1304             linkNode = findNodeForTarget(linkPair.first, node, marker);
    1305             if (!linkNode || linkNode == node)
    1306                 anchorPair = linkPair;
    1307             else
    1308                 anchorPair = anchorForNode(linkNode);
    1309 
    1310             out() << "  <link rel=\"next\" href=\""
    1311                   << anchorPair.first << "\" />\n";
    1312 
    1313             navigationLinks += "[Next: <a href=\"" + anchorPair.first + "\">";
    1314             if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
    1315                 navigationLinks += protect(anchorPair.second);
    1316             else
    1317                 navigationLinks += protect(linkPair.second);
    1318             navigationLinks += "</a>]\n";
    1319         }
    1320         if (node->links().contains(Node::IndexLink)) {
    1321             linkPair = node->links()[Node::IndexLink];
    1322             linkNode = findNodeForTarget(linkPair.first, node, marker);
    1323             if (!linkNode || linkNode == node)
    1324                 anchorPair = linkPair;
    1325             else
    1326                 anchorPair = anchorForNode(linkNode);
    1327             out() << "  <link rel=\"index\" href=\""
    1328                   << anchorPair.first << "\" />\n";
    1329         }
    1330         if (node->links().contains(Node::StartLink)) {
    1331             linkPair = node->links()[Node::StartLink];
    1332             linkNode = findNodeForTarget(linkPair.first, node, marker);
    1333             if (!linkNode || linkNode == node)
    1334                 anchorPair = linkPair;
    1335             else
    1336                 anchorPair = anchorForNode(linkNode);
    1337             out() << "  <link rel=\"start\" href=\""
    1338                   << anchorPair.first << "\" />\n";
    1339         }
    1340     }
    1341 
    1342     foreach (const QString &stylesheet, stylesheets) {
    1343         out() << "  <link href=\"" << stylesheet << "\" rel=\"stylesheet\" "
    1344               << "type=\"text/css\" />\n";
    1345     }
    1346 
    1347     foreach (const QString &customHeadElement, customHeadElements) {
    1348         out() << "  " << customHeadElement << "\n";
    1349     }
    1350 
    1351     out() << "</head>\n"
    1352              "<body>\n";
    1353     if (mainPage)
    1354         generateMacRef(node, marker);
    1355     out() << QString(postHeader).replace("\\" + COMMAND_VERSION, tre->version());
    1356 
    1357 
    1358     if (node && !node->links().empty())
    1359         out() << "<p>\n" << navigationLinks << "</p>\n";
    1360 }
    1361 
    1362 void HtmlGenerator::generateTitle(const QString& title,
    1363                                   const Text &subTitle,
    1364                                   SubTitleSize subTitleSize,
    1365                                   const Node *relative,
    1366                                   CodeMarker *marker)
    1367 {
    1368     out() << "<h1 class=\"title\">" << protect(title);
    1369     if (!subTitle.isEmpty()) {
    1370         out() << "<br />";
    1371         if (subTitleSize == SmallSubTitle)
    1372             out() << "<span class=\"small-subtitle\">";
    1373         else
    1374             out() << "<span class=\"subtitle\">";
    1375         generateText(subTitle, relative, marker);
    1376         out() << "</span>\n";
    1377     }
    1378     out() << "</h1>\n";
    1379 }
    1380 
    1381 void HtmlGenerator::generateFooter(const Node *node)
    1382 {
    1383     if (node && !node->links().empty())
    1384         out() << "<p>\n" << navigationLinks << "</p>\n";
    1385 
    1386     out() << QString(footer).replace("\\" + COMMAND_VERSION, tre->version())
    1387           << QString(address).replace("\\" + COMMAND_VERSION, tre->version())
    1388           << "</body>\n"
    1389              "</html>\n";
    1390 }
    1391 
    1392 void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker,
    1393                                   const Node *relative)
    1394 {
    1395     Text brief = node->doc().briefText();
    1396     if (!brief.isEmpty()) {
    1397         out() << "<p>";
    1398         generateText(brief, node, marker);
    1399         if (!relative || node == relative)
    1400             out() << " <a href=\"#";
    1401         else
    1402             out() << " <a href=\"" << linkForNode(node, relative) << "#";
    1403         out() << registerRef("details") << "\">More...</a></p>\n";
    1404     }
    1405 }
    1406 
    1407 void HtmlGenerator::generateIncludes(const InnerNode *inner, CodeMarker *marker)
    1408 {
    1409     if (!inner->includes().isEmpty()) {
    1410         out() << "<pre>" << trimmedTrailing(highlightedCode(indent(codeIndent,
    1411                                                                    marker->markedUpIncludes(
    1412                                                                         inner->includes())),
    1413                                                                         marker, inner))
    1414               << "</pre>";
    1415     }
    1416 }
    1417 
    1418 void HtmlGenerator::generateTableOfContents(const Node *node, CodeMarker *marker,
    1419                                             Doc::SectioningUnit sectioningUnit,
    1420                                             int numColumns, const Node *relative)
    1421 
    1422 {
    1423     if (!node->doc().hasTableOfContents())
    1424         return;
    1425     QList<Atom *> toc = node->doc().tableOfContents();
    1426     if (toc.isEmpty())
    1427         return;
    1428 
    1429     QString nodeName = "";
    1430     if (node != relative)
    1431         nodeName = node->name();
    1432 
    1433     QStringList sectionNumber;
    1434     int columnSize = 0;
    1435 
    1436     QString tdTag;
    1437     if (numColumns > 1) {
    1438         tdTag = "<td width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";
    1439         out() << "<p><table width=\"100%\">\n<tr valign=\"top\">" << tdTag << "\n";
    1440     }
    1441 
    1442     // disable nested links in table of contents
    1443     inContents = true;
    1444     inLink = true;
    1445 
    1446     for (int i = 0; i < toc.size(); ++i) {
    1447         Atom *atom = toc.at(i);
    1448 
    1449         int nextLevel = atom->string().toInt();
    1450         if (nextLevel > (int)sectioningUnit)
    1451             continue;
    1452 
    1453         if (sectionNumber.size() < nextLevel) {
    1454             do {
    1455                 out() << "<ul>";
    1456                 sectionNumber.append("1");
    1457             } while (sectionNumber.size() < nextLevel);
    1458         } else {
    1459             while (sectionNumber.size() > nextLevel) {
    1460                 out() << "</ul>\n";
    1461                 sectionNumber.removeLast();
    1462             }
    1463             sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1);
    1464         }
    1465         int numAtoms;
    1466         Text headingText = Text::sectionHeading(atom);
    1467 
    1468         if (sectionNumber.size() == 1 && columnSize > toc.size() / numColumns) {
    1469             out() << "</ul></td>" << tdTag << "<ul>\n";
    1470             columnSize = 0;
    1471         }
    1472         out() << "<li>";
    1473         out() << "<a href=\"" << nodeName << "#" << Doc::canonicalTitle(headingText.toString())
    1474               << "\">";
    1475         generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms);
    1476         out() << "</a></li>\n";
    1477 
    1478         ++columnSize;
    1479     }
    1480     while (!sectionNumber.isEmpty()) {
    1481         out() << "</ul>\n";
    1482         sectionNumber.removeLast();
    1483     }
    1484 
    1485     if (numColumns > 1)
    1486         out() << "</td></tr></table></p>\n";
    1487 
    1488     inContents = false;
    1489     inLink = false;
    1490 }
    1491 
    1492 #if 0
    1493 void HtmlGenerator::generateNavigationBar(const NavigationBar& bar,
    1494                                            const Node *node,
    1495                                            CodeMarker *marker)
    1496 {
    1497     if (bar.prev.begin() != 0 || bar.current.begin() != 0 ||
    1498          bar.next.begin() != 0) {
    1499         out() << "<p align=\"right\">";
    1500         if (bar.prev.begin() != 0) {
    1501 #if 0
    1502             out() << "[<a href=\"" << section.previousBaseName()
    1503                   << ".html\">Prev: ";
    1504             generateText(section.previousHeading(), node, marker);
    1505             out() << "</a>]\n";
    1506 #endif
    1507         }
    1508         if (bar.current.begin() != 0) {
    1509             out() << "[<a href=\"" << "home"
    1510                   << ".html\">Home</a>]\n";
    1511         }
    1512         if (bar.next.begin() != 0) {
    1513             out() << "[<a href=\"" << fileBase(node, bar.next)
    1514                   << ".html\">Next: ";
    1515             generateText(Text::sectionHeading(bar.next.begin()), node, marker);
    1516             out() << "</a>]\n";
    1517         }
    1518         out() << "</p>\n";
    1519     }
    1520 }
    1521 #endif
    1522 
    1523 QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner, CodeMarker *marker)
    1524 {
    1525     QList<Section> sections;
    1526     QList<Section>::ConstIterator s;
    1527 
    1528     sections = marker->sections(inner, CodeMarker::SeparateList, CodeMarker::Okay);
    1529     if (sections.isEmpty())
    1530         return QString();
    1531 
    1532     QString fileName = fileBase(inner) + "-members." + fileExtension(inner);
    1533     beginSubPage(inner->location(), fileName);
    1534     QString title = "List of All Members for " + inner->name();
    1535     generateHeader(title, inner, marker, false);
    1536     generateTitle(title, Text(), SmallSubTitle, inner, marker);
    1537     out() << "<p>This is the complete list of members for ";
    1538     generateFullName(inner, 0, marker);
    1539     out() << ", including inherited members.</p>\n";
    1540 
    1541     Section section = sections.first();
    1542     generateSectionList(section, 0, marker, CodeMarker::SeparateList);
    1543 
    1544     generateFooter();
    1545     endSubPage();
    1546     return fileName;
    1547 }
    1548 
    1549 QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner, CodeMarker *marker,
    1550                                                    CodeMarker::Status status)
    1551 {
    1552     QList<Section> sections = marker->sections(inner, CodeMarker::Summary, status);
    1553     QMutableListIterator<Section> j(sections);
    1554     while (j.hasNext()) {
    1555         if (j.next().members.size() == 0)
    1556             j.remove();
    1557     }
    1558     if (sections.isEmpty())
    1559         return QString();
    1560 
    1561     int i;
    1562 
    1563     QString title;
    1564     QString fileName;
    1565 
    1566     if (status == CodeMarker::Compat) {
    1567         title = "Qt 3 Support Members for " + inner->name();
    1568         fileName = fileBase(inner) + "-qt3." + fileExtension(inner);
    1569     } else {
    1570         title = "Obsolete Members for " + inner->name();
    1571         fileName = fileBase(inner) + "-obsolete." + fileExtension(inner);
    1572     }
    1573 
    1574     beginSubPage(inner->location(), fileName);
    1575     generateHeader(title, inner, marker, false);
    1576     generateTitle(title, Text(), SmallSubTitle, inner, marker);
    1577 
    1578     if (status == CodeMarker::Compat) {
    1579         out() << "<p><b>The following class members are part of the "
    1580                  "<a href=\"qt3support.html\">Qt 3 support layer</a>.</b> "
    1581                  "They are provided to help you port old code to Qt 4. We advise against "
    1582                  "using them in new code.</p>\n";
    1583     } else {
    1584         out() << "<p><b>The following class members are obsolete.</b> They are provided to keep "
    1585                  "old source code working. We strongly advise against using them in new "
    1586                  "code.</p>\n";
    1587     }
    1588 
    1589     out() << "<p><ul><li><a href=\"" << linkForNode(inner, 0) << "\">" << protect(inner->name())
    1590           << " class reference</a></li></ul></p>\n";
    1591 
    1592     for (i = 0; i < sections.size(); ++i) {
    1593         out() << "<h3>" << protect(sections.at(i).name) << "</h3>\n";
    1594 
    1595         generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary);
    1596     }
    1597 
    1598     sections = marker->sections(inner, CodeMarker::Detailed, status);
    1599     for (i = 0; i < sections.size(); ++i) {
    1600         out() << "<hr />\n";
    1601         out() << "<h2>" << protect(sections.at(i).name) << "</h2>\n";
    1602 
    1603         NodeList::ConstIterator m = sections.at(i).members.begin();
    1604         while (m != sections.at(i).members.end()) {
    1605             if ((*m)->access() != Node::Private)
    1606                 generateDetailedMember(*m, inner, marker);
    1607             ++m;
    1608         }
    1609     }
    1610 
    1611     generateFooter();
    1612     endSubPage();
    1613     return fileName;
    1614 }
    1615 
    1616 void HtmlGenerator::generateClassHierarchy(const Node *relative, CodeMarker *marker,
    1617                                            const QMap<QString, const Node *> &classMap)
    1618 {
    1619     if (classMap.isEmpty())
    1620         return;
    1621 
    1622     QMap<QString, const Node *> topLevel;
    1623     QMap<QString, const Node *>::ConstIterator c = classMap.begin();
    1624     while (c != classMap.end()) {
    1625         const ClassNode *classe = static_cast<const ClassNode *>(*c);
    1626         if (classe->baseClasses().isEmpty())
    1627             topLevel.insert(classe->name(), classe);
    1628         ++c;
    1629     }
    1630 
    1631     QStack<QMap<QString, const Node *> > stack;
    1632     stack.push(topLevel);
    1633 
    1634     out() << "<ul>\n";
    1635     while (!stack.isEmpty()) {
    1636         if (stack.top().isEmpty()) {
    1637             stack.pop();
    1638             out() << "</ul>\n";
    1639         } else {
    1640             const ClassNode *child = static_cast<const ClassNode *>(*stack.top().begin());
    1641             out() << "<li>";
    1642             generateFullName(child, relative, marker);
    1643             out() << "</li>\n";
    1644             stack.top().erase(stack.top().begin());
    1645 
    1646             QMap<QString, const Node *> newTop;
    1647             foreach (const RelatedClass &d, child->derivedClasses()) {
    1648                 if (d.access != Node::Private)
    1649                     newTop.insert(d.node->name(), d.node);
    1650             }
    1651             if (!newTop.isEmpty()) {
    1652                 stack.push(newTop);
    1653                 out() << "<ul>\n";
    1654             }
    1655         }
    1656     }
    1657 }
    1658 
    1659 void HtmlGenerator::generateAnnotatedList(const Node *relative, CodeMarker *marker,
    1660                     const QMap<QString, const Node *> &nodeMap)
    1661 {
    1662     out() << "<p><table width=\"100%\" class=\"annotated\" cellpadding=\"2\" cellspacing=\"1\" border=\"0\">\n";
    1663 
    1664     int row = 0;
    1665     foreach (const QString &name, nodeMap.keys()) {
    1666         const Node *node = nodeMap[name];
    1667 
    1668         if (++row % 2 == 1)
    1669             out() << "<tr valign=\"top\" class=\"odd\">";
    1670         else
    1671             out() << "<tr valign=\"top\" class=\"even\">";
    1672         out() << "<th>";
    1673         generateFullName(node, relative, marker);
    1674         out() << "</th>";
    1675 
    1676         if (!(node->type() == Node::Fake)) {
    1677             Text brief = node->doc().trimmedBriefText(name);
    1678             if (!brief.isEmpty()) {
    1679                 out() << "<td>";
    1680                 generateText(brief, node, marker);
    1681                 out() << "</td>";
    1682             }
    1683         } else {
    1684             out() << "<td>";
    1685             out() << protect(node->doc().briefText().toString());
    1686             out() << "</td>";
    1687         }
    1688         out() << "</tr>\n";
    1689     }
    1690     out() << "</table></p>\n";
    1691 }
    1692 
    1693 void HtmlGenerator::generateCompactList(const Node *relative, CodeMarker *marker,
    1694                                         const QMap<QString, const Node *> &classMap)
    1695 {
    1696     const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_'
    1697     const int NumColumns = 4; // number of columns in the result
    1698 
    1699     if (classMap.isEmpty())
    1700         return;
    1701 
    1702     /*
    1703       First, find out the common prefix of all non-namespaced classes.
    1704       For Qt, the prefix is Q. It can easily be derived from the first
    1705       and last classes in alphabetical order (QAccel and QXtWidget in Qt 2.1).
    1706     */
    1707     int commonPrefixLen = 0;
    1708     QString commonPrefix;
    1709     QString first;
    1710     QString last;
    1711 
    1712     QMap<QString, const Node *>::const_iterator iter = classMap.begin();
    1713     while (iter != classMap.end()) {
    1714         if (!iter.key().contains("::")) {
    1715             first = iter.key();
    1716             break;
    1717         }
    1718         ++iter;
    1719     }
    1720 
    1721     if (first.isEmpty())
    1722         first = classMap.begin().key();
    1723 
    1724     iter = classMap.end();
    1725     while (iter != classMap.begin()) {
    1726         --iter;
    1727         if (!iter.key().contains("::")) {
    1728             last = iter.key();
    1729             break;
    1730         }
    1731     }
    1732 
    1733     if (last.isEmpty())
    1734         last = classMap.begin().key();
    1735 
    1736     if (classMap.size() > 1) {
    1737         while (commonPrefixLen < first.length() + 1 && commonPrefixLen < last.length() + 1
    1738                && first[commonPrefixLen] == last[commonPrefixLen])
    1739             ++commonPrefixLen;
    1740     }
    1741 
    1742     commonPrefix = first.left(commonPrefixLen);
    1743 
    1744     /*
    1745       Divide the data into 37 paragraphs: 0, ..., 9, A, ..., Z,
    1746       underscore (_). QAccel will fall in paragraph 10 (A) and
    1747       QXtWidget in paragraph 33 (X). This is the only place where we
    1748       assume that NumParagraphs is 37. Each paragraph is a
    1749       QMap<QString, const Node *>.
    1750     */
    1751     QMap<QString, const Node *> paragraph[NumParagraphs];
    1752     QString paragraphName[NumParagraphs];
    1753 
    1754     QMap<QString, const Node *>::ConstIterator c = classMap.begin();
    1755     while (c != classMap.end()) {
    1756         QStringList pieces = c.key().split("::");
    1757         QString key;
    1758         if (pieces.size() == 1)
    1759             key = pieces.last().mid(commonPrefixLen).toLower();
    1760         else
    1761             key = pieces.last().toLower();
    1762 
    1763         int paragraphNo = NumParagraphs - 1;
    1764 
    1765         if (key[0].digitValue() != -1) {
    1766             paragraphNo = key[0].digitValue();
    1767         } else if (key[0] >= QLatin1Char('a') && key[0] <= QLatin1Char('z')) {
    1768             paragraphNo = 10 + key[0].unicode() - 'a';
    1769         }
    1770 
    1771         paragraphName[paragraphNo] = key[0].toUpper();
    1772         paragraph[paragraphNo].insert(key, c.value());
    1773         ++c;
    1774     }
    1775 
    1776     /*
    1777       Each paragraph j has a size: paragraph[j].count(). In the
    1778       discussion, we will assume paragraphs 0 to 5 will have sizes
    1779       3, 1, 4, 1, 5, 9.
    1780 
    1781       We now want to compute the paragraph offset. Paragraphs 0 to 6
    1782       start at offsets 0, 3, 4, 8, 9, 14, 23.
    1783     */
    1784     int paragraphOffset[NumParagraphs + 1];
    1785     int i, j, k;
    1786 
    1787     paragraphOffset[0] = 0;
    1788     for (j = 0; j < NumParagraphs; j++)
    1789         paragraphOffset[j + 1] = paragraphOffset[j] + paragraph[j].count();
    1790 
    1791     int firstOffset[NumColumns + 1];
    1792     int currentOffset[NumColumns];
    1793     int currentParagraphNo[NumColumns];
    1794     int currentOffsetInParagraph[NumColumns];
    1795 
    1796     int numRows = (classMap.count() + NumColumns - 1) / NumColumns;
    1797     int curParagNo = 0;
    1798 
    1799     for (i = 0; i < NumColumns; i++) {
    1800         firstOffset[i] = qMin(i * numRows, classMap.size());
    1801         currentOffset[i] = firstOffset[i];
    1802 
    1803         for (j = curParagNo; j < NumParagraphs; j++) {
    1804             if (paragraphOffset[j] > firstOffset[i])
    1805                 break;
    1806             if (paragraphOffset[j] <= firstOffset[i])
    1807                 curParagNo = j;
    1808         }
    1809         currentParagraphNo[i] = curParagNo;
    1810         currentOffsetInParagraph[i] = firstOffset[i] -
    1811                                       paragraphOffset[curParagNo];
    1812     }
    1813     firstOffset[NumColumns] = classMap.count();
    1814 
    1815     out() << "<p><table width=\"100%\">\n";
    1816     for (k = 0; k < numRows; k++) {
    1817         out() << "<tr>\n";
    1818         for (i = 0; i < NumColumns; i++) {
    1819             if (currentOffset[i] >= firstOffset[i + 1]) {
    1820                 // this column is finished
    1821                 out() << "<td>\n</td>\n";
    1822             } else {
    1823                 while (currentOffsetInParagraph[i] == paragraph[currentParagraphNo[i]].count()) {
    1824                     ++currentParagraphNo[i];
    1825                     currentOffsetInParagraph[i] = 0;
    1826                 }
    1827 
    1828                 out() << "<td align=\"right\">";
    1829                 if (currentOffsetInParagraph[i] == 0) {
    1830                     // start a new paragraph
    1831                     out() << "<b>" << paragraphName[currentParagraphNo[i]] << "&nbsp;</b>";
    1832                 }
    1833                 out() << "</td>\n";
    1834 
    1835                 // bad loop
    1836                 QMap<QString, const Node *>::Iterator it;
    1837                 it = paragraph[currentParagraphNo[i]].begin();
    1838                 for (j = 0; j < currentOffsetInParagraph[i]; j++)
    1839                     ++it;
    1840 
    1841                 out() << "<td>";
    1842                 // Previously, we used generateFullName() for this, but we
    1843                 // require some special formatting.
    1844                 out() << "<a href=\"" << linkForNode(it.value(), relative) << "\">";
    1845                 QStringList pieces = fullName(it.value(), relative, marker).split("::");
    1846                 out() << protect(pieces.last());
    1847                 out() << "</a>";
    1848                 if (pieces.size() > 1) {
    1849                     out() << " (";
    1850                     generateFullName(it.value()->parent(), relative, marker);
    1851                     out() << ")";
    1852                 }
    1853                 out() << "</td>\n";
    1854 
    1855                 currentOffset[i]++;
    1856                 currentOffsetInParagraph[i]++;
    1857             }
    1858         }
    1859         out() << "</tr>\n";
    1860     }
    1861     out() << "</table></p>\n";
    1862 }
    1863 
    1864 void HtmlGenerator::generateFunctionIndex(const Node *relative, CodeMarker *marker)
    1865 {
    1866     out() << "<p align=\"center\"><font size=\"+1\"><b>";
    1867     for (int i = 0; i < 26; i++) {
    1868         QChar ch('a' + i);
    1869         out() << QString("<a href=\"#%1\">%2</a>&nbsp;").arg(ch).arg(ch.toUpper());
    1870     }
    1871     out() << "</b></font></p>\n";
    1872 
    1873     char nextLetter = 'a';
    1874     char currentLetter;
    1875 
    1876 #if 1
    1877     out() << "<ul>\n";
    1878 #endif
    1879     QMap<QString, QMap<QString, const Node *> >::ConstIterator f = funcIndex.begin();
    1880     while (f != funcIndex.end()) {
    1881 #if 1
    1882         out() << "<li>";
    1883 #else
    1884         out() << "<p>";
    1885 #endif
    1886         out() << protect(f.key()) << ":";
    1887 
    1888         currentLetter = f.key()[0].unicode();
    1889         while (islower(currentLetter) && currentLetter >= nextLetter) {
    1890             out() << QString("<a name=\"%1\"></a>").arg(nextLetter);
    1891             nextLetter++;
    1892         }
    1893 
    1894         QMap<QString, const Node *>::ConstIterator s = (*f).begin();
    1895         while (s != (*f).end()) {
    1896             out() << " ";
    1897             generateFullName((*s)->parent(), relative, marker, *s);
    1898             ++s;
    1899         }
    1900 #if 1
    1901         out() << "</li>";
    1902 #else
    1903         out() << "</p>";
    1904 #endif
    1905         out() << "\n";
    1906         ++f;
    1907     }
    1908 #if 1
    1909     out() << "</ul>\n";
    1910 #endif
    1911 }
    1912 
    1913 void HtmlGenerator::generateLegaleseList(const Node *relative, CodeMarker *marker)
    1914 {
    1915     QMap<Text, const Node *>::ConstIterator it = legaleseTexts.begin();
    1916     while (it != legaleseTexts.end()) {
    1917         Text text = it.key();
    1918         out() << "<hr />\n";
    1919         generateText(text, relative, marker);
    1920         out() << "<ul>\n";
    1921         do {
    1922             out() << "<li>";
    1923             generateFullName(it.value(), relative, marker);
    1924             out() << "</li>\n";
    1925             ++it;
    1926         } while (it != legaleseTexts.end() && it.key() == text);
    1927         out() << "</ul>\n";
    1928     }
    1929 }
    1930 
    1931 void HtmlGenerator::generateSynopsis(const Node *node, const Node *relative,
    1932                                      CodeMarker *marker, CodeMarker::SynopsisStyle style)
    1933 {
    1934     QString marked = marker->markedUpSynopsis(node, relative, style);
    1935     QRegExp templateTag("(<[^@>]*>)");
    1936     if (marked.indexOf(templateTag) != -1) {
    1937         QString contents = protect(marked.mid(templateTag.pos(1),
    1938                                               templateTag.cap(1).length()));
    1939         marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
    1940                         contents);
    1941     }
    1942     marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"), "<i>\\1<sub>\\2</sub></i>");
    1943     marked.replace("<@param>", "<i>");
    1944     marked.replace("</@param>", "</i>");
    1945 
    1946     if (style == CodeMarker::Summary)
    1947         marked.replace("@name>", "b>");
    1948 
    1949     if (style == CodeMarker::SeparateList) {
    1950         QRegExp extraRegExp("<@extra>.*</@extra>");
    1951         extraRegExp.setMinimal(true);
    1952         marked.replace(extraRegExp, "");
    1953     } else {
    1954         marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
    1955         marked.replace("</@extra>", "</tt>");
    1956     }
    1957 
    1958     if (style != CodeMarker::Detailed) {
    1959         marked.replace("<@type>", "");
    1960         marked.replace("</@type>", "");
    1961     }
    1962     out() << highlightedCode(marked, marker, relative);
    1963 }
    1964 
    1965 void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* marker */)
    1966 {
    1967     QMap<const FakeNode *, QMap<QString, FakeNode *> > fakeNodeMap;
    1968     QMap<QString, const FakeNode *> groupTitlesMap;
    1969     QMap<QString, FakeNode *> uncategorizedNodeMap;
    1970     QRegExp singleDigit("\\b([0-9])\\b");
    1971 
    1972     const NodeList children = tre->root()->childNodes();
    1973     foreach (Node *child, children) {
    1974         if (child->type() == Node::Fake && child != relative) {
    1975             FakeNode *fakeNode = static_cast<FakeNode *>(child);
    1976 
    1977             // Check whether the page is part of a group or is the group
    1978             // definition page.
    1979             QString group;
    1980             bool isGroupPage = false;
    1981             if (fakeNode->doc().metaCommandsUsed().contains("group")) {
    1982                 group = fakeNode->doc().metaCommandArgs("group")[0];
    1983                 isGroupPage = true;
    1984             }
    1985 
    1986             // there are too many examples; they would clutter the list
    1987             if (fakeNode->subType() == FakeNode::Example)
    1988                 continue;
    1989 
    1990             // not interested either in individual (Qt Designer etc.) manual chapters
    1991             if (fakeNode->links().contains(Node::ContentsLink))
    1992                 continue;
    1993 
    1994             // Discard external nodes.
    1995             if (fakeNode->subType() == FakeNode::ExternalPage)
    1996                 continue;
    1997 
    1998             QString sortKey = fakeNode->fullTitle().toLower();
    1999             if (sortKey.startsWith("the "))
    2000                 sortKey.remove(0, 4);
    2001             sortKey.replace(singleDigit, "0\\1");
    2002 
    2003             if (!group.isEmpty()) {
    2004                 if (isGroupPage) {
    2005                     // If we encounter a group definition page, we add all
    2006                     // the pages in that group to the list for that group.
    2007                     foreach (Node *member, fakeNode->groupMembers()) {
    2008                         if (member->type() != Node::Fake)
    2009                             continue;
    2010                         FakeNode *page = static_cast<FakeNode *>(member);
    2011                         if (page) {
    2012                             QString sortKey = page->fullTitle().toLower();
    2013                             if (sortKey.startsWith("the "))
    2014                                 sortKey.remove(0, 4);
    2015                             sortKey.replace(singleDigit, "0\\1");
    2016                             fakeNodeMap[const_cast<const FakeNode *>(fakeNode)].insert(sortKey, page);
    2017                             groupTitlesMap[fakeNode->fullTitle()] = const_cast<const FakeNode *>(fakeNode);
    2018                         }
    2019                     }
    2020                 } else if (!isGroupPage) {
    2021                     // If we encounter a page that belongs to a group then
    2022                     // we add that page to the list for that group.
    2023                     const FakeNode *groupNode = static_cast<const FakeNode *>(tre->root()->findNode(group, Node::Fake));
    2024                     if (groupNode)
    2025                         fakeNodeMap[groupNode].insert(sortKey, fakeNode);
    2026                     //else
    2027                     //    uncategorizedNodeMap.insert(sortKey, fakeNode);
    2028                 }// else
    2029                 //    uncategorizedNodeMap.insert(sortKey, fakeNode);
    2030             }// else
    2031             //    uncategorizedNodeMap.insert(sortKey, fakeNode);
    2032         }
    2033     }
    2034 
    2035     // We now list all the pages found that belong to groups.
    2036     // If only certain pages were found for a group, but the definition page
    2037     // for that group wasn't listed, the list of pages will be intentionally
    2038     // incomplete. However, if the group definition page was listed, all the
    2039     // pages in that group are listed for completeness.
    2040 
    2041     if (!fakeNodeMap.isEmpty()) {
    2042         foreach (const QString &groupTitle, groupTitlesMap.keys()) {
    2043             const FakeNode *groupNode = groupTitlesMap[groupTitle];
    2044             out() << QString("<h3><a href=\"%1\">%2</a></h3>\n").arg(
    2045                         linkForNode(groupNode, relative)).arg(
    2046                         protect(groupNode->fullTitle()));
    2047 
    2048             if (fakeNodeMap[groupNode].count() == 0)
    2049                 continue;
    2050 
    2051             out() << "<ul>\n";
    2052 
    2053             foreach (const FakeNode *fakeNode, fakeNodeMap[groupNode]) {
    2054                 QString title = fakeNode->fullTitle();
    2055                 if (title.startsWith("The "))
    2056                     title.remove(0, 4);
    2057                 out() << "<li><a href=\"" << linkForNode(fakeNode, relative) << "\">"
    2058                       << protect(title) << "</a></li>\n";
    2059             }
    2060             out() << "</ul>\n";
    2061         }
    2062     }
    2063 
    2064     if (!uncategorizedNodeMap.isEmpty()) {
    2065         out() << QString("<h3>Miscellaneous</h3>\n");
    2066         out() << "<ul>\n";
    2067         foreach (const FakeNode *fakeNode, uncategorizedNodeMap) {
    2068             QString title = fakeNode->fullTitle();
    2069             if (title.startsWith("The "))
    2070                 title.remove(0, 4);
    2071             out() << "<li><a href=\"" << linkForNode(fakeNode, relative) << "\">"
    2072                   << protect(title) << "</a></li>\n";
    2073         }
    2074         out() << "</ul>\n";
    2075     }
    2076 }
    2077 
    2078 void HtmlGenerator::generateSectionList(const Section& section, const Node *relative,
    2079                                         CodeMarker *marker, CodeMarker::SynopsisStyle style)
    2080 {
    2081     if (!section.members.isEmpty()) {
    2082         bool twoColumn = false;
    2083         if (style == CodeMarker::SeparateList) {
    2084             twoColumn = (section.members.count() >= 16);
    2085         } else if (section.members.first()->type() == Node::Property) {
    2086             twoColumn = (section.members.count() >= 5);
    2087         }
    2088         if (twoColumn)
    2089             out() << "<p><table width=\"100%\" border=\"0\" cellpadding=\"0\""
    2090                      " cellspacing=\"0\">\n"
    2091                   << "<tr><td width=\"45%\" valign=\"top\">";
    2092         out() << "<ul>\n";
    2093 
    2094         int i = 0;
    2095         NodeList::ConstIterator m = section.members.begin();
    2096         while (m != section.members.end()) {
    2097             if ((*m)->access() == Node::Private) {
    2098                 ++m;
    2099                 continue;
    2100             }
    2101 
    2102             if (twoColumn && i == (int) (section.members.count() + 1) / 2)
    2103                 out() << "</ul></td><td valign=\"top\"><ul>\n";
    2104 
    2105             out() << "<li><div class=\"fn\"></div>";
    2106             if (style == CodeMarker::Accessors)
    2107                 out() << "<b>";
    2108             generateSynopsis(*m, relative, marker, style);
    2109             if (style == CodeMarker::Accessors)
    2110                 out() << "</b>";
    2111             out() << "</li>\n";
    2112             i++;
    2113             ++m;
    2114         }
    2115         out() << "</ul>\n";
    2116         if (twoColumn)
    2117             out() << "</td></tr>\n</table></p>\n";
    2118     }
    2119 
    2120     if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
    2121         out() << "<ul>\n";
    2122         generateSectionInheritedList(section, relative, marker);
    2123         out() << "</ul>\n";
    2124     }
    2125 }
    2126 
    2127 void HtmlGenerator::generateSectionInheritedList(const Section& section, const Node *relative,
    2128                                                  CodeMarker *marker)
    2129 {
    2130     QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
    2131     while (p != section.inherited.end()) {
    2132         out() << "<li><div class=\"fn\"></div>";
    2133         out() << (*p).second << " ";
    2134         if ((*p).second == 1) {
    2135             out() << section.singularMember;
    2136         } else {
    2137             out() << section.pluralMember;
    2138         }
    2139         out() << " inherited from <a href=\"" << fileName((*p).first)
    2140               << "#" << HtmlGenerator::cleanRef(section.name.toLower()) << "\">"
    2141               << protect(marker->plainFullName((*p).first, relative))
    2142               << "</a></li>\n";
    2143         ++p;
    2144     }
    2145 }
    2146 
    2147 void HtmlGenerator::generateLink(const Atom *atom, const Node * /* relative */, CodeMarker *marker)
    2148 {
    2149     static QRegExp camelCase("[A-Z][A-Z][a-z]|[a-z][A-Z0-9]|_");
    2150 
    2151     if (funcLeftParen.indexIn(atom->string()) != -1 && marker->recognizeLanguage("Cpp")) {
    2152         // hack for C++: move () outside of link
    2153         int k = funcLeftParen.pos(1);
    2154         out() << protect(atom->string().left(k));
    2155         if (link.isEmpty()) {
    2156             if (showBrokenLinks)
    2157                 out() << "</i>";
    2158         } else {
    2159             out() << "</a>";
    2160         }
    2161         inLink = false;
    2162         out() << protect(atom->string().mid(k));
    2163     } else if (marker->recognizeLanguage("Java")) {
    2164         // hack for Java: remove () and use <tt> when appropriate
    2165         bool func = atom->string().endsWith("()");
    2166         bool tt = (func || atom->string().contains(camelCase));
    2167         if (tt)
    2168             out() << "<tt>";
    2169         if (func) {
    2170             out() << protect(atom->string().left(atom->string().length() - 2));
    2171         } else {
    2172             out() << protect(atom->string());
    2173         }
    2174         out() << "</tt>";
    2175     } else {
    2176         out() << protect(atom->string());
    2177     }
    2178 }
    2179 
    2180 QString HtmlGenerator::cleanRef(const QString& ref)
    2181 {
    2182     QString clean;
    2183 
    2184     if (ref.isEmpty())
    2185         return clean;
    2186 
    2187     clean.reserve(ref.size() + 20);
    2188     const QChar c = ref[0];
    2189     const uint u = c.unicode();
    2190 
    2191     if ((u >= 'a' && u <= 'z') ||
    2192          (u >= 'A' && u <= 'Z') ||
    2193          (u >= '0' && u <= '9')) {
    2194         clean += c;
    2195     } else if (u == '~') {
    2196         clean += "dtor.";
    2197     } else if (u == '_') {
    2198         clean += "underscore.";
    2199     } else {
    2200         clean += "A";
    2201     }
    2202 
    2203     for (int i = 1; i < (int) ref.length(); i++) {
    2204         const QChar c = ref[i];
    2205         const uint u = c.unicode();
    2206         if ((u >= 'a' && u <= 'z') ||
    2207              (u >= 'A' && u <= 'Z') ||
    2208              (u >= '0' && u <= '9') || u == '-' ||
    2209              u == '_' || u == ':' || u == '.') {
    2210             clean += c;
    2211         } else if (c.isSpace()) {
    2212             clean += "-";
    2213         } else if (u == '!') {
    2214             clean += "-not";
    2215         } else if (u == '&') {
    2216             clean += "-and";
    2217         } else if (u == '<') {
    2218             clean += "-lt";
    2219         } else if (u == '=') {
    2220             clean += "-eq";
    2221         } else if (u == '>') {
    2222             clean += "-gt";
    2223         } else if (u == '#') {
    2224             clean += "#";
    2225         } else {
    2226             clean += "-";
    2227             clean += QString::number((int)u, 16);
    2228         }
    2229     }
    2230     return clean;
    2231 }
    2232 
    2233 QString HtmlGenerator::registerRef(const QString& ref)
    2234 {
    2235     QString clean = HtmlGenerator::cleanRef(ref);
    2236 
    2237     for (;;) {
    2238         QString& prevRef = refMap[clean.toLower()];
    2239         if (prevRef.isEmpty()) {
    2240             prevRef = ref;
    2241             break;
    2242         } else if (prevRef == ref) {
    2243             break;
    2244         }
    2245         clean += "x";
    2246     }
    2247     return clean;
    2248 }
    2249 
    2250 QString HtmlGenerator::protect(const QString& string)
    2251 {
    2252 #define APPEND(x) \
    2253     if (html.isEmpty()) { \
    2254         html = string; \
    2255         html.truncate(i); \
    2256     } \
    2257     html += (x);
    2258 
    2259     QString html;
    2260     int n = string.length();
    2261 
    2262     for (int i = 0; i < n; ++i) {
    2263         QChar ch = string.at(i);
    2264 
    2265         if (ch == QLatin1Char('&')) {
    2266             APPEND("&amp;");
    2267         } else if (ch == QLatin1Char('<')) {
    2268             APPEND("&lt;");
    2269         } else if (ch == QLatin1Char('>')) {
    2270             APPEND("&gt;");
    2271         } else if (ch == QLatin1Char('"')) {
    2272             APPEND("&quot;");
    2273         } else if (ch.unicode() > 0x007F
    2274                    || (ch == QLatin1Char('*') && i + 1 < n && string.at(i) == QLatin1Char('/'))
    2275                    || (ch == QLatin1Char('.') && i > 2 && string.at(i - 2) == QLatin1Char('.'))) {
    2276             // we escape '*/' and the last dot in 'e.g.' and 'i.e.' for the Javadoc generator
    2277             APPEND("&#x");
    2278             html += QString::number(ch.unicode(), 16);
    2279             html += QLatin1Char(';');
    2280         } else {
    2281             if (!html.isEmpty())
    2282                 html += ch;
    2283         }
    2284     }
    2285 
    2286     if (!html.isEmpty())
    2287         return html;
    2288     return string;
    2289 
    2290 #undef APPEND
    2291 }
    229281
    229382static QRegExp linkTag("(<@link node=\"([^\"]+)\">).*(</@link>)");
     
    2411200}
    2412201
     202
     203HtmlGenerator::HtmlGenerator()
     204    : helpProjectWriter(0), inLink(false), inContents(false),
     205      inSectionHeading(false), inTableHeader(false), numTableRows(0),
     206      threeColumnEnumValueTable(true), funcLeftParen("\\S(\\()"),
     207      myTree(0), slow(false), obsoleteLinks(false)
     208{
     209}
     210
     211HtmlGenerator::~HtmlGenerator()
     212{
     213    if (helpProjectWriter)
     214        delete helpProjectWriter;
     215}
     216
     217void HtmlGenerator::initializeGenerator(const Config &config)
     218{
     219    static const struct {
     220        const char *key;
     221        const char *left;
     222        const char *right;
     223    } defaults[] = {
     224        { ATOM_FORMATTING_BOLD, "<b>", "</b>" },
     225        { ATOM_FORMATTING_INDEX, "<!--", "-->" },
     226        { ATOM_FORMATTING_ITALIC, "<i>", "</i>" },
     227        { ATOM_FORMATTING_PARAMETER, "<i>", "</i>" },
     228        { ATOM_FORMATTING_SUBSCRIPT, "<sub>", "</sub>" },
     229        { ATOM_FORMATTING_SUPERSCRIPT, "<sup>", "</sup>" },
     230        { ATOM_FORMATTING_TELETYPE, "<tt>", "</tt>" },
     231        { ATOM_FORMATTING_UNDERLINE, "<u>", "</u>" },
     232        { 0, 0, 0 }
     233    };
     234
     235    Generator::initializeGenerator(config);
     236    obsoleteLinks = config.getBool(QLatin1String(CONFIG_OBSOLETELINKS));
     237    setImageFileExtensions(QStringList() << "png" << "jpg" << "jpeg" << "gif");
     238    int i = 0;
     239    while (defaults[i].key) {
     240        formattingLeftMap().insert(defaults[i].key, defaults[i].left);
     241        formattingRightMap().insert(defaults[i].key, defaults[i].right);
     242        i++;
     243    }
     244
     245    style = config.getString(HtmlGenerator::format() +
     246                             Config::dot +
     247                             HTMLGENERATOR_STYLE);
     248    postHeader = config.getString(HtmlGenerator::format() +
     249                                  Config::dot +
     250                                  HTMLGENERATOR_POSTHEADER);
     251    footer = config.getString(HtmlGenerator::format() +
     252                              Config::dot +
     253                              HTMLGENERATOR_FOOTER);
     254    address = config.getString(HtmlGenerator::format() +
     255                               Config::dot +
     256                               HTMLGENERATOR_ADDRESS);
     257    pleaseGenerateMacRef = config.getBool(HtmlGenerator::format() +
     258                                          Config::dot +
     259                                          HTMLGENERATOR_GENERATEMACREFS);
     260
     261    project = config.getString(CONFIG_PROJECT);
     262
     263    projectDescription = config.getString(CONFIG_DESCRIPTION);
     264    if (projectDescription.isEmpty() && !project.isEmpty())
     265        projectDescription = project + " Reference Documentation";
     266
     267    projectUrl = config.getString(CONFIG_URL);
     268
     269    QSet<QString> editionNames = config.subVars(CONFIG_EDITION);
     270    QSet<QString>::ConstIterator edition = editionNames.begin();
     271    while (edition != editionNames.end()) {
     272        QString editionName = *edition;
     273        QStringList editionModules = config.getStringList(CONFIG_EDITION +
     274                                                          Config::dot +
     275                                                          editionName +
     276                                                          Config::dot +
     277                                                          "modules");
     278        QStringList editionGroups = config.getStringList(CONFIG_EDITION +
     279                                                         Config::dot +
     280                                                         editionName +
     281                                                         Config::dot +
     282                                                         "groups");
     283
     284        if (!editionModules.isEmpty())
     285            editionModuleMap[editionName] = editionModules;
     286        if (!editionGroups.isEmpty())
     287            editionGroupMap[editionName] = editionGroups;
     288
     289        ++edition;
     290    }
     291
     292    slow = config.getBool(CONFIG_SLOW);
     293
     294    stylesheets = config.getStringList(HtmlGenerator::format() +
     295                                       Config::dot +
     296                                       HTMLGENERATOR_STYLESHEETS);
     297    customHeadElements = config.getStringList(HtmlGenerator::format() +
     298                                              Config::dot +
     299                                              HTMLGENERATOR_CUSTOMHEADELEMENTS);
     300    codeIndent = config.getInt(CONFIG_CODEINDENT);
     301
     302    helpProjectWriter = new HelpProjectWriter(config,
     303                                              project.toLower() +
     304                                              ".qhp");
     305}
     306
     307void HtmlGenerator::terminateGenerator()
     308{
     309    Generator::terminateGenerator();
     310}
     311
     312QString HtmlGenerator::format()
     313{
     314    return "HTML";
     315}
     316
     317/*!
     318  This is where the html files and dcf files are written.
     319  \note The html file generation is done in the base class,
     320  PageGenerator::generateTree().
     321 */
     322void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker)
     323{
     324    // Copy the stylesheets from the directory containing the qdocconf file.
     325    // ### This should be changed to use a special directory in doc/src.
     326    QStringList::ConstIterator styleIter = stylesheets.begin();
     327    QDir configPath = QDir::current();
     328    while (styleIter != stylesheets.end()) {
     329        QString filePath = configPath.absoluteFilePath(*styleIter);
     330        Config::copyFile(Location(), filePath, filePath, outputDir());
     331        ++styleIter;
     332    }
     333
     334    myTree = tree;
     335    nonCompatClasses.clear();
     336    mainClasses.clear();
     337    compatClasses.clear();
     338    obsoleteClasses.clear();
     339    moduleClassMap.clear();
     340    moduleNamespaceMap.clear();
     341    funcIndex.clear();
     342    legaleseTexts.clear();
     343    serviceClasses.clear();
     344    findAllClasses(tree->root());
     345    findAllFunctions(tree->root());
     346    findAllLegaleseTexts(tree->root());
     347    findAllNamespaces(tree->root());
     348#ifdef ZZZ_QDOC_QML
     349    findAllQmlClasses(tree->root());
     350#endif
     351    findAllSince(tree->root());
     352
     353    PageGenerator::generateTree(tree, marker);
     354
     355    dcfClassesRoot.ref = "classes.html";
     356    dcfClassesRoot.title = "Classes";
     357    qSort(dcfClassesRoot.subsections);
     358
     359    dcfOverviewsRoot.ref = "overviews.html";
     360    dcfOverviewsRoot.title = "Overviews";
     361    qSort(dcfOverviewsRoot.subsections);
     362
     363    dcfExamplesRoot.ref = "examples.html";
     364    dcfExamplesRoot.title = "Tutorial & Examples";
     365    qSort(dcfExamplesRoot.subsections);
     366
     367    DcfSection qtRoot;
     368    appendDcfSubSection(&qtRoot, dcfClassesRoot);
     369    appendDcfSubSection(&qtRoot, dcfOverviewsRoot);
     370    appendDcfSubSection(&qtRoot, dcfExamplesRoot);
     371
     372    generateDcf(project.toLower().simplified().replace(" ", "-"),
     373                "index.html",
     374                projectDescription, qtRoot);
     375    generateDcf("designer",
     376                "designer-manual.html",
     377                "Qt Designer Manual",
     378                dcfDesignerRoot);
     379    generateDcf("linguist",
     380                "linguist-manual.html",
     381                "Qt Linguist Manual",
     382                dcfLinguistRoot);
     383    generateDcf("assistant",
     384                "assistant-manual.html",
     385                "Qt Assistant Manual",
     386                dcfAssistantRoot);
     387    generateDcf("qmake",
     388                "qmake-manual.html",
     389                "qmake Manual",
     390                dcfQmakeRoot);
     391
     392    generateIndex(project.toLower().simplified().replace(" ", "-"),
     393                  projectUrl,
     394                  projectDescription);
     395
     396    helpProjectWriter->generate(myTree);
     397}
     398
     399void HtmlGenerator::startText(const Node * /* relative */,
     400                              CodeMarker * /* marker */)
     401{
     402    inLink = false;
     403    inContents = false;
     404    inSectionHeading = false;
     405    inTableHeader = false;
     406    numTableRows = 0;
     407    threeColumnEnumValueTable = true;
     408    link.clear();
     409    sectionNumber.clear();
     410}
     411
     412int HtmlGenerator::generateAtom(const Atom *atom,
     413                                const Node *relative,
     414                                CodeMarker *marker)
     415{
     416    int skipAhead = 0;
     417    static bool in_para = false;
     418
     419    switch (atom->type()) {
     420    case Atom::AbstractLeft:
     421        break;
     422    case Atom::AbstractRight:
     423        break;
     424    case Atom::AutoLink:
     425        if (!inLink && !inContents && !inSectionHeading) {
     426            const Node *node = 0;
     427            QString link = getLink(atom, relative, marker, &node);
     428            if (!link.isEmpty()) {
     429                beginLink(link, node, relative, marker);
     430                generateLink(atom, relative, marker);
     431                endLink();
     432            }
     433            else {
     434                out() << protect(atom->string());
     435            }
     436        }
     437        else {
     438            out() << protect(atom->string());
     439        }
     440        break;
     441    case Atom::BaseName:
     442        break;
     443    case Atom::BriefLeft:
     444        if (relative->type() == Node::Fake) {
     445            skipAhead = skipAtoms(atom, Atom::BriefRight);
     446            break;
     447        }
     448
     449        out() << "<p>";
     450        if (relative->type() == Node::Property ||
     451            relative->type() == Node::Variable) {
     452            QString str;
     453            atom = atom->next();
     454            while (atom != 0 && atom->type() != Atom::BriefRight) {
     455                if (atom->type() == Atom::String ||
     456                    atom->type() == Atom::AutoLink)
     457                    str += atom->string();
     458                skipAhead++;
     459                atom = atom->next();
     460            }
     461            str[0] = str[0].toLower();
     462            if (str.right(1) == ".")
     463                str.truncate(str.length() - 1);
     464            out() << "This ";
     465            if (relative->type() == Node::Property)
     466                out() << "property";
     467            else
     468                out() << "variable";
     469            QStringList words = str.split(" ");
     470            if (!(words.first() == "contains" || words.first() == "specifies"
     471                || words.first() == "describes" || words.first() == "defines"
     472                || words.first() == "holds" || words.first() == "determines"))
     473                out() << " holds ";
     474            else
     475                out() << " ";
     476            out() << str << ".";
     477        }
     478        break;
     479    case Atom::BriefRight:
     480        if (relative->type() != Node::Fake)
     481            out() << "</p>\n";
     482        break;
     483    case Atom::C:
     484        out() << formattingLeftMap()[ATOM_FORMATTING_TELETYPE];
     485        if (inLink) {
     486            out() << protect(plainCode(atom->string()));
     487        }
     488        else {
     489            out() << highlightedCode(atom->string(), marker, relative);
     490        }
     491        out() << formattingRightMap()[ATOM_FORMATTING_TELETYPE];
     492        break;
     493    case Atom::Code:
     494        out() << "<pre>"
     495              << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
     496                                                 marker,relative))
     497              << "</pre>\n";
     498        break;
     499#ifdef QDOC_QML
     500    case Atom::Qml:
     501        out() << "<pre>"
     502              << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
     503                                                 marker,relative))
     504              << "</pre>\n";
     505        break;
     506#endif
     507    case Atom::CodeNew:
     508        out() << "<p>you can rewrite it as</p>\n"
     509              << "<pre>"
     510              << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
     511                                                 marker,relative))
     512              << "</pre>\n";
     513        break;
     514    case Atom::CodeOld:
     515        out() << "<p>For example, if you have code like</p>\n";
     516        // fallthrough
     517    case Atom::CodeBad:
     518        out() << "<pre><font color=\"#404040\">"
     519              << trimmedTrailing(protect(plainCode(indent(codeIndent,atom->string()))))
     520              << "</font></pre>\n";
     521        break;
     522    case Atom::FootnoteLeft:
     523        // ### For now
     524        if (in_para) {
     525            out() << "</p>\n";
     526            in_para = false;
     527        }
     528        out() << "<!-- ";
     529        break;
     530    case Atom::FootnoteRight:
     531        // ### For now
     532        out() << "-->";
     533        break;
     534    case Atom::FormatElse:
     535    case Atom::FormatEndif:
     536    case Atom::FormatIf:
     537        break;
     538    case Atom::FormattingLeft:
     539        out() << formattingLeftMap()[atom->string()];
     540        if (atom->string() == ATOM_FORMATTING_PARAMETER) {
     541            if (atom->next() != 0 && atom->next()->type() == Atom::String) {
     542                QRegExp subscriptRegExp("([a-z]+)_([0-9n])");
     543                if (subscriptRegExp.exactMatch(atom->next()->string())) {
     544                    out() << subscriptRegExp.cap(1) << "<sub>"
     545                          << subscriptRegExp.cap(2) << "</sub>";
     546                    skipAhead = 1;
     547                }
     548            }
     549        }
     550        break;
     551    case Atom::FormattingRight:
     552        if (atom->string() == ATOM_FORMATTING_LINK) {
     553            endLink();
     554        }
     555        else {
     556            out() << formattingRightMap()[atom->string()];
     557        }
     558        break;
     559    case Atom::AnnotatedList:
     560        {
     561            QList<Node*> values = myTree->groups().values(atom->string());
     562            NodeMap nodeMap;
     563            for (int i = 0; i < values.size(); ++i) {
     564                const Node* n = values.at(i);
     565                if ((n->status() != Node::Internal) && (n->access() != Node::Private)) {
     566                    nodeMap.insert(n->nameForLists(),n);
     567                }
     568            }
     569            generateAnnotatedList(relative, marker, nodeMap);
     570        }
     571        break;
     572    case Atom::GeneratedList:
     573        if (atom->string() == "annotatedclasses") {
     574            generateAnnotatedList(relative, marker, nonCompatClasses);
     575        }
     576        else if (atom->string() == "classes") {
     577            generateCompactList(relative, marker, nonCompatClasses);
     578        }
     579        else if (atom->string().contains("classesbymodule")) {
     580            QString arg = atom->string().trimmed();
     581            QString moduleName = atom->string().mid(atom->string().indexOf(
     582                "classesbymodule") + 15).trimmed();
     583            if (moduleClassMap.contains(moduleName))
     584                generateAnnotatedList(relative, marker, moduleClassMap[moduleName]);
     585        }
     586        else if (atom->string().contains("classesbyedition")) {
     587
     588            QString arg = atom->string().trimmed();
     589            QString editionName = atom->string().mid(atom->string().indexOf(
     590                "classesbyedition") + 16).trimmed();
     591
     592            if (editionModuleMap.contains(editionName)) {
     593
     594                // Add all classes in the modules listed for that edition.
     595                NodeMap editionClasses;
     596                foreach (const QString &moduleName, editionModuleMap[editionName]) {
     597                    if (moduleClassMap.contains(moduleName))
     598                        editionClasses.unite(moduleClassMap[moduleName]);
     599                }
     600
     601                // Add additional groups and remove groups of classes that
     602                // should be excluded from the edition.
     603
     604                QMultiMap <QString, Node *> groups = myTree->groups();
     605                foreach (const QString &groupName, editionGroupMap[editionName]) {
     606                    QList<Node *> groupClasses;
     607                    if (groupName.startsWith("-")) {
     608                        groupClasses = groups.values(groupName.mid(1));
     609                        foreach (const Node *node, groupClasses)
     610                            editionClasses.remove(node->name());
     611                    }
     612                    else {
     613                        groupClasses = groups.values(groupName);
     614                        foreach (const Node *node, groupClasses)
     615                            editionClasses.insert(node->name(), node);
     616                    }
     617                }
     618                generateAnnotatedList(relative, marker, editionClasses);
     619            }
     620        }
     621        else if (atom->string() == "classhierarchy") {
     622            generateClassHierarchy(relative, marker, nonCompatClasses);
     623        }
     624        else if (atom->string() == "compatclasses") {
     625            generateCompactList(relative, marker, compatClasses);
     626        }
     627        else if (atom->string() == "obsoleteclasses") {
     628            generateCompactList(relative, marker, obsoleteClasses);
     629        }
     630        else if (atom->string() == "functionindex") {
     631            generateFunctionIndex(relative, marker);
     632        }
     633        else if (atom->string() == "legalese") {
     634            generateLegaleseList(relative, marker);
     635        }
     636        else if (atom->string() == "mainclasses") {
     637            generateCompactList(relative, marker, mainClasses);
     638        }
     639        else if (atom->string() == "services") {
     640            generateCompactList(relative, marker, serviceClasses);
     641        }
     642        else if (atom->string() == "overviews") {
     643            generateOverviewList(relative, marker);
     644        }
     645        else if (atom->string() == "namespaces") {
     646            generateAnnotatedList(relative, marker, namespaceIndex);
     647        }
     648        else if (atom->string() == "related") {
     649            const FakeNode *fake = static_cast<const FakeNode *>(relative);
     650            if (fake && !fake->groupMembers().isEmpty()) {
     651                NodeMap groupMembersMap;
     652                foreach (const Node *node, fake->groupMembers()) {
     653                    if (node->type() == Node::Fake)
     654                        groupMembersMap[fullName(node, relative, marker)] = node;
     655                }
     656                generateAnnotatedList(fake, marker, groupMembersMap);
     657            }
     658        }
     659        else if (atom->string() == "relatedinline") {
     660            const FakeNode *fake = static_cast<const FakeNode *>(relative);
     661            if (fake && !fake->groupMembers().isEmpty()) {
     662                // Reverse the list into the original scan order.
     663                // Should be sorted.  But on what?  It may not be a
     664                // regular class or page definition.
     665                QList<const Node *> list;
     666                foreach (const Node *node, fake->groupMembers())
     667                    list.prepend(node);
     668                foreach (const Node *node, list)
     669                    generateBody(node, marker);
     670            }
     671        }
     672        break;
     673    case Atom::SinceList:
     674        {
     675            NewSinceMaps::const_iterator nsmap;
     676            nsmap = newSinceMaps.find(atom->string());
     677            NewClassMaps::const_iterator ncmap;
     678            ncmap = newClassMaps.find(atom->string());
     679            if ((nsmap != newSinceMaps.constEnd()) && !nsmap.value().isEmpty()) {
     680                QList<Section> sections;
     681                QList<Section>::ConstIterator s;
     682                for (int i=0; i<LastSinceType; ++i)
     683                    sections.append(Section(sinceTitle(i),QString(),QString()));
     684
     685                NodeMultiMap::const_iterator n = nsmap.value().constBegin();
     686                while (n != nsmap.value().constEnd()) {
     687                    const Node* node = n.value();
     688                    switch (node->type()) {
     689                      case Node::Namespace:
     690                          sections[Namespace].appendMember((Node*)node);
     691                          break;
     692                      case Node::Class:
     693                          sections[Class].appendMember((Node*)node);
     694                          break;
     695                      case Node::Enum:
     696                          sections[Enum].appendMember((Node*)node);
     697                          break;
     698                      case Node::Typedef:
     699                          sections[Typedef].appendMember((Node*)node);
     700                          break;
     701                      case Node::Function: {
     702                          const FunctionNode* fn = static_cast<const FunctionNode*>(node);
     703                          if (fn->isMacro())
     704                              sections[Macro].appendMember((Node*)node);
     705                          else {
     706                              Node* p = fn->parent();
     707                              if (p) {
     708                                  if (p->type() == Node::Class)
     709                                      sections[MemberFunction].appendMember((Node*)node);
     710                                  else if (p->type() == Node::Namespace) {
     711                                      if (p->name().isEmpty())
     712                                          sections[GlobalFunction].appendMember((Node*)node);
     713                                      else
     714                                          sections[NamespaceFunction].appendMember((Node*)node);
     715                                  }
     716                                  else
     717                                      sections[GlobalFunction].appendMember((Node*)node);
     718                              }
     719                              else
     720                                  sections[GlobalFunction].appendMember((Node*)node);
     721                          }
     722                          break;
     723                      }
     724                      case Node::Property:
     725                          sections[Property].appendMember((Node*)node);
     726                          break;
     727                      case Node::Variable:
     728                          sections[Variable].appendMember((Node*)node);
     729                          break;
     730                      case Node::QmlProperty:
     731                          sections[QmlProperty].appendMember((Node*)node);
     732                          break;
     733                      case Node::QmlSignal:
     734                          sections[QmlSignal].appendMember((Node*)node);
     735                          break;
     736                      case Node::QmlMethod:
     737                          sections[QmlMethod].appendMember((Node*)node);
     738                          break;
     739                      default:
     740                          break;
     741                    }
     742                    ++n;
     743                }
     744
     745                /*
     746                  First generate the table of contents.
     747                 */
     748                out() << "<ul>\n";
     749                s = sections.constBegin();
     750                while (s != sections.constEnd()) {
     751                    if (!(*s).members.isEmpty()) {
     752
     753                        out() << "<li>"
     754                              << "<a href=\"#"
     755                              << Doc::canonicalTitle((*s).name)
     756                              << "\">"
     757                              << (*s).name
     758                              << "</a></li>\n";
     759                    }
     760                    ++s;
     761                }
     762                out() << "</ul>\n";
     763
     764                int idx = 0;
     765                s = sections.constBegin();
     766                while (s != sections.constEnd()) {
     767                    if (!(*s).members.isEmpty()) {
     768                        out() << "<a name=\""
     769                              << Doc::canonicalTitle((*s).name)
     770                              << "\"></a>\n";
     771                        out() << "<h3>" << protect((*s).name) << "</h3>\n";
     772                        if (idx == Class)
     773                            generateCompactList(0, marker, ncmap.value(), QString("Q"));
     774                        else if (idx == MemberFunction) {
     775                            ParentMaps parentmaps;
     776                            ParentMaps::iterator pmap;
     777                            NodeList::const_iterator i = s->members.constBegin();
     778                            while (i != s->members.constEnd()) {
     779                                Node* p = (*i)->parent();
     780                                pmap = parentmaps.find(p);
     781                                if (pmap == parentmaps.end())
     782                                    pmap = parentmaps.insert(p,NodeMultiMap());
     783                                pmap->insert((*i)->name(),(*i));
     784                                ++i;
     785                            }
     786                            pmap = parentmaps.begin();
     787                            while (pmap != parentmaps.end()) {
     788                                NodeList nlist = pmap->values();
     789                                out() << "<p>Class ";
     790
     791                                out() << "<a href=\""
     792                                      << linkForNode(pmap.key(), 0)
     793                                      << "\">";
     794                                QStringList pieces = fullName(pmap.key(), 0, marker).split("::");
     795                                out() << protect(pieces.last());
     796                                out() << "</a>"  << ":</p>\n";
     797
     798                                generateSection(nlist, 0, marker, CodeMarker::Summary);
     799                                out() << "<br />";
     800                                ++pmap;
     801                            }
     802                        }
     803                        else
     804                            generateSection(s->members, 0, marker, CodeMarker::Summary);
     805                     }
     806                    ++idx;
     807                    ++s;
     808                }
     809            }
     810        }
     811        break;
     812    case Atom::Image:
     813    case Atom::InlineImage:
     814        {
     815            QString fileName = imageFileName(relative, atom->string());
     816            QString text;
     817            if (atom->next() != 0)
     818                text = atom->next()->string();
     819            if (atom->type() == Atom::Image)
     820                out() << "<p align=\"center\">";
     821            if (fileName.isEmpty()) {
     822                out() << "<font color=\"red\">[Missing image "
     823                      << protect(atom->string()) << "]</font>";
     824            }
     825            else {
     826                out() << "<img src=\"" << protect(fileName) << "\"";
     827                if (!text.isEmpty())
     828                    out() << " alt=\"" << protect(text) << "\"";
     829                out() << " />";
     830                helpProjectWriter->addExtraFile(fileName);
     831            }
     832            if (atom->type() == Atom::Image)
     833                out() << "</p>";
     834        }
     835        break;
     836    case Atom::ImageText:
     837        break;
     838    case Atom::LegaleseLeft:
     839        out() << "<div style=\"padding: 0.5em; background: #e0e0e0; color: black\">";
     840        break;
     841    case Atom::LegaleseRight:
     842        out() << "</div>";
     843        break;
     844    case Atom::LineBreak:
     845        out() << "<br />";
     846        break;
     847    case Atom::Link:
     848        {
     849            const Node *node = 0;
     850            QString myLink = getLink(atom, relative, marker, &node);
     851            if (myLink.isEmpty()) {
     852                relative->doc().location().warning(tr("Cannot link to '%1' in %2")
     853                        .arg(atom->string())
     854                        .arg(marker->plainFullName(relative)));
     855            }
     856            beginLink(myLink, node, relative, marker);
     857            skipAhead = 1;
     858        }
     859        break;
     860    case Atom::LinkNode:
     861        {
     862            const Node *node = CodeMarker::nodeForString(atom->string());
     863            beginLink(linkForNode(node, relative), node, relative, marker);
     864            skipAhead = 1;
     865        }
     866        break;
     867    case Atom::ListLeft:
     868        if (in_para) {
     869            out() << "</p>\n";
     870            in_para = false;
     871        }
     872        if (atom->string() == ATOM_LIST_BULLET) {
     873            out() << "<ul>\n";
     874        }
     875        else if (atom->string() == ATOM_LIST_TAG) {
     876            out() << "<dl>\n";
     877        }
     878        else if (atom->string() == ATOM_LIST_VALUE) {
     879            threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom);
     880            if (threeColumnEnumValueTable) {
     881                out() << "<p><table class=\"valuelist\" border=\"1\" cellpadding=\"2\" "
     882                      << "cellspacing=\"1\" width=\"100%\">\n"
     883                      << "<tr><th width=\"25%\">Constant</th>"
     884                      << "<th width=\"15%\">Value</th>"
     885                      << "<th width=\"60%\">Description</th></tr>\n";
     886            }
     887            else {
     888                out() << "<p><table  class=\"valuelist\" border=\"1\" cellpadding=\"2\" "
     889                      << "cellspacing=\"1\" width=\"40%\">\n"
     890                      << "<tr><th width=\"60%\">Constant</th><th "
     891                      << "width=\"40%\">Value</th></tr>\n";
     892            }
     893        }
     894        else {
     895            out() << "<ol type=";
     896            if (atom->string() == ATOM_LIST_UPPERALPHA) {
     897                out() << "\"A\"";
     898            }
     899            else if (atom->string() == ATOM_LIST_LOWERALPHA) {
     900                out() << "\"a\"";
     901            }
     902            else if (atom->string() == ATOM_LIST_UPPERROMAN) {
     903                out() << "\"I\"";
     904            }
     905            else if (atom->string() == ATOM_LIST_LOWERROMAN) {
     906                out() << "\"i\"";
     907            }
     908            else { // (atom->string() == ATOM_LIST_NUMERIC)
     909                out() << "\"1\"";
     910            }
     911            if (atom->next() != 0 && atom->next()->string().toInt() != 1)
     912                out() << " start=\"" << atom->next()->string() << "\"";
     913            out() << ">\n";
     914        }
     915        break;
     916    case Atom::ListItemNumber:
     917        break;
     918    case Atom::ListTagLeft:
     919        if (atom->string() == ATOM_LIST_TAG) {
     920            out() << "<dt>";
     921        }
     922        else { // (atom->string() == ATOM_LIST_VALUE)
     923            // ### Trenton
     924
     925            out() << "<tr><td valign=\"top\"><tt>"
     926                  << protect(plainCode(marker->markedUpEnumValue(atom->next()->string(),
     927                                                                 relative)))
     928                  << "</tt></td><td align=\"center\" valign=\"top\">";
     929
     930            QString itemValue;
     931            if (relative->type() == Node::Enum) {
     932                const EnumNode *enume = static_cast<const EnumNode *>(relative);
     933                itemValue = enume->itemValue(atom->next()->string());
     934            }
     935
     936            if (itemValue.isEmpty())
     937                out() << "?";
     938            else
     939                out() << "<tt>" << protect(itemValue) << "</tt>";
     940
     941            skipAhead = 1;
     942        }
     943        break;
     944    case Atom::ListTagRight:
     945        if (atom->string() == ATOM_LIST_TAG)
     946            out() << "</dt>\n";
     947        break;
     948    case Atom::ListItemLeft:
     949        if (atom->string() == ATOM_LIST_TAG) {
     950            out() << "<dd>";
     951        }
     952        else if (atom->string() == ATOM_LIST_VALUE) {
     953            if (threeColumnEnumValueTable) {
     954                out() << "</td><td valign=\"top\">";
     955                if (matchAhead(atom, Atom::ListItemRight))
     956                    out() << "&nbsp;";
     957            }
     958        }
     959        else {
     960            out() << "<li>";
     961        }
     962        if (matchAhead(atom, Atom::ParaLeft))
     963            skipAhead = 1;
     964        break;
     965    case Atom::ListItemRight:
     966        if (atom->string() == ATOM_LIST_TAG) {
     967            out() << "</dd>\n";
     968        }
     969        else if (atom->string() == ATOM_LIST_VALUE) {
     970            out() << "</td></tr>\n";
     971        }
     972        else {
     973            out() << "</li>\n";
     974        }
     975        break;
     976    case Atom::ListRight:
     977        if (atom->string() == ATOM_LIST_BULLET) {
     978            out() << "</ul>\n";
     979        }
     980        else if (atom->string() == ATOM_LIST_TAG) {
     981            out() << "</dl>\n";
     982        }
     983        else if (atom->string() == ATOM_LIST_VALUE) {
     984            out() << "</table></p>\n";
     985        }
     986        else {
     987            out() << "</ol>\n";
     988        }
     989        break;
     990    case Atom::Nop:
     991        break;
     992    case Atom::ParaLeft:
     993        out() << "<p>";
     994        in_para = true;
     995        break;
     996    case Atom::ParaRight:
     997        endLink();
     998        if (in_para) {
     999            out() << "</p>\n";
     1000            in_para = false;
     1001        }
     1002        //if (!matchAhead(atom, Atom::ListItemRight) && !matchAhead(atom, Atom::TableItemRight))
     1003        //    out() << "</p>\n";
     1004        break;
     1005    case Atom::QuotationLeft:
     1006        out() << "<blockquote>";
     1007        break;
     1008    case Atom::QuotationRight:
     1009        out() << "</blockquote>\n";
     1010        break;
     1011    case Atom::RawString:
     1012        out() << atom->string();
     1013        break;
     1014    case Atom::SectionLeft:
     1015#if 0
     1016        {
     1017            int nextLevel = atom->string().toInt();
     1018            if (sectionNumber.size() < nextLevel) {
     1019                do {
     1020                    sectionNumber.append("1");
     1021                } while (sectionNumber.size() < nextLevel);
     1022            }
     1023            else {
     1024                while (sectionNumber.size() > nextLevel) {
     1025                    sectionNumber.removeLast();
     1026                }
     1027                sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1);
     1028            }
     1029            out() << "<a name=\"sec-" << sectionNumber.join("-") << "\"></a>\n";
     1030        }
     1031#else
     1032        out() << "<a name=\"" << Doc::canonicalTitle(Text::sectionHeading(atom).toString())
     1033              << "\"></a>\n";
     1034#endif
     1035        break;
     1036    case Atom::SectionRight:
     1037        break;
     1038    case Atom::SectionHeadingLeft:
     1039        out() << "<h" + QString::number(atom->string().toInt() + hOffset(relative)) + ">";
     1040        inSectionHeading = true;
     1041        break;
     1042    case Atom::SectionHeadingRight:
     1043        out() << "</h" + QString::number(atom->string().toInt() + hOffset(relative)) + ">\n";
     1044        inSectionHeading = false;
     1045        break;
     1046    case Atom::SidebarLeft:
     1047        break;
     1048    case Atom::SidebarRight:
     1049        break;
     1050    case Atom::String:
     1051        if (inLink && !inContents && !inSectionHeading) {
     1052            generateLink(atom, relative, marker);
     1053        }
     1054        else {
     1055            out() << protect(atom->string());
     1056        }
     1057        break;
     1058    case Atom::TableLeft:
     1059        if (in_para) {
     1060            out() << "</p>\n";
     1061            in_para = false;
     1062        }
     1063        if (!atom->string().isEmpty()) {
     1064            if (atom->string().contains("%"))
     1065                out() << "<p><table class=\"generic\" width=\"" << atom->string() << "\" "
     1066                      << "align=\"center\" cellpadding=\"2\" "
     1067                      << "cellspacing=\"1\" border=\"0\">\n";
     1068            else {
     1069                out() << "<p><table class=\"generic\" align=\"center\" cellpadding=\"2\" "
     1070                      << "cellspacing=\"1\" border=\"0\">\n";
     1071            }
     1072        }
     1073        else {
     1074            out() << "<p><table class=\"generic\" align=\"center\" cellpadding=\"2\" "
     1075                  << "cellspacing=\"1\" border=\"0\">\n";
     1076        }
     1077        numTableRows = 0;
     1078        break;
     1079    case Atom::TableRight:
     1080        out() << "</table></p>\n";
     1081        break;
     1082    case Atom::TableHeaderLeft:
     1083        out() << "<thead><tr valign=\"top\" class=\"qt-style\">";
     1084        inTableHeader = true;
     1085        break;
     1086    case Atom::TableHeaderRight:
     1087        out() << "</tr>";
     1088        if (matchAhead(atom, Atom::TableHeaderLeft)) {
     1089            skipAhead = 1;
     1090            out() << "\n<tr valign=\"top\" class=\"qt-style\">";
     1091        }
     1092        else {
     1093            out() << "</thead>\n";
     1094            inTableHeader = false;
     1095        }
     1096        break;
     1097    case Atom::TableRowLeft:
     1098        if (++numTableRows % 2 == 1)
     1099            out() << "<tr valign=\"top\" class=\"odd\">";
     1100        else
     1101            out() << "<tr valign=\"top\" class=\"even\">";
     1102        break;
     1103    case Atom::TableRowRight:
     1104        out() << "</tr>\n";
     1105        break;
     1106    case Atom::TableItemLeft:
     1107        {
     1108            if (inTableHeader)
     1109                out() << "<th";
     1110            else
     1111                out() << "<td";
     1112
     1113            QStringList spans = atom->string().split(",");
     1114            if (spans.size() == 2) {
     1115                if (spans.at(0) != "1")
     1116                    out() << " colspan=\"" << spans.at(0) << "\"";
     1117                if (spans.at(1) != "1")
     1118                    out() << " rowspan=\"" << spans.at(1) << "\"";
     1119                out() << ">";
     1120            }
     1121            if (matchAhead(atom, Atom::ParaLeft))
     1122                skipAhead = 1;
     1123        }
     1124        break;
     1125    case Atom::TableItemRight:
     1126        if (inTableHeader)
     1127            out() << "</th>";
     1128        else
     1129            out() << "</td>";
     1130        if (matchAhead(atom, Atom::ParaLeft))
     1131            skipAhead = 1;
     1132        break;
     1133    case Atom::TableOfContents:
     1134        {
     1135            int numColumns = 1;
     1136            const Node *node = relative;
     1137
     1138            Doc::SectioningUnit sectioningUnit = Doc::Section4;
     1139            QStringList params = atom->string().split(",");
     1140            QString columnText = params.at(0);
     1141            QStringList pieces = columnText.split(" ", QString::SkipEmptyParts);
     1142            if (pieces.size() >= 2) {
     1143                columnText = pieces.at(0);
     1144                pieces.pop_front();
     1145                QString path = pieces.join(" ").trimmed();
     1146                node = findNodeForTarget(path, relative, marker, atom);
     1147            }
     1148
     1149            if (params.size() == 2) {
     1150                numColumns = qMax(columnText.toInt(), numColumns);
     1151                sectioningUnit = (Doc::SectioningUnit)params.at(1).toInt();
     1152            }
     1153
     1154            if (node)
     1155                generateTableOfContents(node,
     1156                                        marker,
     1157                                        sectioningUnit,
     1158                                        numColumns,
     1159                                        relative);
     1160        }
     1161        break;
     1162    case Atom::Target:
     1163        out() << "<a name=\"" << Doc::canonicalTitle(atom->string()) << "\"></a>";
     1164        break;
     1165    case Atom::UnhandledFormat:
     1166        out() << "<font color=\"red\"><b>&lt;Missing HTML&gt;</b></font>";
     1167        break;
     1168    case Atom::UnknownCommand:
     1169        out() << "<font color=\"red\"><b><code>\\" << protect(atom->string())
     1170              << "</code></b></font>";
     1171        break;
     1172#ifdef QDOC_QML
     1173    case Atom::QmlText:
     1174    case Atom::EndQmlText:
     1175        // don't do anything with these. They are just tags.
     1176        break;
     1177#endif
     1178    default:
     1179        unknownAtom(atom);
     1180    }
     1181    return skipAhead;
     1182}
     1183
     1184void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
     1185                                          CodeMarker *marker)
     1186{
     1187    QList<Section> sections;
     1188    QList<Section>::ConstIterator s;
     1189
     1190    const ClassNode *classe = 0;
     1191    const NamespaceNode *namespasse = 0;
     1192
     1193    QString title;
     1194    QString rawTitle;
     1195    QString fullTitle;
     1196    if (inner->type() == Node::Namespace) {
     1197        namespasse = static_cast<const NamespaceNode *>(inner);
     1198        rawTitle = marker->plainName(inner);
     1199        fullTitle = marker->plainFullName(inner);
     1200        title = rawTitle + " Namespace Reference";
     1201    }
     1202    else if (inner->type() == Node::Class) {
     1203        classe = static_cast<const ClassNode *>(inner);
     1204        rawTitle = marker->plainName(inner);
     1205        fullTitle = marker->plainFullName(inner);
     1206        title = rawTitle + " Class Reference";
     1207    }
     1208
     1209    DcfSection classSection;
     1210    classSection.title = title;
     1211    classSection.ref = linkForNode(inner, 0);
     1212    classSection.keywords += qMakePair(inner->name(), classSection.ref);
     1213
     1214    Text subtitleText;
     1215    if (rawTitle != fullTitle)
     1216        subtitleText << "(" << Atom(Atom::AutoLink, fullTitle) << ")"
     1217                     << Atom(Atom::LineBreak);
     1218
     1219    QString fixedModule = inner->moduleName();
     1220    if (fixedModule == "Qt3SupportLight")
     1221        fixedModule = "Qt3Support";
     1222    if (!fixedModule.isEmpty())
     1223        subtitleText << "[" << Atom(Atom::AutoLink, fixedModule) << " module]";
     1224
     1225    if (fixedModule.isEmpty()) {
     1226        QMultiMap<QString, QString> publicGroups = myTree->publicGroups();
     1227        QList<QString> groupNames = publicGroups.values(inner->name());
     1228        if (!groupNames.isEmpty()) {
     1229            qSort(groupNames.begin(), groupNames.end());
     1230            subtitleText << "[";
     1231            for (int j=0; j<groupNames.count(); j++) {
     1232                subtitleText <<  Atom(Atom::AutoLink, groupNames[j]);
     1233                if (j<groupNames.count()-1)
     1234                    subtitleText <<", ";
     1235            }
     1236            subtitleText << "]";
     1237        }
     1238    }
     1239
     1240    generateHeader(title, inner, marker, true);
     1241    generateTitle(title, subtitleText, SmallSubTitle, inner, marker);
     1242
     1243#ifdef QDOC_QML
     1244    if (classe && !classe->qmlElement().isEmpty()) {
     1245        generateInstantiatedBy(classe,marker);
     1246    }
     1247#endif
     1248   
     1249    generateBrief(inner, marker);
     1250    generateIncludes(inner, marker);
     1251    generateStatus(inner, marker);
     1252    if (classe) {
     1253        generateModuleWarning(classe, marker);
     1254        generateInherits(classe, marker);
     1255        generateInheritedBy(classe, marker);
     1256    }
     1257    generateThreadSafeness(inner, marker);
     1258    generateSince(inner, marker);
     1259
     1260    out() << "<ul>\n";
     1261
     1262    QString membersLink = generateListOfAllMemberFile(inner, marker);
     1263    if (!membersLink.isEmpty())
     1264        out() << "<li><a href=\"" << membersLink << "\">"
     1265              << "List of all members, including inherited members</a></li>\n";
     1266
     1267    QString obsoleteLink = generateLowStatusMemberFile(inner,
     1268                                                       marker,
     1269                                                       CodeMarker::Obsolete);
     1270    if (!obsoleteLink.isEmpty())
     1271        out() << "<li><a href=\"" << obsoleteLink << "\">"
     1272              << "Obsolete members</a></li>\n";
     1273
     1274    QString compatLink = generateLowStatusMemberFile(inner,
     1275                                                     marker,
     1276                                                     CodeMarker::Compat);
     1277    if (!compatLink.isEmpty())
     1278        out() << "<li><a href=\"" << compatLink << "\">"
     1279              << "Qt 3 support members</a></li>\n";
     1280
     1281    out() << "</ul>\n";
     1282
     1283    bool needOtherSection = false;
     1284
     1285    sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
     1286    s = sections.begin();
     1287    while (s != sections.end()) {
     1288        if (s->members.isEmpty() && s->reimpMembers.isEmpty()) {
     1289            if (!s->inherited.isEmpty())
     1290                needOtherSection = true;
     1291        }
     1292        else {
     1293            if (!s->members.isEmpty()) {
     1294                out() << "<hr />\n";
     1295                out() << "<a name=\""
     1296                      << registerRef((*s).name.toLower())
     1297                      << "\"></a>\n";
     1298                out() << "<h2>" << protect((*s).name) << "</h2>\n";
     1299                generateSection(s->members, inner, marker, CodeMarker::Summary);
     1300            }
     1301            if (!s->reimpMembers.isEmpty()) {
     1302                QString name = QString("Reimplemented ") + (*s).name;
     1303                out() << "<hr />\n";
     1304                out() << "<a name=\""
     1305                      << registerRef(name.toLower())
     1306                      << "\"></a>\n";
     1307                out() << "<h2>" << protect(name) << "</h2>\n";
     1308                generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary);
     1309            }
     1310
     1311            if (!s->inherited.isEmpty()) {
     1312                out() << "<ul>\n";
     1313                generateSectionInheritedList(*s, inner, marker, true);
     1314                out() << "</ul>\n";
     1315            }
     1316        }
     1317        ++s;
     1318    }
     1319
     1320    if (needOtherSection) {
     1321        out() << "<h3>Additional Inherited Members</h3>\n"
     1322                 "<ul>\n";
     1323
     1324        s = sections.begin();
     1325        while (s != sections.end()) {
     1326            if (s->members.isEmpty() && !s->inherited.isEmpty())
     1327                generateSectionInheritedList(*s, inner, marker);
     1328            ++s;
     1329        }
     1330        out() << "</ul>\n";
     1331    }
     1332
     1333    out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
     1334
     1335    if (!inner->doc().isEmpty()) {
     1336        out() << "<hr />\n"
     1337              << "<h2>" << "Detailed Description" << "</h2>\n";
     1338        generateBody(inner, marker);
     1339        generateAlsoList(inner, marker);
     1340    }
     1341
     1342    sections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay);
     1343    s = sections.begin();
     1344    while (s != sections.end()) {
     1345        out() << "<hr />\n";
     1346        out() << "<h2>" << protect((*s).name) << "</h2>\n";
     1347
     1348        NodeList::ConstIterator m = (*s).members.begin();
     1349        while (m != (*s).members.end()) {
     1350            if ((*m)->access() != Node::Private) { // ### check necessary?
     1351                if ((*m)->type() != Node::Class)
     1352                    generateDetailedMember(*m, inner, marker);
     1353                else {
     1354                    out() << "<h3> class ";
     1355                    generateFullName(*m, inner, marker);
     1356                    out() << "</h3>";
     1357                    generateBrief(*m, marker, inner);
     1358                }
     1359
     1360                QStringList names;
     1361                names << (*m)->name();
     1362                if ((*m)->type() == Node::Function) {
     1363                    const FunctionNode *func = reinterpret_cast<const FunctionNode *>(*m);
     1364                    if (func->metaness() == FunctionNode::Ctor ||
     1365                        func->metaness() == FunctionNode::Dtor ||
     1366                        func->overloadNumber() != 1)
     1367                        names.clear();
     1368                }
     1369                else if ((*m)->type() == Node::Property) {
     1370                    const PropertyNode *prop = reinterpret_cast<const PropertyNode *>(*m);
     1371                    if (!prop->getters().isEmpty() &&
     1372                        !names.contains(prop->getters().first()->name()))
     1373                        names << prop->getters().first()->name();
     1374                    if (!prop->setters().isEmpty())
     1375                        names << prop->setters().first()->name();
     1376                    if (!prop->resetters().isEmpty())
     1377                        names << prop->resetters().first()->name();
     1378                }
     1379                else if ((*m)->type() == Node::Enum) {
     1380                    const EnumNode *enume = reinterpret_cast<const EnumNode*>(*m);
     1381                    if (enume->flagsType())
     1382                        names << enume->flagsType()->name();
     1383
     1384                    foreach (const QString &enumName,
     1385                             enume->doc().enumItemNames().toSet() -
     1386                             enume->doc().omitEnumItemNames().toSet())
     1387                        names << plainCode(marker->markedUpEnumValue(enumName,
     1388                                                                     enume));
     1389                }
     1390                foreach (const QString &name, names)
     1391                    classSection.keywords += qMakePair(name,linkForNode(*m,0));
     1392            }
     1393            ++m;
     1394        }
     1395        ++s;
     1396    }
     1397    generateFooter(inner);
     1398
     1399    if (!membersLink.isEmpty()) {
     1400        DcfSection membersSection;
     1401        membersSection.title = "List of all members";
     1402        membersSection.ref = membersLink;
     1403        appendDcfSubSection(&classSection, membersSection);
     1404    }
     1405    if (!obsoleteLink.isEmpty()) {
     1406        DcfSection obsoleteSection;
     1407        obsoleteSection.title = "Obsolete members";
     1408        obsoleteSection.ref = obsoleteLink;
     1409        appendDcfSubSection(&classSection, obsoleteSection);
     1410    }
     1411    if (!compatLink.isEmpty()) {
     1412        DcfSection compatSection;
     1413        compatSection.title = "Qt 3 support members";
     1414        compatSection.ref = compatLink;
     1415        appendDcfSubSection(&classSection, compatSection);
     1416    }
     1417
     1418    appendDcfSubSection(&dcfClassesRoot, classSection);
     1419}
     1420
     1421void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
     1422{
     1423    SubTitleSize subTitleSize = LargeSubTitle;
     1424    DcfSection fakeSection;
     1425    fakeSection.title = fake->fullTitle();
     1426    fakeSection.ref = linkForNode(fake, 0);
     1427
     1428    QList<Section> sections;
     1429    QList<Section>::const_iterator s;
     1430
     1431    QString htmlTitle = fake->fullTitle();
     1432    if (fake->subType() == Node::File && !fake->subTitle().isEmpty()) {
     1433        subTitleSize = SmallSubTitle;
     1434        htmlTitle += " (" + fake->subTitle() + ")";
     1435    }
     1436
     1437    generateHeader(htmlTitle, fake, marker, true);
     1438    generateTitle(fake->fullTitle(),
     1439                  Text() << fake->subTitle(),
     1440                  subTitleSize,
     1441                  fake,
     1442                  marker);
     1443
     1444    if (fake->subType() == Node::Module) {
     1445        // Generate brief text and status for modules.
     1446        generateBrief(fake, marker);
     1447        generateStatus(fake, marker);
     1448
     1449        if (moduleNamespaceMap.contains(fake->name())) {
     1450            out() << "<h2>Namespaces</h2>\n";
     1451            generateAnnotatedList(fake, marker, moduleNamespaceMap[fake->name()]);
     1452        }
     1453        if (moduleClassMap.contains(fake->name())) {
     1454            out() << "<h2>Classes</h2>\n";
     1455            generateAnnotatedList(fake, marker, moduleClassMap[fake->name()]);
     1456        }
     1457    }
     1458    else if (fake->subType() == Node::HeaderFile) {
     1459        // Generate brief text and status for modules.
     1460        generateBrief(fake, marker);
     1461        generateStatus(fake, marker);
     1462
     1463        out() << "<ul>\n";
     1464
     1465        QString membersLink = generateListOfAllMemberFile(fake, marker);
     1466        if (!membersLink.isEmpty())
     1467            out() << "<li><a href=\"" << membersLink << "\">"
     1468                  << "List of all members, including inherited members</a></li>\n";
     1469
     1470        QString obsoleteLink = generateLowStatusMemberFile(fake,
     1471                                                           marker,
     1472                                                           CodeMarker::Obsolete);
     1473        if (!obsoleteLink.isEmpty())
     1474            out() << "<li><a href=\"" << obsoleteLink << "\">"
     1475                  << "Obsolete members</a></li>\n";
     1476
     1477        QString compatLink = generateLowStatusMemberFile(fake,
     1478                                                         marker,
     1479                                                         CodeMarker::Compat);
     1480        if (!compatLink.isEmpty())
     1481            out() << "<li><a href=\"" << compatLink << "\">"
     1482                  << "Qt 3 support members</a></li>\n";
     1483
     1484        out() << "</ul>\n";
     1485
     1486        if (!membersLink.isEmpty()) {
     1487            DcfSection membersSection;
     1488            membersSection.title = "List of all members";
     1489            membersSection.ref = membersLink;
     1490            appendDcfSubSection(&fakeSection, membersSection);
     1491        }
     1492        if (!obsoleteLink.isEmpty()) {
     1493            DcfSection obsoleteSection;
     1494            obsoleteSection.title = "Obsolete members";
     1495            obsoleteSection.ref = obsoleteLink;
     1496            appendDcfSubSection(&fakeSection, obsoleteSection);
     1497        }
     1498        if (!compatLink.isEmpty()) {
     1499            DcfSection compatSection;
     1500            compatSection.title = "Qt 3 support members";
     1501            compatSection.ref = compatLink;
     1502            appendDcfSubSection(&fakeSection, compatSection);
     1503        }
     1504    }
     1505#ifdef QDOC_QML
     1506    else if (fake->subType() == Node::QmlClass) {
     1507        const QmlClassNode* qml_cn = static_cast<const QmlClassNode*>(fake);
     1508        const ClassNode* cn = qml_cn->classNode();
     1509        generateQmlInherits(qml_cn, marker);
     1510        generateQmlInstantiates(qml_cn, marker);
     1511        generateBrief(qml_cn, marker);
     1512        sections = marker->qmlSections(qml_cn,CodeMarker::Summary);
     1513        s = sections.begin();
     1514        while (s != sections.end()) {
     1515            out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
     1516            out() << "<h2>" << protect((*s).name) << "</h2>\n";
     1517            generateQmlSummary(*s,fake,marker);
     1518            ++s;
     1519        }
     1520
     1521        out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
     1522        out() << "<h2>" << "Detailed Description" << "</h2>\n";
     1523        generateBody(fake, marker);
     1524        if (cn)
     1525            generateQmlText(cn->doc().body(), cn, marker, fake->name());
     1526        generateAlsoList(fake, marker);
     1527        out() << "<hr />\n";
     1528
     1529        sections = marker->qmlSections(qml_cn,CodeMarker::Detailed);
     1530        s = sections.begin();
     1531        while (s != sections.end()) {
     1532            out() << "<h2>" << protect((*s).name) << "</h2>\n";
     1533            NodeList::ConstIterator m = (*s).members.begin();
     1534            while (m != (*s).members.end()) {
     1535                generateDetailedQmlMember(*m, fake, marker);
     1536                out() << "<br />\n";
     1537                fakeSection.keywords += qMakePair((*m)->name(),
     1538                                                  linkForNode(*m,0));
     1539                ++m;
     1540            }
     1541            ++s;
     1542        }
     1543        generateFooter(fake);
     1544        return;
     1545    }
     1546#endif
     1547   
     1548    sections = marker->sections(fake, CodeMarker::Summary, CodeMarker::Okay);
     1549    s = sections.begin();
     1550    while (s != sections.end()) {
     1551        out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
     1552        out() << "<h2>" << protect((*s).name) << "</h2>\n";
     1553        generateSectionList(*s, fake, marker, CodeMarker::Summary);
     1554        ++s;
     1555    }
     1556
     1557    Text brief = fake->doc().briefText();
     1558    if (fake->subType() == Node::Module && !brief.isEmpty()) {
     1559        out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
     1560        out() << "<h2>" << "Detailed Description" << "</h2>\n";
     1561    }
     1562
     1563    generateBody(fake, marker);
     1564    generateAlsoList(fake, marker);
     1565
     1566    if (!fake->groupMembers().isEmpty()) {
     1567        NodeMap groupMembersMap;
     1568        foreach (const Node *node, fake->groupMembers()) {
     1569            if (node->type() == Node::Class || node->type() == Node::Namespace)
     1570                groupMembersMap[node->name()] = node;
     1571        }
     1572        generateAnnotatedList(fake, marker, groupMembersMap);
     1573    }
     1574
     1575    fakeSection.keywords += qMakePair(fakeSection.title, fakeSection.ref);
     1576
     1577    sections = marker->sections(fake, CodeMarker::Detailed, CodeMarker::Okay);
     1578    s = sections.begin();
     1579    while (s != sections.end()) {
     1580        out() << "<hr />\n";
     1581        out() << "<h2>" << protect((*s).name) << "</h2>\n";
     1582
     1583        NodeList::ConstIterator m = (*s).members.begin();
     1584        while (m != (*s).members.end()) {
     1585            generateDetailedMember(*m, fake, marker);
     1586            fakeSection.keywords += qMakePair((*m)->name(), linkForNode(*m, 0));
     1587            ++m;
     1588        }
     1589        ++s;
     1590    }
     1591    generateFooter(fake);
     1592
     1593    if (fake->subType() == Node::Example) {
     1594        appendDcfSubSection(&dcfExamplesRoot, fakeSection);
     1595    }
     1596    else if (fake->subType() != Node::File) {
     1597        QString contentsPage = fake->links().value(Node::ContentsLink).first;
     1598
     1599        if (contentsPage == "Qt Designer Manual") {
     1600            appendDcfSubSection(&dcfDesignerRoot, fakeSection);
     1601        }
     1602        else if (contentsPage == "Qt Linguist Manual") {
     1603            appendDcfSubSection(&dcfLinguistRoot, fakeSection);
     1604        }
     1605        else if (contentsPage == "Qt Assistant Manual") {
     1606            appendDcfSubSection(&dcfAssistantRoot, fakeSection);
     1607        }
     1608        else if (contentsPage == "qmake Manual") {
     1609            appendDcfSubSection(&dcfQmakeRoot, fakeSection);
     1610        }
     1611        else {
     1612            appendDcfSubSection(&dcfOverviewsRoot, fakeSection);
     1613        }
     1614    }
     1615}
     1616
     1617QString HtmlGenerator::fileExtension(const Node * /* node */)
     1618{
     1619    return "html";
     1620}
     1621
     1622void HtmlGenerator::generateHeader(const QString& title,
     1623                                   const Node *node,
     1624                                   CodeMarker *marker,
     1625                                   bool mainPage)
     1626{
     1627    out() << "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n";
     1628
     1629    out() << "<!DOCTYPE html\n"
     1630             "    PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n"
     1631             "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n";
     1632
     1633    QString shortVersion;
     1634    if ((project != "Qtopia") && (project != "Qt Extended")) {
     1635        shortVersion = project + " " + shortVersion + ": ";
     1636        if (node && !node->doc().location().isEmpty())
     1637            out() << "<!-- " << node->doc().location().fileName() << " -->\n";
     1638
     1639        shortVersion = myTree->version();
     1640        if (shortVersion.count(QChar('.')) == 2)
     1641            shortVersion.truncate(shortVersion.lastIndexOf(QChar('.')));
     1642        if (!shortVersion.isEmpty()) {
     1643            if (project == "QSA")
     1644                shortVersion = "QSA " + shortVersion + ": ";
     1645            else
     1646                shortVersion = "Qt " + shortVersion + ": ";
     1647        }
     1648    }
     1649
     1650    out() << "<head>\n"
     1651             "  <title>" << shortVersion << protect(title) << "</title>\n";
     1652    if (!style.isEmpty())
     1653        out() << "    <style type=\"text/css\">" << style << "</style>\n";
     1654
     1655    const QMap<QString, QString> &metaMap = node->doc().metaTagMap();
     1656    if (!metaMap.isEmpty()) {
     1657        QMapIterator<QString, QString> i(metaMap);
     1658        while (i.hasNext()) {
     1659            i.next();
     1660            out() << "    <meta name=\"" << protect(i.key()) << "\" contents=\""
     1661                  << protect(i.value()) << "\" />\n";
     1662        }
     1663    }
     1664
     1665    navigationLinks.clear();
     1666
     1667    if (node && !node->links().empty()) {
     1668        QPair<QString,QString> linkPair;
     1669        QPair<QString,QString> anchorPair;
     1670        const Node *linkNode;
     1671
     1672        if (node->links().contains(Node::PreviousLink)) {
     1673            linkPair = node->links()[Node::PreviousLink];
     1674            linkNode = findNodeForTarget(linkPair.first, node, marker);
     1675            if (!linkNode || linkNode == node)
     1676                anchorPair = linkPair;
     1677            else
     1678                anchorPair = anchorForNode(linkNode);
     1679
     1680            out() << "  <link rel=\"prev\" href=\""
     1681                  << anchorPair.first << "\" />\n";
     1682
     1683            navigationLinks += "[Previous: <a href=\"" + anchorPair.first + "\">";
     1684            if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
     1685                navigationLinks += protect(anchorPair.second);
     1686            else
     1687                navigationLinks += protect(linkPair.second);
     1688            navigationLinks += "</a>]\n";
     1689        }
     1690        if (node->links().contains(Node::ContentsLink)) {
     1691            linkPair = node->links()[Node::ContentsLink];
     1692            linkNode = findNodeForTarget(linkPair.first, node, marker);
     1693            if (!linkNode || linkNode == node)
     1694                anchorPair = linkPair;
     1695            else
     1696                anchorPair = anchorForNode(linkNode);
     1697
     1698            out() << "  <link rel=\"contents\" href=\""
     1699                  << anchorPair.first << "\" />\n";
     1700
     1701            navigationLinks += "[<a href=\"" + anchorPair.first + "\">";
     1702            if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
     1703                navigationLinks += protect(anchorPair.second);
     1704            else
     1705                navigationLinks += protect(linkPair.second);
     1706            navigationLinks += "</a>]\n";
     1707        }
     1708        if (node->links().contains(Node::NextLink)) {
     1709            linkPair = node->links()[Node::NextLink];
     1710            linkNode = findNodeForTarget(linkPair.first, node, marker);
     1711            if (!linkNode || linkNode == node)
     1712                anchorPair = linkPair;
     1713            else
     1714                anchorPair = anchorForNode(linkNode);
     1715
     1716            out() << "  <link rel=\"next\" href=\""
     1717                  << anchorPair.first << "\" />\n";
     1718
     1719            navigationLinks += "[Next: <a href=\"" + anchorPair.first + "\">";
     1720            if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
     1721                navigationLinks += protect(anchorPair.second);
     1722            else
     1723                navigationLinks += protect(linkPair.second);
     1724            navigationLinks += "</a>]\n";
     1725        }
     1726        if (node->links().contains(Node::IndexLink)) {
     1727            linkPair = node->links()[Node::IndexLink];
     1728            linkNode = findNodeForTarget(linkPair.first, node, marker);
     1729            if (!linkNode || linkNode == node)
     1730                anchorPair = linkPair;
     1731            else
     1732                anchorPair = anchorForNode(linkNode);
     1733            out() << "  <link rel=\"index\" href=\""
     1734                  << anchorPair.first << "\" />\n";
     1735        }
     1736        if (node->links().contains(Node::StartLink)) {
     1737            linkPair = node->links()[Node::StartLink];
     1738            linkNode = findNodeForTarget(linkPair.first, node, marker);
     1739            if (!linkNode || linkNode == node)
     1740                anchorPair = linkPair;
     1741            else
     1742                anchorPair = anchorForNode(linkNode);
     1743            out() << "  <link rel=\"start\" href=\""
     1744                  << anchorPair.first << "\" />\n";
     1745        }
     1746    }
     1747
     1748    foreach (const QString &stylesheet, stylesheets) {
     1749        out() << "  <link href=\"" << stylesheet << "\" rel=\"stylesheet\" "
     1750              << "type=\"text/css\" />\n";
     1751    }
     1752
     1753    foreach (const QString &customHeadElement, customHeadElements) {
     1754        out() << "  " << customHeadElement << "\n";
     1755    }
     1756
     1757    out() << "</head>\n"
     1758             "<body>\n";
     1759    if (mainPage)
     1760        generateMacRef(node, marker);
     1761    out() << QString(postHeader).replace("\\" + COMMAND_VERSION, myTree->version());
     1762
     1763
     1764    if (node && !node->links().empty())
     1765        out() << "<p>\n" << navigationLinks << "</p>\n";
     1766}
     1767
     1768void HtmlGenerator::generateTitle(const QString& title,
     1769                                  const Text &subTitle,
     1770                                  SubTitleSize subTitleSize,
     1771                                  const Node *relative,
     1772                                  CodeMarker *marker)
     1773{
     1774    out() << "<h1 class=\"title\">" << protect(title);
     1775    if (!subTitle.isEmpty()) {
     1776        out() << "<br />";
     1777        if (subTitleSize == SmallSubTitle)
     1778            out() << "<span class=\"small-subtitle\">";
     1779        else
     1780            out() << "<span class=\"subtitle\">";
     1781        generateText(subTitle, relative, marker);
     1782        out() << "</span>\n";
     1783    }
     1784    out() << "</h1>\n";
     1785}
     1786
     1787void HtmlGenerator::generateFooter(const Node *node)
     1788{
     1789    if (node && !node->links().empty())
     1790        out() << "<p>\n" << navigationLinks << "</p>\n";
     1791
     1792    out() << QString(footer).replace("\\" + COMMAND_VERSION, myTree->version())
     1793          << QString(address).replace("\\" + COMMAND_VERSION, myTree->version())
     1794          << "</body>\n"
     1795             "</html>\n";
     1796}
     1797
     1798void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker,
     1799                                  const Node *relative)
     1800{
     1801    Text brief = node->doc().briefText();
     1802    if (!brief.isEmpty()) {
     1803        out() << "<p>";
     1804        generateText(brief, node, marker);
     1805        if (!relative || node == relative)
     1806            out() << " <a href=\"#";
     1807        else
     1808            out() << " <a href=\"" << linkForNode(node, relative) << "#";
     1809        out() << registerRef("details") << "\">More...</a></p>\n";
     1810    }
     1811}
     1812
     1813void HtmlGenerator::generateIncludes(const InnerNode *inner, CodeMarker *marker)
     1814{
     1815    if (!inner->includes().isEmpty()) {
     1816        out() << "<pre>"
     1817              << trimmedTrailing(highlightedCode(indent(codeIndent,
     1818                                                        marker->markedUpIncludes(inner->includes())),
     1819                                                 marker,inner))
     1820              << "</pre>";
     1821    }
     1822}
     1823
     1824void HtmlGenerator::generateTableOfContents(const Node *node,
     1825                                            CodeMarker *marker,
     1826                                            Doc::SectioningUnit sectioningUnit,
     1827                                            int numColumns,
     1828                                            const Node *relative)
     1829
     1830{
     1831    if (!node->doc().hasTableOfContents())
     1832        return;
     1833    QList<Atom *> toc = node->doc().tableOfContents();
     1834    if (toc.isEmpty())
     1835        return;
     1836
     1837    QString nodeName = "";
     1838    if (node != relative)
     1839        nodeName = node->name();
     1840
     1841    QStringList sectionNumber;
     1842    int columnSize = 0;
     1843
     1844    QString tdTag;
     1845    if (numColumns > 1) {
     1846        tdTag = "<td width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";
     1847        out() << "<p><table class=\"toc\" width=\"100%\">\n<tr valign=\"top\">"
     1848              << tdTag << "\n";
     1849    }
     1850
     1851    // disable nested links in table of contents
     1852    inContents = true;
     1853    inLink = true;
     1854
     1855    for (int i = 0; i < toc.size(); ++i) {
     1856        Atom *atom = toc.at(i);
     1857
     1858        int nextLevel = atom->string().toInt();
     1859        if (nextLevel > (int)sectioningUnit)
     1860            continue;
     1861
     1862        if (sectionNumber.size() < nextLevel) {
     1863            do {
     1864                out() << "<ul>";
     1865                sectionNumber.append("1");
     1866            } while (sectionNumber.size() < nextLevel);
     1867        }
     1868        else {
     1869            while (sectionNumber.size() > nextLevel) {
     1870                out() << "</ul>\n";
     1871                sectionNumber.removeLast();
     1872            }
     1873            sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1);
     1874        }
     1875        int numAtoms;
     1876        Text headingText = Text::sectionHeading(atom);
     1877
     1878        if (sectionNumber.size() == 1 && columnSize > toc.size() / numColumns) {
     1879            out() << "</ul></td>" << tdTag << "<ul>\n";
     1880            columnSize = 0;
     1881        }
     1882        out() << "<li>";
     1883        out() << "<a href=\""
     1884              << nodeName
     1885              << "#"
     1886              << Doc::canonicalTitle(headingText.toString())
     1887              << "\">";
     1888        generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms);
     1889        out() << "</a></li>\n";
     1890
     1891        ++columnSize;
     1892    }
     1893    while (!sectionNumber.isEmpty()) {
     1894        out() << "</ul>\n";
     1895        sectionNumber.removeLast();
     1896    }
     1897
     1898    if (numColumns > 1)
     1899        out() << "</td></tr></table></p>\n";
     1900
     1901    inContents = false;
     1902    inLink = false;
     1903}
     1904
     1905#if 0
     1906void HtmlGenerator::generateNavigationBar(const NavigationBar& bar,
     1907                                           const Node *node,
     1908                                           CodeMarker *marker)
     1909{
     1910    if (bar.prev.begin() != 0 || bar.current.begin() != 0 ||
     1911         bar.next.begin() != 0) {
     1912        out() << "<p align=\"right\">";
     1913        if (bar.prev.begin() != 0) {
     1914#if 0
     1915            out() << "[<a href=\"" << section.previousBaseName()
     1916                  << ".html\">Prev: ";
     1917            generateText(section.previousHeading(), node, marker);
     1918            out() << "</a>]\n";
     1919#endif
     1920        }
     1921        if (bar.current.begin() != 0) {
     1922            out() << "[<a href=\"" << "home"
     1923                  << ".html\">Home</a>]\n";
     1924        }
     1925        if (bar.next.begin() != 0) {
     1926            out() << "[<a href=\"" << fileBase(node, bar.next)
     1927                  << ".html\">Next: ";
     1928            generateText(Text::sectionHeading(bar.next.begin()), node, marker);
     1929            out() << "</a>]\n";
     1930        }
     1931        out() << "</p>\n";
     1932    }
     1933}
     1934#endif
     1935
     1936QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner,
     1937                                                   CodeMarker *marker)
     1938{
     1939    QList<Section> sections;
     1940    QList<Section>::ConstIterator s;
     1941
     1942    sections = marker->sections(inner,
     1943                                CodeMarker::SeparateList,
     1944                                CodeMarker::Okay);
     1945    if (sections.isEmpty())
     1946        return QString();
     1947
     1948    QString fileName = fileBase(inner) + "-members." + fileExtension(inner);
     1949    beginSubPage(inner->location(), fileName);
     1950    QString title = "List of All Members for " + inner->name();
     1951    generateHeader(title, inner, marker, false);
     1952    generateTitle(title, Text(), SmallSubTitle, inner, marker);
     1953    out() << "<p>This is the complete list of members for ";
     1954    generateFullName(inner, 0, marker);
     1955    out() << ", including inherited members.</p>\n";
     1956
     1957    Section section = sections.first();
     1958    generateSectionList(section, 0, marker, CodeMarker::SeparateList);
     1959
     1960    generateFooter();
     1961    endSubPage();
     1962    return fileName;
     1963}
     1964
     1965QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner,
     1966                                                   CodeMarker *marker,
     1967                                                   CodeMarker::Status status)
     1968{
     1969    QList<Section> sections = marker->sections(inner,
     1970                                               CodeMarker::Summary,
     1971                                               status);
     1972    QMutableListIterator<Section> j(sections);
     1973    while (j.hasNext()) {
     1974        if (j.next().members.size() == 0)
     1975            j.remove();
     1976    }
     1977    if (sections.isEmpty())
     1978        return QString();
     1979
     1980    int i;
     1981
     1982    QString title;
     1983    QString fileName;
     1984
     1985    if (status == CodeMarker::Compat) {
     1986        title = "Qt 3 Support Members for " + inner->name();
     1987        fileName = fileBase(inner) + "-qt3." + fileExtension(inner);
     1988    }
     1989    else {
     1990        title = "Obsolete Members for " + inner->name();
     1991        fileName = fileBase(inner) + "-obsolete." + fileExtension(inner);
     1992    }
     1993
     1994    beginSubPage(inner->location(), fileName);
     1995    generateHeader(title, inner, marker, false);
     1996    generateTitle(title, Text(), SmallSubTitle, inner, marker);
     1997
     1998    if (status == CodeMarker::Compat) {
     1999        out() << "<p><b>The following class members are part of the "
     2000                 "<a href=\"qt3support.html\">Qt 3 support layer</a>.</b> "
     2001                 "They are provided to help you port old code to Qt 4. We advise against "
     2002                 "using them in new code.</p>\n";
     2003    }
     2004    else {
     2005        out() << "<p><b>The following class members are obsolete.</b> "
     2006              << "They are provided to keep old source code working. "
     2007              << "We strongly advise against using them in new code.</p>\n";
     2008    }
     2009
     2010    out() << "<p><ul><li><a href=\""
     2011          << linkForNode(inner, 0) << "\">"
     2012          << protect(inner->name())
     2013          << " class reference</a></li></ul></p>\n";
     2014
     2015    for (i = 0; i < sections.size(); ++i) {
     2016        out() << "<h2>" << protect(sections.at(i).name) << "</h2>\n";
     2017        generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary);
     2018    }
     2019
     2020    sections = marker->sections(inner, CodeMarker::Detailed, status);
     2021    for (i = 0; i < sections.size(); ++i) {
     2022        out() << "<hr />\n";
     2023        out() << "<h2>" << protect(sections.at(i).name) << "</h2>\n";
     2024
     2025        NodeList::ConstIterator m = sections.at(i).members.begin();
     2026        while (m != sections.at(i).members.end()) {
     2027            if ((*m)->access() != Node::Private)
     2028                generateDetailedMember(*m, inner, marker);
     2029            ++m;
     2030        }
     2031    }
     2032
     2033    generateFooter();
     2034    endSubPage();
     2035    return fileName;
     2036}
     2037
     2038void HtmlGenerator::generateClassHierarchy(const Node *relative,
     2039                                           CodeMarker *marker,
     2040                                           const QMap<QString,const Node*> &classMap)
     2041{
     2042    if (classMap.isEmpty())
     2043        return;
     2044
     2045    NodeMap topLevel;
     2046    NodeMap::ConstIterator c = classMap.begin();
     2047    while (c != classMap.end()) {
     2048        const ClassNode *classe = static_cast<const ClassNode *>(*c);
     2049        if (classe->baseClasses().isEmpty())
     2050            topLevel.insert(classe->name(), classe);
     2051        ++c;
     2052    }
     2053
     2054    QStack<NodeMap > stack;
     2055    stack.push(topLevel);
     2056
     2057    out() << "<ul>\n";
     2058    while (!stack.isEmpty()) {
     2059        if (stack.top().isEmpty()) {
     2060            stack.pop();
     2061            out() << "</ul>\n";
     2062        }
     2063        else {
     2064            const ClassNode *child =
     2065                static_cast<const ClassNode *>(*stack.top().begin());
     2066            out() << "<li>";
     2067            generateFullName(child, relative, marker);
     2068            out() << "</li>\n";
     2069            stack.top().erase(stack.top().begin());
     2070
     2071            NodeMap newTop;
     2072            foreach (const RelatedClass &d, child->derivedClasses()) {
     2073                if (d.access != Node::Private)
     2074                    newTop.insert(d.node->name(), d.node);
     2075            }
     2076            if (!newTop.isEmpty()) {
     2077                stack.push(newTop);
     2078                out() << "<ul>\n";
     2079            }
     2080        }
     2081    }
     2082}
     2083
     2084void HtmlGenerator::generateAnnotatedList(const Node *relative,
     2085                                          CodeMarker *marker,
     2086                                          const NodeMap &nodeMap)
     2087{
     2088    out() << "<p><table width=\"100%\" class=\"annotated\" cellpadding=\"2\" "
     2089          << "cellspacing=\"1\" border=\"0\">\n";
     2090
     2091    int row = 0;
     2092    foreach (const QString &name, nodeMap.keys()) {
     2093        const Node *node = nodeMap[name];
     2094
     2095        if (node->status() == Node::Obsolete)
     2096            continue;
     2097
     2098        if (++row % 2 == 1)
     2099            out() << "<tr valign=\"top\" class=\"odd\">";
     2100        else
     2101            out() << "<tr valign=\"top\" class=\"even\">";
     2102        out() << "<th>";
     2103        generateFullName(node, relative, marker);
     2104        out() << "</th>";
     2105
     2106        if (!(node->type() == Node::Fake)) {
     2107            Text brief = node->doc().trimmedBriefText(name);
     2108            if (!brief.isEmpty()) {
     2109                out() << "<td>";
     2110                generateText(brief, node, marker);
     2111                out() << "</td>";
     2112            }
     2113        }
     2114        else {
     2115            out() << "<td>";
     2116            out() << protect(node->doc().briefText().toString());
     2117            out() << "</td>";
     2118        }
     2119        out() << "</tr>\n";
     2120    }
     2121    out() << "</table></p>\n";
     2122}
     2123
     2124/*!
     2125  This function finds the common prefix of the names of all
     2126  the classes in \a classMap and then generates a compact
     2127  list of the class names alphabetized on the part of the
     2128  name not including the common prefix. You can tell the
     2129  function to use \a comonPrefix as the common prefix, but
     2130  normally you let it figure it out itself by looking at
     2131  the name of the first and last classes in \a classMap.
     2132 */
     2133void HtmlGenerator::generateCompactList(const Node *relative,
     2134                                        CodeMarker *marker,
     2135                                        const NodeMap &classMap,
     2136                                        QString commonPrefix)
     2137{
     2138    const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_'
     2139    const int NumColumns = 4; // number of columns in the result
     2140
     2141    if (classMap.isEmpty())
     2142        return;
     2143
     2144    /*
     2145      If commonPrefix is not empty, then the caller knows what
     2146      the common prefix is and has passed it in, so just use that
     2147      one.
     2148     */
     2149    int commonPrefixLen = commonPrefix.length();
     2150    if (commonPrefixLen == 0) {
     2151        QString first;
     2152        QString last;
     2153       
     2154        /*
     2155          The caller didn't pass in a common prefix, so get the common
     2156          prefix by looking at the class names of the first and last
     2157          classes in the class map. Discard any namespace names and
     2158          just use the bare class names. For Qt, the prefix is "Q".
     2159
     2160          Note that the algorithm used here to derive the common prefix
     2161          from the first and last classes in alphabetical order (QAccel
     2162          and QXtWidget in Qt 2.1), fails if either class name does not
     2163          begin with Q.
     2164        */
     2165
     2166        NodeMap::const_iterator iter = classMap.begin();
     2167        while (iter != classMap.end()) {
     2168            if (!iter.key().contains("::")) {
     2169                first = iter.key();
     2170                break;
     2171            }
     2172            ++iter;
     2173        }
     2174
     2175        if (first.isEmpty())
     2176            first = classMap.begin().key();
     2177
     2178        iter = classMap.end();
     2179        while (iter != classMap.begin()) {
     2180            --iter;
     2181            if (!iter.key().contains("::")) {
     2182                last = iter.key();
     2183                break;
     2184            }
     2185        }
     2186
     2187        if (last.isEmpty())
     2188            last = classMap.begin().key();
     2189
     2190        if (classMap.size() > 1) {
     2191            while (commonPrefixLen < first.length() + 1 &&
     2192                   commonPrefixLen < last.length() + 1 &&
     2193                   first[commonPrefixLen] == last[commonPrefixLen])
     2194                ++commonPrefixLen;
     2195        }
     2196
     2197        commonPrefix = first.left(commonPrefixLen);
     2198    }
     2199
     2200    /*
     2201      Divide the data into 37 paragraphs: 0, ..., 9, A, ..., Z,
     2202      underscore (_). QAccel will fall in paragraph 10 (A) and
     2203      QXtWidget in paragraph 33 (X). This is the only place where we
     2204      assume that NumParagraphs is 37. Each paragraph is a NodeMap.
     2205    */
     2206    NodeMap paragraph[NumParagraphs+1];
     2207    QString paragraphName[NumParagraphs+1];
     2208
     2209    NodeMap::ConstIterator c = classMap.begin();
     2210    while (c != classMap.end()) {
     2211        QStringList pieces = c.key().split("::");
     2212        QString key;
     2213        int idx = commonPrefixLen;
     2214        if (!pieces.last().startsWith(commonPrefix))
     2215            idx = 0;
     2216        if (pieces.size() == 1)
     2217            key = pieces.last().mid(idx).toLower();
     2218        else
     2219            key = pieces.last().toLower();
     2220
     2221        int paragraphNo = NumParagraphs - 1;
     2222
     2223        if (key[0].digitValue() != -1) {
     2224            paragraphNo = key[0].digitValue();
     2225        }
     2226        else if (key[0] >= QLatin1Char('a') && key[0] <= QLatin1Char('z')) {
     2227            paragraphNo = 10 + key[0].unicode() - 'a';
     2228        }
     2229
     2230        paragraphName[paragraphNo] = key[0].toUpper();
     2231        paragraph[paragraphNo].insert(key, c.value());
     2232        ++c;
     2233    }
     2234
     2235    /*
     2236      Each paragraph j has a size: paragraph[j].count(). In the
     2237      discussion, we will assume paragraphs 0 to 5 will have sizes
     2238      3, 1, 4, 1, 5, 9.
     2239
     2240      We now want to compute the paragraph offset. Paragraphs 0 to 6
     2241      start at offsets 0, 3, 4, 8, 9, 14, 23.
     2242    */
     2243    int paragraphOffset[NumParagraphs + 1];     // 37 + 1
     2244    int i, j, k;
     2245
     2246    paragraphOffset[0] = 0;
     2247    for (j = 0; j < NumParagraphs; j++)         // j = 0..36
     2248        paragraphOffset[j + 1] = paragraphOffset[j] + paragraph[j].count();
     2249
     2250    int firstOffset[NumColumns + 1];            // 4 + 1
     2251    int currentOffset[NumColumns];              // 4
     2252    int currentParagraphNo[NumColumns];         // 4
     2253    int currentOffsetInParagraph[NumColumns];   // 4
     2254
     2255    int numRows = (classMap.count() + NumColumns - 1) / NumColumns;
     2256    int curParagNo = 0;
     2257
     2258    for (i = 0; i < NumColumns; i++) {          // i = 0..3
     2259        firstOffset[i] = qMin(i * numRows, classMap.size());
     2260        currentOffset[i] = firstOffset[i];
     2261
     2262        for (j = curParagNo; j < NumParagraphs; j++) {
     2263            if (paragraphOffset[j] > firstOffset[i])
     2264                break;
     2265            if (paragraphOffset[j] <= firstOffset[i])
     2266                curParagNo = j;
     2267        }
     2268        currentParagraphNo[i] = curParagNo;
     2269        currentOffsetInParagraph[i] = firstOffset[i] -
     2270                                      paragraphOffset[curParagNo];
     2271    }
     2272    firstOffset[NumColumns] = classMap.count();
     2273
     2274    out() << "<p><table class=\"generic\" width=\"100%\">\n";
     2275    for (k = 0; k < numRows; k++) {
     2276        out() << "<tr>\n";
     2277        for (i = 0; i < NumColumns; i++) {
     2278            if (currentOffset[i] >= firstOffset[i + 1]) {
     2279                // this column is finished
     2280                out() << "<td>\n</td>\n";
     2281            }
     2282            else {
     2283                while ((currentParagraphNo[i] < NumParagraphs) &&
     2284                       (currentOffsetInParagraph[i] == paragraph[currentParagraphNo[i]].count())) {
     2285                    ++currentParagraphNo[i];
     2286                    currentOffsetInParagraph[i] = 0;
     2287                }
     2288#if 0
     2289                if (currentParagraphNo[i] >= NumParagraphs) {
     2290                    qDebug() << "### Internal error ###" << __FILE__ << __LINE__
     2291                             << currentParagraphNo[i] << NumParagraphs;
     2292                    currentParagraphNo[i] = NumParagraphs - 1;
     2293                }
     2294#endif
     2295                out() << "<td align=\"right\">";
     2296                if (currentOffsetInParagraph[i] == 0) {
     2297                    // start a new paragraph
     2298                    out() << "<b>"
     2299                          << paragraphName[currentParagraphNo[i]]
     2300                          << "&nbsp;</b>";
     2301                }
     2302                out() << "</td>\n";
     2303
     2304                out() << "<td>";
     2305                if ((currentParagraphNo[i] < NumParagraphs) &&
     2306                    !paragraphName[currentParagraphNo[i]].isEmpty()) {
     2307                    NodeMap::Iterator it;
     2308                    it = paragraph[currentParagraphNo[i]].begin();
     2309                    for (j = 0; j < currentOffsetInParagraph[i]; j++)
     2310                        ++it;
     2311
     2312                    // Previously, we used generateFullName() for this, but we
     2313                    // require some special formatting.
     2314                    out() << "<a href=\""
     2315                        << linkForNode(it.value(), relative)
     2316                        << "\">";
     2317                    QStringList pieces = fullName(it.value(), relative, marker).split("::");
     2318                    out() << protect(pieces.last());
     2319                    out() << "</a>";
     2320                    if (pieces.size() > 1) {
     2321                        out() << " (";
     2322                        generateFullName(it.value()->parent(), relative, marker);
     2323                        out() << ")";
     2324                    }
     2325                }
     2326                out() << "</td>\n";
     2327
     2328                currentOffset[i]++;
     2329                currentOffsetInParagraph[i]++;
     2330            }
     2331        }
     2332        out() << "</tr>\n";
     2333    }
     2334    out() << "</table></p>\n";
     2335}
     2336
     2337void HtmlGenerator::generateFunctionIndex(const Node *relative,
     2338                                          CodeMarker *marker)
     2339{
     2340    out() << "<p align=\"center\"><font size=\"+1\"><b>";
     2341    for (int i = 0; i < 26; i++) {
     2342        QChar ch('a' + i);
     2343        out() << QString("<a href=\"#%1\">%2</a>&nbsp;").arg(ch).arg(ch.toUpper());
     2344    }
     2345    out() << "</b></font></p>\n";
     2346
     2347    char nextLetter = 'a';
     2348    char currentLetter;
     2349
     2350#if 1
     2351    out() << "<ul>\n";
     2352#endif
     2353    QMap<QString, NodeMap >::ConstIterator f = funcIndex.begin();
     2354    while (f != funcIndex.end()) {
     2355#if 1
     2356        out() << "<li>";
     2357#else
     2358        out() << "<p>";
     2359#endif
     2360        out() << protect(f.key()) << ":";
     2361
     2362        currentLetter = f.key()[0].unicode();
     2363        while (islower(currentLetter) && currentLetter >= nextLetter) {
     2364            out() << QString("<a name=\"%1\"></a>").arg(nextLetter);
     2365            nextLetter++;
     2366        }
     2367
     2368        NodeMap::ConstIterator s = (*f).begin();
     2369        while (s != (*f).end()) {
     2370            out() << " ";
     2371            generateFullName((*s)->parent(), relative, marker, *s);
     2372            ++s;
     2373        }
     2374#if 1
     2375        out() << "</li>";
     2376#else
     2377        out() << "</p>";
     2378#endif
     2379        out() << "\n";
     2380        ++f;
     2381    }
     2382#if 1
     2383    out() << "</ul>\n";
     2384#endif
     2385}
     2386
     2387void HtmlGenerator::generateLegaleseList(const Node *relative,
     2388                                         CodeMarker *marker)
     2389{
     2390    QMap<Text, const Node *>::ConstIterator it = legaleseTexts.begin();
     2391    while (it != legaleseTexts.end()) {
     2392        Text text = it.key();
     2393        out() << "<hr />\n";
     2394        generateText(text, relative, marker);
     2395        out() << "<ul>\n";
     2396        do {
     2397            out() << "<li>";
     2398            generateFullName(it.value(), relative, marker);
     2399            out() << "</li>\n";
     2400            ++it;
     2401        } while (it != legaleseTexts.end() && it.key() == text);
     2402        out() << "</ul>\n";
     2403    }
     2404}
     2405
     2406/*void HtmlGenerator::generateSynopsis(const Node *node,
     2407                                     const Node *relative,
     2408                                     CodeMarker *marker,
     2409                                     CodeMarker::SynopsisStyle style)
     2410{
     2411    QString marked = marker->markedUpSynopsis(node, relative, style);
     2412    QRegExp templateTag("(<[^@>]*>)");
     2413    if (marked.indexOf(templateTag) != -1) {
     2414        QString contents = protect(marked.mid(templateTag.pos(1),
     2415                                              templateTag.cap(1).length()));
     2416        marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
     2417                        contents);
     2418    }
     2419    marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
     2420                   "<i>\\1<sub>\\2</sub></i>");
     2421    marked.replace("<@param>", "<i>");
     2422    marked.replace("</@param>", "</i>");
     2423
     2424    if (style == CodeMarker::Summary)
     2425        marked.replace("@name>", "b>");
     2426
     2427    if (style == CodeMarker::SeparateList) {
     2428        QRegExp extraRegExp("<@extra>.*</@extra>");
     2429        extraRegExp.setMinimal(true);
     2430        marked.replace(extraRegExp, "");
     2431    }
     2432    else {
     2433        marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
     2434        marked.replace("</@extra>", "</tt>");
     2435    }
     2436
     2437    if (style != CodeMarker::Detailed) {
     2438        marked.replace("<@type>", "");
     2439        marked.replace("</@type>", "");
     2440    }
     2441    out() << highlightedCode(marked, marker, relative);
     2442}*/
     2443
     2444#ifdef QDOC_QML
     2445void HtmlGenerator::generateQmlItem(const Node *node,
     2446                                    const Node *relative,
     2447                                    CodeMarker *marker,
     2448                                    bool summary)
     2449{
     2450    QString marked = marker->markedUpQmlItem(node,summary);
     2451    QRegExp templateTag("(<[^@>]*>)");
     2452    if (marked.indexOf(templateTag) != -1) {
     2453        QString contents = protect(marked.mid(templateTag.pos(1),
     2454                                              templateTag.cap(1).length()));
     2455        marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
     2456                        contents);
     2457    }
     2458    marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
     2459                   "<i>\\1<sub>\\2</sub></i>");
     2460    marked.replace("<@param>", "<i>");
     2461    marked.replace("</@param>", "</i>");
     2462
     2463    if (summary)
     2464        marked.replace("@name>", "b>");
     2465
     2466    marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
     2467    marked.replace("</@extra>", "</tt>");
     2468
     2469    if (summary) {
     2470        marked.replace("<@type>", "");
     2471        marked.replace("</@type>", "");
     2472    }
     2473    out() << highlightedCode(marked, marker, relative);
     2474}
     2475#endif
     2476
     2477void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* marker */)
     2478{
     2479    QMap<const FakeNode *, QMap<QString, FakeNode *> > fakeNodeMap;
     2480    QMap<QString, const FakeNode *> groupTitlesMap;
     2481    QMap<QString, FakeNode *> uncategorizedNodeMap;
     2482    QRegExp singleDigit("\\b([0-9])\\b");
     2483
     2484    const NodeList children = myTree->root()->childNodes();
     2485    foreach (Node *child, children) {
     2486        if (child->type() == Node::Fake && child != relative) {
     2487            FakeNode *fakeNode = static_cast<FakeNode *>(child);
     2488
     2489            // Check whether the page is part of a group or is the group
     2490            // definition page.
     2491            QString group;
     2492            bool isGroupPage = false;
     2493            if (fakeNode->doc().metaCommandsUsed().contains("group")) {
     2494                group = fakeNode->doc().metaCommandArgs("group")[0];
     2495                isGroupPage = true;
     2496            }
     2497
     2498            // there are too many examples; they would clutter the list
     2499            if (fakeNode->subType() == Node::Example)
     2500                continue;
     2501
     2502            // not interested either in individual (Qt Designer etc.) manual chapters
     2503            if (fakeNode->links().contains(Node::ContentsLink))
     2504                continue;
     2505
     2506            // Discard external nodes.
     2507            if (fakeNode->subType() == Node::ExternalPage)
     2508                continue;
     2509
     2510            QString sortKey = fakeNode->fullTitle().toLower();
     2511            if (sortKey.startsWith("the "))
     2512                sortKey.remove(0, 4);
     2513            sortKey.replace(singleDigit, "0\\1");
     2514
     2515            if (!group.isEmpty()) {
     2516                if (isGroupPage) {
     2517                    // If we encounter a group definition page, we add all
     2518                    // the pages in that group to the list for that group.
     2519                    foreach (Node *member, fakeNode->groupMembers()) {
     2520                        if (member->type() != Node::Fake)
     2521                            continue;
     2522                        FakeNode *page = static_cast<FakeNode *>(member);
     2523                        if (page) {
     2524                            QString sortKey = page->fullTitle().toLower();
     2525                            if (sortKey.startsWith("the "))
     2526                                sortKey.remove(0, 4);
     2527                            sortKey.replace(singleDigit, "0\\1");
     2528                            fakeNodeMap[const_cast<const FakeNode *>(fakeNode)].insert(sortKey, page);
     2529                            groupTitlesMap[fakeNode->fullTitle()] = const_cast<const FakeNode *>(fakeNode);
     2530                        }
     2531                    }
     2532                }
     2533                else if (!isGroupPage) {
     2534                    // If we encounter a page that belongs to a group then
     2535                    // we add that page to the list for that group.
     2536                    const FakeNode *groupNode = static_cast<const FakeNode *>(myTree->root()->findNode(group, Node::Fake));
     2537                    if (groupNode)
     2538                        fakeNodeMap[groupNode].insert(sortKey, fakeNode);
     2539                    //else
     2540                    //    uncategorizedNodeMap.insert(sortKey, fakeNode);
     2541                }// else
     2542                //    uncategorizedNodeMap.insert(sortKey, fakeNode);
     2543            }// else
     2544            //    uncategorizedNodeMap.insert(sortKey, fakeNode);
     2545        }
     2546    }
     2547
     2548    // We now list all the pages found that belong to groups.
     2549    // If only certain pages were found for a group, but the definition page
     2550    // for that group wasn't listed, the list of pages will be intentionally
     2551    // incomplete. However, if the group definition page was listed, all the
     2552    // pages in that group are listed for completeness.
     2553
     2554    if (!fakeNodeMap.isEmpty()) {
     2555        foreach (const QString &groupTitle, groupTitlesMap.keys()) {
     2556            const FakeNode *groupNode = groupTitlesMap[groupTitle];
     2557            out() << QString("<h3><a href=\"%1\">%2</a></h3>\n").arg(
     2558                        linkForNode(groupNode, relative)).arg(
     2559                        protect(groupNode->fullTitle()));
     2560
     2561            if (fakeNodeMap[groupNode].count() == 0)
     2562                continue;
     2563
     2564            out() << "<ul>\n";
     2565
     2566            foreach (const FakeNode *fakeNode, fakeNodeMap[groupNode]) {
     2567                QString title = fakeNode->fullTitle();
     2568                if (title.startsWith("The "))
     2569                    title.remove(0, 4);
     2570                out() << "<li><a href=\"" << linkForNode(fakeNode, relative) << "\">"
     2571                      << protect(title) << "</a></li>\n";
     2572            }
     2573            out() << "</ul>\n";
     2574        }
     2575    }
     2576
     2577    if (!uncategorizedNodeMap.isEmpty()) {
     2578        out() << QString("<h3>Miscellaneous</h3>\n");
     2579        out() << "<ul>\n";
     2580        foreach (const FakeNode *fakeNode, uncategorizedNodeMap) {
     2581            QString title = fakeNode->fullTitle();
     2582            if (title.startsWith("The "))
     2583                title.remove(0, 4);
     2584            out() << "<li><a href=\"" << linkForNode(fakeNode, relative) << "\">"
     2585                  << protect(title) << "</a></li>\n";
     2586        }
     2587        out() << "</ul>\n";
     2588    }
     2589}
     2590
     2591#ifdef QDOC_NAME_ALIGNMENT
     2592void HtmlGenerator::generateSection(const NodeList& nl,
     2593                                    const Node *relative,
     2594                                    CodeMarker *marker,
     2595                                    CodeMarker::SynopsisStyle style)
     2596{
     2597    bool name_alignment = true;
     2598    if (!nl.isEmpty()) {
     2599        bool twoColumn = false;
     2600        if (style == CodeMarker::SeparateList) {
     2601            name_alignment = false;
     2602            twoColumn = (nl.count() >= 16);
     2603        }
     2604        else if (nl.first()->type() == Node::Property) {
     2605            twoColumn = (nl.count() >= 5);
     2606            name_alignment = false;
     2607        }
     2608        if (name_alignment) {
     2609            out() << "<table class=\"alignedsummary\" border=\"0\" cellpadding=\"0\" "
     2610                  << "cellspacing=\"0\" width=\"100%\">\n";
     2611        }
     2612        else {
     2613            if (twoColumn)
     2614                out() << "<p><table class=\"propsummary\" width=\"100%\" "
     2615                      << "border=\"0\" cellpadding=\"0\""
     2616                      << " cellspacing=\"0\">\n"
     2617                      << "<tr><td width=\"45%\" valign=\"top\">";
     2618            out() << "<ul>\n";
     2619        }
     2620
     2621        int i = 0;
     2622        NodeList::ConstIterator m = nl.begin();
     2623        while (m != nl.end()) {
     2624            if ((*m)->access() == Node::Private) {
     2625                ++m;
     2626                continue;
     2627            }
     2628
     2629            if (name_alignment) {
     2630                out() << "<tr><td class=\"memItemLeft\" "
     2631                      << "align=\"right\" valign=\"top\">";
     2632            }
     2633            else {
     2634                if (twoColumn && i == (int) (nl.count() + 1) / 2)
     2635                    out() << "</ul></td><td valign=\"top\"><ul>\n";
     2636                out() << "<li><div class=\"fn\">";
     2637            }
     2638
     2639            generateSynopsis(*m, relative, marker, style, name_alignment);
     2640            if (name_alignment)
     2641                out() << "</td></tr>\n";
     2642            else
     2643                out() << "</div></li>\n";
     2644            i++;
     2645            ++m;
     2646        }
     2647        if (name_alignment)
     2648            out() << "</table>\n";
     2649        else {
     2650            out() << "</ul>\n";
     2651            if (twoColumn)
     2652                out() << "</td></tr>\n</table></p>\n";
     2653        }
     2654    }
     2655}
     2656
     2657void HtmlGenerator::generateSectionList(const Section& section,
     2658                                        const Node *relative,
     2659                                        CodeMarker *marker,
     2660                                        CodeMarker::SynopsisStyle style)
     2661{
     2662    bool name_alignment = true;
     2663    if (!section.members.isEmpty()) {
     2664        bool twoColumn = false;
     2665        if (style == CodeMarker::SeparateList) {
     2666            name_alignment = false;
     2667            twoColumn = (section.members.count() >= 16);
     2668        }
     2669        else if (section.members.first()->type() == Node::Property) {
     2670            twoColumn = (section.members.count() >= 5);
     2671            name_alignment = false;
     2672        }
     2673        if (name_alignment) {
     2674            out() << "<table class=\"alignedsummary\" border=\"0\" cellpadding=\"0\" "
     2675                  << "cellspacing=\"0\" width=\"100%\">\n";
     2676        }
     2677        else {
     2678            if (twoColumn)
     2679                out() << "<p><table class=\"propsummary\" width=\"100%\" "
     2680                      << "border=\"0\" cellpadding=\"0\""
     2681                      << " cellspacing=\"0\">\n"
     2682                      << "<tr><td width=\"45%\" valign=\"top\">";
     2683            out() << "<ul>\n";
     2684        }
     2685
     2686        int i = 0;
     2687        NodeList::ConstIterator m = section.members.begin();
     2688        while (m != section.members.end()) {
     2689            if ((*m)->access() == Node::Private) {
     2690                ++m;
     2691                continue;
     2692            }
     2693
     2694            if (name_alignment) {
     2695                out() << "<tr><td class=\"memItemLeft\" "
     2696                      << "align=\"right\" valign=\"top\">";
     2697            }
     2698            else {
     2699                if (twoColumn && i == (int) (section.members.count() + 1) / 2)
     2700                    out() << "</ul></td><td valign=\"top\"><ul>\n";
     2701                out() << "<li><div class=\"fn\">";
     2702            }
     2703
     2704            generateSynopsis(*m, relative, marker, style, name_alignment);
     2705            if (name_alignment)
     2706                out() << "</td></tr>\n";
     2707            else
     2708                out() << "</div></li>\n";
     2709            i++;
     2710            ++m;
     2711        }
     2712        if (name_alignment)
     2713            out() << "</table>\n";
     2714        else {
     2715            out() << "</ul>\n";
     2716            if (twoColumn)
     2717                out() << "</td></tr>\n</table></p>\n";
     2718        }
     2719    }
     2720
     2721    if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
     2722        out() << "<ul>\n";
     2723        generateSectionInheritedList(section, relative, marker, name_alignment);
     2724        out() << "</ul>\n";
     2725    }
     2726}
     2727
     2728void HtmlGenerator::generateSectionInheritedList(const Section& section,
     2729                                                 const Node *relative,
     2730                                                 CodeMarker *marker,
     2731                                                 bool nameAlignment)
     2732{
     2733    QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
     2734    while (p != section.inherited.end()) {
     2735        if (nameAlignment)
     2736            out() << "<li><div bar=\"2\" class=\"fn\"></div>";
     2737        else
     2738            out() << "<li><div class=\"fn\"></div>";
     2739        out() << (*p).second << " ";
     2740        if ((*p).second == 1) {
     2741            out() << section.singularMember;
     2742        }
     2743        else {
     2744            out() << section.pluralMember;
     2745        }
     2746        out() << " inherited from <a href=\"" << fileName((*p).first)
     2747              << "#" << HtmlGenerator::cleanRef(section.name.toLower()) << "\">"
     2748              << protect(marker->plainFullName((*p).first, relative))
     2749              << "</a></li>\n";
     2750        ++p;
     2751    }
     2752}
     2753
     2754void HtmlGenerator::generateSynopsis(const Node *node,
     2755                                     const Node *relative,
     2756                                     CodeMarker *marker,
     2757                                     CodeMarker::SynopsisStyle style,
     2758                                     bool nameAlignment)
     2759{
     2760    QString marked = marker->markedUpSynopsis(node, relative, style);
     2761    QRegExp templateTag("(<[^@>]*>)");
     2762    if (marked.indexOf(templateTag) != -1) {
     2763        QString contents = protect(marked.mid(templateTag.pos(1),
     2764                                              templateTag.cap(1).length()));
     2765        marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
     2766                        contents);
     2767    }
     2768    marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
     2769                   "<i>\\1<sub>\\2</sub></i>");
     2770    marked.replace("<@param>", "<i>");
     2771    marked.replace("</@param>", "</i>");
     2772
     2773    if (style == CodeMarker::Summary) {
     2774        marked.replace("<@name>", "");   // was "<b>"
     2775        marked.replace("</@name>", "");  // was "</b>"
     2776    }
     2777
     2778    if (style == CodeMarker::SeparateList) {
     2779        QRegExp extraRegExp("<@extra>.*</@extra>");
     2780        extraRegExp.setMinimal(true);
     2781        marked.replace(extraRegExp, "");
     2782    } else {
     2783        marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
     2784        marked.replace("</@extra>", "</tt>");
     2785    }
     2786
     2787    if (style != CodeMarker::Detailed) {
     2788        marked.replace("<@type>", "");
     2789        marked.replace("</@type>", "");
     2790    }
     2791    out() << highlightedCode(marked, marker, relative, style, nameAlignment);
     2792}
     2793
    24132794QString HtmlGenerator::highlightedCode(const QString& markedCode,
    24142795                                       CodeMarker *marker,
    2415                                        const Node *relative)
     2796                                       const Node *relative,
     2797                                       CodeMarker::SynopsisStyle ,
     2798                                       bool nameAlignment)
    24162799{
    24172800    QString src = markedCode;
     
    24252808    // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)"
    24262809    static const QString linkTag("link");
     2810    bool done = false;
    24272811    for (int i = 0, n = src.size(); i < n;) {
    2428         if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
     2812        if (src.at(i) == charLangle && src.at(i + 1).unicode() == '@') {
     2813            if (nameAlignment && !done) {// && (i != 0)) Why was this here?
     2814                html += "</td><td class=\"memItemRight\" valign=\"bottom\">";
     2815                done = true;
     2816            }
    24292817            i += 2;
    24302818            if (parseArg(src, linkTag, &i, n, &arg, &par1)) {
     2819                html += "<b>";
    24312820                QString link = linkForNode(
    24322821                    CodeMarker::nodeForString(par1.toString()), relative);
    24332822                addLink(link, arg, &html);
     2823                html += "</b>";
    24342824            }
    24352825            else {
     
    24562846                    QString link = linkForNode(
    24572847                            marker->resolveTarget(par1.toString(),
    2458                                                   tre,
     2848                                                  myTree,
    24592849                                                  relative),
    24602850                            relative);
     
    24852875                    par1 = QStringRef();
    24862876                    QString link = linkForNode(
    2487                             marker->resolveTarget(arg.toString(), tre, relative),
     2877                            marker->resolveTarget(arg.toString(), myTree, relative),
    24882878                            relative);
    24892879                    addLink(link, arg, &html);
     
    25722962}
    25732963
     2964#else
     2965void HtmlGenerator::generateSectionList(const Section& section,
     2966                                        const Node *relative,
     2967                                        CodeMarker *marker,
     2968                                        CodeMarker::SynopsisStyle style)
     2969{
     2970    if (!section.members.isEmpty()) {
     2971        bool twoColumn = false;
     2972        if (style == CodeMarker::SeparateList) {
     2973            twoColumn = (section.members.count() >= 16);
     2974        }
     2975        else if (section.members.first()->type() == Node::Property) {
     2976            twoColumn = (section.members.count() >= 5);
     2977        }
     2978        if (twoColumn)
     2979            out() << "<p><table class=\"generic\" width=\"100%\" border=\"0\" "
     2980                  << "cellpadding=\"0\" cellspacing=\"0\">\n"
     2981                  << "<tr><td width=\"45%\" valign=\"top\">";
     2982        out() << "<ul>\n";
     2983
     2984        int i = 0;
     2985        NodeList::ConstIterator m = section.members.begin();
     2986        while (m != section.members.end()) {
     2987            if ((*m)->access() == Node::Private) {
     2988                ++m;
     2989                continue;
     2990            }
     2991
     2992            if (twoColumn && i == (int) (section.members.count() + 1) / 2)
     2993                out() << "</ul></td><td valign=\"top\"><ul>\n";
     2994
     2995            out() << "<li><div class=\"fn\"></div>";
     2996            if (style == CodeMarker::Accessors)
     2997                out() << "<b>";
     2998            generateSynopsis(*m, relative, marker, style);
     2999            if (style == CodeMarker::Accessors)
     3000                out() << "</b>";
     3001            out() << "</li>\n";
     3002            i++;
     3003            ++m;
     3004        }
     3005        out() << "</ul>\n";
     3006        if (twoColumn)
     3007            out() << "</td></tr>\n</table></p>\n";
     3008    }
     3009
     3010    if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
     3011        out() << "<ul>\n";
     3012        generateSectionInheritedList(section, relative, marker);
     3013        out() << "</ul>\n";
     3014    }
     3015}
     3016
     3017void HtmlGenerator::generateSectionInheritedList(const Section& section,
     3018                                                 const Node *relative,
     3019                                                 CodeMarker *marker)
     3020{
     3021    QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
     3022    while (p != section.inherited.end()) {
     3023        out() << "<li><div bar=\"2\" class=\"fn\"></div>";
     3024        out() << (*p).second << " ";
     3025        if ((*p).second == 1) {
     3026            out() << section.singularMember;
     3027        } else {
     3028            out() << section.pluralMember;
     3029        }
     3030        out() << " inherited from <a href=\"" << fileName((*p).first)
     3031              << "#" << HtmlGenerator::cleanRef(section.name.toLower()) << "\">"
     3032              << protect(marker->plainFullName((*p).first, relative))
     3033              << "</a></li>\n";
     3034        ++p;
     3035    }
     3036}
     3037
     3038void HtmlGenerator::generateSynopsis(const Node *node,
     3039                                     const Node *relative,
     3040                                     CodeMarker *marker,
     3041                                     CodeMarker::SynopsisStyle style)
     3042{
     3043    QString marked = marker->markedUpSynopsis(node, relative, style);
     3044    QRegExp templateTag("(<[^@>]*>)");
     3045    if (marked.indexOf(templateTag) != -1) {
     3046        QString contents = protect(marked.mid(templateTag.pos(1),
     3047                                              templateTag.cap(1).length()));
     3048        marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
     3049                        contents);
     3050    }
     3051    marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"), "<i>\\1<sub>\\2</sub></i>");
     3052    marked.replace("<@param>", "<i>");
     3053    marked.replace("</@param>", "</i>");
     3054
     3055    if (style == CodeMarker::Summary)
     3056        marked.replace("@name>", "b>");
     3057
     3058    if (style == CodeMarker::SeparateList) {
     3059        QRegExp extraRegExp("<@extra>.*</@extra>");
     3060        extraRegExp.setMinimal(true);
     3061        marked.replace(extraRegExp, "");
     3062    } else {
     3063        marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
     3064        marked.replace("</@extra>", "</tt>");
     3065    }
     3066
     3067    if (style != CodeMarker::Detailed) {
     3068        marked.replace("<@type>", "");
     3069        marked.replace("</@type>", "");
     3070    }
     3071    out() << highlightedCode(marked, marker, relative);
     3072}
     3073
     3074QString HtmlGenerator::highlightedCode(const QString& markedCode,
     3075                                       CodeMarker *marker,
     3076                                       const Node *relative)
     3077{
     3078    QString src = markedCode;
     3079    QString html;
     3080    QStringRef arg;
     3081    QStringRef par1;
     3082
     3083    const QChar charLangle = '<';
     3084    const QChar charAt = '@';
     3085
     3086    // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)"
     3087    static const QString linkTag("link");
     3088    for (int i = 0, n = src.size(); i < n;) {
     3089        if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
     3090            i += 2;
     3091            if (parseArg(src, linkTag, &i, n, &arg, &par1)) {
     3092                const Node* node = CodeMarker::nodeForString(par1.toString());
     3093                QString link = linkForNode(node, relative);
     3094                addLink(link, arg, &html);
     3095            }
     3096            else {
     3097                html += charLangle;
     3098                html += charAt;
     3099            }
     3100        }
     3101        else {
     3102            html += src.at(i++);
     3103        }
     3104    }
     3105
     3106    if (slow) {
     3107        // is this block ever used at all?
     3108        // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)"
     3109        src = html;
     3110        html = QString();
     3111        static const QString funcTag("func");
     3112        for (int i = 0, n = src.size(); i < n;) {
     3113            if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
     3114                i += 2;
     3115                if (parseArg(src, funcTag, &i, n, &arg, &par1)) {
     3116                    QString link = linkForNode(
     3117                            marker->resolveTarget(par1.toString(),
     3118                                                  myTree,
     3119                                                  relative),
     3120                            relative);
     3121                    addLink(link, arg, &html);
     3122                    par1 = QStringRef();
     3123                }
     3124                else {
     3125                    html += charLangle;
     3126                    html += charAt;
     3127                }
     3128            }
     3129            else {
     3130                html += src.at(i++);
     3131            }
     3132        }
     3133    }
     3134
     3135    // replace all "(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(</@\\2>)" tags
     3136    src = html;
     3137    html = QString();
     3138    static const QString typeTags[] = { "type", "headerfile", "func" };
     3139    for (int i = 0, n = src.size(); i < n;) {
     3140        if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
     3141            i += 2;
     3142            bool handled = false;
     3143            for (int k = 0; k != 3; ++k) {
     3144                if (parseArg(src, typeTags[k], &i, n, &arg, &par1)) {
     3145                    par1 = QStringRef();
     3146                    QString link = linkForNode(
     3147                            marker->resolveTarget(arg.toString(), myTree, relative),
     3148                            relative);
     3149                    addLink(link, arg, &html);
     3150                    handled = true;
     3151                    break;
     3152                }
     3153            }
     3154            if (!handled) {
     3155                html += charLangle;
     3156                html += charAt;
     3157            }
     3158        }
     3159        else {
     3160            html += src.at(i++);
     3161        }
     3162    }
     3163
     3164    // replace all
     3165    // "<@comment>" -> "<span class=\"comment\">";
     3166    // "<@preprocessor>" -> "<span class=\"preprocessor\">";
     3167    // "<@string>" -> "<span class=\"string\">";
     3168    // "<@char>" -> "<span class=\"char\">";
     3169    // "</@(?:comment|preprocessor|string|char)>" -> "</span>"
     3170    src = html;
     3171    html = QString();
     3172    static const QString spanTags[] = {
     3173        "<@comment>",      "<span class=\"comment\">",
     3174        "<@preprocessor>", "<span class=\"preprocessor\">",
     3175        "<@string>",       "<span class=\"string\">",
     3176        "<@char>",         "<span class=\"char\">",
     3177        "</@comment>",     "</span>",
     3178        "</@preprocessor>","</span>",
     3179        "</@string>",      "</span>",
     3180        "</@char>",        "</span>"
     3181        // "<@char>",      "<font color=blue>",
     3182        // "</@char>",     "</font>",
     3183        // "<@func>",      "<font color=green>",
     3184        // "</@func>",     "</font>",
     3185        // "<@id>",        "<i>",
     3186        // "</@id>",       "</i>",
     3187        // "<@keyword>",   "<b>",
     3188        // "</@keyword>",  "</b>",
     3189        // "<@number>",    "<font color=yellow>",
     3190        // "</@number>",   "</font>",
     3191        // "<@op>",        "<b>",
     3192        // "</@op>",       "</b>",
     3193        // "<@param>",     "<i>",
     3194        // "</@param>",    "</i>",
     3195        // "<@string>",    "<font color=green>",
     3196        // "</@string>",  "</font>",
     3197    };
     3198    for (int i = 0, n = src.size(); i < n;) {
     3199        if (src.at(i) == charLangle) {
     3200            bool handled = false;
     3201            for (int k = 0; k != 8; ++k) {
     3202                const QString & tag = spanTags[2 * k];
     3203                if (tag == QStringRef(&src, i, tag.length())) {
     3204                    html += spanTags[2 * k + 1];
     3205                    i += tag.length();
     3206                    handled = true;
     3207                    break;
     3208                }
     3209            }
     3210            if (!handled) {
     3211                ++i;
     3212                if (src.at(i) == charAt ||
     3213                    (src.at(i) == QLatin1Char('/') && src.at(i + 1) == charAt)) {
     3214                    // drop 'our' unknown tags (the ones still containing '@')
     3215                    while (i < n && src.at(i) != QLatin1Char('>'))
     3216                        ++i;
     3217                    ++i;
     3218                }
     3219                else {
     3220                    // retain all others
     3221                    html += charLangle;
     3222                }
     3223            }
     3224        }
     3225        else {
     3226            html += src.at(i);
     3227            ++i;
     3228        }
     3229    }
     3230
     3231    return html;
     3232}
     3233#endif
     3234
     3235void HtmlGenerator::generateLink(const Atom* atom,
     3236                                 const Node* /* relative */,
     3237                                 CodeMarker* marker)
     3238{
     3239    static QRegExp camelCase("[A-Z][A-Z][a-z]|[a-z][A-Z0-9]|_");
     3240
     3241    if (funcLeftParen.indexIn(atom->string()) != -1 && marker->recognizeLanguage("Cpp")) {
     3242        // hack for C++: move () outside of link
     3243        int k = funcLeftParen.pos(1);
     3244        out() << protect(atom->string().left(k));
     3245        if (link.isEmpty()) {
     3246            if (showBrokenLinks)
     3247                out() << "</i>";
     3248        } else {
     3249            out() << "</a>";
     3250        }
     3251        inLink = false;
     3252        out() << protect(atom->string().mid(k));
     3253    } else if (marker->recognizeLanguage("Java")) {
     3254        // hack for Java: remove () and use <tt> when appropriate
     3255        bool func = atom->string().endsWith("()");
     3256        bool tt = (func || atom->string().contains(camelCase));
     3257        if (tt)
     3258            out() << "<tt>";
     3259        if (func) {
     3260            out() << protect(atom->string().left(atom->string().length() - 2));
     3261        } else {
     3262            out() << protect(atom->string());
     3263        }
     3264        out() << "</tt>";
     3265    } else {
     3266        out() << protect(atom->string());
     3267    }
     3268}
     3269
     3270QString HtmlGenerator::cleanRef(const QString& ref)
     3271{
     3272    QString clean;
     3273
     3274    if (ref.isEmpty())
     3275        return clean;
     3276
     3277    clean.reserve(ref.size() + 20);
     3278    const QChar c = ref[0];
     3279    const uint u = c.unicode();
     3280
     3281    if ((u >= 'a' && u <= 'z') ||
     3282         (u >= 'A' && u <= 'Z') ||
     3283         (u >= '0' && u <= '9')) {
     3284        clean += c;
     3285    } else if (u == '~') {
     3286        clean += "dtor.";
     3287    } else if (u == '_') {
     3288        clean += "underscore.";
     3289    } else {
     3290        clean += "A";
     3291    }
     3292
     3293    for (int i = 1; i < (int) ref.length(); i++) {
     3294        const QChar c = ref[i];
     3295        const uint u = c.unicode();
     3296        if ((u >= 'a' && u <= 'z') ||
     3297             (u >= 'A' && u <= 'Z') ||
     3298             (u >= '0' && u <= '9') || u == '-' ||
     3299             u == '_' || u == ':' || u == '.') {
     3300            clean += c;
     3301        } else if (c.isSpace()) {
     3302            clean += "-";
     3303        } else if (u == '!') {
     3304            clean += "-not";
     3305        } else if (u == '&') {
     3306            clean += "-and";
     3307        } else if (u == '<') {
     3308            clean += "-lt";
     3309        } else if (u == '=') {
     3310            clean += "-eq";
     3311        } else if (u == '>') {
     3312            clean += "-gt";
     3313        } else if (u == '#') {
     3314            clean += "#";
     3315        } else {
     3316            clean += "-";
     3317            clean += QString::number((int)u, 16);
     3318        }
     3319    }
     3320    return clean;
     3321}
     3322
     3323QString HtmlGenerator::registerRef(const QString& ref)
     3324{
     3325    QString clean = HtmlGenerator::cleanRef(ref);
     3326
     3327    for (;;) {
     3328        QString& prevRef = refMap[clean.toLower()];
     3329        if (prevRef.isEmpty()) {
     3330            prevRef = ref;
     3331            break;
     3332        } else if (prevRef == ref) {
     3333            break;
     3334        }
     3335        clean += "x";
     3336    }
     3337    return clean;
     3338}
     3339
     3340QString HtmlGenerator::protect(const QString& string)
     3341{
     3342#define APPEND(x) \
     3343    if (html.isEmpty()) { \
     3344        html = string; \
     3345        html.truncate(i); \
     3346    } \
     3347    html += (x);
     3348
     3349    QString html;
     3350    int n = string.length();
     3351
     3352    for (int i = 0; i < n; ++i) {
     3353        QChar ch = string.at(i);
     3354
     3355        if (ch == QLatin1Char('&')) {
     3356            APPEND("&amp;");
     3357        } else if (ch == QLatin1Char('<')) {
     3358            APPEND("&lt;");
     3359        } else if (ch == QLatin1Char('>')) {
     3360            APPEND("&gt;");
     3361        } else if (ch == QLatin1Char('"')) {
     3362            APPEND("&quot;");
     3363        } else if (ch.unicode() > 0x007F
     3364                   || (ch == QLatin1Char('*') && i + 1 < n && string.at(i) == QLatin1Char('/'))
     3365                   || (ch == QLatin1Char('.') && i > 2 && string.at(i - 2) == QLatin1Char('.'))) {
     3366            // we escape '*/' and the last dot in 'e.g.' and 'i.e.' for the Javadoc generator
     3367            APPEND("&#x");
     3368            html += QString::number(ch.unicode(), 16);
     3369            html += QLatin1Char(';');
     3370        } else {
     3371            if (!html.isEmpty())
     3372                html += ch;
     3373        }
     3374    }
     3375
     3376    if (!html.isEmpty())
     3377        return html;
     3378    return string;
     3379
     3380#undef APPEND
     3381}
     3382
    25743383QString HtmlGenerator::fileBase(const Node *node)
    25753384{
     
    26193428{
    26203429    if (node->type() == Node::Fake) {
    2621         if (static_cast<const FakeNode *>(node)->subType() == FakeNode::ExternalPage)
     3430        if (static_cast<const FakeNode *>(node)->subType() == Node::ExternalPage)
    26223431            return node->name();
    2623     }
    2624 
     3432        if (static_cast<const FakeNode *>(node)->subType() == Node::Image)
     3433            return node->name();
     3434    }
    26253435    return PageGenerator::fileName(node);
    26263436}
     
    26443454        if (typedeffe->associatedEnum()) {
    26453455            return refForNode(typedeffe->associatedEnum());
    2646         } else {
     3456        }
     3457        else {
    26473458            ref = node->name() + "-typedef";
    26483459        }
     
    26523463        if (func->associatedProperty()) {
    26533464            return refForNode(func->associatedProperty());
    2654         } else {
     3465        }
     3466        else {
    26553467            ref = func->name();
    26563468            if (func->overloadNumber() != 1)
     
    26583470        }
    26593471        break;
     3472#ifdef QDOC_QML       
     3473    case Node::Fake:
     3474        if (node->subType() != Node::QmlPropertyGroup)
     3475            break;
     3476    case Node::QmlProperty:
     3477#endif       
    26603478    case Node::Property:
    26613479        ref = node->name() + "-prop";
    26623480        break;
     3481#ifdef QDOC_QML
     3482    case Node::QmlSignal:
     3483        ref = node->name() + "-signal";
     3484        break;
     3485    case Node::QmlMethod:
     3486        ref = node->name() + "-method";
     3487        break;
     3488#endif       
    26633489    case Node::Variable:
    26643490        ref = node->name() + "-var";
     
    26923518    if (fn != outFileName())
    26933519#endif
    2694         link += fn;
    2695 
    2696     if (!node->isInnerNode()) {
     3520    link += fn;
     3521
     3522    if (!node->isInnerNode() || node->subType() == Node::QmlPropertyGroup) {
    26973523        ref = refForNode(node);
    26983524        if (relative && fn == fileName(relative) && ref == refForNode(relative))
     
    27093535    if (atom->type() == Atom::SectionLeft) {
    27103536        return Doc::canonicalTitle(Text::sectionHeading(atom).toString());
    2711     } else if (atom->type() == Atom::Target) {
     3537    }
     3538    else if (atom->type() == Atom::Target) {
    27123539        return Doc::canonicalTitle(atom->string());
    2713     } else {
     3540    }
     3541    else {
    27143542        return QString();
    27153543    }
     
    27553583        generateSynopsis(enume, relative, marker, CodeMarker::Detailed);
    27563584        out() << "<br />";
    2757         generateSynopsis(enume->flagsType(), relative, marker, CodeMarker::Detailed);
     3585        generateSynopsis(enume->flagsType(),
     3586                         relative,
     3587                         marker,
     3588                         CodeMarker::Detailed);
    27583589        out() << "</h3>\n";
    27593590    }
     
    27793610
    27803611        if (!section.members.isEmpty()) {
    2781             out() << "<p>Access functions:</p>\n";
     3612            out() << "<p><b>Access functions:</b></p>\n";
    27823613            generateSectionList(section, node, marker, CodeMarker::Accessors);
     3614        }
     3615
     3616        Section notifiers;
     3617        notifiers.members += property->notifiers();
     3618       
     3619        if (!notifiers.members.isEmpty()) {
     3620            out() << "<p><b>Notifier signal:</b></p>\n";
     3621            //out() << "<p>This signal is emitted when the property value is changed.</p>\n";
     3622            generateSectionList(notifiers, node, marker, CodeMarker::Accessors);
    27833623        }
    27843624    }
     
    27903630                  << "<a href=\"qflags.html\">QFlags</a>&lt;"
    27913631                  << protect(enume->name())
    2792                   << "&gt;. It stores an OR combination of " << protect(enume->name())
     3632                  << "&gt;. It stores an OR combination of "
     3633                  << protect(enume->name())
    27933634                  << " values.</p>\n";
    27943635        }
     
    28043645            if ((*c)->type() == Node::Class && !(*c)->doc().isEmpty()) {
    28053646                QString className = (*c)->name();
    2806                 if ((*c)->parent() && (*c)->parent()->type() == Node::Namespace &&
     3647                if ((*c)->parent() &&
     3648                    (*c)->parent()->type() == Node::Namespace &&
    28073649                    !(*c)->parent()->name().isEmpty())
    28083650                    className = (*c)->parent()->name()+"::"+className;
     
    28113653                    if ((*c)->status() == Node::Compat) {
    28123654                        compatClasses.insert(className, *c);
     3655                    }
     3656                    else if ((*c)->status() == Node::Obsolete) {
     3657                        obsoleteClasses.insert(className, *c);
    28133658                    }
    28143659                    else {
     
    28403685}
    28413686
     3687/*!
     3688  For generating the "New Classes... in 4.6" section on the
     3689  What's New in 4.6" page.
     3690 */
     3691void HtmlGenerator::findAllSince(const InnerNode *node)
     3692{
     3693    NodeList::const_iterator child = node->childNodes().constBegin();
     3694    while (child != node->childNodes().constEnd()) {
     3695        QString sinceVersion = (*child)->since();
     3696        if (((*child)->access() != Node::Private) && !sinceVersion.isEmpty()) {
     3697            NewSinceMaps::iterator nsmap = newSinceMaps.find(sinceVersion);
     3698            if (nsmap == newSinceMaps.end())
     3699                nsmap = newSinceMaps.insert(sinceVersion,NodeMultiMap());
     3700            NewClassMaps::iterator ncmap = newClassMaps.find(sinceVersion);
     3701            if (ncmap == newClassMaps.end())
     3702                ncmap = newClassMaps.insert(sinceVersion,NodeMap());
     3703 
     3704            if ((*child)->type() == Node::Function) {
     3705                FunctionNode *func = static_cast<FunctionNode *>(*child);
     3706                if ((func->status() > Node::Obsolete) &&
     3707                    (func->metaness() != FunctionNode::Ctor) &&
     3708                    (func->metaness() != FunctionNode::Dtor)) {
     3709                    nsmap.value().insert(func->name(),(*child));
     3710                }
     3711            }
     3712            else if ((*child)->url().isEmpty()) {
     3713                if ((*child)->type() == Node::Class && !(*child)->doc().isEmpty()) {
     3714                    QString className = (*child)->name();
     3715                    if ((*child)->parent() &&
     3716                        (*child)->parent()->type() == Node::Namespace &&
     3717                        !(*child)->parent()->name().isEmpty())
     3718                        className = (*child)->parent()->name()+"::"+className;
     3719                    nsmap.value().insert(className,(*child));
     3720                    ncmap.value().insert(className,(*child));
     3721                }
     3722            }
     3723            else {
     3724                QString name = (*child)->name();
     3725                if ((*child)->parent() &&
     3726                    (*child)->parent()->type() == Node::Namespace &&
     3727                    !(*child)->parent()->name().isEmpty())
     3728                    name = (*child)->parent()->name()+"::"+name;
     3729                nsmap.value().insert(name,(*child));
     3730            }
     3731            if ((*child)->isInnerNode()) {
     3732                findAllSince(static_cast<InnerNode *>(*child));
     3733            }
     3734        }
     3735        ++child;
     3736    }
     3737}
     3738
     3739#if 0
     3740    const QRegExp versionSeparator("[\\-\\.]");
     3741    const int minorIndex = version.indexOf(versionSeparator);
     3742    const int patchIndex = version.indexOf(versionSeparator, minorIndex+1);
     3743    version = version.left(patchIndex);
     3744#endif
     3745
    28423746void HtmlGenerator::findAllFunctions(const InnerNode *node)
    28433747{
     
    28503754            else if ((*c)->type() == Node::Function) {
    28513755                const FunctionNode *func = static_cast<const FunctionNode *>(*c);
    2852                 if (func->status() > Node::Obsolete && func->metaness() != FunctionNode::Ctor
    2853                         && func->metaness() != FunctionNode::Dtor) {
    2854                     funcIndex[(*c)->name()].insert((*c)->parent()->name(), *c);
     3756                if ((func->status() > Node::Obsolete) &&
     3757                    (func->metaness() != FunctionNode::Ctor) &&
     3758                    (func->metaness() != FunctionNode::Dtor)) {
     3759                    funcIndex[(*c)->name()].insert(myTree->fullDocumentName((*c)->parent()), *c);
    28553760                }
    28563761            }
     
    29023807}
    29033808
    2904 #ifdef ZZZ_QDOC_QML   
     3809#ifdef ZZZ_QDOC_QML
    29053810/*!
    29063811  This function finds all the qml element nodes and
     
    29133818        if ((*c)->type() == Node::Fake) {
    29143819            const FakeNode* fakeNode = static_cast<const FakeNode *>(*c);
    2915             if (fakeNode->subType() == FakeNode::QmlClass) {
    2916                 const QmlNode* qmlNode = static_cast<const QmlNode*>(fakeNode);
    2917                 //qDebug() << "HtmlGenerator: QML CLASS" << qmlNode->name();
     3820            if (fakeNode->subType() == Node::QmlClass) {
     3821                const QmlClassNode* qmlNode =
     3822                    static_cast<const QmlClassNode*>(fakeNode);
    29183823                const Node* n = qmlNode->classNode();
    2919                 if (n)
    2920                     //qDebug() << "  FOUND IT!" << n->name();
    29213824            }
    29223825            qmlClasses.insert(fakeNode->name(),*c);
     
    29253828    }
    29263829}
    2927 #endif   
    2928 
    2929 #if 0
    2930             else if ((*c)->isInnerNode()) {
    2931                 findAllClasses(static_cast<InnerNode *>(*c));
    2932             }
    29333830#endif
    29343831
     
    29743871    }
    29753872    else if (target.endsWith(".html")) {
    2976         node = tre->root()->findNode(target, Node::Fake);
     3873        node = myTree->root()->findNode(target, Node::Fake);
    29773874    }
    29783875    else if (marker) {
    2979         node = marker->resolveTarget(target, tre, relative);
     3876        node = marker->resolveTarget(target, myTree, relative);
    29803877        if (!node)
    2981             node = tre->findFakeNodeByTitle(target);
     3878            node = myTree->findFakeNodeByTitle(target);
    29823879        if (!node && atom) {
    2983             node = tre->findUnambiguousTarget(target,
     3880            node = myTree->findUnambiguousTarget(target,
    29843881                *const_cast<Atom**>(&atom));
    29853882        }
     
    30083905                               const Node *relative,
    30093906                               CodeMarker *marker,
    3010                                const Node *node)
     3907                               const Node** node)
    30113908{
    30123909    QString link;
    3013     node = 0;
     3910    *node = 0;
     3911    inObsoleteLink = false;
    30143912
    30153913    if (atom->string().contains(":") &&
     
    30353933        QString first = path.first().trimmed();
    30363934        if (first.isEmpty()) {
    3037             node = relative;
     3935            *node = relative;
    30383936        }
    30393937        else if (first.endsWith(".html")) {
    3040             node = tre->root()->findNode(first, Node::Fake);
     3938            *node = myTree->root()->findNode(first, Node::Fake);
    30413939        }
    30423940        else {
    3043             node = marker->resolveTarget(first, tre, relative);
    3044             if (!node)
    3045                 node = tre->findFakeNodeByTitle(first);
    3046             if (!node)
    3047                 node = tre->findUnambiguousTarget(first, targetAtom);
    3048         }
    3049 
    3050         if (node) {
    3051             if (!node->url().isEmpty())
    3052                 return node->url();
     3941            *node = marker->resolveTarget(first, myTree, relative);
     3942            if (!*node)
     3943                *node = myTree->findFakeNodeByTitle(first);
     3944            if (!*node)
     3945                *node = myTree->findUnambiguousTarget(first, targetAtom);
     3946        }
     3947
     3948        if (*node) {
     3949            if (!(*node)->url().isEmpty())
     3950                return (*node)->url();
    30533951            else
    30543952                path.removeFirst();
    30553953        }
    30563954        else {
    3057             node = relative;
     3955            *node = relative;
     3956        }
     3957
     3958        if (*node) {
     3959            if ((*node)->status() == Node::Obsolete) {
     3960                if (relative) {
     3961                    if (relative->parent() != *node) {
     3962                        if (relative->status() != Node::Obsolete) {
     3963                            bool porting = false;
     3964                            if (relative->type() == Node::Fake) {
     3965                                const FakeNode* fake = static_cast<const FakeNode*>(relative);
     3966                                if (fake->title().startsWith("Porting"))
     3967                                    porting = true;
     3968                            }
     3969                            QString name = marker->plainFullName(relative);
     3970                            if (!porting && !name.startsWith("Q3")) {
     3971                                if (obsoleteLinks) {
     3972                                    relative->doc().location().warning(tr("Link to obsolete item '%1' in %2")
     3973                                                                       .arg(atom->string())
     3974                                                                       .arg(name));
     3975                                }
     3976                                inObsoleteLink = true;
     3977                            }
     3978                        }
     3979                    }
     3980                }
     3981                else {
     3982                    qDebug() << "Link to Obsolete entity"
     3983                             << (*node)->name() << "no relative";
     3984                }
     3985            }
     3986#if 0                   
     3987            else if ((*node)->status() == Node::Deprecated) {
     3988                qDebug() << "Link to Deprecated entity";
     3989            }
     3990            else if ((*node)->status() == Node::Internal) {
     3991                qDebug() << "Link to Internal entity";
     3992            }
     3993#endif               
    30583994        }
    30593995
    30603996        while (!path.isEmpty()) {
    3061             targetAtom = tre->findTarget(path.first(), node);
     3997            targetAtom = myTree->findTarget(path.first(), *node);
    30623998            if (targetAtom == 0)
    30633999                break;
     
    30664002
    30674003        if (path.isEmpty()) {
    3068             link = linkForNode(node, relative);
     4004            link = linkForNode(*node, relative);
     4005            if (*node && (*node)->subType() == Node::Image)
     4006                link = "images/used-in-examples/" + link;
    30694007            if (targetAtom)
    3070                 link += "#" + refForAtom(targetAtom, node);
     4008                link += "#" + refForAtom(targetAtom, *node);
    30714009        }
    30724010    }
     
    30884026                                  const QString &title)
    30894027{
    3090     tre->generateIndex(outputDir() + "/" + fileBase + ".index", url, title);
     4028    myTree->generateIndex(outputDir() + "/" + fileBase + ".index", url, title);
    30914029}
    30924030
     
    31034041        if (node->isInnerNode()) {
    31044042            text << Atom::ParaLeft
    3105                  << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD) << "This "
    3106                  << typeString(node) << " is part of the Qt 3 support library."
     4043                 << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD)
     4044                 << "This "
     4045                 << typeString(node)
     4046                 << " is part of the Qt 3 support library."
    31074047                 << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
    3108                  << " It is provided to keep old source code working. We strongly advise against "
     4048                 << " It is provided to keep old source code working. "
     4049                 << "We strongly advise against "
    31094050                 << "using it in new code. See ";
    31104051
    3111             const FakeNode *fakeNode = tre->findFakeNodeByTitle("Porting To Qt 4");
     4052            const FakeNode *fakeNode = myTree->findFakeNodeByTitle("Porting To Qt 4");
    31124053            Atom *targetAtom = 0;
    31134054            if (fakeNode && node->type() == Node::Class) {
    31144055                QString oldName(node->name());
    3115                 targetAtom = tre->findTarget(oldName.replace("3", ""),
    3116                                              fakeNode);
     4056                targetAtom = myTree->findTarget(oldName.replace("3", ""),
     4057                                                fakeNode);
    31174058            }
    31184059
     
    31444085    QStringList macRefs = marker->macRefsForNode(node);
    31454086    foreach (const QString &macRef, macRefs)
    3146         out() << "<a name=\"" << "//apple_ref/" << macRef << "\" />\n";
     4087        out() << "<a name=\"" << "//apple_ref/" << macRef << "\"></a>\n";
    31474088}
    31484089
     
    31874128        }
    31884129        else {
     4130            if (inObsoleteLink) {
     4131                out() << "<sup>(obsolete)</sup>";
     4132            }
    31894133            out() << "</a>";
    31904134        }
    31914135    }
    31924136    inLink = false;
     4137    inObsoleteLink = false;
    31934138}
    31944139
    31954140QT_END_NAMESPACE
     4141
     4142#ifdef QDOC_QML
     4143
     4144/*!
     4145  Generates the summary for for the \a section. Only used for
     4146  sections of QML element documentation.
     4147
     4148  Currently handles only the QML property group.
     4149 */
     4150void HtmlGenerator::generateQmlSummary(const Section& section,
     4151                                       const Node *relative,
     4152                                       CodeMarker *marker)
     4153{
     4154    if (!section.members.isEmpty()) {
     4155        NodeList::ConstIterator m;
     4156        int count = section.members.size();
     4157        bool twoColumn = false;
     4158        if (section.members.first()->type() == Node::QmlProperty) {
     4159            twoColumn = (count >= 5);
     4160        }
     4161        if (twoColumn)
     4162            out() << "<p><table width=\"100%\" border=\"0\" cellpadding=\"0\""
     4163                     " cellspacing=\"0\">\n"
     4164                  << "<tr><td width=\"45%\" valign=\"top\">";
     4165        out() << "<ul>\n";
     4166
     4167        int row = 0;
     4168        m = section.members.begin();
     4169        while (m != section.members.end()) {
     4170            if (twoColumn && row == (int) (count + 1) / 2)
     4171                out() << "</ul></td><td valign=\"top\"><ul>\n";
     4172            out() << "<li><div class=\"fn\"></div>";
     4173            generateQmlItem(*m,relative,marker,true);
     4174            out() << "</li>\n";
     4175            row++;
     4176            ++m;
     4177        }
     4178        out() << "</ul>\n";
     4179        if (twoColumn)
     4180            out() << "</td></tr>\n</table></p>\n";
     4181    }
     4182}
     4183
     4184/*!
     4185  Outputs the html detailed documentation for a section
     4186  on a QML element reference page.
     4187 */
     4188void HtmlGenerator::generateDetailedQmlMember(const Node *node,
     4189                                              const InnerNode *relative,
     4190                                              CodeMarker *marker)
     4191{
     4192    const QmlPropertyNode* qpn = 0;
     4193    generateMacRef(node, marker);
     4194    out() << "<div class=\"qmlitem\">";
     4195    if (node->subType() == Node::QmlPropertyGroup) {
     4196        const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
     4197        NodeList::ConstIterator p = qpgn->childNodes().begin();
     4198        out() << "<div class=\"qmlproto\">";
     4199        out() << "<table width=\"100%\" class=\"qmlname\">";
     4200
     4201        while (p != qpgn->childNodes().end()) {
     4202            if ((*p)->type() == Node::QmlProperty) {
     4203                qpn = static_cast<const QmlPropertyNode*>(*p);
     4204                out() << "<tr><td>";
     4205                out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
     4206                if (!qpn->isWritable())
     4207                    out() << "<span class=\"qmlreadonly\">read-only</span>";
     4208                generateQmlItem(qpn, relative, marker, false);
     4209                out() << "</td></tr>";
     4210                if (qpgn->isDefault()) {
     4211                    out() << "</table>"
     4212                          << "</div></div>"
     4213                          << "<div class=\"qmlitem\">"
     4214                          << "<div class=\"qmlproto\">"
     4215                          << "<table class=\"qmlname\">"
     4216                          << "<tr><td><font color=\"green\">"
     4217                          << "default</font></td></tr>";
     4218                }
     4219            }
     4220            ++p;
     4221        }
     4222        out() << "</table>";
     4223        out() << "</div>";
     4224    }
     4225    else if (node->type() == Node::QmlSignal) {
     4226        const FunctionNode* qsn = static_cast<const FunctionNode*>(node);
     4227        out() << "<div class=\"qmlproto\">";
     4228        out() << "<table class=\"qmlname\">";
     4229        out() << "<tr><td>";
     4230        out() << "<a name=\"" + refForNode(qsn) + "\"></a>";
     4231        generateSynopsis(qsn,relative,marker,CodeMarker::Detailed,false);
     4232        //generateQmlItem(qsn,relative,marker,false);
     4233        out() << "</td></tr>";
     4234        out() << "</table>";
     4235        out() << "</div>";
     4236    }
     4237    else if (node->type() == Node::QmlMethod) {
     4238        const FunctionNode* qmn = static_cast<const FunctionNode*>(node);
     4239        out() << "<div class=\"qmlproto\">";
     4240        out() << "<table class=\"qmlname\">";
     4241        out() << "<tr><td>";
     4242        out() << "<a name=\"" + refForNode(qmn) + "\"></a>";
     4243        generateSynopsis(qmn,relative,marker,CodeMarker::Detailed,false);
     4244        out() << "</td></tr>";
     4245        out() << "</table>";
     4246        out() << "</div>";
     4247    }
     4248    out() << "<div class=\"qmldoc\">";
     4249    generateStatus(node, marker);
     4250    generateBody(node, marker);
     4251    generateThreadSafeness(node, marker);
     4252    generateSince(node, marker);
     4253    generateAlsoList(node, marker);
     4254    out() << "</div>";
     4255    out() << "</div>";
     4256}
     4257
     4258/*!
     4259  Output the "Inherits" line for the QML element,
     4260  if there should be one.
     4261 */
     4262void HtmlGenerator::generateQmlInherits(const QmlClassNode* cn,
     4263                                        CodeMarker* marker)
     4264{
     4265    if (cn && !cn->links().empty()) {
     4266        if (cn->links().contains(Node::InheritsLink)) {
     4267            QPair<QString,QString> linkPair;
     4268            linkPair = cn->links()[Node::InheritsLink];
     4269            QStringList strList(linkPair.first);
     4270            const Node* n = myTree->findNode(strList,Node::Fake);
     4271            if (n && n->subType() == Node::QmlClass) {
     4272                const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n);
     4273                out() << "<p style=\"text-align: center\">";
     4274                Text text;
     4275                text << "[Inherits ";
     4276                text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
     4277                text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
     4278                text << Atom(Atom::String, linkPair.second);
     4279                text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
     4280                text << "]";
     4281                generateText(text, cn, marker);
     4282                out() << "</p>";
     4283            }
     4284        }
     4285    }
     4286}
     4287
     4288/*!
     4289  Output the "[Xxx instantiates the C++ class QmlGraphicsXxx]"
     4290  line for the QML element, if there should be one.
     4291
     4292  If there is no class node, or if the class node status
     4293  is set to Node::Internal, do nothing.
     4294 */
     4295void HtmlGenerator::generateQmlInstantiates(const QmlClassNode* qcn,
     4296                                            CodeMarker* marker)
     4297{
     4298    const ClassNode* cn = qcn->classNode();
     4299    if (cn && (cn->status() != Node::Internal)) {
     4300        out() << "<p style=\"text-align: center\">";
     4301        Text text;
     4302        text << "[";
     4303        text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
     4304        text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
     4305        text << Atom(Atom::String, qcn->name());
     4306        text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
     4307        text << " instantiates the C++ class ";
     4308        text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
     4309        text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
     4310        text << Atom(Atom::String, cn->name());
     4311        text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
     4312        text << "]";
     4313        generateText(text, qcn, marker);
     4314        out() << "</p>";
     4315    }
     4316}
     4317
     4318/*!
     4319  Output the "[QmlGraphicsXxx is instantiated by QML element Xxx]"
     4320  line for the class, if there should be one.
     4321
     4322  If there is no QML element, or if the class node status
     4323  is set to Node::Internal, do nothing.
     4324 */
     4325void HtmlGenerator::generateInstantiatedBy(const ClassNode* cn,
     4326                                           CodeMarker* marker)
     4327{
     4328    if (cn &&  cn->status() != Node::Internal && !cn->qmlElement().isEmpty()) {
     4329        const Node* n = myTree->root()->findNode(cn->qmlElement(),Node::Fake);
     4330        if (n && n->subType() == Node::QmlClass) {
     4331            out() << "<p style=\"text-align: center\">";
     4332            Text text;
     4333            text << "[";
     4334            text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
     4335            text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
     4336            text << Atom(Atom::String, cn->name());
     4337            text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
     4338            text << " is instantiated by QML element ";
     4339            text << Atom(Atom::LinkNode,CodeMarker::stringForNode(n));
     4340            text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
     4341            text << Atom(Atom::String, n->name());
     4342            text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
     4343            text << "]";
     4344            generateText(text, cn, marker);
     4345            out() << "</p>";
     4346        }
     4347    }
     4348}
     4349
     4350#endif
  • trunk/tools/qdoc3/htmlgenerator.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4646#ifndef HTMLGENERATOR_H
    4747#define HTMLGENERATOR_H
     48
     49#define QDOC_NAME_ALIGNMENT
    4850
    4951#include <qmap.h>
     
    6668#endif
    6769
     70typedef QMultiMap<QString, Node*> NodeMultiMap;
     71typedef QMap<QString, NodeMultiMap> NewSinceMaps;
     72typedef QMap<Node*, NodeMultiMap> ParentMaps;
     73typedef QMap<QString, const Node*> NodeMap;
     74typedef QMap<QString, NodeMap> NewClassMaps;
     75
    6876class HelpProjectWriter;
    6977
    7078class HtmlGenerator : public PageGenerator
    7179{
     80 public:
     81    enum SinceType {
     82        Namespace,
     83        Class,
     84        MemberFunction,
     85        NamespaceFunction,
     86        GlobalFunction,
     87        Macro,
     88        Enum,
     89        Typedef,
     90        Property,
     91        Variable,
     92        QmlProperty,
     93        QmlSignal,
     94        QmlMethod,
     95        LastSinceType
     96    };
     97
    7298 public:
    7399    HtmlGenerator();
     
    81107    static QString protect(const QString& string);
    82108    static QString cleanRef(const QString& ref);
     109    static QString sinceTitle(int i) { return sinceTitles[i]; }
    83110
    84111 protected:
     
    130157    void generateClassHierarchy(const Node *relative,
    131158                                CodeMarker *marker,
    132                                 const QMap<QString,const Node *> &classMap);
     159                                const NodeMap &classMap);
    133160    void generateAnnotatedList(const Node *relative,
    134161                               CodeMarker *marker,
    135                                const QMap<QString, const Node *> &nodeMap);
     162                               const NodeMap &nodeMap);
    136163    void generateCompactList(const Node *relative,
    137164                             CodeMarker *marker,
    138                              const QMap<QString, const Node *> &classMap);
     165                             const NodeMap &classMap,
     166                             QString commonPrefix = QString());
    139167    void generateFunctionIndex(const Node *relative, CodeMarker *marker);
    140168    void generateLegaleseList(const Node *relative, CodeMarker *marker);
    141169    void generateOverviewList(const Node *relative, CodeMarker *marker);
     170    void generateSectionList(const Section& section,
     171                             const Node *relative,
     172                             CodeMarker *marker,
     173                             CodeMarker::SynopsisStyle style);
     174#ifdef QDOC_QML
     175    void generateQmlSummary(const Section& section,
     176                            const Node *relative,
     177                            CodeMarker *marker);
     178    void generateQmlItem(const Node *node,
     179                         const Node *relative,
     180                         CodeMarker *marker,
     181                         bool summary);
     182    void generateDetailedQmlMember(const Node *node,
     183                                   const InnerNode *relative,
     184                                   CodeMarker *marker);
     185    void generateQmlInherits(const QmlClassNode* cn, CodeMarker* marker);
     186    void generateQmlInstantiates(const QmlClassNode* qcn, CodeMarker* marker);
     187    void generateInstantiatedBy(const ClassNode* cn, CodeMarker* marker);
     188#endif
     189#ifdef QDOC_NAME_ALIGNMENT
     190    void generateSection(const NodeList& nl,
     191                         const Node *relative,
     192                         CodeMarker *marker,
     193                         CodeMarker::SynopsisStyle style);
     194    void generateSynopsis(const Node *node,
     195                          const Node *relative,
     196                          CodeMarker *marker,
     197                          CodeMarker::SynopsisStyle style,
     198                          bool nameAlignment = false);
     199    void generateSectionInheritedList(const Section& section,
     200                                      const Node *relative,
     201                                      CodeMarker *marker,
     202                                      bool nameAlignment = false);
     203    QString highlightedCode(const QString& markedCode,
     204                            CodeMarker *marker,
     205                            const Node *relative,
     206                            CodeMarker::SynopsisStyle style = CodeMarker::Accessors,
     207                            bool nameAlignment = false);
     208#else
    142209    void generateSynopsis(const Node *node,
    143210                          const Node *relative,
    144211                          CodeMarker *marker,
    145212                          CodeMarker::SynopsisStyle style);
    146     void generateSectionList(const Section& section,
    147                              const Node *relative,
    148                              CodeMarker *marker,
    149                              CodeMarker::SynopsisStyle style);
    150213    void generateSectionInheritedList(const Section& section,
    151214                                      const Node *relative,
    152215                                      CodeMarker *marker);
     216    QString highlightedCode(const QString& markedCode,
     217                            CodeMarker *marker,
     218                            const Node *relative);
     219#endif
    153220    void generateFullName(const Node *apparentNode,
    154221                          const Node *relative,
    155222                          CodeMarker *marker,
    156223                          const Node *actualNode = 0);
    157     void generateDetailedMember(const Node *node, const InnerNode *relative, CodeMarker *marker);
    158     void generateLink(const Atom *atom, const Node *relative, CodeMarker *marker);
     224    void generateDetailedMember(const Node *node,
     225                                const InnerNode *relative,
     226                                CodeMarker *marker);
     227    void generateLink(const Atom *atom,
     228                      const Node *relative,
     229                      CodeMarker *marker);
    159230    void generateStatus(const Node *node, CodeMarker *marker);
    160231   
    161232    QString registerRef(const QString& ref);
    162     QString highlightedCode(const QString& markedCode, CodeMarker *marker, const Node *relative);
    163233    QString fileBase(const Node *node);
    164234#if 0
     
    173243    void findAllQmlClasses(const InnerNode *node);
    174244#endif
     245    void findAllSince(const InnerNode *node);
    175246    static int hOffset(const Node *node);
    176247    static bool isThreeColumnEnumValueTable(const Atom *atom);
     
    178249                            const Node *relative,
    179250                            CodeMarker *marker,
    180                             const Node *node = 0);
     251                            const Node** node);
    181252    virtual void generateDcf(const QString &fileBase,
    182253                             const QString &startPage,
     
    206277    HelpProjectWriter *helpProjectWriter;
    207278    bool inLink;
     279    bool inObsoleteLink;
    208280    bool inContents;
    209281    bool inSectionHeading;
     
    225297    QStringList stylesheets;
    226298    QStringList customHeadElements;
    227     const Tree *tre;
     299    const Tree *myTree;
    228300    bool slow;
    229     QMap<QString, QMap<QString, const Node *> > moduleClassMap;
    230     QMap<QString, QMap<QString, const Node *> > moduleNamespaceMap;
    231     QMap<QString, const Node *> nonCompatClasses;
    232     QMap<QString, const Node *> mainClasses;
    233     QMap<QString, const Node *> compatClasses;
    234     QMap<QString, const Node *> namespaceIndex;
    235     QMap<QString, const Node *> serviceClasses;
     301    bool obsoleteLinks;
     302    QMap<QString, NodeMap > moduleClassMap;
     303    QMap<QString, NodeMap > moduleNamespaceMap;
     304    NodeMap nonCompatClasses;
     305    NodeMap mainClasses;
     306    NodeMap compatClasses;
     307    NodeMap obsoleteClasses;
     308    NodeMap namespaceIndex;
     309    NodeMap serviceClasses;
    236310#ifdef QDOC_QML   
    237     QMap<QString, const Node *> qmlClasses;
    238 #endif
    239     QMap<QString, QMap<QString, const Node *> > funcIndex;
     311    NodeMap qmlClasses;
     312#endif
     313    QMap<QString, NodeMap > funcIndex;
    240314    QMap<Text, const Node *> legaleseTexts;
     315    NewSinceMaps newSinceMaps;
     316    static QString sinceTitles[];
     317    NewClassMaps newClassMaps;
    241318};
    242319
     
    252329
    253330#endif
     331
  • trunk/tools/qdoc3/jambiapiparser.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    235235        if (cppNode->type() == Node::Fake) {
    236236            FakeNode *cppFake = static_cast<FakeNode *>(cppNode);
    237             if (cppFake->subType() == FakeNode::Page) {
    238                 FakeNode *javaFake = new FakeNode(javaTre->root(), cppFake->name(),
     237            if (cppFake->subType() == Node::Page) {
     238                FakeNode *javaFake = new FakeNode(javaTre->root(),
     239                                                  cppFake->name(),
    239240                                                  cppFake->subType());
    240241                javaFake->setModuleName("com.trolltech.qt");    // ### hard-coded
  • trunk/tools/qdoc3/jambiapiparser.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/javacodemarker.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/javacodemarker.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/javadocgenerator.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    273273}
    274274
    275 void JavadocGenerator::generateText(const Text& text, const Node *relative, CodeMarker *marker)
     275bool JavadocGenerator::generateText(const Text& text, const Node *relative, CodeMarker *marker)
    276276{
    277277    HtmlGenerator::generateText(text, relative, marker);
     278    return true;
    278279}
    279280
  • trunk/tools/qdoc3/javadocgenerator.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    6969    void generateFakeNode( const FakeNode *fake, CodeMarker *marker );
    7070
    71     void generateText( const Text& text, const Node *relative, CodeMarker *marker );
     71    bool generateText( const Text& text, const Node *relative, CodeMarker *marker );
    7272    void generateBody( const Node *node, CodeMarker *marker );
    7373    void generateAlsoList( const Node *node, CodeMarker *marker );
  • trunk/tools/qdoc3/linguistgenerator.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/linguistgenerator.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/location.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/location.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/loutgenerator.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/loutgenerator.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/main.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4444*/
    4545
     46#include <qglobal.h>
    4647#include <QtCore>
    4748#include <stdlib.h>
     
    9596
    9697static bool slow = false;
     98static bool showInternal = false;
     99static bool obsoleteLinks = false;
    97100static QStringList defines;
    98101static QHash<QString, Tree *> trees;
    99 
    100 //static int doxygen = 0;
    101102
    102103/*!
     
    122123    Location::information(tr("Usage: qdoc [options] file1.qdocconf ...\n"
    123124                              "Options:\n"
    124                               "    -help     "
     125                              "    -help         "
    125126                              "Display this information and exit\n"
    126                               "    -version  "
     127                              "    -version      "
    127128                              "Display version of qdoc and exit\n"
    128                               "    -D<name>  "
     129                              "    -D<name>      "
    129130                              "Define <name> as a macro while parsing sources\n"
    130                               "    -slow     "
    131                               "Turn on features that slow down qdoc") );
     131                              "    -slow         "
     132                              "Turn on features that slow down qdoc\n"
     133                              "    -showinternal "
     134                              "Include stuff marked internal\n"
     135                              "    -obsoletelinks "
     136                              "Report links from obsolete items to non-obsolete items") );
    132137}
    133138
     
    137142static void printVersion()
    138143{
    139     Location::information(tr("qdoc version 4.4.1"));
     144    QString s = QString(tr("qdoc version ")) + QString(QT_VERSION_STR);
     145    Location::information(s);
    140146}
    141147
     
    161167    }
    162168    config.setStringList(CONFIG_SLOW, QStringList(slow ? "true" : "false"));
     169    config.setStringList(CONFIG_SHOWINTERNAL,
     170                         QStringList(showInternal ? "true" : "false"));
     171    config.setStringList(CONFIG_OBSOLETELINKS,
     172                         QStringList(obsoleteLinks ? "true" : "false"));
    163173
    164174    /*
     
    223233    Location langLocation = config.lastLocation();
    224234
    225 #ifdef QDOC2DOX   
    226     // qdoc -> doxygen
    227     if (doxygen == 2) {
    228         qDebug() << "READING anchors.txt";
    229         DoxWriter::readAnchors();
    230         qDebug() << "READING title maps";
    231         DoxWriter::readTitles();
    232         qDebug() << "READING member multimaps";
    233         DoxWriter::readMembers();
    234     }
    235 #endif   
    236 
    237235    /*
    238236      Initialize the tree where all the parsed sources will be stored.
     
    321319    tree->resolveTargets();
    322320
    323 #ifdef QDOC2DOX   
    324     // qdoc -> doxygen
    325     if (doxygen == 1) {
    326         DoxWriter::writeAnchors();
    327         DoxWriter::writeTitles();
    328         DoxWriter::writeMembers();
    329     }
    330 
    331     if (doxygen == 0) {
    332 #endif   
    333 
    334321    /*
    335322      Now the tree has been built, and all the stuff that needed
     
    353340    if (!tagFile.isEmpty())
    354341        tree->generateTagFile(tagFile);
    355    
     342
    356343    tree->setVersion("");
    357344    Generator::terminate();
    358 
    359 #ifdef QDOC2DOX   
    360     }
    361 #endif   
    362 
    363345    CodeParser::terminate();
    364346    CodeMarker::terminate();
     
    371353    foreach (QTranslator *translator, translators)
    372354        delete translator;
    373 
    374355    delete tree;
    375356}
     
    455436            slow = true;
    456437        }
    457        
    458 #ifdef QDOC2DOX       
    459         else if (opt == "-doxygen1") {
    460             // qdoc -> doxygen
    461             // Don't use this; it isn't ready yet.
    462             // Now it's a fossil.
    463             qDebug() << "doxygen pass 1";
    464             doxygen = 1;
    465             DoxWriter::setDoxPass(1);
     438        else if (opt == "-showinternal") {
     439            showInternal = true;
    466440        }
    467         else if (opt == "-doxygen2") {
    468             // qdoc -> doxygen
    469             // Don't use this; it isn't ready yet.
    470             // Now it's a fossil.
    471             qDebug() << "doxygen pass 2";
    472             doxygen = 2;
    473             DoxWriter::setDoxPass(2);
     441        else if (opt == "-obsoletelinks") {
     442            obsoleteLinks = true;
    474443        }
    475 #endif
    476        
    477444        else {
    478445            qdocFiles.append(opt);
  • trunk/tools/qdoc3/mangenerator.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/mangenerator.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/node.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4444*/
    4545
     46#include <QtCore>
    4647#include "node.h"
    4748
     
    5051/*!
    5152  \class Node
    52   \brief A node in a Tree.
    53  */
    54 
    55 /*!
     53  \brief The Node class is a node in the Tree.
     54
     55  A Node represents a class or function or something else
     56  from the source code..
     57 */
     58
     59/*!
     60  When this Node is destroyed, if it has a parent Node, it
     61  removes itself from the parent node's child list.
    5662 */
    5763Node::~Node()
     
    6470
    6571/*!
     72  Sets this Node's Doc to \a doc. If \a replace is false and
     73  this Node already has a Doc, a warning is reported that the
     74  Doc is being overridden, and it reports where the previous
     75  Doc was found. If \a replace is true, the Doc is replaced
     76  silently.
    6677 */
    6778void Node::setDoc(const Doc& doc, bool replace)
     
    114125
    115126/*!
     127  This function creates a pair that describes a link.
     128  The pair is composed from \a link and \a desc. The
     129  \a linkType is the map index the pair is filed under.
    116130 */
    117131void Node::setLink(LinkType linkType, const QString &link, const QString &desc)
     
    205219
    206220/*!
     221  Find the function node in this node for the function named \a name.
    207222 */
    208223FunctionNode *InnerNode::findFunctionNode(const QString& name)
     
    212227
    213228/*!
     229  Find the function node in this node that has the same name as \a clone.
    214230 */
    215231FunctionNode *InnerNode::findFunctionNode(const FunctionNode *clone)
     
    232248    }
    233249    return 0;
     250}
     251
     252/*!
     253  Returns the list of keys from the primary function map.
     254 */
     255QStringList InnerNode::primaryKeys()
     256{
     257    QStringList t;
     258    QMap<QString, Node*>::iterator i = primaryFunctionMap.begin();
     259    while (i != primaryFunctionMap.end()) {
     260        t.append(i.key());
     261        ++i;
     262    }
     263    return t;
     264}
     265
     266/*!
     267  Returns the list of keys from the secondary function map.
     268 */
     269QStringList InnerNode::secondaryKeys()
     270{
     271    QStringList t;
     272    QMap<QString, NodeList>::iterator i = secondaryFunctionMap.begin();
     273    while (i != secondaryFunctionMap.end()) {
     274        t.append(i.key());
     275        ++i;
     276    }
     277    return t;
    234278}
    235279
     
    379423
    380424/*!
     425  Find the function node in this node that has the given \a name.
    381426 */
    382427const FunctionNode *InnerNode::findFunctionNode(const QString& name) const
     
    387432
    388433/*!
    389  */
    390 const FunctionNode *InnerNode::findFunctionNode(
    391         const FunctionNode *clone) const
     434  Find the function node in this node that has the same name as \a clone.
     435 */
     436const FunctionNode *InnerNode::findFunctionNode(const FunctionNode *clone) const
    392437{
    393438    InnerNode *that = (InnerNode *) this;
     
    507552{
    508553    children.append(child);
    509     if (child->type() == Function) {
     554    if ((child->type() == Function) || (child->type() == QmlMethod)) {
    510555        FunctionNode *func = (FunctionNode *) child;
    511556        if (!primaryFunctionMap.contains(func->name())) {
     
    624669
    625670/*!
    626   Returns false because this is an InnerNode.
     671  Returns false because this is a LeafNode.
    627672 */
    628673bool LeafNode::isInnerNode() const
     
    714759
    715760/*!
    716  */
    717 FakeNode::FakeNode(InnerNode *parent, const QString& name, SubType subType)
    718     : InnerNode(Fake, parent, name), sub(subType)
    719 {
    720 }
    721 
    722 /*!
     761  The type of a FakeNode is Fake, and it has a \a subtype,
     762  which specifies the type of FakeNode.
     763 */
     764FakeNode::FakeNode(InnerNode *parent, const QString& name, SubType subtype)
     765    : InnerNode(Fake, parent, name), sub(subtype)
     766{
     767}
     768
     769/*!
     770  Returns the fake node's full title, which is usually
     771  just title(), but for some SubType values is different
     772  from title()
    723773 */
    724774QString FakeNode::fullTitle() const
     
    730780            return title();
    731781    }
     782    else if (sub == Image) {
     783        if (title().isEmpty())
     784            return name().mid(name().lastIndexOf('/') + 1) + " Image File";
     785        else
     786            return title();
     787    }
    732788    else if (sub == HeaderFile) {
    733789        if (title().isEmpty())
     
    742798
    743799/*!
     800  Returns the subtitle.
    744801 */
    745802QString FakeNode::subTitle() const
     
    748805        return stle;
    749806
    750     if (sub == File) {
     807    if ((sub == File) || (sub == Image)) {
    751808        if (title().isEmpty() && name().contains("/"))
    752809            return name();
     
    818875/*!
    819876  \class Parameter
    820  */
    821 
    822 /*!
     877  \brief The class Parameter contains one parameter.
     878
     879  A parameter can be a function parameter or a macro
     880  parameter.
     881 */
     882
     883/*!
     884  Constructs this parameter from the left and right types
     885  \a leftType and rightType, the parameter \a name, and the
     886  \a defaultValue. In practice, \a rightType is not used,
     887  and I don't know what is was meant for.
    823888 */
    824889Parameter::Parameter(const QString& leftType,
     
    831896
    832897/*!
     898  The standard copy constructor copies the strings from \a p.
    833899 */
    834900Parameter::Parameter(const Parameter& p)
     
    838904
    839905/*!
     906  Assigning Parameter \a p to this Parameter copies the
     907  strings across.
    840908 */
    841909Parameter& Parameter::operator=(const Parameter& p)
     
    849917
    850918/*!
     919  Reconstructs the text describing the parameter and
     920  returns it. If \a value is true, the default value
     921  will be included, if there is one.
     922 */
     923QString Parameter::reconstruct(bool value) const
     924{
     925    QString p = lef + rig;
     926    if (!p.endsWith(QChar('*')) && !p.endsWith(QChar('&')) && !p.endsWith(QChar(' ')))
     927        p += " ";
     928    p += nam;
     929    if (value)
     930        p += def;
     931    return p;
     932}
     933
     934
     935/*!
    851936  \class FunctionNode
    852937 */
    853938
    854939/*!
     940  Construct a function node for a C++ function. It's parent
     941  is \a parent, and it's name is \a name.
    855942 */
    856943FunctionNode::FunctionNode(InnerNode *parent, const QString& name)
    857     : LeafNode(Function, parent, name), met(Plain), vir(NonVirtual),
    858       con(false), sta(false), ove(false), rf(0), ap(0)
    859 {
     944    : LeafNode(Function, parent, name),
     945      met(Plain),
     946      vir(NonVirtual),
     947      con(false),
     948      sta(false),
     949      ove(false),
     950      att(false),
     951      rf(0),
     952      ap(0)
     953{
     954    // nothing.
     955}
     956
     957/*!
     958  Construct a function node for a QML method or signal, specified
     959  by \a type. It's parent is \a parent, and it's name is \a name.
     960  If \a attached is true, it is an attached method or signal.
     961 */
     962FunctionNode::FunctionNode(Type type, InnerNode *parent, const QString& name, bool attached)
     963    : LeafNode(type, parent, name),
     964      met(Plain),
     965      vir(NonVirtual),
     966      con(false),
     967      sta(false),
     968      ove(false),
     969      att(attached),
     970      rf(0),
     971      ap(0)
     972{
     973    // nothing.
    860974}
    861975
     
    866980    parent()->setOverload(this, overlode);
    867981    ove = overlode;
     982}
     983
     984/*!
     985  Sets the function node's reimplementation flag to \a r.
     986  When \a r is true, it is supposed to mean that this function
     987  is a reimplementation of a virtual function in a base class,
     988  but it really just means the \e reimp command was seen in the
     989  qdoc comment.
     990 */
     991void FunctionNode::setReimp(bool r)
     992{
     993    reimp = r;
    868994}
    869995
     
    8901016
    8911017/*!
     1018  If this function is a reimplementation, \a from points
     1019  to the FunctionNode of the function being reimplemented.
    8921020 */
    8931021void FunctionNode::setReimplementedFrom(FunctionNode *from)
     
    8981026
    8991027/*!
     1028  Sets the "associated" property to \a property. The function
     1029  might be the setter or getter for a property, for example.
    9001030 */
    9011031void FunctionNode::setAssociatedProperty(PropertyNode *property)
     
    9051035
    9061036/*!
     1037  Returns the overload number for this function obtained
     1038  from the parent.
    9071039 */
    9081040int FunctionNode::overloadNumber() const
     
    9121044
    9131045/*!
     1046  Returns the number of times this function name has been
     1047  overloaded, obtained from the parent.
    9141048 */
    9151049int FunctionNode::numOverloads() const
     
    9191053
    9201054/*!
     1055  Returns the list of parameter names.
    9211056 */
    9221057QStringList FunctionNode::parameterNames() const
     
    9291064    }
    9301065    return names;
     1066}
     1067
     1068/*!
     1069  Returns the list of reconstructed parameters. If \a values
     1070  is true, the default values are included, if any are present.
     1071 */
     1072QStringList FunctionNode::reconstructParams(bool values) const
     1073{
     1074    QStringList params;
     1075    QList<Parameter>::ConstIterator p = parameters().begin();
     1076    while (p != parameters().end()) {
     1077        params << (*p).reconstruct(values);
     1078        ++p;
     1079    }
     1080    return params;
     1081}
     1082
     1083/*!
     1084  Reconstructs and returns the function's signature. If \a values
     1085  is true, the default values of the parameters are included, if
     1086  present.
     1087 */
     1088QString FunctionNode::signature(bool values) const
     1089{
     1090    QString s;
     1091    if (!returnType().isEmpty())
     1092        s = returnType() + " ";
     1093    s += name() + "(";
     1094    QStringList params = reconstructParams(values);
     1095    int p = params.size();
     1096    if (p > 0) {
     1097        for (int i=0; i<p; i++) {
     1098            s += params[i];
     1099            if (i < (p-1))
     1100                s += ", ";
     1101        }
     1102    }
     1103    s += ")";
     1104    return s;
     1105}
     1106
     1107/*!
     1108  Print some debugging stuff.
     1109 */
     1110void FunctionNode::debug() const
     1111{
     1112    qDebug() << "QML METHOD" << name() << "rt" << rt << "pp" << pp;
    9311113}
    9321114
     
    10221204}
    10231205
     1206#ifdef QDOC_QML
     1207bool QmlClassNode::qmlOnly = false;
     1208
     1209/*!
     1210  Constructor for the Qml class node.
     1211 */
     1212QmlClassNode::QmlClassNode(InnerNode *parent,
     1213                           const QString& name,
     1214                           const ClassNode* cn)
     1215    : FakeNode(parent, name, QmlClass), cnode(cn)
     1216{
     1217    setTitle((qmlOnly ? "" : "QML ") + name + " Element Reference");
     1218}
     1219
     1220/*!
     1221  The base file name for this kind of node has "qml_"
     1222  prepended to it.
     1223
     1224  But not yet. Still testing.
     1225 */
     1226QString QmlClassNode::fileBase() const
     1227{
     1228#if 0   
     1229    if (Node::fileBase() == "item")
     1230        qDebug() << "FILEBASE: qmlitem" << name();
     1231    return "qml_" + Node::fileBase();
     1232#endif
     1233    return Node::fileBase();
     1234}
     1235
     1236/*!
     1237  Constructor for the Qml property group node. \a parent is
     1238  always a QmlClassNode.
     1239 */
     1240QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent,
     1241                                   const QString& name,
     1242                                   bool attached)
     1243    : FakeNode(parent, name, QmlPropertyGroup),
     1244      isdefault(false),
     1245      att(attached)
     1246{
     1247    // nothing.
     1248}
     1249
     1250/*!
     1251  Constructor for the QML property node.
     1252 */
     1253QmlPropertyNode::QmlPropertyNode(QmlPropGroupNode *parent,
     1254                                 const QString& name,
     1255                                 const QString& type,
     1256                                 bool attached)
     1257    : LeafNode(QmlProperty, parent, name),
     1258      dt(type),
     1259      sto(Trool_Default),
     1260      des(Trool_Default),
     1261      att(attached)
     1262{
     1263    // nothing.
     1264}
     1265
     1266/*!
     1267  I don't know what this is.
     1268 */
     1269QmlPropertyNode::Trool QmlPropertyNode::toTrool(bool boolean)
     1270{
     1271    return boolean ? Trool_True : Trool_False;
     1272}
     1273
     1274/*!
     1275  I don't know what this is either.
     1276 */
     1277bool QmlPropertyNode::fromTrool(Trool troolean, bool defaultValue)
     1278{
     1279    switch (troolean) {
     1280    case Trool_True:
     1281        return true;
     1282    case Trool_False:
     1283        return false;
     1284    default:
     1285        return defaultValue;
     1286    }
     1287}
     1288#endif
     1289
    10241290QT_END_NAMESPACE
  • trunk/tools/qdoc3/node.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    7373        Property,
    7474        Variable,
    75         Target
     75#ifdef QDOC_QML
     76        Target,
     77        QmlProperty,
     78        QmlSignal,
     79        QmlMethod,
     80        LastType
     81#else
     82        Target,
     83        LastType
     84#endif
     85    };
     86
     87    enum SubType {
     88        NoSubType,
     89        Example,
     90        HeaderFile,
     91        File,
     92        Image,
     93        Group,
     94        Module,
     95        Page,
     96#ifdef QDOC_QML
     97        ExternalPage,
     98        QmlClass,
     99        QmlPropertyGroup
     100#else
     101        ExternalPage
     102#endif
    76103    };
    77104   
     
    100127        PreviousLink,
    101128        ContentsLink,
    102         IndexLink /*,
     129        IndexLink,
     130        InheritsLink /*,
    103131        GlossaryLink,
    104132        CopyrightLink,
     
    124152
    125153    virtual bool isInnerNode() const = 0;
     154    virtual bool isReimp() const { return false; }
     155    virtual bool isFunction() const { return false; }
    126156    Type type() const { return typ; }
     157    virtual SubType subType() const { return NoSubType; }
    127158    InnerNode *parent() const { return par; }
    128159    InnerNode *relates() const { return rel; }
     
    131162    QString moduleName() const;
    132163    QString url() const;
     164    virtual QString nameForLists() const { return nam; }
    133165
    134166    Access access() const { return acc; }
     
    144176    void clearRelated() { rel = 0; }
    145177
    146     QString fileBase() const;
     178    virtual QString fileBase() const;
    147179
    148180 protected:
     
    150182
    151183 private:
     184
    152185#ifdef Q_WS_WIN
    153186    Type typ;
     
    181214{
    182215 public:
    183     ~InnerNode();
     216    virtual ~InnerNode();
    184217
    185218    Node *findNode(const QString& name);
     
    203236    const NodeList & childNodes() const { return children; }
    204237    const NodeList & relatedNodes() const { return related; }
     238    int count() const { return children.size(); }
    205239    int overloadNumber(const FunctionNode *func) const;
    206240    int numOverloads(const QString& funcName) const;
    207241    NodeList overloads(const QString &funcName) const;
    208242    const QStringList& includes() const { return inc; }
     243
     244    QStringList primaryKeys();
     245    QStringList secondaryKeys();
    209246
    210247 protected:
     
    232269 public:
    233270    LeafNode();
     271    virtual ~LeafNode() { }
    234272
    235273    virtual bool isInnerNode() const;
    236274
    237275 protected:
    238     LeafNode(Type type, InnerNode *parent, const QString& name);
     276    LeafNode(Type type, InnerNode* parent, const QString& name);
    239277};
    240278
     
    243281 public:
    244282    NamespaceNode(InnerNode *parent, const QString& name);
     283    virtual ~NamespaceNode() { }
    245284};
    246285
     
    266305 public:
    267306    ClassNode(InnerNode *parent, const QString& name);
     307    virtual ~ClassNode() { }
    268308
    269309    void addBaseClass(Access access,
     
    280320    QString serviceName() const { return sname; }
    281321    void setServiceName(const QString& value) { sname = value; }
     322    QString qmlElement() const { return qmlelement; }
     323    void setQmlElement(const QString& value) { qmlelement = value; }
    282324
    283325 private:
     
    286328    bool hidden;
    287329    QString sname;
     330    QString qmlelement;
    288331};
    289332
     
    291334{
    292335 public:
    293     enum SubType {
    294         Example,
    295         HeaderFile,
    296         File,
    297         Group,
    298         Module,
    299         Page,
    300         ExternalPage,
    301         QmlClass
    302     };
    303336
    304337    FakeNode(InnerNode *parent, const QString& name, SubType subType);
     338    virtual ~FakeNode() { }
    305339
    306340    void setTitle(const QString &title) { tle = title; }
     
    313347    QString subTitle() const;
    314348    const NodeList &groupMembers() const { return gr; }
     349    virtual QString nameForLists() const { return title(); }
    315350
    316351 private:
     
    321356};
    322357
    323 class QmlNode : public FakeNode
    324 {
    325  public:
    326     QmlNode(InnerNode *parent, const QString& name, const ClassNode* cn)
    327         : FakeNode(parent, name, QmlClass), cnode(cn) { }
     358#ifdef QDOC_QML
     359class QmlClassNode : public FakeNode
     360{
     361 public:
     362    QmlClassNode(InnerNode *parent,
     363                 const QString& name,
     364                 const ClassNode* cn);
     365    virtual ~QmlClassNode() { }
    328366
    329367    const ClassNode* classNode() const { return cnode; }
     368    virtual QString fileBase() const;
     369
     370    static bool qmlOnly;
    330371
    331372 private:
    332373    const ClassNode* cnode;
    333374};
     375
     376class QmlPropGroupNode : public FakeNode
     377{
     378 public:
     379    QmlPropGroupNode(QmlClassNode* parent,
     380                     const QString& name,
     381                     bool attached);
     382    virtual ~QmlPropGroupNode() { }
     383
     384    const QString& element() const { return parent()->name(); }
     385    void setDefault() { isdefault = true; }
     386    bool isDefault() const { return isdefault; }
     387    bool isAttached() const { return att; }
     388
     389 private:
     390    bool    isdefault;
     391    bool    att;
     392};
     393
     394class QmlPropertyNode : public LeafNode
     395{
     396 public:
     397    QmlPropertyNode(QmlPropGroupNode* parent,
     398                    const QString& name,
     399                    const QString& type,
     400                    bool attached);
     401    virtual ~QmlPropertyNode() { }
     402
     403    void setDataType(const QString& dataType) { dt = dataType; }
     404    void setStored(bool stored) { sto = toTrool(stored); }
     405    void setDesignable(bool designable) { des = toTrool(designable); }
     406    void setWritable(bool writable) { wri = toTrool(writable); }
     407
     408    const QString &dataType() const { return dt; }
     409    QString qualifiedDataType() const { return dt; }
     410    bool isStored() const { return fromTrool(sto,true); }
     411    bool isDesignable() const { return fromTrool(des,false); }
     412    bool isWritable() const { return fromTrool(wri,true); }
     413    bool isAttached() const { return att; }
     414
     415    const QString& element() const { return static_cast<QmlPropGroupNode*>(parent())->element(); }
     416
     417 private:
     418    enum Trool { Trool_True, Trool_False, Trool_Default };
     419
     420    static Trool toTrool(bool boolean);
     421    static bool fromTrool(Trool troolean, bool defaultValue);
     422
     423    QString dt;
     424    Trool   sto;
     425    Trool   des;
     426    Trool   wri;
     427    bool    att;
     428};
     429#endif
    334430
    335431class EnumItem
     
    358454 public:
    359455    EnumNode(InnerNode *parent, const QString& name);
     456    virtual ~EnumNode() { }
    360457
    361458    void addItem(const EnumItem& item);
     
    378475 public:
    379476    TypedefNode(InnerNode *parent, const QString& name);
     477    virtual ~TypedefNode() { }
    380478
    381479    const EnumNode *associatedEnum() const { return ae; }
     
    400498 public:
    401499    Parameter() {}
    402     Parameter(const QString& leftType, const QString& rightType = "",
    403                const QString& name = "", const QString& defaultValue = "");
     500    Parameter(const QString& leftType,
     501              const QString& rightType = "",
     502              const QString& name = "",
     503              const QString& defaultValue = "");
    404504    Parameter(const Parameter& p);
    405505
     
    413513    const QString& name() const { return nam; }
    414514    const QString& defaultValue() const { return def; }
     515
     516    QString reconstruct(bool value = false) const;
    415517
    416518 private:
     
    438540
    439541    FunctionNode(InnerNode *parent, const QString &name);
     542    FunctionNode(Type type, InnerNode *parent, const QString &name, bool attached);
     543    virtual ~FunctionNode() { }
    440544
    441545    void setReturnType(const QString& returnType) { rt = returnType; }
     546    void setParentPath(const QStringList& parentPath) { pp = parentPath; }
    442547    void setMetaness(Metaness metaness) { met = metaness; }
    443548    void setVirtualness(Virtualness virtualness) { vir = virtualness; }
     
    445550    void setStatic(bool statique) { sta = statique; }
    446551    void setOverload(bool overlode);
     552    void setReimp(bool r);
    447553    void addParameter(const Parameter& parameter);
    448554    inline void setParameters(const QList<Parameter>& parameters);
     
    459565    bool isStatic() const { return sta; }
    460566    bool isOverload() const { return ove; }
     567    bool isReimp() const { return reimp; }
     568    bool isFunction() const { return true; }
    461569    int overloadNumber() const;
    462570    int numOverloads() const;
     
    466574    const QList<FunctionNode *> &reimplementedBy() const { return rb; }
    467575    const PropertyNode *associatedProperty() const { return ap; }
     576    const QStringList& parentPath() const { return pp; }
     577
     578    QStringList reconstructParams(bool values = false) const;
     579    QString signature(bool values = false) const;
     580    const QString& element() const { return parent()->name(); }
     581    bool isAttached() const { return att; }
     582
     583    void debug() const;
    468584
    469585 private:
     
    473589    friend class PropertyNode;
    474590
    475     QString rt;
     591    QString     rt;
     592    QStringList pp;
    476593#ifdef Q_WS_WIN
    477     Metaness met;
     594    Metaness    met;
    478595    Virtualness vir;
    479596#else
     
    484601    bool sta : 1;
    485602    bool ove : 1;
     603    bool reimp: 1;
     604    bool att: 1;
    486605    QList<Parameter> params;
    487606    const FunctionNode *rf;
     
    493612{
    494613 public:
    495     enum FunctionRole { Getter, Setter, Resetter };
    496     enum { NumFunctionRoles = Resetter + 1 };
     614    enum FunctionRole { Getter, Setter, Resetter, Notifier };
     615    enum { NumFunctionRoles = Notifier + 1 };
    497616
    498617    PropertyNode(InnerNode *parent, const QString& name);
     618    virtual ~PropertyNode() { }
    499619
    500620    void setDataType(const QString& dataType) { dt = dataType; }
    501621    void addFunction(FunctionNode *function, FunctionRole role);
     622    void addSignal(FunctionNode *function, FunctionRole role);
    502623    void setStored(bool stored) { sto = toTrool(stored); }
    503624    void setDesignable(bool designable) { des = toTrool(designable); }
     625    void setWritable(bool writable) { wri = toTrool(writable); }
    504626    void setOverriddenFrom(const PropertyNode *baseProperty);
    505627
     
    511633    NodeList setters() const { return functions(Setter); }
    512634    NodeList resetters() const { return functions(Resetter); }
     635    NodeList notifiers() const { return functions(Notifier); }
    513636    bool isStored() const { return fromTrool(sto, storedDefault()); }
    514637    bool isDesignable() const { return fromTrool(des, designableDefault()); }
     638    bool isWritable() const { return fromTrool(wri, writableDefault()); }
    515639    const PropertyNode *overriddenFrom() const { return overrides; }
    516640
     
    523647    bool storedDefault() const { return true; }
    524648    bool designableDefault() const { return !setters().isEmpty(); }
     649    bool writableDefault() const { return !setters().isEmpty(); }
    525650
    526651    QString dt;
     
    528653    Trool sto;
    529654    Trool des;
     655    Trool wri;
    530656    const PropertyNode *overrides;
    531657};
     
    540666    funcs[(int)role].append(function);
    541667    function->setAssociatedProperty(this);
     668}
     669
     670inline void PropertyNode::addSignal(FunctionNode *function, FunctionRole role)
     671{
     672    funcs[(int)role].append(function);
    542673}
    543674
     
    554685 public:
    555686    VariableNode(InnerNode *parent, const QString &name);
     687    virtual ~VariableNode() { }
    556688
    557689    void setLeftType(const QString &leftType) { lt = leftType; }
     
    579711 public:
    580712    TargetNode(InnerNode *parent, const QString& name);
     713    virtual ~TargetNode() { }
    581714
    582715    virtual bool isInnerNode() const;
  • trunk/tools/qdoc3/openedlist.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/openedlist.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/pagegenerator.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    8484    else if (!node->isInnerNode())
    8585        node = node->parent();
     86#ifdef QDOC_QML
     87    if (node->subType() == Node::QmlPropertyGroup) {
     88        node = node->parent();
     89    }
     90#endif       
    8691
    8792    QString base = node->doc().baseName();
     
    8994        return base;
    9095
    91         const Node *p = node;
    92 
    93         forever {
    94             base.prepend(p->name());
     96    const Node *p = node;
     97
     98    forever {
    9599        const Node *pp = p->parent();
     100        base.prepend(p->name());
     101#ifdef QDOC_QML
     102        /*
     103          To avoid file name conflicts in the html directory,
     104          we prepend "qml-" to the file name of QML element doc
     105          files.
     106         */
     107        if (p->subType() == Node::QmlClass) {
     108            base.prepend("qml-");
     109        }
     110#endif       
    96111        if (!pp || pp->name().isEmpty() || pp->type() == Node::Fake)
    97                 break;
     112            break;
    98113        base.prepend(QLatin1Char('-'));
    99114        p = pp;
    100         }
    101 
    102         if (node->type() == Node::Fake) {
     115    }
     116   
     117    if (node->type() == Node::Fake) {
    103118#ifdef QDOC2_COMPAT
    104             if (base.endsWith(".html"))
    105                 base.truncate(base.length() - 5);
     119        if (base.endsWith(".html"))
     120            base.truncate(base.length() - 5);
    106121#endif
    107         }
     122    }
    108123
    109124    // the code below is effectively equivalent to:
     
    127142            res += QLatin1Char(u);
    128143            begun = true;
    129         } else if (begun) {
     144        }
     145        else if (begun) {
    130146            res += QLatin1Char('-');
    131147            begun = false;
     
    188204    if (node->type() == Node::Fake) {
    189205        const FakeNode *fakeNode = static_cast<const FakeNode *>(node);
    190         if (fakeNode->subType() == FakeNode::ExternalPage)
     206        if (fakeNode->subType() == Node::ExternalPage)
    191207            return;
     208#ifdef QDOC_QML           
     209        if (fakeNode->subType() == Node::QmlPropertyGroup)
     210            return;
     211#endif           
    192212    }
    193213
     
    198218        }
    199219        else if (node->type() == Node::Fake) {
    200             const FakeNode* fakeNode = static_cast<const FakeNode *>(node);
    201 #ifdef QDOC_QML           
    202             if (fakeNode->subType() == FakeNode::QmlClass) {
    203                 //qDebug() << "FILENAME:" << fileName(node);
    204             }
    205 #endif           
    206220            generateFakeNode(static_cast<const FakeNode *>(node), marker);
    207221        }
  • trunk/tools/qdoc3/pagegenerator.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/plaincodemarker.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/plaincodemarker.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/polyarchiveextractor.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/polyarchiveextractor.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/polyuncompressor.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/polyuncompressor.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/qdoc3.pro

    r2 r561  
    11DEFINES += QDOC2_COMPAT
    2 #DEFINES += QT_NO_CAST_TO_ASCII
     2DEFINES += QT_NO_CAST_TO_ASCII
    33#DEFINES += QT_NO_CAST_FROM_ASCII
     4#DEFINES += QT_USE_FAST_OPERATOR_PLUS
     5#DEFINES += QT_USE_FAST_CONCATENATION
    46
    57QT = core xml
    68CONFIG += console
     9CONFIG -= debug_and_release_target
     10!isEmpty(QT_BUILD_TREE):DESTDIR = $$QT_BUILD_TREE/bin
     11#CONFIG += debug
    712build_all:!build_pass {
    813    CONFIG -= build_all
    914    CONFIG += release
     15#    CONFIG += debug
    1016}
    1117mac:CONFIG -= app_bundle
     
    100106           yyindent.cpp
    101107
    102 
    103 win32 {
    104     QT_WINCONFIG = release
    105     CONFIG(debug, debug|release) {
    106         QT_WINCONFIG = debug
    107     }   
    108 }
     108target.path = $$[QT_INSTALL_BINS]
     109INSTALLS += target
  • trunk/tools/qdoc3/qsakernelparser.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/qsakernelparser.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/qscodemarker.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/qscodemarker.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/qscodeparser.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/qscodeparser.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/quoter.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/quoter.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/separator.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    4949QT_BEGIN_NAMESPACE
    5050
    51 QString separator( int index, int count )
     51QString separator(int index, int count)
    5252{
    53     if ( index == count - 1 )
    54         return tr( ".", "terminator" );
     53    if (index == count - 1)
     54        return tr(".", "terminator");
     55    if (count == 2)
     56        return tr(" and ", "separator when N = 2");
     57    if (index == 0)
     58        return tr(", ", "first separator when N > 2");
     59    if (index < count - 2)
     60        return tr(", ", "general separator when N > 2");
     61    return tr(", and ", "last separator when N > 2");
     62}
    5563
    56     if ( count == 2 ) {
    57         return tr( " and ", "separator when N = 2" );
    58     } else {
    59         if ( index == 0 ) {
    60             return tr( ", ", "first separator when N > 2" );
    61         } else if ( index < count - 2 ) {
    62             return tr( ", ", "general separator when N > 2" );
    63         } else {
    64             return tr( ", and ", "last separator when N > 2" );
    65         }
    66     }
     64QString comma(int index, int count)
     65{
     66    if (index == count - 1)
     67        return QString("");
     68    if (count == 2)
     69        return tr(" and ", "separator when N = 2");
     70    if (index == 0)
     71        return tr(", ", "first separator when N > 2");
     72    if (index < count - 2)
     73        return tr(", ", "general separator when N > 2");
     74    return tr(", and ", "last separator when N > 2");
    6775}
    6876
  • trunk/tools/qdoc3/separator.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    5252
    5353QString separator( int index, int count );
     54QString comma( int index, int count );
    5455
    5556QT_END_NAMESPACE
  • trunk/tools/qdoc3/sgmlgenerator.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/sgmlgenerator.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/test/assistant.qdocconf

    r2 r561  
    77project                 = Qt Assistant
    88description             = Qt Assistant Manual
    9 url                     = http://doc.trolltech.com/4.5
     9url                     = http://qt.nokia.com/doc/4.6
    1010
    1111indexes                 = $QT_BUILD_TREE/doc-build/html-qt/qt.index
     
    1414
    1515qhp.Assistant.file                = assistant.qhp
    16 qhp.Assistant.namespace           = com.trolltech.assistant.451
     16qhp.Assistant.namespace           = com.trolltech.assistant.460
    1717qhp.Assistant.virtualFolder       = qdoc
    1818qhp.Assistant.indexTitle          = Qt Assistant Manual
    1919qhp.Assistant.extraFiles          = classic.css images/qt-logo.png images/trolltech-logo.png
    20 qhp.Assistant.filterAttributes    = qt 4.5.1 tools assistant
     20qhp.Assistant.filterAttributes    = qt 4.6.1 tools assistant
    2121qhp.Assistant.customFilters.Assistant.name = Qt Assistant Manual
    2222qhp.Assistant.customFilters.Assistant.filterAttributes = qt tools assistant
     
    3232language                = Cpp
    3333
    34 sources                 = $QT_SOURCE_TREE/doc/src/assistant-manual.qdoc \
     34sources                 = $QT_SOURCE_TREE/doc/src/development/assistant-manual.qdoc \
    3535                          $QT_SOURCE_TREE/doc/src/examples/simpletextviewer.qdoc
    3636
  • trunk/tools/qdoc3/test/carbide-eclipse-integration.qdocconf

    r2 r561  
    77HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \
    88              "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \
    9               "<td width=\"40%\" align="left">Copyright &copy; 2009 <a href=\"http://doc.trolltech.com/trolltech.html\">Nokia Corporation</a></td>\n" \
    10               "<td width=\"30%\" align=\"center\"><a href=\"http://doc.trolltech.com\">Trademarks</a></td>\n" \
    11               "<td width=\"40%\" align=\"right\"><div align=\"right\">Carbide.c++</div></td>\n" \
     9              "<td width=\"30%\" align=\"left\">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies)</td>\n" \
     10              "<td width=\"40%\" align=\"center\"><a href=\"http://qt.nokia.com/doc\">Trademarks</a></td>\n" \
     11              "<td width=\"30%\" align=\"right\"><div align=\"right\">Carbide.c++</div></td>\n" \
    1212              "</tr></table></div></address>"
  • trunk/tools/qdoc3/test/classic.css

    r2 r561  
     1BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
     2  font-family: Arial, Geneva, Helvetica, sans-serif;
     3}
     4H1 {
     5  text-align: center;
     6  font-size: 160%;
     7}
     8H2 {
     9  font-size: 120%;
     10}
     11H3 {
     12  font-size: 100%;
     13}
     14
    115h3.fn,span.fn
    216{
    3   margin-left: 1cm;
    4   text-indent: -1cm;
     17  background-color: #eee;
     18  border-width: 1px;
     19  border-style: solid;
     20  border-color: #ddd;
     21  font-weight: bold;
     22  padding: 6px 0px 6px 10px;
     23  margin: 42px 0px 0px 0px;
     24}
     25
     26hr {
     27  border: 0;
     28  color: #a0a0a0;
     29  background-color: #ccc;
     30  height: 1px;
     31  width: 100%;
     32  text-align: left;
     33  margin: 34px 0px 34px 0px;
     34}
     35
     36table.valuelist {
     37        border-width: 1px 1px 1px 1px;
     38        border-style: solid;
     39        border-color: #dddddd;
     40        border-collapse: collapse;
     41        background-color: #f0f0f0;
     42}
     43
     44table.indextable {
     45        border-width: 1px 1px 1px 1px;
     46        border-style: solid;
     47        border-collapse: collapse;
     48        background-color: #f0f0f0;
     49    border-color:#555;
     50    font-size: 100%;
     51}
     52
     53table td.largeindex {
     54        border-width: 1px 1px 1px 1px;
     55        border-collapse: collapse;
     56        background-color: #f0f0f0;
     57    border-color:#555;
     58    font-size: 120%;
     59}
     60
     61table.valuelist th {
     62        border-width: 1px 1px 1px 2px;
     63        padding: 4px;
     64        border-style: solid;
     65        border-color: #666;
     66    color:white;
     67    background-color:#666;
     68}
     69
     70th.titleheader  {
     71        border-width: 1px 0px 1px 0px;
     72        padding: 2px;
     73        border-style: solid;
     74        border-color: #666;
     75    color:white;
     76    background-color:#555;
     77    background-image:url('images/gradient.png')};
     78    background-repeat: repeat-x;
     79    font-size: 100%;
     80}
     81
     82
     83th.largeheader {
     84        border-width: 1px 0px 1px 0px;
     85        padding: 4px;
     86        border-style: solid;
     87        border-color: #444;
     88    color:white;
     89    background-color:#555555;
     90    font-size: 120%;
     91}
     92
     93p {
     94
     95  margin-left: 4px;
     96  margin-top: 8px;
     97  margin-bottom: 8px;
    598}
    699
    7100a:link
    8101{
    9   color: #004faf;
     102  color: #0046ad;
    10103  text-decoration: none
    11104}
     
    41134}
    42135
    43 td.postheader
    44 {
    45   font-family: sans-serif
    46 }
    47 
    48 tr.address
    49 {
    50   font-family: sans-serif
    51 }
    52 
    53136body
    54137{
    55138  background: #ffffff;
    56139  color: black
     140}
     141
     142table.generic, table.annotated
     143{
     144  border-width: 1px;
     145  border-color:#bbb;
     146  border-style:solid; 
     147  border-collapse:collapse;
     148}
     149
     150table td.memItemLeft {
     151  width: 180px;
     152  padding: 2px 0px 0px 8px;
     153  margin: 4px;
     154  border-width: 1px;
     155  border-color: #E0E0E0;
     156  border-style: none;
     157  font-size: 100%;
     158  white-space: nowrap
     159}
     160
     161table td.memItemRight {
     162  padding: 2px 8px 0px 8px;
     163  margin: 4px;
     164  border-width: 1px;
     165  border-color: #E0E0E0;
     166  border-style: none;
     167  font-size: 100%;
    57168}
    58169
     
    78189table tr pre
    79190{
    80   padding-top: none;
    81   padding-bottom: none;
    82   padding-left: none;
    83   padding-right: none;
     191  padding-top: 0px;
     192  padding-bottom: 0px;
     193  padding-left: 0px;
     194  padding-right: 0px;
    84195  border: none;
    85196  background: none
     
    138249    font-size: 0.65em
    139250}
     251
     252.qmlitem {
     253    padding: 0;
     254}
     255
     256.qmlname {
     257    white-space: nowrap;
     258}
     259
     260.qmltype {
     261    text-align: center;
     262    font-size: 160%;
     263}
     264
     265.qmlproto {
     266    background-color: #eee;
     267    border-width: 1px;
     268    border-style: solid;
     269    border-color: #ddd;
     270    font-weight: bold;
     271    padding: 6px 10px 6px 10px;
     272    margin: 42px 0px 0px 0px;
     273}
     274
     275.qmlreadonly {
     276    float: right;
     277    color: red
     278}
     279
     280.qmldoc {
     281}
     282
     283*.qmlitem p {
     284}
  • trunk/tools/qdoc3/test/designer.qdocconf

    r2 r561  
    77project                 = Qt Designer
    88description             = Qt Designer Manual
    9 url                     = http://doc.trolltech.com/4.5
     9url                     = http://qt.nokia.com/doc/4.6
    1010
    1111indexes                 = $QT_BUILD_TREE/doc-build/html-qt/qt.index
     
    1414
    1515qhp.Designer.file                = designer.qhp
    16 qhp.Designer.namespace           = com.trolltech.designer.451
     16qhp.Designer.namespace           = com.trolltech.designer.460
    1717qhp.Designer.virtualFolder       = qdoc
    1818qhp.Designer.indexTitle          = Qt Designer Manual
    1919qhp.Designer.extraFiles          = classic.css images/qt-logo.png images/trolltech-logo.png
    20 qhp.Designer.filterAttributes    = qt 4.5.1 tools designer
     20qhp.Designer.filterAttributes    = qt 4.6.1 tools designer
    2121qhp.Designer.customFilters.Designer.name = Qt Designer Manual
    2222qhp.Designer.customFilters.Designer.filterAttributes = qt tools designer
     
    3232language                = Cpp
    3333
    34 sources                 = $QT_SOURCE_TREE/doc/src/designer-manual.qdoc \
     34sources                 = $QT_SOURCE_TREE/doc/src/development/designer-manual.qdoc \
    3535                          $QT_SOURCE_TREE/doc/src/examples/calculatorbuilder.qdoc \
    3636                          $QT_SOURCE_TREE/doc/src/examples/calculatorform.qdoc \
  • trunk/tools/qdoc3/test/eclipse-integration.qdocconf

    r2 r561  
    33headerdirs =
    44sourcedirs =
    5 sourcedirs = $QTDIR/../qteclipsetools/main/doc
    6 imagedirs = $QTDIR/../qteclipsetools/main/doc
    7 outputdir = $QTDIR/../qteclipsetools/main/doc/html
     5sourcedirs = $QTDIR/../qteclipsetools/eclipse_patched/doc
     6imagedirs = $QTDIR/../qteclipsetools/eclipse_patched/doc
     7outputdir = $QTDIR/../qteclipsetools/eclipse_patched/doc/html
    88
    99project               = Qt Eclipse Integration
    1010description           = "Qt Eclipse Integration"
    11 url                   = http://doc.trolltech.com/eclipse-integration-4.4
     11url                   = http://qt.nokia.com/doc/qt-eclipse-1.5
    1212
    1313HTML.{postheader,address} = ""
  • trunk/tools/qdoc3/test/jambi.qdocconf

    r2 r561  
    44project                 = Qt Jambi
    55description             = Qt Jambi Reference Documentation
    6 url                     = http://doc.trolltech.com/qtjambi
     6url                     = http://qt.nokia.com/doc/qtjambi
    77
    88version                 = 4.4.0_01
     
    4242HTML.footer             = "<p /><address><hr /><div align=\"center\">\n" \
    4343                          "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \
    44                           "<td width=\"30%\">Copyright &copy; \$THISYEAR\$ <a href=\"trolltech.html\">Trolltech</a></td>\n" \
     44                          "<td width=\"30%\" align=\"left\">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies)</td>\n" \
    4545                          "<td width=\"40%\" align=\"center\"><a href=\"trademarks.html\">Trademarks</a></td>\n" \
    4646                          "<td width=\"30%\" align=\"right\"><div align=\"right\">Qt Jambi \\version</div></td>\n" \
  • trunk/tools/qdoc3/test/linguist.qdocconf

    r2 r561  
    77project                 = Qt Linguist
    88description             = Qt Linguist Manual
    9 url                     = http://doc.trolltech.com/4.5
     9url                     = http://qt.nokia.com/doc/4.6
    1010
    1111indexes                 = $QT_BUILD_TREE/doc-build/html-qt/qt.index
     
    1414
    1515qhp.Linguist.file                = linguist.qhp
    16 qhp.Linguist.namespace           = com.trolltech.linguist.451
     16qhp.Linguist.namespace           = com.trolltech.linguist.460
    1717qhp.Linguist.virtualFolder       = qdoc
    1818qhp.Linguist.indexTitle          = Qt Linguist Manual
    1919qhp.Linguist.extraFiles          = classic.css images/qt-logo.png images/trolltech-logo.png
    20 qhp.Linguist.filterAttributes    = qt 4.5.1 tools linguist
     20qhp.Linguist.filterAttributes    = qt 4.6.1 tools linguist
    2121qhp.Linguist.customFilters.Linguist.name = Qt Linguist Manual
    2222qhp.Linguist.customFilters.Linguist.filterAttributes = qt tools linguist
     
    3232language                = Cpp
    3333
    34 sources                 = $QT_SOURCE_TREE/doc/src/linguist-manual.qdoc \
     34sources                 = $QT_SOURCE_TREE/doc/src/internationalization/linguist-manual.qdoc \
    3535                          $QT_SOURCE_TREE/doc/src/examples/hellotr.qdoc \
    3636                          $QT_SOURCE_TREE/doc/src/examples/arrowpad.qdoc \
  • trunk/tools/qdoc3/test/macros.qdocconf

    r2 r561  
     1macro.aacute.HTML       = "&aacute;"
    12macro.Aring.HTML        = "&Aring;"
    23macro.aring.HTML        = "&aring;"
     
    56macro.br.HTML           = "<br />"
    67macro.BR.HTML           = "<br />"
    7 macro.aacute.HTML       = "&aacute;"
     8macro.copyright.HTML    = "&copy;"
    89macro.eacute.HTML       = "&eacute;"
    9 macro.iacute.HTML       = "&iacute;"
    1010macro.gui               = "\\bold"
    1111macro.hr.HTML           = "<hr />"
     12macro.iacute.HTML       = "&iacute;"
    1213macro.key               = "\\bold"
    1314macro.menu              = "\\bold"
     
    2829macro.uuml.HTML         = "&uuml;"
    2930macro.mdash.HTML        = "&mdash;"
     31
     32macro.beginfloatleft.HTML   = "<div style=\"float: left; margin-right: 2em\">"
     33macro.beginfloatright.HTML  = "<div style=\"float: right; margin-left: 2em\">"
     34macro.endfloat.HTML         = "</div>"
     35macro.clearfloat.HTML       = "<div style=\"clear: both\">"
  • trunk/tools/qdoc3/test/qmake.qdocconf

    r2 r561  
    77project                 = QMake
    88description             = QMake Manual
    9 url                     = http://doc.trolltech.com/4.5
     9url                     = http://qt.nokia.com/doc/4.6
    1010
    1111indexes                 = $QT_BUILD_TREE/doc-build/html-qt/qt.index
     
    1414
    1515qhp.qmake.file                = qmake.qhp
    16 qhp.qmake.namespace           = com.trolltech.qmake.451
     16qhp.qmake.namespace           = com.trolltech.qmake.460
    1717qhp.qmake.virtualFolder       = qdoc
    1818qhp.qmake.indexTitle          = QMake Manual
    1919qhp.qmake.extraFiles          = classic.css images/qt-logo.png images/trolltech-logo.png
    20 qhp.qmake.filterAttributes    = qt 4.5.1 tools qmake
     20qhp.qmake.filterAttributes    = qt 4.6.1 tools qmake
    2121qhp.qmake.customFilters.qmake.name = qmake Manual
    2222qhp.qmake.customFilters.qmake.filterAttributes = qt tools qmake
     
    2828language                = Cpp
    2929
    30 sources                 = $QT_SOURCE_TREE/doc/src/qmake-manual.qdoc
     30sources                 = $QT_SOURCE_TREE/doc/src/development/qmake-manual.qdoc
    3131
    3232sources.fileextensions  = "*.cpp *.qdoc"
  • trunk/tools/qdoc3/test/qt-api-only.qdocconf

    r2 r561  
    1010# .qhp file.
    1111
    12 qhp.Qt.excluded  += $QT_SOURCE_TREE/doc/src/assistant-manual.qdoc \
     12qhp.Qt.excluded  += $QT_SOURCE_TREE/doc/src/development/assistant-manual.qdoc \
    1313                    $QT_SOURCE_TREE/doc/src/examples/simpletextviewer.qdoc \
    14                     $QT_SOURCE_TREE/doc/src/designer-manual.qdoc \
     14                    $QT_SOURCE_TREE/doc/src/development/designer-manual.qdoc \
    1515                    $QT_SOURCE_TREE/doc/src/examples/calculatorbuilder.qdoc \
    1616                    $QT_SOURCE_TREE/doc/src/examples/calculatorform.qdoc \
     
    2020                    $QT_SOURCE_TREE/doc/src/examples/worldtimeclockbuilder.qdoc \
    2121                    $QT_SOURCE_TREE/doc/src/examples/worldtimeclockplugin.qdoc \
    22                     $QT_SOURCE_TREE/doc/src/linguist-manual.qdoc \
     22                    $QT_SOURCE_TREE/doc/src/internationalization/linguist-manual.qdoc \
    2323                    $QT_SOURCE_TREE/doc/src/examples/hellotr.qdoc \
    2424                    $QT_SOURCE_TREE/doc/src/examples/arrowpad.qdoc \
    2525                    $QT_SOURCE_TREE/doc/src/examples/trollprint.qdoc \
    26                     $QT_SOURCE_TREE/doc/src/qmake-manual.qdoc
     26                    $QT_SOURCE_TREE/doc/src/development/qmake-manual.qdoc
    2727
    2828outputdir         = $QT_BUILD_TREE/doc-build/html-qt
  • trunk/tools/qdoc3/test/qt-build-docs.qdocconf

    r2 r561  
    77project                 = Qt
    88description             = Qt Reference Documentation
    9 url                     = http://doc.trolltech.com/4.5
     9url                     = http://qt.nokia.com/doc/4.6
    1010
    11 edition.Console.modules = QtCore QtDBus QtNetwork QtScript QtSql QtXml \
    12                           QtXmlPatterns QtTest
    13 edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript QtSql QtSvg \
     11edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript QtScriptTools QtSql QtSvg \
    1412                          QtWebKit QtXml QtXmlPatterns Qt3Support QtHelp \
    1513                          QtDesigner QtAssistant QAxContainer Phonon \
     
    2119
    2220qhp.Qt.file                = qt.qhp
    23 qhp.Qt.namespace           = com.trolltech.qt.451
     21qhp.Qt.namespace           = com.trolltech.qt.460
    2422qhp.Qt.virtualFolder       = qdoc
    2523qhp.Qt.indexTitle          = Qt Reference Documentation
     
    3028qhp.Qt.extraFiles          = classic.css \
    3129                             images/qt-logo.png \
    32                              images/trolltech-logo \
    3330                             images/taskmenuextension-example.png \
    3431                             images/coloreditorfactoryimage.png \
     
    3633                             images/stylesheet-coffee-plastique.png
    3734
    38 qhp.Qt.filterAttributes    = qt 4.5.1 qtrefdoc
    39 qhp.Qt.customFilters.Qt.name = Qt 4.5.1
    40 qhp.Qt.customFilters.Qt.filterAttributes = qt 4.5.1
     35qhp.Qt.filterAttributes    = qt 4.6.1 qtrefdoc
     36qhp.Qt.customFilters.Qt.name = Qt 4.6.1
     37qhp.Qt.customFilters.Qt.filterAttributes = qt 4.6.1
    4138qhp.Qt.subprojects         = classes overviews examples
    4239qhp.Qt.subprojects.classes.title = Classes
     
    10198sources.fileextensions  = "*.cpp *.qdoc *.mm"
    10299examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp"
     100examples.imageextensions = "*.png"
    103101
    104102exampledirs             = $QT_SOURCE_TREE/doc/src \
     
    106104                          $QT_SOURCE_TREE/examples/tutorials \
    107105                          $QT_SOURCE_TREE \
    108                           $QT_SOURCE_TREE/qmake/examples
     106                          $QT_SOURCE_TREE/qmake/examples \
     107                          $QT_SOURCE_TREE/src/3rdparty/webkit/WebKit/qt/docs
    109108imagedirs               = $QT_SOURCE_TREE/doc/src/images \
    110109                          $QT_SOURCE_TREE/examples
     
    112111tagfile                 = $QT_BUILD_TREE/doc/html/qt.tags
    113112base                    = file:$QT_BUILD_TREE/doc/html
     113
     114HTML.generatemacrefs    = "true"
  • trunk/tools/qdoc3/test/qt-cpp-ignore.qdocconf

    r2 r561  
    1313                          QM_EXPORT_NETWORK \
    1414                          QM_EXPORT_OPENGL \
     15                          QM_EXPORT_OPENVG \
    1516                          QM_EXPORT_SQL \
    1617                          QM_EXPORT_TABLE \
     
    2627                          Q_COMPAT_EXPORT \
    2728                          Q_CORE_EXPORT \
     29                          Q_CORE_EXPORT_INLINE \
    2830                          Q_EXPLICIT \
    2931                          Q_EXPORT \
     
    5153                          Q_NETWORK_EXPORT \
    5254                          Q_OPENGL_EXPORT \
     55                          Q_OPENVG_EXPORT \
    5356                          Q_OUTOFLINE_TEMPLATE \
    5457                          Q_SQL_EXPORT \
     
    6669                          QT_END_NAMESPACE \
    6770                          QT_END_INCLUDE_NAMESPACE \
    68                           PHONON_EXPORT
     71                          PHONON_EXPORT \
     72                          Q_DECLARATIVE_EXPORT \
     73                          Q_GADGET \
     74                          QWEBKIT_EXPORT
    6975Cpp.ignoredirectives    = Q_DECLARE_HANDLE \
    7076                          Q_DECLARE_INTERFACE \
  • trunk/tools/qdoc3/test/qt-html-templates.qdocconf

    r2 r561  
    33                          "<tr>\n" \
    44                          "<td align=\"left\" valign=\"top\" width=\"32\">" \
    5                           "<a href=\"http://qtsoftware.com/products/qt\"><img src=\"images/qt-logo.png\" align=\"left\" border=\"0\" /></a>" \
     5                          "<a href=\"http://qt.nokia.com/\"><img src=\"images/qt-logo.png\" align=\"left\" border=\"0\" /></a>" \
    66                          "</td>\n" \
    77                          "<td width=\"1\">&nbsp;&nbsp;</td>" \
     
    99                          "<a href=\"index.html\">" \
    1010                          "<font color=\"#004faf\">Home</font></a>&nbsp;&middot;" \
    11                           " <a href=\"namespaces.html\">" \
    12                           "<font color=\"#004faf\">All&nbsp;Namespaces</font></a>&nbsp;&middot;" \
    1311                          " <a href=\"classes.html\">" \
    1412                          "<font color=\"#004faf\">All&nbsp;Classes</font></a>&nbsp;&middot;" \
    15                           " <a href=\"mainclasses.html\">" \
    16                           "<font color=\"#004faf\">Main&nbsp;Classes</font></a>&nbsp;&middot;" \
    17                           " <a href=\"groups.html\">" \
    18                           "<font color=\"#004faf\">Grouped&nbsp;Classes</font></a>&nbsp;&middot;" \
    19                           " <a href=\"modules.html\">" \
    20                           "<font color=\"#004faf\">Modules</font></a>&nbsp;&middot;" \
    2113                          " <a href=\"functions.html\">" \
    22                           "<font color=\"#004faf\">Functions</font></a>" \
    23                           "</td>\n" \
    24                           "<td align=\"right\" valign=\"top\" width=\"230\"></td></tr></table>"
     14                          "<font color=\"#004faf\">All&nbsp;Functions</font></a>&nbsp;&middot;" \
     15                          " <a href=\"overviews.html\">" \
     16                          "<font color=\"#004faf\">Overviews</font></a>" \
     17                          "</td>" \
     18                          "</tr></table>"
    2519
    2620HTML.footer             = "<p /><address><hr /><div align=\"center\">\n" \
    2721                          "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \
    28                           "<td width=\"30%\" align=\"left\">Copyright &copy; 2009 Nokia Corporation " \
    29                           "and/or its subsidiary(-ies)</td>\n" \
    30                           "<td width=\"40%\" align=\"center\"><a href=\"trademarks.html\">Trademarks</a></td>\n" \
    31                           "<td width=\"30%\" align=\"right\"><div align=\"right\">Qt \\version</div></td>\n" \
     22                          "<td width=\"40%\" align=\"left\">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies)</td>\n" \
     23                          "<td width=\"20%\" align=\"center\"><a href=\"trademarks.html\">Trademarks</a></td>\n" \
     24                          "<td width=\"40%\" align=\"right\"><div align=\"right\">Qt \\version</div></td>\n" \
    3225                          "</tr></table></div></address>"
  • trunk/tools/qdoc3/test/qt.qdocconf

    r2 r561  
    77project                 = Qt
    88versionsym              =
    9 version                 = 4.5.1
     9version                 = 4.6.1
    1010description             = Qt Reference Documentation
    11 url                     = http://doc.trolltech.com/4.5
     11url                     = http://qt.nokia.com/doc/4.6
    1212
    13 edition.Console.modules = QtCore QtDBus QtNetwork QtScript QtSql QtXml \
    14                           QtXmlPatterns QtTest
    1513edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript QtScriptTools QtSql QtSvg \
    1614                          QtWebKit QtXml QtXmlPatterns Qt3Support QtHelp \
     
    2321
    2422qhp.Qt.file                = qt.qhp
    25 qhp.Qt.namespace           = com.trolltech.qt.451
     23qhp.Qt.namespace           = com.trolltech.qt.460
    2624qhp.Qt.virtualFolder       = qdoc
    2725qhp.Qt.indexTitle          = Qt Reference Documentation
     
    3230qhp.Qt.extraFiles          = classic.css \
    3331                             images/qt-logo.png \
    34                              images/trolltech-logo \
    3532                             images/taskmenuextension-example.png \
    3633                             images/coloreditorfactoryimage.png \
     
    3835                             images/stylesheet-coffee-plastique.png
    3936
    40 qhp.Qt.filterAttributes    = qt 4.5.1 qtrefdoc
    41 qhp.Qt.customFilters.Qt.name = Qt 4.5.1
    42 qhp.Qt.customFilters.Qt.filterAttributes = qt 4.5.1
     37qhp.Qt.filterAttributes    = qt 4.6.1 qtrefdoc
     38qhp.Qt.customFilters.Qt.name = Qt 4.6.1
     39qhp.Qt.customFilters.Qt.filterAttributes = qt 4.6.1
    4340qhp.Qt.subprojects         = classes overviews examples
    4441qhp.Qt.subprojects.classes.title = Classes
     
    9996                          $QTDIR/src/3rdparty/phonon/ds9 \
    10097                          $QTDIR/src/3rdparty/phonon/qt7 \
     98                          $QTDIR/src/3rdparty/phonon/mmf \
    10199                          $QTDIR/src/3rdparty/phonon/waveout
    102100
    103101sources.fileextensions  = "*.cpp *.qdoc *.mm"
    104102examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp"
     103examples.imageextensions = "*.png"
    105104
    106105exampledirs             = $QTDIR/doc/src \
     
    108107                          $QTDIR/examples/tutorials \
    109108                          $QTDIR \
    110                           $QTDIR/qmake/examples
     109                          $QTDIR/qmake/examples \
     110                          $QTDIR/src/3rdparty/webkit/WebKit/qt/docs
    111111imagedirs               = $QTDIR/doc/src/images \
    112112                          $QTDIR/examples
     
    114114tagfile                 = $QTDIR/doc/html/qt.tags
    115115base                    = file:$QTDIR/doc/html
     116
     117HTML.generatemacrefs    = "true"
  • trunk/tools/qdoc3/test/standalone-eclipse-integration.qdocconf

    r2 r561  
    66HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \
    77              "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \
    8               "<td width=\"40%\" align="left">Copyright &copy; 2009 <a href=\"http://doc.trolltech.com\">Nokia Corporation</a></td>\n" \
    9               "<td width=\"30%\" align=\"center\"><a href=\"http://doc.trolltech.com/trademarks.html\">Trademarks</a></td>\n" \
    10               "<td width=\"40%\" align=\"right\"><div align=\"right\">Qt Eclipse Integration 1.4.3</div></td>\n" \
     8              "<td width=\"30%\" align=\"left\">Copyright &copy; 2009 Nokia Corporation and/or its subsidiary(-ies)</td>\n" \
     9              "<td width=\"40%\" align=\"center\"><a href=\"http://qt.nokia.com/doc/trademarks.html\">Trademarks</a></td>\n" \
     10              "<td width=\"30%\" align=\"right\"><div align=\"right\">Qt Eclipse Integration 1.5.3</div></td>\n" \
    1111              "</tr></table></div></address>"
  • trunk/tools/qdoc3/text.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/text.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/tokenizer.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/tokenizer.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/tr.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/tree.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    177177
    178178/*!
     179  Find the node with the specified \a path name of the
     180  specified \a type.
    179181 */
    180182Node *Tree::findNode(const QStringList &path,
     
    190192
    191193/*!
     194  Find the node with the specified \a path name of the
     195  specified \a type.
    192196 */
    193197const Node *Tree::findNode(const QStringList &path,
     
    209213{
    210214    return const_cast<FunctionNode *>(
    211                 const_cast<const Tree *>(this)->findFunctionNode(path, relative, findFlags));
     215                const_cast<const Tree *>(this)->findFunctionNode(path,
     216                                                                 relative,
     217                                                                 findFlags));
    212218}
    213219
     
    220226    if (!relative)
    221227        relative = root();
     228
    222229    do {
    223230        const Node *node = relative;
     
    234241                next = ((InnerNode *) node)->findNode(path.at(i));
    235242
    236             if (!next && node->type() == Node::Class && (findFlags & SearchBaseClasses)) {
     243            if (!next && node->type() == Node::Class &&
     244                (findFlags & SearchBaseClasses)) {
    237245                NodeList baseClasses = allBaseClasses(static_cast<const ClassNode *>(node));
    238246                foreach (const Node *baseClass, baseClasses) {
    239247                    if (i == path.size() - 1)
    240                         next = static_cast<const InnerNode *>(baseClass)->
    241                                 findFunctionNode(path.at(i));
     248                        next = static_cast<const InnerNode *>(baseClass)->findFunctionNode(path.at(i));
    242249                    else
    243250                        next = static_cast<const InnerNode *>(baseClass)->findNode(path.at(i));
     
    250257            node = next;
    251258        }
    252         if (node && i == path.size() && node->type() == Node::Function) {
     259        if (node && i == path.size() && node->isFunction()) {
    253260            // CppCodeParser::processOtherMetaCommand ensures that reimplemented
    254261            // functions are private.
    255262            const FunctionNode *func = static_cast<const FunctionNode*>(node);
    256 
    257263            while (func->access() == Node::Private) {
    258264                const FunctionNode *from = func->reimplementedFrom();
     
    262268                    else
    263269                        func = from;
    264                 } else
     270                }
     271                else
    265272                    break;
    266273            }
     
    297304    if (parent == 0 || !parent->isInnerNode()) {
    298305        return 0;
    299     } else {
     306    }
     307    else {
    300308        return ((InnerNode *)parent)->findFunctionNode(clone);
    301309    }
     
    413421
    414422/*!
     423  This function adds the \a node to the \a group. The group
     424  can be listed anywhere using the \e{annotated list} command.
    415425 */
    416426void Tree::addToGroup(Node *node, const QString &group)
     
    477487        QString setterName = (*propEntry)[PropertyNode::Setter];
    478488        QString resetterName = (*propEntry)[PropertyNode::Resetter];
     489        QString notifierName = (*propEntry)[PropertyNode::Notifier];
    479490
    480491        NodeList::ConstIterator c = parent->childNodes().begin();
     
    491502                    } else if (function->name() == resetterName) {
    492503                        property->addFunction(function, PropertyNode::Resetter);
     504                    } else if (function->name() == notifierName) {
     505                        property->addSignal(function, PropertyNode::Notifier);
    493506                    }
    494507                }
     
    564577        FakeNode *fake =
    565578            static_cast<FakeNode*>(findNode(QStringList(i.key()),Node::Fake));
    566         if (fake && fake->subType() == FakeNode::Group) {
     579        if (fake && fake->subType() == Node::Group) {
    567580            fake->addGroupMember(i.value());
    568581        }
     582#if 0       
    569583        else {
    570584            if (prevGroup != i.key())
    571585                i.value()->doc().location().warning(tr("No such group '%1'").arg(i.key()));
    572586        }
     587#endif       
    573588
    574589        prevGroup = i.key();
     
    771786    }
    772787    else if (element.nodeName() == "page") {
    773         FakeNode::SubType subtype;
     788        Node::SubType subtype;
    774789        if (element.attribute("subtype") == "example")
    775             subtype = FakeNode::Example;
     790            subtype = Node::Example;
    776791        else if (element.attribute("subtype") == "header")
    777             subtype = FakeNode::HeaderFile;
     792            subtype = Node::HeaderFile;
    778793        else if (element.attribute("subtype") == "file")
    779             subtype = FakeNode::File;
     794            subtype = Node::File;
    780795        else if (element.attribute("subtype") == "group")
    781             subtype = FakeNode::Group;
     796            subtype = Node::Group;
    782797        else if (element.attribute("subtype") == "module")
    783             subtype = FakeNode::Module;
     798            subtype = Node::Module;
    784799        else if (element.attribute("subtype") == "page")
    785             subtype = FakeNode::Page;
     800            subtype = Node::Page;
    786801        else if (element.attribute("subtype") == "externalpage")
    787             subtype = FakeNode::ExternalPage;
     802            subtype = Node::ExternalPage;
    788803        else
    789804            return;
     
    12271242            const FakeNode *fakeNode = static_cast<const FakeNode*>(node);
    12281243            switch (fakeNode->subType()) {
    1229                 case FakeNode::Example:
     1244                case Node::Example:
    12301245                    writer.writeAttribute("subtype", "example");
    12311246                    break;
    1232                 case FakeNode::HeaderFile:
     1247                case Node::HeaderFile:
    12331248                    writer.writeAttribute("subtype", "header");
    12341249                    break;
    1235                 case FakeNode::File:
     1250                case Node::File:
    12361251                    writer.writeAttribute("subtype", "file");
    12371252                    break;
    1238                 case FakeNode::Group:
     1253                case Node::Group:
    12391254                    writer.writeAttribute("subtype", "group");
    12401255                    break;
    1241                 case FakeNode::Module:
     1256                case Node::Module:
    12421257                    writer.writeAttribute("subtype", "module");
    12431258                    break;
    1244                 case FakeNode::Page:
     1259                case Node::Page:
    12451260                    writer.writeAttribute("subtype", "page");
    12461261                    break;
    1247                 case FakeNode::ExternalPage:
     1262                case Node::ExternalPage:
    12481263                    writer.writeAttribute("subtype", "externalpage");
    12491264                    break;
     
    13841399            if (inner->type() == Node::Fake) {
    13851400                const FakeNode *fakeNode = static_cast<const FakeNode *>(inner);
    1386                 if (fakeNode->subType() == FakeNode::ExternalPage)
     1401                if (fakeNode->subType() == Node::ExternalPage)
    13871402                    external = true;
    13881403            }
     
    18641879void Tree::addExternalLink(const QString &url, const Node *relative)
    18651880{
    1866     FakeNode *fakeNode = new FakeNode(root(), url, FakeNode::ExternalPage);
     1881    FakeNode *fakeNode = new FakeNode(root(), url, Node::ExternalPage);
    18671882    fakeNode->setAccess(Node::Public);
    18681883
     
    18851900        return node->url();
    18861901
     1902    QString parentName;
     1903    QString anchorRef;
     1904
    18871905    if (node->type() == Node::Namespace) {
    18881906
     
    18911909
    18921910        if (!node->fileBase().isEmpty())
    1893             return node->fileBase() + ".html";
     1911            parentName = node->fileBase() + ".html";
    18941912        else
    18951913            return "";
    18961914    }
    18971915    else if (node->type() == Node::Fake) {
    1898         return node->fileBase() + ".html";
     1916#ifdef QDOC_QML
     1917        if (node->subType() == Node::QmlClass)
     1918            return "qml-" + node->fileBase() + ".html";
     1919        else
     1920#endif
     1921        parentName = node->fileBase() + ".html";
    18991922    }
    19001923    else if (node->fileBase().isEmpty())
    19011924        return "";
    19021925
    1903     QString parentName;
    19041926    Node *parentNode = 0;
    19051927
     
    19131935        case Node::Namespace:
    19141936            if (parentNode && !parentNode->name().isEmpty())
    1915                 return parentName.replace(".html", "") + "-"
    1916                     + node->fileBase().toLower() + ".html";
     1937                parentName = parentName.replace(".html", "") + "-"
     1938                           + node->fileBase().toLower() + ".html";
    19171939            else
    1918                 return node->fileBase() + ".html";
     1940                parentName = node->fileBase() + ".html";
     1941            break;
    19191942        case Node::Function:
    19201943            {
     
    19261949                    static_cast<const FunctionNode *>(node);
    19271950
    1928                 // Functions can be compatibility functions or be obsolete.
    1929                 switch (node->status()) {
    1930                 case Node::Compat:
    1931                     parentName.replace(".html", "-qt3.html");
    1932                     break;
    1933                 case Node::Obsolete:
    1934                     parentName.replace(".html", "-obsolete.html");
    1935                     break;
    1936                 default:
    1937                     ;
    1938                 }
    1939 
    19401951                if (functionNode->metaness() == FunctionNode::Dtor)
    1941                     return parentName + "#dtor." + functionNode->name().mid(1);
    1942 
    1943                 if (functionNode->associatedProperty())
     1952                    anchorRef = "#dtor." + functionNode->name().mid(1);
     1953
     1954                else if (functionNode->associatedProperty())
    19441955                    return fullDocumentLocation(functionNode->associatedProperty());
    19451956
    1946                 if (functionNode->overloadNumber() > 1)
    1947                     return parentName + "#" + functionNode->name()
    1948                            + "-" + QString::number(functionNode->overloadNumber());
     1957                else if (functionNode->overloadNumber() > 1)
     1958                    anchorRef = "#" + functionNode->name()
     1959                              + "-" + QString::number(functionNode->overloadNumber());
    19491960                else
    1950                     return parentName + "#" + functionNode->name();
     1961                    anchorRef = "#" + functionNode->name();
    19511962            }
    19521963
     
    19561967              HTML anchors, we need to preserve the case.
    19571968            */
     1969            break;
    19581970        case Node::Enum:
    1959             return parentName + "#" + node->name() + "-enum";
     1971            anchorRef = "#" + node->name() + "-enum";
     1972            break;
    19601973        case Node::Typedef:
    1961             return parentName + "#" + node->name() + "-typedef";
     1974            anchorRef = "#" + node->name() + "-typedef";
     1975            break;
    19621976        case Node::Property:
    1963             return parentName + "#" + node->name() + "-prop";
     1977            anchorRef = "#" + node->name() + "-prop";
     1978            break;
    19641979        case Node::Variable:
    1965             return parentName + "#" + node->name() + "-var";
     1980            anchorRef = "#" + node->name() + "-var";
     1981            break;
    19661982        case Node::Target:
    1967             return parentName + "#" + Doc::canonicalTitle(node->name());
     1983            anchorRef = "#" + Doc::canonicalTitle(node->name());
     1984            break;
    19681985        case Node::Fake:
    19691986            {
    1970             QString pageName = node->name();
    1971             return pageName.replace("/", "-").replace(".", "-") + ".html";
     1987            /*
     1988              Use node->fileBase() for fake nodes because they are represented
     1989              by pages whose file names are lower-case.
     1990            */
     1991            parentName = node->fileBase();
     1992            parentName.replace("/", "-").replace(".", "-");
     1993            parentName += ".html";
    19721994            }
    19731995            break;
     
    19761998    }
    19771999
    1978     return "";
     2000    // Various objects can be compat (deprecated) or obsolete.
     2001    if (node->type() != Node::Class && node->type() != Node::Namespace) {
     2002        switch (node->status()) {
     2003        case Node::Compat:
     2004            parentName.replace(".html", "-qt3.html");
     2005            break;
     2006        case Node::Obsolete:
     2007            parentName.replace(".html", "-obsolete.html");
     2008            break;
     2009        default:
     2010            ;
     2011        }
     2012    }
     2013
     2014    return parentName.toLower() + anchorRef;
    19792015}
    19802016
  • trunk/tools/qdoc3/tree.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/uncompressor.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/uncompressor.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/webxmlgenerator.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    192192            generateRelations(writer, node, marker);
    193193
    194             if (fake->subType() == FakeNode::Module) {
     194            if (fake->subType() == Node::Module) {
    195195                writer.writeStartElement("generatedlist");
    196196                writer.writeAttribute("contents", "classesbymodule");
     
    265265    if (node->type() == Node::Fake) {
    266266        const FakeNode *fakeNode = static_cast<const FakeNode *>(node);
    267         if (fakeNode->subType() == FakeNode::ExternalPage)
     267        if (fakeNode->subType() == Node::ExternalPage)
    268268            return;
    269269    }
  • trunk/tools/qdoc3/webxmlgenerator.h

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
  • trunk/tools/qdoc3/yyindent.cpp

    r2 r561  
    22**
    33** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
    4 ** Contact: Qt Software Information (qt-info@nokia.com)
     4** All rights reserved.
     5** Contact: Nokia Corporation (qt-info@nokia.com)
    56**
    67** This file is part of the tools applications of the Qt Toolkit.
     
    2122** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    2223**
    23 ** In addition, as a special exception, Nokia gives you certain
    24 ** additional rights. These rights are described in the Nokia Qt LGPL
    25 ** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
    26 ** package.
     24** In addition, as a special exception, Nokia gives you certain additional
     25** rights.  These rights are described in the Nokia Qt LGPL Exception
     26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    2727**
    2828** GNU General Public License Usage
     
    3434** met: http://www.gnu.org/copyleft/gpl.html.
    3535**
    36 ** If you are unsure which license is appropriate for your use, please
    37 ** contact the sales department at qt-sales@nokia.com.
     36** If you have questions regarding the use of this file, please contact
     37** Nokia at qt-info@nokia.com.
    3838** $QT_END_LICENSE$
    3939**
     
    720720                /*
    721721                    An unclosed delimiter is a good place to align at,
    722                     at least for some styles (including Trolltech's).
     722                    at least for some styles (including Qt's).
    723723                */
    724724                if ( delimDepth == -1 )
Note: See TracChangeset for help on using the changeset viewer.