Okular

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

KDE's Doxygen guidelines are available online.