KBookmarks

kbookmarkmenu.cpp
1 /* This file is part of the KDE project
2  Copyright (C) 1998, 1999 Torben Weis <[email protected]>
3  Copyright (C) 2006 Daniel Teske <[email protected]>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 */
20 
21 #include "kbookmarkmenu.h"
22 #include "kbookmarkmenu_p.h"
23 
24 #include "kbookmarkaction.h"
25 #include "kbookmarkactionmenu.h"
26 #include "kbookmarkcontextmenu.h"
27 #include "kbookmarks_debug.h"
28 #include "kbookmarkdialog.h"
29 #include "kbookmarkowner.h"
30 
31 #include <KActionCollection>
32 #include <KAuthorized>
33 #include <KStandardAction>
34 
35 #include <QApplication>
36 #include <QMenu>
37 #include <QObject>
38 #include <QStandardPaths>
39 
40 /********************************************************************/
41 /********************************************************************/
42 /********************************************************************/
43 class KBookmarkMenuPrivate
44 {
45 public:
46  KBookmarkMenuPrivate()
47  : newBookmarkFolderAction(nullptr),
48  addBookmarkAction(nullptr),
49  bookmarksToFolderAction(nullptr),
50  editBookmarksAction(nullptr),
51  numberOfOpenTabs(2)
52  {
53  }
54 
55  QAction *newBookmarkFolderAction;
56  QAction *addBookmarkAction;
57  QAction *bookmarksToFolderAction;
58  QAction *editBookmarksAction;
59  int numberOfOpenTabs;
60 };
61 
62 #if KBOOKMARKS_BUILD_DEPRECATED_SINCE(5, 69)
64  KBookmarkOwner *_owner,
65  QMenu *_parentMenu,
66  KActionCollection *actionCollection)
67  : QObject(),
68  m_actionCollection(actionCollection),
69  d(new KBookmarkMenuPrivate()),
70  m_bIsRoot(true),
71  m_pManager(mgr),
72  m_pOwner(_owner),
73  m_parentMenu(_parentMenu),
74  m_parentAddress(QString()) //TODO KBookmarkAdress::root
75 {
76  init();
77 }
78 
79 #endif
80 
82  : QObject(),
83  m_actionCollection(new KActionCollection(this)),
84  d(new KBookmarkMenuPrivate()),
85  m_bIsRoot(true),
86  m_pManager(manager),
87  m_pOwner(_owner),
88  m_parentMenu(_parentMenu),
89  m_parentAddress(QString()) //TODO KBookmarkAdress::root
90 {
91  // TODO KDE5 find a QMenu equvalnet for this one
92  //m_parentMenu->setKeyboardShortcutsEnabled( true );
93 
94  init();
95 }
96 
97 void KBookmarkMenu::init()
98 {
99  connect(m_parentMenu, &QMenu::aboutToShow,
100  this, &KBookmarkMenu::slotAboutToShow);
101 
102  if (KBookmarkSettings::self()->m_contextmenu) {
104  connect(m_parentMenu, &QWidget::customContextMenuRequested, this, &KBookmarkMenu::slotCustomContextMenu);
105  }
106 
107  connect(m_pManager, &KBookmarkManager::changed,
108  this, &KBookmarkMenu::slotBookmarksChanged);
109 
110  m_bDirty = true;
111  addActions();
112 }
113 
114 void KBookmarkMenu::addActions()
115 {
116  if (m_bIsRoot) {
117  addAddBookmark();
118  addAddBookmarksList();
119  addNewFolder();
120  addEditBookmarks();
121  } else {
122  if (!m_parentMenu->actions().isEmpty()) {
123  m_parentMenu->addSeparator();
124  }
125 
126  addOpenInTabs();
127  addAddBookmark();
128  addAddBookmarksList();
129  addNewFolder();
130  }
131 }
132 
134  KBookmarkOwner *_owner,
135  QMenu *_parentMenu,
136  const QString &parentAddress)
137  : QObject(),
138  m_actionCollection(new KActionCollection(this)),
139  d(new KBookmarkMenuPrivate()),
140  m_bIsRoot(false),
141  m_pManager(mgr),
142  m_pOwner(_owner),
143  m_parentMenu(_parentMenu),
144  m_parentAddress(parentAddress)
145 {
146  connect(_parentMenu, &QMenu::aboutToShow, this, &KBookmarkMenu::slotAboutToShow);
147  if (KBookmarkSettings::self()->m_contextmenu) {
149  connect(m_parentMenu, &QWidget::customContextMenuRequested, this, &KBookmarkMenu::slotCustomContextMenu);
150  }
151  m_bDirty = true;
152 }
153 
154 KBookmarkMenu::~KBookmarkMenu()
155 {
156  qDeleteAll(m_lstSubMenus);
157  qDeleteAll(m_actions);
158  delete d;
159 }
160 
162 {
163  slotAboutToShow();
164 }
165 
167 {
168  if (numberOfOpenTabs == d->numberOfOpenTabs) {
169  return;
170  }
171  m_bDirty = (d->numberOfOpenTabs < 2) != (numberOfOpenTabs < 2);
172  d->numberOfOpenTabs = numberOfOpenTabs;
173 }
174 
176 {
177  return d->numberOfOpenTabs;
178 }
179 
180 void KBookmarkMenu::slotAboutToShow()
181 {
182  // Did the bookmarks change since the last time we showed them ?
183  if (m_bDirty) {
184  m_bDirty = false;
185  clear();
186  refill();
187  m_parentMenu->adjustSize();
188  }
189 }
190 
191 void KBookmarkMenu::slotCustomContextMenu(const QPoint &pos)
192 {
193  QAction *action = m_parentMenu->actionAt(pos);
194  QMenu *menu = contextMenu(action);
195  if (!menu) {
196  return;
197  }
199  menu->popup(m_parentMenu->mapToGlobal(pos));
200 }
201 
202 QMenu *KBookmarkMenu::contextMenu(QAction *action)
203 {
204  KBookmarkActionInterface *act = dynamic_cast<KBookmarkActionInterface *>(action);
205  if (!act) {
206  return nullptr;
207  }
208  return new KBookmarkContextMenu(act->bookmark(), m_pManager, m_pOwner);
209 }
210 
211 bool KBookmarkMenu::isRoot() const
212 {
213  return m_bIsRoot;
214 }
215 
216 bool KBookmarkMenu::isDirty() const
217 {
218  return m_bDirty;
219 }
220 
222 {
223  return m_parentAddress;
224 }
225 
226 KBookmarkManager *KBookmarkMenu::manager() const
227 {
228  return m_pManager;
229 }
230 
231 KBookmarkOwner *KBookmarkMenu::owner() const
232 {
233  return m_pOwner;
234 }
235 
237 {
238  return m_parentMenu;
239 }
240 
241 /********************************************************************/
242 /********************************************************************/
243 /********************************************************************/
244 
245 
246 /********************************************************************/
247 /********************************************************************/
248 /********************************************************************/
249 
250 void KBookmarkMenu::slotBookmarksChanged(const QString &groupAddress)
251 {
252  qCDebug(KBOOKMARKS_LOG) << "KBookmarkMenu::slotBookmarksChanged groupAddress: " << groupAddress;
253  if (groupAddress == m_parentAddress) {
254  //qCDebug(KBOOKMARKS_LOG) << "KBookmarkMenu::slotBookmarksChanged -> setting m_bDirty on " << groupAddress;
255  m_bDirty = true;
256  } else {
257  // Iterate recursively into child menus
259  it != end; ++it) {
260  (*it)->slotBookmarksChanged(groupAddress);
261  }
262  }
263 }
264 
265 void KBookmarkMenu::clear()
266 {
267  qDeleteAll(m_lstSubMenus);
269 
271  it != end; ++it) {
272  m_parentMenu->removeAction(*it);
273  delete *it;
274  }
275 
276  m_parentMenu->clear();
277  m_actions.clear();
278 }
279 
280 void KBookmarkMenu::refill()
281 {
282  //qCDebug(KBOOKMARKS_LOG) << "KBookmarkMenu::refill()";
283  if (m_bIsRoot) {
284  addActions();
285  }
286  fillBookmarks();
287  if (!m_bIsRoot) {
288  addActions();
289  }
290 }
291 
292 void KBookmarkMenu::addOpenInTabs()
293 {
294  if (!m_pOwner || !m_pOwner->supportsTabs() ||
295  !KAuthorized::authorizeAction(QStringLiteral("bookmarks"))) {
296  return;
297  }
298 
299  const QString title = tr("Open Folder in Tabs", "@action:inmenu");
300 
301  QAction *paOpenFolderInTabs = new QAction(title, this);
302  paOpenFolderInTabs->setIcon(QIcon::fromTheme(QStringLiteral("tab-new")));
303  paOpenFolderInTabs->setToolTip(tr("Open all bookmarks in this folder as a new tab", "@info:tooltip"));
304  paOpenFolderInTabs->setStatusTip(paOpenFolderInTabs->toolTip());
305  connect(paOpenFolderInTabs, &QAction::triggered, this, &KBookmarkMenu::slotOpenFolderInTabs);
306 
307  m_parentMenu->addAction(paOpenFolderInTabs);
308  m_actions.append(paOpenFolderInTabs);
309 }
310 
311 void KBookmarkMenu::addAddBookmarksList()
312 {
313  if (!m_pOwner || !m_pOwner->enableOption(KBookmarkOwner::ShowAddBookmark) || !m_pOwner->supportsTabs() ||
314  (d->numberOfOpenTabs < 2) || !KAuthorized::authorizeAction(QStringLiteral("bookmarks"))) {
315  return;
316  }
317 
318  if (!d->bookmarksToFolderAction) {
319  const QString title = tr("Bookmark Tabs as Folder...", "@action:inmenu");
320  d->bookmarksToFolderAction = new QAction(title, this);
321 
322  if (m_bIsRoot) {
323  d->bookmarksToFolderAction->setObjectName(QStringLiteral("add_bookmarks_list"));
324  }
325 
326  d->bookmarksToFolderAction->setIcon(QIcon::fromTheme(QStringLiteral("bookmark-new-list")));
327  d->bookmarksToFolderAction->setToolTip(tr("Add a folder of bookmarks for all open tabs", "@info:tooltip"));
328  d->bookmarksToFolderAction->setStatusTip(d->bookmarksToFolderAction->toolTip());
329  connect(d->bookmarksToFolderAction, &QAction::triggered, this, &KBookmarkMenu::slotAddBookmarksList);
330 
331  if (m_actionCollection) {
332  m_actionCollection->addAction(d->bookmarksToFolderAction->objectName(), d->bookmarksToFolderAction);
333  }
334  }
335 
336  m_parentMenu->addAction(d->bookmarksToFolderAction);
337 }
338 
339 void KBookmarkMenu::addAddBookmark()
340 {
341  if (!m_pOwner || !m_pOwner->enableOption(KBookmarkOwner::ShowAddBookmark) ||
342  !KAuthorized::authorizeAction(QStringLiteral("bookmarks"))) {
343  return;
344  }
345 
346  if (!d->addBookmarkAction) {
347  d->addBookmarkAction = KStandardAction::addBookmark(this, SLOT(slotAddBookmark()), this);
348  if (m_bIsRoot) {
349  d->addBookmarkAction->setObjectName(QStringLiteral("add_bookmark"));
350  }
351 
352  if (m_actionCollection) {
353  m_actionCollection->addAction(d->addBookmarkAction->objectName(), d->addBookmarkAction);
354  }
355 
356  if (!m_bIsRoot) {
357  d->addBookmarkAction->setShortcut(QKeySequence());
358  }
359  }
360 
361  m_parentMenu->addAction(d->addBookmarkAction);
362 }
363 
364 void KBookmarkMenu::addEditBookmarks()
365 {
366  if ((m_pOwner && !m_pOwner->enableOption(KBookmarkOwner::ShowEditBookmark)) ||
367  QStandardPaths::findExecutable(QStringLiteral(KEDITBOOKMARKS_BINARY)).isEmpty() ||
368  !KAuthorized::authorizeAction(QStringLiteral("bookmarks"))) {
369  return;
370  }
371 
372  d->editBookmarksAction = KStandardAction::editBookmarks(m_pManager, SLOT(slotEditBookmarks()), this);
373  d->editBookmarksAction->setObjectName(QStringLiteral("edit_bookmarks"));
374 
375  m_parentMenu->addAction(d->editBookmarksAction);
376  d->editBookmarksAction->setToolTip(tr("Edit your bookmark collection in a separate window", "@info:tooltip"));
377  d->editBookmarksAction->setStatusTip(d->editBookmarksAction->toolTip());
378 
379  if (m_actionCollection) {
380  m_actionCollection->addAction(d->editBookmarksAction->objectName(), d->editBookmarksAction);
381  }
382 }
383 
384 void KBookmarkMenu::addNewFolder()
385 {
386  if (!m_pOwner || !m_pOwner->enableOption(KBookmarkOwner::ShowAddBookmark) ||
387  !KAuthorized::authorizeAction(QStringLiteral("bookmarks"))) {
388  return;
389  }
390 
391  if (!d->newBookmarkFolderAction) {
392  d->newBookmarkFolderAction = new QAction(tr("New Bookmark Folder...", "@action:inmenu"), this);
393  d->newBookmarkFolderAction->setIcon(QIcon::fromTheme(QStringLiteral("folder-new")));
394  d->newBookmarkFolderAction->setToolTip(tr("Create a new bookmark folder in this menu", "@info:tooltip"));
395  d->newBookmarkFolderAction->setStatusTip(d->newBookmarkFolderAction->toolTip());
396 
397  if (m_bIsRoot) {
398  d->newBookmarkFolderAction->setObjectName(QStringLiteral("new_bookmark_folder"));
399  }
400 
401  connect(d->newBookmarkFolderAction, &QAction::triggered, this, &KBookmarkMenu::slotNewFolder);
402  }
403 
404  m_parentMenu->addAction(d->newBookmarkFolderAction);
405 
406 }
407 
408 void KBookmarkMenu::fillBookmarks()
409 {
410  KBookmarkGroup parentBookmark = m_pManager->findByAddress(m_parentAddress).toGroup();
411  Q_ASSERT(!parentBookmark.isNull());
412 
413  if (m_bIsRoot && !parentBookmark.first().isNull()) { // at least one bookmark
414  m_parentMenu->addSeparator();
415  }
416 
417  for (KBookmark bm = parentBookmark.first(); !bm.isNull(); bm = parentBookmark.next(bm)) {
418  m_parentMenu->addAction(actionForBookmark(bm));
419  }
420 }
421 
422 QAction *KBookmarkMenu::actionForBookmark(const KBookmark &bm)
423 {
424  if (bm.isGroup()) {
425  //qCDebug(KBOOKMARKS_LOG) << "Creating bookmark submenu named " << bm.text();
426  KActionMenu *actionMenu = new KBookmarkActionMenu(bm, this);
427  m_actions.append(actionMenu);
428  KBookmarkMenu *subMenu = new KBookmarkMenu(m_pManager, m_pOwner, actionMenu->menu(), bm.address());
429  m_lstSubMenus.append(subMenu);
430  return actionMenu;
431  } else if (bm.isSeparator()) {
432  QAction *sa = new QAction(this);
433  sa->setSeparator(true);
434  m_actions.append(sa);
435  return sa;
436  } else {
437  //qCDebug(KBOOKMARKS_LOG) << "Creating bookmark menu item for " << bm.text();
438  QAction *action = new KBookmarkAction(bm, m_pOwner, this);
439  m_actions.append(action);
440  return action;
441  }
442 }
443 
444 void KBookmarkMenu::slotAddBookmarksList()
445 {
446  if (!m_pOwner || !m_pOwner->supportsTabs()) {
447  return;
448  }
449 
450  KBookmarkGroup parentBookmark = m_pManager->findByAddress(m_parentAddress).toGroup();
451 
452  KBookmarkDialog *dlg = m_pOwner->bookmarkDialog(m_pManager, QApplication::activeWindow());
453  dlg->addBookmarks(m_pOwner->currentBookmarkList(), QLatin1String(""), parentBookmark);
454  delete dlg;
455 }
456 
457 void KBookmarkMenu::slotAddBookmark()
458 {
459  if (!m_pOwner) {
460  return;
461  }
462  if (m_pOwner->currentTitle().isEmpty() && m_pOwner->currentUrl().isEmpty()) {
463  return;
464  }
465  KBookmarkGroup parentBookmark = m_pManager->findByAddress(m_parentAddress).toGroup();
466 
467  if (KBookmarkSettings::self()->m_advancedaddbookmark) {
468  KBookmarkDialog *dlg = m_pOwner->bookmarkDialog(m_pManager, QApplication::activeWindow());
469  dlg->addBookmark(m_pOwner->currentTitle(), m_pOwner->currentUrl(), m_pOwner->currentIcon(), parentBookmark);
470  delete dlg;
471  } else {
472  parentBookmark.addBookmark(m_pOwner->currentTitle(), m_pOwner->currentUrl(), m_pOwner->currentIcon());
473  m_pManager->emitChanged(parentBookmark);
474  }
475 
476 }
477 
478 void KBookmarkMenu::slotOpenFolderInTabs()
479 {
480  m_pOwner->openFolderinTabs(m_pManager->findByAddress(m_parentAddress).toGroup());
481 }
482 
483 void KBookmarkMenu::slotNewFolder()
484 {
485  if (!m_pOwner) {
486  return; // this view doesn't handle bookmarks...
487  }
488  KBookmarkGroup parentBookmark = m_pManager->findByAddress(m_parentAddress).toGroup();
489  Q_ASSERT(!parentBookmark.isNull());
490  KBookmarkDialog *dlg = m_pOwner->bookmarkDialog(m_pManager, QApplication::activeWindow());
491  dlg->createNewFolder(QLatin1String(""), parentBookmark);
492  delete dlg;
493 }
494 
496 {
497  return d->addBookmarkAction;
498 }
499 
501 {
502  return d->bookmarksToFolderAction;
503 }
504 
506 {
507  return d->newBookmarkFolderAction;
508 }
509 
511 {
512  return d->editBookmarksAction;
513 }
void customContextMenuRequested(const QPoint &pos)
QList< KBookmarkMenu * > m_lstSubMenus
List of our sub menus.
void clear()
KBookmark addBookmark(const QString &title, const QUrl &url, const QString &icon, KBookmark parent=KBookmark())
Shows a "Add Bookmark" dialog Note: this updates the bookmark and calls KBookmarkManager::emitChanged...
void triggered(bool checked)
void setSeparator(bool b)
KBookmarkGroup createNewFolder(const QString &name, KBookmark parent=KBookmark())
Shows a dialog to create a new folder.
QAction * newBookmarkFolderAction() const
Returns the action for adding a new bookmarks folder.
QAction * addBookmarkAction() const
Returns the action for adding a bookmark.
void ensureUpToDate()
Call ensureUpToDate() if you need KBookmarkMenu to adjust to its final size before it is executed...
void setIcon(const QIcon &icon)
virtual bool enableOption(BookmarkOption option) const
Returns true if action should be shown in the menu The default is to show both a add and editBookmark...
QPoint mapToGlobal(const QPoint &pos) const const
QString findExecutable(const QString &executableName, const QStringList &paths)
QMenu * parentMenu() const
The menu in which we insert our actions Supplied in the constructor.
void setAttribute(Qt::WidgetAttribute attribute, bool on)
virtual QUrl currentUrl() const
This function is called whenever the user wants to add the current page to the bookmarks list...
Q_INVOKABLE QAction * addAction(const QString &name, QAction *action)
This class implements the reading/writing of bookmarks in XML.
virtual QString currentTitle() const
This function is called whenever the user wants to add the current page to the bookmarks list...
void setNumberOfOpenTabs(int numberOfOpenTabs)
Sets the number of currently open tabs.
void adjustSize()
bool isEmpty() const const
QString tr(const char *sourceText, const char *disambiguation, int n)
QAction * addAction(const QString &text)
virtual QList< FutureBookmark > currentBookmarkList() const
Returns a list of bookmark data for the open tabs.
CustomContextMenu
void setToolTip(const QString &tip)
void clear()
QWidget * activeWindow()
void append(const T &value)
void aboutToShow()
void popup(const QPoint &p, QAction *atAction)
QAction * actionAt(const QPoint &pt) const const
QString parentAddress() const
Parent bookmark for this menu.
KBookmark addBookmark(const KBookmark &bm)
Create a new bookmark, as the last child of this group Don&#39;t forget to use KBookmarkManager::self()->...
Definition: kbookmark.cpp:212
bool isEmpty() const const
bool isEmpty() const const
QAction * editBookmarksAction() const
Returns the action for editing bookmarks.
A group of bookmarks.
Definition: kbookmark.h:327
void changed(const QString &groupAddress, const QString &caller)
Signals that the group (or any of its children) with the address groupAddress (e.g.
QAction * addSeparator()
The KBookmarkMenu and KBookmarkBar classes gives the user the ability to either edit bookmarks or add...
This class is a QAction for bookmarks.
QAction * addBookmark(const QObject *recvr, const char *slot, QObject *parent)
virtual QString currentIcon() const
This function is called whenever the user wants to add the current page to the bookmarks list...
virtual void openFolderinTabs(const KBookmarkGroup &bm)
Called if the user wants to open every bookmark in this folder in a new tab.
QList< QAction * > m_actions
List of our actions.
QList::iterator end()
void setContextMenuPolicy(Qt::ContextMenuPolicy policy)
QAction * editBookmarks(const QObject *recvr, const char *slot, QObject *parent)
int numberOfOpenTabs() const
This function returns how many (if any) tabs the application has open.
WA_DeleteOnClose
KBookmark findByAddress(const QString &address)
KBookmarkMenu(KBookmarkManager *mgr, KBookmarkOwner *owner, QMenu *parentMenu, KActionCollection *collec)
Fills a bookmark menu (one instance of KBookmarkMenu is created for the toplevel menu, but also one per submenu).
void emitChanged()
Saves the bookmark file and notifies everyone.
void setStatusTip(const QString &statusTip)
This class provides a bookmark menu.
Definition: kbookmarkmenu.h:60
void removeAction(QAction *action)
virtual bool supportsTabs() const
This function returns whether the owner supports tabs.
KBookmarkGroup addBookmarks(const QList< KBookmarkOwner::FutureBookmark > &list, const QString &name=QString(), KBookmarkGroup parent=KBookmarkGroup())
Creates a folder from a list of bookmarks Note: this updates the bookmark and calls KBookmarkManager:...
QIcon fromTheme(const QString &name)
KCONFIGCORE_EXPORT bool authorizeAction(const QString &action)
QAction * bookmarkTabsAsFolderAction() const
Returns the action for adding all current tabs as bookmarks.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QList< QAction * > actions() const const
QMenu * menu() const const
KBookmark next(const KBookmark &current) const
Return the next sibling of a child bookmark of this group.
Definition: kbookmark.cpp:127
KBookmark first() const
Return the first child bookmark of this group.
Definition: kbookmark.cpp:117
QList::iterator begin()
This class provides a Dialog for editing properties, adding Bookmarks and creating new folders...
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Wed Jul 1 2020 22:38:34 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.