From 579c713959c150a276f42b3f69ccfb89d9e6eebb Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Mon, 24 Sep 2018 14:55:35 +0200 Subject: Bookmarks: add BookmarkItem and BookmarkModel - read-only xbel - only enabled in debug build --- lib/bookmarks/CMakeLists.txt | 16 ++- lib/bookmarks/bookmarkitem.cpp | 136 ++++++++++++++++++++ lib/bookmarks/bookmarkitem.h | 68 ++++++++++ lib/bookmarks/bookmarkmodel.cpp | 193 +++++++++++++++++++++++++++++ lib/bookmarks/bookmarkmodel.h | 51 ++++++++ lib/bookmarks/bookmarkswidget.cpp | 56 ++++++++- lib/bookmarks/forms/editbookmarkdialog.cpp | 45 +++++++ lib/bookmarks/forms/editbookmarkdialog.h | 32 +++++ lib/bookmarks/forms/editbookmarkdialog.ui | 108 ++++++++++++++++ lib/bookmarks/xbel.cpp | 40 ++++++ lib/bookmarks/xbel.h | 3 + 11 files changed, 743 insertions(+), 5 deletions(-) create mode 100644 lib/bookmarks/bookmarkitem.cpp create mode 100644 lib/bookmarks/bookmarkitem.h create mode 100644 lib/bookmarks/bookmarkmodel.cpp create mode 100644 lib/bookmarks/bookmarkmodel.h create mode 100644 lib/bookmarks/forms/editbookmarkdialog.cpp create mode 100644 lib/bookmarks/forms/editbookmarkdialog.h create mode 100644 lib/bookmarks/forms/editbookmarkdialog.ui diff --git a/lib/bookmarks/CMakeLists.txt b/lib/bookmarks/CMakeLists.txt index b7bbf0d..d2256c6 100644 --- a/lib/bookmarks/CMakeLists.txt +++ b/lib/bookmarks/CMakeLists.txt @@ -14,8 +14,16 @@ add_library(bookmarks bookmarksview.h # xbel xbel.cpp - xbel.h) + xbel.h -target_include_directories(bookmarks - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(bookmarks Qt5::Widgets) \ No newline at end of file + # bookmark item/model/view + bookmarkitem.cpp + bookmarkitem.h + bookmarkmodel.cpp + bookmarkmodel.h + forms/editbookmarkdialog.cpp + forms/editbookmarkdialog.h + forms/editbookmarkdialog.ui +) + +target_link_libraries(bookmarks Qt5::Widgets) diff --git a/lib/bookmarks/bookmarkitem.cpp b/lib/bookmarks/bookmarkitem.cpp new file mode 100644 index 0000000..197c0ae --- /dev/null +++ b/lib/bookmarks/bookmarkitem.cpp @@ -0,0 +1,136 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/smolbote.hg + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#include "bookmarkitem.h" +#include +#include + +BookmarkItem::BookmarkItem(const QVector &data, Type type, BookmarkItem *parent) +{ + m_parentItem = parent; + + m_type = type; + if(m_type == Folder) { + m_icon.addPixmap(qApp->style()->standardPixmap(QStyle::SP_DirClosedIcon), QIcon::Normal, QIcon::Off); + m_icon.addPixmap(qApp->style()->standardPixmap(QStyle::SP_DirOpenIcon), QIcon::Normal, QIcon::On); + } else if(m_type == Bookmark) + m_icon.addPixmap(qApp->style()->standardPixmap(QStyle::SP_FileIcon)); + + m_data.resize(FieldCount); + for(int i = 0; i < FieldCount; ++i) { + m_data[i] = data.value(i, QVariant()); + } +} + +BookmarkItem::~BookmarkItem() +{ + qDeleteAll(m_children); +} + +BookmarkItem *BookmarkItem::parent() const +{ + return m_parentItem; +} + +bool BookmarkItem::appendChild(BookmarkItem *childItem) +{ + // Only folders can have children, so only append them on folders + // This way, we don't need to add checks to the other methods + if(m_type == Folder) { + m_children.append(childItem); + return true; + } + + return false; +} + +bool BookmarkItem::insertChild(int position, BookmarkItem *childItem) +{ + if(m_type == Folder) { + m_children.insert(position, childItem); + return true; + } + + return false; +} + +bool BookmarkItem::removeChildAt(int index, int count) +{ + if(index < 0 || index + count > m_children.size()) + return false; + + // delete the item at index count times + for(int i = 0; i < count; ++i) { + delete m_children.takeAt(index); + } + return true; +} + +BookmarkItem *BookmarkItem::takeChild(int index, BookmarkItem *newParent) +{ + m_children[index]->m_parentItem = newParent; + return m_children.takeAt(index); +} + +BookmarkItem *BookmarkItem::child(int index) +{ + return m_children.value(index); +} + +int BookmarkItem::childCount() const +{ + return m_children.count(); +} + +QVariant BookmarkItem::data(int column) const +{ + return m_data.value(column); +} + +bool BookmarkItem::setData(Fields column, const QVariant &data) +{ + if(column >= FieldCount) + return false; + + m_data[column] = data; + return true; +} + +QIcon BookmarkItem::icon() const +{ + return m_icon; +} + +bool BookmarkItem::isExpanded() const +{ + return m_isExpanded; +} + +void BookmarkItem::setExpanded(bool expanded) +{ + if(m_type == BookmarkItem::Folder) + m_isExpanded = expanded; +} + +QString BookmarkItem::tooltip() const +{ + return m_data.value(Tags).toStringList().join(", "); +} + +BookmarkItem::Type BookmarkItem::type() const +{ + return m_type; +} + +int BookmarkItem::row() const +{ + if(m_parentItem) + return m_parentItem->m_children.indexOf(const_cast(this)); + + return 0; +} diff --git a/lib/bookmarks/bookmarkitem.h b/lib/bookmarks/bookmarkitem.h new file mode 100644 index 0000000..37a9b5d --- /dev/null +++ b/lib/bookmarks/bookmarkitem.h @@ -0,0 +1,68 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/smolbote.hg + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#ifndef SMOLBOTE_BOOKMARKITEM_H +#define SMOLBOTE_BOOKMARKITEM_H + +#include +#include +#include + +class BookmarkItem +{ +public: + enum Type { + Folder, + Bookmark, + }; + + enum Fields { + Title, + Href, + Tags, + Description, + FieldCount + }; + + explicit BookmarkItem(const QVector &data, Type type, BookmarkItem *parent = nullptr); + ~BookmarkItem(); + + BookmarkItem *parent() const; + + bool appendChild(BookmarkItem *childItem); + bool insertChild(int position, BookmarkItem *childItem); + bool removeChildAt(int index, int count = 1); + BookmarkItem *takeChild(int index, BookmarkItem *newParent); + + BookmarkItem *child(int index); + int childCount() const; + + QVariant data(int column) const; + bool setData(Fields column, const QVariant &data); + + QIcon icon() const; + bool isExpanded() const; + void setExpanded(bool expanded); + + QString tooltip() const; + Type type() const; + int row() const; + +private: + QVector m_children; + BookmarkItem *m_parentItem; + + Type m_type; + QIcon m_icon; + bool m_isExpanded = false; + + // fields + QVector m_data; +}; + +#endif //SMOLBOTE_BOOKMARKITEM_H diff --git a/lib/bookmarks/bookmarkmodel.cpp b/lib/bookmarks/bookmarkmodel.cpp new file mode 100644 index 0000000..3b57fea --- /dev/null +++ b/lib/bookmarks/bookmarkmodel.cpp @@ -0,0 +1,193 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/smolbote.hg + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#include "bookmarkmodel.h" +#include "bookmarkitem.h" + +BookmarkModel::BookmarkModel(QObject *parent) + : QAbstractItemModel(parent) +{ + rootItem = new BookmarkItem({ "Title", "Address" }, BookmarkItem::Folder, nullptr); +} + +BookmarkModel::~BookmarkModel() +{ + delete rootItem; +} + +QVariant BookmarkModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(orientation == Qt::Horizontal && role == Qt::DisplayRole) + return rootItem->data(section); + + return QVariant(); +} + +QVariant BookmarkModel::data(const QModelIndex &index, int role) const +{ + if(!index.isValid()) + return QVariant(); + + if(role == Qt::DecorationRole && index.column() == 0) + return static_cast(index.internalPointer())->icon(); + else if(role == Qt::ToolTipRole) + return static_cast(index.internalPointer())->tooltip(); + else if(role != Qt::DisplayRole) + return QVariant(); + + return static_cast(index.internalPointer())->data(index.column()); +} + +QVariant BookmarkModel::data(const QModelIndex &index, int column, int role) const +{ + if(!index.isValid()) + return QVariant(); + + if(role == Qt::DisplayRole) + return static_cast(index.internalPointer())->data(column); + + return QVariant(); +} + +bool BookmarkModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if(!index.isValid() || role != Qt::DisplayRole) + return false; + + bool success = static_cast(index.internalPointer())->setData(static_cast(index.column()), value); + if(success) + emit dataChanged(index, index, { role }); + return success; +} + +bool BookmarkModel::setData(const QModelIndex &index, const QVariant &value, BookmarkItem::Fields column, int role) +{ + if(!index.isValid() || role != Qt::DisplayRole) + return false; + + bool success = static_cast(index.internalPointer())->setData(column, value); + if(success) + emit dataChanged(index, index, { role }); + return success; +} + +Qt::ItemFlags BookmarkModel::flags(const QModelIndex &index) const +{ + if(getItem(index)->type() == BookmarkItem::Folder) + return QAbstractItemModel::flags(index) | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; + else + return QAbstractItemModel::flags(index) | Qt::ItemIsDragEnabled; +} + +bool BookmarkModel::isItemExpanded(const QModelIndex &index) const +{ + if(!index.isValid()) + return false; + + return static_cast(index.internalPointer())->isExpanded(); +} + +int BookmarkModel::rowCount(const QModelIndex &index) const +{ + if(index.column() > 0) + return 0; + + return getItem(index)->childCount(); +} + +bool BookmarkModel::insertRows(int position, int rows, const QModelIndex &parent) +{ + auto *parentItem = getItem(parent); + + // if position is negative, or past the number of children in the item + if(position < 0 || position > parentItem->childCount()) + return false; + + beginInsertRows(parent, position, position + rows - 1); + for(int i = 0; i < rows; ++i) { + parentItem->insertChild(position + i, new BookmarkItem({}, BookmarkItem::Bookmark, parentItem)); + } + endInsertRows(); + return true; +} + +bool BookmarkModel::removeRows(int position, int rows, const QModelIndex &parent) +{ + auto *parentItem = getItem(parent); + + beginRemoveRows(parent, position, position + rows - 1); + bool success = parentItem->removeChildAt(position, rows); + endRemoveRows(); + return success; +} + +bool BookmarkModel::moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) +{ + auto *sourceParentItem = getItem(sourceParent); + auto *destinationParentItem = getItem(destinationParent); + + bool success = true; + beginMoveRows(sourceParent, sourceRow, sourceRow + count - 1, destinationParent, destinationChild); + for(int i = 0; i < count; ++i) { + auto *child = sourceParentItem->takeChild(sourceRow, destinationParentItem); + if(!destinationParentItem->insertChild(destinationChild, child)) { + success = false; + break; + } + } + endMoveRows(); + return success; +} + +int BookmarkModel::columnCount(const QModelIndex &index) const +{ + return 2; + // if(!index.isValid()) + // return rootItem->columnCount(); + // else + // return static_cast(index.internalPointer())->columnCount(); +} + +Qt::DropActions BookmarkModel::supportedDropActions() const +{ + return Qt::MoveAction; +} + +QModelIndex BookmarkModel::index(int row, int column, const QModelIndex &parent) const +{ + if(!this->hasIndex(row, column, parent)) + return QModelIndex(); + + BookmarkItem *parentItem = getItem(parent); + BookmarkItem *childItem = parentItem->child(row); + if(childItem) + return createIndex(row, column, childItem); + else + return QModelIndex(); +} + +QModelIndex BookmarkModel::parent(const QModelIndex &index) const +{ + if(!index.isValid()) + return QModelIndex(); + + auto *childItem = static_cast(index.internalPointer()); + auto *parentItem = childItem->parent(); + + if(parentItem == rootItem) + return QModelIndex(); + + return createIndex(parentItem->row(), 0, parentItem); +} +BookmarkItem *BookmarkModel::getItem(const QModelIndex &index) const +{ + if(!index.isValid()) + return rootItem; + else + return static_cast(index.internalPointer()); +} diff --git a/lib/bookmarks/bookmarkmodel.h b/lib/bookmarks/bookmarkmodel.h new file mode 100644 index 0000000..90fdb2a --- /dev/null +++ b/lib/bookmarks/bookmarkmodel.h @@ -0,0 +1,51 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/smolbote.hg + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#ifndef SMOLBOTE_BOOKMARKMODEL_H +#define SMOLBOTE_BOOKMARKMODEL_H + +#include +#include "bookmarkitem.h" + +class BookmarkModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + explicit BookmarkModel(QObject *parent = nullptr); + ~BookmarkModel() override; + + QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + QVariant data(const QModelIndex &index, int role) const override; + QVariant data(const QModelIndex &index, int column, int role) const; + bool setData(const QModelIndex &index, const QVariant &value, int role) override; + bool setData(const QModelIndex &index, const QVariant &value, BookmarkItem::Fields column, int role); + Qt::ItemFlags flags(const QModelIndex &index) const override; + + bool isItemExpanded(const QModelIndex &index) const; + + int rowCount(const QModelIndex &index) const override; + bool insertRows(int position, int rows, const QModelIndex &parent) override; + bool removeRows(int position, int rows, const QModelIndex &parent) override; + bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override; + int columnCount(const QModelIndex &index) const override; + Qt::DropActions supportedDropActions() const override; + + QModelIndex index(int row, int column, const QModelIndex &parent) const override; + QModelIndex parent(const QModelIndex &index) const override; + + BookmarkItem *root() { + return rootItem; + } + +private: + BookmarkItem *getItem(const QModelIndex &index) const; + BookmarkItem *rootItem; +}; + +#endif //SMOLBOTE_BOOKMARKMODEL_H diff --git a/lib/bookmarks/bookmarkswidget.cpp b/lib/bookmarks/bookmarkswidget.cpp index c56fe6c..8e6677c 100644 --- a/lib/bookmarks/bookmarkswidget.cpp +++ b/lib/bookmarks/bookmarkswidget.cpp @@ -11,6 +11,26 @@ #include "xbel.h" #include +#ifdef QT_DEBUG +#include +#include "bookmarkmodel.h" +#include "bookmarkitem.h" +#include "forms/editbookmarkdialog.h" + +inline void expandChildren(QTreeView *view, BookmarkModel *model, const QModelIndex &rootIndex) +{ + for(int i = 0; i < model->rowCount(rootIndex); ++i) { + QModelIndex idx = model->index(i, 0, rootIndex); + if(model->isItemExpanded(idx)) + view->expand(idx); + + // check if index has children + if(model->rowCount(idx) > 0) + expandChildren(view, model, idx); + } +} +#endif + BookmarksWidget::BookmarksWidget(const QString &path, QWidget *parent) : QWidget(parent) , ui(new Ui::BookmarksDialog) @@ -27,6 +47,40 @@ BookmarksWidget::BookmarksWidget(const QString &path, QWidget *parent) ui->deleteItem_toolButton->setIcon(style()->standardPixmap(QStyle::SP_TrashIcon)); ui->deleteItem_toolButton->setShortcut(QKeySequence::Delete); + // Testing model/view +#ifdef QT_DEBUG + { + auto *treeView = new QTreeView(this); + treeView->setDragEnabled(true); + treeView->setAcceptDrops(true); + treeView->setDropIndicatorShown(true); + treeView->setDragDropMode(QAbstractItemView::InternalMove); + ui->verticalLayout->addWidget(treeView); + auto *model = new BookmarkModel(this); + + QFile bookmarksFile(path); + if(bookmarksFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + XbelReader xbel(&bookmarksFile); + xbel.read(model); + bookmarksFile.close(); + } + + treeView->setModel(model); + + expandChildren(treeView, model, QModelIndex()); + + connect(treeView, &QTreeView::activated, this, [this, model](const QModelIndex &index) { + if(index.column() == 1) + emit openUrl(index.data(Qt::DisplayRole).toUrl()); + else { + auto *dlg = new EditBookmarkDialog(model, index, this); + dlg->exec(); + } + }); + } +#endif + // + m_bookmarksPath = path; // read bookmarks @@ -115,7 +169,7 @@ BookmarksWidget::~BookmarksWidget() void BookmarksWidget::save() { - if (!m_isChanged) { + if(!m_isChanged) { return; } diff --git a/lib/bookmarks/forms/editbookmarkdialog.cpp b/lib/bookmarks/forms/editbookmarkdialog.cpp new file mode 100644 index 0000000..47aa0b7 --- /dev/null +++ b/lib/bookmarks/forms/editbookmarkdialog.cpp @@ -0,0 +1,45 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/smolbote.hg + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#include "editbookmarkdialog.h" +#include "../bookmarkitem.h" +#include "../bookmarkmodel.h" +#include "ui_editbookmarkdialog.h" + +EditBookmarkDialog::EditBookmarkDialog(BookmarkModel *model, const QModelIndex &index, QWidget *parent) + : QDialog(parent) + , ui(new Ui::EditBookmarkDialog) +{ + ui->setupUi(this); + setAttribute(Qt::WA_DeleteOnClose, true); + + ui->title->setText(model->data(index, BookmarkItem::Title, Qt::DisplayRole).toString()); + connect(ui->title, &QLineEdit::editingFinished, this, [this, model, index]() { + model->setData(index, ui->title->text(), BookmarkItem::Title, Qt::DisplayRole); + }); + + ui->address->setText(model->data(index, BookmarkItem::Href, Qt::DisplayRole).toString()); + connect(ui->address, &QLineEdit::editingFinished, this, [this, model, index]() { + model->setData(index, ui->address->text(), BookmarkItem::Href, Qt::DisplayRole); + }); + + ui->tags->setText(model->data(index, BookmarkItem::Tags, Qt::DisplayRole).toStringList().join(", ")); + connect(ui->tags, &QLineEdit::editingFinished, this, [this, model, index]() { + model->setData(index, ui->tags->text().split(", "), BookmarkItem::Tags, Qt::DisplayRole); + }); + + ui->description->setPlainText(model->data(index, BookmarkItem::Description, Qt::DisplayRole).toString()); + connect(ui->description, &QPlainTextEdit::textChanged, this, [this, model, index]() { + model->setData(index, ui->description->toPlainText(), BookmarkItem::Description, Qt::DisplayRole); + }); +} + +EditBookmarkDialog::~EditBookmarkDialog() +{ + delete ui; +} diff --git a/lib/bookmarks/forms/editbookmarkdialog.h b/lib/bookmarks/forms/editbookmarkdialog.h new file mode 100644 index 0000000..968b6af --- /dev/null +++ b/lib/bookmarks/forms/editbookmarkdialog.h @@ -0,0 +1,32 @@ +/* + * This file is part of smolbote. It's copyrighted by the contributors recorded + * in the version control history of the file, available from its original + * location: https://neueland.iserlohn-fortress.net/smolbote.hg + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#ifndef SMOLBOTE_EDITBOOKMARKDIALOG_H +#define SMOLBOTE_EDITBOOKMARKDIALOG_H + +#include + +namespace Ui +{ +class EditBookmarkDialog; +} + +class BookmarkModel; +class EditBookmarkDialog : public QDialog +{ + Q_OBJECT + +public: + explicit EditBookmarkDialog(BookmarkModel *model, const QModelIndex &index, QWidget *parent = nullptr); + ~EditBookmarkDialog() override; + +private: + Ui::EditBookmarkDialog *ui; +}; + +#endif // SMOLBOTE_EDITBOOKMARKDIALOG_H diff --git a/lib/bookmarks/forms/editbookmarkdialog.ui b/lib/bookmarks/forms/editbookmarkdialog.ui new file mode 100644 index 0000000..1861fcc --- /dev/null +++ b/lib/bookmarks/forms/editbookmarkdialog.ui @@ -0,0 +1,108 @@ + + + EditBookmarkDialog + + + + 0 + 0 + 262 + 320 + + + + Dialog + + + + + + + + Title + + + + + + + + + + Address + + + + + + + + + + Tags + + + + + + + + + + Description + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close|QDialogButtonBox::Save + + + + + + + + + buttonBox + accepted() + EditBookmarkDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + EditBookmarkDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/lib/bookmarks/xbel.cpp b/lib/bookmarks/xbel.cpp index cd17f2d..a1bf2f6 100644 --- a/lib/bookmarks/xbel.cpp +++ b/lib/bookmarks/xbel.cpp @@ -8,6 +8,9 @@ #include "xbel.h" #include +#include +#include "bookmarkitem.h" +#include "bookmarkmodel.h" XbelReader::XbelReader(QIODevice *file) { @@ -38,6 +41,30 @@ void readChildElements(QXmlStreamReader &reader, BookmarksView *widget, QTreeWid } } +void readChildElements(QXmlStreamReader &reader, BookmarkItem *parent) +{ + while(reader.readNextStartElement()) { + if(reader.name() == "title") { + parent->setData(BookmarkItem::Title, reader.readElementText()); + + } else if(reader.name() == "folder") { + auto *item = new BookmarkItem({}, BookmarkItem::Folder, parent); + item->setExpanded(!(reader.attributes().value("folded") == QLatin1Literal("yes"))); + parent->appendChild(item); + readChildElements(reader, item); + + } else if(reader.name() == "bookmark") { + auto *item = new BookmarkItem({}, BookmarkItem::Bookmark, parent); + item->setData(BookmarkItem::Href, reader.attributes().value("href").toString()); + parent->appendChild(item); + readChildElements(reader, item); + + } else { + reader.skipCurrentElement(); + } + } +} + void XbelReader::read(BookmarksView *treeWidget) { QXmlStreamReader qXmlStreamReader(m_file); @@ -51,6 +78,19 @@ void XbelReader::read(BookmarksView *treeWidget) } } +void XbelReader::read(BookmarkModel *model) +{ + QXmlStreamReader qXmlStreamReader(m_file); + + if(qXmlStreamReader.readNextStartElement()) { + if(!(qXmlStreamReader.name() == "xbel" && qXmlStreamReader.attributes().value("version") == "1.0")) { + return; + } + + readChildElements(qXmlStreamReader, model->root()); + } +} + XbelWriter::XbelWriter(QIODevice *file) { Q_CHECK_PTR(file); diff --git a/lib/bookmarks/xbel.h b/lib/bookmarks/xbel.h index ecc185a..e285b70 100644 --- a/lib/bookmarks/xbel.h +++ b/lib/bookmarks/xbel.h @@ -12,12 +12,15 @@ #include "bookmarksview.h" #include #include +#include "bookmarkmodel.h" +class BookmarkModel; class XbelReader { public: explicit XbelReader(QIODevice *file); void read(BookmarksView *treeWidget); + void read(BookmarkModel *model); private: QIODevice *m_file; -- cgit v1.2.1