Ignore:
Timestamp:
May 5, 2011, 5:36:53 AM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk

  • trunk/tools/qdoc3/htmlgenerator.cpp

    r651 r846  
    11/****************************************************************************
    22**
    3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
     3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
    44** All rights reserved.
    55** Contact: Nokia Corporation (qt-info@nokia.com)
     
    4545
    4646#include "codemarker.h"
     47#include "codeparser.h"
    4748#include "helpprojectwriter.h"
    4849#include "htmlgenerator.h"
     
    5556#include <qlist.h>
    5657#include <qiterator.h>
     58#include <qtextcodec.h>
    5759
    5860QT_BEGIN_NAMESPACE
    5961
    6062#define COMMAND_VERSION                 Doc::alias("version")
     63int HtmlGenerator::id = 0;
     64bool HtmlGenerator::debugging_on = false;
     65
     66#if 0
     67QString HtmlGenerator::divNavTop = "<div class=\"navTop\"><a href=\"#toc\"><img src=\"./images/bullet_up.png\"></a></div>";
     68#endif
     69
     70QString HtmlGenerator::divNavTop = "";
    6171
    6272QString HtmlGenerator::sinceTitles[] =
     
    7282        "    New Properties",
    7383        "    New Variables",
     84        "    New QML Elements",
    7485        "    New Qml Properties",
    7586        "    New Qml Signals",
     
    202213
    203214HtmlGenerator::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)
     215    : helpProjectWriter(0),
     216      inLink(false),
     217      inContents(false),
     218      inSectionHeading(false),
     219      inTableHeader(false),
     220      numTableRows(0),
     221      threeColumnEnumValueTable(true),
     222      application(Online),
     223      funcLeftParen("\\S(\\()"),
     224      myTree(0),
     225      slow(false),
     226      obsoleteLinks(false)
    208227{
    209228}
     
    249268                                  Config::dot +
    250269                                  HTMLGENERATOR_POSTHEADER);
     270    postPostHeader = config.getString(HtmlGenerator::format() +
     271                                      Config::dot +
     272                                      HTMLGENERATOR_POSTPOSTHEADER);
     273    creatorPostHeader = config.getString(HtmlGenerator::format() +
     274                                  Config::dot +
     275                                  HTMLGENERATOR_CREATORPOSTHEADER);
     276    creatorPostPostHeader = config.getString(HtmlGenerator::format() +
     277                                      Config::dot +
     278                                      HTMLGENERATOR_CREATORPOSTPOSTHEADER);
    251279    footer = config.getString(HtmlGenerator::format() +
    252280                              Config::dot +
     
    261289    project = config.getString(CONFIG_PROJECT);
    262290
     291    QString app = config.getString(CONFIG_APPLICATION);
     292    if (app == "online")
     293        application = Online;
     294    else if (app == "creator")
     295        application = Creator;
     296    else
     297        application = Creator;
     298
    263299    projectDescription = config.getString(CONFIG_DESCRIPTION);
    264300    if (projectDescription.isEmpty() && !project.isEmpty())
     
    266302
    267303    projectUrl = config.getString(CONFIG_URL);
     304
     305    outputEncoding = config.getString(CONFIG_OUTPUTENCODING);
     306    if (outputEncoding.isEmpty())
     307        outputEncoding = QLatin1String("ISO-8859-1");
     308    outputCodec = QTextCodec::codecForName(outputEncoding.toLocal8Bit());
     309
     310    naturalLanguage = config.getString(CONFIG_NATURALLANGUAGE);
     311    if (naturalLanguage.isEmpty())
     312        naturalLanguage = QLatin1String("en");
    268313
    269314    QSet<QString> editionNames = config.subVars(CONFIG_EDITION);
     
    322367void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker)
    323368{
    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 
    334369    myTree = tree;
    335370    nonCompatClasses.clear();
     
    342377    legaleseTexts.clear();
    343378    serviceClasses.clear();
     379    qmlClasses.clear();
    344380    findAllClasses(tree->root());
    345381    findAllFunctions(tree->root());
    346382    findAllLegaleseTexts(tree->root());
    347383    findAllNamespaces(tree->root());
    348 #ifdef ZZZ_QDOC_QML
    349     findAllQmlClasses(tree->root());
    350 #endif
    351384    findAllSince(tree->root());
    352385
     
    390423                dcfQmakeRoot);
    391424
    392     generateIndex(project.toLower().simplified().replace(" ", "-"),
    393                   projectUrl,
    394                   projectDescription);
     425    QString fileBase = project.toLower().simplified().replace(" ", "-");
     426    generateIndex(fileBase, projectUrl, projectDescription);
     427    generatePageIndex(outputDir() + "/" + fileBase + ".pageindex", marker);
    395428
    396429    helpProjectWriter->generate(myTree);
     
    410443}
    411444
     445/*!
     446  Generate html from an instance of Atom.
     447 */
    412448int HtmlGenerator::generateAtom(const Atom *atom,
    413449                                const Node *relative,
     
    432468            }
    433469            else {
    434                 out() << protect(atom->string());
     470                out() << protectEnc(atom->string());
    435471            }
    436472        }
    437473        else {
    438             out() << protect(atom->string());
     474            out() << protectEnc(atom->string());
    439475        }
    440476        break;
     
    484520        out() << formattingLeftMap()[ATOM_FORMATTING_TELETYPE];
    485521        if (inLink) {
    486             out() << protect(plainCode(atom->string()));
     522            out() << protectEnc(plainCode(atom->string()));
    487523        }
    488524        else {
     
    492528        break;
    493529    case Atom::Code:
    494         out() << "<pre>"
     530        out() << "<pre class=\"highlightedCode brush: cpp\">"
    495531              << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
    496532                                                 marker,relative))
    497533              << "</pre>\n";
    498         break;
     534        break;
    499535#ifdef QDOC_QML
    500536    case Atom::Qml:
    501         out() << "<pre>"
     537        out() << "<pre class=\"highlightedCode brush: cpp\">"
    502538              << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
    503539                                                 marker,relative))
    504540              << "</pre>\n";
    505         break;
     541        break;
    506542#endif
    507543    case Atom::CodeNew:
    508544        out() << "<p>you can rewrite it as</p>\n"
    509               << "<pre>"
     545              << "<pre class=\"highlightedCode brush: cpp\">"
    510546              << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
    511547                                                 marker,relative))
     
    516552        // fallthrough
    517553    case Atom::CodeBad:
    518         out() << "<pre><font color=\"#404040\">"
    519               << trimmedTrailing(protect(plainCode(indent(codeIndent,atom->string()))))
    520               << "</font></pre>\n";
    521         break;
     554        out() << "<pre class=\"highlightedCode brush: cpp\">"
     555              << trimmedTrailing(protectEnc(plainCode(indent(codeIndent,atom->string()))))
     556              << "</pre>\n";
     557        break;
    522558    case Atom::FootnoteLeft:
    523559        // ### For now
     
    575611        }
    576612        else if (atom->string() == "classes") {
    577             generateCompactList(relative, marker, nonCompatClasses);
     613            generateCompactList(relative, marker, nonCompatClasses, true);
     614        }
     615        else if (atom->string() == "qmlclasses") {
     616            generateCompactList(relative, marker, qmlClasses, true);
    578617        }
    579618        else if (atom->string().contains("classesbymodule")) {
     
    623662        }
    624663        else if (atom->string() == "compatclasses") {
    625             generateCompactList(relative, marker, compatClasses);
     664            generateCompactList(relative, marker, compatClasses, false);
    626665        }
    627666        else if (atom->string() == "obsoleteclasses") {
    628             generateCompactList(relative, marker, obsoleteClasses);
     667            generateCompactList(relative, marker, obsoleteClasses, false);
    629668        }
    630669        else if (atom->string() == "functionindex") {
     
    635674        }
    636675        else if (atom->string() == "mainclasses") {
    637             generateCompactList(relative, marker, mainClasses);
     676            generateCompactList(relative, marker, mainClasses, true);
    638677        }
    639678        else if (atom->string() == "services") {
    640             generateCompactList(relative, marker, serviceClasses);
     679            generateCompactList(relative, marker, serviceClasses, false);
    641680        }
    642681        else if (atom->string() == "overviews") {
     
    677716            NewClassMaps::const_iterator ncmap;
    678717            ncmap = newClassMaps.find(atom->string());
     718            NewClassMaps::const_iterator nqcmap;
     719            nqcmap = newQmlClassMaps.find(atom->string());
    679720            if ((nsmap != newSinceMaps.constEnd()) && !nsmap.value().isEmpty()) {
    680721                QList<Section> sections;
    681722                QList<Section>::ConstIterator s;
    682723                for (int i=0; i<LastSinceType; ++i)
    683                     sections.append(Section(sinceTitle(i),QString(),QString()));
     724                    sections.append(Section(sinceTitle(i),QString(),QString(),QString()));
    684725
    685726                NodeMultiMap::const_iterator n = nsmap.value().constBegin();
     
    687728                    const Node* node = n.value();
    688729                    switch (node->type()) {
     730                      case Node::Fake:
     731                          if (node->subType() == Node::QmlClass) {
     732                              sections[QmlClass].appendMember((Node*)node);
     733                          }
     734                          break;
    689735                      case Node::Namespace:
    690736                          sections[Namespace].appendMember((Node*)node);
     
    769815                              << Doc::canonicalTitle((*s).name)
    770816                              << "\"></a>\n";
    771                         out() << "<h3>" << protect((*s).name) << "</h3>\n";
     817                        out() << "<h3>" << protectEnc((*s).name) << "</h3>\n";
    772818                        if (idx == Class)
    773                             generateCompactList(0, marker, ncmap.value(), QString("Q"));
     819                            generateCompactList(0, marker, ncmap.value(), false, QString("Q"));
     820                        else if (idx == QmlClass)
     821                            generateCompactList(0, marker, nqcmap.value(), false, QString("Q"));
    774822                        else if (idx == MemberFunction) {
    775823                            ParentMaps parentmaps;
     
    793841                                      << "\">";
    794842                                QStringList pieces = fullName(pmap.key(), 0, marker).split("::");
    795                                 out() << protect(pieces.last());
     843                                out() << protectEnc(pieces.last());
    796844                                out() << "</a>"  << ":</p>\n";
    797845
    798846                                generateSection(nlist, 0, marker, CodeMarker::Summary);
    799                                 out() << "<br />";
     847                                out() << "<br/>";
    800848                                ++pmap;
    801849                            }
     
    818866                text = atom->next()->string();
    819867            if (atom->type() == Atom::Image)
    820                 out() << "<p align=\"center\">";
     868                out() << "<p class=\"centerAlign\">";
    821869            if (fileName.isEmpty()) {
    822870                out() << "<font color=\"red\">[Missing image "
    823                       << protect(atom->string()) << "]</font>";
     871                      << protectEnc(atom->string()) << "]</font>";
    824872            }
    825873            else {
    826                 out() << "<img src=\"" << protect(fileName) << "\"";
     874                out() << "<img src=\"" << protectEnc(fileName) << "\"";
    827875                if (!text.isEmpty())
    828                     out() << " alt=\"" << protect(text) << "\"";
     876                    out() << " alt=\"" << protectEnc(text) << "\"";
    829877                out() << " />";
    830878                helpProjectWriter->addExtraFile(fileName);
     
    837885        break;
    838886    case Atom::LegaleseLeft:
    839         out() << "<div style=\"padding: 0.5em; background: #e0e0e0; color: black\">";
     887        out() << "<div class=\"LegaleseLeft\">";
    840888        break;
    841889    case Atom::LegaleseRight:
     
    843891        break;
    844892    case Atom::LineBreak:
    845         out() << "<br />";
     893        out() << "<br/>";
    846894        break;
    847895    case Atom::Link:
     
    879927            threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom);
    880928            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";
     929                out() << "<table class=\"valuelist\">";
     930                if (++numTableRows % 2 == 1)
     931                        out() << "<tr class=\"odd\">";
     932                else
     933                        out() << "<tr class=\"even\">";
     934
     935                out() << "<th class=\"tblConst\">Constant</th>"
     936                      << "<th class=\"tblval\">Value</th>"
     937                      << "<th class=\"tbldscr\">Description</th></tr>\n";
    886938            }
    887939            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";
     940                out() << "<table class=\"valuelist\">"
     941                      << "<tr><th class=\"tblConst\">Constant</th><th class=\"tblVal\">Value</th></tr>\n";
    892942            }
    893943        }
    894944        else {
    895             out() << "<ol type=";
     945            out() << "<ol class=";
    896946            if (atom->string() == ATOM_LIST_UPPERALPHA) {
    897947                out() << "\"A\"";
    898             }
     948            } /* why type? changed to */
    899949            else if (atom->string() == ATOM_LIST_LOWERALPHA) {
    900950                out() << "\"a\"";
     
    923973            // ### Trenton
    924974
    925             out() << "<tr><td valign=\"top\"><tt>"
    926                   << protect(plainCode(marker->markedUpEnumValue(atom->next()->string(),
     975            out() << "<tr><td  class=\"topAlign\"><tt>"
     976                  << protectEnc(plainCode(marker->markedUpEnumValue(atom->next()->string(),
    927977                                                                 relative)))
    928                   << "</tt></td><td align=\"center\" valign=\"top\">";
     978                  << "</tt></td><td class=\" topAlign\">";
    929979
    930980            QString itemValue;
     
    937987                out() << "?";
    938988            else
    939                 out() << "<tt>" << protect(itemValue) << "</tt>";
     989                out() << "<tt>" << protectEnc(itemValue) << "</tt>";
    940990
    941991            skipAhead = 1;
     
    9521002        else if (atom->string() == ATOM_LIST_VALUE) {
    9531003            if (threeColumnEnumValueTable) {
    954                 out() << "</td><td valign=\"top\">";
     1004                out() << "</td><td  class=\"topAlign\">";
    9551005                if (matchAhead(atom, Atom::ListItemRight))
    9561006                    out() << "&nbsp;";
     
    9821032        }
    9831033        else if (atom->string() == ATOM_LIST_VALUE) {
    984             out() << "</table></p>\n";
     1034            out() << "</table>\n";
    9851035        }
    9861036        else {
     
    10271077                sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1);
    10281078            }
    1029             out() << "<a name=\"sec-" << sectionNumber.join("-") << "\"></a>\n";
     1079            out() << "<a name=\"sec-" << sectionNumber.join("-") << "\"></a>" << divNavTop << "\n";
    10301080        }
    10311081#else
    10321082        out() << "<a name=\"" << Doc::canonicalTitle(Text::sectionHeading(atom).toString())
    1033               << "\"></a>\n";
     1083              << "\"></a>" << divNavTop << "\n";
    10341084#endif
    10351085        break;
     
    10531103        }
    10541104        else {
    1055             out() << protect(atom->string());
     1105            out() << protectEnc(atom->string());
    10561106        }
    10571107        break;
     
    10631113        if (!atom->string().isEmpty()) {
    10641114            if (atom->string().contains("%"))
    1065                 out() << "<p><table class=\"generic\" width=\"" << atom->string() << "\" "
    1066                       << "align=\"center\" cellpadding=\"2\" "
    1067                       << "cellspacing=\"1\" border=\"0\">\n";
     1115                out() << "<table class=\"generic\">\n "; // width=\"" << atom->string() << "\">\n ";
    10681116            else {
    1069                 out() << "<p><table class=\"generic\" align=\"center\" cellpadding=\"2\" "
    1070                       << "cellspacing=\"1\" border=\"0\">\n";
     1117                out() << "<table class=\"generic\">\n";
    10711118            }
    10721119        }
    10731120        else {
    1074             out() << "<p><table class=\"generic\" align=\"center\" cellpadding=\"2\" "
    1075                   << "cellspacing=\"1\" border=\"0\">\n";
     1121            out() << "<table class=\"generic\">\n";
    10761122        }
    10771123        numTableRows = 0;
    10781124        break;
    10791125    case Atom::TableRight:
    1080         out() << "</table></p>\n";
     1126        out() << "</table>\n";
    10811127        break;
    10821128    case Atom::TableHeaderLeft:
    1083         out() << "<thead><tr valign=\"top\" class=\"qt-style\">";
     1129        out() << "<thead><tr class=\"qt-style topAlign\">";
    10841130        inTableHeader = true;
    10851131        break;
     
    10881134        if (matchAhead(atom, Atom::TableHeaderLeft)) {
    10891135            skipAhead = 1;
    1090             out() << "\n<tr valign=\"top\" class=\"qt-style\">";
     1136            out() << "\n<tr class=\"qt-style topAlign\">";
    10911137        }
    10921138        else {
     
    10971143    case Atom::TableRowLeft:
    10981144        if (++numTableRows % 2 == 1)
    1099             out() << "<tr valign=\"top\" class=\"odd\">";
     1145            out() << "<tr class=\"odd topAlign\">";
    11001146        else
    1101             out() << "<tr valign=\"top\" class=\"even\">";
     1147            out() << "<tr class=\"even topAlign\">";
    11021148        break;
    11031149    case Atom::TableRowRight:
     
    11071153        {
    11081154            if (inTableHeader)
    1109                 out() << "<th";
     1155                out() << "<th ";
    11101156            else
    1111                 out() << "<td";
     1157                out() << "<td ";
    11121158
    11131159            QStringList spans = atom->string().split(",");
     
    11171163                if (spans.at(1) != "1")
    11181164                    out() << " rowspan=\"" << spans.at(1) << "\"";
     1165            if (inTableHeader)
    11191166                out() << ">";
     1167            else
     1168                out() << "><p>";
    11201169            }
    11211170            if (matchAhead(atom, Atom::ParaLeft))
     
    11271176            out() << "</th>";
    11281177        else
    1129             out() << "</td>";
     1178            out() << "</p></td>";
    11301179        if (matchAhead(atom, Atom::ParaLeft))
    11311180            skipAhead = 1;
     
    11641213        break;
    11651214    case Atom::UnhandledFormat:
    1166         out() << "<font color=\"red\"><b>&lt;Missing HTML&gt;</b></font>";
     1215        out() << "<b class=\"redFont\">&lt;Missing HTML&gt;</b>";
    11671216        break;
    11681217    case Atom::UnknownCommand:
    1169         out() << "<font color=\"red\"><b><code>\\" << protect(atom->string())
    1170               << "</code></b></font>";
     1218        out() << "<b class=\"redFont\"><code>\\" << protectEnc(atom->string())
     1219              << "</code></b>";
    11711220        break;
    11721221#ifdef QDOC_QML
     
    11821231}
    11831232
     1233/*!
     1234  Generate a reference page for a C++ class.
     1235 */
    11841236void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
    11851237                                          CodeMarker *marker)
     
    11981250        rawTitle = marker->plainName(inner);
    11991251        fullTitle = marker->plainFullName(inner);
    1200         title = rawTitle + " Namespace Reference";
     1252        title = rawTitle + " Namespace";
    12011253    }
    12021254    else if (inner->type() == Node::Class) {
     
    12171269                     << Atom(Atom::LineBreak);
    12181270
    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    
     1271    generateHeader(title, inner, marker);
     1272    sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
     1273    generateTableOfContents(inner,marker,&sections);
     1274    generateTitle(title, subtitleText, SmallSubTitle, inner, marker);   
    12491275    generateBrief(inner, marker);
    12501276    generateIncludes(inner, marker);
    12511277    generateStatus(inner, marker);
    12521278    if (classe) {
    1253         generateModuleWarning(classe, marker);
    12541279        generateInherits(classe, marker);
    12551280        generateInheritedBy(classe, marker);
     1281#ifdef QDOC_QML
     1282        if (!classe->qmlElement().isEmpty()) {
     1283            generateInstantiatedBy(classe,marker);
     1284        }
     1285#endif
    12561286    }
    12571287    generateThreadSafeness(inner, marker);
     
    12831313    bool needOtherSection = false;
    12841314
    1285     sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
     1315    /*
     1316      sections is built above for the call to generateTableOfContents().
     1317     */
    12861318    s = sections.begin();
    12871319    while (s != sections.end()) {
     
    12921324        else {
    12931325            if (!s->members.isEmpty()) {
    1294                 out() << "<hr />\n";
     1326               // out() << "<hr />\n";
    12951327                out() << "<a name=\""
    12961328                      << registerRef((*s).name.toLower())
    1297                       << "\"></a>\n";
    1298                 out() << "<h2>" << protect((*s).name) << "</h2>\n";
     1329                      << "\"></a>" << divNavTop << "\n";
     1330                out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
    12991331                generateSection(s->members, inner, marker, CodeMarker::Summary);
    13001332            }
    13011333            if (!s->reimpMembers.isEmpty()) {
    13021334                QString name = QString("Reimplemented ") + (*s).name;
    1303                 out() << "<hr />\n";
     1335              //  out() << "<hr />\n";
    13041336                out() << "<a name=\""
    13051337                      << registerRef(name.toLower())
    1306                       << "\"></a>\n";
    1307                 out() << "<h2>" << protect(name) << "</h2>\n";
     1338                      << "\"></a>" << divNavTop << "\n";
     1339                out() << "<h2>" << protectEnc(name) << "</h2>\n";
    13081340                generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary);
    13091341            }
     
    13111343            if (!s->inherited.isEmpty()) {
    13121344                out() << "<ul>\n";
    1313                 generateSectionInheritedList(*s, inner, marker, true);
     1345                generateSectionInheritedList(*s, inner, marker);
    13141346                out() << "</ul>\n";
    13151347            }
     
    13311363    }
    13321364
    1333     out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
     1365    out() << "<a name=\"" << registerRef("details") << "\"></a>" << divNavTop << "\n";
    13341366
    13351367    if (!inner->doc().isEmpty()) {
    1336         out() << "<hr />\n"
     1368        generateExtractionMark(inner, DetailedDescriptionMark);
     1369        //out() << "<hr />\n"
     1370        out() << "<div class=\"descr\">\n" // QTBUG-9504
    13371371              << "<h2>" << "Detailed Description" << "</h2>\n";
    13381372        generateBody(inner, marker);
     1373        out() << "</div>\n"; // QTBUG-9504
    13391374        generateAlsoList(inner, marker);
     1375        generateExtractionMark(inner, EndMark);
    13401376    }
    13411377
     
    13431379    s = sections.begin();
    13441380    while (s != sections.end()) {
    1345         out() << "<hr />\n";
    1346         out() << "<h2>" << protect((*s).name) << "</h2>\n";
     1381        //out() << "<hr />\n";
     1382        if (!(*s).divClass.isEmpty())
     1383            out() << "<div class=\"" << (*s).divClass << "\">\n"; // QTBUG-9504
     1384        out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
    13471385
    13481386        NodeList::ConstIterator m = (*s).members.begin();
     
    13931431            ++m;
    13941432        }
     1433        if (!(*s).divClass.isEmpty())
     1434            out() << "</div>\n"; // QTBUG-9504
    13951435        ++s;
    13961436    }
     
    14191459}
    14201460
     1461/*!
     1462  Generate the html page for a qdoc file that doesn't map
     1463  to an underlying c++ file.
     1464 */
    14211465void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
    14221466{
     
    14291473    QList<Section>::const_iterator s;
    14301474
    1431     QString htmlTitle = fake->fullTitle();
     1475    QString fullTitle = fake->fullTitle();
     1476    QString htmlTitle = fullTitle;
    14321477    if (fake->subType() == Node::File && !fake->subTitle().isEmpty()) {
    14331478        subTitleSize = SmallSubTitle;
    14341479        htmlTitle += " (" + fake->subTitle() + ")";
    14351480    }
    1436 
    1437     generateHeader(htmlTitle, fake, marker, true);
    1438     generateTitle(fake->fullTitle(),
     1481    else if (fake->subType() == Node::QmlBasicType) {
     1482        fullTitle = "QML Basic Type: " + fullTitle;
     1483        htmlTitle = fullTitle;
     1484    }
     1485
     1486    generateHeader(htmlTitle, fake, marker);
     1487       
     1488    /*
     1489      Generate the TOC for the new doc format.
     1490      Don't generate a TOC for the home page.
     1491    */
     1492    const QmlClassNode* qml_cn = 0;
     1493    if (fake->subType() == Node::QmlClass) {
     1494        qml_cn = static_cast<const QmlClassNode*>(fake);
     1495        sections = marker->qmlSections(qml_cn,CodeMarker::Summary,0);
     1496        generateTableOfContents(fake,marker,&sections);
     1497    }
     1498    else if (fake->name() != QString("index.html"))
     1499        generateTableOfContents(fake,marker,0);
     1500
     1501    generateTitle(fullTitle,
    14391502                  Text() << fake->subTitle(),
    14401503                  subTitleSize,
     
    14481511
    14491512        if (moduleNamespaceMap.contains(fake->name())) {
     1513            out() << "<a name=\"" << registerRef("namespaces") << "\"></a>" << divNavTop << "\n";
    14501514            out() << "<h2>Namespaces</h2>\n";
    14511515            generateAnnotatedList(fake, marker, moduleNamespaceMap[fake->name()]);
    14521516        }
    14531517        if (moduleClassMap.contains(fake->name())) {
     1518            out() << "<a name=\"" << registerRef("classes") << "\"></a>" << divNavTop << "\n";
    14541519            out() << "<h2>Classes</h2>\n";
    14551520            generateAnnotatedList(fake, marker, moduleClassMap[fake->name()]);
     
    15051570#ifdef QDOC_QML
    15061571    else if (fake->subType() == Node::QmlClass) {
    1507         const QmlClassNode* qml_cn = static_cast<const QmlClassNode*>(fake);
    15081572        const ClassNode* cn = qml_cn->classNode();
     1573        generateBrief(qml_cn, marker);
    15091574        generateQmlInherits(qml_cn, marker);
     1575        generateQmlInheritedBy(qml_cn, marker);
    15101576        generateQmlInstantiates(qml_cn, marker);
    1511         generateBrief(qml_cn, marker);
    1512         sections = marker->qmlSections(qml_cn,CodeMarker::Summary);
     1577
     1578        QString allQmlMembersLink = generateAllQmlMembersFile(qml_cn, marker);
     1579        if (!allQmlMembersLink.isEmpty()) {
     1580            out() << "<li><a href=\"" << allQmlMembersLink << "\">"
     1581                  << "List of all members, including inherited members</a></li>\n";
     1582        }
     1583
    15131584        s = sections.begin();
    15141585        while (s != sections.end()) {
    1515             out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
    1516             out() << "<h2>" << protect((*s).name) << "</h2>\n";
     1586            out() << "<a name=\"" << registerRef((*s).name.toLower())
     1587                  << "\"></a>" << divNavTop << "\n";
     1588            out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
    15171589            generateQmlSummary(*s,fake,marker);
    15181590            ++s;
    15191591        }
    15201592
    1521         out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
     1593        generateExtractionMark(fake, DetailedDescriptionMark);
     1594        out() << "<a name=\"" << registerRef("details") << "\"></a>" << divNavTop << "\n";
    15221595        out() << "<h2>" << "Detailed Description" << "</h2>\n";
    15231596        generateBody(fake, marker);
     
    15251598            generateQmlText(cn->doc().body(), cn, marker, fake->name());
    15261599        generateAlsoList(fake, marker);
    1527         out() << "<hr />\n";
    1528 
    1529         sections = marker->qmlSections(qml_cn,CodeMarker::Detailed);
     1600        generateExtractionMark(fake, EndMark);
     1601        //out() << "<hr />\n";
     1602
     1603        sections = marker->qmlSections(qml_cn,CodeMarker::Detailed,0);
    15301604        s = sections.begin();
    15311605        while (s != sections.end()) {
    1532             out() << "<h2>" << protect((*s).name) << "</h2>\n";
     1606            out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
    15331607            NodeList::ConstIterator m = (*s).members.begin();
    15341608            while (m != (*s).members.end()) {
    15351609                generateDetailedQmlMember(*m, fake, marker);
    1536                 out() << "<br />\n";
     1610                out() << "<br/>\n";
    15371611                fakeSection.keywords += qMakePair((*m)->name(),
    15381612                                                  linkForNode(*m,0));
     
    15491623    s = sections.begin();
    15501624    while (s != sections.end()) {
    1551         out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
    1552         out() << "<h2>" << protect((*s).name) << "</h2>\n";
     1625        out() << "<a name=\"" << registerRef((*s).name) << "\"></a>" << divNavTop << "\n";
     1626        out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
    15531627        generateSectionList(*s, fake, marker, CodeMarker::Summary);
    15541628        ++s;
     
    15571631    Text brief = fake->doc().briefText();
    15581632    if (fake->subType() == Node::Module && !brief.isEmpty()) {
    1559         out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
     1633        generateExtractionMark(fake, DetailedDescriptionMark);
     1634        out() << "<a name=\"" << registerRef("details") << "\"></a>" << divNavTop << "\n";
     1635        out() << "<div class=\"descr\">\n"; // QTBUG-9504
    15601636        out() << "<h2>" << "Detailed Description" << "</h2>\n";
    15611637    }
     1638    else {
     1639        generateExtractionMark(fake, DetailedDescriptionMark);
     1640        out() << "<div class=\"descr\"> <a name=\"" << registerRef("details") << "\"></a>\n"; // QTBUG-9504
     1641    }
    15621642
    15631643    generateBody(fake, marker);
     1644    out() << "</div>\n"; // QTBUG-9504
    15641645    generateAlsoList(fake, marker);
     1646    generateExtractionMark(fake, EndMark);
    15651647
    15661648    if (!fake->groupMembers().isEmpty()) {
     
    15781660    s = sections.begin();
    15791661    while (s != sections.end()) {
    1580         out() << "<hr />\n";
    1581         out() << "<h2>" << protect((*s).name) << "</h2>\n";
     1662        //out() << "<hr />\n";
     1663        out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
    15821664
    15831665        NodeList::ConstIterator m = (*s).members.begin();
     
    16151697}
    16161698
    1617 QString HtmlGenerator::fileExtension(const Node * /* node */)
     1699/*!
     1700  Returns "html" for this subclass of Generator.
     1701 */
     1702QString HtmlGenerator::fileExtension(const Node * /* node */) const
    16181703{
    16191704    return "html";
     1705}
     1706
     1707/*!
     1708  Output breadcrumb list in the html file.
     1709 */
     1710void HtmlGenerator::generateBreadCrumbs(const QString& title,
     1711                                        const Node *node,
     1712                                        CodeMarker *marker)
     1713{
     1714    Text breadcrumb;
     1715    if (node->type() == Node::Class) {
     1716        const ClassNode* cn = static_cast<const ClassNode*>(node);
     1717        QString name =  node->moduleName();
     1718        out() << "              <li><a href=\"modules.html\">Modules</a></li>";
     1719        if (!name.isEmpty()) {
     1720            out() << "              <li>";
     1721            breadcrumb << Atom(Atom::AutoLink,name);
     1722            generateText(breadcrumb, node, marker);
     1723            out() << "</li>\n";
     1724        }
     1725        if (!cn->name().isEmpty())
     1726            out() << "              <li>" << protectEnc(cn->name()) << "</li>\n";
     1727    }
     1728    else if (node->type() == Node::Fake) {
     1729        const FakeNode* fn = static_cast<const FakeNode*>(node);
     1730        if (node->subType() == Node::Module) {
     1731            out() << "              <li><a href=\"modules.html\">Modules</a></li>";
     1732            QString name =  node->name();
     1733            if (!name.isEmpty())
     1734                out() << "              <li>" << protectEnc(name) << "</li>\n";
     1735        }
     1736        else if (node->subType() == Node::Group) {
     1737            if (fn->name() == QString("modules"))
     1738                out() << "              <li>Modules</li>";
     1739            else {
     1740                out() << "              <li>" << protectEnc(title) << "</li>";
     1741            }
     1742        }
     1743        else if (node->subType() == Node::Page) {
     1744            if (fn->name() == QString("qdeclarativeexamples.html")) {
     1745                out() << "              <li><a href=\"all-examples.html\">Examples</a></li>";
     1746                out() << "              <li>QML Examples &amp; Demos</li>";
     1747            }
     1748            else if (fn->name().startsWith("examples-")) {
     1749                out() << "              <li><a href=\"all-examples.html\">Examples</a></li>";
     1750                out() << "              <li>" << protectEnc(title) << "</li>";
     1751            }
     1752            else if (fn->name() == QString("namespaces.html")) {
     1753                out() << "              <li>Namespaces</li>";
     1754            }
     1755            else {
     1756                out() << "              <li>" << protectEnc(title) << "</li>";
     1757            }
     1758        }
     1759        else if (node->subType() == Node::QmlClass) {
     1760            out() << "              <li><a href=\"qdeclarativeelements.html\">QML Elements</a></li>";
     1761            out() << "              <li>" << protectEnc(title) << "</li>";
     1762        }
     1763        else if (node->subType() == Node::Example) {
     1764            out() << "              <li><a href=\"all-examples.html\">Examples</a></li>";
     1765            QStringList sl = fn->name().split('/');
     1766            if (sl.contains("declarative"))
     1767                out() << "              <li><a href=\"qdeclarativeexamples.html\">QML Examples &amp; Demos</a></li>";
     1768            else {
     1769                QString name = protectEnc("examples-" + sl.at(0) + ".html"); // this generates an empty link
     1770                QString t = CodeParser::titleFromName(name);
     1771            }
     1772            out() << "              <li>" << protectEnc(title) << "</li>";
     1773        }
     1774    }
     1775    else if (node->type() == Node::Namespace) {
     1776        out() << "              <li><a href=\"namespaces.html\">Namespaces</a></li>";
     1777        out() << "              <li>" << protectEnc(title) << "</li>";
     1778    }
    16201779}
    16211780
    16221781void HtmlGenerator::generateHeader(const QString& title,
    16231782                                   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 
     1783                                   CodeMarker *marker)
     1784{
     1785    out() << QString("<?xml version=\"1.0\" encoding=\"%1\"?>\n").arg(outputEncoding);
     1786    out() << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
     1787    out() << QString("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"%1\" lang=\"%1\">\n").arg(naturalLanguage);
     1788    out() << "<head>\n";
     1789    out() << "  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
    16331790    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();
     1791    shortVersion = project + " " + shortVersion + ": ";
     1792    if (node && !node->doc().location().isEmpty())
     1793        out() << "<!-- " << node->doc().location().fileName() << " -->\n";
     1794
     1795    shortVersion = myTree->version();
     1796    if (shortVersion.count(QChar('.')) == 2)
     1797        shortVersion.truncate(shortVersion.lastIndexOf(QChar('.')));
     1798    if (!shortVersion.isEmpty()) {
     1799        if (project == "QSA")
     1800            shortVersion = "QSA " + shortVersion + ": ";
     1801        else
     1802            shortVersion = "Qt " + shortVersion + ": ";
     1803    }
     1804
     1805    // Generating page title
     1806    out() << "  <title>" << shortVersion << protectEnc(title) << "</title>\n";
     1807    // Adding style sheet
     1808    out() << "  <link rel=\"stylesheet\" type=\"text/css\" href=\"style/style.css\" />\n";
     1809    // Adding jquery and functions - providing online tools and search features
     1810    out() << "  <script src=\"scripts/jquery.js\" type=\"text/javascript\"></script>\n";
     1811    out() << "  <script src=\"scripts/functions.js\" type=\"text/javascript\"></script>\n";
     1812
     1813
     1814    // Adding syntax highlighter         // future release
     1815
     1816    // Setting some additional style sheet related details depending on configuration (e.g. Online/Creator)
     1817
     1818    switch (application) {
     1819    case Online:
     1820    // Adding style and js for small windows
     1821        out() << "  <script src=\"./scripts/superfish.js\" type=\"text/javascript\"></script>\n";
     1822        out() << "  <link rel=\"stylesheet\" type=\"text/css\" href=\"style/superfish.css\" />";
     1823        out() << "  <script src=\"./scripts/narrow.js\" type=\"text/javascript\"></script>\n";
     1824        out() << "  <link rel=\"stylesheet\" type=\"text/css\" href=\"style/narrow.css\" />\n";
     1825        // Browser spec styles
     1826        out() << "  <!--[if IE]>\n";
     1827        out() << "<meta name=\"MSSmartTagsPreventParsing\" content=\"true\">\n";
     1828        out() << "<meta http-equiv=\"imagetoolbar\" content=\"no\">\n";
     1829        out() << "<![endif]-->\n";
     1830        out() << "<!--[if lt IE 7]>\n";
     1831        out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie6.css\">\n";
     1832        out() << "<![endif]-->\n";
     1833        out() << "<!--[if IE 7]>\n";
     1834        out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie7.css\">\n";
     1835        out() << "<![endif]-->\n";
     1836        out() << "<!--[if IE 8]>\n";
     1837        out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie8.css\">\n";
     1838        out() << "<![endif]-->\n";
     1839
     1840        out() << "</head>\n";
     1841        // CheckEmptyAndLoadList activating search
     1842        out() << "<body class=\"\" onload=\"CheckEmptyAndLoadList();\">\n";
     1843        break;
     1844    case Creator:
     1845        out() << "</head>\n";
     1846        out() << "<body class=\"offline narrow creator\">\n"; // offline narrow
     1847        break;
     1848    default:
     1849        out() << "</head>\n";
     1850        out() << "<body>\n";
     1851        break;
     1852    }
     1853
     1854#ifdef GENERATE_MAC_REFS   
     1855    if (mainPage)
     1856        generateMacRef(node, marker);
     1857#endif   
     1858 
     1859    switch (application) {
     1860    case Online:
     1861        out() << QString(postHeader).replace("\\" + COMMAND_VERSION, myTree->version());
     1862        generateBreadCrumbs(title,node,marker);
     1863        out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, myTree->version());
     1864        break;
     1865    case Creator:
     1866        out() << QString(creatorPostHeader).replace("\\" + COMMAND_VERSION, myTree->version());
     1867        generateBreadCrumbs(title,node,marker);
     1868        out() << QString(creatorPostPostHeader).replace("\\" + COMMAND_VERSION, myTree->version());
     1869        break;
     1870    default: // default -- not used except if one forgets to set any of the above settings to true
     1871        out() << QString(creatorPostHeader).replace("\\" + COMMAND_VERSION, myTree->version());
     1872        generateBreadCrumbs(title,node,marker);
     1873        out() << QString(creatorPostPostHeader).replace("\\" + COMMAND_VERSION, myTree->version());
     1874        break;
     1875    }
     1876
     1877        navigationLinks.clear();
    16661878
    16671879    if (node && !node->links().empty()) {
     
    16881900            navigationLinks += "</a>]\n";
    16891901        }
    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         }
    17081902        if (node->links().contains(Node::NextLink)) {
    17091903            linkPair = node->links()[Node::NextLink];
     
    17231917                navigationLinks += protect(linkPair.second);
    17241918            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";
    17351919        }
    17361920        if (node->links().contains(Node::StartLink)) {
     
    17461930    }
    17471931
    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 
    17641932    if (node && !node->links().empty())
    1765         out() << "<p>\n" << navigationLinks << "</p>\n";
     1933        out() << "<p class=\"naviNextPrevious headerNavi\">\n" << navigationLinks << "</p><p/>\n";
    17661934}
    17671935
     
    17721940                                  CodeMarker *marker)
    17731941{
    1774     out() << "<h1 class=\"title\">" << protect(title);
     1942    if (!title.isEmpty())
     1943        out() << "<h1 class=\"title\">" << protectEnc(title) << "</h1>\n";
    17751944    if (!subTitle.isEmpty()) {
    1776         out() << "<br />";
     1945        out() << "<span";
    17771946        if (subTitleSize == SmallSubTitle)
    1778             out() << "<span class=\"small-subtitle\">";
     1947            out() << " class=\"small-subtitle\">";
    17791948        else
    1780             out() << "<span class=\"subtitle\">";
     1949            out() << " class=\"subtitle\">";
    17811950        generateText(subTitle, relative, marker);
    17821951        out() << "</span>\n";
    17831952    }
    1784     out() << "</h1>\n";
    17851953}
    17861954
     
    17881956{
    17891957    if (node && !node->links().empty())
    1790         out() << "<p>\n" << navigationLinks << "</p>\n";
     1958        out() << "<p class=\"naviNextPrevious footerNavi\">\n" << navigationLinks << "</p>\n";
    17911959
    17921960    out() << QString(footer).replace("\\" + COMMAND_VERSION, myTree->version())
    1793           << QString(address).replace("\\" + COMMAND_VERSION, myTree->version())
    1794           << "</body>\n"
    1795              "</html>\n";
     1961          << QString(address).replace("\\" + COMMAND_VERSION, myTree->version());
     1962
     1963    switch (application) {
     1964    case Online:
     1965        out() << "  <script src=\"scripts/functions.js\" type=\"text/javascript\"></script>\n";
     1966        out() << "  <script type=\"text/javascript\">\n";
     1967        out() << "  var _gaq = _gaq || [];\n";
     1968        out() << "  _gaq.push(['_setAccount', 'UA-4457116-5']);\n";
     1969        out() << "  _gaq.push(['_trackPageview']);\n";
     1970        out() << "  (function() {\n";
     1971        out() << "  var ga = document.createElement('script'); ";
     1972        out() << "ga.type = 'text/javascript'; ga.async = true;\n";
     1973        out() << "  ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + ";
     1974        out() << "'.google-analytics.com/ga.js';\n";
     1975        out() << "  var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);\n";
     1976        out() << "  })();\n";
     1977        out() << "  </script>\n";
     1978        out() << "</body>\n";
     1979        break;
     1980    case Creator:
     1981        out() << "</body>\n";
     1982        break;
     1983    default:
     1984        out() << "</body>\n";
     1985    }
     1986          out() <<   "</html>\n";
    17961987}
    17971988
     
    18011992    Text brief = node->doc().briefText();
    18021993    if (!brief.isEmpty()) {
     1994        generateExtractionMark(node, BriefMark);
    18031995        out() << "<p>";
    18041996        generateText(brief, node, marker);
     1997
    18051998        if (!relative || node == relative)
    18061999            out() << " <a href=\"#";
     
    18082001            out() << " <a href=\"" << linkForNode(node, relative) << "#";
    18092002        out() << registerRef("details") << "\">More...</a></p>\n";
     2003
     2004
     2005        generateExtractionMark(node, EndMark);
    18102006    }
    18112007}
     
    18142010{
    18152011    if (!inner->includes().isEmpty()) {
    1816         out() << "<pre>"
     2012        out() << "<pre class=\"highlightedCode brush: cpp\">"
    18172013              << trimmedTrailing(highlightedCode(indent(codeIndent,
    18182014                                                        marker->markedUpIncludes(inner->includes())),
     
    18222018}
    18232019
     2020/*!
     2021  Generates a table of contents beginning at \a node.
     2022 */
    18242023void HtmlGenerator::generateTableOfContents(const Node *node,
    18252024                                            CodeMarker *marker,
     
    18292028
    18302029{
     2030    return;
    18312031    if (!node->doc().hasTableOfContents())
    18322032        return;
     
    18442044    QString tdTag;
    18452045    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\">"
     2046        tdTag = "<td>"; /* width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";*/
     2047        out() << "<table class=\"toc\">\n<tr class=\"topAlign\">"
    18482048              << tdTag << "\n";
    18492049    }
     
    18972097
    18982098    if (numColumns > 1)
    1899         out() << "</td></tr></table></p>\n";
    1900 
     2099        out() << "</td></tr></table>\n";
     2100
     2101    inContents = false;
     2102    inLink = false;
     2103}
     2104
     2105/*!
     2106  Revised for the new doc format.
     2107  Generates a table of contents beginning at \a node.
     2108 */
     2109void HtmlGenerator::generateTableOfContents(const Node *node,
     2110                                            CodeMarker *marker,
     2111                                            QList<Section>* sections)
     2112{
     2113    QList<Atom*> toc;
     2114    if (node->doc().hasTableOfContents())
     2115        toc = node->doc().tableOfContents();
     2116    if (toc.isEmpty() && !sections && (node->subType() != Node::Module))
     2117        return;
     2118
     2119    QStringList sectionNumber;
     2120    int detailsBase = 0;
     2121
     2122    // disable nested links in table of contents
     2123    inContents = true;
     2124    inLink = true;
     2125
     2126    out() << "<div class=\"toc\">\n";
     2127    out() << "<h3><a name=\"toc\">Contents</a></h3>\n";
     2128    sectionNumber.append("1");
     2129    out() << "<ul>\n";
     2130
     2131    if (node->subType() == Node::Module) {
     2132        if (moduleNamespaceMap.contains(node->name())) {
     2133            out() << "<li class=\"level"
     2134                  << sectionNumber.size()
     2135                  << "\"><a href=\"#"
     2136                  << registerRef("namespaces")
     2137                  << "\">Namespaces</a></li>\n";
     2138        }
     2139        if (moduleClassMap.contains(node->name())) {
     2140            out() << "<li class=\"level"
     2141                  << sectionNumber.size()
     2142                  << "\"><a href=\"#"
     2143                  << registerRef("classes")
     2144                  << "\">Classes</a></li>\n";
     2145        }
     2146        out() << "<li class=\"level"
     2147              << sectionNumber.size()
     2148              << "\"><a href=\"#"
     2149              << registerRef("details")
     2150              << "\">Detailed Description</a></li>\n";
     2151        for (int i = 0; i < toc.size(); ++i) {
     2152            if (toc.at(i)->string().toInt() == 1) {
     2153                detailsBase = 1;
     2154                break;
     2155            }
     2156        }
     2157    }
     2158    else if (sections && ((node->type() == Node::Class) ||
     2159                          (node->type() == Node::Namespace) ||
     2160                          (node->subType() == Node::QmlClass))) {
     2161        QList<Section>::ConstIterator s = sections->begin();
     2162        while (s != sections->end()) {
     2163            if (!s->members.isEmpty() || !s->reimpMembers.isEmpty()) {
     2164                out() << "<li class=\"level"
     2165                      << sectionNumber.size()
     2166                      << "\"><a href=\"#"
     2167                      << registerRef((*s).pluralMember)
     2168                      << "\">" << (*s).name
     2169                      << "</a></li>\n";
     2170            }
     2171            ++s;
     2172        }
     2173        out() << "<li class=\"level"
     2174              << sectionNumber.size()
     2175              << "\"><a href=\"#"
     2176              << registerRef("details")
     2177              << "\">Detailed Description</a></li>\n";
     2178        for (int i = 0; i < toc.size(); ++i) {
     2179            if (toc.at(i)->string().toInt() == 1) {
     2180                detailsBase = 1;
     2181                break;
     2182            }
     2183        }
     2184    }
     2185
     2186    for (int i = 0; i < toc.size(); ++i) {
     2187        Atom *atom = toc.at(i);
     2188        int nextLevel = atom->string().toInt() + detailsBase;
     2189        if (sectionNumber.size() < nextLevel) {
     2190            do {
     2191                sectionNumber.append("1");
     2192            } while (sectionNumber.size() < nextLevel);
     2193        }
     2194        else {
     2195            while (sectionNumber.size() > nextLevel) {
     2196                sectionNumber.removeLast();
     2197            }
     2198            sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1);
     2199        }
     2200        int numAtoms;
     2201        Text headingText = Text::sectionHeading(atom);
     2202        QString s = headingText.toString();
     2203        out() << "<li class=\"level"
     2204              << sectionNumber.size()
     2205              << "\">";
     2206        out() << "<a href=\""
     2207              << "#"
     2208              << Doc::canonicalTitle(s)
     2209              << "\">";
     2210        generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms);
     2211        out() << "</a></li>\n";
     2212    }
     2213    while (!sectionNumber.isEmpty()) {
     2214        sectionNumber.removeLast();
     2215    }
     2216    out() << "</ul>\n";
     2217    out() << "</div>\n";
    19012218    inContents = false;
    19022219    inLink = false;
     
    19102227    if (bar.prev.begin() != 0 || bar.current.begin() != 0 ||
    19112228         bar.next.begin() != 0) {
    1912         out() << "<p align=\"right\">";
     2229        out() << "<p class=\"rightAlign\">";
    19132230        if (bar.prev.begin() != 0) {
    19142231#if 0
     
    19192236#endif
    19202237        }
    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";
     2238        if (fake->name() != QString("index.html")) {
     2239            if (bar.current.begin() != 0) {
     2240                out() << "[<a href=\"" << "home"
     2241                      << ".html\">Home</a>]\n";
     2242            }
     2243            if (bar.next.begin() != 0) {
     2244                out() << "[<a href=\"" << fileBase(node, bar.next)
     2245                      << ".html\">Next: ";
     2246                generateText(Text::sectionHeading(bar.next.begin()), node, marker);
     2247                out() << "</a>]\n";
     2248            }
     2249            out() << "</p>\n";
     2250        }
    19322251    }
    19332252}
     
    19492268    beginSubPage(inner->location(), fileName);
    19502269    QString title = "List of All Members for " + inner->name();
    1951     generateHeader(title, inner, marker, false);
     2270    generateHeader(title, inner, marker);
    19522271    generateTitle(title, Text(), SmallSubTitle, inner, marker);
    19532272    out() << "<p>This is the complete list of members for ";
    19542273    generateFullName(inner, 0, marker);
     2274    out() << ", including inherited members.</p>\n";
     2275
     2276    Section section = sections.first();
     2277    generateSectionList(section, 0, marker, CodeMarker::SeparateList);
     2278
     2279    generateFooter();
     2280    endSubPage();
     2281    return fileName;
     2282}
     2283
     2284/*!
     2285  This function creates an html page on which are listed all
     2286  the members of QML class \a qml_cn, including the inherited
     2287  members. The \a marker is used for formatting stuff.
     2288 */
     2289QString HtmlGenerator::generateAllQmlMembersFile(const QmlClassNode* qml_cn,
     2290                                                 CodeMarker* marker)
     2291{
     2292    QList<Section> sections;
     2293    QList<Section>::ConstIterator s;
     2294
     2295    sections = marker->qmlSections(qml_cn,CodeMarker::SeparateList,myTree);
     2296    if (sections.isEmpty())
     2297        return QString();
     2298
     2299    QString fileName = fileBase(qml_cn) + "-members." + fileExtension(qml_cn);
     2300    beginSubPage(qml_cn->location(), fileName);
     2301    QString title = "List of All Members for " + qml_cn->name();
     2302    generateHeader(title, qml_cn, marker);
     2303    generateTitle(title, Text(), SmallSubTitle, qml_cn, marker);
     2304    out() << "<p>This is the complete list of members for ";
     2305    generateFullName(qml_cn, 0, marker);
    19552306    out() << ", including inherited members.</p>\n";
    19562307
     
    19932344
    19942345    beginSubPage(inner->location(), fileName);
    1995     generateHeader(title, inner, marker, false);
     2346    generateHeader(title, inner, marker);
    19962347    generateTitle(title, Text(), SmallSubTitle, inner, marker);
    19972348
     
    20102361    out() << "<p><ul><li><a href=\""
    20112362          << linkForNode(inner, 0) << "\">"
    2012           << protect(inner->name())
     2363          << protectEnc(inner->name())
    20132364          << " class reference</a></li></ul></p>\n";
    20142365
    20152366    for (i = 0; i < sections.size(); ++i) {
    2016         out() << "<h2>" << protect(sections.at(i).name) << "</h2>\n";
     2367        out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n";
    20172368        generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary);
    20182369    }
     
    20202371    sections = marker->sections(inner, CodeMarker::Detailed, status);
    20212372    for (i = 0; i < sections.size(); ++i) {
    2022         out() << "<hr />\n";
    2023         out() << "<h2>" << protect(sections.at(i).name) << "</h2>\n";
     2373        //out() << "<hr />\n";
     2374        out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n";
    20242375
    20252376        NodeList::ConstIterator m = sections.at(i).members.begin();
     
    20862437                                          const NodeMap &nodeMap)
    20872438{
    2088     out() << "<p><table width=\"100%\" class=\"annotated\" cellpadding=\"2\" "
    2089           << "cellspacing=\"1\" border=\"0\">\n";
     2439    out() << "<table class=\"annotated\">\n";
    20902440
    20912441    int row = 0;
     
    20972447
    20982448        if (++row % 2 == 1)
    2099             out() << "<tr valign=\"top\" class=\"odd\">";
     2449            out() << "<tr class=\"odd topAlign\">";
    21002450        else
    2101             out() << "<tr valign=\"top\" class=\"even\">";
    2102         out() << "<th>";
     2451            out() << "<tr class=\"even topAlign\">";
     2452        out() << "<td class=\"tblName\"><p>";
    21032453        generateFullName(node, relative, marker);
    2104         out() << "</th>";
     2454        out() << "</p></td>";
    21052455
    21062456        if (!(node->type() == Node::Fake)) {
    21072457            Text brief = node->doc().trimmedBriefText(name);
    21082458            if (!brief.isEmpty()) {
    2109                 out() << "<td>";
     2459                out() << "<td class=\"tblDescr\"><p>";
    21102460                generateText(brief, node, marker);
    2111                 out() << "</td>";
     2461                out() << "</p></td>";
    21122462            }
    21132463        }
    21142464        else {
    2115             out() << "<td>";
    2116             out() << protect(node->doc().briefText().toString());
    2117             out() << "</td>";
     2465            out() << "<td class=\"tblDescr\"><p>";
     2466            out() << protectEnc(node->doc().briefText().toString());
     2467            out() << "</p></td>";
    21182468        }
    21192469        out() << "</tr>\n";
    21202470    }
    2121     out() << "</table></p>\n";
     2471    out() << "</table>\n";
    21222472}
    21232473
     
    21342484                                        CodeMarker *marker,
    21352485                                        const NodeMap &classMap,
     2486                                        bool includeAlphabet,
    21362487                                        QString commonPrefix)
    21372488{
    21382489    const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_'
    2139     const int NumColumns = 4; // number of columns in the result
    21402490
    21412491    if (classMap.isEmpty())
     
    22062556    NodeMap paragraph[NumParagraphs+1];
    22072557    QString paragraphName[NumParagraphs+1];
     2558    QSet<char> usedParagraphNames;
    22082559
    22092560    NodeMap::ConstIterator c = classMap.begin();
     
    22192570            key = pieces.last().toLower();
    22202571
    2221         int paragraphNo = NumParagraphs - 1;
     2572        int paragraphNr = NumParagraphs - 1;
    22222573
    22232574        if (key[0].digitValue() != -1) {
    2224             paragraphNo = key[0].digitValue();
     2575            paragraphNr = key[0].digitValue();
    22252576        }
    22262577        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());
     2578            paragraphNr = 10 + key[0].unicode() - 'a';
     2579        }
     2580
     2581        paragraphName[paragraphNr] = key[0].toUpper();
     2582        usedParagraphNames.insert(key[0].toLower().cell());
     2583        paragraph[paragraphNr].insert(key, c.value());
    22322584        ++c;
    22332585    }
     
    22422594    */
    22432595    int paragraphOffset[NumParagraphs + 1];     // 37 + 1
    2244     int i, j, k;
    2245 
    22462596    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";
     2597    for (int i=0; i<NumParagraphs; i++)         // i = 0..36
     2598        paragraphOffset[i+1] = paragraphOffset[i] + paragraph[i].count();
     2599
     2600    int curParNr = 0;
     2601    int curParOffset = 0;
     2602
     2603    /*
     2604      Output the alphabet as a row of links.
     2605     */
     2606    if (includeAlphabet) {
     2607        out() << "<p  class=\"centerAlign functionIndex\"><b>";
     2608        for (int i = 0; i < 26; i++) {
     2609            QChar ch('a' + i);
     2610            if (usedParagraphNames.contains(char('a' + i)))
     2611                out() << QString("<a href=\"#%1\">%2</a>&nbsp;").arg(ch).arg(ch.toUpper());
     2612        }
     2613        out() << "</b></p>\n";
     2614    }
     2615
     2616    /*
     2617      Output a <div> element to contain all the <dl> elements.
     2618     */
     2619    out() << "<div class=\"flowListDiv\">\n";
     2620
     2621    for (int i=0; i<classMap.count()-1; i++) {
     2622        while ((curParNr < NumParagraphs) &&
     2623               (curParOffset == paragraph[curParNr].count())) {
     2624            ++curParNr;
     2625            curParOffset = 0;
     2626        }
     2627
     2628        /*
     2629          Starting a new paragraph means starting a new <dl>.
     2630        */
     2631        if (curParOffset == 0) {
     2632            if (i > 0)
     2633                out() << "</dl>\n";
     2634            if (++numTableRows % 2 == 1)
     2635                out() << "<dl class=\"flowList odd\">";
     2636            else
     2637                out() << "<dl class=\"flowList even\">";
     2638            out() << "<dt class=\"alphaChar\">";
     2639            if (includeAlphabet) {
     2640                QChar c = paragraphName[curParNr][0].toLower();
     2641                out() << QString("<a name=\"%1\"></a>").arg(c);
     2642            }
     2643            out() << "<b>"
     2644                  << paragraphName[curParNr]
     2645                  << "</b>";
     2646            out() << "</dt>\n";
     2647        }
     2648
     2649        /*
     2650          Output a <dd> for the current offset in the current paragraph.
     2651         */
     2652        out() << "<dd>";
     2653        if ((curParNr < NumParagraphs) &&
     2654            !paragraphName[curParNr].isEmpty()) {
     2655            NodeMap::Iterator it;
     2656            it = paragraph[curParNr].begin();
     2657            for (int i=0; i<curParOffset; i++)
     2658                ++it;
     2659
     2660            /*
     2661              Previously, we used generateFullName() for this, but we
     2662              require some special formatting.
     2663            */
     2664            out() << "<a href=\"" << linkForNode(it.value(), relative) << "\">";
     2665           
     2666            QStringList pieces;
     2667            if (it.value()->subType() == Node::QmlClass)
     2668                pieces << it.value()->name();
     2669            else
     2670                pieces = fullName(it.value(), relative, marker).split("::");
     2671            out() << protectEnc(pieces.last());
     2672            out() << "</a>";
     2673            if (pieces.size() > 1) {
     2674                out() << " (";
     2675                generateFullName(it.value()->parent(), relative, marker);
     2676                out() << ")";
     2677            }
     2678        }
     2679        out() << "</dd>\n";
     2680        curParOffset++;
     2681    }
     2682    out() << "</dl>\n";
     2683    out() << "</div>\n";
    23352684}
    23362685
     
    23382687                                          CodeMarker *marker)
    23392688{
    2340     out() << "<p align=\"center\"><font size=\"+1\"><b>";
     2689    out() << "<p  class=\"centerAlign functionIndex\"><b>";
    23412690    for (int i = 0; i < 26; i++) {
    23422691        QChar ch('a' + i);
    23432692        out() << QString("<a href=\"#%1\">%2</a>&nbsp;").arg(ch).arg(ch.toUpper());
    23442693    }
    2345     out() << "</b></font></p>\n";
     2694    out() << "</b></p>\n";
    23462695
    23472696    char nextLetter = 'a';
     
    23582707        out() << "<p>";
    23592708#endif
    2360         out() << protect(f.key()) << ":";
     2709        out() << protectEnc(f.key()) << ":";
    23612710
    23622711        currentLetter = f.key()[0].unicode();
     
    23912740    while (it != legaleseTexts.end()) {
    23922741        Text text = it.key();
    2393         out() << "<hr />\n";
     2742        //out() << "<hr />\n";
    23942743        generateText(text, relative, marker);
    23952744        out() << "<ul>\n";
     
    24042753}
    24052754
    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 
    24442755#ifdef QDOC_QML
    24452756void HtmlGenerator::generateQmlItem(const Node *node,
     
    24512762    QRegExp templateTag("(<[^@>]*>)");
    24522763    if (marked.indexOf(templateTag) != -1) {
    2453         QString contents = protect(marked.mid(templateTag.pos(1),
     2764        QString contents = protectEnc(marked.mid(templateTag.pos(1),
    24542765                                              templateTag.cap(1).length()));
    24552766        marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
     
    24642775        marked.replace("@name>", "b>");
    24652776
    2466     marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
     2777    marked.replace("<@extra>", "<tt>");
    24672778    marked.replace("</@extra>", "</tt>");
    24682779
     
    24712782        marked.replace("</@type>", "");
    24722783    }
    2473     out() << highlightedCode(marked, marker, relative);
     2784    out() << highlightedCode(marked, marker, relative, false, node);
    24742785}
    24752786#endif
     
    25572868            out() << QString("<h3><a href=\"%1\">%2</a></h3>\n").arg(
    25582869                        linkForNode(groupNode, relative)).arg(
    2559                         protect(groupNode->fullTitle()));
     2870                        protectEnc(groupNode->fullTitle()));
    25602871
    25612872            if (fakeNodeMap[groupNode].count() == 0)
     
    25692880                    title.remove(0, 4);
    25702881                out() << "<li><a href=\"" << linkForNode(fakeNode, relative) << "\">"
    2571                       << protect(title) << "</a></li>\n";
     2882                      << protectEnc(title) << "</a></li>\n";
    25722883            }
    25732884            out() << "</ul>\n";
     
    25832894                title.remove(0, 4);
    25842895            out() << "<li><a href=\"" << linkForNode(fakeNode, relative) << "\">"
    2585                   << protect(title) << "</a></li>\n";
     2896                  << protectEnc(title) << "</a></li>\n";
    25862897        }
    25872898        out() << "</ul>\n";
     
    25892900}
    25902901
    2591 #ifdef QDOC_NAME_ALIGNMENT
    25922902void HtmlGenerator::generateSection(const NodeList& nl,
    25932903                                    const Node *relative,
     
    25952905                                    CodeMarker::SynopsisStyle style)
    25962906{
    2597     bool name_alignment = true;
     2907    bool alignNames = true;
    25982908    if (!nl.isEmpty()) {
    25992909        bool twoColumn = false;
    26002910        if (style == CodeMarker::SeparateList) {
    2601             name_alignment = false;
     2911            alignNames = false;
    26022912            twoColumn = (nl.count() >= 16);
    26032913        }
    26042914        else if (nl.first()->type() == Node::Property) {
    26052915            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";
     2916            alignNames = false;
     2917        }
     2918        if (alignNames) {
     2919            out() << "<table class=\"alignedsummary\">\n";
    26112920        }
    26122921        else {
    26132922            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\">";
     2923                out() << "<table class=\"propsummary\">\n"
     2924                      << "<tr><td  class=\"topAlign\">";
    26182925            out() << "<ul>\n";
    26192926        }
     
    26272934            }
    26282935
    2629             if (name_alignment) {
    2630                 out() << "<tr><td class=\"memItemLeft\" "
    2631                       << "align=\"right\" valign=\"top\">";
     2936            if (alignNames) {
     2937                out() << "<tr><td class=\"memItemLeft rightAlign topAlign\"> ";
    26322938            }
    26332939            else {
    26342940                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)
     2941                    out() << "</ul></td><td  class=\"topAlign\"><ul>\n";
     2942                out() << "<li class=\"fn\">";
     2943            }
     2944
     2945            generateSynopsis(*m, relative, marker, style, alignNames);
     2946            if (alignNames)
    26412947                out() << "</td></tr>\n";
    26422948            else
    2643                 out() << "</div></li>\n";
     2949                out() << "</li>\n";
    26442950            i++;
    26452951            ++m;
    26462952        }
    2647         if (name_alignment)
     2953        if (alignNames)
    26482954            out() << "</table>\n";
    26492955        else {
    26502956            out() << "</ul>\n";
    26512957            if (twoColumn)
    2652                 out() << "</td></tr>\n</table></p>\n";
     2958                out() << "</td></tr>\n</table>\n";
    26532959        }
    26542960    }
     
    26602966                                        CodeMarker::SynopsisStyle style)
    26612967{
    2662     bool name_alignment = true;
     2968    bool alignNames = true;
    26632969    if (!section.members.isEmpty()) {
    26642970        bool twoColumn = false;
    26652971        if (style == CodeMarker::SeparateList) {
    2666             name_alignment = false;
     2972            alignNames = false;
    26672973            twoColumn = (section.members.count() >= 16);
    26682974        }
    26692975        else if (section.members.first()->type() == Node::Property) {
    26702976            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";
     2977            alignNames = false;
     2978        }
     2979        if (alignNames) {
     2980            out() << "<table class=\"alignedsummary\">\n";
    26762981        }
    26772982        else {
    26782983            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\">";
     2984                out() << "<table class=\"propsummary\">\n"
     2985                      << "<tr><td  class=\"topAlign\">";
    26832986            out() << "<ul>\n";
    26842987        }
     
    26922995            }
    26932996
    2694             if (name_alignment) {
    2695                 out() << "<tr><td class=\"memItemLeft\" "
    2696                       << "align=\"right\" valign=\"top\">";
     2997            if (alignNames) {
     2998                out() << "<tr><td class=\"memItemLeft topAlign rightAlign\"> ";
    26972999            }
    26983000            else {
    26993001                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)
     3002                    out() << "</ul></td><td class=\"topAlign\"><ul>\n";
     3003                out() << "<li class=\"fn\">";
     3004            }
     3005
     3006            generateSynopsis(*m, relative, marker, style, alignNames);
     3007            if (alignNames)
    27063008                out() << "</td></tr>\n";
    27073009            else
    2708                 out() << "</div></li>\n";
     3010                out() << "</li>\n";
    27093011            i++;
    27103012            ++m;
    27113013        }
    2712         if (name_alignment)
     3014        if (alignNames)
    27133015            out() << "</table>\n";
    27143016        else {
    27153017            out() << "</ul>\n";
    27163018            if (twoColumn)
    2717                 out() << "</td></tr>\n</table></p>\n";
     3019                out() << "</td></tr>\n</table>\n";
    27183020        }
    27193021    }
     
    27213023    if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
    27223024        out() << "<ul>\n";
    2723         generateSectionInheritedList(section, relative, marker, name_alignment);
     3025        generateSectionInheritedList(section, relative, marker);
    27243026        out() << "</ul>\n";
    27253027    }
     
    27283030void HtmlGenerator::generateSectionInheritedList(const Section& section,
    27293031                                                 const Node *relative,
    2730                                                  CodeMarker *marker,
    2731                                                  bool nameAlignment)
     3032                                                 CodeMarker *marker)
    27323033{
    27333034    QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
    27343035    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>";
     3036        out() << "<li class=\"fn\">";
    27393037        out() << (*p).second << " ";
    27403038        if ((*p).second == 1) {
     
    27463044        out() << " inherited from <a href=\"" << fileName((*p).first)
    27473045              << "#" << HtmlGenerator::cleanRef(section.name.toLower()) << "\">"
    2748               << protect(marker->plainFullName((*p).first, relative))
     3046              << protectEnc(marker->plainFullName((*p).first, relative))
    27493047              << "</a></li>\n";
    27503048        ++p;
     
    27563054                                     CodeMarker *marker,
    27573055                                     CodeMarker::SynopsisStyle style,
    2758                                      bool nameAlignment)
     3056                                     bool alignNames)
    27593057{
    27603058    QString marked = marker->markedUpSynopsis(node, relative, style);
    27613059    QRegExp templateTag("(<[^@>]*>)");
    27623060    if (marked.indexOf(templateTag) != -1) {
    2763         QString contents = protect(marked.mid(templateTag.pos(1),
     3061        QString contents = protectEnc(marked.mid(templateTag.pos(1),
    27643062                                              templateTag.cap(1).length()));
    27653063        marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
     
    27813079        marked.replace(extraRegExp, "");
    27823080    } else {
    2783         marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
     3081        marked.replace("<@extra>", "<tt>");
    27843082        marked.replace("</@extra>", "</tt>");
    27853083    }
     
    27893087        marked.replace("</@type>", "");
    27903088    }
    2791     out() << highlightedCode(marked, marker, relative, style, nameAlignment);
     3089    out() << highlightedCode(marked, marker, relative, alignNames);
    27923090}
    27933091
    27943092QString HtmlGenerator::highlightedCode(const QString& markedCode,
    2795                                        CodeMarker *marker,
    2796                                        const Node *relative,
    2797                                        CodeMarker::SynopsisStyle ,
    2798                                        bool nameAlignment)
     3093                                       CodeMarker* marker,
     3094                                       const Node* relative,
     3095                                       bool alignNames,
     3096                                       const Node* self)
    27993097{
    28003098    QString src = markedCode;
     
    28063104    const QChar charAt = '@';
    28073105
     3106    static const QString typeTag("type");
     3107    static const QString headerTag("headerfile");
     3108    static const QString funcTag("func");
     3109    static const QString linkTag("link");
     3110   
    28083111    // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)"
    2809     static const QString linkTag("link");
    28103112    bool done = false;
    2811     for (int i = 0, n = src.size(); i < n;) {
     3113    for (int i = 0, srcSize = src.size(); i < srcSize;) {
    28123114        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\">";
     3115            if (alignNames && !done) {// && (i != 0)) Why was this here?
     3116                html += "</td><td class=\"memItemRight bottomAlign\">";
    28153117                done = true;
    28163118            }
    28173119            i += 2;
    2818             if (parseArg(src, linkTag, &i, n, &arg, &par1)) {
     3120            if (parseArg(src, linkTag, &i, srcSize, &arg, &par1)) {
    28193121                html += "<b>";
    2820                 QString link = linkForNode(
    2821                     CodeMarker::nodeForString(par1.toString()), relative);
     3122                const Node* n = CodeMarker::nodeForString(par1.toString());
     3123                QString link = linkForNode(n, relative);
    28223124                addLink(link, arg, &html);
    28233125                html += "</b>";
     
    28393141        src = html;
    28403142        html = QString();
    2841         static const QString funcTag("func");
    2842         for (int i = 0, n = src.size(); i < n;) {
     3143        for (int i = 0, srcSize = src.size(); i < srcSize;) {
    28433144            if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
    28443145                i += 2;
    2845                 if (parseArg(src, funcTag, &i, n, &arg, &par1)) {
    2846                     QString link = linkForNode(
    2847                             marker->resolveTarget(par1.toString(),
    2848                                                   myTree,
    2849                                                   relative),
    2850                             relative);
     3146                if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) {
     3147                    const Node* n = marker->resolveTarget(par1.toString(),
     3148                                                          myTree,
     3149                                                          relative);
     3150                    QString link = linkForNode(n, relative);
    28513151                    addLink(link, arg, &html);
    28523152                    par1 = QStringRef();
     
    28663166    src = html;
    28673167    html = QString();
    2868     static const QString typeTags[] = { "type", "headerfile", "func" };
    2869     for (int i = 0, n = src.size(); i < n;) {
    2870         if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
     3168
     3169    for (int i=0, srcSize=src.size(); i<srcSize;) {
     3170        if (src.at(i) == charLangle && src.at(i+1) == charAt) {
    28713171            i += 2;
    28723172            bool handled = false;
    2873             for (int k = 0; k != 3; ++k) {
    2874                 if (parseArg(src, typeTags[k], &i, n, &arg, &par1)) {
    2875                     par1 = QStringRef();
    2876                     QString link = linkForNode(
    2877                             marker->resolveTarget(arg.toString(), myTree, relative),
    2878                             relative);
    2879                     addLink(link, arg, &html);
    2880                     handled = true;
    2881                     break;
     3173            if (parseArg(src, typeTag, &i, srcSize, &arg, &par1)) {
     3174                par1 = QStringRef();
     3175                const Node* n = marker->resolveTarget(arg.toString(), myTree, relative, self);
     3176                if (n && n->subType() == Node::QmlBasicType) {
     3177                    if (relative && relative->subType() == Node::QmlClass)
     3178                        addLink(linkForNode(n,relative), arg, &html);
     3179                    else
     3180                        html += arg.toString();
    28823181                }
    2883             }
     3182                else
     3183                    addLink(linkForNode(n,relative), arg, &html);
     3184                handled = true;
     3185            }
     3186            else if (parseArg(src, headerTag, &i, srcSize, &arg, &par1)) {
     3187                par1 = QStringRef();
     3188                const Node* n = marker->resolveTarget(arg.toString(), myTree, relative);
     3189                addLink(linkForNode(n,relative), arg, &html);
     3190                handled = true;
     3191            }
     3192            else if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) {
     3193                par1 = QStringRef();
     3194                const Node* n = marker->resolveTarget(arg.toString(), myTree, relative);
     3195                addLink(linkForNode(n,relative), arg, &html);
     3196                handled = true;
     3197            }
     3198
    28843199            if (!handled) {
    28853200                html += charLangle;
     
    29093224        "</@string>",      "</span>",
    29103225        "</@char>",        "</span>"
    2911         // "<@char>",      "<font color=blue>",
    2912         // "</@char>",     "</font>",
    2913         // "<@func>",      "<font color=green>",
    2914         // "</@func>",     "</font>",
    2915         // "<@id>",        "<i>",
    2916         // "</@id>",       "</i>",
    2917         // "<@keyword>",   "<b>",
    2918         // "</@keyword>",  "</b>",
    2919         // "<@number>",    "<font color=yellow>",
    2920         // "</@number>",   "</font>",
    2921         // "<@op>",        "<b>",
    2922         // "</@op>",       "</b>",
    2923         // "<@param>",     "<i>",
    2924         // "</@param>",    "</i>",
    2925         // "<@string>",    "<font color=green>",
    2926         // "</@string>",  "</font>",
    29273226    };
    29283227    for (int i = 0, n = src.size(); i < n;) {
     
    29623261}
    29633262
    2964 #else
    2965 void 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 
    3017 void 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 
    3038 void 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 
    3074 QString 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 
    32353263void HtmlGenerator::generateLink(const Atom* atom,
    32363264                                 const Node* /* relative */,
     
    32423270        // hack for C++: move () outside of link
    32433271        int k = funcLeftParen.pos(1);
    3244         out() << protect(atom->string().left(k));
     3272        out() << protectEnc(atom->string().left(k));
    32453273        if (link.isEmpty()) {
    32463274            if (showBrokenLinks)
     
    32503278        }
    32513279        inLink = false;
    3252         out() << protect(atom->string().mid(k));
     3280        out() << protectEnc(atom->string().mid(k));
    32533281    } else if (marker->recognizeLanguage("Java")) {
    3254         // hack for Java: remove () and use <tt> when appropriate
     3282        // hack for Java: remove () and use <tt> when appropriate
    32553283        bool func = atom->string().endsWith("()");
    32563284        bool tt = (func || atom->string().contains(camelCase));
     
    32583286            out() << "<tt>";
    32593287        if (func) {
    3260             out() << protect(atom->string().left(atom->string().length() - 2));
     3288            out() << protectEnc(atom->string().left(atom->string().length() - 2));
    32613289        } else {
    3262             out() << protect(atom->string());
     3290            out() << protectEnc(atom->string());
    32633291        }
    32643292        out() << "</tt>";
    32653293    } else {
    3266         out() << protect(atom->string());
     3294        out() << protectEnc(atom->string());
    32673295    }
    32683296}
     
    33383366}
    33393367
    3340 QString HtmlGenerator::protect(const QString& string)
     3368QString HtmlGenerator::protectEnc(const QString &string)
     3369{
     3370    return protect(string, outputEncoding);
     3371}
     3372
     3373QString HtmlGenerator::protect(const QString &string, const QString &outputEncoding)
    33413374{
    33423375#define APPEND(x) \
     
    33613394        } else if (ch == QLatin1Char('"')) {
    33623395            APPEND("&quot;");
    3363         } else if (ch.unicode() > 0x007F
     3396        } else if ((outputEncoding == "ISO-8859-1" && ch.unicode() > 0x007F)
    33643397                   || (ch == QLatin1Char('*') && i + 1 < n && string.at(i) == QLatin1Char('/'))
    33653398                   || (ch == QLatin1Char('.') && i > 2 && string.at(i - 2) == QLatin1Char('.'))) {
     
    33813414}
    33823415
    3383 QString HtmlGenerator::fileBase(const Node *node)
     3416QString HtmlGenerator::fileBase(const Node *node) const
    33843417{
    33853418    QString result;
     
    34913524        break;
    34923525    case Node::Target:
    3493         return protect(node->name());
     3526        return protectEnc(node->name());
    34943527    }
    34953528    return registerRef(ref);
     
    35103543    if (node->access() == Node::Private)
    35113544        return QString();
    3512 
     3545 
    35133546    fn = fileName(node);
    3514 /*    if (!node->url().isEmpty())
    3515         return fn;*/
     3547#if 0
     3548    if (!node->url().isEmpty())
     3549        return fn;
     3550#endif   
     3551
    35163552#if 0
    35173553    // ### reintroduce this test, without breaking .dcf files
     
    35653601    }
    35663602    out() << "\">";
    3567     out() << protect(fullName(apparentNode, relative, marker));
     3603    out() << protectEnc(fullName(apparentNode, relative, marker));
    35683604    out() << "</a>";
    35693605}
     
    35753611    const EnumNode *enume;
    35763612
     3613#ifdef GENERATE_MAC_REFS   
    35773614    generateMacRef(node, marker);
     3615#endif   
     3616    generateExtractionMark(node, MemberMark);
    35783617    if (node->type() == Node::Enum
    35793618            && (enume = static_cast<const EnumNode *>(node))->flagsType()) {
     3619#ifdef GENERATE_MAC_REFS   
    35803620        generateMacRef(enume->flagsType(), marker);
     3621#endif       
    35813622        out() << "<h3 class=\"flags\">";
    35823623        out() << "<a name=\"" + refForNode(node) + "\"></a>";
    35833624        generateSynopsis(enume, relative, marker, CodeMarker::Detailed);
    3584         out() << "<br />";
     3625        out() << "<br/>";
    35853626        generateSynopsis(enume->flagsType(),
    35863627                         relative,
     
    35933634        out() << "<a name=\"" + refForNode(node) + "\"></a>";
    35943635        generateSynopsis(node, relative, marker, CodeMarker::Detailed);
    3595         out() << "</h3>\n";
     3636        out() << "</h3>" << divNavTop << "\n";
    35963637    }
    35973638
     
    36263667        const EnumNode *enume = static_cast<const EnumNode *>(node);
    36273668        if (enume->flagsType()) {
    3628             out() << "<p>The " << protect(enume->flagsType()->name())
     3669            out() << "<p>The " << protectEnc(enume->flagsType()->name())
    36293670                  << " type is a typedef for "
    36303671                  << "<a href=\"qflags.html\">QFlags</a>&lt;"
    3631                   << protect(enume->name())
     3672                  << protectEnc(enume->name())
    36323673                  << "&gt;. It stores an OR combination of "
    3633                   << protect(enume->name())
     3674                  << protectEnc(enume->name())
    36343675                  << " values.</p>\n";
    36353676        }
    36363677    }
    36373678    generateAlsoList(node, marker);
     3679    generateExtractionMark(node, EndMark);
    36383680}
    36393681
     
    36773719                    serviceClasses.insert(serviceName, *c);
    36783720            }
     3721            else if ((*c)->type() == Node::Fake &&
     3722                     (*c)->subType() == Node::QmlClass &&
     3723                     !(*c)->doc().isEmpty()) {
     3724                QString qmlClassName = (*c)->name();
     3725                // Remove the "QML:" prefix if present.
     3726                if (qmlClassName.startsWith(QLatin1String("QML:")))
     3727                    qmlClasses.insert(qmlClassName.mid(4),*c);
     3728                else
     3729                    qmlClasses.insert(qmlClassName,*c);
     3730            }
    36793731            else if ((*c)->isInnerNode()) {
    36803732                findAllClasses(static_cast<InnerNode *>(*c));
     
    37013753            if (ncmap == newClassMaps.end())
    37023754                ncmap = newClassMaps.insert(sinceVersion,NodeMap());
     3755            NewClassMaps::iterator nqcmap = newQmlClassMaps.find(sinceVersion);
     3756            if (nqcmap == newQmlClassMaps.end())
     3757                nqcmap = newQmlClassMaps.insert(sinceVersion,NodeMap());
    37033758 
    37043759            if ((*child)->type() == Node::Function) {
     
    37203775                    ncmap.value().insert(className,(*child));
    37213776                }
     3777                else if ((*child)->subType() == Node::QmlClass) {
     3778                    QString className = (*child)->name();
     3779                    if ((*child)->parent() &&
     3780                        (*child)->parent()->type() == Node::Namespace &&
     3781                        !(*child)->parent()->name().isEmpty())
     3782                        className = (*child)->parent()->name()+"::"+className;
     3783                    nsmap.value().insert(className,(*child));
     3784                    nqcmap.value().insert(className,(*child));
     3785                }
    37223786            }
    37233787            else {
     
    37363800    }
    37373801}
    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
    37453802
    37463803void HtmlGenerator::findAllFunctions(const InnerNode *node)
     
    38073864}
    38083865
    3809 #ifdef ZZZ_QDOC_QML
    3810 /*!
    3811   This function finds all the qml element nodes and
    3812   stores them in a map for later use.
    3813  */
    3814 void HtmlGenerator::findAllQmlClasses(const InnerNode *node)
    3815 {
    3816     NodeList::const_iterator c = node->childNodes().constBegin();
    3817     while (c != node->childNodes().constEnd()) {
    3818         if ((*c)->type() == Node::Fake) {
    3819             const FakeNode* fakeNode = static_cast<const FakeNode *>(*c);
    3820             if (fakeNode->subType() == Node::QmlClass) {
    3821                 const QmlClassNode* qmlNode =
    3822                     static_cast<const QmlClassNode*>(fakeNode);
    3823                 const Node* n = qmlNode->classNode();
    3824             }
    3825             qmlClasses.insert(fakeNode->name(),*c);
    3826         }
    3827         ++c;
    3828     }
    3829 }
    3830 #endif
    3831 
    38323866int HtmlGenerator::hOffset(const Node *node)
    38333867{
     
    38373871        return 2;
    38383872    case Node::Fake:
    3839         if (node->doc().briefText().isEmpty())
    3840             return 1;
    3841         else
    3842             return 2;
     3873        return 1;
    38433874    case Node::Enum:
    38443875    case Node::Typedef:
     
    39403971        else {
    39413972            *node = marker->resolveTarget(first, myTree, relative);
    3942             if (!*node)
     3973            if (!*node) {
    39433974                *node = myTree->findFakeNodeByTitle(first);
    3944             if (!*node)
     3975            }
     3976            if (!*node) {
    39453977                *node = myTree->findUnambiguousTarget(first, targetAtom);
     3978            }
    39463979        }
    39473980
     
    40364069    case Node::Obsolete:
    40374070        if (node->isInnerNode())
    4038             Generator::generateStatus(node, marker);
     4071            Generator::generateStatus(node, marker);
    40394072        break;
    40404073    case Node::Compat:
     
    40784111}
    40794112
     4113#ifdef GENERATE_MAC_REFS   
     4114/*
     4115  No longer valid.
     4116 */
    40804117void HtmlGenerator::generateMacRef(const Node *node, CodeMarker *marker)
    40814118{
     
    40874124        out() << "<a name=\"" << "//apple_ref/" << macRef << "\"></a>\n";
    40884125}
     4126#endif
    40894127
    40904128void HtmlGenerator::beginLink(const QString &link,
     
    41384176}
    41394177
    4140 QT_END_NAMESPACE
    4141 
    41424178#ifdef QDOC_QML
    41434179
    41444180/*!
    4145   Generates the summary for for the \a section. Only used for
     4181  Generates the summary for the \a section. Only used for
    41464182  sections of QML element documentation.
    41474183
     
    41534189{
    41544190    if (!section.members.isEmpty()) {
     4191        out() << "<ul>\n";
    41554192        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;
    41684193        m = section.members.begin();
    41694194        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>";
     4195            out() << "<li class=\"fn\">";
    41734196            generateQmlItem(*m,relative,marker,true);
    41744197            out() << "</li>\n";
    4175             row++;
    41764198            ++m;
    41774199        }
    41784200        out() << "</ul>\n";
    4179         if (twoColumn)
    4180             out() << "</td></tr>\n</table></p>\n";
    41814201    }
    41824202}
     
    41914211{
    41924212    const QmlPropertyNode* qpn = 0;
     4213#ifdef GENERATE_MAC_REFS   
    41934214    generateMacRef(node, marker);
     4215#endif   
     4216    generateExtractionMark(node, MemberMark);
    41944217    out() << "<div class=\"qmlitem\">";
    41954218    if (node->subType() == Node::QmlPropertyGroup) {
     
    41974220        NodeList::ConstIterator p = qpgn->childNodes().begin();
    41984221        out() << "<div class=\"qmlproto\">";
    4199         out() << "<table width=\"100%\" class=\"qmlname\">";
     4222        out() << "<table class=\"qmlname\">";
    42004223
    42014224        while (p != qpgn->childNodes().end()) {
    42024225            if ((*p)->type() == Node::QmlProperty) {
    42034226                qpn = static_cast<const QmlPropertyNode*>(*p);
    4204                 out() << "<tr><td>";
     4227                if (++numTableRows % 2 == 1)
     4228                    out() << "<tr class=\"odd\">";
     4229                else
     4230                    out() << "<tr class=\"even\">";
     4231
     4232                out() << "<td class=\"tblQmlPropNode\"><p>";
     4233
    42054234                out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
    4206                 if (!qpn->isWritable())
     4235
     4236                if (!qpn->isWritable(myTree)) {
    42074237                    out() << "<span class=\"qmlreadonly\">read-only</span>";
     4238                }
     4239                if (qpgn->isDefault())
     4240                    out() << "<span class=\"qmldefault\">default</span>";
    42084241                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                 }
     4242                out() << "</p></td></tr>";
    42194243            }
    42204244            ++p;
     
    42274251        out() << "<div class=\"qmlproto\">";
    42284252        out() << "<table class=\"qmlname\">";
    4229         out() << "<tr><td>";
     4253        //out() << "<tr>";
     4254        if (++numTableRows % 2 == 1)
     4255            out() << "<tr class=\"odd\">";
     4256        else
     4257            out() << "<tr class=\"even\">";
     4258        out() << "<td class=\"tblQmlFuncNode\"><p>";
    42304259        out() << "<a name=\"" + refForNode(qsn) + "\"></a>";
    42314260        generateSynopsis(qsn,relative,marker,CodeMarker::Detailed,false);
    42324261        //generateQmlItem(qsn,relative,marker,false);
    4233         out() << "</td></tr>";
     4262        out() << "</p></td></tr>";
    42344263        out() << "</table>";
    42354264        out() << "</div>";
     
    42394268        out() << "<div class=\"qmlproto\">";
    42404269        out() << "<table class=\"qmlname\">";
    4241         out() << "<tr><td>";
     4270        //out() << "<tr>";
     4271        if (++numTableRows % 2 == 1)
     4272            out() << "<tr class=\"odd\">";
     4273        else
     4274            out() << "<tr class=\"even\">";
     4275        out() << "<td class=\"tblQmlFuncNode\"><p>";
    42424276        out() << "<a name=\"" + refForNode(qmn) + "\"></a>";
    42434277        generateSynopsis(qmn,relative,marker,CodeMarker::Detailed,false);
    4244         out() << "</td></tr>";
     4278        out() << "</p></td></tr>";
    42454279        out() << "</table>";
    42464280        out() << "</div>";
     
    42544288    out() << "</div>";
    42554289    out() << "</div>";
     4290    generateExtractionMark(node, EndMark);
    42564291}
    42574292
     
    42714306            if (n && n->subType() == Node::QmlClass) {
    42724307                const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n);
    4273                 out() << "<p style=\"text-align: center\">";
    42744308                Text text;
    4275                 text << "[Inherits ";
     4309                text << Atom::ParaLeft << "Inherits ";
    42764310                text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
    42774311                text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
    42784312                text << Atom(Atom::String, linkPair.second);
    42794313                text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
    4280                 text << "]";
     4314                text << Atom::ParaRight;
    42814315                generateText(text, cn, marker);
    4282                 out() << "</p>";
    4283             }
     4316            }
     4317        }
     4318    }
     4319}
     4320
     4321/*!
     4322  Output the "Inherit by" list for the QML element,
     4323  if it is inherited by any other elements.
     4324 */
     4325void HtmlGenerator::generateQmlInheritedBy(const QmlClassNode* cn,
     4326                                           CodeMarker* marker)
     4327{
     4328    if (cn) {
     4329        NodeList subs;
     4330        QmlClassNode::subclasses(cn->name(),subs);
     4331        if (!subs.isEmpty()) {
     4332            Text text;
     4333            text << Atom::ParaLeft << "Inherited by ";
     4334            appendSortedQmlNames(text,cn,subs,marker);
     4335            text << Atom::ParaRight;
     4336            generateText(text, cn, marker);
    42844337        }
    42854338    }
     
    42984351    const ClassNode* cn = qcn->classNode();
    42994352    if (cn && (cn->status() != Node::Internal)) {
    4300         out() << "<p style=\"text-align: center\">";
    43014353        Text text;
    4302         text << "[";
     4354        text << Atom::ParaLeft;
    43034355        text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
    43044356        text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
    4305         text << Atom(Atom::String, qcn->name());
     4357        QString name = qcn->name();
     4358        if (name.startsWith(QLatin1String("QML:")))
     4359            name = name.mid(4); // remove the "QML:" prefix
     4360        text << Atom(Atom::String, name);
    43064361        text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
    43074362        text << " instantiates the C++ class ";
     
    43104365        text << Atom(Atom::String, cn->name());
    43114366        text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
    4312         text << "]";
     4367        text << Atom::ParaRight;
    43134368        generateText(text, qcn, marker);
    4314         out() << "</p>";
    43154369    }
    43164370}
     
    43294383        const Node* n = myTree->root()->findNode(cn->qmlElement(),Node::Fake);
    43304384        if (n && n->subType() == Node::QmlClass) {
    4331             out() << "<p style=\"text-align: center\">";
    43324385            Text text;
    4333             text << "[";
     4386            text << Atom::ParaLeft;
    43344387            text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
    43354388            text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
     
    43414394            text << Atom(Atom::String, n->name());
    43424395            text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
    4343             text << "]";
     4396            text << Atom::ParaRight;
    43444397            generateText(text, cn, marker);
    4345             out() << "</p>";
    4346         }
     4398        }
     4399    }
     4400}
     4401
     4402/*!
     4403  Generate the <page> element for the given \a node using the \a writer.
     4404  Return true if a <page> element was written; otherwise return false.
     4405 */
     4406bool HtmlGenerator::generatePageElement(QXmlStreamWriter& writer,
     4407                                        const Node* node,
     4408                                        CodeMarker* marker) const
     4409{
     4410    if (node->pageType() == Node::NoPageType)
     4411        return false;
     4412    if (node->name().isEmpty())
     4413        return true;
     4414    if (node->access() == Node::Private)
     4415        return false;
     4416
     4417    QString guid = QUuid::createUuid().toString();
     4418    QString url = PageGenerator::fileName(node);
     4419    QString title;
     4420    QString rawTitle;
     4421    QString fullTitle;
     4422    QStringList pageWords;
     4423    QXmlStreamAttributes attributes;
     4424
     4425    writer.writeStartElement("page");
     4426
     4427    if (node->isInnerNode()) {
     4428        const InnerNode* inner = static_cast<const InnerNode*>(node);
     4429        if (!inner->pageKeywords().isEmpty())
     4430            pageWords << inner->pageKeywords();
     4431
     4432        switch (node->type()) {
     4433        case Node::Fake:
     4434            {
     4435                const FakeNode* fake = static_cast<const FakeNode*>(node);
     4436                title = fake->fullTitle();
     4437                pageWords << title;
     4438                break;
     4439            }
     4440        case Node::Class:
     4441            {
     4442                title = node->name() + " Class Reference";
     4443                pageWords << node->name() << "class" << "reference";
     4444                break;
     4445            }
     4446        case Node::Namespace:
     4447            {
     4448                rawTitle = marker->plainName(inner);
     4449                fullTitle = marker->plainFullName(inner);
     4450                title = rawTitle + " Namespace Reference";
     4451                pageWords << rawTitle << "namespace" << "reference";
     4452                break;
     4453            }
     4454        default:
     4455            title = node->name();
     4456            pageWords << title;
     4457            break;
     4458        }
     4459    }
     4460    else {
     4461        switch (node->type()) {
     4462        case Node::Enum:
     4463            {
     4464                title = node->name() + " Enum Reference";
     4465                pageWords << node->name() << "enum" << "type";
     4466                url += "#" + node->name() + "-enum";
     4467                break;
     4468            }
     4469        case Node::Function:
     4470            {
     4471                title = node->name() + " Function Reference";
     4472                pageWords << node->name() << "function";
     4473                url += "#" + node->name();
     4474                break;
     4475            }
     4476        case Node::Property:
     4477            {
     4478                title = node->name() + " Property Reference";
     4479                pageWords << node->name() << "property";
     4480                url += "#" + node->name() + "-prop";
     4481                break;
     4482            }
     4483        case Node::Typedef:
     4484            {
     4485                title = node->name() + " Type Reference";
     4486                pageWords << node->name() << "typedef" << "type";
     4487                url += "#" + node->name();
     4488                break;
     4489            }
     4490        default:
     4491            title = node->name();
     4492            pageWords << title;
     4493            break;
     4494        }
     4495
     4496        Node* parent = node->parent();
     4497        if (parent && ((parent->type() == Node::Class) ||
     4498                       (parent->type() == Node::Namespace))) {
     4499            pageWords << parent->name();
     4500        }
     4501    }
     4502
     4503    writer.writeAttribute("id",guid);
     4504    writer.writeStartElement("pageWords");
     4505    writer.writeCharacters(pageWords.join(" "));
     4506
     4507    writer.writeEndElement();
     4508    writer.writeStartElement("pageTitle");
     4509    writer.writeCharacters(title);
     4510    writer.writeEndElement();
     4511    writer.writeStartElement("pageUrl");
     4512    writer.writeCharacters(url);
     4513    writer.writeEndElement();
     4514    writer.writeStartElement("pageType");
     4515    switch (node->pageType()) {
     4516    case Node::ApiPage:
     4517        writer.writeCharacters("APIPage");
     4518        break;
     4519    case Node::ArticlePage:
     4520        writer.writeCharacters("Article");
     4521        break;
     4522    case Node::ExamplePage:
     4523        writer.writeCharacters("Example");
     4524        break;
     4525    default:
     4526        break;
     4527    }
     4528    writer.writeEndElement();
     4529    writer.writeEndElement();
     4530
     4531    if (node->type() == Node::Fake && node->doc().hasTableOfContents()) {
     4532        QList<Atom*> toc = node->doc().tableOfContents();
     4533        if (!toc.isEmpty()) {
     4534            for (int i = 0; i < toc.size(); ++i) {
     4535                Text headingText = Text::sectionHeading(toc.at(i));
     4536                QString s = headingText.toString();
     4537                writer.writeStartElement("page");
     4538                guid = QUuid::createUuid().toString();
     4539                QString internalUrl = url + "#" + Doc::canonicalTitle(s);
     4540                writer.writeAttribute("id",guid);
     4541                writer.writeStartElement("pageWords");
     4542                writer.writeCharacters(pageWords.join(" "));
     4543                writer.writeCharacters(" ");
     4544                writer.writeCharacters(s);
     4545                writer.writeEndElement();
     4546                writer.writeStartElement("pageTitle");
     4547                writer.writeCharacters(s);
     4548                writer.writeEndElement();
     4549                writer.writeStartElement("pageUrl");
     4550                writer.writeCharacters(internalUrl);
     4551                writer.writeEndElement();
     4552                writer.writeStartElement("pageType");
     4553                writer.writeCharacters("Article");
     4554                writer.writeEndElement();
     4555                writer.writeEndElement();
     4556            }
     4557        }
     4558    }
     4559    return true;
     4560}
     4561
     4562/*!
     4563  Traverse the tree recursively and generate the <keyword>
     4564  elements.
     4565 */
     4566void HtmlGenerator::generatePageElements(QXmlStreamWriter& writer, const Node* node, CodeMarker* marker) const
     4567{
     4568    if (generatePageElement(writer, node, marker)) {
     4569
     4570        if (node->isInnerNode()) {
     4571            const InnerNode *inner = static_cast<const InnerNode *>(node);
     4572
     4573            // Recurse to write an element for this child node and all its children.
     4574            foreach (const Node *child, inner->childNodes())
     4575                generatePageElements(writer, child, marker);
     4576        }
     4577    }
     4578}
     4579
     4580/*!
     4581  Outputs the file containing the index used for searching the html docs.
     4582 */
     4583void HtmlGenerator::generatePageIndex(const QString& fileName, CodeMarker* marker) const
     4584{
     4585    QFile file(fileName);
     4586    if (!file.open(QFile::WriteOnly | QFile::Text))
     4587        return ;
     4588
     4589    QXmlStreamWriter writer(&file);
     4590    writer.setAutoFormatting(true);
     4591    writer.writeStartDocument();
     4592    writer.writeStartElement("qtPageIndex");
     4593
     4594    generatePageElements(writer, myTree->root(), marker);
     4595
     4596    writer.writeEndElement(); // qtPageIndex
     4597    writer.writeEndDocument();
     4598    file.close();
     4599}
     4600
     4601void HtmlGenerator::generateExtractionMark(const Node *node, ExtractionMarkType markType)
     4602{
     4603    if (markType != EndMark) {
     4604        out() << "<!-- $$$" + node->name();
     4605        if (markType == MemberMark) {
     4606            if (node->type() == Node::Function) {
     4607                const FunctionNode *func = static_cast<const FunctionNode *>(node);
     4608                if (!func->associatedProperty()) {
     4609                    if (func->overloadNumber() == 1)
     4610                        out() << "[overload1]";
     4611                    out() << "$$$" + func->name() + func->rawParameters().remove(' ');
     4612                }
     4613            } else if (node->type() == Node::Property) {
     4614                out() << "-prop";
     4615                const PropertyNode *prop = static_cast<const PropertyNode *>(node);
     4616                const NodeList &list = prop->functions();
     4617                foreach (const Node *propFuncNode, list) {
     4618                    if (propFuncNode->type() == Node::Function) {
     4619                        const FunctionNode *func = static_cast<const FunctionNode *>(propFuncNode);
     4620                        out() << "$$$" + func->name() + func->rawParameters().remove(' ');
     4621                    }
     4622                }
     4623            } else if (node->type() == Node::Enum) {
     4624                const EnumNode *enumNode = static_cast<const EnumNode *>(node);
     4625                foreach (const EnumItem &item, enumNode->items())
     4626                    out() << "$$$" + item.name();
     4627            }
     4628        } else if (markType == BriefMark) {
     4629            out() << "-brief";
     4630        } else if (markType == DetailedDescriptionMark) {
     4631            out() << "-description";
     4632        }
     4633        out() << " -->\n";
     4634    } else {
     4635        out() << "<!-- @@@" + node->name() + " -->\n";
    43474636    }
    43484637}
    43494638
    43504639#endif
     4640
     4641 QT_END_NAMESPACE
Note: See TracChangeset for help on using the changeset viewer.