docuparser.cpp

来自「奇趣公司比较新的qt/emd版本」· C++ 代码 · 共 427 行

CPP
427
字号
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the Qt Assistant of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "docuparser.h"#include "profile.h"#include <QDir>#include <QFile>#include <QFileInfo>#include <QRegExp>#include <QString>#include <QtXml>#include <QDataStream>QDataStream &operator>>(QDataStream &s, ContentItem &ci){    s >> ci.title;    s >> ci.reference;    s >> ci.depth;    return s;}QDataStream &operator<<(QDataStream &s, const ContentItem &ci){    s << ci.title;    s << ci.reference;    s << ci.depth;    return s;}const QString DocuParser::DocumentKey = QLatin1String("/Qt Assistant/") + QLatin1String(QT_VERSION_STR) + QLatin1String("/");DocuParser *DocuParser::createParser(const QString &fileName){    QFile file(fileName);    if(!file.open(QFile::ReadOnly)) {        return 0;    }    QString str;    int maxlen = 1024;    int majVer = 0, minVer = 0, serVer = 0;    static QRegExp re(QLatin1String("assistantconfig +version=\"(\\d)\\.(\\d)\\.(\\d)\""), Qt::CaseInsensitive);    Q_ASSERT(re.isValid());    while(!(str = QLatin1String(file.readLine(maxlen))).isEmpty()) {        if(re.indexIn(str) >= 0) {            majVer = re.cap(1).toInt();            minVer = re.cap(2).toInt();            serVer = re.cap(3).toInt();            break;        }    }    if (majVer < 3 || majVer == 3 && minVer < 2) {        return new DocuParser310;    }    return new DocuParser320;}bool DocuParser::parse(QFile *file){    QXmlInputSource source(file);    QXmlSimpleReader reader;    reader.setContentHandler(this);    reader.setErrorHandler(this);    setFileName(QFileInfo(*file).absoluteFilePath());    return reader.parse(source);}QString DocuParser::errorProtocol() const{    return errorProt;}QList<ContentItem> DocuParser::getContentItems(){    return contentList;}QList<IndexItem*> DocuParser::getIndexItems(){    return indexList;}QString DocuParser::absolutify(const QString &name, bool makeUrl) const{    if (!name.isEmpty()) {        QString s = name;        s.replace(QLatin1String("\\"), QLatin1String("/"));        QFileInfo orgPath(name);        if(orgPath.isRelative())            s = QFileInfo(fname).path() + QLatin1Char('/') + name;        if (makeUrl)            s.prepend(QLatin1String("file:"));        return s;    }    return name;}void DocuParser310::addTo(Profile *p){    p->addDCFTitle(fname, docTitle);    p->addDCFIcon(docTitle, iconName);    p->addDCFIndexPage(docTitle, conURL);}bool DocuParser310::startDocument(){    state = StateInit;    errorProt = QLatin1String("");    contentRef = QLatin1String("");    indexRef = QLatin1String("");    depth = 0;    contentList.clear();    qDeleteAll(indexList);    indexList.clear();    return true;}bool DocuParser310::startElement(const QString &, const QString &,                               const QString &qname,                               const QXmlAttributes &attr){    if (qname == QLatin1String("DCF") && state == StateInit) {        state = StateContent;        contentRef = absolutify(attr.value(QLatin1String("ref")), false);        conURL = contentRef;        docTitle = attr.value(QLatin1String("title"));        iconName = absolutify(attr.value(QLatin1String("icon")), false);        contentList.append(ContentItem(docTitle, absolutify(contentRef), depth));    } else if (qname == QLatin1String("section") && (state == StateContent || state == StateSect)) {        state = StateSect;        contentRef = absolutify(attr.value(QLatin1String("ref")));        title = attr.value(QLatin1String("title"));        depth++;        contentList.append(ContentItem(title, contentRef, depth));    } else if (qname == QLatin1String("keyword") && state == StateSect) {        state = StateKeyword;        indexRef = absolutify(attr.value(QLatin1String("ref")));    } else        return false;    return true;}bool DocuParser310::endElement(const QString &nameSpace, const QString &localName,                             const QString &qName){    Q_UNUSED(nameSpace);    Q_UNUSED(localName);    Q_UNUSED(qName);    switch(state) {    case StateInit:        break;    case StateContent:        state = StateInit;        break;    case StateSect:        state = --depth ? StateSect : StateContent;        break;    case StateKeyword:        state = StateSect;        break;    default:        break;    }    return true;}bool DocuParser310::characters(const QString& ch){    QString str = ch.simplified();    if (str.isEmpty())        return true;    switch (state) {        case StateInit:        case StateContent:        case StateSect:            return false;            break;        case StateKeyword:            indexList.append(new IndexItem(str, indexRef));            break;        default:            return false;    }    return true;}bool DocuParser310::fatalError(const QXmlParseException& exception){    errorProt += QString::fromLatin1("fatal parsing error: %1 in line %2, column %3\n")        .arg(exception.message())        .arg(exception.lineNumber())        .arg(exception.columnNumber());    return QXmlDefaultHandler::fatalError(exception);}DocuParser320::DocuParser320()    : prof(new Profile){}void DocuParser320::addTo(Profile *p){    QMap<QString,QString>::ConstIterator it;    for (it = prof->dcfTitles.constBegin(); it != prof->dcfTitles.constEnd(); ++it)        p->dcfTitles[it.key()] = *it;    for (it = prof->icons.constBegin(); it != prof->icons.constEnd(); ++it)        p->icons[it.key()] = *it;    for (it = prof->indexPages.constBegin(); it != prof->indexPages.constEnd(); ++it)        p->indexPages[it.key()] = *it;}bool DocuParser320::startDocument(){    state = StateInit;    errorProt = QLatin1String("");    contentRef = QLatin1String("");    indexRef = QLatin1String("");    depth = 0;    contentList.clear();    indexList.clear();    prof->addDCF(fname);    return true;}bool DocuParser320::startElement(const QString &, const QString &,                               const QString &qname,                               const QXmlAttributes &attr){    QString lower = qname.toLower();    switch(state) {    case StateInit:        if(lower == QLatin1String("assistantconfig"))            state = StateDocRoot;        break;    case StateDocRoot:        if(lower == QLatin1String("dcf")) {            state = StateContent;            contentRef = absolutify(attr.value(QLatin1String("ref")));            conURL = contentRef;            docTitle = attr.value(QLatin1String("title"));            iconName = absolutify(attr.value(QLatin1String("icon")));            contentList.append(ContentItem(docTitle, contentRef, depth));        } else if(lower == QLatin1String("profile")) {            state = StateProfile;        }        break;    case StateSect:        if (lower == QLatin1String("keyword") && state == StateSect) {            state = StateKeyword;            indexRef = absolutify(attr.value(QLatin1String("ref")));            break;        } // else if (lower == "section")    case StateContent:        if(lower == QLatin1String("section")) {            state = StateSect;            contentRef = absolutify(attr.value(QLatin1String("ref")));            title = attr.value(QLatin1String("title"));            depth++;            contentList.append(ContentItem(title, contentRef, depth));        }        break;    case StateProfile:        if(lower == QLatin1String("property")) {            state = StateProperty;            propertyName = attr.value(QLatin1String("name"));        }        break;    case StateProperty:        break;    default:        break;    }    return true;}bool DocuParser320::endElement(const QString &nameSpace,                                const QString &localName,                                const QString &qName){    Q_UNUSED(nameSpace);    Q_UNUSED(localName);    Q_UNUSED(qName);    switch(state) {    case StateInit:        break;    case StateDocRoot:        state = StateInit;        break;    case StateProfile:        state = StateDocRoot;        break;    case StateProperty:        state = StateProfile;        if(propertyName.isEmpty() || propertyValue.isEmpty())            return false;        {            static const QStringList lst = QStringList()                << QLatin1String("startpage") << QLatin1String("abouturl")                << QLatin1String("applicationicon") << QLatin1String("assistantdocs");            if (lst.contains(propertyName))                propertyValue = absolutify(propertyValue);        }        prof->addProperty(propertyName, propertyValue);        break;    case StateContent:        if(!iconName.isEmpty())            prof->addDCFIcon(docTitle, iconName);        if(contentRef.isEmpty())            return false;        prof->addDCFIndexPage(docTitle, conURL);        prof->addDCFTitle(fname, docTitle);        state = StateDocRoot;        break;    case StateSect:        state = --depth ? StateSect : StateContent;        break;    case StateKeyword:        state = StateSect;        break;    }    return true;}bool DocuParser320::characters(const QString& ch){    QString str = ch.simplified();    if (str.isEmpty())        return true;    switch (state) {    case StateInit:    case StateContent:    case StateSect:        return false;        break;    case StateKeyword:        indexList.append(new IndexItem(str, indexRef));        break;    case StateProperty:        propertyValue = ch;        break;    default:        return false;    }    return true;}bool DocuParser320::fatalError(const QXmlParseException& exception){    errorProt += QString::fromLatin1("fatal parsing error: %1 in line %2, column %3\n")        .arg(exception.message())        .arg(exception.lineNumber())        .arg(exception.columnNumber());    return QXmlDefaultHandler::fatalError(exception);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?