/* * 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 "bookmarkmodel.h" #include "editbookmarkdialog.h" #include "mainwindow/mainwindow.h" #include "subwindow/subwindow.h" #include "ui_bookmarksform.h" #include "webengine/webprofilemanager.h" #include "webengine/webview.h" #include #include #include #include inline void expandChildren(QTreeView *view, BookmarkModel *m_model, const QModelIndex &rootIndex) { 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(m_model->rowCount(idx) > 0) expandChildren(view, m_model, idx); } } 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) >> m_model; f.close(); } } else if(path.endsWith(".json")) { QFile f(path); if(f.open(QIODevice::ReadOnly | QIODevice::Text)) { BookmarkFormat(&f) >> m_model; f.close(); } } view->setModel(m_model); expandChildren(view, m_model, QModelIndex()); } 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); m_model = new BookmarkModel(this); m_bookmarksPath = path; loadModel(path, m_model, ui->treeView); // 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) { m_model->setItemExpanded(index, true); }); connect(ui->treeView, &QTreeView::collapsed, this, [this](const QModelIndex &index) { 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 = m_model->data(idx, 1, Qt::DisplayRole).toUrl(); // get parent main window MainWindow *window = nullptr; for(QWidget *w = this; w != nullptr && window == nullptr; w = w->parentWidget()) { window = qobject_cast(w); } if(window == nullptr) return; auto *subwindow = window->currentSubWindow(); if(subwindow == nullptr) return; auto *menu = new QMenu(this); menu->addAction(tr("Open link in current tab"), subwindow, [url, subwindow]() { subwindow->currentView()->load(url); }); auto *openInCurrentTabWithProfile = menu->addMenu(tr("Open link in current tab with profile")); profileMenu(openInCurrentTabWithProfile, [url, subwindow](WebProfile *profile) { subwindow->currentView()->setProfile(profile); subwindow->currentView()->load(url); }); menu->addAction(tr("Open link in new tab"), subwindow, [url, subwindow]() { subwindow->addTab(url); }); auto *openInNewTabWithProfile = menu->addMenu(tr("Open link in new tab with profile")); profileMenu(openInNewTabWithProfile, [url, subwindow](WebProfile *profile) { subwindow->addTab(url, profile); }); menu->addSeparator(); menu->addAction(tr("Clear selection"), this, [this]() { ui->treeView->setCurrentIndex(QModelIndex()); ui->treeView->clearSelection(); }); menu->exec(ui->treeView->viewport()->mapToGlobal(pos)); } }); // addBookmark connect(ui->addBookmark_toolButton, &QToolButton::clicked, this, [this]() { 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 = m_model->parentFolder(ui->treeView->currentIndex()); const QModelIndex childIdx = m_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(); m_model->removeRow(idx.row(), idx.parent()); }); // import button connect(ui->import_toolButton, &QToolButton::clicked, this, [this]() { const auto import_path = QFileDialog::getOpenFileName(this, tr("Open bookmarks file"), QDir::homePath(), tr("Firefox bookmarks backup (*.json)")); if(!import_path.isEmpty()) { loadModel(import_path, m_model, ui->treeView); } }); } BookmarksWidget::~BookmarksWidget() { delete ui; } void BookmarksWidget::editBookmark(const QModelIndex &index) { auto *dlg = new EditBookmarkDialog(m_model, index, this); dlg->exec(); } void BookmarksWidget::save() { if(!m_model->isModified()) return; QFile bookmarksFile(m_bookmarksPath); if(bookmarksFile.open(QIODevice::WriteOnly | QIODevice::Text)) { BookmarkFormat f(&bookmarksFile); m_model >> f; bookmarksFile.flush(); } } void BookmarksWidget::addBookmark(const QString &title, const QString &url) { m_model->appendBookmark(title, url, QModelIndex()); } void BookmarksWidget::search(const QString &term, const std::function &callback) const { QStringList ret = m_model->search(term); callback(ret); }