xbel.cpp
上传用户:huahtool
上传日期:2015-12-10
资源大小:1089k
文件大小:9k
源码类别:

浏览器

开发平台:

Visual C++

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
  4. ** Contact: Qt Software Information (qt-info@nokia.com)
  5. **
  6. ** This file is part of the demonstration applications of the Qt Toolkit.
  7. **
  8. ** Commercial Usage
  9. ** Licensees holding valid Qt Commercial licenses may use this file in
  10. ** accordance with the Qt Commercial License Agreement provided with the
  11. ** Software or, alternatively, in accordance with the terms contained in
  12. ** a written agreement between you and Nokia.
  13. **
  14. **
  15. ** GNU General Public License Usage
  16. ** Alternatively, this file may be used under the terms of the GNU
  17. ** General Public License versions 2.0 or 3.0 as published by the Free
  18. ** Software Foundation and appearing in the file LICENSE.GPL included in
  19. ** the packaging of this file.  Please review the following information
  20. ** to ensure GNU General Public Licensing requirements will be met:
  21. ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
  22. ** http://www.gnu.org/copyleft/gpl.html.  In addition, as a special
  23. ** exception, Nokia gives you certain additional rights. These rights
  24. ** are described in the Nokia Qt GPL Exception version 1.3, included in
  25. ** the file GPL_EXCEPTION.txt in this package.
  26. **
  27. ** Qt for Windows(R) Licensees
  28. ** As a special exception, Nokia, as the sole copyright holder for Qt
  29. ** Designer, grants users of the Qt/Eclipse Integration plug-in the
  30. ** right for the Qt/Eclipse Integration to link to functionality
  31. ** provided by Qt Designer and its related libraries.
  32. **
  33. ** If you are unsure which license is appropriate for your use, please
  34. ** contact the sales department at qt-sales@nokia.com.
  35. **
  36. ****************************************************************************/
  37. #include "xbel.h"
  38. #include <QtCore/QFile>
  39. BookmarkNode::BookmarkNode(BookmarkNode::Type type, BookmarkNode *parent) :
  40.      expanded(false)
  41.    , m_parent(parent)
  42.    , m_type(type)
  43. {
  44.     if (parent)
  45.         parent->add(this);
  46. }
  47. BookmarkNode::~BookmarkNode()
  48. {
  49.     if (m_parent)
  50.         m_parent->remove(this);
  51.     qDeleteAll(m_children);
  52.     m_parent = 0;
  53.     m_type = BookmarkNode::Root;
  54. }
  55. bool BookmarkNode::operator==(const BookmarkNode &other)
  56. {
  57.     if (url != other.url
  58.         || title != other.title
  59.         || desc != other.desc
  60.         || expanded != other.expanded
  61.         || m_type != other.m_type
  62.         || m_children.count() != other.m_children.count())
  63.         return false;
  64.     for (int i = 0; i < m_children.count(); ++i)
  65.         if (!((*(m_children[i])) == (*(other.m_children[i]))))
  66.             return false;
  67.     return true;
  68. }
  69. BookmarkNode::Type BookmarkNode::type() const
  70. {
  71.     return m_type;
  72. }
  73. void BookmarkNode::setType(Type type)
  74. {
  75.     m_type = type;
  76. }
  77. QList<BookmarkNode *> BookmarkNode::children() const
  78. {
  79.     return m_children;
  80. }
  81. BookmarkNode *BookmarkNode::parent() const
  82. {
  83.     return m_parent;
  84. }
  85. void BookmarkNode::add(BookmarkNode *child, int offset)
  86. {
  87.     Q_ASSERT(child->m_type != Root);
  88.     if (child->m_parent)
  89.         child->m_parent->remove(child);
  90.     child->m_parent = this;
  91.     if (-1 == offset)
  92.         offset = m_children.size();
  93.     m_children.insert(offset, child);
  94. }
  95. void BookmarkNode::remove(BookmarkNode *child)
  96. {
  97.     child->m_parent = 0;
  98.     m_children.removeAll(child);
  99. }
  100. XbelReader::XbelReader()
  101. {
  102. }
  103. BookmarkNode *XbelReader::read(const QString &fileName)
  104. {
  105.     QFile file(fileName);
  106.     if (!file.exists()) {
  107.         return new BookmarkNode(BookmarkNode::Root);
  108.     }
  109.     file.open(QFile::ReadOnly);
  110.     return read(&file);
  111. }
  112. BookmarkNode *XbelReader::read(QIODevice *device)
  113. {
  114.     BookmarkNode *root = new BookmarkNode(BookmarkNode::Root);
  115.     setDevice(device);
  116.     while (!atEnd()) {
  117.         readNext();
  118.         if (isStartElement()) {
  119.             QString version = attributes().value(QLatin1String("version")).toString();
  120.             if (name() == QLatin1String("xbel")
  121.                 && (version.isEmpty() || version == QLatin1String("1.0"))) {
  122.                 readXBEL(root);
  123.             } else {
  124.                 raiseError(QObject::tr("The file is not an XBEL version 1.0 file."));
  125.             }
  126.         }
  127.     }
  128.     return root;
  129. }
  130. void XbelReader::readXBEL(BookmarkNode *parent)
  131. {
  132.     Q_ASSERT(isStartElement() && name() == QLatin1String("xbel"));
  133.     while (!atEnd()) {
  134.         readNext();
  135.         if (isEndElement())
  136.             break;
  137.         if (isStartElement()) {
  138.             if (name() == QLatin1String("folder"))
  139.                 readFolder(parent);
  140.             else if (name() == QLatin1String("bookmark"))
  141.                 readBookmarkNode(parent);
  142.             else if (name() == QLatin1String("separator"))
  143.                 readSeparator(parent);
  144.             else
  145.                 skipUnknownElement();
  146.         }
  147.     }
  148. }
  149. void XbelReader::readFolder(BookmarkNode *parent)
  150. {
  151.     Q_ASSERT(isStartElement() && name() == QLatin1String("folder"));
  152.     BookmarkNode *folder = new BookmarkNode(BookmarkNode::Folder, parent);
  153.     folder->expanded = (attributes().value(QLatin1String("folded")) == QLatin1String("no"));
  154.     while (!atEnd()) {
  155.         readNext();
  156.         if (isEndElement())
  157.             break;
  158.         if (isStartElement()) {
  159.             if (name() == QLatin1String("title"))
  160.                 readTitle(folder);
  161.             else if (name() == QLatin1String("desc"))
  162.                 readDescription(folder);
  163.             else if (name() == QLatin1String("folder"))
  164.                 readFolder(folder);
  165.             else if (name() == QLatin1String("bookmark"))
  166.                 readBookmarkNode(folder);
  167.             else if (name() == QLatin1String("separator"))
  168.                 readSeparator(folder);
  169.             else
  170.                 skipUnknownElement();
  171.         }
  172.     }
  173. }
  174. void XbelReader::readTitle(BookmarkNode *parent)
  175. {
  176.     Q_ASSERT(isStartElement() && name() == QLatin1String("title"));
  177.     parent->title = readElementText();
  178. }
  179. void XbelReader::readDescription(BookmarkNode *parent)
  180. {
  181.     Q_ASSERT(isStartElement() && name() == QLatin1String("desc"));
  182.     parent->desc = readElementText();
  183. }
  184. void XbelReader::readSeparator(BookmarkNode *parent)
  185. {
  186.     new BookmarkNode(BookmarkNode::Separator, parent);
  187.     // empty elements have a start and end element
  188.     readNext();
  189. }
  190. void XbelReader::readBookmarkNode(BookmarkNode *parent)
  191. {
  192.     Q_ASSERT(isStartElement() && name() == QLatin1String("bookmark"));
  193.     BookmarkNode *bookmark = new BookmarkNode(BookmarkNode::Bookmark, parent);
  194.     bookmark->url = attributes().value(QLatin1String("href")).toString();
  195.     while (!atEnd()) {
  196.         readNext();
  197.         if (isEndElement())
  198.             break;
  199.         if (isStartElement()) {
  200.             if (name() == QLatin1String("title"))
  201.                 readTitle(bookmark);
  202.             else if (name() == QLatin1String("desc"))
  203.                 readDescription(bookmark);
  204.             else
  205.                 skipUnknownElement();
  206.         }
  207.     }
  208.     if (bookmark->title.isEmpty())
  209.         bookmark->title = QObject::tr("Unknown title");
  210. }
  211. void XbelReader::skipUnknownElement()
  212. {
  213.     Q_ASSERT(isStartElement());
  214.     while (!atEnd()) {
  215.         readNext();
  216.         if (isEndElement())
  217.             break;
  218.         if (isStartElement())
  219.             skipUnknownElement();
  220.     }
  221. }
  222. XbelWriter::XbelWriter()
  223. {
  224.     setAutoFormatting(true);
  225. }
  226. bool XbelWriter::write(const QString &fileName, const BookmarkNode *root)
  227. {
  228.     QFile file(fileName);
  229.     if (!root || !file.open(QFile::WriteOnly))
  230.         return false;
  231.     return write(&file, root);
  232. }
  233. bool XbelWriter::write(QIODevice *device, const BookmarkNode *root)
  234. {
  235.     setDevice(device);
  236.     writeStartDocument();
  237.     writeDTD(QLatin1String("<!DOCTYPE xbel>"));
  238.     writeStartElement(QLatin1String("xbel"));
  239.     writeAttribute(QLatin1String("version"), QLatin1String("1.0"));
  240.     if (root->type() == BookmarkNode::Root) {
  241.         for (int i = 0; i < root->children().count(); ++i)
  242.             writeItem(root->children().at(i));
  243.     } else {
  244.         writeItem(root);
  245.     }
  246.     writeEndDocument();
  247.     return true;
  248. }
  249. void XbelWriter::writeItem(const BookmarkNode *parent)
  250. {
  251.     switch (parent->type()) {
  252.     case BookmarkNode::Folder:
  253.         writeStartElement(QLatin1String("folder"));
  254.         writeAttribute(QLatin1String("folded"), parent->expanded ? QLatin1String("no") : QLatin1String("yes"));
  255.         writeTextElement(QLatin1String("title"), parent->title);
  256.         for (int i = 0; i < parent->children().count(); ++i)
  257.             writeItem(parent->children().at(i));
  258.         writeEndElement();
  259.         break;
  260.     case BookmarkNode::Bookmark:
  261.         writeStartElement(QLatin1String("bookmark"));
  262.         if (!parent->url.isEmpty())
  263.             writeAttribute(QLatin1String("href"), parent->url);
  264.         writeTextElement(QLatin1String("title"), parent->title);
  265.         if (!parent->desc.isEmpty())
  266.             writeAttribute(QLatin1String("desc"), parent->desc);
  267.         writeEndElement();
  268.         break;
  269.     case BookmarkNode::Separator:
  270.         writeEmptyElement(QLatin1String("separator"));
  271.         break;
  272.     default:
  273.         break;
  274.     }
  275. }