From eea675e1f33d29550c9f3e90eb6b6b2402e5ef37 Mon Sep 17 00:00:00 2001 From: Aqua-sama Date: Tue, 28 Jan 2020 14:59:23 +0200 Subject: Add bookmarks toolbar Bookmarks Toolbar displays the contents of the top-level "Bookmarks Toolbar" folder. --- lib/bookmarks/bookmarkformat.cpp | 12 +++--- lib/bookmarks/bookmarkformat.h | 35 ++-------------- lib/bookmarks/bookmarkitem.cpp | 5 +++ lib/bookmarks/bookmarkitem.h | 1 + lib/bookmarks/bookmarkmodel.h | 34 +++++++++++++++- src/bookmarks/bookmarkstoolbar.cpp | 62 +++++++++++++++++++++++++++++ src/bookmarks/bookmarkstoolbar.h | 29 ++++++++++++++ src/bookmarks/bookmarkswidget.cpp | 58 +++++++++++++-------------- src/bookmarks/bookmarkswidget.h | 3 +- src/bookmarks/builtins.cpp | 5 +-- src/mainwindow/mainwindow.cpp | 6 +++ src/meson.build | 2 +- test/firefox-bookmarks-json-parser/main.cpp | 11 +++-- 13 files changed, 184 insertions(+), 79 deletions(-) create mode 100644 src/bookmarks/bookmarkstoolbar.cpp create mode 100644 src/bookmarks/bookmarkstoolbar.h diff --git a/lib/bookmarks/bookmarkformat.cpp b/lib/bookmarks/bookmarkformat.cpp index 87b816c..491d69a 100644 --- a/lib/bookmarks/bookmarkformat.cpp +++ b/lib/bookmarks/bookmarkformat.cpp @@ -7,25 +7,25 @@ */ #include "bookmarkformat.h" -#include "formats/xbel.h" +#include "bookmarkitem.h" #include "formats/ffjson.h" +#include "formats/xbel.h" #include -template<> +template <> void BookmarkFormat::read(BookmarkItem *root) const { Xbel::read(m_device, root); } -template<> -void BookmarkFormat::write(BookmarkItem *root) +template <> +void BookmarkFormat::write(const BookmarkItem *root) { Xbel::write(m_device, root); } -template<> +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 c886546..cdae24e 100644 --- a/lib/bookmarks/bookmarkformat.h +++ b/lib/bookmarks/bookmarkformat.h @@ -9,57 +9,28 @@ #ifndef BOOKMARKFORMAT_H #define BOOKMARKFORMAT_H -#include "bookmarkmodel.h" - class QIODevice; +class BookmarkItem; enum BookmarkFormats { XbelFormat, FirefoxJsonFormat }; -template +template class BookmarkFormat { public: explicit BookmarkFormat(QIODevice *device) { - Q_CHECK_PTR(device); m_device = device; } void read(BookmarkItem *root) const; - void write(BookmarkItem *root); + void write(const 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 index d361e26..242ab57 100644 --- a/lib/bookmarks/bookmarkitem.cpp +++ b/lib/bookmarks/bookmarkitem.cpp @@ -109,6 +109,11 @@ QIcon BookmarkItem::icon() return m_icon; } +QIcon BookmarkItem::icon() const +{ + return m_icon; +} + bool BookmarkItem::isExpanded() const { return m_isExpanded; diff --git a/lib/bookmarks/bookmarkitem.h b/lib/bookmarks/bookmarkitem.h index 97d3e89..310d263 100644 --- a/lib/bookmarks/bookmarkitem.h +++ b/lib/bookmarks/bookmarkitem.h @@ -49,6 +49,7 @@ public: bool setData(Fields column, const QVariant &data); QIcon icon(); + QIcon icon() const; bool isExpanded() const; void setExpanded(bool expanded); diff --git a/lib/bookmarks/bookmarkmodel.h b/lib/bookmarks/bookmarkmodel.h index 300b724..1ddab1e 100644 --- a/lib/bookmarks/bookmarkmodel.h +++ b/lib/bookmarks/bookmarkmodel.h @@ -9,6 +9,7 @@ #ifndef SMOLBOTE_BOOKMARKMODEL_H #define SMOLBOTE_BOOKMARKMODEL_H +#include "bookmarkformat.h" #include "bookmarkitem.h" #include @@ -16,6 +17,11 @@ class BookmarkModel : public QAbstractItemModel { Q_OBJECT + template + friend void operator<<(BookmarkModel *model, const BookmarkFormat &format); + template + friend void operator>>(const BookmarkFormat &format, BookmarkModel *model); + public: explicit BookmarkModel(QObject *parent = nullptr); ~BookmarkModel() override; @@ -45,7 +51,7 @@ public: QModelIndex parent(const QModelIndex &index) const override; QModelIndex parentFolder(const QModelIndex &index) const; - BookmarkItem *root() + const BookmarkItem *root() const { return rootItem; } @@ -70,4 +76,30 @@ private: bool m_isModified = false; }; +template +void operator<<(BookmarkModel *model, const BookmarkFormat &format) +{ + format.read(model->rootItem); +} + +template +void operator>>(const BookmarkFormat &format, BookmarkModel *model) +{ + format.read(model->rootItem); +} + +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 // SMOLBOTE_BOOKMARKMODEL_H diff --git a/src/bookmarks/bookmarkstoolbar.cpp b/src/bookmarks/bookmarkstoolbar.cpp new file mode 100644 index 0000000..11dd712 --- /dev/null +++ b/src/bookmarks/bookmarkstoolbar.cpp @@ -0,0 +1,62 @@ +/* + * 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 "bookmarkstoolbar.h" +#include "bookmarkmodel.h" +#include "mainwindow/mainwindow.h" +#include + +BookmarksToolbar::BookmarksToolbar(const BookmarkModel *model, MainWindow *parent) + : QToolBar(parent) +{ + m_window = parent; + + const auto *root = model->root(); + for(int i = 0; i < root->childCount(); ++i) { + const auto *child = root->child(i); + if(child->type() == BookmarkItem::Folder && child->data(BookmarkItem::Title).toString() == "Bookmarks Toolbar") { + addFolder(child); + break; + } + } +} + +void BookmarksToolbar::addBookmark(const BookmarkItem *item, QMenu *where) +{ + QAction *action = nullptr; + if(where) + action = where->addAction(item->data(BookmarkItem::Title).toString()); + else + action = addAction(item->data(BookmarkItem::Title).toString()); + + action->setIcon(item->icon()); + + const auto url = item->data(BookmarkItem::Href).toUrl(); + connect(action, &QAction::triggered, m_window, [this, url]() { + m_window->createTab(url); + }); +} + +void BookmarksToolbar::addFolder(const BookmarkItem *item, QMenu *where) +{ + for(int i = 0; i < item->childCount(); ++i) { + auto *child = item->child(i); + + if(child->type() == BookmarkItem::Bookmark) + addBookmark(child, where); + + else if(child->type() == BookmarkItem::Folder) { + auto *action = addAction(child->data(BookmarkItem::Title).toString()); + //action->setIcon(child->icon()); + + auto *menu = new QMenu(this); + addFolder(child, menu); + action->setMenu(menu); + } + } +} diff --git a/src/bookmarks/bookmarkstoolbar.h b/src/bookmarks/bookmarkstoolbar.h new file mode 100644 index 0000000..b3cb19d --- /dev/null +++ b/src/bookmarks/bookmarkstoolbar.h @@ -0,0 +1,29 @@ +/* + * 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 BOOKMARKSTOOLBAR +#define BOOKMARKSTOOLBAR + +#include + +class BookmarkModel; +class BookmarkItem; +class MainWindow; +class BookmarksToolbar : public QToolBar +{ +public: + explicit BookmarksToolbar(const BookmarkModel *model, MainWindow *parent = nullptr); + +private: + void addBookmark(const BookmarkItem *item, QMenu *where = nullptr); + void addFolder(const BookmarkItem *item, QMenu *where = nullptr); + + MainWindow *m_window = nullptr; +}; + +#endif // BOOKMARKSTOOLBAR diff --git a/src/bookmarks/bookmarkswidget.cpp b/src/bookmarks/bookmarkswidget.cpp index bd2d607..21739e7 100644 --- a/src/bookmarks/bookmarkswidget.cpp +++ b/src/bookmarks/bookmarkswidget.cpp @@ -7,47 +7,47 @@ */ #include "bookmarkswidget.h" +#include "bookmarkmodel.h" #include "editbookmarkdialog.h" #include "ui_bookmarksform.h" -#include "bookmarkformat.h" +#include #include #include -#include -inline void expandChildren(QTreeView *view, BookmarkModel *model, const QModelIndex &rootIndex) +inline void expandChildren(QTreeView *view, BookmarkModel *m_model, const QModelIndex &rootIndex) { - for(int i = 0; i < model->rowCount(rootIndex); ++i) { - QModelIndex idx = model->index(i, 0, rootIndex); - if(model->isItemExpanded(idx)) + for(int i = 0; i < m_model->rowCount(rootIndex); ++i) { + QModelIndex idx = m_model->index(i, 0, rootIndex); + if(m_model->isItemExpanded(idx)) view->expand(idx); // check if index has children - if(model->rowCount(idx) > 0) - expandChildren(view, model, idx); + if(m_model->rowCount(idx) > 0) + expandChildren(view, m_model, idx); } } -inline void loadModel(const QString &path, BookmarkModel *model, QTreeView *view) +inline void loadModel(const QString &path, BookmarkModel *m_model, QTreeView *view) { view->setModel(nullptr); if(path.endsWith(".xbel")) { QFile f(path); if(f.open(QIODevice::ReadOnly | QIODevice::Text)) { - BookmarkFormat(&f) >> model; + BookmarkFormat(&f) >> m_model; f.close(); } } else if(path.endsWith(".json")) { QFile f(path); if(f.open(QIODevice::ReadOnly | QIODevice::Text)) { - BookmarkFormat(&f) >> model; + BookmarkFormat(&f) >> m_model; f.close(); } } - view->setModel(model); - expandChildren(view, model, QModelIndex()); + view->setModel(m_model); + expandChildren(view, m_model, QModelIndex()); } BookmarksWidget::BookmarksWidget(const QString &path, QWidget *parent) @@ -66,9 +66,9 @@ BookmarksWidget::BookmarksWidget(const QString &path, QWidget *parent) ui->deleteItem_toolButton->setIcon(style()->standardPixmap(QStyle::SP_TrashIcon)); ui->deleteItem_toolButton->setShortcut(QKeySequence::Delete); - model = new BookmarkModel(this); + m_model = new BookmarkModel(this); m_bookmarksPath = path; - loadModel(path, model, ui->treeView); + loadModel(path, m_model, ui->treeView); // item activated connect(ui->treeView, &QTreeView::activated, this, [this](const QModelIndex &index) { @@ -79,17 +79,17 @@ BookmarksWidget::BookmarksWidget(const QString &path, QWidget *parent) }); connect(ui->treeView, &QTreeView::expanded, this, [this](const QModelIndex &index) { - model->setItemExpanded(index, true); + m_model->setItemExpanded(index, true); }); connect(ui->treeView, &QTreeView::collapsed, this, [this](const QModelIndex &index) { - model->setItemExpanded(index, false); + m_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 QUrl url = m_model->data(idx, 1, Qt::DisplayRole).toUrl(); const QPoint _pos = ui->treeView->viewport()->mapToGlobal(pos); emit showContextMenu(url, _pos); @@ -98,16 +98,16 @@ BookmarksWidget::BookmarksWidget(const QString &path, QWidget *parent) // 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); + const QModelIndex idx = m_model->parentFolder(ui->treeView->currentIndex()); + const QModelIndex childIdx = m_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); + const QModelIndex idx = m_model->parentFolder(ui->treeView->currentIndex()); + const QModelIndex childIdx = m_model->appendFolder(tr("Title"), idx); ui->treeView->setCurrentIndex(childIdx); editBookmark(childIdx); }); @@ -115,14 +115,14 @@ BookmarksWidget::BookmarksWidget(const QString &path, QWidget *parent) // deleteItem connect(ui->deleteItem_toolButton, &QToolButton::clicked, this, [this]() { const QModelIndex idx = ui->treeView->currentIndex(); - model->removeRow(idx.row(), idx.parent()); + m_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); + loadModel(path, m_model, ui->treeView); } }); } @@ -134,30 +134,30 @@ BookmarksWidget::~BookmarksWidget() void BookmarksWidget::editBookmark(const QModelIndex &index) { - auto *dlg = new EditBookmarkDialog(model, index, this); + auto *dlg = new EditBookmarkDialog(m_model, index, this); dlg->exec(); } void BookmarksWidget::save() { - if(!model->isModified()) + if(!m_model->isModified()) return; QFile bookmarksFile(m_bookmarksPath); if(bookmarksFile.open(QIODevice::WriteOnly | QIODevice::Text)) { BookmarkFormat f(&bookmarksFile); - model >> f; + m_model >> f; bookmarksFile.flush(); } } void BookmarksWidget::addBookmark(const QString &title, const QString &url) { - model->appendBookmark(title, url, QModelIndex()); + m_model->appendBookmark(title, url, QModelIndex()); } void BookmarksWidget::search(const QString &term, const std::function &callback) const { - QStringList ret = model->search(term); + QStringList ret = m_model->search(term); callback(ret); } diff --git a/src/bookmarks/bookmarkswidget.h b/src/bookmarks/bookmarkswidget.h index 149d2a6..432d936 100644 --- a/src/bookmarks/bookmarkswidget.h +++ b/src/bookmarks/bookmarkswidget.h @@ -28,6 +28,7 @@ class BookmarksWidget : public QWidget public: explicit BookmarksWidget(const QString &path, QWidget *parent = nullptr); ~BookmarksWidget() override; + const BookmarkModel *model() const { return m_model; }; protected: void editBookmark(const QModelIndex &index); @@ -44,7 +45,7 @@ public slots: private: Ui::BookmarksDialog *ui; QString m_bookmarksPath; - BookmarkModel *model; + BookmarkModel *m_model; }; #endif // BOOKMARKSDIALOG_H diff --git a/src/bookmarks/builtins.cpp b/src/bookmarks/builtins.cpp index 259bfa6..2e97e1a 100644 --- a/src/bookmarks/builtins.cpp +++ b/src/bookmarks/builtins.cpp @@ -7,7 +7,7 @@ */ #include "builtins.h" -#include "bookmarkformat.h" +#include "bookmarkmodel.h" #include "configuration.h" #include #include @@ -18,8 +18,7 @@ int builtins::bookmarks(const std::string &progname, std::vector::c { args::ArgumentParser parser("bookmarks", "If an output location is not specified, this command will append imported bookmarks to the browser's bookmarks.\n" - "If an output location is specified, this command will load all XBEL-format bookmarks, then all JSON-format bookmarks, and write them to the output location." - ); + "If an output location is specified, this command will load all XBEL-format bookmarks, then all JSON-format bookmarks, and write them to the output location."); parser.Prog(progname); args::HelpFlag help(parser, "help", "Display this help message and exit.", { 'h', "help" }); diff --git a/src/mainwindow/mainwindow.cpp b/src/mainwindow/mainwindow.cpp index 558fe49..5386aab 100644 --- a/src/mainwindow/mainwindow.cpp +++ b/src/mainwindow/mainwindow.cpp @@ -8,6 +8,8 @@ #include "mainwindow.h" #include "addressbar.h" +#include "bookmarks/bookmarkstoolbar.h" +#include "bookmarks/bookmarkswidget.h" #include "browser.h" #include "configuration.h" #include "menubar.h" @@ -76,6 +78,10 @@ MainWindow::MainWindow(QWidget *parent) addressBar = new AddressBar(this); navigationToolBar->addWidget(addressBar); + Browser *app = qobject_cast(qApp); + this->addToolBarBreak(); + this->addToolBar(new BookmarksToolbar(app->bookmarks()->model(), this)); + mdiArea->setBackground(Qt::NoBrush); setCentralWidget(mdiArea); mdiArea->setFocus(); diff --git a/src/meson.build b/src/meson.build index 95f81f7..12c41c8 100644 --- a/src/meson.build +++ b/src/meson.build @@ -38,7 +38,7 @@ poi_sourceset.add(files( 'mainwindow/widgets/navigationbar.cpp', 'mainwindow/widgets/searchform.cpp', - 'bookmarks/builtins.cpp', 'bookmarks/bookmarkswidget.cpp', 'bookmarks/editbookmarkdialog.cpp', + 'bookmarks/builtins.cpp', 'bookmarks/bookmarkswidget.cpp', 'bookmarks/editbookmarkdialog.cpp', 'bookmarks/bookmarkstoolbar.cpp', 'session/session.cpp', 'session/savesessiondialog.cpp', diff --git a/test/firefox-bookmarks-json-parser/main.cpp b/test/firefox-bookmarks-json-parser/main.cpp index 54819a2..b145d02 100644 --- a/test/firefox-bookmarks-json-parser/main.cpp +++ b/test/firefox-bookmarks-json-parser/main.cpp @@ -1,17 +1,17 @@ -#include -#include "bookmarkformat.h" -#include +#include "bookmarkmodel.h" #include #include +#include +#include -int main(int argc, char** argv) +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(); @@ -29,7 +29,6 @@ int main(int argc, char** argv) qDebug() << tags.join(" || "); }); - view->show(); return app.exec(); } -- cgit v1.2.1