Okular

bookmarkmanager.cpp
1 /*
2  SPDX-FileCopyrightText: 2006 Pino Toscano <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #include "bookmarkmanager.h"
8 
9 // qt/kde includes
10 #include <KBookmarkAction>
11 #include <KBookmarkManager>
12 #include <KBookmarkMenu>
13 #include <KBookmarkOwner>
14 #include <QDebug>
15 #include <QFileInfo>
16 #include <QGuiApplication>
17 #include <QHash>
18 #include <QSet>
19 #include <QStandardPaths>
20 #include <QUrl>
21 
22 // local includes
23 #include "document_p.h"
24 #include "observer.h"
25 
26 using namespace Okular;
27 
28 #define foreachObserver(cmd) \
29  { \
30  QSet<DocumentObserver *>::const_iterator it = d->document->m_observers.constBegin(), end = d->document->m_observers.constEnd(); \
31  for (; it != end; ++it) { \
32  (*it)->cmd; \
33  } \
34  }
35 
36 #define foreachObserverD(cmd) \
37  { \
38  QSet<DocumentObserver *>::const_iterator it = document->m_observers.constBegin(), end = document->m_observers.constEnd(); \
39  for (; it != end; ++it) { \
40  (*it)->cmd; \
41  } \
42  }
43 
44 class OkularBookmarkAction : public KBookmarkAction
45 {
46  Q_OBJECT
47 public:
48  OkularBookmarkAction(const Okular::DocumentViewport &vp, const KBookmark &bk, KBookmarkOwner *owner, QObject *parent)
49  : KBookmarkAction(bk, owner, parent)
50  {
51  if (vp.isValid()) {
52  setText(QString::number(vp.pageNumber + 1) + QStringLiteral(" - ") + text());
53  }
54  setProperty("pageNumber", vp.pageNumber + 1);
55  setProperty("htmlRef", bk.url().fragment(QUrl::FullyDecoded));
56  }
57 
58  inline int pageNumber() const
59  {
60  return property("pageNumber").toInt();
61  }
62 
63  inline QString htmlRef() const
64  {
65  return property("htmlRef").toString();
66  }
67 };
68 
69 static inline bool documentViewportFuzzyCompare(const DocumentViewport &vp1, const DocumentViewport &vp2)
70 {
71  bool equal = vp1.isValid() && vp2.isValid() && (vp1.pageNumber == vp2.pageNumber) && (vp1.rePos.pos == vp2.rePos.pos);
72 
73  if (!equal) {
74  return false;
75  }
76 
77  if (qAbs(vp1.rePos.normalizedX - vp2.rePos.normalizedX) >= 0.000001) {
78  return false;
79  }
80 
81  if (qAbs(vp1.rePos.normalizedY - vp2.rePos.normalizedY) >= 0.000001) {
82  return false;
83  }
84 
85  return true;
86 }
87 
88 static inline bool bookmarkLessThan(const KBookmark &b1, const KBookmark &b2)
89 {
92 
93  return vp1 < vp2;
94 }
95 
96 static inline bool okularBookmarkActionLessThan(QAction *a1, QAction *a2)
97 {
98  DocumentViewport vp1(static_cast<OkularBookmarkAction *>(a1)->htmlRef());
99  DocumentViewport vp2(static_cast<OkularBookmarkAction *>(a2)->htmlRef());
100 
101  return vp1 < vp2;
102 }
103 
104 static QUrl mostCanonicalUrl(const QUrl &url)
105 {
106  if (!url.isLocalFile()) {
107  return url;
108  }
109 
110  const QFileInfo fi(url.toLocalFile());
111  return QUrl::fromLocalFile(fi.canonicalFilePath());
112 }
113 
114 class BookmarkManager::Private : public KBookmarkOwner
115 {
116 public:
117  explicit Private(BookmarkManager *qq)
118  : KBookmarkOwner()
119  , q(qq)
120  , document(nullptr)
121  , manager(nullptr)
122  {
123  }
124 
125  ~Private() override
126  {
127  knownFiles.clear();
128  // no need to delete the manager, it's automatically done by KBookmarkManager
129  // delete manager;
130  }
131 
132  Private(const Private &) = delete;
133  Private &operator=(const Private &) = delete;
134 
135  QUrl currentUrl() const override;
136  QString currentTitle() const override;
137  bool enableOption(BookmarkOption option) const override;
138  void openBookmark(const KBookmark &bm, Qt::MouseButtons, Qt::KeyboardModifiers) override;
139 
140  QHash<QUrl, QString>::iterator bookmarkFind(const QUrl &url, bool doCreate, KBookmarkGroup *result = nullptr);
141 
142  // slots
143  void _o_changed(const QString &groupAddress, const QString &caller);
144 
145  BookmarkManager *q;
146  QUrl url;
147  QHash<int, int> urlBookmarks;
148  DocumentPrivate *document;
149  QString file;
150  KBookmarkManager *manager;
151  QHash<QUrl, QString> knownFiles;
152 };
153 
154 static inline QUrl urlForGroup(const KBookmark &group)
155 {
156  if (group.url().isValid()) {
157  return group.url();
158  } else {
159  return QUrl::fromUserInput(group.fullText());
160  }
161 }
162 
163 BookmarkManager::BookmarkManager(DocumentPrivate *document)
164  : QObject(document->m_parent)
165  , d(new Private(this))
166 {
167  setObjectName(QStringLiteral("Okular::BookmarkManager"));
168 
169  d->document = document;
170 
171  d->file = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/okular/bookmarks.xml");
172 
173  d->manager = KBookmarkManager::managerForFile(d->file, QStringLiteral("okular"));
174  d->manager->setEditorOptions(QGuiApplication::applicationDisplayName(), false);
175  d->manager->setUpdate(true);
176  connect(d->manager, &KBookmarkManager::changed, this, [this](const QString &groupAddress, const QString &caller) { d->_o_changed(groupAddress, caller); });
177 }
178 
179 BookmarkManager::~BookmarkManager()
180 {
181  delete d;
182 }
183 
184 // BEGIN Reimplementations from KBookmarkOwner
185 QUrl BookmarkManager::Private::currentUrl() const
186 {
187  return url;
188 }
189 
190 QString BookmarkManager::Private::currentTitle() const
191 {
192  return url.toDisplayString();
193 }
194 
195 bool BookmarkManager::Private::enableOption(BookmarkOption option) const
196 {
197  Q_UNUSED(option)
198  return false;
199 }
200 
201 void BookmarkManager::Private::openBookmark(const KBookmark &bm, Qt::MouseButtons, Qt::KeyboardModifiers)
202 {
203  Q_EMIT q->openUrl(bm.url());
204 }
205 // END Reimplementations from KBookmarkOwner
206 
207 void BookmarkManager::Private::_o_changed(const QString &groupAddress, const QString &caller)
208 {
209  Q_UNUSED(caller);
210  if (groupAddress.isEmpty()) {
211  return;
212  }
213 
214  QUrl referurl;
215  // first, try to find the bookmark group whom change notification was just received
216  QHash<QUrl, QString>::iterator it = knownFiles.begin(), itEnd = knownFiles.end();
217  for (; it != itEnd; ++it) {
218  if (it.value() == groupAddress) {
219  referurl = it.key();
220  knownFiles.erase(it);
221  break;
222  }
223  }
224  if (!referurl.isValid()) {
225  const KBookmark bm = manager->findByAddress(groupAddress);
226  // better be safe than sorry
227  if (bm.isNull()) {
228  return;
229  }
230  Q_ASSERT(bm.isGroup());
231  referurl = urlForGroup(bm);
232  }
233  Q_ASSERT(referurl.isValid());
234  Q_EMIT q->bookmarksChanged(referurl);
235  // case for the url representing the current document
236  // (this might happen if the same document is open in another place;
237  // in such case, make really sure to be in sync)
238  if (referurl == url) {
239  // save the old bookmarks for the current url
240  const QHash<int, int> oldUrlBookmarks = urlBookmarks;
241  // set the same url again, so we reload the information we have about it
242  q->setUrl(referurl);
243  // then notify the observers about the changes in the bookmarks
244  for (int i = 0; i < qMax(oldUrlBookmarks.size(), urlBookmarks.size()); i++) {
245  bool oldContains = oldUrlBookmarks.contains(i) && oldUrlBookmarks[i] > 0;
246  bool curContains = urlBookmarks.contains(i) && urlBookmarks[i] > 0;
247 
248  if (oldContains != curContains) {
249  foreachObserverD(notifyPageChanged(i, DocumentObserver::Bookmark));
250  } else if (oldContains && oldUrlBookmarks[i] != urlBookmarks[i]) {
251  foreachObserverD(notifyPageChanged(i, DocumentObserver::Bookmark));
252  }
253  }
254  }
255  Q_EMIT q->saved();
256 }
257 
259 {
260  QList<QUrl> ret;
261  KBookmarkGroup group = d->manager->root();
262  for (KBookmark bm = group.first(); !bm.isNull(); bm = group.next(bm)) {
263  if (bm.isSeparator() || !bm.isGroup()) {
264  continue;
265  }
266 
267  ret.append(urlForGroup(bm));
268  }
269  return ret;
270 }
271 
273 {
274  const QUrl url = mostCanonicalUrl(documentUrl);
275  KBookmark::List ret;
276  KBookmarkGroup group = d->manager->root();
277  for (KBookmark bm = group.first(); !bm.isNull(); bm = group.next(bm)) {
278  if (!bm.isGroup() || urlForGroup(bm) != url) {
279  continue;
280  }
281 
282  KBookmarkGroup group = bm.toGroup();
283  for (KBookmark b = group.first(); !b.isNull(); b = group.next(b)) {
284  if (b.isSeparator() || b.isGroup()) {
285  continue;
286  }
287 
288  ret.append(b);
289  }
290  break;
291  }
292 
293  return ret;
294 }
295 
297 {
298  return bookmarks(d->url);
299 }
300 
302 {
303  const KBookmark::List bmarks = bookmarks();
304  KBookmark::List ret;
305  for (const KBookmark &bm : bmarks) {
307  if (vp.isValid() && vp.pageNumber == page) {
308  ret.append(bm);
309  }
310  }
311 
312  return ret;
313 }
314 
316 {
317  const KBookmark::List bmarks = bookmarks();
318  for (const KBookmark &bm : bmarks) {
320  if (vp.isValid() && vp.pageNumber == page) {
321  return bm;
322  }
323  }
324  return KBookmark();
325 }
326 
328 {
329  if (!viewport.isValid() || !isBookmarked(viewport.pageNumber)) {
330  return KBookmark();
331  }
332 
333  KBookmarkGroup thebg;
334  QHash<QUrl, QString>::iterator it = d->bookmarkFind(d->url, false, &thebg);
335  if (it == d->knownFiles.end()) {
336  return KBookmark();
337  }
338 
339  for (KBookmark bm = thebg.first(); !bm.isNull(); bm = thebg.next(bm)) {
340  if (bm.isSeparator() || bm.isGroup()) {
341  continue;
342  }
343 
345  if (documentViewportFuzzyCompare(vp, viewport)) {
346  return bm;
347  }
348  }
349 
350  return KBookmark();
351 }
352 
354 {
355  d->manager->emitChanged();
356  Q_EMIT const_cast<BookmarkManager *>(this)->saved();
357 }
358 
359 QHash<QUrl, QString>::iterator BookmarkManager::Private::bookmarkFind(const QUrl &url, bool doCreate, KBookmarkGroup *result)
360 {
361  QHash<QUrl, QString>::iterator it = knownFiles.find(url);
362  if (it == knownFiles.end()) {
363  // if the url we want to add a new entry for is not in the hash of the
364  // known files, then first try to find the file among the top-level
365  // "folder" names
366  bool found = false;
367  KBookmarkGroup root = manager->root();
368  for (KBookmark bm = root.first(); !found && !bm.isNull(); bm = root.next(bm)) {
369  if (bm.isSeparator() || !bm.isGroup()) {
370  continue;
371  }
372 
373  QUrl tmpurl(urlForGroup(bm));
374  if (tmpurl == url) {
375  // got it! place it the hash of known files
376  KBookmarkGroup bg = bm.toGroup();
377  it = knownFiles.insert(url, bg.address());
378  found = true;
379  if (result) {
380  *result = bg;
381  }
382  break;
383  }
384  }
385  if (!found && doCreate) {
386  // folder not found :(
387  // then, in a single step create a new folder and add it in our cache :)
388  QString purl = url.isLocalFile() ? url.toLocalFile() : url.toDisplayString();
389  KBookmarkGroup newbg = root.createNewFolder(purl);
390  newbg.setUrl(url);
391  it = knownFiles.insert(url, newbg.address());
392  if (result) {
393  *result = newbg;
394  }
395  }
396  } else if (result) {
397  const KBookmark bm = manager->findByAddress(it.value());
398  Q_ASSERT(bm.isGroup());
399  *result = bm.toGroup();
400  }
401  return it;
402 }
403 
405 {
406  if (page >= 0 && page < (int)d->document->m_pagesVector.count()) {
407  if (setPageBookmark(page))
408  foreachObserver(notifyPageChanged(page, DocumentObserver::Bookmark));
409  }
410 }
411 
413 {
414  addBookmark(d->url, vp);
415 }
416 
417 bool BookmarkManager::addBookmark(const QUrl &documentUrl, const Okular::DocumentViewport &vp, const QString &title)
418 {
419  if (!documentUrl.isValid() || !vp.isValid()) {
420  return false;
421  }
422 
423  if (vp.pageNumber < 0 || vp.pageNumber >= d->document->m_pagesVector.count()) {
424  return false;
425  }
426 
427  const QUrl referurl = mostCanonicalUrl(documentUrl);
428 
429  KBookmarkGroup thebg;
430  QHash<QUrl, QString>::iterator it = d->bookmarkFind(referurl, true, &thebg);
431  Q_ASSERT(it != d->knownFiles.end());
432 
433  int count = 0; // Number of bookmarks in the current page
434  bool found = false;
435  // Check if the bookmark already exists
436  for (KBookmark bm = thebg.first(); !found && !bm.isNull(); bm = thebg.next(bm)) {
437  if (bm.isSeparator() || bm.isGroup()) {
438  continue;
439  }
440 
442  if (bmViewport.isValid() && bmViewport.pageNumber == vp.pageNumber) {
443  ++count;
444 
445  if (documentViewportFuzzyCompare(bmViewport, vp)) {
446  found = true;
447  }
448  }
449  }
450 
451  if (found) {
452  return false;
453  }
454 
455  QString newtitle;
456  if (title.isEmpty()) {
457  // if we have no title specified for the new bookmark, then give it the
458  // name '#p' where p is the page number where the bookmark is located.
459  // if there's more than one bookmark per page, give the name '#p-n'
460  // where n is the index of this bookmark among the ones of its page.
461  if (count > 0) {
462  newtitle = QStringLiteral("#%1-%2").arg(vp.pageNumber + 1).arg(count);
463  } else {
464  newtitle = QStringLiteral("#%1").arg(vp.pageNumber + 1);
465  }
466  } else {
467  newtitle = title;
468  }
469 
470  QUrl newurl = referurl;
471  newurl.setFragment(vp.toString(), QUrl::DecodedMode);
472  thebg.addBookmark(newtitle, newurl, QString());
473  if (referurl == d->document->m_url) {
474  d->urlBookmarks[vp.pageNumber]++;
475  foreachObserver(notifyPageChanged(vp.pageNumber, DocumentObserver::Bookmark));
476  }
477  d->manager->emitChanged(thebg);
478  return true;
479 }
480 
482 {
483  if (page >= 0 && page < (int)d->document->m_pagesVector.count()) {
484  if (removePageBookmark(page))
485  foreachObserver(notifyPageChanged(page, DocumentObserver::Bookmark));
486  }
487 }
488 
490 {
491  int page = vp.pageNumber;
492  if (page >= 0 && page < d->document->m_pagesVector.count()) {
493  removeBookmark(d->url, bookmark(vp));
494  }
495 }
496 
498 {
499  KBookmarkGroup thebg;
500  QHash<QUrl, QString>::iterator it = d->bookmarkFind(d->url, false, &thebg);
501  Q_ASSERT(it != d->knownFiles.end());
502  if (it == d->knownFiles.end()) {
503  return;
504  }
505 
506  bm->setFullText(newName);
507  d->manager->emitChanged(thebg);
508 }
509 
510 void BookmarkManager::renameBookmark(const QUrl &documentUrl, const QString &newName)
511 {
512  if (!documentUrl.isValid()) {
513  return;
514  }
515 
516  const QUrl referurl = mostCanonicalUrl(documentUrl);
517 
518  KBookmarkGroup thebg;
519  QHash<QUrl, QString>::iterator it = d->bookmarkFind(referurl, false, &thebg);
520  Q_ASSERT(it != d->knownFiles.end());
521  if (it == d->knownFiles.end()) {
522  return;
523  }
524 
525  thebg.setFullText(newName);
526  d->manager->emitChanged(thebg);
527 }
528 
529 QString BookmarkManager::titleForUrl(const QUrl &documentUrl) const
530 {
531  KBookmarkGroup thebg;
532  QHash<QUrl, QString>::iterator it = d->bookmarkFind(mostCanonicalUrl(documentUrl), false, &thebg);
533  Q_ASSERT(it != d->knownFiles.end());
534 
535  return thebg.fullText();
536 }
537 
538 int BookmarkManager::removeBookmark(const QUrl &documentUrl, const KBookmark &bm)
539 {
540  if (!documentUrl.isValid() || bm.isNull() || bm.isGroup() || bm.isSeparator()) {
541  return -1;
542  }
543 
545  if (!vp.isValid()) {
546  return -1;
547  }
548 
549  const QUrl referurl = mostCanonicalUrl(documentUrl);
550 
551  KBookmarkGroup thebg;
552  QHash<QUrl, QString>::iterator it = d->bookmarkFind(referurl, false, &thebg);
553  if (it == d->knownFiles.end()) {
554  return -1;
555  }
556 
557  thebg.deleteBookmark(bm);
558 
559  if (referurl == d->document->m_url) {
560  d->urlBookmarks[vp.pageNumber]--;
561  foreachObserver(notifyPageChanged(vp.pageNumber, DocumentObserver::Bookmark));
562  }
563  d->manager->emitChanged(thebg);
564 
565  return vp.pageNumber;
566 }
567 
568 void BookmarkManager::removeBookmarks(const QUrl &documentUrl, const KBookmark::List &list)
569 {
570  if (!documentUrl.isValid() || list.isEmpty()) {
571  return;
572  }
573 
574  const QUrl referurl = mostCanonicalUrl(documentUrl);
575 
576  KBookmarkGroup thebg;
577  QHash<QUrl, QString>::iterator it = d->bookmarkFind(referurl, false, &thebg);
578  if (it == d->knownFiles.end()) {
579  return;
580  }
581 
582  const QHash<int, int> oldUrlBookmarks = d->urlBookmarks;
583  bool deletedAny = false;
584  for (const KBookmark &bm : list) {
585  if (bm.parentGroup() == thebg) {
586  thebg.deleteBookmark(bm);
587  deletedAny = true;
588 
590  if (referurl == d->document->m_url) {
591  d->urlBookmarks[vp.pageNumber]--;
592  }
593  }
594  }
595 
596  if (referurl == d->document->m_url) {
597  for (int i = 0; i < qMax(oldUrlBookmarks.size(), d->urlBookmarks.size()); i++) {
598  bool oldContains = oldUrlBookmarks.contains(i) && oldUrlBookmarks[i] > 0;
599  bool curContains = d->urlBookmarks.contains(i) && d->urlBookmarks[i] > 0;
600 
601  if (oldContains != curContains) {
602  foreachObserver(notifyPageChanged(i, DocumentObserver::Bookmark));
603  } else if (oldContains && oldUrlBookmarks[i] != d->urlBookmarks[i]) {
604  foreachObserver(notifyPageChanged(i, DocumentObserver::Bookmark));
605  }
606  }
607  }
608  if (deletedAny) {
609  d->manager->emitChanged(thebg);
610  }
611 }
612 
614 {
615  const QUrl url = mostCanonicalUrl(documentUrl);
616  QList<QAction *> ret;
617  KBookmarkGroup group = d->manager->root();
618  for (KBookmark bm = group.first(); !bm.isNull(); bm = group.next(bm)) {
619  if (!bm.isGroup() || urlForGroup(bm) != url) {
620  continue;
621  }
622 
623  KBookmarkGroup group = bm.toGroup();
624  for (KBookmark b = group.first(); !b.isNull(); b = group.next(b)) {
625  if (b.isSeparator() || b.isGroup()) {
626  continue;
627  }
628 
629  ret.append(new OkularBookmarkAction(DocumentViewport(b.url().fragment(QUrl::FullyDecoded)), b, d, nullptr));
630  }
631  break;
632  }
633  std::sort(ret.begin(), ret.end(), okularBookmarkActionLessThan);
634  return ret;
635 }
636 
637 void BookmarkManager::setUrl(const QUrl &url)
638 {
639  d->url = mostCanonicalUrl(url);
640  d->urlBookmarks.clear();
641  KBookmarkGroup thebg;
642  QHash<QUrl, QString>::iterator it = d->bookmarkFind(d->url, false, &thebg);
643  if (it != d->knownFiles.end()) {
644  for (KBookmark bm = thebg.first(); !bm.isNull(); bm = thebg.next(bm)) {
645  if (bm.isSeparator() || bm.isGroup()) {
646  continue;
647  }
648 
650  if (!vp.isValid()) {
651  continue;
652  }
653 
654  d->urlBookmarks[vp.pageNumber]++;
655  }
656  }
657 }
658 
659 bool BookmarkManager::setPageBookmark(int page)
660 {
661  KBookmarkGroup thebg;
662  QHash<QUrl, QString>::iterator it = d->bookmarkFind(d->url, true, &thebg);
663  Q_ASSERT(it != d->knownFiles.end());
664 
665  bool found = false;
666  bool added = false;
667  for (KBookmark bm = thebg.first(); !found && !bm.isNull(); bm = thebg.next(bm)) {
668  if (bm.isSeparator() || bm.isGroup()) {
669  continue;
670  }
671 
673  if (vp.isValid() && vp.pageNumber == page) {
674  found = true;
675  }
676  }
677  if (!found) {
678  d->urlBookmarks[page]++;
679  DocumentViewport vp;
680  vp.pageNumber = page;
681  QUrl newurl = d->url;
682  newurl.setFragment(vp.toString(), QUrl::DecodedMode);
683  thebg.addBookmark(QLatin1String("#") + QString::number(vp.pageNumber + 1), newurl, QString());
684  added = true;
685  d->manager->emitChanged(thebg);
686  }
687  return added;
688 }
689 
690 bool BookmarkManager::removePageBookmark(int page)
691 {
692  KBookmarkGroup thebg;
693  QHash<QUrl, QString>::iterator it = d->bookmarkFind(d->url, false, &thebg);
694  if (it == d->knownFiles.end()) {
695  return false;
696  }
697 
698  bool found = false;
699  for (KBookmark bm = thebg.first(); !found && !bm.isNull(); bm = thebg.next(bm)) {
700  if (bm.isSeparator() || bm.isGroup()) {
701  continue;
702  }
703 
705  if (vp.isValid() && vp.pageNumber == page) {
706  found = true;
707  thebg.deleteBookmark(bm);
708  d->urlBookmarks[page]--;
709  d->manager->emitChanged(thebg);
710  }
711  }
712  return found;
713 }
714 
715 bool BookmarkManager::isBookmarked(int page) const
716 {
717  return d->urlBookmarks.contains(page) && d->urlBookmarks[page] > 0;
718 }
719 
721 {
722  KBookmark bm = bookmark(viewport);
723 
724  return !bm.isNull();
725 }
726 
728 {
729  KBookmark::List bmarks = bookmarks();
730  std::sort(bmarks.begin(), bmarks.end(), bookmarkLessThan);
731 
733  for (const KBookmark &bm : qAsConst(bmarks)) {
735  if (viewport < vp) {
736  bookmark = bm;
737  break;
738  }
739  }
740 
741  return bookmark;
742 }
743 
745 {
746  KBookmark::List bmarks = bookmarks();
747  std::sort(bmarks.begin(), bmarks.end(), bookmarkLessThan);
748 
750  for (KBookmark::List::const_iterator it = bmarks.constEnd(); it != bmarks.constBegin(); --it) {
751  KBookmark bm = *(it - 1);
753  if (vp < viewport) {
754  bookmark = bm;
755  break;
756  }
757  }
758 
759  return bookmark;
760 }
761 
762 #undef foreachObserver
763 #undef foreachObserverD
764 
765 #include "bookmarkmanager.moc"
766 
767 /* kate: replace-tabs on; indent-width 4; */
void append(const T &value)
QString toString() const
Returns the viewport as xml description.
Definition: document.cpp:5646
bool isBookmarked(int page) const
Returns whether the given page is bookmarked.
const T value(const Key &key) const const
QString number(int n, int base)
KBookmark bookmark(int page) const
Returns the bookmark for the given page of the document.
QString titleForUrl(const QUrl &documentUrl) const
Returns title for the documentUrl.
The documentation to the global Okular namespace.
Definition: action.h:16
KBookmark previousBookmark(const DocumentViewport &viewport) const
Given a viewport, returns the previous bookmark.
Q_EMITQ_EMIT
struct Okular::DocumentViewport::@0 rePos
If 'rePos.enabled == true' then this structure contains the viewport center or top left depending on ...
KBookmarkGroup createNewFolder(const QString &text)
QHash::iterator begin()
QHash::iterator find(const Key &key)
bool isSeparator() const
void changed(const QString &groupAddress, const QString &caller)
QCA_EXPORT void setProperty(const QString &name, const QVariant &value)
QString writableLocation(QStandardPaths::StandardLocation type)
KBookmark first() const
QList::const_iterator constBegin() const const
void setUrl(const QUrl &url)
typedef MouseButtons
KBookmark nextBookmark(const DocumentViewport &viewport) const
Given a viewport, returns the next bookmark.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QString address() const
void setFullText(const QString &fullText)
QHash::iterator insert(const Key &key, const T &value)
QList< QAction * > actionsForUrl(const QUrl &documentUrl) const
Returns a list of actions for the bookmarks of the specified url.
void deleteBookmark(const KBookmark &bk)
KBookmark::List bookmarks() const
Returns the list of bookmarks for document.
bool isValid() const const
void save() const
Forces to save the list of bookmarks.
KBookmark next(const KBookmark &current) const
int size() const const
FullyDecoded
Bookmarks manager utility.
int pageNumber
The number of the page nearest the center of the viewport.
Definition: document.h:1381
KBookmarkGroup toGroup() const
bool isEmpty() const const
QUrl fromLocalFile(const QString &localFile)
const Key key(const T &value) const const
QString toDisplayString(QUrl::FormattingOptions options) const const
bool isNull() const
void renameBookmark(KBookmark *bm, const QString &newName)
Returns the bookmark given bookmark of the document.
bool isEmpty() const const
QString toLocalFile() const const
QUrl url() const
KBookmark addBookmark(const KBookmark &bm)
A view on the document.
Definition: document.h:1349
bool isValid() const
Returns whether the viewport is valid.
Definition: document.cpp:5661
void removeBookmarks(const QUrl &documentUrl, const KBookmark::List &list)
Removes the bookmarks in list for the documentUrl specified.
QString fragment(QUrl::ComponentFormattingOptions options) const const
QString fullText() const
QList::const_iterator constEnd() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
void setObjectName(const QString &name)
void addBookmark(int page)
Adds a bookmark for the given page.
static KBookmarkManager * managerForFile(const QString &bookmarksFile, const QString &dbusObjectName)
bool isLocalFile() const const
KBookmarkGroup parentGroup() const
void setFragment(const QString &fragment, QUrl::ParsingMode mode)
QList::iterator begin()
void saved()
This signal is emitted whenever bookmarks have been saved.
bool isGroup() const
bool contains(const Key &key) const const
QList::iterator end()
typedef KeyboardModifiers
void removeBookmark(int page)
Remove a bookmark for the given page.
QUrl fromUserInput(const QString &userInput)
QList< QUrl > files() const
Returns the list of documents with bookmarks.
@ Bookmark
Bookmarks has been changed.
Definition: observer.h:46
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Tue Sep 26 2023 04:06:53 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.