From f779510603e01de438e337c82c439cc6649cd7c3 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Wed, 7 Feb 2018 21:08:39 +0100 Subject: Rewrote bookmark manager to use QTreeWidget over QTreeView - cut out all the boilerplate that was BookmarkItem/BookmarksModel - deleting items no longer crash; proper drag'n'drop - Split Xbel into XbelReader and XbelWriter --- lib/bookmarks/CMakeLists.txt | 9 +- lib/bookmarks/bookmarkitem.cpp | 67 ------- lib/bookmarks/bookmarkitem.h | 56 ------ lib/bookmarks/bookmarksform.ui | 35 +++- lib/bookmarks/bookmarksmodel.cpp | 393 -------------------------------------- lib/bookmarks/bookmarksmodel.h | 80 -------- lib/bookmarks/bookmarksview.cpp | 49 +++++ lib/bookmarks/bookmarksview.h | 38 ++++ lib/bookmarks/bookmarkswidget.cpp | 109 ++++------- lib/bookmarks/bookmarkswidget.h | 4 - lib/bookmarks/xbel.cpp | 104 +++++----- lib/bookmarks/xbel.h | 20 +- 12 files changed, 232 insertions(+), 732 deletions(-) delete mode 100644 lib/bookmarks/bookmarkitem.cpp delete mode 100644 lib/bookmarks/bookmarkitem.h delete mode 100644 lib/bookmarks/bookmarksmodel.cpp delete mode 100644 lib/bookmarks/bookmarksmodel.h create mode 100644 lib/bookmarks/bookmarksview.cpp create mode 100644 lib/bookmarks/bookmarksview.h (limited to 'lib/bookmarks') diff --git a/lib/bookmarks/CMakeLists.txt b/lib/bookmarks/CMakeLists.txt index 53ba51e..e94c494 100644 --- a/lib/bookmarks/CMakeLists.txt +++ b/lib/bookmarks/CMakeLists.txt @@ -4,13 +4,12 @@ add_library(bookmarks bookmarksform.ui bookmarkswidget.cpp bookmarkswidget.h - # model - bookmarkitem.cpp - bookmarkitem.h - bookmarksmodel.cpp - bookmarksmodel.h + bookmarksview.cpp + bookmarksview.h # xbel xbel.cpp xbel.h) +target_include_directories(bookmarks + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(bookmarks Qt5::Widgets) \ No newline at end of file diff --git a/lib/bookmarks/bookmarkitem.cpp b/lib/bookmarks/bookmarkitem.cpp deleted file mode 100644 index 25b1004..0000000 --- a/lib/bookmarks/bookmarkitem.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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" - -BookmarkItem::BookmarkItem(BookmarkItemType type, BookmarkItem *parent) -{ - m_type = type; - - // parentItem will either be a valid item, or a nullptr - m_parentItem = parent; - if(m_parentItem) { - m_parentItem->appendChild(this); - } -} - -BookmarkItem::~BookmarkItem() -{ - qDeleteAll(m_childItems); -} - -void BookmarkItem::appendChild(BookmarkItem *child) -{ - Q_CHECK_PTR(child); - m_childItems.append(child); -} - -bool BookmarkItem::removeChild(BookmarkItem *child) -{ - Q_CHECK_PTR(child); - return m_childItems.removeOne(child); -} - -BookmarkItem *BookmarkItem::child(int row) -{ - return m_childItems.at(row); -} - -int BookmarkItem::childIndex(BookmarkItem *item) const -{ - return m_childItems.indexOf(item); -} - -int BookmarkItem::childCount() const -{ - return m_childItems.size(); -} - -int BookmarkItem::row() const -{ - if(m_parentItem != nullptr) { - return m_parentItem->m_childItems.indexOf(const_cast(this)); - } - - // no parent item, we are root - return 0; -} - -BookmarkItem *BookmarkItem::parentItem() -{ - return m_parentItem; -} diff --git a/lib/bookmarks/bookmarkitem.h b/lib/bookmarks/bookmarkitem.h deleted file mode 100644 index fa1a91c..0000000 --- a/lib/bookmarks/bookmarkitem.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 -#include - -#ifndef BOOKMARKITEM_H -#define BOOKMARKITEM_H - -class BookmarkItem -{ -public: - enum BookmarkItemType { - Root, - Folder, - Bookmark - }; - - explicit BookmarkItem(BookmarkItemType type, BookmarkItem *parent = nullptr); - ~BookmarkItem(); - - void appendChild(BookmarkItem *child); - bool removeChild(BookmarkItem *child); - BookmarkItem *child(int row); - int childIndex(BookmarkItem *item) const; - int childCount() const; - - BookmarkItemType type() const - { - return m_type; - }; - int columnCount() const - { - return 2; - }; - - int row() const; - BookmarkItem *parentItem(); - - // item data - QString title; - QString href; - bool folded = true; - -private: - BookmarkItemType m_type; - BookmarkItem *m_parentItem; - QVector m_childItems; -}; - -#endif //BOOKMARKITEM_H diff --git a/lib/bookmarks/bookmarksform.ui b/lib/bookmarks/bookmarksform.ui index 5d0f269..78902af 100644 --- a/lib/bookmarks/bookmarksform.ui +++ b/lib/bookmarks/bookmarksform.ui @@ -53,7 +53,33 @@ - + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::DragDrop + + + Qt::MoveAction + + + 2 + + + + Title + + + + + Address + + + @@ -105,6 +131,13 @@ + + + BookmarksView + QTreeWidget +
bookmarksview.h
+
+
diff --git a/lib/bookmarks/bookmarksmodel.cpp b/lib/bookmarks/bookmarksmodel.cpp deleted file mode 100644 index 5b91216..0000000 --- a/lib/bookmarks/bookmarksmodel.cpp +++ /dev/null @@ -1,393 +0,0 @@ -/* - * 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 "bookmarksmodel.h" -#include -#include - -BookmarksModel::BookmarksModel(QStyle *style, QObject *parent) - : QAbstractItemModel(parent) -{ - 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)); - - // create a root item - m_rootItem = new BookmarkItem(BookmarkItem::Root, nullptr); - m_rootItem->title = tr("Title"); - m_rootItem->href = tr("href"); -} - -BookmarksModel::~BookmarksModel() -{ - delete m_rootItem; -} - -bool BookmarksModel::isModified() const -{ - return modified; -} - -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 -{ - if(orientation == Qt::Horizontal && role == Qt::DisplayRole) { - if(section == 0) { - return m_rootItem->title; - } else if(section == 1) { - return m_rootItem->href; - } else { - return QVariant(); - } - } - - return QVariant(); -} - -QModelIndex BookmarksModel::index(BookmarkItem *node, int column) const -{ - BookmarkItem *parentItem = node->parentItem(); - if(!parentItem) { - return QModelIndex(); - } - - return createIndex(parentItem->childIndex(node), column, node); -} - -QModelIndex BookmarksModel::index(int row, int column, const QModelIndex &parent) const -{ - // invalid item requested - if(!hasIndex(row, column, parent)) { - return QModelIndex(); - } - - // index exists - BookmarkItem *parentItem; - if(parent.isValid()) { - parentItem = static_cast(parent.internalPointer()); - } else { - parentItem = m_rootItem; - } - - BookmarkItem *childItem = parentItem->child(row); - if(childItem) { - return createIndex(row, column, childItem); - } - return QModelIndex(); -} - -QModelIndex BookmarksModel::parent(const QModelIndex &index) const -{ - if(!index.isValid()) { - return QModelIndex(); - } - - BookmarkItem *childItem = static_cast(index.internalPointer()); - BookmarkItem *parentItem = childItem->parentItem(); - - if(parentItem == m_rootItem) { - return QModelIndex(); - } - - return createIndex(parentItem->row(), 0, parentItem); -} - -int BookmarksModel::rowCount(const QModelIndex &parent) const -{ - if(parent.column() > 0) { - return 0; - } - - BookmarkItem *parentItem; - if(!parent.isValid()) { - parentItem = m_rootItem; - } else { - parentItem = static_cast(parent.internalPointer()); - } - - return parentItem->childCount(); -} - -QModelIndex BookmarksModel::insertItem(BookmarkItem::BookmarkItemType type, const QModelIndex &parent) -{ - BookmarkItem *parentItem; - if(!parent.isValid()) { - parentItem = m_rootItem; - } else { - parentItem = static_cast(parent.internalPointer()); - if(parentItem->type() == BookmarkItem::Bookmark) - parentItem = parentItem->parentItem(); - } - - beginInsertRows(index(parentItem), parentItem->row(), parentItem->row()); - auto *node = new BookmarkItem(type, parentItem); - node->title = tr("title"); - node->href = tr("href"); - endInsertRows(); - - return index(node); -} - -bool BookmarksModel::removeItem(const QModelIndex &node) -{ - if(!node.isValid()) - return false; - - auto *item = static_cast(node.internalPointer()); - auto *parentItem = item->parentItem(); - - beginRemoveRows(node, node.row(), node.row()); - parentItem->removeChild(item); - delete item; - endRemoveRows(); - return true; -} - -int BookmarksModel::columnCount(const QModelIndex &parent) const -{ - if(parent.isValid()) { - return static_cast(parent.internalPointer())->columnCount(); - } else { - return m_rootItem->columnCount(); - } -} - -Qt::ItemFlags BookmarksModel::flags(const QModelIndex &index) const -{ - if(!index.isValid()) - return Qt::NoItemFlags; - - Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; - auto *node = static_cast(index.internalPointer()); - switch(node->type()) { - case BookmarkItem::Root: - break; - case BookmarkItem::Folder: - flags |= Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; - break; - case BookmarkItem::Bookmark: - flags |= Qt::ItemIsEnabled | Qt::ItemNeverHasChildren | Qt::ItemIsDragEnabled; - break; - } - return flags; -} - -BookmarkItem::BookmarkItemType BookmarksModel::type(const QModelIndex &index) const -{ - if(!index.isValid()) { - return BookmarkItem::Root; - } - - return static_cast(index.internalPointer())->type(); -} - -QVariant BookmarksModel::data(const QModelIndex &index, int role) const -{ - // get data of invalid index? - if(!index.isValid()) { - return QVariant(); - } - - const BookmarkItem *item = static_cast(index.internalPointer()); - switch(role) { - case Qt::DisplayRole: - case Qt::EditRole: - if(index.column() == 0) { - return item->title; - } else if(index.column() == 1) { - return item->href; - } else { - return QVariant(); - } - - case Qt::DecorationRole: - if(index.column() == 0) { - if(item->type() == BookmarkItem::Folder) { - return folderIcon; - } else if(item->type() == BookmarkItem::Bookmark) { - return bookmarkIcon; - } else { - return QVariant(); - } - } else { - return QVariant(); - } - - case TitleRole: - return item->title; - - case OpenUrlRole: - if(item->type() == BookmarkItem::Bookmark) { - return item->href; - } else { - return QVariant(); - } - - default: - return QVariant(); - } -} - -bool BookmarksModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if(!index.isValid()) - return false; - - auto *node = static_cast(index.internalPointer()); - switch(node->type()) { - case BookmarkItem::Root: - return false; - - case BookmarkItem::Folder: - if(role == TitleRole && (node->title != value.toString())) { - node->title = value.toString(); - modified = true; - emit dataChanged(this->index(node, 0), this->index(node, 1)); - //emit dataChanged(index, index); - return true; - } - return false; - - case BookmarkItem::Bookmark: - if(role == TitleRole && (node->title != value.toString())) { - node->title = value.toString(); - modified = true; - emit dataChanged(this->index(node, 0), this->index(node, 1)); - //emit dataChanged(index, index); - return true; - - } else if(role == OpenUrlRole && (node->href != value.toString())) { - node->href = value.toString(); - modified = true; - emit dataChanged(this->index(node, 0), this->index(node, 1)); - //emit dataChanged(index, index); - return true; - } - return false; - } -} - -bool BookmarksModel::hasChildren(const QModelIndex &parent) const -{ - if(!parent.isValid()) { - return true; - } - - const BookmarkItem *parentItem = static_cast(parent.internalPointer()); - return (parentItem->type() == BookmarkItem::Folder); -} - -QModelIndexList BookmarksModel::match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const -{ - QModelIndexList list; - - // search root - BookmarkItem *searchRoot; - if(!start.isValid()) { - searchRoot = m_rootItem; - } else { - searchRoot = static_cast(start.internalPointer()); - } - - // iterate through searchRoot children - for(int i = 0; i < searchRoot->childCount(); ++i) { - BookmarkItem *item = searchRoot->child(i); - if(item->type() == BookmarkItem::Bookmark) { - if(item->href.contains(value.toString())) { - list.append(index(item, 1)); - } - } else if(item->type() == BookmarkItem::Folder) { - list.append(match(index(item), role, value, hits, flags)); - } - } - - 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); - } - } -} -QMimeData *BookmarksModel::mimeData(const QModelIndexList &indexes) const -{ - auto *qMimeData = new QMimeData(); - QByteArray data; - - for(const QModelIndex &idx : indexes) { - if(idx.column() != 0 || !idx.isValid()) - continue; - - QByteArray encodedData; - QBuffer buffer(&encodedData); - buffer.open(QBuffer::ReadWrite); - Xbel writer(&buffer); - writer.write(static_cast(idx.internalPointer())); - - data.append(encodedData); - } - - qMimeData->setData(mimeTypes().first(), data); - - return qMimeData; -} - -bool BookmarksModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) -{ - if(action == Qt::IgnoreAction) - return true; - - // invalid format or column - if(!data->hasFormat(mimeTypes().first()) || column > 0) - return false; - - QByteArray bytes = data->data(mimeTypes().first()); - - QBuffer buffer(&bytes); - buffer.open(QIODevice::ReadOnly); - - Xbel reader(&buffer); - auto *parentItem = static_cast(parent.internalPointer()); - Q_CHECK_PTR(parentItem); - - beginInsertRows(parent, parentItem->row(), parentItem->row()); - reader.read(parentItem); - endInsertRows(); - - modified = true; - return true; -} diff --git a/lib/bookmarks/bookmarksmodel.h b/lib/bookmarks/bookmarksmodel.h deleted file mode 100644 index 7ae20fa..0000000 --- a/lib/bookmarks/bookmarksmodel.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * 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 "xbel.h" -#include -#include -#include - -#ifndef BOOKMARKSMODEL_H -#define BOOKMARKSMODEL_H - -class QStyle; -class BookmarksModel : public QAbstractItemModel -{ - Q_OBJECT - -public: - enum { - TitleRole = Qt::UserRole + 1, - OpenUrlRole = Qt::UserRole + 2 - }; - - explicit BookmarksModel(QStyle *style, QObject *parent = nullptr); - ~BookmarksModel() override; - - bool isModified() const; - - bool read(Xbel *xbel); - bool write(Xbel *xbel); - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; - - QModelIndex index(BookmarkItem *node, int column = 0) const; - QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; - QModelIndex parent(const QModelIndex &index) const override; - - int rowCount(const QModelIndex &parent = QModelIndex()) const override; - QModelIndex insertItem(BookmarkItem::BookmarkItemType type, const QModelIndex &parent); - bool removeItem(const QModelIndex &node); - - int columnCount(const QModelIndex &parent = QModelIndex()) const override; - - Qt::ItemFlags flags(const QModelIndex &index) const override; - BookmarkItem::BookmarkItemType type(const QModelIndex &index) const; - QVariant data(const QModelIndex &index, int role) const override; - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; - - bool hasChildren(const QModelIndex &parent) const override; - - QModelIndexList match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const override; - - void expandItems(QTreeView *view, BookmarkItem *root = nullptr); - - // drag and drop - Qt::DropActions supportedDropActions() const override - { - return Qt::CopyAction | Qt::MoveAction; - } - QStringList mimeTypes() const override - { - return {"application/bookmarks.xbel"}; - } - QMimeData *mimeData(const QModelIndexList &indexes) const override; - bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; - -private: - QIcon folderIcon; - QIcon bookmarkIcon; - bool modified = false; - - BookmarkItem *m_rootItem; -}; - -#endif //BOOKMARKSMODEL_H diff --git a/lib/bookmarks/bookmarksview.cpp b/lib/bookmarks/bookmarksview.cpp new file mode 100644 index 0000000..e427c2f --- /dev/null +++ b/lib/bookmarks/bookmarksview.cpp @@ -0,0 +1,49 @@ +/* + * 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 "bookmarksview.h" + +inline QTreeWidgetItem *createTreeWidgetItem(QTreeWidget *widget, QTreeWidgetItem *parentItem) +{ + if(parentItem) + return new QTreeWidgetItem(parentItem); + else + return new QTreeWidgetItem(widget); +} + +BookmarksView::BookmarksView(QWidget *parent) + : QTreeWidget(parent) +{ + QStyle *qStyle = style(); + folderIcon.addPixmap(qStyle->standardPixmap(QStyle::SP_DirClosedIcon), QIcon::Normal, QIcon::Off); + folderIcon.addPixmap(qStyle->standardPixmap(QStyle::SP_DirOpenIcon), QIcon::Normal, QIcon::On); + bookmarkIcon.addPixmap(qStyle->standardPixmap(QStyle::SP_FileIcon)); +} + +QTreeWidgetItem *BookmarksView::createBookmark(QTreeWidgetItem *parentItem) +{ + QTreeWidgetItem *item = createTreeWidgetItem(this, parentItem); + item->setFlags(item->flags().setFlag(Qt::ItemIsDropEnabled, false) | Qt::ItemIsEditable | Qt::ItemIsDragEnabled); + item->setData(0, Qt::UserRole, Type::Bookmark); + item->setIcon(0, bookmarkIcon); + return item; +} + +QTreeWidgetItem *BookmarksView::createFolder(QTreeWidgetItem *parentItem) +{ + QTreeWidgetItem *item = createTreeWidgetItem(this, parentItem); + item->setFlags(item->flags() | Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled); + item->setData(0, Qt::UserRole, Type::Folder); + item->setIcon(0, folderIcon); + return item; +} + +BookmarksView::Type BookmarksView::itemType(QTreeWidgetItem *item) const +{ + return item->data(0, Qt::UserRole).value(); +} \ No newline at end of file diff --git a/lib/bookmarks/bookmarksview.h b/lib/bookmarks/bookmarksview.h new file mode 100644 index 0000000..5b408e0 --- /dev/null +++ b/lib/bookmarks/bookmarksview.h @@ -0,0 +1,38 @@ +/* + * 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_BOOKMARKSVIEW_H +#define SMOLBOTE_BOOKMARKSVIEW_H + +#include + +class BookmarksView : public QTreeWidget +{ + Q_OBJECT + +public: + enum Type { + Folder, + Bookmark + }; + Q_ENUM(Type) + + explicit BookmarksView(QWidget *parent = nullptr); + + QTreeWidgetItem *createBookmark(QTreeWidgetItem *parentItem); + QTreeWidgetItem *createFolder(QTreeWidgetItem *parentItem); + + Type itemType(QTreeWidgetItem *item) const; + +private: + QIcon folderIcon; + QIcon bookmarkIcon; +}; + + +#endif // SMOLBOTE_BOOKMARKSVIEW_H diff --git a/lib/bookmarks/bookmarkswidget.cpp b/lib/bookmarks/bookmarkswidget.cpp index 8711b35..6ddd71c 100644 --- a/lib/bookmarks/bookmarkswidget.cpp +++ b/lib/bookmarks/bookmarkswidget.cpp @@ -8,6 +8,7 @@ #include "bookmarkswidget.h" #include "ui_bookmarksform.h" +#include "xbel.h" #include BookmarksWidget::BookmarksWidget(const QString &path, QWidget *parent) @@ -19,7 +20,6 @@ BookmarksWidget::BookmarksWidget(const QString &path, QWidget *parent) setWindowTitle(tr("Bookmarks")); ui->setupUi(this); - ui->treeView->header()->setSectionResizeMode(QHeaderView::Stretch); ui->bookmark_groupBox->setVisible(false); ui->folder_groupBox->setVisible(false); @@ -28,94 +28,72 @@ BookmarksWidget::BookmarksWidget(const QString &path, QWidget *parent) ui->deleteItem_toolButton->setIcon(style()->standardPixmap(QStyle::SP_TrashIcon)); ui->deleteItem_toolButton->setShortcut(QKeySequence::Delete); - m_model = new BookmarksModel(style(), this); - ui->treeView->setModel(m_model); - ui->treeView->viewport()->setAcceptDrops(true); - ui->treeView->setDragEnabled(true); - ui->treeView->setDragDropMode(QAbstractItemView::InternalMove); - ui->treeView->setDropIndicatorShown(true); - m_bookmarksPath = path; // read bookmarks { QFile bookmarksFile(m_bookmarksPath); - if (bookmarksFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - Xbel xbel(&bookmarksFile); - qDebug("Reading bookmarks [%s] %s", qUtf8Printable(path), m_model->read(&xbel) ? "ok" : "failed"); + if(bookmarksFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + XbelReader xbel(&bookmarksFile); + xbel.read(ui->treeWidget); + //qDebug("Reading bookmarks [%s] %s", qUtf8Printable(path), m_model->read(&xbel) ? "ok" : "failed"); bookmarksFile.close(); } } - m_model->expandItems(ui->treeView); - // open bookmark action - connect(ui->treeView, &QTreeView::activated, this, [this](const QModelIndex &index) { - emit openUrl(m_model->data(index, BookmarksModel::OpenUrlRole).toUrl()); + connect(ui->treeWidget, &QTreeWidget::itemActivated, this, [this](QTreeWidgetItem *item, int column) { + emit openUrl(QUrl::fromUserInput(item->text(1))); }); // add bookmark action connect(ui->addBookmark_toolButton, &QToolButton::clicked, this, [this]() { - QModelIndex idx = ui->treeView->currentIndex(); - m_model->insertItem(BookmarkItem::Bookmark, idx); + auto *parentItem = ui->treeWidget->currentItem(); + if(ui->treeWidget->itemType(parentItem) == BookmarksView::Bookmark) + parentItem = parentItem->parent(); + + auto *bookmark = ui->treeWidget->createBookmark(parentItem); + bookmark->setText(0, tr("title")); + bookmark->setText(1, tr("href")); }); // add folder action connect(ui->addFolder_toolButton, &QToolButton::clicked, this, [this]() { - QModelIndex idx = ui->treeView->currentIndex(); - m_model->insertItem(BookmarkItem::Folder, idx); - }); - - connect(ui->deleteItem_toolButton, &QToolButton::clicked, this, [this]() { - QModelIndex idx = ui->treeView->currentIndex(); - ui->treeView->clearSelection(); - ui->folder_groupBox->setVisible(false); - ui->bookmark_groupBox->setVisible(false); - m_model->removeItem(idx); - }); + auto *parentItem = ui->treeWidget->currentItem(); + if(ui->treeWidget->itemType(parentItem) == BookmarksView::Bookmark) + parentItem = parentItem->parent(); - // set folder title action - connect(ui->folderTitle, &QLineEdit::returnPressed, this, [this]() { - QModelIndex idx = ui->treeView->currentIndex(); - Q_ASSERT(m_model->type(idx) == BookmarkItem::Folder); - m_model->setData(idx, ui->folderTitle->text(), BookmarksModel::TitleRole); + auto *folder = ui->treeWidget->createFolder(parentItem); + folder->setText(0, tr("title")); }); - // set bookmark title action - connect(ui->bookmarkTitle, &QLineEdit::returnPressed, this, [this]() { - QModelIndex idx = ui->treeView->currentIndex(); - Q_ASSERT(m_model->type(idx) == BookmarkItem::Bookmark); - m_model->setData(idx, ui->bookmarkTitle->text(), BookmarksModel::TitleRole); - }); - - // set bookmark href action - connect(ui->bookmarkHref, &QLineEdit::returnPressed, this, [this]() { - QModelIndex idx = ui->treeView->currentIndex(); - Q_ASSERT(m_model->type(idx) == BookmarkItem::Bookmark); - m_model->setData(idx, ui->bookmarkHref->text(), BookmarksModel::OpenUrlRole); + // delete item action + connect(ui->deleteItem_toolButton, &QToolButton::clicked, this, [this]() { + delete ui->treeWidget->currentItem(); }); - // set item action - connect(ui->treeView->selectionModel(), &QItemSelectionModel::currentChanged, this, [this](const QModelIndex ¤t, const QModelIndex &previous) { + // edit item action + connect(ui->treeWidget, &QTreeWidget::currentItemChanged, this, [this](QTreeWidgetItem *current, QTreeWidgetItem *previous) { // save the previous item - if(previous.isValid() && (ui->folder_groupBox->isVisible() || ui->bookmark_groupBox->isVisible())) { - if(m_model->type(previous) == BookmarkItem::Folder) { - m_model->setData(previous, ui->folderTitle->text(), BookmarksModel::TitleRole); + if(previous) { + if(ui->treeWidget->itemType(previous) == BookmarksView::Folder) { + previous->setText(0, ui->folderTitle->text()); ui->folder_groupBox->setVisible(false); - } else if(m_model->type(previous) == BookmarkItem::Bookmark) { - m_model->setData(previous, ui->bookmarkTitle->text(), BookmarksModel::TitleRole); - m_model->setData(previous, ui->bookmarkHref->text(), BookmarksModel::OpenUrlRole); + } else if(ui->treeWidget->itemType(previous) == BookmarksView::Bookmark) { + previous->setText(0, ui->bookmarkTitle->text()); + previous->setText(1, ui->bookmarkHref->text()); ui->bookmark_groupBox->setVisible(false); } } - if(current.isValid()) { - if(m_model->type(current) == BookmarkItem::Folder) { - ui->folderTitle->setText(m_model->data(current, BookmarksModel::TitleRole).toString()); + // edit current item + if(current) { + if(ui->treeWidget->itemType(current) == BookmarksView::Folder) { + ui->folderTitle->setText(current->text(0)); ui->folder_groupBox->setVisible(true); - } else if(m_model->type(current) == BookmarkItem::Bookmark) { - ui->bookmarkTitle->setText(m_model->data(current, BookmarksModel::TitleRole).toString()); - ui->bookmarkHref->setText(m_model->data(current, BookmarksModel::OpenUrlRole).toString()); + } else if(ui->treeWidget->itemType(current) == BookmarksView::Bookmark) { + ui->bookmarkTitle->setText(current->text(0)); + ui->bookmarkHref->setText(current->text(1)); ui->bookmark_groupBox->setVisible(true); } } @@ -129,26 +107,23 @@ BookmarksWidget::~BookmarksWidget() void BookmarksWidget::save() { + /* if(!m_model->isModified()) { qDebug("Writing bookmarks skipped"); return; } + */ QFile bookmarksFile(m_bookmarksPath); if(bookmarksFile.open(QIODevice::WriteOnly | QIODevice::Text)) { - Xbel xbel(&bookmarksFile); - qDebug("Writing bookmarks %s", m_model->write(&xbel) ? "ok" : "failed"); + XbelWriter xbel(&bookmarksFile); + xbel.write(ui->treeWidget); + //qDebug("Writing bookmarks %s", m_model->write(&xbel) ? "ok" : "failed"); bookmarksFile.flush(); bookmarksFile.close(); } } -QAbstractItemModel *BookmarksWidget::model() const -{ - Q_CHECK_PTR(m_model); - return m_model; -} - void BookmarksWidget::closeOthers() { emit closeOthersSignal(); diff --git a/lib/bookmarks/bookmarkswidget.h b/lib/bookmarks/bookmarkswidget.h index f84b21a..129a5bc 100644 --- a/lib/bookmarks/bookmarkswidget.h +++ b/lib/bookmarks/bookmarkswidget.h @@ -9,8 +9,6 @@ #ifndef BOOKMARKSDIALOG_H #define BOOKMARKSDIALOG_H -#include "bookmarksmodel.h" -#include "xbel.h" #include #include #include @@ -29,7 +27,6 @@ public: ~BookmarksWidget() override; void save(); - QAbstractItemModel *model() const; void closeOthers(); @@ -39,7 +36,6 @@ signals: private: Ui::BookmarksDialog *ui; - BookmarksModel *m_model; QString m_bookmarksPath; }; diff --git a/lib/bookmarks/xbel.cpp b/lib/bookmarks/xbel.cpp index 47d855b..0f84447 100644 --- a/lib/bookmarks/xbel.cpp +++ b/lib/bookmarks/xbel.cpp @@ -9,42 +9,28 @@ #include "xbel.h" #include -Xbel::Xbel(QIODevice *file) +XbelReader::XbelReader(QIODevice *file) { Q_CHECK_PTR(file); m_file = file; } -bool Xbel::read(BookmarkItem *root) -{ - QXmlStreamReader xmlReader(m_file); - - if(xmlReader.readNextStartElement()) { - if(!(xmlReader.name() == "xbel" && xmlReader.attributes().value("version") == "1.0")) { - return false; - } - - readChildElements(xmlReader, root); - } - - return true; -} - -void Xbel::readChildElements(QXmlStreamReader &reader, BookmarkItem *parentItem) +void readChildElements(QXmlStreamReader &reader, BookmarksView *widget, QTreeWidgetItem *parentItem = nullptr) { while(reader.readNextStartElement()) { if(reader.name() == "title") { - parentItem->title = reader.readElementText(); + Q_CHECK_PTR(parentItem); + parentItem->setText(0, reader.readElementText()); } else if(reader.name() == "folder") { - BookmarkItem *item = new BookmarkItem(BookmarkItem::Folder, parentItem); - item->folded = reader.attributes().value("folded") == QLatin1String("yes"); - readChildElements(reader, item); + auto *item = widget->createFolder(parentItem); + widget->setItemExpanded(item, !(reader.attributes().value("folded") == QLatin1String("yes"))); + readChildElements(reader, widget, item); } else if(reader.name() == "bookmark") { - BookmarkItem *item = new BookmarkItem(BookmarkItem::Bookmark, parentItem); - item->href = reader.attributes().value("href").toString(); - readChildElements(reader, item); + auto *item = widget->createBookmark(parentItem); + item->setText(1, reader.attributes().value("href").toString()); + readChildElements(reader, widget, item); } else { reader.skipCurrentElement(); @@ -52,50 +38,64 @@ void Xbel::readChildElements(QXmlStreamReader &reader, BookmarkItem *parentItem) } } -bool Xbel::write(BookmarkItem *root) +void XbelReader::read(BookmarksView *treeWidget) { - QXmlStreamWriter xmlWriter(m_file); - xmlWriter.setAutoFormatting(true); + QXmlStreamReader qXmlStreamReader(m_file); - xmlWriter.writeStartDocument(); - xmlWriter.writeDTD(""); - - xmlWriter.writeStartElement("xbel"); - xmlWriter.writeAttribute("version", "1.0"); - - writeChildElements(xmlWriter, root); - - xmlWriter.writeEndDocument(); + if(qXmlStreamReader.readNextStartElement()) { + if(!(qXmlStreamReader.name() == "xbel" && qXmlStreamReader.attributes().value("version") == "1.0")) { + return; + } - return true; + readChildElements(qXmlStreamReader, treeWidget); + } } -void Xbel::writeChildElements(QXmlStreamWriter &writer, BookmarkItem *parentItem) +XbelWriter::XbelWriter(QIODevice *file) { - switch(parentItem->type()) { - case BookmarkItem::Root: - for(int i = 0; i < parentItem->childCount(); ++i) { - writeChildElements(writer, parentItem->child(i)); - } - break; + Q_CHECK_PTR(file); + m_file = file; +} - case BookmarkItem::Folder: +void writeChildElements(QXmlStreamWriter &writer, BookmarksView *treeWidget, QTreeWidgetItem *parentItem) +{ + switch(treeWidget->itemType(parentItem)) { + case BookmarksView::Folder: writer.writeStartElement("folder"); - writer.writeAttribute("folded", parentItem->folded ? "yes" : "no"); - writer.writeTextElement("title", parentItem->title); + writer.writeAttribute("folded", !treeWidget->isItemExpanded(parentItem) ? "yes" : "no"); + writer.writeTextElement("title", parentItem->text(0)); for(int i = 0; i < parentItem->childCount(); ++i) { - writeChildElements(writer, parentItem->child(i)); + writeChildElements(writer, treeWidget, parentItem->child(i)); } writer.writeEndElement(); - break; - case BookmarkItem::Bookmark: + break; + case BookmarksView::Bookmark: writer.writeStartElement("bookmark"); - writer.writeAttribute("href", parentItem->href); - writer.writeTextElement("title", parentItem->title); + writer.writeAttribute("href", parentItem->text(1)); + writer.writeTextElement("title", parentItem->text(0)); writer.writeEndElement(); + break; } } + +void XbelWriter::write(BookmarksView *treeWidget) +{ + QXmlStreamWriter xmlWriter(m_file); + xmlWriter.setAutoFormatting(true); + + xmlWriter.writeStartDocument(); + xmlWriter.writeDTD(""); + + xmlWriter.writeStartElement("xbel"); + xmlWriter.writeAttribute("version", "1.0"); + + for(int i = 0; i < treeWidget->topLevelItemCount(); ++i) { + writeChildElements(xmlWriter, treeWidget, treeWidget->topLevelItem(i)); + } + + xmlWriter.writeEndDocument(); +} diff --git a/lib/bookmarks/xbel.h b/lib/bookmarks/xbel.h index f0945bf..6981627 100644 --- a/lib/bookmarks/xbel.h +++ b/lib/bookmarks/xbel.h @@ -9,21 +9,27 @@ #ifndef XBELREADER_H #define XBELREADER_H -#include "bookmarkitem.h" #include #include +#include "bookmarksview.h" -class Xbel +class XbelReader { public: - explicit Xbel(QIODevice *file); - bool read(BookmarkItem *root); - bool write(BookmarkItem *root); + explicit XbelReader(QIODevice *file); + void read(BookmarksView *treeWidget); private: - void readChildElements(QXmlStreamReader &reader, BookmarkItem *parentItem); - void writeChildElements(QXmlStreamWriter &writer, BookmarkItem *parentItem); + QIODevice *m_file; +}; + +class XbelWriter +{ +public: + explicit XbelWriter(QIODevice *file); + void write(BookmarksView *treeWidget); +private: QIODevice *m_file; }; -- cgit v1.2.1