aboutsummaryrefslogtreecommitdiff
path: root/lib/bookmarks
diff options
context:
space:
mode:
authorAqua-sama <aqua@iserlohn-fortress.net>2018-02-07 21:08:39 +0100
committerAqua-sama <aqua@iserlohn-fortress.net>2018-02-07 21:08:39 +0100
commitf779510603e01de438e337c82c439cc6649cd7c3 (patch)
tree98254e5ab079edcc6e207d692af28378573d4f0f /lib/bookmarks
parentBookmarks bugfixes (diff)
downloadsmolbote-f779510603e01de438e337c82c439cc6649cd7c3.tar.xz
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
Diffstat (limited to 'lib/bookmarks')
-rw-r--r--lib/bookmarks/CMakeLists.txt9
-rw-r--r--lib/bookmarks/bookmarkitem.cpp67
-rw-r--r--lib/bookmarks/bookmarkitem.h56
-rw-r--r--lib/bookmarks/bookmarksform.ui35
-rw-r--r--lib/bookmarks/bookmarksmodel.cpp393
-rw-r--r--lib/bookmarks/bookmarksmodel.h80
-rw-r--r--lib/bookmarks/bookmarksview.cpp49
-rw-r--r--lib/bookmarks/bookmarksview.h38
-rw-r--r--lib/bookmarks/bookmarkswidget.cpp109
-rw-r--r--lib/bookmarks/bookmarkswidget.h4
-rw-r--r--lib/bookmarks/xbel.cpp104
-rw-r--r--lib/bookmarks/xbel.h20
12 files changed, 232 insertions, 732 deletions
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<BookmarkItem *>(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 <QVariant>
-#include <QVector>
-
-#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<BookmarkItem *> 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 @@
</layout>
</item>
<item>
- <widget class="QTreeView" name="treeView"/>
+ <widget class="BookmarksView" name="treeWidget">
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
+ </property>
+ <property name="dragEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="dragDropMode">
+ <enum>QAbstractItemView::DragDrop</enum>
+ </property>
+ <property name="defaultDropAction">
+ <enum>Qt::MoveAction</enum>
+ </property>
+ <property name="columnCount">
+ <number>2</number>
+ </property>
+ <column>
+ <property name="text">
+ <string notr="true">Title</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Address</string>
+ </property>
+ </column>
+ </widget>
</item>
<item>
<widget class="QGroupBox" name="bookmark_groupBox">
@@ -105,6 +131,13 @@
</item>
</layout>
</widget>
+ <customwidgets>
+ <customwidget>
+ <class>BookmarksView</class>
+ <extends>QTreeWidget</extends>
+ <header>bookmarksview.h</header>
+ </customwidget>
+ </customwidgets>
<resources/>
<connections/>
</ui>
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 <QBuffer>
-#include <QMimeData>
-
-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<BookmarkItem *>(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<BookmarkItem *>(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<BookmarkItem *>(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<BookmarkItem *>(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<BookmarkItem *>(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<BookmarkItem *>(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<BookmarkItem *>(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<BookmarkItem *>(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<BookmarkItem *>(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<BookmarkItem *>(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<BookmarkItem *>(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<BookmarkItem *>(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<BookmarkItem *>(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<BookmarkItem *>(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 <QAbstractItemModel>
-#include <QIcon>
-#include <QTreeView>
-
-#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<Type>();
+} \ 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 <QTreeWidget>
+
+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 <QUrl>
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 &current, 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 <QShortcut>
#include <QWidget>
#include <QFile>
@@ -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 <QFile>
-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("<!DOCTYPE xbel>");
-
- 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("<!DOCTYPE xbel>");
+
+ 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 <QString>
#include <QXmlStreamReader>
+#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;
};