1 | /* |
---|---|
2 | This file is part of the KDE project |
3 | SPDX-FileCopyrightText: 1998, 1999 Torben Weis <weis@kde.org> |
4 | SPDX-FileCopyrightText: 2006 Daniel Teske <teske@squorn.de> |
5 | |
6 | SPDX-License-Identifier: LGPL-2.0-or-later |
7 | */ |
8 | |
9 | #include "kbookmarkmenu.h" |
10 | #include "kbookmarkmenu_p.h" |
11 | |
12 | #include "../kbookmarksettings_p.h" |
13 | #include "kbookmarkaction.h" |
14 | #include "kbookmarkactionmenu.h" |
15 | #include "kbookmarkcontextmenu.h" |
16 | #include "kbookmarkdialog.h" |
17 | #include "kbookmarkmanager.h" |
18 | #include "kbookmarkowner.h" |
19 | #include "kbookmarkswidgets_debug.h" |
20 | #include "keditbookmarks_p.h" |
21 | |
22 | #include <KAuthorized> |
23 | #include <KStandardAction> |
24 | |
25 | #include <QApplication> |
26 | #include <QMenu> |
27 | #include <QMessageBox> |
28 | #include <QStandardPaths> |
29 | |
30 | /********************************************************************/ |
31 | /********************************************************************/ |
32 | /********************************************************************/ |
33 | class KBookmarkMenuPrivate |
34 | { |
35 | public: |
36 | QAction *newBookmarkFolderAction = nullptr; |
37 | QAction *addBookmarkAction = nullptr; |
38 | QAction *bookmarksToFolderAction = nullptr; |
39 | QAction *editBookmarksAction = nullptr; |
40 | bool browserMode = false; |
41 | bool isRoot; |
42 | bool dirty; |
43 | KBookmarkManager *manager; |
44 | KBookmarkOwner *owner; |
45 | QMenu *parentMenu; |
46 | QString parentAddress; |
47 | }; |
48 | |
49 | KBookmarkMenu::KBookmarkMenu(KBookmarkManager *manager, KBookmarkOwner *_owner, QMenu *_parentMenu) |
50 | : QObject() |
51 | , d(new KBookmarkMenuPrivate()) |
52 | { |
53 | d->isRoot = true; |
54 | d->manager = manager; |
55 | d->owner = _owner; |
56 | d->parentMenu = _parentMenu; |
57 | d->parentAddress = QString(); // TODO KBookmarkAdress::root |
58 | // TODO KDE5 find a QMenu equvalnet for this one |
59 | // m_parentMenu->setKeyboardShortcutsEnabled( true ); |
60 | |
61 | init(); |
62 | } |
63 | |
64 | void KBookmarkMenu::init() |
65 | { |
66 | connect(sender: d->parentMenu, signal: &QMenu::aboutToShow, context: this, slot: &KBookmarkMenu::slotAboutToShow); |
67 | |
68 | if (KBookmarkSettings::self()->m_contextmenu) { |
69 | d->parentMenu->setContextMenuPolicy(Qt::CustomContextMenu); |
70 | connect(sender: d->parentMenu, signal: &QWidget::customContextMenuRequested, context: this, slot: &KBookmarkMenu::slotCustomContextMenu); |
71 | } |
72 | |
73 | connect(sender: d->manager, signal: &KBookmarkManager::changed, context: this, slot: &KBookmarkMenu::slotBookmarksChanged); |
74 | |
75 | d->dirty = true; |
76 | addActions(); |
77 | } |
78 | |
79 | void KBookmarkMenu::addActions() |
80 | { |
81 | if (d->isRoot) { |
82 | addAddBookmark(); |
83 | addAddBookmarksList(); |
84 | addNewFolder(); |
85 | addEditBookmarks(); |
86 | } else { |
87 | if (!d->parentMenu->actions().isEmpty()) { |
88 | d->parentMenu->addSeparator(); |
89 | } |
90 | |
91 | addOpenInTabs(); |
92 | addAddBookmark(); |
93 | addAddBookmarksList(); |
94 | addNewFolder(); |
95 | } |
96 | } |
97 | |
98 | KBookmarkMenu::KBookmarkMenu(KBookmarkManager *mgr, KBookmarkOwner *_owner, QMenu *_parentMenu, const QString &parentAddress) |
99 | : QObject() |
100 | , d(new KBookmarkMenuPrivate()) |
101 | { |
102 | d->isRoot = false; |
103 | d->manager = mgr; |
104 | d->owner = _owner; |
105 | d->parentMenu = _parentMenu; |
106 | d->parentAddress = parentAddress; |
107 | |
108 | connect(sender: _parentMenu, signal: &QMenu::aboutToShow, context: this, slot: &KBookmarkMenu::slotAboutToShow); |
109 | if (KBookmarkSettings::self()->m_contextmenu) { |
110 | d->parentMenu->setContextMenuPolicy(Qt::CustomContextMenu); |
111 | connect(sender: d->parentMenu, signal: &QWidget::customContextMenuRequested, context: this, slot: &KBookmarkMenu::slotCustomContextMenu); |
112 | } |
113 | d->dirty = true; |
114 | } |
115 | |
116 | KBookmarkMenu::~KBookmarkMenu() |
117 | { |
118 | qDeleteAll(c: m_lstSubMenus); |
119 | qDeleteAll(c: m_actions); |
120 | } |
121 | |
122 | void KBookmarkMenu::ensureUpToDate() |
123 | { |
124 | slotAboutToShow(); |
125 | } |
126 | |
127 | void KBookmarkMenu::slotAboutToShow() |
128 | { |
129 | // Did the bookmarks change since the last time we showed them ? |
130 | if (d->dirty) { |
131 | d->dirty = false; |
132 | clear(); |
133 | refill(); |
134 | d->parentMenu->adjustSize(); |
135 | } |
136 | } |
137 | |
138 | void KBookmarkMenu::slotCustomContextMenu(const QPoint &pos) |
139 | { |
140 | QAction *action = d->parentMenu->actionAt(pos); |
141 | QMenu *menu = contextMenu(action); |
142 | if (!menu) { |
143 | return; |
144 | } |
145 | menu->setAttribute(Qt::WA_DeleteOnClose); |
146 | menu->popup(pos: d->parentMenu->mapToGlobal(pos)); |
147 | } |
148 | |
149 | QMenu *KBookmarkMenu::contextMenu(QAction *action) |
150 | { |
151 | KBookmarkActionInterface *act = dynamic_cast<KBookmarkActionInterface *>(action); |
152 | if (!act) { |
153 | return nullptr; |
154 | } |
155 | return new KBookmarkContextMenu(act->bookmark(), d->manager, d->owner); |
156 | } |
157 | |
158 | bool KBookmarkMenu::isRoot() const |
159 | { |
160 | return d->isRoot; |
161 | } |
162 | |
163 | bool KBookmarkMenu::isDirty() const |
164 | { |
165 | return d->dirty; |
166 | } |
167 | |
168 | QString KBookmarkMenu::parentAddress() const |
169 | { |
170 | return d->parentAddress; |
171 | } |
172 | |
173 | KBookmarkManager *KBookmarkMenu::manager() const |
174 | { |
175 | return d->manager; |
176 | } |
177 | |
178 | KBookmarkOwner *KBookmarkMenu::owner() const |
179 | { |
180 | return d->owner; |
181 | } |
182 | |
183 | QMenu *KBookmarkMenu::parentMenu() const |
184 | { |
185 | return d->parentMenu; |
186 | } |
187 | |
188 | /********************************************************************/ |
189 | /********************************************************************/ |
190 | /********************************************************************/ |
191 | |
192 | /********************************************************************/ |
193 | /********************************************************************/ |
194 | /********************************************************************/ |
195 | |
196 | void KBookmarkMenu::slotBookmarksChanged(const QString &groupAddress) |
197 | { |
198 | qCDebug(KBOOKMARKSWIDGETS_LOG) << "KBookmarkMenu::slotBookmarksChanged groupAddress: "<< groupAddress; |
199 | if (groupAddress == d->parentAddress) { |
200 | // qCDebug(KBOOKMARKS_LOG) << "KBookmarkMenu::slotBookmarksChanged -> setting m_bDirty on " << groupAddress; |
201 | d->dirty = true; |
202 | } else { |
203 | // Iterate recursively into child menus |
204 | for (QList<KBookmarkMenu *>::iterator it = m_lstSubMenus.begin(), end = m_lstSubMenus.end(); it != end; ++it) { |
205 | (*it)->slotBookmarksChanged(groupAddress); |
206 | } |
207 | } |
208 | } |
209 | |
210 | void KBookmarkMenu::clear() |
211 | { |
212 | qDeleteAll(c: m_lstSubMenus); |
213 | m_lstSubMenus.clear(); |
214 | |
215 | for (QList<QAction *>::iterator it = m_actions.begin(), end = m_actions.end(); it != end; ++it) { |
216 | d->parentMenu->removeAction(action: *it); |
217 | delete *it; |
218 | } |
219 | |
220 | d->parentMenu->clear(); |
221 | m_actions.clear(); |
222 | } |
223 | |
224 | void KBookmarkMenu::refill() |
225 | { |
226 | // qCDebug(KBOOKMARKS_LOG) << "KBookmarkMenu::refill()"; |
227 | if (d->isRoot) { |
228 | addActions(); |
229 | } |
230 | fillBookmarks(); |
231 | if (!d->isRoot) { |
232 | addActions(); |
233 | } |
234 | } |
235 | |
236 | void KBookmarkMenu::addOpenInTabs() |
237 | { |
238 | if (!d->owner || !d->owner->supportsTabs() || !KAuthorized::authorizeAction(QStringLiteral("bookmarks"))) { |
239 | return; |
240 | } |
241 | |
242 | const QString title = tr(s: "Open Folder in Tabs", c: "@action:inmenu"); |
243 | |
244 | QAction *paOpenFolderInTabs = new QAction(title, this); |
245 | paOpenFolderInTabs->setIcon(QIcon::fromTheme(QStringLiteral("tab-new"))); |
246 | paOpenFolderInTabs->setToolTip(tr(s: "Open all bookmarks in this folder as a new tab", c: "@info:tooltip")); |
247 | paOpenFolderInTabs->setStatusTip(paOpenFolderInTabs->toolTip()); |
248 | connect(sender: paOpenFolderInTabs, signal: &QAction::triggered, context: this, slot: &KBookmarkMenu::slotOpenFolderInTabs); |
249 | |
250 | d->parentMenu->addAction(action: paOpenFolderInTabs); |
251 | m_actions.append(t: paOpenFolderInTabs); |
252 | } |
253 | |
254 | void KBookmarkMenu::addAddBookmarksList() |
255 | { |
256 | if (!d->owner || !d->owner->enableOption(option: KBookmarkOwner::ShowAddBookmark) || !d->owner->supportsTabs() |
257 | || !KAuthorized::authorizeAction(QStringLiteral("bookmarks"))) { |
258 | return; |
259 | } |
260 | |
261 | if (!d->bookmarksToFolderAction) { |
262 | const QString title = tr(s: "Bookmark Tabs as Folder...", c: "@action:inmenu"); |
263 | d->bookmarksToFolderAction = new QAction(title, this); |
264 | |
265 | if (d->isRoot) { |
266 | d->bookmarksToFolderAction->setObjectName(QStringLiteral("add_bookmarks_list")); |
267 | } |
268 | |
269 | d->bookmarksToFolderAction->setIcon(QIcon::fromTheme(QStringLiteral("bookmark-new-list"))); |
270 | d->bookmarksToFolderAction->setToolTip(tr(s: "Add a folder of bookmarks for all open tabs", c: "@info:tooltip")); |
271 | d->bookmarksToFolderAction->setStatusTip(d->bookmarksToFolderAction->toolTip()); |
272 | connect(sender: d->bookmarksToFolderAction, signal: &QAction::triggered, context: this, slot: &KBookmarkMenu::slotAddBookmarksList); |
273 | } |
274 | |
275 | d->parentMenu->addAction(action: d->bookmarksToFolderAction); |
276 | } |
277 | |
278 | void KBookmarkMenu::addAddBookmark() |
279 | { |
280 | if (!d->owner || !d->owner->enableOption(option: KBookmarkOwner::ShowAddBookmark) || !KAuthorized::authorizeAction(QStringLiteral("bookmarks"))) { |
281 | return; |
282 | } |
283 | |
284 | if (!d->addBookmarkAction) { |
285 | d->addBookmarkAction = KStandardAction::addBookmark(recvr: this, slot: &KBookmarkMenu::slotAddBookmark, parent: this); |
286 | if (d->isRoot) { |
287 | d->addBookmarkAction->setObjectName(QStringLiteral("add_bookmark")); |
288 | } |
289 | |
290 | if (!d->isRoot) { |
291 | d->addBookmarkAction->setShortcut(QKeySequence()); |
292 | } |
293 | } |
294 | |
295 | d->parentMenu->addAction(action: d->addBookmarkAction); |
296 | } |
297 | |
298 | void KBookmarkMenu::addEditBookmarks() |
299 | { |
300 | if ((d->owner && !d->owner->enableOption(option: KBookmarkOwner::ShowEditBookmark)) |
301 | || QStandardPaths::findExecutable(QStringLiteral(KEDITBOOKMARKS_BINARY)).isEmpty() || !KAuthorized::authorizeAction(QStringLiteral("bookmarks"))) { |
302 | return; |
303 | } |
304 | |
305 | d->editBookmarksAction = KStandardAction::editBookmarks(recvr: this, slot: &KBookmarkMenu::slotEditBookmarks, parent: this); |
306 | d->editBookmarksAction->setObjectName(QStringLiteral("edit_bookmarks")); |
307 | |
308 | d->parentMenu->addAction(action: d->editBookmarksAction); |
309 | d->editBookmarksAction->setToolTip(tr(s: "Edit your bookmark collection in a separate window", c: "@info:tooltip")); |
310 | d->editBookmarksAction->setStatusTip(d->editBookmarksAction->toolTip()); |
311 | } |
312 | |
313 | void KBookmarkMenu::slotEditBookmarks() |
314 | { |
315 | KEditBookmarks editBookmarks; |
316 | editBookmarks.setBrowserMode(d->browserMode); |
317 | auto result = editBookmarks.openForFile(file: d->manager->path()); |
318 | |
319 | if (!result.sucess()) { |
320 | QMessageBox::critical(parent: QApplication::activeWindow(), title: QApplication::applicationDisplayName(), text: result.errorMessage()); |
321 | } |
322 | } |
323 | |
324 | void KBookmarkMenu::addNewFolder() |
325 | { |
326 | if (!d->owner || !d->owner->enableOption(option: KBookmarkOwner::ShowAddBookmark) || !KAuthorized::authorizeAction(QStringLiteral("bookmarks"))) { |
327 | return; |
328 | } |
329 | |
330 | if (!d->newBookmarkFolderAction) { |
331 | d->newBookmarkFolderAction = new QAction(tr(s: "New Bookmark Folder...", c: "@action:inmenu"), this); |
332 | d->newBookmarkFolderAction->setIcon(QIcon::fromTheme(QStringLiteral("folder-new"))); |
333 | d->newBookmarkFolderAction->setToolTip(tr(s: "Create a new bookmark folder in this menu", c: "@info:tooltip")); |
334 | d->newBookmarkFolderAction->setStatusTip(d->newBookmarkFolderAction->toolTip()); |
335 | |
336 | if (d->isRoot) { |
337 | d->newBookmarkFolderAction->setObjectName(QStringLiteral("new_bookmark_folder")); |
338 | } |
339 | |
340 | connect(sender: d->newBookmarkFolderAction, signal: &QAction::triggered, context: this, slot: &KBookmarkMenu::slotNewFolder); |
341 | } |
342 | |
343 | d->parentMenu->addAction(action: d->newBookmarkFolderAction); |
344 | } |
345 | |
346 | void KBookmarkMenu::fillBookmarks() |
347 | { |
348 | KBookmarkGroup parentBookmark = d->manager->findByAddress(address: d->parentAddress).toGroup(); |
349 | Q_ASSERT(!parentBookmark.isNull()); |
350 | |
351 | if (d->isRoot && !parentBookmark.first().isNull()) { // at least one bookmark |
352 | d->parentMenu->addSeparator(); |
353 | } |
354 | |
355 | for (KBookmark bm = parentBookmark.first(); !bm.isNull(); bm = parentBookmark.next(current: bm)) { |
356 | d->parentMenu->addAction(action: actionForBookmark(bm)); |
357 | } |
358 | } |
359 | |
360 | QAction *KBookmarkMenu::actionForBookmark(const KBookmark &bm) |
361 | { |
362 | if (bm.isGroup()) { |
363 | // qCDebug(KBOOKMARKS_LOG) << "Creating bookmark submenu named " << bm.text(); |
364 | KActionMenu *actionMenu = new KBookmarkActionMenu(bm, this); |
365 | m_actions.append(t: actionMenu); |
366 | KBookmarkMenu *subMenu = new KBookmarkMenu(d->manager, d->owner, actionMenu->menu(), bm.address()); |
367 | m_lstSubMenus.append(t: subMenu); |
368 | return actionMenu; |
369 | } else if (bm.isSeparator()) { |
370 | QAction *sa = new QAction(this); |
371 | sa->setSeparator(true); |
372 | m_actions.append(t: sa); |
373 | return sa; |
374 | } else { |
375 | // qCDebug(KBOOKMARKS_LOG) << "Creating bookmark menu item for " << bm.text(); |
376 | QAction *action = new KBookmarkAction(bm, d->owner, this); |
377 | m_actions.append(t: action); |
378 | return action; |
379 | } |
380 | } |
381 | |
382 | void KBookmarkMenu::slotAddBookmarksList() |
383 | { |
384 | if (!d->owner || !d->owner->supportsTabs()) { |
385 | return; |
386 | } |
387 | |
388 | KBookmarkGroup parentBookmark = d->manager->findByAddress(address: d->parentAddress).toGroup(); |
389 | |
390 | KBookmarkDialog *dlg = new KBookmarkDialog(d->manager, QApplication::activeWindow()); |
391 | dlg->addBookmarks(list: d->owner->currentBookmarkList(), name: QLatin1String(""), parent: parentBookmark); |
392 | delete dlg; |
393 | } |
394 | |
395 | void KBookmarkMenu::slotAddBookmark() |
396 | { |
397 | if (!d->owner) { |
398 | return; |
399 | } |
400 | if (d->owner->currentTitle().isEmpty() && d->owner->currentUrl().isEmpty()) { |
401 | return; |
402 | } |
403 | KBookmarkGroup parentBookmark = d->manager->findByAddress(address: d->parentAddress).toGroup(); |
404 | |
405 | if (KBookmarkSettings::self()->m_advancedaddbookmark) { |
406 | KBookmarkDialog *dlg = new KBookmarkDialog(d->manager, QApplication::activeWindow()); |
407 | dlg->addBookmark(title: d->owner->currentTitle(), url: d->owner->currentUrl(), icon: d->owner->currentIcon(), parent: parentBookmark); |
408 | delete dlg; |
409 | } else { |
410 | parentBookmark.addBookmark(text: d->owner->currentTitle(), url: d->owner->currentUrl(), icon: d->owner->currentIcon()); |
411 | d->manager->emitChanged(group: parentBookmark); |
412 | } |
413 | } |
414 | |
415 | void KBookmarkMenu::slotOpenFolderInTabs() |
416 | { |
417 | d->owner->openFolderinTabs(bm: d->manager->findByAddress(address: d->parentAddress).toGroup()); |
418 | } |
419 | |
420 | void KBookmarkMenu::slotNewFolder() |
421 | { |
422 | if (!d->owner) { |
423 | return; // this view doesn't handle bookmarks... |
424 | } |
425 | KBookmarkGroup parentBookmark = d->manager->findByAddress(address: d->parentAddress).toGroup(); |
426 | Q_ASSERT(!parentBookmark.isNull()); |
427 | KBookmarkDialog *dlg = new KBookmarkDialog(d->manager, QApplication::activeWindow()); |
428 | dlg->createNewFolder(name: QLatin1String(""), parent: parentBookmark); |
429 | delete dlg; |
430 | } |
431 | |
432 | QAction *KBookmarkMenu::addBookmarkAction() const |
433 | { |
434 | return d->addBookmarkAction; |
435 | } |
436 | |
437 | QAction *KBookmarkMenu::bookmarkTabsAsFolderAction() const |
438 | { |
439 | return d->bookmarksToFolderAction; |
440 | } |
441 | |
442 | QAction *KBookmarkMenu::newBookmarkFolderAction() const |
443 | { |
444 | return d->newBookmarkFolderAction; |
445 | } |
446 | |
447 | QAction *KBookmarkMenu::editBookmarksAction() const |
448 | { |
449 | return d->editBookmarksAction; |
450 | } |
451 | |
452 | void KBookmarkMenu::setBrowserMode(bool browserMode) |
453 | { |
454 | d->browserMode = browserMode; |
455 | } |
456 | |
457 | bool KBookmarkMenu::browserMode() const |
458 | { |
459 | return d->browserMode; |
460 | } |
461 | |
462 | #include "moc_kbookmarkmenu.cpp" |
463 |
Definitions
- KBookmarkMenuPrivate
- KBookmarkMenu
- init
- addActions
- KBookmarkMenu
- ~KBookmarkMenu
- ensureUpToDate
- slotAboutToShow
- slotCustomContextMenu
- contextMenu
- isRoot
- isDirty
- parentAddress
- manager
- owner
- parentMenu
- slotBookmarksChanged
- clear
- refill
- addOpenInTabs
- addAddBookmarksList
- addAddBookmark
- addEditBookmarks
- slotEditBookmarks
- addNewFolder
- fillBookmarks
- actionForBookmark
- slotAddBookmarksList
- slotAddBookmark
- slotOpenFolderInTabs
- slotNewFolder
- addBookmarkAction
- bookmarkTabsAsFolderAction
- newBookmarkFolderAction
- editBookmarksAction
- setBrowserMode
Learn to use CMake with our Intro Training
Find out more