2021-05-24 07:25:56 +00:00
|
|
|
/*
|
|
|
|
SPDX-FileCopyrightText: 2006 Pino Toscano <pino@kde.org>
|
|
|
|
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
*/
|
2006-12-27 16:04:49 +00:00
|
|
|
|
2007-04-19 18:30:20 +00:00
|
|
|
#include "bookmarklist.h"
|
|
|
|
|
2006-12-27 16:04:49 +00:00
|
|
|
// qt/kde includes
|
2020-07-08 11:54:37 +00:00
|
|
|
#include <QAction>
|
|
|
|
#include <QCursor>
|
2018-08-17 18:05:01 +00:00
|
|
|
#include <QDebug>
|
2020-07-08 11:54:37 +00:00
|
|
|
#include <QHeaderView>
|
2014-10-06 06:31:17 +00:00
|
|
|
#include <QIcon>
|
2020-07-08 11:54:37 +00:00
|
|
|
#include <QLayout>
|
2016-07-17 00:28:57 +00:00
|
|
|
#include <QMenu>
|
2020-07-08 11:54:37 +00:00
|
|
|
#include <QToolBar>
|
|
|
|
#include <QTreeWidget>
|
2006-12-27 16:04:49 +00:00
|
|
|
|
2014-10-19 13:20:30 +00:00
|
|
|
#include <KLocalizedString>
|
Improve the sidebar's navigation and UX
Okular's sidebar vertical view chooser toolbar suffers from a few issues:
* It's a nonstandard UI not used for category choosers in other pieces of KDE software,
and not used in other FOSS document readers
* What is shown and what is hidden is simultaneously too configurable while still not
offering the desirable UI common to other programs (i.e. no visible category chooser,
but a sidebar capable of displaying thumbnails, table of contents, search results, etc.)
* With labels on it takes up quite a bit of horizontal space, while with labels off, the
categories are less than clear
* UX is kind of clunky with nonstandard behaviors (e.g. clicking on the current category
to hide that category's view while keeping the view chooser visible, showing mostly
disabled items)
* It's made with custom painting code, which reduces maintainability and introduces bugs
(e.g. https://bugs.kde.org/show_bug.cgi?id=408190)
This patch removes the vertical category chooser entirely and replaces it with a tabbed
view on the top of the sidebar itself. The tabs are icons-only and have large icons. A
button is added on the left side of the default toolbar to quickly hide or show the
sidebar. In order to make room for the new button, the Previous and Next buttons on the
toolbar are removed, as previous/next buttons are already present on the Page Bar on the
bottom of the window so there's no need to duplicate this functionality. This improves
the UX, fixes a variety of bugs, and deletes a lot of custom code of dubious long-term
maintainability.
![vokoscreenNG-2020-04-16_13-29-24](https://invent.kde.org/graphics/okular/uploads/a1f96a315b69282df51de9993b1befaf/vokoscreenNG-2020-04-16_13-29-24.webm)
BUG: 213508
BUG: 334441
BUG: 344599
BUG: 408190
CCBUG: 335189
FIXED-IN: 1.11.0
CHANGELOG: The sidebar can now be easily shown or hidden with a toolbar button, and the category chooser no longer takes up so much space
2020-05-27 13:37:42 +00:00
|
|
|
#include <KTitleWidget>
|
2016-07-17 00:28:57 +00:00
|
|
|
#include <KTreeWidgetSearchLine>
|
2006-12-27 16:04:49 +00:00
|
|
|
|
Improve the sidebar's navigation and UX
Okular's sidebar vertical view chooser toolbar suffers from a few issues:
* It's a nonstandard UI not used for category choosers in other pieces of KDE software,
and not used in other FOSS document readers
* What is shown and what is hidden is simultaneously too configurable while still not
offering the desirable UI common to other programs (i.e. no visible category chooser,
but a sidebar capable of displaying thumbnails, table of contents, search results, etc.)
* With labels on it takes up quite a bit of horizontal space, while with labels off, the
categories are less than clear
* UX is kind of clunky with nonstandard behaviors (e.g. clicking on the current category
to hide that category's view while keeping the view chooser visible, showing mostly
disabled items)
* It's made with custom painting code, which reduces maintainability and introduces bugs
(e.g. https://bugs.kde.org/show_bug.cgi?id=408190)
This patch removes the vertical category chooser entirely and replaces it with a tabbed
view on the top of the sidebar itself. The tabs are icons-only and have large icons. A
button is added on the left side of the default toolbar to quickly hide or show the
sidebar. In order to make room for the new button, the Previous and Next buttons on the
toolbar are removed, as previous/next buttons are already present on the Page Bar on the
bottom of the window so there's no need to duplicate this functionality. This improves
the UX, fixes a variety of bugs, and deletes a lot of custom code of dubious long-term
maintainability.
![vokoscreenNG-2020-04-16_13-29-24](https://invent.kde.org/graphics/okular/uploads/a1f96a315b69282df51de9993b1befaf/vokoscreenNG-2020-04-16_13-29-24.webm)
BUG: 213508
BUG: 334441
BUG: 344599
BUG: 408190
CCBUG: 335189
FIXED-IN: 1.11.0
CHANGELOG: The sidebar can now be easily shown or hidden with a toolbar button, and the category chooser no longer takes up so much space
2020-05-27 13:37:42 +00:00
|
|
|
#include <kwidgetsaddons_version.h>
|
|
|
|
|
2007-05-21 19:53:13 +00:00
|
|
|
#include "core/action.h"
|
2006-12-27 16:04:49 +00:00
|
|
|
#include "core/bookmarkmanager.h"
|
|
|
|
#include "core/document.h"
|
|
|
|
#include "pageitemdelegate.h"
|
|
|
|
|
2006-12-31 11:20:33 +00:00
|
|
|
static const int BookmarkItemType = QTreeWidgetItem::UserType + 1;
|
|
|
|
static const int FileItemType = QTreeWidgetItem::UserType + 2;
|
2008-04-04 10:04:03 +00:00
|
|
|
static const int UrlRole = Qt::UserRole + 1;
|
2006-12-31 11:20:33 +00:00
|
|
|
|
2006-12-27 16:04:49 +00:00
|
|
|
class BookmarkItem : public QTreeWidgetItem
|
|
|
|
{
|
|
|
|
public:
|
2021-08-21 23:14:34 +00:00
|
|
|
explicit BookmarkItem(const KBookmark &bm)
|
2006-12-31 11:20:33 +00:00
|
|
|
: QTreeWidgetItem(BookmarkItemType)
|
|
|
|
, m_bookmark(bm)
|
2006-12-27 16:04:49 +00:00
|
|
|
{
|
|
|
|
setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
|
|
|
|
m_url = m_bookmark.url();
|
2015-01-29 19:55:57 +00:00
|
|
|
m_viewport = Okular::DocumentViewport(m_url.fragment(QUrl::FullyDecoded));
|
|
|
|
m_url.setFragment(QString());
|
2006-12-27 16:04:49 +00:00
|
|
|
setText(0, m_bookmark.fullText());
|
|
|
|
if (m_viewport.isValid())
|
|
|
|
setData(0, PageItemDelegate::PageRole, QString::number(m_viewport.pageNumber + 1));
|
|
|
|
}
|
|
|
|
|
2020-02-21 15:11:42 +00:00
|
|
|
BookmarkItem(const BookmarkItem &) = delete;
|
|
|
|
BookmarkItem &operator=(const BookmarkItem &) = delete;
|
|
|
|
|
2016-10-29 14:38:19 +00:00
|
|
|
QVariant data(int column, int role) const override
|
2008-03-31 23:03:50 +00:00
|
|
|
{
|
|
|
|
switch (role) {
|
|
|
|
case Qt::ToolTipRole:
|
|
|
|
return m_bookmark.fullText();
|
|
|
|
}
|
|
|
|
return QTreeWidgetItem::data(column, role);
|
2020-07-10 22:15:05 +00:00
|
|
|
}
|
2008-03-31 23:03:50 +00:00
|
|
|
|
2016-10-29 14:38:19 +00:00
|
|
|
bool operator<(const QTreeWidgetItem &other) const override
|
2009-05-23 13:03:45 +00:00
|
|
|
{
|
|
|
|
if (other.type() == BookmarkItemType) {
|
|
|
|
const BookmarkItem *cmp = static_cast<const BookmarkItem *>(&other);
|
2012-06-04 14:10:33 +00:00
|
|
|
return m_viewport < cmp->m_viewport;
|
2009-05-23 13:03:45 +00:00
|
|
|
}
|
|
|
|
return QTreeWidgetItem::operator<(other);
|
2020-07-10 22:15:05 +00:00
|
|
|
}
|
2009-05-23 13:03:45 +00:00
|
|
|
|
2007-08-28 15:02:39 +00:00
|
|
|
KBookmark &bookmark()
|
2006-12-27 16:04:49 +00:00
|
|
|
{
|
|
|
|
return m_bookmark;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Okular::DocumentViewport &viewport() const
|
|
|
|
{
|
|
|
|
return m_viewport;
|
|
|
|
}
|
|
|
|
|
2015-01-29 19:55:57 +00:00
|
|
|
QUrl url() const
|
2006-12-27 16:04:49 +00:00
|
|
|
{
|
|
|
|
return m_url;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
KBookmark m_bookmark;
|
2015-01-29 19:55:57 +00:00
|
|
|
QUrl m_url;
|
2006-12-27 16:04:49 +00:00
|
|
|
Okular::DocumentViewport m_viewport;
|
|
|
|
};
|
|
|
|
|
2010-01-09 12:06:44 +00:00
|
|
|
class FileItem : public QTreeWidgetItem
|
|
|
|
{
|
|
|
|
public:
|
2015-01-29 19:55:57 +00:00
|
|
|
FileItem(const QUrl &url, QTreeWidget *tree, Okular::Document *document)
|
2010-01-09 12:06:44 +00:00
|
|
|
: QTreeWidgetItem(tree, FileItemType)
|
|
|
|
{
|
2012-03-08 22:26:44 +00:00
|
|
|
setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
|
|
|
|
const QString fileString = document->bookmarkManager()->titleForUrl(url);
|
2010-01-09 12:06:44 +00:00
|
|
|
setText(0, fileString);
|
2019-09-18 11:41:19 +00:00
|
|
|
setData(0, UrlRole, QVariant::fromValue(url));
|
2010-01-09 12:06:44 +00:00
|
|
|
}
|
|
|
|
|
2020-02-21 15:11:42 +00:00
|
|
|
FileItem(const FileItem &) = delete;
|
|
|
|
FileItem &operator=(const FileItem &) = delete;
|
2020-07-10 22:15:05 +00:00
|
|
|
|
2016-10-29 14:38:19 +00:00
|
|
|
QVariant data(int column, int role) const override
|
2010-01-09 12:06:44 +00:00
|
|
|
{
|
|
|
|
switch (role) {
|
|
|
|
case Qt::ToolTipRole:
|
|
|
|
return i18ncp("%1 is the file name", "%1\n\nOne bookmark", "%1\n\n%2 bookmarks", text(0), childCount());
|
|
|
|
}
|
|
|
|
return QTreeWidgetItem::data(column, role);
|
2020-07-10 22:15:05 +00:00
|
|
|
}
|
2010-01-09 12:06:44 +00:00
|
|
|
};
|
|
|
|
|
2021-08-27 15:42:02 +00:00
|
|
|
BookmarkList::BookmarkList(Okular::Document *document, QAction *addBookmarkAction, QWidget *parent)
|
2017-09-05 21:27:18 +00:00
|
|
|
: QWidget(parent)
|
|
|
|
, m_document(document)
|
|
|
|
, m_currentDocumentItem(nullptr)
|
2006-12-27 16:04:49 +00:00
|
|
|
{
|
|
|
|
QVBoxLayout *mainlay = new QVBoxLayout(this);
|
2007-08-24 14:20:03 +00:00
|
|
|
mainlay->setSpacing(6);
|
2020-07-10 22:15:05 +00:00
|
|
|
|
Improve the sidebar's navigation and UX
Okular's sidebar vertical view chooser toolbar suffers from a few issues:
* It's a nonstandard UI not used for category choosers in other pieces of KDE software,
and not used in other FOSS document readers
* What is shown and what is hidden is simultaneously too configurable while still not
offering the desirable UI common to other programs (i.e. no visible category chooser,
but a sidebar capable of displaying thumbnails, table of contents, search results, etc.)
* With labels on it takes up quite a bit of horizontal space, while with labels off, the
categories are less than clear
* UX is kind of clunky with nonstandard behaviors (e.g. clicking on the current category
to hide that category's view while keeping the view chooser visible, showing mostly
disabled items)
* It's made with custom painting code, which reduces maintainability and introduces bugs
(e.g. https://bugs.kde.org/show_bug.cgi?id=408190)
This patch removes the vertical category chooser entirely and replaces it with a tabbed
view on the top of the sidebar itself. The tabs are icons-only and have large icons. A
button is added on the left side of the default toolbar to quickly hide or show the
sidebar. In order to make room for the new button, the Previous and Next buttons on the
toolbar are removed, as previous/next buttons are already present on the Page Bar on the
bottom of the window so there's no need to duplicate this functionality. This improves
the UX, fixes a variety of bugs, and deletes a lot of custom code of dubious long-term
maintainability.
![vokoscreenNG-2020-04-16_13-29-24](https://invent.kde.org/graphics/okular/uploads/a1f96a315b69282df51de9993b1befaf/vokoscreenNG-2020-04-16_13-29-24.webm)
BUG: 213508
BUG: 334441
BUG: 344599
BUG: 408190
CCBUG: 335189
FIXED-IN: 1.11.0
CHANGELOG: The sidebar can now be easily shown or hidden with a toolbar button, and the category chooser no longer takes up so much space
2020-05-27 13:37:42 +00:00
|
|
|
KTitleWidget *titleWidget = new KTitleWidget(this);
|
|
|
|
titleWidget->setLevel(2);
|
|
|
|
titleWidget->setText(i18n("Bookmarks"));
|
|
|
|
mainlay->addWidget(titleWidget);
|
|
|
|
mainlay->setAlignment(titleWidget, Qt::AlignHCenter);
|
2006-12-27 16:04:49 +00:00
|
|
|
m_searchLine = new KTreeWidgetSearchLine(this);
|
2007-08-24 14:20:03 +00:00
|
|
|
mainlay->addWidget(m_searchLine);
|
2019-01-21 14:26:02 +00:00
|
|
|
m_searchLine->setPlaceholderText(i18n("Search..."));
|
2020-07-10 22:15:05 +00:00
|
|
|
|
2006-12-27 16:04:49 +00:00
|
|
|
m_tree = new QTreeWidget(this);
|
|
|
|
mainlay->addWidget(m_tree);
|
|
|
|
QStringList cols;
|
2015-10-29 12:37:11 +00:00
|
|
|
cols.append(QStringLiteral("Bookmarks"));
|
2006-12-27 16:04:49 +00:00
|
|
|
m_tree->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
m_tree->setHeaderLabels(cols);
|
|
|
|
m_tree->setSortingEnabled(false);
|
|
|
|
m_tree->setRootIsDecorated(true);
|
|
|
|
m_tree->setAlternatingRowColors(true);
|
|
|
|
m_tree->setItemDelegate(new PageItemDelegate(m_tree));
|
|
|
|
m_tree->header()->hide();
|
|
|
|
m_tree->setSelectionBehavior(QAbstractItemView::SelectRows);
|
2007-05-18 22:26:03 +00:00
|
|
|
m_tree->setEditTriggers(QAbstractItemView::EditKeyPressed);
|
2014-10-01 17:40:48 +00:00
|
|
|
connect(m_tree, &QTreeWidget::itemActivated, this, &BookmarkList::slotExecuted);
|
|
|
|
connect(m_tree, &QTreeWidget::customContextMenuRequested, this, &BookmarkList::slotContextMenu);
|
2006-12-27 16:04:49 +00:00
|
|
|
m_searchLine->addTreeWidget(m_tree);
|
|
|
|
|
|
|
|
QToolBar *bookmarkController = new QToolBar(this);
|
|
|
|
mainlay->addWidget(bookmarkController);
|
2015-10-29 12:37:11 +00:00
|
|
|
bookmarkController->setObjectName(QStringLiteral("BookmarkControlBar"));
|
2006-12-27 16:04:49 +00:00
|
|
|
// change toolbar appearance
|
|
|
|
bookmarkController->setIconSize(QSize(16, 16));
|
|
|
|
bookmarkController->setMovable(false);
|
|
|
|
QSizePolicy sp = bookmarkController->sizePolicy();
|
|
|
|
sp.setVerticalPolicy(QSizePolicy::Minimum);
|
|
|
|
bookmarkController->setSizePolicy(sp);
|
|
|
|
// insert a togglebutton [show only bookmarks in the current document]
|
2015-10-29 12:37:11 +00:00
|
|
|
m_showBoomarkOnlyAction = bookmarkController->addAction(QIcon::fromTheme(QStringLiteral("bookmarks")), i18n("Current document only"));
|
2006-12-27 16:04:49 +00:00
|
|
|
m_showBoomarkOnlyAction->setCheckable(true);
|
2014-10-01 17:40:48 +00:00
|
|
|
connect(m_showBoomarkOnlyAction, &QAction::toggled, this, &BookmarkList::slotFilterBookmarks);
|
2021-08-27 15:42:02 +00:00
|
|
|
// insert a button to bookmark/un-bookmark the current page
|
|
|
|
bookmarkController->addAction(addBookmarkAction);
|
2006-12-27 16:04:49 +00:00
|
|
|
|
2015-10-29 12:37:11 +00:00
|
|
|
connect(m_document->bookmarkManager(), &Okular::BookmarkManager::bookmarksChanged, this, &BookmarkList::slotBookmarksChanged);
|
2008-04-04 10:04:03 +00:00
|
|
|
|
2007-08-28 15:02:39 +00:00
|
|
|
rebuildTree(m_showBoomarkOnlyAction->isChecked());
|
2006-12-27 16:04:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
BookmarkList::~BookmarkList()
|
|
|
|
{
|
2008-09-22 22:58:32 +00:00
|
|
|
m_document->removeObserver(this);
|
2006-12-27 16:04:49 +00:00
|
|
|
}
|
|
|
|
|
2007-09-09 10:50:36 +00:00
|
|
|
void BookmarkList::notifySetup(const QVector<Okular::Page *> &pages, int setupFlags)
|
2006-12-27 16:04:49 +00:00
|
|
|
{
|
2010-01-09 13:57:09 +00:00
|
|
|
Q_UNUSED(pages);
|
2014-05-11 15:38:30 +00:00
|
|
|
if (!(setupFlags & Okular::DocumentObserver::UrlChanged))
|
2006-12-27 16:04:49 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
// clear contents
|
|
|
|
m_searchLine->clear();
|
|
|
|
|
2008-04-04 10:20:57 +00:00
|
|
|
if (m_showBoomarkOnlyAction->isChecked()) {
|
|
|
|
rebuildTree(m_showBoomarkOnlyAction->isChecked());
|
|
|
|
} else {
|
2014-10-01 17:40:48 +00:00
|
|
|
disconnect(m_tree, &QTreeWidget::itemChanged, this, &BookmarkList::slotChanged);
|
2008-04-04 10:20:57 +00:00
|
|
|
if (m_currentDocumentItem && m_currentDocumentItem != m_tree->invisibleRootItem()) {
|
|
|
|
m_currentDocumentItem->setIcon(0, QIcon());
|
|
|
|
}
|
|
|
|
m_currentDocumentItem = itemForUrl(m_document->currentDocument());
|
|
|
|
if (m_currentDocumentItem && m_currentDocumentItem != m_tree->invisibleRootItem()) {
|
2015-10-29 12:37:11 +00:00
|
|
|
m_currentDocumentItem->setIcon(0, QIcon::fromTheme(QStringLiteral("bookmarks")));
|
2008-04-04 10:20:57 +00:00
|
|
|
m_currentDocumentItem->setExpanded(true);
|
|
|
|
}
|
2014-10-01 17:40:48 +00:00
|
|
|
connect(m_tree, &QTreeWidget::itemChanged, this, &BookmarkList::slotChanged);
|
2008-04-04 10:20:57 +00:00
|
|
|
}
|
2006-12-27 16:04:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void BookmarkList::slotFilterBookmarks(bool on)
|
|
|
|
{
|
|
|
|
rebuildTree(on);
|
|
|
|
}
|
|
|
|
|
|
|
|
void BookmarkList::slotExecuted(QTreeWidgetItem *item)
|
|
|
|
{
|
|
|
|
BookmarkItem *bmItem = dynamic_cast<BookmarkItem *>(item);
|
|
|
|
if (!bmItem || !bmItem->viewport().isValid())
|
|
|
|
return;
|
|
|
|
|
|
|
|
goTo(bmItem);
|
|
|
|
}
|
|
|
|
|
|
|
|
void BookmarkList::slotChanged(QTreeWidgetItem *item)
|
|
|
|
{
|
|
|
|
BookmarkItem *bmItem = dynamic_cast<BookmarkItem *>(item);
|
2012-03-08 22:26:44 +00:00
|
|
|
if (bmItem && bmItem->viewport().isValid()) {
|
|
|
|
bmItem->bookmark().setFullText(bmItem->text(0));
|
|
|
|
m_document->bookmarkManager()->save();
|
|
|
|
}
|
2006-12-27 16:04:49 +00:00
|
|
|
|
2012-03-08 22:26:44 +00:00
|
|
|
FileItem *fItem = dynamic_cast<FileItem *>(item);
|
|
|
|
if (fItem) {
|
2015-01-29 19:55:57 +00:00
|
|
|
const QUrl url = fItem->data(0, UrlRole).value<QUrl>();
|
2012-05-23 15:30:41 +00:00
|
|
|
m_document->bookmarkManager()->renameBookmark(url, fItem->text(0));
|
2012-03-08 22:26:44 +00:00
|
|
|
m_document->bookmarkManager()->save();
|
|
|
|
}
|
2006-12-27 16:04:49 +00:00
|
|
|
}
|
|
|
|
|
2020-02-20 17:45:46 +00:00
|
|
|
void BookmarkList::slotContextMenu(const QPoint p)
|
2006-12-27 16:04:49 +00:00
|
|
|
{
|
|
|
|
QTreeWidgetItem *item = m_tree->itemAt(p);
|
2017-09-05 21:27:18 +00:00
|
|
|
BookmarkItem *bmItem = item ? dynamic_cast<BookmarkItem *>(item) : nullptr;
|
2010-01-09 11:10:08 +00:00
|
|
|
if (bmItem)
|
|
|
|
contextMenuForBookmarkItem(p, bmItem);
|
2010-01-09 13:15:33 +00:00
|
|
|
else if (FileItem *fItem = dynamic_cast<FileItem *>(item))
|
|
|
|
contextMenuForFileItem(p, fItem);
|
2010-01-09 11:10:08 +00:00
|
|
|
}
|
|
|
|
|
2020-02-20 17:45:46 +00:00
|
|
|
void BookmarkList::contextMenuForBookmarkItem(const QPoint p, BookmarkItem *bmItem)
|
2010-01-09 11:10:08 +00:00
|
|
|
{
|
2010-01-09 13:57:09 +00:00
|
|
|
Q_UNUSED(p);
|
2006-12-27 16:04:49 +00:00
|
|
|
if (!bmItem || !bmItem->viewport().isValid())
|
|
|
|
return;
|
|
|
|
|
2014-08-13 10:45:40 +00:00
|
|
|
QMenu menu(this);
|
2006-12-27 16:04:49 +00:00
|
|
|
QAction *gotobm = menu.addAction(i18n("Go to This Bookmark"));
|
2015-10-29 12:37:11 +00:00
|
|
|
QAction *editbm = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-rename")), i18n("Rename Bookmark"));
|
|
|
|
QAction *removebm = menu.addAction(QIcon::fromTheme(QStringLiteral("list-remove")), i18n("Remove Bookmark"));
|
2006-12-27 16:04:49 +00:00
|
|
|
QAction *res = menu.exec(QCursor::pos());
|
|
|
|
if (!res)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (res == gotobm)
|
|
|
|
goTo(bmItem);
|
|
|
|
else if (res == editbm)
|
2010-01-09 11:10:08 +00:00
|
|
|
m_tree->editItem(bmItem, 0);
|
2006-12-27 16:04:49 +00:00
|
|
|
else if (res == removebm)
|
2007-10-28 18:31:33 +00:00
|
|
|
m_document->bookmarkManager()->removeBookmark(bmItem->url(), bmItem->bookmark());
|
2006-12-27 16:04:49 +00:00
|
|
|
}
|
|
|
|
|
2020-02-20 17:45:46 +00:00
|
|
|
void BookmarkList::contextMenuForFileItem(const QPoint p, FileItem *fItem)
|
2010-01-09 13:15:33 +00:00
|
|
|
{
|
2010-01-09 13:57:09 +00:00
|
|
|
Q_UNUSED(p);
|
2010-01-09 13:15:33 +00:00
|
|
|
if (!fItem)
|
|
|
|
return;
|
|
|
|
|
2015-01-29 19:55:57 +00:00
|
|
|
const QUrl itemurl = fItem->data(0, UrlRole).value<QUrl>();
|
2010-01-09 13:15:33 +00:00
|
|
|
const bool thisdoc = itemurl == m_document->currentDocument();
|
|
|
|
|
2014-08-13 10:45:40 +00:00
|
|
|
QMenu menu(this);
|
2017-09-05 21:27:18 +00:00
|
|
|
QAction *open = nullptr;
|
2010-01-09 13:15:33 +00:00
|
|
|
if (!thisdoc)
|
|
|
|
open = menu.addAction(i18nc("Opens the selected document", "Open Document"));
|
2015-10-29 12:37:11 +00:00
|
|
|
QAction *editbm = menu.addAction(QIcon::fromTheme(QStringLiteral("edit-rename")), i18n("Rename Bookmark"));
|
|
|
|
QAction *removebm = menu.addAction(QIcon::fromTheme(QStringLiteral("list-remove")), i18n("Remove Bookmarks"));
|
2010-01-09 13:15:33 +00:00
|
|
|
QAction *res = menu.exec(QCursor::pos());
|
|
|
|
if (!res)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (res == open) {
|
2015-01-29 19:55:57 +00:00
|
|
|
Okular::GotoAction action(itemurl.toDisplayString(QUrl::PreferLocalFile), Okular::DocumentViewport());
|
2010-01-09 13:15:33 +00:00
|
|
|
m_document->processAction(&action);
|
2012-03-08 22:26:44 +00:00
|
|
|
} else if (res == editbm)
|
|
|
|
m_tree->editItem(fItem, 0);
|
2010-01-09 13:15:33 +00:00
|
|
|
else if (res == removebm) {
|
|
|
|
KBookmark::List list;
|
|
|
|
for (int i = 0; i < fItem->childCount(); ++i) {
|
|
|
|
list.append(static_cast<BookmarkItem *>(fItem->child(i))->bookmark());
|
|
|
|
}
|
|
|
|
m_document->bookmarkManager()->removeBookmarks(itemurl, list);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-29 19:55:57 +00:00
|
|
|
void BookmarkList::slotBookmarksChanged(const QUrl &url)
|
2008-04-04 10:04:03 +00:00
|
|
|
{
|
|
|
|
// special case here, as m_currentDocumentItem could represent
|
|
|
|
// the invisible root item
|
|
|
|
if (url == m_document->currentDocument()) {
|
|
|
|
selectiveUrlUpdate(m_document->currentDocument(), m_currentDocumentItem);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// we are showing the bookmarks for the current document only
|
|
|
|
if (m_showBoomarkOnlyAction->isChecked())
|
|
|
|
return;
|
|
|
|
|
2008-04-04 10:19:12 +00:00
|
|
|
QTreeWidgetItem *item = itemForUrl(url);
|
2009-12-26 18:19:07 +00:00
|
|
|
selectiveUrlUpdate(url, item);
|
2008-04-04 10:04:03 +00:00
|
|
|
}
|
|
|
|
|
2015-01-29 19:55:57 +00:00
|
|
|
QList<QTreeWidgetItem *> createItems(const QUrl &baseurl, const KBookmark::List &bmlist)
|
2006-12-27 16:04:49 +00:00
|
|
|
{
|
2015-01-29 19:55:57 +00:00
|
|
|
Q_UNUSED(baseurl)
|
2006-12-27 16:04:49 +00:00
|
|
|
QList<QTreeWidgetItem *> ret;
|
2019-12-09 13:39:47 +00:00
|
|
|
for (const KBookmark &bm : bmlist) {
|
2014-09-11 17:36:01 +00:00
|
|
|
// qCDebug(OkularUiDebug).nospace() << "checking '" << tmp << "'";
|
|
|
|
// qCDebug(OkularUiDebug).nospace() << " vs '" << baseurl << "'";
|
2006-12-27 16:04:49 +00:00
|
|
|
// TODO check that bm and baseurl are the same (#ref excluded)
|
|
|
|
QTreeWidgetItem *item = new BookmarkItem(bm);
|
|
|
|
ret.append(item);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void BookmarkList::rebuildTree(bool filter)
|
|
|
|
{
|
2007-05-01 14:51:55 +00:00
|
|
|
// disconnect and reconnect later, otherwise we'll get many itemChanged()
|
|
|
|
// signals for all the current items
|
2014-10-01 17:40:48 +00:00
|
|
|
disconnect(m_tree, &QTreeWidget::itemChanged, this, &BookmarkList::slotChanged);
|
2007-05-01 14:51:55 +00:00
|
|
|
|
2017-09-05 21:27:18 +00:00
|
|
|
m_currentDocumentItem = nullptr;
|
2007-08-28 15:02:39 +00:00
|
|
|
m_tree->clear();
|
|
|
|
|
2019-12-09 13:39:47 +00:00
|
|
|
const QList<QUrl> urls = m_document->bookmarkManager()->files();
|
2006-12-27 16:04:49 +00:00
|
|
|
if (filter) {
|
2007-08-28 15:02:39 +00:00
|
|
|
if (m_document->isOpened()) {
|
2019-12-09 13:39:47 +00:00
|
|
|
for (const QUrl &url : urls) {
|
2006-12-27 16:04:49 +00:00
|
|
|
if (url == m_document->currentDocument()) {
|
|
|
|
m_tree->addTopLevelItems(createItems(url, m_document->bookmarkManager()->bookmarks(url)));
|
2008-04-04 10:04:03 +00:00
|
|
|
m_currentDocumentItem = m_tree->invisibleRootItem();
|
2006-12-27 16:04:49 +00:00
|
|
|
break;
|
2020-07-10 22:15:05 +00:00
|
|
|
}
|
2006-12-27 16:04:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2017-09-05 21:27:18 +00:00
|
|
|
QTreeWidgetItem *currenturlitem = nullptr;
|
2019-12-09 13:39:47 +00:00
|
|
|
for (const QUrl &url : urls) {
|
2007-05-19 22:19:24 +00:00
|
|
|
QList<QTreeWidgetItem *> subitems = createItems(url, m_document->bookmarkManager()->bookmarks(url));
|
|
|
|
if (!subitems.isEmpty()) {
|
2012-03-08 22:26:44 +00:00
|
|
|
FileItem *item = new FileItem(url, m_tree, m_document);
|
2007-05-19 22:19:24 +00:00
|
|
|
item->addChildren(subitems);
|
|
|
|
if (!currenturlitem && url == m_document->currentDocument()) {
|
|
|
|
currenturlitem = item;
|
|
|
|
}
|
2006-12-27 16:04:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (currenturlitem) {
|
|
|
|
currenturlitem->setExpanded(true);
|
2015-10-29 12:37:11 +00:00
|
|
|
currenturlitem->setIcon(0, QIcon::fromTheme(QStringLiteral("bookmarks")));
|
2006-12-27 16:04:49 +00:00
|
|
|
m_tree->scrollToItem(currenturlitem, QAbstractItemView::PositionAtTop);
|
2008-04-04 10:04:03 +00:00
|
|
|
m_currentDocumentItem = currenturlitem;
|
2006-12-27 16:04:49 +00:00
|
|
|
}
|
|
|
|
}
|
2007-05-01 14:51:55 +00:00
|
|
|
|
2009-05-23 13:03:45 +00:00
|
|
|
m_tree->sortItems(0, Qt::AscendingOrder);
|
|
|
|
|
2014-10-01 17:40:48 +00:00
|
|
|
connect(m_tree, &QTreeWidget::itemChanged, this, &BookmarkList::slotChanged);
|
2006-12-27 16:04:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void BookmarkList::goTo(BookmarkItem *item)
|
|
|
|
{
|
|
|
|
if (item->url() == m_document->currentDocument()) {
|
2019-11-15 16:08:25 +00:00
|
|
|
m_document->setViewport(item->viewport(), nullptr, true);
|
2006-12-27 16:04:49 +00:00
|
|
|
} else {
|
2015-01-29 19:55:57 +00:00
|
|
|
Okular::GotoAction action(item->url().toDisplayString(QUrl::PreferLocalFile), item->viewport());
|
2007-05-21 19:53:13 +00:00
|
|
|
m_document->processAction(&action);
|
2006-12-27 16:04:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-29 19:55:57 +00:00
|
|
|
void BookmarkList::selectiveUrlUpdate(const QUrl &url, QTreeWidgetItem *&item)
|
2008-04-04 10:04:03 +00:00
|
|
|
{
|
2014-10-01 17:40:48 +00:00
|
|
|
disconnect(m_tree, &QTreeWidget::itemChanged, this, &BookmarkList::slotChanged);
|
2008-04-04 10:29:06 +00:00
|
|
|
|
2008-04-04 10:04:03 +00:00
|
|
|
const KBookmark::List urlbookmarks = m_document->bookmarkManager()->bookmarks(url);
|
|
|
|
if (urlbookmarks.isEmpty()) {
|
|
|
|
if (item != m_tree->invisibleRootItem()) {
|
|
|
|
m_tree->invisibleRootItem()->removeChild(item);
|
2017-09-05 21:27:18 +00:00
|
|
|
item = nullptr;
|
2008-04-04 10:04:03 +00:00
|
|
|
} else if (item) {
|
|
|
|
for (int i = item->childCount(); i >= 0; --i) {
|
|
|
|
item->removeChild(item->child(i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2010-05-22 17:19:36 +00:00
|
|
|
bool fileitem_created = false;
|
|
|
|
|
2008-04-04 10:04:03 +00:00
|
|
|
if (item) {
|
2009-12-26 18:19:07 +00:00
|
|
|
for (int i = item->childCount() - 1; i >= 0; --i) {
|
2008-04-04 10:04:03 +00:00
|
|
|
item->removeChild(item->child(i));
|
|
|
|
}
|
|
|
|
} else {
|
2012-03-08 22:26:44 +00:00
|
|
|
item = new FileItem(url, m_tree, m_document);
|
2010-05-22 17:19:36 +00:00
|
|
|
fileitem_created = true;
|
2009-12-26 18:19:07 +00:00
|
|
|
}
|
|
|
|
if (m_document->isOpened() && url == m_document->currentDocument()) {
|
2015-10-29 12:37:11 +00:00
|
|
|
item->setIcon(0, QIcon::fromTheme(QStringLiteral("bookmarks")));
|
2008-04-04 10:04:03 +00:00
|
|
|
item->setExpanded(true);
|
|
|
|
}
|
|
|
|
item->addChildren(createItems(url, urlbookmarks));
|
2010-05-22 17:19:36 +00:00
|
|
|
|
|
|
|
if (fileitem_created) {
|
|
|
|
// we need to sort also the parent of the new file item,
|
|
|
|
// so it can be properly shown in the correct place
|
|
|
|
m_tree->invisibleRootItem()->sortChildren(0, Qt::AscendingOrder);
|
|
|
|
}
|
|
|
|
item->sortChildren(0, Qt::AscendingOrder);
|
2008-04-04 10:04:03 +00:00
|
|
|
}
|
2008-04-04 10:29:06 +00:00
|
|
|
|
2014-10-01 17:40:48 +00:00
|
|
|
connect(m_tree, &QTreeWidget::itemChanged, this, &BookmarkList::slotChanged);
|
2008-04-04 10:04:03 +00:00
|
|
|
}
|
2006-12-27 16:04:49 +00:00
|
|
|
|
2015-01-29 19:55:57 +00:00
|
|
|
QTreeWidgetItem *BookmarkList::itemForUrl(const QUrl &url) const
|
2008-04-04 10:19:12 +00:00
|
|
|
{
|
|
|
|
const int count = m_tree->topLevelItemCount();
|
|
|
|
for (int i = 0; i < count; ++i) {
|
|
|
|
QTreeWidgetItem *item = m_tree->topLevelItem(i);
|
2015-01-29 19:55:57 +00:00
|
|
|
const QUrl itemurl = item->data(0, UrlRole).value<QUrl>();
|
2008-04-04 10:19:12 +00:00
|
|
|
if (itemurl.isValid() && itemurl == url) {
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
}
|
2017-09-05 21:27:18 +00:00
|
|
|
return nullptr;
|
2008-04-04 10:19:12 +00:00
|
|
|
}
|
|
|
|
|
2014-08-08 22:00:07 +00:00
|
|
|
#include "moc_bookmarklist.cpp"
|