From 5d0adf426a33440542eb88eca83c804dcec58475 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Thu, 11 Jan 2018 17:30:38 +0100 Subject: Writing BookmarksModel to xbel --- lib/bookmarks/bookmarksmodel.cpp | 45 +++++++++++++++++++++--- lib/bookmarks/bookmarksmodel.h | 10 +++++- lib/bookmarks/bookmarkswidget.cpp | 27 +++------------ lib/bookmarks/bookmarkswidget.h | 2 -- lib/bookmarks/xbel.cpp | 72 +++++++++++++++++++++++++++++++++------ lib/bookmarks/xbel.h | 4 ++- 6 files changed, 118 insertions(+), 42 deletions(-) diff --git a/lib/bookmarks/bookmarksmodel.cpp b/lib/bookmarks/bookmarksmodel.cpp index e67668f..5cf343f 100644 --- a/lib/bookmarks/bookmarksmodel.cpp +++ b/lib/bookmarks/bookmarksmodel.cpp @@ -7,7 +7,6 @@ */ #include "bookmarksmodel.h" -#include BookmarksModel::BookmarksModel(QStyle *style, QObject *parent) : QAbstractItemModel(parent) @@ -27,12 +26,25 @@ BookmarksModel::~BookmarksModel() delete m_rootItem; } -void BookmarksModel::setRoot(BookmarkItem *root) +bool BookmarksModel::isModified() const { - Q_CHECK_PTR(root); + return modified; +} - delete m_rootItem; - m_rootItem = root; +bool BookmarksModel::read(Xbel *xbel) +{ + Q_CHECK_PTR(xbel); + // if there are items in the bookmark list, we're adding to them, so the model becomes modified + if(m_rootItem->childCount() != 0) { + modified = true; + } + return xbel->read(m_rootItem); +} + +bool BookmarksModel::write(Xbel *xbel) +{ + Q_CHECK_PTR(xbel); + return xbel->write(m_rootItem); } QVariant BookmarksModel::headerData(int section, Qt::Orientation orientation, int role) const @@ -220,6 +232,7 @@ bool BookmarksModel::setData(const QModelIndex &index, const QVariant &value, in case BookmarkItem::Folder: if(index.column() == 0) { node->title = value.toString(); + modified = true; emit dataChanged(index, index); return true; } @@ -228,10 +241,12 @@ bool BookmarksModel::setData(const QModelIndex &index, const QVariant &value, in case BookmarkItem::Bookmark: if(index.column() == 0) { node->title = value.toString(); + modified = true; emit dataChanged(index, index); return true; } else if(index.column() == 1) { node->href = value.toString(); + modified = true; emit dataChanged(index, index); return true; } @@ -275,3 +290,23 @@ QModelIndexList BookmarksModel::match(const QModelIndex &start, int role, const return list; } + +void BookmarksModel::expandItems(QTreeView *view, BookmarkItem *root) +{ + if(root == nullptr) + root = m_rootItem; + + // iterate through children + for(int i = 0; i < root->childCount(); ++i) { + BookmarkItem *childNode = root->child(i); + + // and if it's a folder + if(childNode->type() == BookmarkItem::Folder) { + QModelIndex idx = index(childNode); + view->setExpanded(idx, !childNode->folded); + + // only folders have children, so go through them + expandItems(view, childNode); + } + } +} diff --git a/lib/bookmarks/bookmarksmodel.h b/lib/bookmarks/bookmarksmodel.h index 986a195..79bd9ce 100644 --- a/lib/bookmarks/bookmarksmodel.h +++ b/lib/bookmarks/bookmarksmodel.h @@ -7,8 +7,10 @@ */ #include "bookmarkitem.h" +#include "xbel.h" #include #include +#include #ifndef BOOKMARKSMODEL_H #define BOOKMARKSMODEL_H @@ -26,7 +28,10 @@ public: explicit BookmarksModel(QStyle *style, QObject *parent = nullptr); ~BookmarksModel() override; - void setRoot(BookmarkItem *root); + bool isModified() const; + + bool read(Xbel *xbel); + bool write(Xbel *xbel); QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; @@ -47,9 +52,12 @@ public: QModelIndexList match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const override; + void expandItems(QTreeView *view, BookmarkItem *root = nullptr); + private: QIcon folderIcon; QIcon bookmarkIcon; + bool modified = false; BookmarkItem *m_rootItem; }; diff --git a/lib/bookmarks/bookmarkswidget.cpp b/lib/bookmarks/bookmarkswidget.cpp index 27f00c3..575f52f 100644 --- a/lib/bookmarks/bookmarkswidget.cpp +++ b/lib/bookmarks/bookmarkswidget.cpp @@ -32,10 +32,8 @@ BookmarksWidget::BookmarksWidget(const QString &path, QWidget *parent) ui->treeView->setModel(m_model); xbel = new Xbel(path); - BookmarkItem *rootNode = xbel->read(); - m_model->setRoot(rootNode); - expandNodes(rootNode); - //qDebug("Reading bookmarks [%s] %s", qUtf8Printable(m_path), xbel->read(m_path) ? "ok" : "failed"); + qDebug("Reading bookmarks [%s] %s", qUtf8Printable(path), m_model->read(xbel) ? "ok" : "failed"); + m_model->expandItems(ui->treeView); connect(ui->treeView, &QTreeView::activated, this, [this](const QModelIndex &index) { if(ui->treeView->isPersistentEditorOpen(index)) @@ -67,8 +65,8 @@ BookmarksWidget::~BookmarksWidget() void BookmarksWidget::save() { - // TODO: check if saving is needed - //qDebug("Writing bookmarks [%s] %s", qUtf8Printable(m_path), xbel->write(m_path) ? "ok" : "failed"); + if(m_model->isModified()) + qDebug("Writing bookmarks %s", m_model->write(xbel) ? "ok" : "failed"); } QAbstractItemModel *BookmarksWidget::model() const @@ -77,23 +75,6 @@ QAbstractItemModel *BookmarksWidget::model() const return m_model; } -void BookmarksWidget::expandNodes(BookmarkItem *node) -{ - // iterate through children - for(int i = 0; i < node->childCount(); ++i) { - BookmarkItem *childNode = node->child(i); - - // and if it's a folder - if(childNode->type() == BookmarkItem::Folder) { - QModelIndex index = m_model->index(childNode); - ui->treeView->setExpanded(index, !childNode->folded); - - // only folders have children, so go through them - expandNodes(childNode); - } - } -} - void BookmarksWidget::closeOthers() { emit closeOthersSignal(); diff --git a/lib/bookmarks/bookmarkswidget.h b/lib/bookmarks/bookmarkswidget.h index 0a44414..ca35457 100644 --- a/lib/bookmarks/bookmarkswidget.h +++ b/lib/bookmarks/bookmarkswidget.h @@ -37,8 +37,6 @@ signals: void closeOthersSignal(); private: - void expandNodes(BookmarkItem *node); - Ui::BookmarksDialog *ui; BookmarksModel *m_model; Xbel *xbel; diff --git a/lib/bookmarks/xbel.cpp b/lib/bookmarks/xbel.cpp index 7a7632c..122ccf8 100644 --- a/lib/bookmarks/xbel.cpp +++ b/lib/bookmarks/xbel.cpp @@ -14,21 +14,17 @@ Xbel::Xbel(const QString &path) m_path = path; } -BookmarkItem *Xbel::read() +bool Xbel::read(BookmarkItem *root) { - BookmarkItem *root = new BookmarkItem(BookmarkItem::Root, nullptr); - root->title = QObject::tr("Title"); - root->href = QObject::tr("href"); - // if the path is empty, there is nothing to load if(m_path.isEmpty()) { - return root; + return false; } QFile file(m_path); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { // file cannot be opened for reading - return root; + return false; } QXmlStreamReader xmlReader(&file); @@ -37,13 +33,14 @@ BookmarkItem *Xbel::read() if(!(xmlReader.name() == "xbel" && xmlReader.attributes().value("version") == "1.0")) { // invalid xbel qWarning("Error parsing %s", qUtf8Printable(m_path)); - return root; + return false; } readChildElements(xmlReader, root); } - return root; + file.close(); + return true; } void Xbel::readChildElements(QXmlStreamReader &reader, BookmarkItem *parentItem) @@ -54,7 +51,6 @@ void Xbel::readChildElements(QXmlStreamReader &reader, BookmarkItem *parentItem) } else if(reader.name() == "folder") { BookmarkItem *item = new BookmarkItem(BookmarkItem::Folder, parentItem); - item->href = reader.attributes().value("href").toString(); item->folded = reader.attributes().value("folded") == QLatin1String("yes"); readChildElements(reader, item); @@ -68,3 +64,59 @@ void Xbel::readChildElements(QXmlStreamReader &reader, BookmarkItem *parentItem) } } } + +bool Xbel::write(BookmarkItem *root) +{ + + // if the path is empty, there is nothing to save to + if(m_path.isEmpty()) + return false; + + QFile file(m_path); + if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + // file cannot be opened for writing + return false; + } + + QXmlStreamWriter xmlWriter(&file); + xmlWriter.setAutoFormatting(true); + + xmlWriter.writeStartDocument(); + xmlWriter.writeDTD(""); + + xmlWriter.writeStartElement("xbel"); + xmlWriter.writeAttribute("version", "1.0"); + + writeChildElements(xmlWriter, root); + + xmlWriter.writeEndDocument(); + + file.close(); + return true; +} + +void Xbel::writeChildElements(QXmlStreamWriter &writer, BookmarkItem *parentItem) +{ + for(int i = 0; i < parentItem->childCount(); ++i) { + BookmarkItem *node = parentItem->child(i); + switch(node->type()) { + case BookmarkItem::Root: + break; + case BookmarkItem::Folder: + writer.writeStartElement("folder"); + writer.writeAttribute("folded", node->folded ? "yes" : "no"); + writer.writeTextElement("title", node->title); + for(int j = 0; j < node->childCount(); ++j) { + writeChildElements(writer, node); + } + writer.writeEndElement(); + break; + case BookmarkItem::Bookmark: + writer.writeStartElement("bookmark"); + writer.writeAttribute("href", node->href); + writer.writeTextElement("title", node->title); + writer.writeEndElement(); + break; + } + } +} diff --git a/lib/bookmarks/xbel.h b/lib/bookmarks/xbel.h index c425cc5..c1de1df 100644 --- a/lib/bookmarks/xbel.h +++ b/lib/bookmarks/xbel.h @@ -17,10 +17,12 @@ class Xbel { public: explicit Xbel(const QString &path); - BookmarkItem *read(); + bool read(BookmarkItem *root); + bool write(BookmarkItem *root); private: void readChildElements(QXmlStreamReader &reader, BookmarkItem *parentItem); + void writeChildElements(QXmlStreamWriter &writer, BookmarkItem *parentItem); QString m_path; }; -- cgit v1.2.1