From 4c71c8571ceb10b29e6550cd0d8eb928049e6851 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Tue, 14 Jan 2020 23:34:13 +0200 Subject: Move/rename files for readability - add BookmarkFormat <<|>> BookmarkModel operators --- lib/bookmarks/bookmarkformat.cpp | 26 +++ lib/bookmarks/bookmarkformat.h | 67 ++++++ lib/bookmarks/bookmarkitem.cpp | 139 +++++++++++ lib/bookmarks/bookmarkitem.h | 69 ++++++ lib/bookmarks/bookmarkmodel.cpp | 356 +++++++++++++++++++++++++++++ lib/bookmarks/bookmarkmodel.h | 73 ++++++ lib/bookmarks/bookmarkswidget.cpp | 14 +- lib/bookmarks/formats/format.cpp | 26 --- lib/bookmarks/formats/format.h | 36 --- lib/bookmarks/formats/xbel.cpp | 2 +- lib/bookmarks/forms/editbookmarkdialog.cpp | 4 +- lib/bookmarks/meson.build | 6 +- lib/bookmarks/model/bookmarkitem.cpp | 139 ----------- lib/bookmarks/model/bookmarkitem.h | 69 ------ lib/bookmarks/model/bookmarkmodel.cpp | 356 ----------------------------- lib/bookmarks/model/bookmarkmodel.h | 73 ------ 16 files changed, 740 insertions(+), 715 deletions(-) create mode 100644 lib/bookmarks/bookmarkformat.cpp create mode 100644 lib/bookmarks/bookmarkformat.h 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 delete mode 100644 lib/bookmarks/formats/format.cpp delete mode 100644 lib/bookmarks/formats/format.h delete mode 100644 lib/bookmarks/model/bookmarkitem.cpp delete mode 100644 lib/bookmarks/model/bookmarkitem.h delete mode 100644 lib/bookmarks/model/bookmarkmodel.cpp delete mode 100644 lib/bookmarks/model/bookmarkmodel.h diff --git a/lib/bookmarks/bookmarkformat.cpp b/lib/bookmarks/bookmarkformat.cpp new file mode 100644 index 0000000..e6149cd --- /dev/null +++ b/lib/bookmarks/bookmarkformat.cpp @@ -0,0 +1,26 @@ +/* + * 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/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#include "bookmarkformat.h" +#include "formats/xbel.h" +#include + +template<> +void BookmarkFormat::read(BookmarkItem *root) const +{ + Q_CHECK_PTR(m_device); + Xbel::read(m_device, root); +} + +template<> +void BookmarkFormat::write(BookmarkItem *root) +{ + Q_CHECK_PTR(m_device); + Xbel::write(m_device, root); +} + diff --git a/lib/bookmarks/bookmarkformat.h b/lib/bookmarks/bookmarkformat.h new file mode 100644 index 0000000..673acbd --- /dev/null +++ b/lib/bookmarks/bookmarkformat.h @@ -0,0 +1,67 @@ +/* + * 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/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#ifndef BOOKMARKFORMAT_H +#define BOOKMARKFORMAT_H + +#include "bookmarkmodel.h" + +class QIODevice; + +enum BookmarkFormats { + XbelFormat +}; + +template +class BookmarkFormat +{ +public: + explicit BookmarkFormat(QIODevice *device) + { + m_device = device; + } + ~BookmarkFormat() + { + m_device->close(); + } + + void read(BookmarkItem *root) const; + void write(BookmarkItem *root); + +protected: + QIODevice *m_device; +}; + +template +void operator<<(BookmarkModel *model, const BookmarkFormat &format) +{ + format.read(model->root()); +} + +template +void operator>>(const BookmarkFormat &format, BookmarkModel *model) +{ + format.read(model->root()); +} + +template +void operator<<(BookmarkFormat &format, BookmarkModel *model) +{ + format.write(model->root()); + model->resetModified(); +} + +template +void operator>>(BookmarkModel *model, BookmarkFormat &format) +{ + format.write(model->root()); + model->resetModified(); +} + +#endif // BOOKMARKSFORMAT_H + diff --git a/lib/bookmarks/bookmarkitem.cpp b/lib/bookmarks/bookmarkitem.cpp new file mode 100644 index 0000000..21d034f --- /dev/null +++ b/lib/bookmarks/bookmarkitem.cpp @@ -0,0 +1,139 @@ +/* + * 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/gitea/aqua/smolbote + * + * 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_type == Root) { + m_children.append(childItem); + return true; + } + + return false; +} + +bool BookmarkItem::insertChild(int position, BookmarkItem *childItem) +{ + // position is invalid (-1) when dropping an item onto the folder, which leads to crash + // make sure that position passed is >= 0 (insert item at first position) + + if(m_type == Folder || m_type == Root) { + m_children.insert(qMax(position, 0), 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) const +{ + return m_children.value(index); +} + +int BookmarkItem::childCount() const +{ + return m_children.count(); +} + +QVariant BookmarkItem::data(Fields 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..8c9463f --- /dev/null +++ b/lib/bookmarks/bookmarkitem.h @@ -0,0 +1,69 @@ +/* + * 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/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#ifndef SMOLBOTE_BOOKMARKITEM_H +#define SMOLBOTE_BOOKMARKITEM_H + +#include +#include +#include + +class BookmarkItem +{ +public: + enum Type { + Root, + 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) const; + int childCount() const; + + QVariant data(Fields 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..895b178 --- /dev/null +++ b/lib/bookmarks/bookmarkmodel.cpp @@ -0,0 +1,356 @@ +/* + * 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/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#include "bookmarkmodel.h" +#include "bookmarkitem.h" +#include "formats/xbel.h" +#include +#include +#include + +BookmarkModel::BookmarkModel(QObject *parent) + : QAbstractItemModel(parent) +{ + rootItem = new BookmarkItem({ tr("Title"), tr("Address") }, BookmarkItem::Root, 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(static_cast(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 static_cast(index.internalPointer())->data(static_cast(index.column())); + + else + return QVariant(); +} + +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(static_cast(column)); + + return QVariant(); +} + +bool BookmarkModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if(!index.isValid()) + return false; + + bool success = false; + + if(role == Qt::DisplayRole) { + success = static_cast(index.internalPointer())->setData(static_cast(index.column()), value); + } + + if(success) { + emit dataChanged(index, index, { role }); + m_isModified = true; + } + 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 }); + m_isModified = true; + } + 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 | Qt::ItemNeverHasChildren; +} + +bool BookmarkModel::isItemExpanded(const QModelIndex &index) const +{ + if(!index.isValid()) + return false; + + return static_cast(index.internalPointer())->isExpanded(); +} + +void BookmarkModel::setItemExpanded(const QModelIndex &index, bool expanded) +{ + BookmarkItem *item = getItem(index); + if(item->type() == BookmarkItem::Folder) { + item->setExpanded(expanded); + m_isModified = true; + } +} + +int BookmarkModel::rowCount(const QModelIndex &index) const +{ + if(index.column() > 0) + return 0; + + return getItem(index)->childCount(); +} + +QModelIndex BookmarkModel::appendBookmark(const QString &title, const QString &url, const QModelIndex &parent) +{ + auto *parentItem = getItem(parent); + + int row = parentItem->childCount(); + beginInsertRows(parent, row, row); + auto *childItem = new BookmarkItem({ title, url }, BookmarkItem::Bookmark, parentItem); + parentItem->appendChild(childItem); + endInsertRows(); + + m_isModified = true; + return createIndex(row, 0, childItem); +} + +QModelIndex BookmarkModel::appendFolder(const QString &title, const QModelIndex &parent) +{ + auto *parentItem = getItem(parent); + const int row = parentItem->childCount(); + + beginInsertRows(parent, row, row); + auto *childItem = new BookmarkItem({ title }, BookmarkItem::Folder, parentItem); + parentItem->appendChild(childItem); + endInsertRows(); + + m_isModified = true; + return createIndex(row, 0, childItem); +} + +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(); + + if(success) + m_isModified = true; + return success; +} + +int BookmarkModel::columnCount(const QModelIndex &index) const +{ + Q_UNUSED(index); + return 2; +} + +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); +} + +QModelIndex BookmarkModel::parentFolder(const QModelIndex &index) const +{ + // invalid index is the root index -> return it back + if(!index.isValid()) + return QModelIndex(); + + if(getItem(index)->type() == BookmarkItem::Bookmark) { + return index.parent(); + } + + return index; +} + +inline bool has(const QStringList &terms, const QStringList &where) +{ + for(const QString &term : terms) { + if(where.contains(term)) + return true; + } + return false; +} + +inline QStringList searchThrough(const QString &term, const QStringList &tags, BookmarkItem *item) +{ + QStringList results; + + for(int i = 0; i < item->childCount(); ++i) { + auto *child = item->child(i); + + if(child->type() == BookmarkItem::Bookmark) { + if((!term.isEmpty() && child->data(BookmarkItem::Href).toString().contains(term)) || has(tags, child->data(BookmarkItem::Tags).toStringList())) + results.append(child->data(BookmarkItem::Href).toString()); + } + + else if(child->type() == BookmarkItem::Folder) { + if(has(tags, child->data(BookmarkItem::Tags).toStringList())) { + + // append all bookmarks + for(int i = 0; i < child->childCount(); ++i) { + auto *subChild = child->child(i); + if(subChild->type() == BookmarkItem::Bookmark) + results.append(subChild->data(BookmarkItem::Href).toString()); + } + } + results.append(searchThrough(term, tags, child)); + } + } + return results; +} + +QStringList BookmarkModel::search(const QString &term) const +{ + QString searchTerm = term; + QStringList tags; + + const QRegularExpression tagRE(":\\w+\\s?", QRegularExpression::CaseInsensitiveOption); + auto i = tagRE.globalMatch(term); + while(i.hasNext()) { + auto match = i.next(); + QString tag = match.captured(); + searchTerm.remove(tag); + tag = tag.remove(0, 1).trimmed(); + tags.append(tag); + } + + return searchThrough(searchTerm, tags, rootItem); +} + +BookmarkItem *BookmarkModel::getItem(const QModelIndex &index) const +{ + if(!index.isValid()) + return rootItem; + else + return static_cast(index.internalPointer()); +} + +/* + * Drag'n'Drop implementation + * How drag and drop actually works: the view encodes the data of the original + * item (through ::mimeData), and then uses ::dropMimeData to create the new + * item. If successful, the old item is removed (through ::removeRows). + * This means that the encoding and decoding needs to be provided. In this case, + * this is done through xbel. + */ + +Qt::DropActions BookmarkModel::supportedDropActions() const +{ + return Qt::MoveAction; +} + +QStringList BookmarkModel::mimeTypes() const +{ + return { mimeType }; +} + +QMimeData *BookmarkModel::mimeData(const QModelIndexList &indexes) const +{ + auto *mimeData = new QMimeData(); + QByteArray data; + + QDataStream stream(&data, QIODevice::WriteOnly); + for(const QModelIndex &index : indexes) { + if(index.isValid() && index.column() == 0) { + QByteArray encodedData; + QBuffer buffer(&encodedData); + buffer.open(QIODevice::WriteOnly); + + Xbel::write(&buffer, getItem(index)); + + stream << encodedData; + } + } + mimeData->setData(mimeType, data); + return mimeData; +} +bool BookmarkModel::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) +{ + if(action == Qt::IgnoreAction) + return true; + + if(action != Qt::MoveAction) + return false; + + if(!mimeData->hasFormat(mimeType) || column > 0) + return false; + + QByteArray data = mimeData->data(mimeType); + QDataStream stream(&data, QIODevice::ReadOnly); + if(stream.atEnd()) + return false; + + while(!stream.atEnd()) { + QByteArray encodedData; + stream >> encodedData; + + QBuffer buffer(&encodedData); + buffer.open(QIODevice::ReadOnly); + + auto *fakeRoot = new BookmarkItem({}, BookmarkItem::Folder, nullptr); + auto *parentItem = getItem(parent); + Xbel::read(&buffer, fakeRoot); + + beginInsertRows(parent, row, row + fakeRoot->childCount() - 1); + for(int i = 0; i < fakeRoot->childCount(); ++i) { + auto *child = fakeRoot->takeChild(0, parentItem); + parentItem->insertChild(row, child); + } + endInsertRows(); + + delete fakeRoot; + } + + m_isModified = true; + return true; +} diff --git a/lib/bookmarks/bookmarkmodel.h b/lib/bookmarks/bookmarkmodel.h new file mode 100644 index 0000000..300b724 --- /dev/null +++ b/lib/bookmarks/bookmarkmodel.h @@ -0,0 +1,73 @@ +/* + * 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/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#ifndef SMOLBOTE_BOOKMARKMODEL_H +#define SMOLBOTE_BOOKMARKMODEL_H + +#include "bookmarkitem.h" +#include + +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; + void setItemExpanded(const QModelIndex &index, bool expanded); + + int rowCount(const QModelIndex &index) const override; + QModelIndex appendBookmark(const QString &title, const QString &url, const QModelIndex &parent); + QModelIndex appendFolder(const QString &title, const QModelIndex &parent); + bool removeRows(int position, int rows, const QModelIndex &parent) override; + int columnCount(const QModelIndex &index) const override; + + Qt::DropActions supportedDropActions() const override; + QStringList mimeTypes() const override; + QMimeData *mimeData(const QModelIndexList &indexes) const override; + bool dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; + + QModelIndex index(int row, int column, const QModelIndex &parent) const override; + QModelIndex parent(const QModelIndex &index) const override; + QModelIndex parentFolder(const QModelIndex &index) const; + + BookmarkItem *root() + { + return rootItem; + } + + QStringList search(const QString &term) const; + + void resetModified() + { + m_isModified = false; + } + bool isModified() const + { + return m_isModified; + } + +private: + const QLatin1String mimeType = QLatin1String("application/xbel"); + + BookmarkItem *getItem(const QModelIndex &index) const; + BookmarkItem *rootItem; + + bool m_isModified = false; +}; + +#endif // SMOLBOTE_BOOKMARKMODEL_H diff --git a/lib/bookmarks/bookmarkswidget.cpp b/lib/bookmarks/bookmarkswidget.cpp index aed7e97..29e388c 100644 --- a/lib/bookmarks/bookmarkswidget.cpp +++ b/lib/bookmarks/bookmarkswidget.cpp @@ -8,10 +8,8 @@ #include "bookmarkswidget.h" #include "forms/editbookmarkdialog.h" -#include "model/bookmarkitem.h" -#include "model/bookmarkmodel.h" #include "ui_bookmarksform.h" -#include "formats/format.h" +#include "bookmarkformat.h" #include #include @@ -48,9 +46,7 @@ BookmarksWidget::BookmarksWidget(const QString &path, QWidget *parent) m_bookmarksPath = path; QFile bookmarksFile(m_bookmarksPath); if(bookmarksFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - BookmarksFormat format(&bookmarksFile); - format.read(model->root()); - bookmarksFile.close(); + BookmarkFormat(&bookmarksFile) >> model; } model->resetModified(); @@ -124,11 +120,9 @@ void BookmarksWidget::save() QFile bookmarksFile(m_bookmarksPath); if(bookmarksFile.open(QIODevice::WriteOnly | QIODevice::Text)) { - BookmarksFormat format(&bookmarksFile); - format.write(model->root()); + BookmarkFormat f(&bookmarksFile); + model >> f; bookmarksFile.flush(); - bookmarksFile.close(); - model->resetModified(); } } diff --git a/lib/bookmarks/formats/format.cpp b/lib/bookmarks/formats/format.cpp deleted file mode 100644 index 551151c..0000000 --- a/lib/bookmarks/formats/format.cpp +++ /dev/null @@ -1,26 +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/gitea/aqua/smolbote - * - * SPDX-License-Identifier: GPL-3.0 - */ - -#include "format.h" -#include "xbel.h" -#include - -template<> -void BookmarksFormat::read(BookmarkItem *root) -{ - Q_CHECK_PTR(m_device); - Xbel::read(m_device, root); -} - -template<> -void BookmarksFormat::write(BookmarkItem *root) -{ - Q_CHECK_PTR(m_device); - Xbel::write(m_device, root); -} - diff --git a/lib/bookmarks/formats/format.h b/lib/bookmarks/formats/format.h deleted file mode 100644 index e96dfcc..0000000 --- a/lib/bookmarks/formats/format.h +++ /dev/null @@ -1,36 +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/gitea/aqua/smolbote - * - * SPDX-License-Identifier: GPL-3.0 - */ - -#ifndef BOOKMARKSFORMAT_H -#define BOOKMARKSFORMAT_H - -class QIODevice; -class BookmarkItem; - -enum BookmarksFormats { - XbelFormat -}; - -template -class BookmarksFormat -{ -public: - explicit BookmarksFormat(QIODevice *device) - { - m_device = device; - } - - void read(BookmarkItem *root); - void write(BookmarkItem *root); - -protected: - QIODevice *m_device; -}; - -#endif // BOOKMARKSFORMAT_H - diff --git a/lib/bookmarks/formats/xbel.cpp b/lib/bookmarks/formats/xbel.cpp index 1cb5756..174995d 100644 --- a/lib/bookmarks/formats/xbel.cpp +++ b/lib/bookmarks/formats/xbel.cpp @@ -7,7 +7,7 @@ */ #include "xbel.h" -#include "model/bookmarkitem.h" +#include "bookmarkitem.h" #include #include diff --git a/lib/bookmarks/forms/editbookmarkdialog.cpp b/lib/bookmarks/forms/editbookmarkdialog.cpp index 9c6efa0..7df90b8 100644 --- a/lib/bookmarks/forms/editbookmarkdialog.cpp +++ b/lib/bookmarks/forms/editbookmarkdialog.cpp @@ -7,8 +7,8 @@ */ #include "editbookmarkdialog.h" -#include "model/bookmarkitem.h" -#include "model/bookmarkmodel.h" +#include "bookmarkitem.h" +#include "bookmarkmodel.h" #include "ui_editbookmarkdialog.h" EditBookmarkDialog::EditBookmarkDialog(BookmarkModel *model, const QModelIndex &index, QWidget *parent) diff --git a/lib/bookmarks/meson.build b/lib/bookmarks/meson.build index 3049e3c..78d0510 100644 --- a/lib/bookmarks/meson.build +++ b/lib/bookmarks/meson.build @@ -1,14 +1,14 @@ bookmarks_inc = include_directories('.') bookmarks_moc = mod_qt5.preprocess( - moc_headers: ['bookmarkswidget.h', 'model/bookmarkmodel.h', 'forms/editbookmarkdialog.h'], + moc_headers: ['bookmarkswidget.h', 'bookmarkmodel.h', 'forms/editbookmarkdialog.h'], ui_files: ['bookmarksform.ui', 'forms/editbookmarkdialog.ui'], dependencies: dep_qt5 ) bookmarks_lib = static_library('bookmarks', ['bookmarkswidget.cpp', bookmarks_moc, - 'formats/format.cpp', 'formats/xbel.cpp', - 'model/bookmarkitem.cpp', 'model/bookmarkmodel.cpp', + 'bookmarksloader.cpp', 'formats/xbel.cpp', + 'bookmarkitem.cpp', 'bookmarkmodel.cpp', 'forms/editbookmarkdialog.cpp'], dependencies: dep_qt5 ) diff --git a/lib/bookmarks/model/bookmarkitem.cpp b/lib/bookmarks/model/bookmarkitem.cpp deleted file mode 100644 index 21d034f..0000000 --- a/lib/bookmarks/model/bookmarkitem.cpp +++ /dev/null @@ -1,139 +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/gitea/aqua/smolbote - * - * 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_type == Root) { - m_children.append(childItem); - return true; - } - - return false; -} - -bool BookmarkItem::insertChild(int position, BookmarkItem *childItem) -{ - // position is invalid (-1) when dropping an item onto the folder, which leads to crash - // make sure that position passed is >= 0 (insert item at first position) - - if(m_type == Folder || m_type == Root) { - m_children.insert(qMax(position, 0), 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) const -{ - return m_children.value(index); -} - -int BookmarkItem::childCount() const -{ - return m_children.count(); -} - -QVariant BookmarkItem::data(Fields 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/model/bookmarkitem.h b/lib/bookmarks/model/bookmarkitem.h deleted file mode 100644 index 8c9463f..0000000 --- a/lib/bookmarks/model/bookmarkitem.h +++ /dev/null @@ -1,69 +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/gitea/aqua/smolbote - * - * SPDX-License-Identifier: GPL-3.0 - */ - -#ifndef SMOLBOTE_BOOKMARKITEM_H -#define SMOLBOTE_BOOKMARKITEM_H - -#include -#include -#include - -class BookmarkItem -{ -public: - enum Type { - Root, - 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) const; - int childCount() const; - - QVariant data(Fields 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/model/bookmarkmodel.cpp b/lib/bookmarks/model/bookmarkmodel.cpp deleted file mode 100644 index 895b178..0000000 --- a/lib/bookmarks/model/bookmarkmodel.cpp +++ /dev/null @@ -1,356 +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/gitea/aqua/smolbote - * - * SPDX-License-Identifier: GPL-3.0 - */ - -#include "bookmarkmodel.h" -#include "bookmarkitem.h" -#include "formats/xbel.h" -#include -#include -#include - -BookmarkModel::BookmarkModel(QObject *parent) - : QAbstractItemModel(parent) -{ - rootItem = new BookmarkItem({ tr("Title"), tr("Address") }, BookmarkItem::Root, 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(static_cast(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 static_cast(index.internalPointer())->data(static_cast(index.column())); - - else - return QVariant(); -} - -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(static_cast(column)); - - return QVariant(); -} - -bool BookmarkModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if(!index.isValid()) - return false; - - bool success = false; - - if(role == Qt::DisplayRole) { - success = static_cast(index.internalPointer())->setData(static_cast(index.column()), value); - } - - if(success) { - emit dataChanged(index, index, { role }); - m_isModified = true; - } - 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 }); - m_isModified = true; - } - 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 | Qt::ItemNeverHasChildren; -} - -bool BookmarkModel::isItemExpanded(const QModelIndex &index) const -{ - if(!index.isValid()) - return false; - - return static_cast(index.internalPointer())->isExpanded(); -} - -void BookmarkModel::setItemExpanded(const QModelIndex &index, bool expanded) -{ - BookmarkItem *item = getItem(index); - if(item->type() == BookmarkItem::Folder) { - item->setExpanded(expanded); - m_isModified = true; - } -} - -int BookmarkModel::rowCount(const QModelIndex &index) const -{ - if(index.column() > 0) - return 0; - - return getItem(index)->childCount(); -} - -QModelIndex BookmarkModel::appendBookmark(const QString &title, const QString &url, const QModelIndex &parent) -{ - auto *parentItem = getItem(parent); - - int row = parentItem->childCount(); - beginInsertRows(parent, row, row); - auto *childItem = new BookmarkItem({ title, url }, BookmarkItem::Bookmark, parentItem); - parentItem->appendChild(childItem); - endInsertRows(); - - m_isModified = true; - return createIndex(row, 0, childItem); -} - -QModelIndex BookmarkModel::appendFolder(const QString &title, const QModelIndex &parent) -{ - auto *parentItem = getItem(parent); - const int row = parentItem->childCount(); - - beginInsertRows(parent, row, row); - auto *childItem = new BookmarkItem({ title }, BookmarkItem::Folder, parentItem); - parentItem->appendChild(childItem); - endInsertRows(); - - m_isModified = true; - return createIndex(row, 0, childItem); -} - -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(); - - if(success) - m_isModified = true; - return success; -} - -int BookmarkModel::columnCount(const QModelIndex &index) const -{ - Q_UNUSED(index); - return 2; -} - -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); -} - -QModelIndex BookmarkModel::parentFolder(const QModelIndex &index) const -{ - // invalid index is the root index -> return it back - if(!index.isValid()) - return QModelIndex(); - - if(getItem(index)->type() == BookmarkItem::Bookmark) { - return index.parent(); - } - - return index; -} - -inline bool has(const QStringList &terms, const QStringList &where) -{ - for(const QString &term : terms) { - if(where.contains(term)) - return true; - } - return false; -} - -inline QStringList searchThrough(const QString &term, const QStringList &tags, BookmarkItem *item) -{ - QStringList results; - - for(int i = 0; i < item->childCount(); ++i) { - auto *child = item->child(i); - - if(child->type() == BookmarkItem::Bookmark) { - if((!term.isEmpty() && child->data(BookmarkItem::Href).toString().contains(term)) || has(tags, child->data(BookmarkItem::Tags).toStringList())) - results.append(child->data(BookmarkItem::Href).toString()); - } - - else if(child->type() == BookmarkItem::Folder) { - if(has(tags, child->data(BookmarkItem::Tags).toStringList())) { - - // append all bookmarks - for(int i = 0; i < child->childCount(); ++i) { - auto *subChild = child->child(i); - if(subChild->type() == BookmarkItem::Bookmark) - results.append(subChild->data(BookmarkItem::Href).toString()); - } - } - results.append(searchThrough(term, tags, child)); - } - } - return results; -} - -QStringList BookmarkModel::search(const QString &term) const -{ - QString searchTerm = term; - QStringList tags; - - const QRegularExpression tagRE(":\\w+\\s?", QRegularExpression::CaseInsensitiveOption); - auto i = tagRE.globalMatch(term); - while(i.hasNext()) { - auto match = i.next(); - QString tag = match.captured(); - searchTerm.remove(tag); - tag = tag.remove(0, 1).trimmed(); - tags.append(tag); - } - - return searchThrough(searchTerm, tags, rootItem); -} - -BookmarkItem *BookmarkModel::getItem(const QModelIndex &index) const -{ - if(!index.isValid()) - return rootItem; - else - return static_cast(index.internalPointer()); -} - -/* - * Drag'n'Drop implementation - * How drag and drop actually works: the view encodes the data of the original - * item (through ::mimeData), and then uses ::dropMimeData to create the new - * item. If successful, the old item is removed (through ::removeRows). - * This means that the encoding and decoding needs to be provided. In this case, - * this is done through xbel. - */ - -Qt::DropActions BookmarkModel::supportedDropActions() const -{ - return Qt::MoveAction; -} - -QStringList BookmarkModel::mimeTypes() const -{ - return { mimeType }; -} - -QMimeData *BookmarkModel::mimeData(const QModelIndexList &indexes) const -{ - auto *mimeData = new QMimeData(); - QByteArray data; - - QDataStream stream(&data, QIODevice::WriteOnly); - for(const QModelIndex &index : indexes) { - if(index.isValid() && index.column() == 0) { - QByteArray encodedData; - QBuffer buffer(&encodedData); - buffer.open(QIODevice::WriteOnly); - - Xbel::write(&buffer, getItem(index)); - - stream << encodedData; - } - } - mimeData->setData(mimeType, data); - return mimeData; -} -bool BookmarkModel::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) -{ - if(action == Qt::IgnoreAction) - return true; - - if(action != Qt::MoveAction) - return false; - - if(!mimeData->hasFormat(mimeType) || column > 0) - return false; - - QByteArray data = mimeData->data(mimeType); - QDataStream stream(&data, QIODevice::ReadOnly); - if(stream.atEnd()) - return false; - - while(!stream.atEnd()) { - QByteArray encodedData; - stream >> encodedData; - - QBuffer buffer(&encodedData); - buffer.open(QIODevice::ReadOnly); - - auto *fakeRoot = new BookmarkItem({}, BookmarkItem::Folder, nullptr); - auto *parentItem = getItem(parent); - Xbel::read(&buffer, fakeRoot); - - beginInsertRows(parent, row, row + fakeRoot->childCount() - 1); - for(int i = 0; i < fakeRoot->childCount(); ++i) { - auto *child = fakeRoot->takeChild(0, parentItem); - parentItem->insertChild(row, child); - } - endInsertRows(); - - delete fakeRoot; - } - - m_isModified = true; - return true; -} diff --git a/lib/bookmarks/model/bookmarkmodel.h b/lib/bookmarks/model/bookmarkmodel.h deleted file mode 100644 index 300b724..0000000 --- a/lib/bookmarks/model/bookmarkmodel.h +++ /dev/null @@ -1,73 +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/gitea/aqua/smolbote - * - * SPDX-License-Identifier: GPL-3.0 - */ - -#ifndef SMOLBOTE_BOOKMARKMODEL_H -#define SMOLBOTE_BOOKMARKMODEL_H - -#include "bookmarkitem.h" -#include - -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; - void setItemExpanded(const QModelIndex &index, bool expanded); - - int rowCount(const QModelIndex &index) const override; - QModelIndex appendBookmark(const QString &title, const QString &url, const QModelIndex &parent); - QModelIndex appendFolder(const QString &title, const QModelIndex &parent); - bool removeRows(int position, int rows, const QModelIndex &parent) override; - int columnCount(const QModelIndex &index) const override; - - Qt::DropActions supportedDropActions() const override; - QStringList mimeTypes() const override; - QMimeData *mimeData(const QModelIndexList &indexes) const override; - bool dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) override; - - QModelIndex index(int row, int column, const QModelIndex &parent) const override; - QModelIndex parent(const QModelIndex &index) const override; - QModelIndex parentFolder(const QModelIndex &index) const; - - BookmarkItem *root() - { - return rootItem; - } - - QStringList search(const QString &term) const; - - void resetModified() - { - m_isModified = false; - } - bool isModified() const - { - return m_isModified; - } - -private: - const QLatin1String mimeType = QLatin1String("application/xbel"); - - BookmarkItem *getItem(const QModelIndex &index) const; - BookmarkItem *rootItem; - - bool m_isModified = false; -}; - -#endif // SMOLBOTE_BOOKMARKMODEL_H -- cgit v1.2.1 From 9643e146c35a3a3e9abf0bf332c7c1efd00be9c2 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Wed, 15 Jan 2020 13:19:46 +0200 Subject: Move BookmarksWidget out of libbookmarks --- lib/bookmarks/bookmarksform.ui | 129 --------------------------- lib/bookmarks/bookmarkswidget.cpp | 138 ----------------------------- lib/bookmarks/bookmarkswidget.h | 50 ----------- lib/bookmarks/forms/editbookmarkdialog.cpp | 70 --------------- lib/bookmarks/forms/editbookmarkdialog.h | 44 --------- lib/bookmarks/forms/editbookmarkdialog.ui | 108 ---------------------- lib/bookmarks/meson.build | 13 ++- src/bookmarks/bookmarksform.ui | 129 +++++++++++++++++++++++++++ src/bookmarks/bookmarkswidget.cpp | 138 +++++++++++++++++++++++++++++ src/bookmarks/bookmarkswidget.h | 50 +++++++++++ src/bookmarks/editbookmarkdialog.cpp | 70 +++++++++++++++ src/bookmarks/editbookmarkdialog.h | 44 +++++++++ src/bookmarks/editbookmarkdialog.ui | 108 ++++++++++++++++++++++ src/browser.cpp | 2 +- src/mainwindow/menubar.cpp | 2 +- src/meson.build | 8 +- 16 files changed, 553 insertions(+), 550 deletions(-) delete mode 100644 lib/bookmarks/bookmarksform.ui delete mode 100644 lib/bookmarks/bookmarkswidget.cpp delete mode 100644 lib/bookmarks/bookmarkswidget.h delete mode 100644 lib/bookmarks/forms/editbookmarkdialog.cpp delete mode 100644 lib/bookmarks/forms/editbookmarkdialog.h delete mode 100644 lib/bookmarks/forms/editbookmarkdialog.ui create mode 100644 src/bookmarks/bookmarksform.ui create mode 100644 src/bookmarks/bookmarkswidget.cpp create mode 100644 src/bookmarks/bookmarkswidget.h create mode 100644 src/bookmarks/editbookmarkdialog.cpp create mode 100644 src/bookmarks/editbookmarkdialog.h create mode 100644 src/bookmarks/editbookmarkdialog.ui diff --git a/lib/bookmarks/bookmarksform.ui b/lib/bookmarks/bookmarksform.ui deleted file mode 100644 index a003e53..0000000 --- a/lib/bookmarks/bookmarksform.ui +++ /dev/null @@ -1,129 +0,0 @@ - - - BookmarksDialog - - - - 0 - 0 - 420 - 600 - - - - Bookmarks - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Add Folder - - - - - - - Add Bookmark - - - - - - - Delete Item - - - - - - - - - QAbstractItemView::NoEditTriggers - - - true - - - QAbstractItemView::DragDrop - - - Qt::MoveAction - - - 200 - - - 50 - - - - - - - Edit Bookmark - - - - - - Title - - - - - - - Address - - - - - - - - - - - - - - - - Edit Folder - - - - - - Name - - - - - - - - - - - - - - diff --git a/lib/bookmarks/bookmarkswidget.cpp b/lib/bookmarks/bookmarkswidget.cpp deleted file mode 100644 index 29e388c..0000000 --- a/lib/bookmarks/bookmarkswidget.cpp +++ /dev/null @@ -1,138 +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/gitea/aqua/smolbote - * - * SPDX-License-Identifier: GPL-3.0 - */ - -#include "bookmarkswidget.h" -#include "forms/editbookmarkdialog.h" -#include "ui_bookmarksform.h" -#include "bookmarkformat.h" -#include -#include - -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); - } -} - -BookmarksWidget::BookmarksWidget(const QString &path, QWidget *parent) - : QWidget(parent) - , ui(new Ui::BookmarksDialog) -{ - // make sure this dialog does not get deleted on close - setAttribute(Qt::WA_DeleteOnClose, false); - - ui->setupUi(this); - ui->bookmark_groupBox->setVisible(false); - ui->folder_groupBox->setVisible(false); - - ui->addFolder_toolButton->setIcon(style()->standardPixmap(QStyle::SP_DirIcon)); - ui->addBookmark_toolButton->setIcon(style()->standardPixmap(QStyle::SP_FileIcon)); - ui->deleteItem_toolButton->setIcon(style()->standardPixmap(QStyle::SP_TrashIcon)); - ui->deleteItem_toolButton->setShortcut(QKeySequence::Delete); - - model = new BookmarkModel(this); - m_bookmarksPath = path; - QFile bookmarksFile(m_bookmarksPath); - if(bookmarksFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - BookmarkFormat(&bookmarksFile) >> model; - } - model->resetModified(); - - ui->treeView->setModel(model); - expandChildren(ui->treeView, model, QModelIndex()); - - // item activated - connect(ui->treeView, &QTreeView::activated, this, [this](const QModelIndex &index) { - if(index.column() == 1) - emit openUrl(index.data(Qt::DisplayRole).toUrl()); - else - editBookmark(index); - }); - - connect(ui->treeView, &QTreeView::expanded, this, [this](const QModelIndex &index) { - model->setItemExpanded(index, true); - }); - connect(ui->treeView, &QTreeView::collapsed, this, [this](const QModelIndex &index) { - model->setItemExpanded(index, false); - }); - - ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu); - connect(ui->treeView, &QTreeView::customContextMenuRequested, this, [this](const QPoint &pos) { - const QModelIndex idx = ui->treeView->indexAt(pos); - if(idx.isValid()) { - const QUrl url = model->data(idx, 1, Qt::DisplayRole).toUrl(); - const QPoint _pos = ui->treeView->viewport()->mapToGlobal(pos); - - emit showContextMenu(url, _pos); - } - }); - - // addBookmark - connect(ui->addBookmark_toolButton, &QToolButton::clicked, this, [this]() { - const QModelIndex idx = model->parentFolder(ui->treeView->currentIndex()); - const QModelIndex childIdx = model->appendBookmark(tr("Title"), QString(), idx); - ui->treeView->setCurrentIndex(childIdx); - editBookmark(childIdx); - }); - - // addFolder - connect(ui->addFolder_toolButton, &QToolButton::clicked, this, [this]() { - const QModelIndex idx = model->parentFolder(ui->treeView->currentIndex()); - const QModelIndex childIdx = model->appendFolder(tr("Title"), idx); - ui->treeView->setCurrentIndex(childIdx); - editBookmark(childIdx); - }); - - // deleteItem - connect(ui->deleteItem_toolButton, &QToolButton::clicked, this, [this]() { - const QModelIndex idx = ui->treeView->currentIndex(); - model->removeRow(idx.row(), idx.parent()); - }); -} - -BookmarksWidget::~BookmarksWidget() -{ - delete ui; -} - -void BookmarksWidget::editBookmark(const QModelIndex &index) -{ - auto *dlg = new EditBookmarkDialog(model, index, this); - dlg->exec(); -} - -void BookmarksWidget::save() -{ - if(!model->isModified()) - return; - - QFile bookmarksFile(m_bookmarksPath); - if(bookmarksFile.open(QIODevice::WriteOnly | QIODevice::Text)) { - BookmarkFormat f(&bookmarksFile); - model >> f; - bookmarksFile.flush(); - } -} - -void BookmarksWidget::addBookmark(const QString &title, const QString &url) -{ - model->appendBookmark(title, url, QModelIndex()); -} - -void BookmarksWidget::search(const QString &term, const std::function &callback) const -{ - QStringList ret = model->search(term); - callback(ret); -} diff --git a/lib/bookmarks/bookmarkswidget.h b/lib/bookmarks/bookmarkswidget.h deleted file mode 100644 index 149d2a6..0000000 --- a/lib/bookmarks/bookmarkswidget.h +++ /dev/null @@ -1,50 +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/gitea/aqua/smolbote - * - * SPDX-License-Identifier: GPL-3.0 - */ - -#ifndef BOOKMARKSDIALOG_H -#define BOOKMARKSDIALOG_H - -#include -#include -#include -#include - -namespace Ui -{ -class BookmarksDialog; -} - -class BookmarksView; -class BookmarkModel; -class BookmarksWidget : public QWidget -{ - Q_OBJECT - -public: - explicit BookmarksWidget(const QString &path, QWidget *parent = nullptr); - ~BookmarksWidget() override; - -protected: - void editBookmark(const QModelIndex &index); - -signals: - void showContextMenu(const QUrl &url, const QPoint &pos); - void openUrl(const QUrl &url); - -public slots: - void save(); - void addBookmark(const QString &title, const QString &url); - void search(const QString &term, const std::function &callback) const; - -private: - Ui::BookmarksDialog *ui; - QString m_bookmarksPath; - BookmarkModel *model; -}; - -#endif // BOOKMARKSDIALOG_H diff --git a/lib/bookmarks/forms/editbookmarkdialog.cpp b/lib/bookmarks/forms/editbookmarkdialog.cpp deleted file mode 100644 index 7df90b8..0000000 --- a/lib/bookmarks/forms/editbookmarkdialog.cpp +++ /dev/null @@ -1,70 +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/gitea/aqua/smolbote - * - * 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); - - Q_CHECK_PTR(model); - m_model = model; - m_index = index; - - ui->title->setText(model->data(index, BookmarkItem::Title, Qt::DisplayRole).toString()); - connect(ui->title, &QLineEdit::editingFinished, this, [this]() { - titleChanged = true; - }); - - ui->address->setText(model->data(index, BookmarkItem::Href, Qt::DisplayRole).toString()); - connect(ui->address, &QLineEdit::editingFinished, this, [this]() { - hrefChanged = true; - }); - - ui->tags->setText(model->data(index, BookmarkItem::Tags, Qt::DisplayRole).toStringList().join(", ")); - connect(ui->tags, &QLineEdit::editingFinished, this, [this]() { - tagsChanged = true; - }); - - ui->description->setPlainText(model->data(index, BookmarkItem::Description, Qt::DisplayRole).toString()); - connect(ui->description, &QPlainTextEdit::textChanged, this, [this]() { - descriptionChanged = true; - }); - - connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &EditBookmarkDialog::saveChanges); -} - -EditBookmarkDialog::~EditBookmarkDialog() -{ - delete ui; -} - -void EditBookmarkDialog::saveChanges() -{ - if(titleChanged) { - m_model->setData(m_index, ui->title->text(), BookmarkItem::Title, Qt::DisplayRole); - } - - if(hrefChanged) { - m_model->setData(m_index, ui->address->text(), BookmarkItem::Href, Qt::DisplayRole); - } - - if(tagsChanged) { - m_model->setData(m_index, ui->tags->text().split(", "), BookmarkItem::Tags, Qt::DisplayRole); - } - - if(descriptionChanged) { - m_model->setData(m_index, ui->description->toPlainText(), BookmarkItem::Description, Qt::DisplayRole); - } -} diff --git a/lib/bookmarks/forms/editbookmarkdialog.h b/lib/bookmarks/forms/editbookmarkdialog.h deleted file mode 100644 index fb53239..0000000 --- a/lib/bookmarks/forms/editbookmarkdialog.h +++ /dev/null @@ -1,44 +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/gitea/aqua/smolbote - * - * SPDX-License-Identifier: GPL-3.0 - */ - -#ifndef SMOLBOTE_EDITBOOKMARKDIALOG_H -#define SMOLBOTE_EDITBOOKMARKDIALOG_H - -#include -#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; - -public slots: - void saveChanges(); - -private: - Ui::EditBookmarkDialog *ui; - - BookmarkModel *m_model; - QModelIndex m_index; - - bool titleChanged = false; - bool hrefChanged = false; - bool tagsChanged = false; - bool descriptionChanged = false; -}; - -#endif // SMOLBOTE_EDITBOOKMARKDIALOG_H diff --git a/lib/bookmarks/forms/editbookmarkdialog.ui b/lib/bookmarks/forms/editbookmarkdialog.ui deleted file mode 100644 index b988394..0000000 --- a/lib/bookmarks/forms/editbookmarkdialog.ui +++ /dev/null @@ -1,108 +0,0 @@ - - - EditBookmarkDialog - - - - 0 - 0 - 400 - 320 - - - - Edit Bookmark - - - - - - - - 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/meson.build b/lib/bookmarks/meson.build index 78d0510..a7f603b 100644 --- a/lib/bookmarks/meson.build +++ b/lib/bookmarks/meson.build @@ -1,19 +1,16 @@ -bookmarks_inc = include_directories('.') bookmarks_moc = mod_qt5.preprocess( - moc_headers: ['bookmarkswidget.h', 'bookmarkmodel.h', 'forms/editbookmarkdialog.h'], - ui_files: ['bookmarksform.ui', 'forms/editbookmarkdialog.ui'], + moc_headers: [ 'bookmarkmodel.h' ], dependencies: dep_qt5 ) bookmarks_lib = static_library('bookmarks', - ['bookmarkswidget.cpp', bookmarks_moc, - 'bookmarksloader.cpp', 'formats/xbel.cpp', - 'bookmarkitem.cpp', 'bookmarkmodel.cpp', - 'forms/editbookmarkdialog.cpp'], + [ bookmarks_moc, + 'bookmarkformat.cpp', 'formats/xbel.cpp', + 'bookmarkitem.cpp', 'bookmarkmodel.cpp' ], dependencies: dep_qt5 ) dep_bookmarks = declare_dependency( - include_directories: bookmarks_inc, + include_directories: include_directories('.'), link_with: bookmarks_lib ) diff --git a/src/bookmarks/bookmarksform.ui b/src/bookmarks/bookmarksform.ui new file mode 100644 index 0000000..a003e53 --- /dev/null +++ b/src/bookmarks/bookmarksform.ui @@ -0,0 +1,129 @@ + + + BookmarksDialog + + + + 0 + 0 + 420 + 600 + + + + Bookmarks + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Add Folder + + + + + + + Add Bookmark + + + + + + + Delete Item + + + + + + + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::DragDrop + + + Qt::MoveAction + + + 200 + + + 50 + + + + + + + Edit Bookmark + + + + + + Title + + + + + + + Address + + + + + + + + + + + + + + + + Edit Folder + + + + + + Name + + + + + + + + + + + + + + diff --git a/src/bookmarks/bookmarkswidget.cpp b/src/bookmarks/bookmarkswidget.cpp new file mode 100644 index 0000000..26fdddf --- /dev/null +++ b/src/bookmarks/bookmarkswidget.cpp @@ -0,0 +1,138 @@ +/* + * 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/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#include "bookmarkswidget.h" +#include "editbookmarkdialog.h" +#include "ui_bookmarksform.h" +#include "bookmarkformat.h" +#include +#include + +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); + } +} + +BookmarksWidget::BookmarksWidget(const QString &path, QWidget *parent) + : QWidget(parent) + , ui(new Ui::BookmarksDialog) +{ + // make sure this dialog does not get deleted on close + setAttribute(Qt::WA_DeleteOnClose, false); + + ui->setupUi(this); + ui->bookmark_groupBox->setVisible(false); + ui->folder_groupBox->setVisible(false); + + ui->addFolder_toolButton->setIcon(style()->standardPixmap(QStyle::SP_DirIcon)); + ui->addBookmark_toolButton->setIcon(style()->standardPixmap(QStyle::SP_FileIcon)); + ui->deleteItem_toolButton->setIcon(style()->standardPixmap(QStyle::SP_TrashIcon)); + ui->deleteItem_toolButton->setShortcut(QKeySequence::Delete); + + model = new BookmarkModel(this); + m_bookmarksPath = path; + QFile bookmarksFile(m_bookmarksPath); + if(bookmarksFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + BookmarkFormat(&bookmarksFile) >> model; + } + model->resetModified(); + + ui->treeView->setModel(model); + expandChildren(ui->treeView, model, QModelIndex()); + + // item activated + connect(ui->treeView, &QTreeView::activated, this, [this](const QModelIndex &index) { + if(index.column() == 1) + emit openUrl(index.data(Qt::DisplayRole).toUrl()); + else + editBookmark(index); + }); + + connect(ui->treeView, &QTreeView::expanded, this, [this](const QModelIndex &index) { + model->setItemExpanded(index, true); + }); + connect(ui->treeView, &QTreeView::collapsed, this, [this](const QModelIndex &index) { + model->setItemExpanded(index, false); + }); + + ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu); + connect(ui->treeView, &QTreeView::customContextMenuRequested, this, [this](const QPoint &pos) { + const QModelIndex idx = ui->treeView->indexAt(pos); + if(idx.isValid()) { + const QUrl url = model->data(idx, 1, Qt::DisplayRole).toUrl(); + const QPoint _pos = ui->treeView->viewport()->mapToGlobal(pos); + + emit showContextMenu(url, _pos); + } + }); + + // addBookmark + connect(ui->addBookmark_toolButton, &QToolButton::clicked, this, [this]() { + const QModelIndex idx = model->parentFolder(ui->treeView->currentIndex()); + const QModelIndex childIdx = model->appendBookmark(tr("Title"), QString(), idx); + ui->treeView->setCurrentIndex(childIdx); + editBookmark(childIdx); + }); + + // addFolder + connect(ui->addFolder_toolButton, &QToolButton::clicked, this, [this]() { + const QModelIndex idx = model->parentFolder(ui->treeView->currentIndex()); + const QModelIndex childIdx = model->appendFolder(tr("Title"), idx); + ui->treeView->setCurrentIndex(childIdx); + editBookmark(childIdx); + }); + + // deleteItem + connect(ui->deleteItem_toolButton, &QToolButton::clicked, this, [this]() { + const QModelIndex idx = ui->treeView->currentIndex(); + model->removeRow(idx.row(), idx.parent()); + }); +} + +BookmarksWidget::~BookmarksWidget() +{ + delete ui; +} + +void BookmarksWidget::editBookmark(const QModelIndex &index) +{ + auto *dlg = new EditBookmarkDialog(model, index, this); + dlg->exec(); +} + +void BookmarksWidget::save() +{ + if(!model->isModified()) + return; + + QFile bookmarksFile(m_bookmarksPath); + if(bookmarksFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + BookmarkFormat f(&bookmarksFile); + model >> f; + bookmarksFile.flush(); + } +} + +void BookmarksWidget::addBookmark(const QString &title, const QString &url) +{ + model->appendBookmark(title, url, QModelIndex()); +} + +void BookmarksWidget::search(const QString &term, const std::function &callback) const +{ + QStringList ret = model->search(term); + callback(ret); +} diff --git a/src/bookmarks/bookmarkswidget.h b/src/bookmarks/bookmarkswidget.h new file mode 100644 index 0000000..149d2a6 --- /dev/null +++ b/src/bookmarks/bookmarkswidget.h @@ -0,0 +1,50 @@ +/* + * 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/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#ifndef BOOKMARKSDIALOG_H +#define BOOKMARKSDIALOG_H + +#include +#include +#include +#include + +namespace Ui +{ +class BookmarksDialog; +} + +class BookmarksView; +class BookmarkModel; +class BookmarksWidget : public QWidget +{ + Q_OBJECT + +public: + explicit BookmarksWidget(const QString &path, QWidget *parent = nullptr); + ~BookmarksWidget() override; + +protected: + void editBookmark(const QModelIndex &index); + +signals: + void showContextMenu(const QUrl &url, const QPoint &pos); + void openUrl(const QUrl &url); + +public slots: + void save(); + void addBookmark(const QString &title, const QString &url); + void search(const QString &term, const std::function &callback) const; + +private: + Ui::BookmarksDialog *ui; + QString m_bookmarksPath; + BookmarkModel *model; +}; + +#endif // BOOKMARKSDIALOG_H diff --git a/src/bookmarks/editbookmarkdialog.cpp b/src/bookmarks/editbookmarkdialog.cpp new file mode 100644 index 0000000..7df90b8 --- /dev/null +++ b/src/bookmarks/editbookmarkdialog.cpp @@ -0,0 +1,70 @@ +/* + * 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/gitea/aqua/smolbote + * + * 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); + + Q_CHECK_PTR(model); + m_model = model; + m_index = index; + + ui->title->setText(model->data(index, BookmarkItem::Title, Qt::DisplayRole).toString()); + connect(ui->title, &QLineEdit::editingFinished, this, [this]() { + titleChanged = true; + }); + + ui->address->setText(model->data(index, BookmarkItem::Href, Qt::DisplayRole).toString()); + connect(ui->address, &QLineEdit::editingFinished, this, [this]() { + hrefChanged = true; + }); + + ui->tags->setText(model->data(index, BookmarkItem::Tags, Qt::DisplayRole).toStringList().join(", ")); + connect(ui->tags, &QLineEdit::editingFinished, this, [this]() { + tagsChanged = true; + }); + + ui->description->setPlainText(model->data(index, BookmarkItem::Description, Qt::DisplayRole).toString()); + connect(ui->description, &QPlainTextEdit::textChanged, this, [this]() { + descriptionChanged = true; + }); + + connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &EditBookmarkDialog::saveChanges); +} + +EditBookmarkDialog::~EditBookmarkDialog() +{ + delete ui; +} + +void EditBookmarkDialog::saveChanges() +{ + if(titleChanged) { + m_model->setData(m_index, ui->title->text(), BookmarkItem::Title, Qt::DisplayRole); + } + + if(hrefChanged) { + m_model->setData(m_index, ui->address->text(), BookmarkItem::Href, Qt::DisplayRole); + } + + if(tagsChanged) { + m_model->setData(m_index, ui->tags->text().split(", "), BookmarkItem::Tags, Qt::DisplayRole); + } + + if(descriptionChanged) { + m_model->setData(m_index, ui->description->toPlainText(), BookmarkItem::Description, Qt::DisplayRole); + } +} diff --git a/src/bookmarks/editbookmarkdialog.h b/src/bookmarks/editbookmarkdialog.h new file mode 100644 index 0000000..fb53239 --- /dev/null +++ b/src/bookmarks/editbookmarkdialog.h @@ -0,0 +1,44 @@ +/* + * 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/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#ifndef SMOLBOTE_EDITBOOKMARKDIALOG_H +#define SMOLBOTE_EDITBOOKMARKDIALOG_H + +#include +#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; + +public slots: + void saveChanges(); + +private: + Ui::EditBookmarkDialog *ui; + + BookmarkModel *m_model; + QModelIndex m_index; + + bool titleChanged = false; + bool hrefChanged = false; + bool tagsChanged = false; + bool descriptionChanged = false; +}; + +#endif // SMOLBOTE_EDITBOOKMARKDIALOG_H diff --git a/src/bookmarks/editbookmarkdialog.ui b/src/bookmarks/editbookmarkdialog.ui new file mode 100644 index 0000000..b988394 --- /dev/null +++ b/src/bookmarks/editbookmarkdialog.ui @@ -0,0 +1,108 @@ + + + EditBookmarkDialog + + + + 0 + 0 + 400 + 320 + + + + Edit Bookmark + + + + + + + + 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/src/browser.cpp b/src/browser.cpp index 09fc2c8..e518a81 100644 --- a/src/browser.cpp +++ b/src/browser.cpp @@ -10,7 +10,7 @@ #include "aboutdialog.h" #include "aboutplugin.h" #include "adblock/adblocklist.h" -#include "bookmarkswidget.h" +#include "bookmarks/bookmarkswidget.h" #include "configuration.h" #include "downloadswidget.h" #include "hostlist/hostlist.h" diff --git a/src/mainwindow/menubar.cpp b/src/mainwindow/menubar.cpp index 7fdad24..a8d0590 100644 --- a/src/mainwindow/menubar.cpp +++ b/src/mainwindow/menubar.cpp @@ -7,7 +7,7 @@ */ #include "menubar.h" -#include "bookmarkswidget.h" +#include "bookmarks/bookmarkswidget.h" #include "browser.h" #include "configuration.h" #include "downloadswidget.h" diff --git a/src/meson.build b/src/meson.build index 6d6a1aa..1783455 100644 --- a/src/meson.build +++ b/src/meson.build @@ -10,10 +10,14 @@ poi_settings_h = custom_target('default_config_value', poi_sourceset.add(mod_qt5.preprocess( moc_headers: ['browser.h', 'mainwindow/mainwindow.h', 'mainwindow/addressbar.h', 'mainwindow/menubar.h', 'mainwindow/widgets/completer.h', 'mainwindow/widgets/urllineedit.h', 'mainwindow/widgets/dockwidget.h', 'mainwindow/widgets/menusearch.h', 'mainwindow/widgets/navigationbar.h', 'mainwindow/widgets/searchform.h', + 'bookmarks/bookmarkswidget.h', 'bookmarks/editbookmarkdialog.h', 'session/savesessiondialog.h', 'session/sessiondialog.h', 'session/sessionform.h', 'subwindow/subwindow.h', 'subwindow/tabwidget.h', 'webengine/urlinterceptor.h', 'webengine/webpage.h', 'webengine/webview.h', 'webengine/webprofilemanager.h', 'webengine/webprofile.h'], - ui_files: ['mainwindow/addressbar.ui', 'mainwindow/widgets/searchform.ui', 'session/savesessiondialog.ui', 'session/sessiondialog.ui', 'session/sessionform.ui'], + ui_files: [ + 'mainwindow/addressbar.ui', 'mainwindow/widgets/searchform.ui', + 'bookmarks/bookmarksform.ui', 'bookmarks/editbookmarkdialog.ui', + 'session/savesessiondialog.ui', 'session/sessiondialog.ui', 'session/sessionform.ui'], qresources: '../data/resources.qrc', rcc_extra_arguments: ['--format-version=1'], dependencies: dep_qt5 @@ -34,6 +38,8 @@ poi_sourceset.add(files( 'mainwindow/widgets/navigationbar.cpp', 'mainwindow/widgets/searchform.cpp', + 'bookmarks/bookmarkswidget.cpp', 'bookmarks/editbookmarkdialog.cpp', + 'session/session.cpp', 'session/savesessiondialog.cpp', 'session/sessiondialog.cpp', -- cgit v1.2.1 From 198be208d49990c3535ac765735768ad1ae79c1b Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Thu, 16 Jan 2020 21:40:15 +0200 Subject: Add Firefox bookmarks.json format to libbookmarks - can only read folders and bookmarks, their title and uri fields Not supported by Bookmark Model: - Separator items - Date added and Date modified fields --- lib/bookmarks/bookmarkformat.cpp | 9 ++++-- lib/bookmarks/bookmarkformat.h | 4 ++- lib/bookmarks/formats/ffjson.cpp | 45 ++++++++++++++++++++++++++ lib/bookmarks/formats/ffjson.h | 19 +++++++++++ lib/bookmarks/meson.build | 2 +- meson.build | 1 + test/firefox-bookmarks-json-parser/main.cpp | 28 ++++++++++++++++ test/firefox-bookmarks-json-parser/meson.build | 13 ++++++++ 8 files changed, 117 insertions(+), 4 deletions(-) create mode 100644 lib/bookmarks/formats/ffjson.cpp create mode 100644 lib/bookmarks/formats/ffjson.h create mode 100644 test/firefox-bookmarks-json-parser/main.cpp create mode 100644 test/firefox-bookmarks-json-parser/meson.build diff --git a/lib/bookmarks/bookmarkformat.cpp b/lib/bookmarks/bookmarkformat.cpp index e6149cd..87b816c 100644 --- a/lib/bookmarks/bookmarkformat.cpp +++ b/lib/bookmarks/bookmarkformat.cpp @@ -8,19 +8,24 @@ #include "bookmarkformat.h" #include "formats/xbel.h" +#include "formats/ffjson.h" #include template<> void BookmarkFormat::read(BookmarkItem *root) const { - Q_CHECK_PTR(m_device); Xbel::read(m_device, root); } template<> void BookmarkFormat::write(BookmarkItem *root) { - Q_CHECK_PTR(m_device); Xbel::write(m_device, root); } +template<> +void BookmarkFormat::read(BookmarkItem *root) const +{ + FFJson::read(m_device, root); +} + diff --git a/lib/bookmarks/bookmarkformat.h b/lib/bookmarks/bookmarkformat.h index 673acbd..5cd1860 100644 --- a/lib/bookmarks/bookmarkformat.h +++ b/lib/bookmarks/bookmarkformat.h @@ -14,7 +14,8 @@ class QIODevice; enum BookmarkFormats { - XbelFormat + XbelFormat, + FirefoxJsonFormat }; template @@ -23,6 +24,7 @@ class BookmarkFormat public: explicit BookmarkFormat(QIODevice *device) { + Q_CHECK_PTR(m_device); m_device = device; } ~BookmarkFormat() diff --git a/lib/bookmarks/formats/ffjson.cpp b/lib/bookmarks/formats/ffjson.cpp new file mode 100644 index 0000000..f173904 --- /dev/null +++ b/lib/bookmarks/formats/ffjson.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/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#include "ffjson.h" +#include "bookmarkitem.h" +#include +#include +#include +#include + +void readChildElements(const QJsonObject &object, BookmarkItem *item) +{ + for(const auto c : object["children"].toArray()) { + const auto child = c.toObject(); + const auto type = child["type"].toString(); + + if(type == "text/x-moz-place-container") { + auto *childItem = new BookmarkItem({}, BookmarkItem::Folder, item); + childItem->setExpanded(true); + childItem->setData(BookmarkItem::Title, child["title"].toString()); + item->appendChild(childItem); + readChildElements(child, childItem); + + } else if(type == "text/x-moz-place") { + auto *childItem = new BookmarkItem({}, BookmarkItem::Bookmark, item); + childItem->setData(BookmarkItem::Title, child["title"].toString()); + childItem->setData(BookmarkItem::Href, child["uri"].toString()); + item->appendChild(childItem); + + } else { + qDebug() << "!!! unknown type " << qUtf8Printable(type); + } + } +} + +void FFJson::read(QIODevice *device, BookmarkItem *item) +{ + const auto doc = QJsonDocument::fromJson(device->readAll()); + readChildElements(doc.object(), item); +} diff --git a/lib/bookmarks/formats/ffjson.h b/lib/bookmarks/formats/ffjson.h new file mode 100644 index 0000000..cc6ac24 --- /dev/null +++ b/lib/bookmarks/formats/ffjson.h @@ -0,0 +1,19 @@ +/* + * 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/gitea/aqua/smolbote + * + * SPDX-License-Identifier: GPL-3.0 + */ + +#ifndef FFJSON_H +#define FFJSON_H + +class QIODevice; +class BookmarkItem; +namespace FFJson +{ +void read(QIODevice *device, BookmarkItem *item); +} + +#endif // FFJSON_H diff --git a/lib/bookmarks/meson.build b/lib/bookmarks/meson.build index a7f603b..81c1ece 100644 --- a/lib/bookmarks/meson.build +++ b/lib/bookmarks/meson.build @@ -5,7 +5,7 @@ bookmarks_moc = mod_qt5.preprocess( bookmarks_lib = static_library('bookmarks', [ bookmarks_moc, - 'bookmarkformat.cpp', 'formats/xbel.cpp', + 'bookmarkformat.cpp', 'formats/xbel.cpp', 'formats/ffjson.cpp', 'bookmarkitem.cpp', 'bookmarkmodel.cpp' ], dependencies: dep_qt5 ) diff --git a/meson.build b/meson.build index 32984ea..5e50801 100644 --- a/meson.build +++ b/meson.build @@ -88,6 +88,7 @@ subdir('tools') #subdir('plugins/ProfileEditor') subdir('test/conf') +subdir('test/firefox-bookmarks-json-parser') ssconfig = poi_sourceset.apply(cdata) diff --git a/test/firefox-bookmarks-json-parser/main.cpp b/test/firefox-bookmarks-json-parser/main.cpp new file mode 100644 index 0000000..48093ec --- /dev/null +++ b/test/firefox-bookmarks-json-parser/main.cpp @@ -0,0 +1,28 @@ +#include +#include "bookmarkformat.h" +#include +#include + +int main(int argc, char** argv) +{ + QApplication app(argc, argv); + + QFile f(qgetenv("FILE")); + + auto *model = new BookmarkModel; + + if(f.open(QIODevice::ReadOnly)) { + BookmarkFormat(&f) >> model; + f.close(); + } else + return -1; + + auto *view = new QTreeView; + view->setModel(model); + + if(qgetenv("NOGUI") == "1") + return 0; + + view->show(); + return app.exec(); +} diff --git a/test/firefox-bookmarks-json-parser/meson.build b/test/firefox-bookmarks-json-parser/meson.build new file mode 100644 index 0000000..1432e68 --- /dev/null +++ b/test/firefox-bookmarks-json-parser/meson.build @@ -0,0 +1,13 @@ +e = executable('bookmarks-json-parser', + sources: [ 'main.cpp' ], + dependencies: [ dep_qt5, dep_bookmarks ] +) + +env = environment({ + 'NOGUI' : '1', + 'FILE' : 'bookmarks.json' +}) +test('Firefox bookmarks.json parser', e, + env: env, + workdir: meson.build_root() +) -- cgit v1.2.1 From 5f708d4618d739d14442b85c466fdbac84a74cc8 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Fri, 17 Jan 2020 10:25:27 +0200 Subject: BookmarkItem::DateAdded and LastModified fields - add read support in FFJson for DateAdded and LastModified fields - add read/write support in Xbel for DateAdded and LastModified fields - BookmarkModel: set DateAdded on appendBookmark and appendFolder - EditBookmarkDialog: set LastModified field when saving changes --- lib/bookmarks/bookmarkformat.h | 2 +- lib/bookmarks/bookmarkitem.h | 2 ++ lib/bookmarks/bookmarkmodel.cpp | 3 +++ lib/bookmarks/formats/ffjson.cpp | 18 ++++++++++++++++-- lib/bookmarks/formats/xbel.cpp | 24 ++++++++++++++++++++++-- src/bookmarks/editbookmarkdialog.cpp | 4 ++++ 6 files changed, 48 insertions(+), 5 deletions(-) diff --git a/lib/bookmarks/bookmarkformat.h b/lib/bookmarks/bookmarkformat.h index 5cd1860..8b64420 100644 --- a/lib/bookmarks/bookmarkformat.h +++ b/lib/bookmarks/bookmarkformat.h @@ -24,7 +24,7 @@ class BookmarkFormat public: explicit BookmarkFormat(QIODevice *device) { - Q_CHECK_PTR(m_device); + Q_CHECK_PTR(device); m_device = device; } ~BookmarkFormat() diff --git a/lib/bookmarks/bookmarkitem.h b/lib/bookmarks/bookmarkitem.h index 8c9463f..6751526 100644 --- a/lib/bookmarks/bookmarkitem.h +++ b/lib/bookmarks/bookmarkitem.h @@ -27,6 +27,8 @@ public: Href, Tags, Description, + DateAdded, + LastModified, FieldCount }; diff --git a/lib/bookmarks/bookmarkmodel.cpp b/lib/bookmarks/bookmarkmodel.cpp index 895b178..05df3d7 100644 --- a/lib/bookmarks/bookmarkmodel.cpp +++ b/lib/bookmarks/bookmarkmodel.cpp @@ -12,6 +12,7 @@ #include #include #include +#include BookmarkModel::BookmarkModel(QObject *parent) : QAbstractItemModel(parent) @@ -132,6 +133,7 @@ QModelIndex BookmarkModel::appendBookmark(const QString &title, const QString &u int row = parentItem->childCount(); beginInsertRows(parent, row, row); auto *childItem = new BookmarkItem({ title, url }, BookmarkItem::Bookmark, parentItem); + childItem->setData(BookmarkItem::DateAdded, QDateTime::currentDateTime()); parentItem->appendChild(childItem); endInsertRows(); @@ -146,6 +148,7 @@ QModelIndex BookmarkModel::appendFolder(const QString &title, const QModelIndex beginInsertRows(parent, row, row); auto *childItem = new BookmarkItem({ title }, BookmarkItem::Folder, parentItem); + childItem->setData(BookmarkItem::DateAdded, QDateTime::currentDateTime()); parentItem->appendChild(childItem); endInsertRows(); diff --git a/lib/bookmarks/formats/ffjson.cpp b/lib/bookmarks/formats/ffjson.cpp index f173904..98f8e60 100644 --- a/lib/bookmarks/formats/ffjson.cpp +++ b/lib/bookmarks/formats/ffjson.cpp @@ -12,6 +12,20 @@ #include #include #include +#include + +inline auto asDate(const QJsonValue &v) +{ + // timestamps in bookmarks.json are, for some reason, in *micro*seconds + return QDateTime::fromMSecsSinceEpoch(v.toVariant().toLongLong() / 1000); +} + +inline void readElementData(const QJsonObject &object, BookmarkItem *item) +{ + item->setData(BookmarkItem::Title, object["title"].toString()); + item->setData(BookmarkItem::DateAdded, asDate(object["dateAdded"])); + item->setData(BookmarkItem::LastModified, asDate(object["lastModified"])); +} void readChildElements(const QJsonObject &object, BookmarkItem *item) { @@ -22,13 +36,13 @@ void readChildElements(const QJsonObject &object, BookmarkItem *item) if(type == "text/x-moz-place-container") { auto *childItem = new BookmarkItem({}, BookmarkItem::Folder, item); childItem->setExpanded(true); - childItem->setData(BookmarkItem::Title, child["title"].toString()); + readElementData(child, childItem); item->appendChild(childItem); readChildElements(child, childItem); } else if(type == "text/x-moz-place") { auto *childItem = new BookmarkItem({}, BookmarkItem::Bookmark, item); - childItem->setData(BookmarkItem::Title, child["title"].toString()); + readElementData(child, childItem); childItem->setData(BookmarkItem::Href, child["uri"].toString()); item->appendChild(childItem); diff --git a/lib/bookmarks/formats/xbel.cpp b/lib/bookmarks/formats/xbel.cpp index 174995d..bac2bc8 100644 --- a/lib/bookmarks/formats/xbel.cpp +++ b/lib/bookmarks/formats/xbel.cpp @@ -10,6 +10,7 @@ #include "bookmarkitem.h" #include #include +#include inline void readChildElements(QXmlStreamReader &reader, BookmarkItem *parent) { @@ -17,6 +18,12 @@ inline void readChildElements(QXmlStreamReader &reader, BookmarkItem *parent) if(reader.name() == "title") { parent->setData(BookmarkItem::Title, reader.readElementText()); + } else if(reader.name() == "dateAdded") { + parent->setData(BookmarkItem::DateAdded, QDateTime::fromString(reader.readElementText(), Qt::RFC2822Date)); + + } else if(reader.name() == "lastModified") { + parent->setData(BookmarkItem::LastModified, QDateTime::fromString(reader.readElementText(), Qt::RFC2822Date)); + } else if(reader.name() == "tags") { parent->setData(BookmarkItem::Tags, reader.readElementText().split(";")); @@ -54,6 +61,19 @@ void Xbel::read(QIODevice *device, BookmarkItem *item) } } +inline void writeCommon(QXmlStreamWriter &writer, const BookmarkItem *item) +{ + writer.writeTextElement("title", item->data(BookmarkItem::Title).toString()); + + const auto dateAdded = item->data(BookmarkItem::DateAdded); + if(!dateAdded.isNull()) + writer.writeTextElement("dateAdded", dateAdded.toDateTime().toString(Qt::RFC2822Date)); + + const auto lastModified = item->data(BookmarkItem::LastModified); + if(!lastModified.isNull()) + writer.writeTextElement("lastModified", lastModified.toDateTime().toString(Qt::RFC2822Date)); +} + inline void writeChildElements(QXmlStreamWriter &writer, const BookmarkItem *item) { switch(item->type()) { @@ -66,7 +86,7 @@ inline void writeChildElements(QXmlStreamWriter &writer, const BookmarkItem *ite case BookmarkItem::Folder: writer.writeStartElement("folder"); writer.writeAttribute("folded", !item->isExpanded() ? "yes" : "no"); - writer.writeTextElement("title", item->data(BookmarkItem::Title).toString()); + writeCommon(writer, item); if(!item->data(BookmarkItem::Tags).isNull()) writer.writeTextElement("tags", item->data(BookmarkItem::Tags).toStringList().join(";")); if(!item->data(BookmarkItem::Description).isNull()) @@ -82,7 +102,7 @@ inline void writeChildElements(QXmlStreamWriter &writer, const BookmarkItem *ite case BookmarkItem::Bookmark: writer.writeStartElement("bookmark"); writer.writeAttribute("href", item->data(BookmarkItem::Href).toString()); - writer.writeTextElement("title", item->data(BookmarkItem::Title).toString()); + writeCommon(writer, item); if(!item->data(BookmarkItem::Tags).isNull()) writer.writeTextElement("tags", item->data(BookmarkItem::Tags).toStringList().join(";")); if(!item->data(BookmarkItem::Description).isNull()) diff --git a/src/bookmarks/editbookmarkdialog.cpp b/src/bookmarks/editbookmarkdialog.cpp index 7df90b8..4461840 100644 --- a/src/bookmarks/editbookmarkdialog.cpp +++ b/src/bookmarks/editbookmarkdialog.cpp @@ -10,6 +10,7 @@ #include "bookmarkitem.h" #include "bookmarkmodel.h" #include "ui_editbookmarkdialog.h" +#include EditBookmarkDialog::EditBookmarkDialog(BookmarkModel *model, const QModelIndex &index, QWidget *parent) : QDialog(parent) @@ -67,4 +68,7 @@ void EditBookmarkDialog::saveChanges() if(descriptionChanged) { m_model->setData(m_index, ui->description->toPlainText(), BookmarkItem::Description, Qt::DisplayRole); } + + if(titleChanged || hrefChanged || tagsChanged || descriptionChanged) + m_model->setData(m_index, QDateTime::currentDateTime(), BookmarkItem::LastModified, Qt::DisplayRole); } -- cgit v1.2.1 From d75794508e1c202d28bdf77c25afb85d80d42554 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Fri, 17 Jan 2020 11:46:20 +0200 Subject: Add Import option to BookmarksWidget --- lib/bookmarks/bookmarkformat.h | 4 ---- src/bookmarks/bookmarksform.ui | 13 ++++++++++--- src/bookmarks/bookmarkswidget.cpp | 41 +++++++++++++++++++++++++++++++-------- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/lib/bookmarks/bookmarkformat.h b/lib/bookmarks/bookmarkformat.h index 8b64420..c886546 100644 --- a/lib/bookmarks/bookmarkformat.h +++ b/lib/bookmarks/bookmarkformat.h @@ -27,10 +27,6 @@ public: Q_CHECK_PTR(device); m_device = device; } - ~BookmarkFormat() - { - m_device->close(); - } void read(BookmarkItem *root) const; void write(BookmarkItem *root); diff --git a/src/bookmarks/bookmarksform.ui b/src/bookmarks/bookmarksform.ui index a003e53..2dfebf4 100644 --- a/src/bookmarks/bookmarksform.ui +++ b/src/bookmarks/bookmarksform.ui @@ -16,6 +16,13 @@ + + + + Import + + + @@ -66,12 +73,12 @@ Qt::MoveAction - - 200 - 50 + + 200 + diff --git a/src/bookmarks/bookmarkswidget.cpp b/src/bookmarks/bookmarkswidget.cpp index 26fdddf..bd2d607 100644 --- a/src/bookmarks/bookmarkswidget.cpp +++ b/src/bookmarks/bookmarkswidget.cpp @@ -12,6 +12,7 @@ #include "bookmarkformat.h" #include #include +#include inline void expandChildren(QTreeView *view, BookmarkModel *model, const QModelIndex &rootIndex) { @@ -26,6 +27,29 @@ inline void expandChildren(QTreeView *view, BookmarkModel *model, const QModelIn } } +inline void loadModel(const QString &path, BookmarkModel *model, QTreeView *view) +{ + view->setModel(nullptr); + + if(path.endsWith(".xbel")) { + QFile f(path); + if(f.open(QIODevice::ReadOnly | QIODevice::Text)) { + BookmarkFormat(&f) >> model; + f.close(); + } + + } else if(path.endsWith(".json")) { + QFile f(path); + if(f.open(QIODevice::ReadOnly | QIODevice::Text)) { + BookmarkFormat(&f) >> model; + f.close(); + } + } + + view->setModel(model); + expandChildren(view, model, QModelIndex()); +} + BookmarksWidget::BookmarksWidget(const QString &path, QWidget *parent) : QWidget(parent) , ui(new Ui::BookmarksDialog) @@ -44,14 +68,7 @@ BookmarksWidget::BookmarksWidget(const QString &path, QWidget *parent) model = new BookmarkModel(this); m_bookmarksPath = path; - QFile bookmarksFile(m_bookmarksPath); - if(bookmarksFile.open(QIODevice::ReadOnly | QIODevice::Text)) { - BookmarkFormat(&bookmarksFile) >> model; - } - model->resetModified(); - - ui->treeView->setModel(model); - expandChildren(ui->treeView, model, QModelIndex()); + loadModel(path, model, ui->treeView); // item activated connect(ui->treeView, &QTreeView::activated, this, [this](const QModelIndex &index) { @@ -100,6 +117,14 @@ BookmarksWidget::BookmarksWidget(const QString &path, QWidget *parent) const QModelIndex idx = ui->treeView->currentIndex(); model->removeRow(idx.row(), idx.parent()); }); + + // import button + connect(ui->import_toolButton, &QToolButton::clicked, this, [this]() { + const auto path = QFileDialog::getOpenFileName(this, tr("Open bookmarks file"), QDir::homePath(), tr("Firefox bookmarks backup (*.json)")); + if(!path.isEmpty()) { + loadModel(path, model, ui->treeView); + } + }); } BookmarksWidget::~BookmarksWidget() -- cgit v1.2.1 From 2c982ae87935c2ce2e2144694a4d55c5e1a688b6 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Fri, 17 Jan 2020 13:14:11 +0200 Subject: Parse Tags and Descriptions in FFJson --- lib/bookmarks/formats/ffjson.cpp | 13 +++++++++++++ test/firefox-bookmarks-json-parser/main.cpp | 7 +++++++ 2 files changed, 20 insertions(+) diff --git a/lib/bookmarks/formats/ffjson.cpp b/lib/bookmarks/formats/ffjson.cpp index 98f8e60..1fe6a96 100644 --- a/lib/bookmarks/formats/ffjson.cpp +++ b/lib/bookmarks/formats/ffjson.cpp @@ -25,6 +25,19 @@ inline void readElementData(const QJsonObject &object, BookmarkItem *item) item->setData(BookmarkItem::Title, object["title"].toString()); item->setData(BookmarkItem::DateAdded, asDate(object["dateAdded"])); item->setData(BookmarkItem::LastModified, asDate(object["lastModified"])); + + // tags + const auto tags = object["tags"].toString().split(","); + if(!tags.isEmpty()) + item->setData(BookmarkItem::Tags, tags); + + // descriptions + for(const auto &a : object["annos"].toArray()) { + const auto anno = a.toObject(); + if(anno["name"] == "bookmarkProperties/description") { + item->setData(BookmarkItem::Description, anno["value"].toString()); + } + } } void readChildElements(const QJsonObject &object, BookmarkItem *item) diff --git a/test/firefox-bookmarks-json-parser/main.cpp b/test/firefox-bookmarks-json-parser/main.cpp index 48093ec..54819a2 100644 --- a/test/firefox-bookmarks-json-parser/main.cpp +++ b/test/firefox-bookmarks-json-parser/main.cpp @@ -2,6 +2,7 @@ #include "bookmarkformat.h" #include #include +#include int main(int argc, char** argv) { @@ -23,6 +24,12 @@ int main(int argc, char** argv) if(qgetenv("NOGUI") == "1") return 0; + QObject::connect(view, &QTreeView::activated, [model](const QModelIndex &index) { + const auto tags = model->data(index, BookmarkItem::Tags, Qt::DisplayRole).toStringList(); + qDebug() << tags.join(" || "); + }); + + view->show(); return app.exec(); } -- cgit v1.2.1