Bookmarks: Resolve symlinks before using an url

If a symlink points to another file, we should use that file as
canonical source for bookmarks, it doesn't make sense to have two
different sets of bookmarks for two paths that are essentially the same
file

BUGS: 424340
This commit is contained in:
Albert Astals Cid 2020-07-23 01:18:59 +02:00
parent 52f07d216e
commit caa351c723
2 changed files with 48 additions and 28 deletions

View file

@ -14,6 +14,7 @@
#include <KBookmarkManager>
#include <KBookmarkMenu>
#include <QDebug>
#include <QFileInfo>
#include <QGuiApplication>
#include <QHash>
#include <QSet>
@ -98,6 +99,15 @@ static inline bool okularBookmarkActionLessThan(QAction *a1, QAction *a2)
return vp1 < vp2;
}
static QUrl mostCanonicalUrl(const QUrl &url)
{
if (!url.isLocalFile())
return url;
const QFileInfo fi(url.toLocalFile());
return QUrl::fromLocalFile(fi.canonicalFilePath());
}
class BookmarkManager::Private : public KBookmarkOwner
{
public:
@ -252,8 +262,9 @@ QList<QUrl> BookmarkManager::files() const
return ret;
}
KBookmark::List BookmarkManager::bookmarks(const QUrl &url) const
KBookmark::List BookmarkManager::bookmarks(const QUrl &documentUrl) const
{
const QUrl url = mostCanonicalUrl(documentUrl);
KBookmark::List ret;
KBookmarkGroup group = d->manager->root();
for (KBookmark bm = group.first(); !bm.isNull(); bm = group.next(bm)) {
@ -388,14 +399,16 @@ void BookmarkManager::addBookmark(const DocumentViewport &vp)
addBookmark(d->url, vp);
}
bool BookmarkManager::addBookmark(const QUrl &referurl, const Okular::DocumentViewport &vp, const QString &title)
bool BookmarkManager::addBookmark(const QUrl &documentUrl, const Okular::DocumentViewport &vp, const QString &title)
{
if (!referurl.isValid() || !vp.isValid())
if (!documentUrl.isValid() || !vp.isValid())
return false;
if (vp.pageNumber < 0 || vp.pageNumber >= d->document->m_pagesVector.count())
return false;
const QUrl referurl = mostCanonicalUrl(documentUrl);
KBookmarkGroup thebg;
QHash<QUrl, QString>::iterator it = d->bookmarkFind(referurl, true, &thebg);
Q_ASSERT(it != d->knownFiles.end());
@ -471,11 +484,13 @@ void BookmarkManager::renameBookmark(KBookmark *bm, const QString &newName)
d->manager->emitChanged(thebg);
}
void BookmarkManager::renameBookmark(const QUrl &referurl, const QString &newName)
void BookmarkManager::renameBookmark(const QUrl &documentUrl, const QString &newName)
{
if (!referurl.isValid())
if (!documentUrl.isValid())
return;
const QUrl referurl = mostCanonicalUrl(documentUrl);
KBookmarkGroup thebg;
QHash<QUrl, QString>::iterator it = d->bookmarkFind(referurl, false, &thebg);
Q_ASSERT(it != d->knownFiles.end());
@ -486,24 +501,26 @@ void BookmarkManager::renameBookmark(const QUrl &referurl, const QString &newNam
d->manager->emitChanged(thebg);
}
QString BookmarkManager::titleForUrl(const QUrl &referurl) const
QString BookmarkManager::titleForUrl(const QUrl &documentUrl) const
{
KBookmarkGroup thebg;
QHash<QUrl, QString>::iterator it = d->bookmarkFind(referurl, false, &thebg);
QHash<QUrl, QString>::iterator it = d->bookmarkFind(mostCanonicalUrl(documentUrl), false, &thebg);
Q_ASSERT(it != d->knownFiles.end());
return thebg.fullText();
}
int BookmarkManager::removeBookmark(const QUrl &referurl, const KBookmark &bm)
int BookmarkManager::removeBookmark(const QUrl &documentUrl, const KBookmark &bm)
{
if (!referurl.isValid() || bm.isNull() || bm.isGroup() || bm.isSeparator())
if (!documentUrl.isValid() || bm.isNull() || bm.isGroup() || bm.isSeparator())
return -1;
DocumentViewport vp(bm.url().fragment(QUrl::FullyDecoded));
if (!vp.isValid())
return -1;
const QUrl referurl = mostCanonicalUrl(documentUrl);
KBookmarkGroup thebg;
QHash<QUrl, QString>::iterator it = d->bookmarkFind(referurl, false, &thebg);
if (it == d->knownFiles.end())
@ -520,11 +537,13 @@ int BookmarkManager::removeBookmark(const QUrl &referurl, const KBookmark &bm)
return vp.pageNumber;
}
void BookmarkManager::removeBookmarks(const QUrl &referurl, const KBookmark::List &list)
void BookmarkManager::removeBookmarks(const QUrl &documentUrl, const KBookmark::List &list)
{
if (!referurl.isValid() || list.isEmpty())
if (!documentUrl.isValid() || list.isEmpty())
return;
const QUrl referurl = mostCanonicalUrl(documentUrl);
KBookmarkGroup thebg;
QHash<QUrl, QString>::iterator it = d->bookmarkFind(referurl, false, &thebg);
if (it == d->knownFiles.end())
@ -560,8 +579,9 @@ void BookmarkManager::removeBookmarks(const QUrl &referurl, const KBookmark::Lis
d->manager->emitChanged(thebg);
}
QList<QAction *> BookmarkManager::actionsForUrl(const QUrl &url) const
QList<QAction *> BookmarkManager::actionsForUrl(const QUrl &documentUrl) const
{
const QUrl url = mostCanonicalUrl(documentUrl);
QList<QAction *> ret;
KBookmarkGroup group = d->manager->root();
for (KBookmark bm = group.first(); !bm.isNull(); bm = group.next(bm)) {
@ -583,10 +603,10 @@ QList<QAction *> BookmarkManager::actionsForUrl(const QUrl &url) const
void BookmarkManager::setUrl(const QUrl &url)
{
d->url = url;
d->url = mostCanonicalUrl(url);
d->urlBookmarks.clear();
KBookmarkGroup thebg;
QHash<QUrl, QString>::iterator it = d->bookmarkFind(url, false, &thebg);
QHash<QUrl, QString>::iterator it = d->bookmarkFind(d->url, false, &thebg);
if (it != d->knownFiles.end()) {
for (KBookmark bm = thebg.first(); !bm.isNull(); bm = thebg.next(bm)) {
if (bm.isSeparator() || bm.isGroup())

View file

@ -43,9 +43,9 @@ public:
QList<QUrl> files() const;
/**
* Returns the list of bookmarks for the specified @p url.
* Returns the list of bookmarks for the specified @p documentUrl.
*/
KBookmark::List bookmarks(const QUrl &url) const;
KBookmark::List bookmarks(const QUrl &documentUrl) const;
/**
* Returns the list of bookmarks for document
@ -88,12 +88,12 @@ public:
void addBookmark(const DocumentViewport &vp);
/**
* Adds a new bookmark for the @p referurl at the specified viewport @p vp,
* Adds a new bookmark for the @p documentUrl at the specified viewport @p vp,
* with an optional @p title.
*
* If no @p title is specified, then \em \#n will be used.
*/
bool addBookmark(const QUrl &referurl, const Okular::DocumentViewport &vp, const QString &title = QString());
bool addBookmark(const QUrl &documentUrl, const Okular::DocumentViewport &vp, const QString &title = QString());
/**
* Remove a bookmark for the given @p page.
@ -107,18 +107,18 @@ public:
void removeBookmark(const DocumentViewport &vp);
/**
* Removes the bookmark @p bm for the @p referurl specified.
* Removes the bookmark @p bm for the @p documentUrl specified.
*/
int removeBookmark(const QUrl &referurl, const KBookmark &bm);
int removeBookmark(const QUrl &documentUrl, const KBookmark &bm);
/**
* Removes the bookmarks in @p list for the @p referurl specified.
* Removes the bookmarks in @p list for the @p documentUrl specified.
*
* @note it will remove only the bookmarks which belong to @p referurl
* @note it will remove only the bookmarks which belong to @p documentUrl
*
* @since 0.11 (KDE 4.5)
*/
void removeBookmarks(const QUrl &referurl, const KBookmark::List &list);
void removeBookmarks(const QUrl &documentUrl, const KBookmark::List &list);
/**
* Returns the bookmark given bookmark of the document
@ -127,17 +127,17 @@ public:
void renameBookmark(KBookmark *bm, const QString &newName);
/**
* Renames the top-level bookmark for the @p referurl specified with
* Renames the top-level bookmark for the @p documentUrl specified with
* the @p newName specified.
* @since 0.15 (KDE 4.9)
*/
void renameBookmark(const QUrl &referurl, const QString &newName);
void renameBookmark(const QUrl &documentUrl, const QString &newName);
/**
* Returns title for the @p referurl
* Returns title for the @p documentUrl
* @since 0.15 (KDE 4.9)
*/
QString titleForUrl(const QUrl &referurl) const;
QString titleForUrl(const QUrl &documentUrl) const;
/**
* Returns whether the given @p page is bookmarked.
@ -168,7 +168,7 @@ public:
* @note the actions will have no parents, so you have to delete them
* yourself
*/
QList<QAction *> actionsForUrl(const QUrl &url) const;
QList<QAction *> actionsForUrl(const QUrl &documentUrl) const;
Q_SIGNALS:
/**