/******************************************************************************* ** ** smolbote: yet another qute browser ** Copyright (C) 2017 Xian Nox ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . ** ******************************************************************************/ #include "xbel.h" #include #include Xbel::Xbel(QTreeWidget *widget) { treeWidget = widget; QStyle *style = treeWidget->style(); folderIcon.addPixmap(style->standardPixmap(QStyle::SP_DirOpenIcon), QIcon::Normal, QIcon::On); folderIcon.addPixmap(style->standardPixmap(QStyle::SP_DirClosedIcon), QIcon::Normal, QIcon::Off); bookmarkIcon.addPixmap(style->standardPixmap(QStyle::SP_FileIcon)); } bool Xbel::read(const QString &xbel) { // no file specified if(xbel.isEmpty()) { return false; } QFile file(xbel); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { // file cannot be opened qDebug("Cannot open xbel: %s", qUtf8Printable(xbel)); return false; } xmlReader.setDevice(&file); if(xmlReader.readNextStartElement()) { if(xmlReader.name() == "xbel" && xmlReader.attributes().value("version") == "1.0") { qDebug("valid xbel"); readChildElements(0); } else { qDebug("invalid xbel"); return false; } } return true; } bool Xbel::write(const QString &xbel) { // no file specified if(xbel.isEmpty()) { return false; } QFile file(xbel); if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) { // file cannot be opened qDebug("Cannot open xbel: %s", qUtf8Printable(xbel)); return false; } xmlWriter.setAutoFormatting(true); xmlWriter.setDevice(&file); xmlWriter.writeStartDocument(); xmlWriter.writeDTD(""); xmlWriter.writeStartElement("xbel"); xmlWriter.writeAttribute("version", "1.0"); for(int i=0; itopLevelItemCount(); i++) { writeItem(treeWidget->topLevelItem(i)); } xmlWriter.writeEndDocument(); return true; } void Xbel::readChildElements(QTreeWidgetItem *parentItem) { while(xmlReader.readNextStartElement()) { if(xmlReader.name() == "title") { readTitle(parentItem); } else if(xmlReader.name() == "folder") { readChildElements(addFolder(parentItem)); } else if(xmlReader.name() == "bookmark") { QTreeWidgetItem *item = addBookmark(parentItem); item->setText(1, xmlReader.attributes().value("href").toString()); readChildElements(item); } else if(xmlReader.name() == "separator") { addSeparator(parentItem); xmlReader.skipCurrentElement(); } else { xmlReader.skipCurrentElement(); } } } void Xbel::readTitle(QTreeWidgetItem *item) { item->setText(0, xmlReader.readElementText()); } QTreeWidgetItem *Xbel::addFolder(QTreeWidgetItem *parentItem) { QTreeWidgetItem *folderItem = createChildItem(parentFolder(parentItem), "folder"); //folderItem->setExpanded(xmlReader.attributes().value("folded") != "no"); treeWidget->setItemExpanded(folderItem, xmlReader.attributes().value("folded") != "yes"); folderItem->setFlags(folderItem->flags() | Qt::ItemIsEditable); folderItem->setIcon(0, folderIcon); return folderItem; } QTreeWidgetItem *Xbel::addBookmark(QTreeWidgetItem *parentItem) { QTreeWidgetItem *bookmarkItem = createChildItem(parentFolder(parentItem), "bookmark"); bookmarkItem->setFlags((bookmarkItem->flags() | Qt::ItemIsEditable) & ~Qt::ItemIsDropEnabled); bookmarkItem->setIcon(0, bookmarkIcon); bookmarkItem->setText(0, "Unknown Title"); bookmarkItem->setText(1, "Unknown Address"); return bookmarkItem; } void Xbel::addSeparator(QTreeWidgetItem *parentItem) { QTreeWidgetItem *separatorItem = createChildItem(parentFolder(parentItem), "separator"); separatorItem->setFlags(separatorItem->flags() & ~Qt::ItemIsDropEnabled); separatorItem->setText(0, "-----"); } QTreeWidgetItem *Xbel::parentFolder(QTreeWidgetItem *item) { QTreeWidgetItem *parentItem = item; if(parentItem) { while(parentItem->data(0, Qt::UserRole) != "folder") { parentItem = parentItem->parent(); if(parentItem == 0) { break; } } } return parentItem; } QTreeWidgetItem *Xbel::createChildItem(QTreeWidgetItem *item, const QString &type) { QTreeWidgetItem *childItem; if(item) { childItem = new QTreeWidgetItem(item); } else { childItem = new QTreeWidgetItem(treeWidget); } childItem->setData(0, Qt::UserRole, type); return childItem; } void Xbel::writeItem(QTreeWidgetItem *item) { QString tagName = item->data(0, Qt::UserRole).toString(); if (tagName == "folder") { xmlWriter.writeStartElement(tagName); xmlWriter.writeAttribute("folded", treeWidget->isItemExpanded(item) ? "no" : "yes"); xmlWriter.writeTextElement("title", item->text(0)); for (int i = 0; i < item->childCount(); ++i) { writeItem(item->child(i)); } xmlWriter.writeEndElement(); } else if (tagName == "bookmark") { xmlWriter.writeStartElement(tagName); if (!item->text(1).isEmpty()) { xmlWriter.writeAttribute("href", item->text(1)); } xmlWriter.writeTextElement("title", item->text(0)); xmlWriter.writeEndElement(); } else if (tagName == "separator") { xmlWriter.writeEmptyElement(tagName); } }