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 + -
显示快捷键?