14#include <QtWidgets/QMenu>
15#include <QtGui/QKeyEvent>
16#include <QtWidgets/QMessageBox>
17#include <QtCore/QSortFilterProxyModel>
18#include <QtWidgets/QToolBar>
22using namespace Qt::StringLiterals;
29 if (event->reason() != Qt::MouseFocusReason) {
30 ui.lineEdit->selectAll();
31 ui.lineEdit->setFocus();
34 emit focusInEventOccurred();
46 setAutoExpandDelay(1000);
47 setUniformRowHeights(
true);
48 setDropIndicatorShown(
true);
49 setExpandsOnDoubleClick(
true);
51 connect(
this, &QTreeView::expanded,
this, &BookmarkTreeView::setExpandedData);
52 connect(
this, &QTreeView::collapsed,
this, &BookmarkTreeView::setExpandedData);
58 QTreeView::keyPressEvent(event);
63 QTreeView::commitData(editor);
84 if (!bookmarkManager) {
85 QMutexLocker _(&mutex);
89 return bookmarkManager;
95 delete bookmarkManager;
96 bookmarkManager =
nullptr;
103 return bookmarkWidget;
111 refreshBookmarkMenu();
118 refreshBookmarkToolBar();
126 showBookmarkDialog(title.isEmpty() ? tr(
"Untitled") : title,
127 url.isEmpty() ?
"about:blank"_L1 : url);
140 bookmarkWidget->installEventFilter(
this);
141 connect(bookmarkWidget->ui.add, &QAbstractButton::clicked,
142 this, &BookmarkManager::addBookmarkActivated);
143 connect(bookmarkWidget->ui.remove, &QAbstractButton::clicked,
144 this, &BookmarkManager::removeBookmarkActivated);
145 connect(bookmarkWidget->ui.lineEdit, &QLineEdit::textChanged,
146 this, &BookmarkManager::textChanged);
147 connect(bookmarkWidget, &BookmarkWidget::focusInEventOccurred,
148 this, &BookmarkManager::focusInEventOccurred);
150 bookmarkTreeView->setModel(bookmarkModel);
151 bookmarkTreeView->installEventFilter(
this);
152 bookmarkTreeView->viewport()->installEventFilter(
this);
153 bookmarkTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
154 bookmarkWidget->ui.stackedWidget->addWidget(bookmarkTreeView);
156 connect(bookmarkTreeView, &QAbstractItemView::activated,
157 this, [
this](
const QModelIndex &index) { setSourceFromIndex(index,
false); });
158 connect(bookmarkTreeView, &QWidget::customContextMenuRequested,
159 this, &BookmarkManager::customContextMenuRequested);
160 connect(bookmarkTreeView, &BookmarkTreeView::editingDone,
161 this, &BookmarkManager::storeBookmarks);
163 connect(&HelpEngineWrapper::instance(), &HelpEngineWrapper::setupFinished,
164 this, &BookmarkManager::setupFinished);
166 connect(bookmarkModel, &QAbstractItemModel::rowsRemoved,
167 this, &BookmarkManager::refreshBookmarkMenu);
168 connect(bookmarkModel, &QAbstractItemModel::rowsInserted,
169 this, &BookmarkManager::refreshBookmarkMenu);
170 connect(bookmarkModel, &QAbstractItemModel::dataChanged,
171 this, &BookmarkManager::refreshBookmarkMenu);
173 connect(bookmarkModel, &QAbstractItemModel::rowsRemoved,
174 this, &BookmarkManager::refreshBookmarkToolBar);
175 connect(bookmarkModel, &QAbstractItemModel::rowsInserted,
176 this, &BookmarkManager::refreshBookmarkToolBar);
177 connect(bookmarkModel, &QAbstractItemModel::dataChanged,
178 this, &BookmarkManager::refreshBookmarkToolBar);
185 delete bookmarkManagerWidget;
187 delete bookmarkModel;
193 QModelIndex current = index;
195 current = typeAndSearchModel->mapToSource(current);
196 current = bookmarkFilterModel->mapToSource(current);
197 }
else if (!bookmarkModel->parent(index).isValid()) {
201 if (bookmarkModel->hasChildren(current)) {
202 int value = QMessageBox::question(bookmarkTreeView, tr(
"Remove"),
203 tr(
"You are going to delete a Folder, this will also<br>"
204 "remove it's content. Are you sure to continue?"),
205 QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
206 if (value == QMessageBox::Cancel)
209 bookmarkModel->removeItem(current);
216 if (object != bookmarkTreeView && object != bookmarkTreeView->viewport()
217 && object != bookmarkWidget)
218 return QObject::eventFilter(object, event);
221 const bool isWidget = object == bookmarkWidget;
222 if (event->type() == QEvent::KeyPress) {
223 QKeyEvent *ke =
static_cast<QKeyEvent*>(event);
226 renameBookmark(bookmarkTreeView->currentIndex());
230 removeItem(bookmarkTreeView->currentIndex());
240 emit escapePressed();
247 if (event->type() == QEvent::MouseButtonRelease && !isWidget) {
248 QMouseEvent *me =
static_cast<QMouseEvent*>(event);
249 switch (me->button()) {
251 if (me->modifiers() & Qt::ControlModifier)
252 setSourceFromIndex(bookmarkTreeView->currentIndex(),
true);
255 case Qt::MiddleButton:
256 setSourceFromIndex(bookmarkTreeView->currentIndex(),
true);
263 return QObject::eventFilter(object, event);
266void BookmarkManager::buildBookmarksMenu(
const QModelIndex &index, QMenu* menu)
269 if (!index.isValid())
272 const QString &text = index.data().toString();
273 const QIcon &icon = qvariant_cast<QIcon>(index.data(Qt::DecorationRole));
275 if (QMenu* subMenu = menu->addMenu(icon, text)) {
276 for (
int i = 0; i < bookmarkModel->rowCount(index); ++i)
277 buildBookmarksMenu(bookmarkModel->index(i, 0, index), subMenu);
280 QAction *action = menu->addAction(icon, text);
281 action->setData(index.data(
UserRoleUrl).toString());
282 connect(action, &QAction::triggered,
283 this, &BookmarkManager::setSourceFromAction);
287void BookmarkManager::showBookmarkDialog(
const QString &name,
const QString &url)
290 BookmarkDialog dialog(bookmarkModel, name, url, bookmarkTreeView);
302 refreshBookmarkMenu();
303 refreshBookmarkToolBar();
305 bookmarkTreeView->hideColumn(1);
306 bookmarkTreeView->header()->setVisible(
false);
307 bookmarkTreeView->header()->setStretchLastSection(
true);
309 if (!bookmarkFilterModel)
310 bookmarkFilterModel =
new BookmarkFilterModel(
this);
311 bookmarkFilterModel->setSourceModel(bookmarkModel);
314 if (!typeAndSearchModel)
315 typeAndSearchModel =
new QSortFilterProxyModel(
this);
316 typeAndSearchModel->setDynamicSortFilter(
true);
317 typeAndSearchModel->setSourceModel(bookmarkFilterModel);
328 if (CentralWidget *widget = CentralWidget::instance())
329 addBookmark(widget->currentTitle(), widget->currentSource().toString());
335 removeItem(bookmarkTreeView->currentIndex());
341 if (bookmarkManagerWidget ==
nullptr) {
342 bookmarkManagerWidget =
new BookmarkManagerWidget(bookmarkModel);
343 connect(bookmarkManagerWidget, &BookmarkManagerWidget::setSource,
344 this, &BookmarkManager::setSource);
345 connect(bookmarkManagerWidget, &BookmarkManagerWidget::setSourceInNewTab,
346 this, &BookmarkManager::setSourceInNewTab);
350 bookmarkManagerWidget->show();
351 bookmarkManagerWidget->raise();
360 bookmarkMenu->clear();
362 bookmarkMenu->addAction(tr(
"Manage Bookmarks..."),
this,
363 &BookmarkManager::manageBookmarks);
364 bookmarkMenu->addAction(QIcon::fromTheme(
"bookmark-new"), tr(
"Add Bookmark..."),
365 QKeySequence(tr(
"Ctrl+D")),
366 this, &BookmarkManager::addBookmarkActivated);
368 bookmarkMenu->addSeparator();
370 QModelIndex root = bookmarkModel->index(0, 0, QModelIndex()).parent();
371 buildBookmarksMenu(bookmarkModel->index(0, 0, root), bookmarkMenu);
373 bookmarkMenu->addSeparator();
375 root = bookmarkModel->index(1, 0, QModelIndex());
376 for (
int i = 0; i < bookmarkModel->rowCount(root); ++i)
377 buildBookmarksMenu(bookmarkModel->index(i, 0, root), bookmarkMenu);
387 m_toolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
389 const QModelIndex &root = bookmarkModel->index(0, 0, QModelIndex());
390 for (
int i = 0; i < bookmarkModel->rowCount(root); ++i) {
391 const QModelIndex &index = bookmarkModel->index(i, 0, root);
393 QToolButton *button =
new QToolButton(m_toolBar);
394 button->setPopupMode(QToolButton::InstantPopup);
395 button->setText(index.data().toString());
396 QMenu *menu =
new QMenu(button);
397 for (
int j = 0; j < bookmarkModel->rowCount(index); ++j)
398 buildBookmarksMenu(bookmarkModel->index(j, 0, index), menu);
399 button->setMenu(menu);
400 button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
401 button->setIcon(qvariant_cast<QIcon>(index.data(Qt::DecorationRole)));
402 QAction *a = m_toolBar->addWidget(button);
403 a->setText(index.data().toString());
405 QAction *action = m_toolBar->addAction(
406 qvariant_cast<QIcon>(index.data(Qt::DecorationRole)),
407 index.data().toString(),
this, &BookmarkManager::setSourceFromAction);
408 action->setData(index.data(
UserRoleUrl).toString());
416 if (!typeAndSearch && !bookmarkModel->parent(index).isValid())
420 bookmarkTreeView->edit(index);
428 const QAction *action = qobject_cast<QAction*>(sender());
432 const QVariant &data = action->data();
433 if (data.canConvert<QUrl>())
434 emit setSource(data.toUrl());
437void BookmarkManager::setSourceFromIndex(
const QModelIndex &index,
bool newTab)
440 QAbstractItemModel *base = bookmarkModel;
442 base = typeAndSearchModel;
447 const QVariant &data = base->data(index, UserRoleUrl);
448 if (data.canConvert<QUrl>()) {
450 emit setSourceInNewTab(data.toUrl());
452 emit setSource(data.toUrl());
459 QModelIndex index = bookmarkTreeView->indexAt(point);
460 if (!index.isValid())
464 if (!typeAndSearch && !bookmarkModel->parent(index).isValid())
467 QAction *remove =
nullptr;
468 QAction *rename =
nullptr;
469 QAction *showItem =
nullptr;
470 QAction *showItemInNewTab =
nullptr;
473 if (!typeAndSearch && bookmarkModel->data(index,
UserRoleFolder).toBool()) {
474 remove = menu.addAction(tr(
"Delete Folder"));
475 rename = menu.addAction(tr(
"Rename Folder"));
477 showItem = menu.addAction(tr(
"Show Bookmark"));
478 showItemInNewTab = menu.addAction(tr(
"Show Bookmark in New Tab"));
480 remove = menu.addAction(tr(
"Delete Bookmark"));
481 rename = menu.addAction(tr(
"Rename Bookmark"));
484 QAction *pickedAction = menu.exec(bookmarkTreeView->mapToGlobal(point));
485 if (pickedAction == rename)
486 renameBookmark(index);
487 else if (pickedAction == remove)
489 else if (pickedAction == showItem || pickedAction == showItemInNewTab)
490 setSourceFromIndex(index, pickedAction == showItemInNewTab);
496 const QModelIndex &index = bookmarkTreeView->indexAt(QPoint(2, 2));
498 bookmarkTreeView->setCurrentIndex(index);
503 if (bookmarkManagerWidget)
504 bookmarkManagerWidget->deleteLater();
505 bookmarkManagerWidget =
nullptr;
513 if (!bookmarkWidget->ui.lineEdit->text().isEmpty()) {
514 if (!typeAndSearch) {
515 typeAndSearch =
true;
516 bookmarkTreeView->setItemsExpandable(
false);
517 bookmarkTreeView->setRootIsDecorated(
false);
518 bookmarkTreeView->setModel(typeAndSearchModel);
520 typeAndSearchModel->setFilterRegularExpression(text);
522 typeAndSearch =
false;
523 bookmarkTreeView->setModel(bookmarkModel);
524 bookmarkTreeView->setItemsExpandable(
true);
525 bookmarkTreeView->setRootIsDecorated(
true);
void filterBookmarkFolders()
void subclassKeyPressEvent(QKeyEvent *event)
void setBookmarksToolbar(QToolBar *toolBar)
QWidget * bookmarkDockWidget() const
void setBookmarksMenu(QMenu *menu)
~BookmarkManager() override
bool eventFilter(QObject *object, QEvent *event) override
Filters events if this object has been installed as an event filter for the watched object.
void setItemsEditable(bool editable)
void expandFoldersIfNeeeded(QTreeView *treeView)
static HelpEngineWrapper & instance()
Combined button and popup list for selecting options.