From 3d8255c70e71e3d4d23a7c798c94b16ab7e970f6 Mon Sep 17 00:00:00 2001 From: aqua Date: Sat, 10 Sep 2022 16:47:56 +0300 Subject: Add Bookmarks panel --- CMakeLists.txt | 2 +- src/CMakeLists.txt | 3 +- src/application.cpp | 54 +++++++------ src/application.hpp | 2 + src/panels/bookmarkspanel.cpp | 179 ++++-------------------------------------- src/panels/bookmarkspanel.h | 93 ---------------------- src/panels/bookmarkspanel.hpp | 27 +++++++ src/rekonq.kcfg | 2 +- src/rekonqwindow.cpp | 25 ------ src/rekonqwindow.hpp | 5 +- src/rekonqwindow.ui | 53 ++++++++++++- src/rekonqwindow_class.cpp | 9 +++ src/test/application_mock.hpp | 1 + 13 files changed, 143 insertions(+), 312 deletions(-) delete mode 100644 src/panels/bookmarkspanel.h create mode 100644 src/panels/bookmarkspanel.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0ee5e07e..69876ac4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,7 +116,7 @@ add_executable(rekonq ${rekonq_SRCS} third-party/resources.qrc) target_include_directories(rekonq PRIVATE src) target_link_libraries(rekonq spdlog::spdlog Qt6::Widgets SingleApplication::SingleApplication - settings pluginloader + bookmarks settings pluginloader ) add_custom_target(rekonq_check_license python scripts/check_license.py ${rekonq_SRCS} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 77155bba..e3a03dba 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,6 +11,7 @@ set(rekonqwindow_SRCS rekonqwindow_class.cpp rekonqwindow.hpp rekonqwindow.ui tabbar/tabbar.cpp tabbar/tabbar.h urlbar/urlbar.cpp urlbar/urlbar.hpp urlbar/completer.cpp urlbar/completer.hpp + panels/bookmarkspanel.cpp panels/bookmarkspanel.hpp ) set(rekonqwindow_IFACES ${PROJECT_SOURCE_DIR}/include/rview.hpp) @@ -126,7 +127,7 @@ if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") add_executable(test_rekonqwindow test/test_rekonqwindow.cpp test/rekonqwindow_mock.hpp test/settings_mock.hpp ${rekonqwindow_SRCS} ${rekonqwindow_IFACES}) target_compile_definitions(test_rekonqwindow PRIVATE REKONQ_TEST) - target_link_libraries(test_rekonqwindow GTest::gtest GTest::gmock settings) + target_link_libraries(test_rekonqwindow GTest::gtest GTest::gmock bookmarks settings) gtest_discover_tests(test_rekonqwindow) endif() diff --git a/src/application.cpp b/src/application.cpp index 38ad7477..0f86feec 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -5,13 +5,11 @@ * Copyright (C) 2012-2013 by Andrea Diamantini * SPDX-License-Identifier: GPL-3.0-only * Copyright (C) 2022 aqua - * ============================================================ - * Description: Application Main Class * ============================================================ */ #include "application.hpp" +#include "bookmarks/bookmarkstreemodel.hpp" #include "plugins/pluginloader.h" -#include "plugins/rplugininterface.hpp" #include "rekonqwindow.hpp" #include "settings/settings.hpp" #include "settings/settingsdialog.h" @@ -59,11 +57,6 @@ Application::Application(int &argc, char *argv[]) : SingleApplication(argc, argv Application::~Application() { - // ok, we are closing well: don't recover on next load.. - // ReKonfig::setRecoverOnCrash(0); - // saveConfiguration(); - delete m_settings; - // Destroy all windows... for (const auto &window : m_windows) delete window; @@ -75,6 +68,11 @@ Application::~Application() plugin->unload(); delete plugin; } + + // ok, we are closing well: don't recover on next load.. + // ReKonfig::setRecoverOnCrash(0); + // saveConfiguration(); + delete m_settings; } // --------------------------------------------------------------------------------------------------------------- @@ -95,7 +93,31 @@ bool Application::registerPlugin(const QString &path) m_plugins.append(loader); return true; } + // --------------------------------------------------------------------------------------------------------------- +// Bookmarks + +struct BookmarksModelPrivate { + + BookmarksModelPrivate() + { + model = new BookmarkModel; + const auto path = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/bookmarks.xbel"; + spdlog::debug("Loading bookmarks from {}", qUtf8Printable(path)); + QFile f(path); + if (f.open(QIODevice::ReadOnly | QIODevice::Text)) { + model->load(&f); + f.close(); + } + } + ~BookmarksModelPrivate() noexcept { delete model; } + + BookmarkModel *model; +}; +Q_GLOBAL_STATIC(BookmarksModelPrivate, bookmarks_d); + +QAbstractItemModel *Application::bookmarks() const { return bookmarks_d->model; } + /* int Application::newInstance() { @@ -409,22 +431,8 @@ RekonqView *Application::newView(const QUrl &url, RekonqWindow *window) return view; } -/* -RekonqWindowList Application::rekonqWindowList() -{ - return m_rekonqWindows; -} - - -WebAppList Application::webAppList() -{ - return m_webApps; -} - - // ------------------------------------------------------------------------------------------------------------------ - - +/* bool Application::eventFilter(QObject* watched, QEvent* event) { // Track which window was activated most recently to prefer it on window choosing diff --git a/src/application.hpp b/src/application.hpp index f435ef8d..c7401563 100644 --- a/src/application.hpp +++ b/src/application.hpp @@ -22,6 +22,7 @@ class RekonqView; class RekonqWindow; class PluginLoader; class RekonqSettings; +class QAbstractItemModel; using RekonqPluginList = QList>; using RekonqWindowList = QList>; @@ -45,6 +46,7 @@ public: // int newInstance(); static Application *instance() { return (qobject_cast(QCoreApplication::instance())); } [[nodiscard]] auto *settings() const { return m_settings; } + REKONQ_TEST_VIRTUAL QAbstractItemModel *bookmarks() const REKONQ_TEST_PURE; // RekonqWindow *rekonqWindow(const QString &activityID = QString()); [[nodiscard]] auto windowList() const { return m_windows; } diff --git a/src/panels/bookmarkspanel.cpp b/src/panels/bookmarkspanel.cpp index 57796a23..ee7ae717 100644 --- a/src/panels/bookmarkspanel.cpp +++ b/src/panels/bookmarkspanel.cpp @@ -1,170 +1,25 @@ /* ============================================================ -* -* This file is a part of the rekonq project -* -* Copyright (C) 2009 by Nils Weigel -* Copyright (C) 2010-2013 by Andrea Diamantini -* Copyright (C) 2010 by Yoann Laissus -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 of -* the License or (at your option) version 3 or any later version -* accepted by the membership of KDE e.V. (or its successor approved -* by the membership of KDE e.V.), which shall act as a proxy -* defined in Section 14 of version 3 of the license. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* ============================================================ */ + * The rekonq project + * ============================================================ + * SPDX-License-Identifier: GPL-3.0-only + * Copyright (C) 2022 aqua + * ============================================================ */ +#include "bookmarkspanel.hpp" +#include "bookmarks/bookmarkstreemodel.hpp" -// Self Includes -#include "bookmarkspanel.h" -#include "bookmarkspanel.moc" - -// Auto Includes -#include "rekonq.h" - -// Local Includes -#include "bookmarkmanager.h" -#include "bookmarkstreemodel.h" -#include "bookmarkscontextmenu.h" -#include "bookmarkowner.h" - -#include "paneltreeview.h" -#include "urlfilterproxymodel.h" - - -BookmarksPanel::BookmarksPanel(const QString &title, QWidget *parent, Qt::WindowFlags flags) - : UrlPanel(title, parent, flags) - , _bkTreeModel(new BookmarksTreeModel(this)) - , _loadingState(false) -{ - setObjectName("bookmarksPanel"); - setVisible(ReKonfig::showBookmarksPanel()); - - panelTreeView()->setDragEnabled(true); - panelTreeView()->setAcceptDrops(true); - connect(_bkTreeModel, SIGNAL(bookmarksUpdated()), this, SLOT(loadFoldedState())); -} - - -BookmarksPanel::~BookmarksPanel() -{ - ReKonfig::setShowBookmarksPanel(!isHidden()); -} - - -void BookmarksPanel::loadFoldedState() -{ - _loadingState = true; - loadFoldedState(QModelIndex()); - _loadingState = false; -} - - -void BookmarksPanel::contextMenu(const QPoint &pos) -{ - if (_loadingState) - return; - - BookmarksContextMenu menu(bookmarkForIndex(panelTreeView()->indexAt(pos)), - BookmarkManager::self()->manager(), - BookmarkManager::self()->owner() - ); - - menu.exec(panelTreeView()->mapToGlobal(pos)); -} - - -void BookmarksPanel::deleteBookmark() -{ - QModelIndex index = panelTreeView()->currentIndex(); - if (_loadingState || !index.isValid()) - return; - - BookmarkManager::self()->owner()->deleteBookmark(bookmarkForIndex(index)); -} - - -void BookmarksPanel::onCollapse(const QModelIndex &index) -{ - if (_loadingState) - return; - - bookmarkForIndex(index).internalElement().setAttribute("folded", "yes"); - emit expansionChanged(); -} - - -void BookmarksPanel::onExpand(const QModelIndex &index) +BookmarksPanel::BookmarksPanel(QWidget *parent) : QTreeView(parent) { - if (_loadingState) - return; - - bookmarkForIndex(index).internalElement().setAttribute("folded", "no"); - emit expansionChanged(); -} - - -void BookmarksPanel::setup() -{ - UrlPanel::setup(); - - connect(panelTreeView(), SIGNAL(delKeyPressed()), this, SLOT(deleteBookmark())); - connect(panelTreeView(), SIGNAL(collapsed(QModelIndex)), this, SLOT(onCollapse(QModelIndex))); - connect(panelTreeView(), SIGNAL(expanded(QModelIndex)), this, SLOT(onExpand(QModelIndex))); - - loadFoldedState(); + connect(this, &QTreeView::activated, this, [this](const QModelIndex &index) { + auto *item = model()->item(index); + const auto url = item->data(BookmarksTreeItem::Href).toUrl(); + emit loadUrl(url, rekonq::CurrentTab); + }); } - -void BookmarksPanel::loadFoldedState(const QModelIndex &root) -{ - QAbstractItemModel *model = panelTreeView()->model(); - if (!model) - return; - - int count = model->rowCount(root); - QModelIndex index; - - for (int i = 0; i < count; ++i) - { - index = model->index(i, 0, root); - if (index.isValid()) - { - KBookmark bm = bookmarkForIndex(index); - if (bm.isGroup()) - { - panelTreeView()->setExpanded(index, bm.toGroup().isOpen()); - loadFoldedState(index); - } - } - } -} - - -KBookmark BookmarksPanel::bookmarkForIndex(const QModelIndex &index) -{ - if (!index.isValid()) - return KBookmark(); - - const UrlFilterProxyModel *proxyModel = static_cast(index.model()); - QModelIndex originalIndex = proxyModel->mapToSource(index); - - BtmItem *node = static_cast(originalIndex.internalPointer()); - return node->getBkm(); -} - - -QAbstractItemModel* BookmarksPanel::model() +BookmarkModel *BookmarksPanel::model() const { - return _bkTreeModel; + auto *m = qobject_cast(QTreeView::model()); + Q_CHECK_PTR(m); + return m; } diff --git a/src/panels/bookmarkspanel.h b/src/panels/bookmarkspanel.h deleted file mode 100644 index 8c827c65..00000000 --- a/src/panels/bookmarkspanel.h +++ /dev/null @@ -1,93 +0,0 @@ -/* ============================================================ -* -* This file is a part of the rekonq project -* -* Copyright (C) 2009 by Nils Weigel -* Copyright (C) 2010-2013 by Andrea Diamantini -* Copyright (C) 2010 by Yoann Laissus -* -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License as -* published by the Free Software Foundation; either version 2 of -* the License or (at your option) version 3 or any later version -* accepted by the membership of KDE e.V. (or its successor approved -* by the membership of KDE e.V.), which shall act as a proxy -* defined in Section 14 of version 3 of the license. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program. If not, see . -* -* ============================================================ */ - - -#ifndef BOOKMARKS_PANEL_H -#define BOOKMARKS_PANEL_H - - -// Rekonq Includes -#include "rekonq_defines.h" - -// Local Includes -#include "urlpanel.h" - -// Forward Declarations -class BookmarksTreeModel; - -class KBookmark; -class QModelIndex; - - -class REKONQ_TESTS_EXPORT BookmarksPanel : public UrlPanel -{ - Q_OBJECT - -public: - explicit BookmarksPanel(const QString &title, QWidget *parent = 0, Qt::WindowFlags flags = 0); - ~BookmarksPanel(); - -public Q_SLOTS: - void loadFoldedState(); - -Q_SIGNALS: - void expansionChanged(); - -private Q_SLOTS: - void contextMenu(const QPoint &pos); - - virtual void contextMenuItem(const QPoint &pos) - { - contextMenu(pos); - } - virtual void contextMenuGroup(const QPoint &pos) - { - contextMenu(pos); - } - virtual void contextMenuEmpty(const QPoint &pos) - { - contextMenu(pos); - } - - void deleteBookmark(); - void onCollapse(const QModelIndex &index); - void onExpand(const QModelIndex &index); - -private: - virtual void setup(); - - void loadFoldedState(const QModelIndex &root); - - KBookmark bookmarkForIndex(const QModelIndex &index); - - virtual QAbstractItemModel* model(); - - BookmarksTreeModel *_bkTreeModel; - bool _loadingState; -}; - -#endif // BOOKMARKS_PANEL_H diff --git a/src/panels/bookmarkspanel.hpp b/src/panels/bookmarkspanel.hpp new file mode 100644 index 00000000..5961af7d --- /dev/null +++ b/src/panels/bookmarkspanel.hpp @@ -0,0 +1,27 @@ +/* ============================================================ + * The rekonq project + * ============================================================ + * SPDX-License-Identifier: GPL-3.0-only + * Copyright (C) 2022 aqua + * ============================================================ */ + +#pragma once + +#include "rekonq.hpp" +#include + +class BookmarkModel; + +class BookmarksPanel : public QTreeView { + Q_OBJECT + +public: + explicit BookmarksPanel(QWidget *parent = nullptr); + ~BookmarksPanel() = default; + +signals: + void loadUrl(const QUrl &url, rekonq::OpenType type); + +private: + [[nodiscard]] BookmarkModel *model() const; +}; diff --git a/src/rekonq.kcfg b/src/rekonq.kcfg index 7776a0b1..52a5d657 100644 --- a/src/rekonq.kcfg +++ b/src/rekonq.kcfg @@ -95,7 +95,7 @@ - + Ctrl+B diff --git a/src/rekonqwindow.cpp b/src/rekonqwindow.cpp index f9f26186..461de12e 100644 --- a/src/rekonqwindow.cpp +++ b/src/rekonqwindow.cpp @@ -90,31 +90,6 @@ void RekonqWindow::loadUrl(const QUrl &url, rekonq::OpenType type) // -------------------------------------------------------------------------------------------------- /* -void RekonqWindow::showBookmarksPanel(bool on) -{ - if (on) - { - if (_bookmarksPanel.isNull()) - { - _bookmarksPanel = new BookmarksPanel(i18n("Bookmarks Panel"), this); - connect(_bookmarksPanel.data(), SIGNAL(openUrl(KUrl,Rekonq::OpenType)), this, -SLOT(loadUrl(KUrl,Rekonq::OpenType))); - - QAction *a = _tabWidget->actionByName(QL1S("show_bookmarks_panel")); - connect(_bookmarksPanel.data(), SIGNAL(visibilityChanged(bool)), a, SLOT(setChecked(bool))); - } - _splitter->insertWidget(0, _bookmarksPanel.data()); - _bookmarksPanel.data()->show(); - } - else - { - _bookmarksPanel.data()->hide(); - delete _bookmarksPanel.data(); - _bookmarksPanel.clear(); - } -} - - void RekonqWindow::showHistoryPanel(bool on) { if (on) diff --git a/src/rekonqwindow.hpp b/src/rekonqwindow.hpp index 849bdff9..04287a90 100644 --- a/src/rekonqwindow.hpp +++ b/src/rekonqwindow.hpp @@ -39,12 +39,9 @@ public slots: // void loadUrl(const KUrl &, Rekonq::OpenType type = Rekonq::CurrentTab, TabHistory *history = 0); private slots: - // void showBookmarksPanel(bool); + void showBookmarksPanel(bool); // void showHistoryPanel(bool); private: Ui::RekonqWindow *ui; - - // QWeakPointer _historyPanel; - // QWeakPointer _bookmarksPanel; }; diff --git a/src/rekonqwindow.ui b/src/rekonqwindow.ui index b16fe187..64e1a517 100644 --- a/src/rekonqwindow.ui +++ b/src/rekonqwindow.ui @@ -110,7 +110,39 @@ - + + + + 0 + 0 + + + + Qt::Horizontal + + + + + 0 + 0 + + + + + 400 + 16777215 + + + + + + + 0 + 0 + + + + @@ -120,7 +152,7 @@ 0 0 800 - 30 + 22 @@ -152,6 +184,7 @@ Bookmarks + @@ -211,6 +244,17 @@ Close Tab + + + true + + + true + + + Show Bookmarks Panel + + @@ -224,6 +268,11 @@
tabbar/tabbar.h
1
+ + BookmarksPanel + QTreeView +
panels/bookmarkspanel.hpp
+
diff --git a/src/rekonqwindow_class.cpp b/src/rekonqwindow_class.cpp index 037abf9a..c83fd3ae 100644 --- a/src/rekonqwindow_class.cpp +++ b/src/rekonqwindow_class.cpp @@ -28,6 +28,12 @@ RekonqWindow::RekonqWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::Re { ui->setupUi(this); +#ifndef REKONQ_TEST + ui->bookmarksPanel->setModel(Application::instance()->bookmarks()); +#endif + connect(ui->bookmarksPanel, &BookmarksPanel::loadUrl, this, + qOverload(&RekonqWindow::loadUrl)); + connect(ui->tabs, &TabBar::currentChanged, this, [this](RekonqView *view) { if (view == nullptr) { // last tab has been closed close(); @@ -70,6 +76,7 @@ RekonqWindow::RekonqWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::Re // view menu // history menu // bookmarks menu + connect(ui->actionShowBookmarksPanel, &QAction::triggered, this, &RekonqWindow::showBookmarksPanel); // settings menu #ifndef REKONQ_TEST connect(ui->actionSettings, &QAction::triggered, this, @@ -100,3 +107,5 @@ void RekonqWindow::setupShortcuts(RekonqSettings *settings) settings->endGroup(); } + +void RekonqWindow::showBookmarksPanel(bool on) { ui->bookmarksPanel->setVisible(on); } diff --git a/src/test/application_mock.hpp b/src/test/application_mock.hpp index edfaf0bc..7b3af1d1 100644 --- a/src/test/application_mock.hpp +++ b/src/test/application_mock.hpp @@ -11,6 +11,7 @@ public: ~FakeApplication() override = default; MOCK_METHOD(bool, registerPlugin, (const QString &), (override)); + MOCK_METHOD(QAbstractItemModel *, bookmarks, (), (const override)); MOCK_METHOD(RekonqWindow *, newWindow, (), (override)); MOCK_METHOD(RekonqView *, newView, (const QUrl &, RekonqWindow *), (override)); -- cgit v1.2.1