/**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). ** Contact: http://www.qt-project.org/legal ** ** This file is part of the demonstration applications of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Digia. For licensing terms and ** conditions see http://qt.digia.com/licensing. For further information ** use the contact form at http://qt.digia.com/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Digia gives you certain additional ** rights. These rights are described in the Digia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.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 the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "xbel.h" #include BookmarkNode::BookmarkNode(BookmarkNode::Type type, BookmarkNode *parent) : expanded(false) , m_parent(parent) , m_type(type) { if (parent) parent->add(this); } BookmarkNode::~BookmarkNode() { if (m_parent) m_parent->remove(this); qDeleteAll(m_children); m_parent = 0; m_type = BookmarkNode::Root; } bool BookmarkNode::operator==(const BookmarkNode &other) { if (url != other.url || title != other.title || desc != other.desc || expanded != other.expanded || m_type != other.m_type || m_children.count() != other.m_children.count()) return false; for (int i = 0; i < m_children.count(); ++i) if (!((*(m_children[i])) == (*(other.m_children[i])))) return false; return true; } BookmarkNode::Type BookmarkNode::type() const { return m_type; } void BookmarkNode::setType(Type type) { m_type = type; } QList BookmarkNode::children() const { return m_children; } BookmarkNode *BookmarkNode::parent() const { return m_parent; } void BookmarkNode::add(BookmarkNode *child, int offset) { Q_ASSERT(child->m_type != Root); if (child->m_parent) child->m_parent->remove(child); child->m_parent = this; if (-1 == offset) offset = m_children.size(); m_children.insert(offset, child); } void BookmarkNode::remove(BookmarkNode *child) { child->m_parent = 0; m_children.removeAll(child); } XbelReader::XbelReader() { } BookmarkNode *XbelReader::read(const QString &fileName) { QFile file(fileName); if (!file.exists()) { return new BookmarkNode(BookmarkNode::Root); } file.open(QFile::ReadOnly); return read(&file); } BookmarkNode *XbelReader::read(QIODevice *device) { BookmarkNode *root = new BookmarkNode(BookmarkNode::Root); setDevice(device); if (readNextStartElement()) { QString version = attributes().value(QLatin1String("version")).toString(); if (name() == QLatin1String("xbel") && (version.isEmpty() || version == QLatin1String("1.0"))) { readXBEL(root); } else { raiseError(QObject::tr("The file is not an XBEL version 1.0 file.")); } } return root; } void XbelReader::readXBEL(BookmarkNode *parent) { Q_ASSERT(isStartElement() && name() == QLatin1String("xbel")); while (readNextStartElement()) { if (name() == QLatin1String("folder")) readFolder(parent); else if (name() == QLatin1String("bookmark")) readBookmarkNode(parent); else if (name() == QLatin1String("separator")) readSeparator(parent); else skipCurrentElement(); } } void XbelReader::readFolder(BookmarkNode *parent) { Q_ASSERT(isStartElement() && name() == QLatin1String("folder")); BookmarkNode *folder = new BookmarkNode(BookmarkNode::Folder, parent); folder->expanded = (attributes().value(QLatin1String("folded")) == QLatin1String("no")); while (readNextStartElement()) { if (name() == QLatin1String("title")) readTitle(folder); else if (name() == QLatin1String("desc")) readDescription(folder); else if (name() == QLatin1String("folder")) readFolder(folder); else if (name() == QLatin1String("bookmark")) readBookmarkNode(folder); else if (name() == QLatin1String("separator")) readSeparator(folder); else skipCurrentElement(); } } void XbelReader::readTitle(BookmarkNode *parent) { Q_ASSERT(isStartElement() && name() == QLatin1String("title")); parent->title = readElementText(); } void XbelReader::readDescription(BookmarkNode *parent) { Q_ASSERT(isStartElement() && name() == QLatin1String("desc")); parent->desc = readElementText(); } void XbelReader::readSeparator(BookmarkNode *parent) { new BookmarkNode(BookmarkNode::Separator, parent); // empty elements have a start and end element readNext(); } void XbelReader::readBookmarkNode(BookmarkNode *parent) { Q_ASSERT(isStartElement() && name() == QLatin1String("bookmark")); BookmarkNode *bookmark = new BookmarkNode(BookmarkNode::Bookmark, parent); bookmark->url = attributes().value(QLatin1String("href")).toString(); while (readNextStartElement()) { if (name() == QLatin1String("title")) readTitle(bookmark); else if (name() == QLatin1String("desc")) readDescription(bookmark); else skipCurrentElement(); } if (bookmark->title.isEmpty()) bookmark->title = QObject::tr("Unknown title"); } XbelWriter::XbelWriter() { setAutoFormatting(true); } bool XbelWriter::write(const QString &fileName, const BookmarkNode *root) { QFile file(fileName); if (!root || !file.open(QFile::WriteOnly)) return false; return write(&file, root); } bool XbelWriter::write(QIODevice *device, const BookmarkNode *root) { setDevice(device); writeStartDocument(); writeDTD(QLatin1String("")); writeStartElement(QLatin1String("xbel")); writeAttribute(QLatin1String("version"), QLatin1String("1.0")); if (root->type() == BookmarkNode::Root) { for (int i = 0; i < root->children().count(); ++i) writeItem(root->children().at(i)); } else { writeItem(root); } writeEndDocument(); return true; } void XbelWriter::writeItem(const BookmarkNode *parent) { switch (parent->type()) { case BookmarkNode::Folder: writeStartElement(QLatin1String("folder")); writeAttribute(QLatin1String("folded"), parent->expanded ? QLatin1String("no") : QLatin1String("yes")); writeTextElement(QLatin1String("title"), parent->title); for (int i = 0; i < parent->children().count(); ++i) writeItem(parent->children().at(i)); writeEndElement(); break; case BookmarkNode::Bookmark: writeStartElement(QLatin1String("bookmark")); if (!parent->url.isEmpty()) writeAttribute(QLatin1String("href"), parent->url); writeTextElement(QLatin1String("title"), parent->title); if (!parent->desc.isEmpty()) writeAttribute(QLatin1String("desc"), parent->desc); writeEndElement(); break; case BookmarkNode::Separator: writeEmptyElement(QLatin1String("separator")); break; default: break; } }