Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
bookmarkmanagerwidget.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
4#include "bookmarkitem.h"
6#include "tracer.h"
7#include "xbelsupport.h"
8
9#include <QtWidgets/QFileDialog>
10#include <QtWidgets/QMessageBox>
11
12#include <QtGui/QCloseEvent>
13#include <QtGui/QKeySequence>
14#include <QtGui/QShortcut>
15
16#include <QtCore/QCoreApplication>
17#include <QtCore/QFile>
18#include <QtCore/QUrl>
19
21
22using namespace Qt::StringLiterals;
23
24BookmarkManagerWidget::BookmarkManagerWidget(BookmarkModel *sourceModel,
25 QWidget *parent)
26 : QWidget(parent)
27 , bookmarkModel(sourceModel)
28{
30 ui.setupUi(this);
31
32 ui.treeView->setModel(bookmarkModel);
33
34 ui.treeView->expandAll();
35 ui.treeView->installEventFilter(this);
36 ui.treeView->viewport()->installEventFilter(this);
37 ui.treeView->setContextMenuPolicy(Qt::CustomContextMenu);
38
39 connect(ui.treeView, &QWidget::customContextMenuRequested,
40 this, &BookmarkManagerWidget::customContextMenuRequested);
41
42 connect(ui.remove, &QAbstractButton::clicked,
43 this, [this]() { removeItem(); });
44 connect(ui.lineEdit, &QLineEdit::textChanged,
45 this, &BookmarkManagerWidget::textChanged);
46 QShortcut *shortcut = new QShortcut(QKeySequence::Find, ui.lineEdit);
47 connect(shortcut, &QShortcut::activated,
48 ui.lineEdit, QOverload<>::of(&QWidget::setFocus));
49
50 importExportMenu.addAction(tr("Import..."), this,
51 &BookmarkManagerWidget::importBookmarks);
52 importExportMenu.addAction(tr("Export..."), this,
53 &BookmarkManagerWidget::exportBookmarks);
54 ui.importExport->setMenu(&importExportMenu);
55
56 shortcut = new QShortcut(QKeySequence::FindNext, this);
57 connect(shortcut, &QShortcut::activated,
58 this, &BookmarkManagerWidget::findNext);
59 shortcut = new QShortcut(QKeySequence::FindPrevious, this);
60 connect(shortcut, &QShortcut::activated,
61 this, &BookmarkManagerWidget::findPrevious);
62
63 connect(bookmarkModel, &QAbstractItemModel::rowsRemoved,
64 this, &BookmarkManagerWidget::refeshBookmarkCache);
65 connect(bookmarkModel, &QAbstractItemModel::rowsInserted,
66 this, &BookmarkManagerWidget::refeshBookmarkCache);
67 connect(bookmarkModel, &QAbstractItemModel::dataChanged,
68 this, &BookmarkManagerWidget::refeshBookmarkCache);
69
70 ui.treeView->setCurrentIndex(ui.treeView->indexAt(QPoint(2, 2)));
71}
72
77
78void BookmarkManagerWidget::closeEvent(QCloseEvent *event)
79{
81 event->accept();
82 emit managerWidgetAboutToClose();
83}
84
85void BookmarkManagerWidget::renameItem(const QModelIndex &index)
86{
88 // check if we should rename the "Bookmarks Menu", bail
89 if (!bookmarkModel->parent(index).isValid())
90 return;
91
92 bookmarkModel->setItemsEditable(true);
93 ui.treeView->edit(index);
94 bookmarkModel->setItemsEditable(false);
95}
96
97static int nextIndex(int current, int count, bool forward)
98{
100 if (current >= 0)
101 return (forward ? (current + 1) : ((current - 1) + count)) % count;
102 return 0;
103}
104
105void BookmarkManagerWidget::selectNextIndex(bool direction) const
106{
107 QModelIndex current = ui.treeView->currentIndex();
108 if (current.isValid() && !cache.isEmpty()) {
109 current = cache.at(nextIndex(cache.indexOf(current), cache.size(),
110 direction));
111 }
112 ui.treeView->setCurrentIndex(current);
113}
114
115bool BookmarkManagerWidget::eventFilter(QObject *object, QEvent *event)
116{
118 if (object != ui.treeView && object != ui.treeView->viewport())
119 return QWidget::eventFilter(object, event);
120
121 if (event->type() == QEvent::KeyPress) {
122 QKeyEvent *ke = static_cast<QKeyEvent*>(event);
123 switch (ke->key()) {
124 case Qt::Key_F2:
125 renameItem(ui.treeView->currentIndex());
126 break;
127
128 case Qt::Key_Delete:
129 removeItem(ui.treeView->currentIndex());
130 break;
131
132 default: break;
133 }
134 }
135
136 if (event->type() == QEvent::MouseButtonRelease) {
137 QMouseEvent *me = static_cast<QMouseEvent*>(event);
138 switch (me->button()) {
139 case Qt::LeftButton:
140 if (me->modifiers() & Qt::ControlModifier)
141 setSourceFromIndex(ui.treeView->currentIndex(), true);
142 break;
143
144 case Qt::MiddleButton:
145 setSourceFromIndex(ui.treeView->currentIndex(), true);
146 break;
147
148 default: break;
149 }
150 }
151 return QObject::eventFilter(object, event);
152}
153
154void BookmarkManagerWidget::findNext()
155{
157 selectNextIndex(true);
158}
159
160void BookmarkManagerWidget::findPrevious()
161{
163 selectNextIndex(false);
164}
165
166void BookmarkManagerWidget::importBookmarks()
167{
169 const QString &fileName = QFileDialog::getOpenFileName(nullptr, tr("Open File"),
170 QDir::currentPath(), tr("Files (*.xbel)"));
171
172 if (fileName.isEmpty())
173 return;
174
175 QFile file(fileName);
176 if (file.open(QIODevice::ReadOnly)) {
177 XbelReader reader(bookmarkModel);
178 reader.readFromFile(&file);
179 }
180}
181
182void BookmarkManagerWidget::exportBookmarks()
183{
185 QString fileName = QFileDialog::getSaveFileName(nullptr, tr("Save File"), "untitled.xbel"_L1,
186 tr("Files (*.xbel)"));
187
188 const QLatin1StringView suffix(".xbel");
189 if (!fileName.endsWith(suffix))
190 fileName.append(suffix);
191
192 QFile file(fileName);
193 if (file.open(QIODevice::WriteOnly)) {
194 XbelWriter writer(bookmarkModel);
195 writer.writeToFile(&file);
196 } else {
197 QMessageBox::information(this, tr("Qt Assistant"),
198 tr("Unable to save bookmarks."), QMessageBox::Ok);
199 }
200}
201
202void BookmarkManagerWidget::refeshBookmarkCache()
203{
205 cache.clear();
206
207 const QString &text = ui.lineEdit->text();
208 if (!text.isEmpty())
209 cache = bookmarkModel->indexListFor(text);
210}
211
212void BookmarkManagerWidget::textChanged(const QString &/*text*/)
213{
215 refeshBookmarkCache();
216 if (!cache.isEmpty())
217 ui.treeView->setCurrentIndex(cache.at(0));
218}
219
220void BookmarkManagerWidget::removeItem(const QModelIndex &index)
221{
223 QModelIndex current = index.isValid() ? index : ui.treeView->currentIndex();
224 if (!current.parent().isValid() && current.row() < 2)
225 return; // check if we should delete the "Bookmarks Menu", bail
226
227 if (bookmarkModel->hasChildren(current)) {
228 int value = QMessageBox::question(this, tr("Remove"), tr("You are going"
229 "to delete a Folder, this will also<br> remove it's content. Are "
230 "you sure to continue?"),
231 QMessageBox::Yes | QMessageBox::Cancel, QMessageBox::Cancel);
232 if (value == QMessageBox::Cancel)
233 return;
234 }
235 bookmarkModel->removeItem(current);
236}
237
238void BookmarkManagerWidget::customContextMenuRequested(const QPoint &point)
239{
241 const QModelIndex &index = ui.treeView->indexAt(point);
242 if (!index.isValid())
243 return;
244
245 // check if we should open the menu on "Bookmarks Menu", bail
246 if (!bookmarkModel->parent(index).isValid())
247 return;
248
249 QAction *remove = nullptr;
250 QAction *rename = nullptr;
251 QAction *showItem = nullptr;
252 QAction *showItemInNewTab = nullptr;
253
254 QMenu menu;
255 if (bookmarkModel->data(index, UserRoleFolder).toBool()) {
256 remove = menu.addAction(tr("Delete Folder"));
257 rename = menu.addAction(tr("Rename Folder"));
258 } else {
259 showItem = menu.addAction(tr("Show Bookmark"));
260 showItemInNewTab = menu.addAction(tr("Show Bookmark in New Tab"));
261 menu.addSeparator();
262 remove = menu.addAction(tr("Delete Bookmark"));
263 rename = menu.addAction(tr("Rename Bookmark"));
264 }
265
266 QAction *pickedAction = menu.exec(ui.treeView->mapToGlobal(point));
267 if (pickedAction == rename)
268 renameItem(index);
269 else if (pickedAction == remove)
270 removeItem(index);
271 else if (pickedAction == showItem || pickedAction == showItemInNewTab)
272 setSourceFromIndex(index, pickedAction == showItemInNewTab);
273}
274
275void
276BookmarkManagerWidget::setSourceFromIndex(const QModelIndex &index, bool newTab)
277{
279 if (bookmarkModel->data(index, UserRoleFolder).toBool())
280 return;
281
282 const QVariant &data = bookmarkModel->data(index, UserRoleUrl);
283 if (data.canConvert<QUrl>()) {
284 if (newTab)
285 emit setSourceInNewTab(data.toUrl());
286 else
287 emit setSource(data.toUrl());
288 }
289}
290
291QT_END_NAMESPACE
@ UserRoleFolder
static int nextIndex(int current, int count, bool forward)
bool eventFilter(QObject *object, QEvent *event) override
Filters events if this object has been installed as an event filter for the watched object.
void closeEvent(QCloseEvent *event) override
This event handler is called with the given event when Qt receives a window close request for a top-l...
void setItemsEditable(bool editable)
XbelReader(BookmarkModel *model)
XbelWriter(BookmarkModel *model)
Combined button and popup list for selecting options.
#define TRACE_OBJ
Definition tracer.h:34