/** LICENSE ********************************************************************
**
** 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");
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);
}
}