| /* poppler-link.cc: qt interface to poppler | 
 |  * Copyright (C) 2006-2007, 2013, 2016-2021, Albert Astals Cid | 
 |  * Copyright (C) 2007-2008, Pino Toscano <pino@kde.org> | 
 |  * Copyright (C) 2010 Hib Eris <hib@hiberis.nl> | 
 |  * Copyright (C) 2012, Tobias Koenig <tokoe@kdab.com> | 
 |  * Copyright (C) 2012, Guillermo A. Amaral B. <gamaral@kde.org> | 
 |  * Copyright (C) 2018 Intevation GmbH <intevation@intevation.de> | 
 |  * Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de> | 
 |  * Copyright (C) 2020 Oliver Sander <oliver.sander@tu-dresden.de> | 
 |  * Adapting code from | 
 |  *   Copyright (C) 2004 by Enrico Ros <eros.kde@email.it> | 
 |  * | 
 |  * This program is free software; you can redistribute it and/or modify | 
 |  * it under the terms of the GNU General Public License as published by | 
 |  * the Free Software Foundation; either version 2, or (at your option) | 
 |  * any later version. | 
 |  * | 
 |  * This program is distributed in the hope that it will be useful, | 
 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 |  * GNU General Public License for more details. | 
 |  * | 
 |  * You should have received a copy of the GNU General Public License | 
 |  * along with this program; if not, write to the Free Software | 
 |  * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. | 
 |  */ | 
 |  | 
 | #include <poppler-qt5.h> | 
 | #include <poppler-link-private.h> | 
 | #include <poppler-private.h> | 
 | #include <poppler-media.h> | 
 |  | 
 | #include <QtCore/QStringList> | 
 |  | 
 | #include "poppler-annotation-private.h" | 
 |  | 
 | #include "Link.h" | 
 | #include "Rendition.h" | 
 |  | 
 | namespace Poppler { | 
 |  | 
 | class LinkDestinationPrivate : public QSharedData | 
 | { | 
 | public: | 
 |     LinkDestinationPrivate(); | 
 |  | 
 |     LinkDestination::Kind kind; // destination type | 
 |     QString name; | 
 |     int pageNum; // page number | 
 |     double left, bottom; // position | 
 |     double right, top; | 
 |     double zoom; // zoom factor | 
 |     bool changeLeft : 1, changeTop : 1; // for destXYZ links, which position | 
 |     bool changeZoom : 1; //   components to change | 
 | }; | 
 |  | 
 | LinkDestinationPrivate::LinkDestinationPrivate() | 
 | { | 
 |     // sane defaults | 
 |     kind = LinkDestination::destXYZ; | 
 |     pageNum = 0; | 
 |     left = 0; | 
 |     bottom = 0; | 
 |     right = 0; | 
 |     top = 0; | 
 |     zoom = 1; | 
 |     changeLeft = true; | 
 |     changeTop = true; | 
 |     changeZoom = false; | 
 | } | 
 |  | 
 | LinkPrivate::~LinkPrivate() | 
 | { | 
 |     qDeleteAll(nextLinks); | 
 | } | 
 |  | 
 | LinkOCGStatePrivate::~LinkOCGStatePrivate() = default; | 
 |  | 
 | LinkHidePrivate::~LinkHidePrivate() = default; | 
 |  | 
 | class LinkGotoPrivate : public LinkPrivate | 
 | { | 
 | public: | 
 |     LinkGotoPrivate(const QRectF &area, const LinkDestination &dest); | 
 |     ~LinkGotoPrivate() override; | 
 |  | 
 |     QString extFileName; | 
 |     LinkDestination destination; | 
 | }; | 
 |  | 
 | LinkGotoPrivate::LinkGotoPrivate(const QRectF &area, const LinkDestination &dest) : LinkPrivate(area), destination(dest) { } | 
 | LinkGotoPrivate::~LinkGotoPrivate() = default; | 
 |  | 
 | class LinkExecutePrivate : public LinkPrivate | 
 | { | 
 | public: | 
 |     explicit LinkExecutePrivate(const QRectF &area); | 
 |     ~LinkExecutePrivate() override; | 
 |  | 
 |     QString fileName; | 
 |     QString parameters; | 
 | }; | 
 |  | 
 | LinkExecutePrivate::LinkExecutePrivate(const QRectF &area) : LinkPrivate(area) { } | 
 | LinkExecutePrivate::~LinkExecutePrivate() = default; | 
 |  | 
 | class LinkBrowsePrivate : public LinkPrivate | 
 | { | 
 | public: | 
 |     explicit LinkBrowsePrivate(const QRectF &area); | 
 |     ~LinkBrowsePrivate() override; | 
 |  | 
 |     QString url; | 
 | }; | 
 |  | 
 | LinkBrowsePrivate::LinkBrowsePrivate(const QRectF &area) : LinkPrivate(area) { } | 
 | LinkBrowsePrivate::~LinkBrowsePrivate() = default; | 
 |  | 
 | class LinkActionPrivate : public LinkPrivate | 
 | { | 
 | public: | 
 |     explicit LinkActionPrivate(const QRectF &area); | 
 |     ~LinkActionPrivate() override; | 
 |  | 
 |     LinkAction::ActionType type; | 
 | }; | 
 |  | 
 | LinkActionPrivate::LinkActionPrivate(const QRectF &area) : LinkPrivate(area) { } | 
 | LinkActionPrivate::~LinkActionPrivate() = default; | 
 |  | 
 | class LinkSoundPrivate : public LinkPrivate | 
 | { | 
 | public: | 
 |     explicit LinkSoundPrivate(const QRectF &area); | 
 |     ~LinkSoundPrivate() override; | 
 |  | 
 |     double volume; | 
 |     bool sync : 1; | 
 |     bool repeat : 1; | 
 |     bool mix : 1; | 
 |     SoundObject *sound; | 
 | }; | 
 |  | 
 | LinkSoundPrivate::LinkSoundPrivate(const QRectF &area) : LinkPrivate(area), sound(nullptr) { } | 
 |  | 
 | LinkSoundPrivate::~LinkSoundPrivate() | 
 | { | 
 |     delete sound; | 
 | } | 
 |  | 
 | class LinkRenditionPrivate : public LinkPrivate | 
 | { | 
 | public: | 
 |     explicit LinkRenditionPrivate(const QRectF &area, ::MediaRendition *rendition, ::LinkRendition::RenditionOperation operation, const QString &script, const Ref ref); | 
 |     ~LinkRenditionPrivate() override; | 
 |  | 
 |     MediaRendition *rendition; | 
 |     LinkRendition::RenditionAction action; | 
 |     QString script; | 
 |     Ref annotationReference; | 
 | }; | 
 |  | 
 | LinkRenditionPrivate::LinkRenditionPrivate(const QRectF &area, ::MediaRendition *r, ::LinkRendition::RenditionOperation operation, const QString &javaScript, const Ref ref) | 
 |     : LinkPrivate(area), rendition(r ? new MediaRendition(r) : nullptr), action(LinkRendition::PlayRendition), script(javaScript), annotationReference(ref) | 
 | { | 
 |     switch (operation) { | 
 |     case ::LinkRendition::NoRendition: | 
 |         action = LinkRendition::NoRendition; | 
 |         break; | 
 |     case ::LinkRendition::PlayRendition: | 
 |         action = LinkRendition::PlayRendition; | 
 |         break; | 
 |     case ::LinkRendition::StopRendition: | 
 |         action = LinkRendition::StopRendition; | 
 |         break; | 
 |     case ::LinkRendition::PauseRendition: | 
 |         action = LinkRendition::PauseRendition; | 
 |         break; | 
 |     case ::LinkRendition::ResumeRendition: | 
 |         action = LinkRendition::ResumeRendition; | 
 |         break; | 
 |     } | 
 | } | 
 |  | 
 | LinkRenditionPrivate::~LinkRenditionPrivate() | 
 | { | 
 |     delete rendition; | 
 | } | 
 |  | 
 | class LinkJavaScriptPrivate : public LinkPrivate | 
 | { | 
 | public: | 
 |     explicit LinkJavaScriptPrivate(const QRectF &area); | 
 |     ~LinkJavaScriptPrivate() override; | 
 |  | 
 |     QString js; | 
 | }; | 
 |  | 
 | LinkJavaScriptPrivate::LinkJavaScriptPrivate(const QRectF &area) : LinkPrivate(area) { } | 
 | LinkJavaScriptPrivate::~LinkJavaScriptPrivate() = default; | 
 |  | 
 | class LinkMoviePrivate : public LinkPrivate | 
 | { | 
 | public: | 
 |     LinkMoviePrivate(const QRectF &area, LinkMovie::Operation operation, const QString &title, const Ref reference); | 
 |     ~LinkMoviePrivate() override; | 
 |  | 
 |     LinkMovie::Operation operation; | 
 |     QString annotationTitle; | 
 |     Ref annotationReference; | 
 | }; | 
 |  | 
 | LinkMoviePrivate::LinkMoviePrivate(const QRectF &area, LinkMovie::Operation _operation, const QString &title, const Ref reference) : LinkPrivate(area), operation(_operation), annotationTitle(title), annotationReference(reference) { } | 
 |  | 
 | LinkMoviePrivate::~LinkMoviePrivate() = default; | 
 |  | 
 | static void cvtUserToDev(::Page *page, double xu, double yu, int *xd, int *yd) | 
 | { | 
 |     double ctm[6]; | 
 |  | 
 |     page->getDefaultCTM(ctm, 72.0, 72.0, 0, false, true); | 
 |     *xd = (int)(ctm[0] * xu + ctm[2] * yu + ctm[4] + 0.5); | 
 |     *yd = (int)(ctm[1] * xu + ctm[3] * yu + ctm[5] + 0.5); | 
 | } | 
 |  | 
 | LinkDestination::LinkDestination(const LinkDestinationData &data) : d(new LinkDestinationPrivate) | 
 | { | 
 |     bool deleteDest = false; | 
 |     const LinkDest *ld = data.ld; | 
 |  | 
 |     if (data.namedDest && !ld && !data.externalDest) { | 
 |         deleteDest = true; | 
 |         ld = data.doc->doc->findDest(data.namedDest).release(); | 
 |     } | 
 |     // in case this destination was named one, and it was not resolved | 
 |     if (data.namedDest && !ld) { | 
 |         d->name = QString::fromLatin1(data.namedDest->c_str()); | 
 |     } | 
 |  | 
 |     if (!ld) { | 
 |         return; | 
 |     } | 
 |  | 
 |     if (ld->getKind() == ::destXYZ) { | 
 |         d->kind = destXYZ; | 
 |     } else if (ld->getKind() == ::destFit) { | 
 |         d->kind = destFit; | 
 |     } else if (ld->getKind() == ::destFitH) { | 
 |         d->kind = destFitH; | 
 |     } else if (ld->getKind() == ::destFitV) { | 
 |         d->kind = destFitV; | 
 |     } else if (ld->getKind() == ::destFitR) { | 
 |         d->kind = destFitR; | 
 |     } else if (ld->getKind() == ::destFitB) { | 
 |         d->kind = destFitB; | 
 |     } else if (ld->getKind() == ::destFitBH) { | 
 |         d->kind = destFitBH; | 
 |     } else if (ld->getKind() == ::destFitBV) { | 
 |         d->kind = destFitBV; | 
 |     } | 
 |  | 
 |     if (!ld->isPageRef()) { | 
 |         d->pageNum = ld->getPageNum(); | 
 |     } else { | 
 |         const Ref ref = ld->getPageRef(); | 
 |         d->pageNum = data.doc->doc->findPage(ref); | 
 |     } | 
 |     double left = ld->getLeft(); | 
 |     double bottom = ld->getBottom(); | 
 |     double right = ld->getRight(); | 
 |     double top = ld->getTop(); | 
 |     d->zoom = ld->getZoom(); | 
 |     d->changeLeft = ld->getChangeLeft(); | 
 |     d->changeTop = ld->getChangeTop(); | 
 |     d->changeZoom = ld->getChangeZoom(); | 
 |  | 
 |     int leftAux = 0, topAux = 0, rightAux = 0, bottomAux = 0; | 
 |  | 
 |     if (!data.externalDest) { | 
 |         ::Page *page; | 
 |         if (d->pageNum > 0 && d->pageNum <= data.doc->doc->getNumPages() && (page = data.doc->doc->getPage(d->pageNum))) { | 
 |             cvtUserToDev(page, left, top, &leftAux, &topAux); | 
 |             cvtUserToDev(page, right, bottom, &rightAux, &bottomAux); | 
 |  | 
 |             d->left = leftAux / (double)page->getCropWidth(); | 
 |             d->top = topAux / (double)page->getCropHeight(); | 
 |             d->right = rightAux / (double)page->getCropWidth(); | 
 |             d->bottom = bottomAux / (double)page->getCropHeight(); | 
 |         } else { | 
 |             d->pageNum = 0; | 
 |         } | 
 |     } | 
 |  | 
 |     if (deleteDest) { | 
 |         delete ld; | 
 |     } | 
 | } | 
 |  | 
 | LinkDestination::LinkDestination(const QString &description) : d(new LinkDestinationPrivate) | 
 | { | 
 |     const QStringList tokens = description.split(';'); | 
 |     if (tokens.size() >= 10) { | 
 |         d->kind = static_cast<Kind>(tokens.at(0).toInt()); | 
 |         d->pageNum = tokens.at(1).toInt(); | 
 |         d->left = tokens.at(2).toDouble(); | 
 |         d->bottom = tokens.at(3).toDouble(); | 
 |         d->right = tokens.at(4).toDouble(); | 
 |         d->top = tokens.at(5).toDouble(); | 
 |         d->zoom = tokens.at(6).toDouble(); | 
 |         d->changeLeft = static_cast<bool>(tokens.at(7).toInt()); | 
 |         d->changeTop = static_cast<bool>(tokens.at(8).toInt()); | 
 |         d->changeZoom = static_cast<bool>(tokens.at(9).toInt()); | 
 |     } | 
 | } | 
 |  | 
 | LinkDestination::LinkDestination(const LinkDestination &other) : d(other.d) { } | 
 |  | 
 | LinkDestination::~LinkDestination() { } | 
 |  | 
 | LinkDestination::Kind LinkDestination::kind() const | 
 | { | 
 |     return d->kind; | 
 | } | 
 |  | 
 | int LinkDestination::pageNumber() const | 
 | { | 
 |     return d->pageNum; | 
 | } | 
 |  | 
 | double LinkDestination::left() const | 
 | { | 
 |     return d->left; | 
 | } | 
 |  | 
 | double LinkDestination::bottom() const | 
 | { | 
 |     return d->bottom; | 
 | } | 
 |  | 
 | double LinkDestination::right() const | 
 | { | 
 |     return d->right; | 
 | } | 
 |  | 
 | double LinkDestination::top() const | 
 | { | 
 |     return d->top; | 
 | } | 
 |  | 
 | double LinkDestination::zoom() const | 
 | { | 
 |     return d->zoom; | 
 | } | 
 |  | 
 | bool LinkDestination::isChangeLeft() const | 
 | { | 
 |     return d->changeLeft; | 
 | } | 
 |  | 
 | bool LinkDestination::isChangeTop() const | 
 | { | 
 |     return d->changeTop; | 
 | } | 
 |  | 
 | bool LinkDestination::isChangeZoom() const | 
 | { | 
 |     return d->changeZoom; | 
 | } | 
 |  | 
 | QString LinkDestination::toString() const | 
 | { | 
 |     QString s = QString::number((qint8)d->kind); | 
 |     s += ";" + QString::number(d->pageNum); | 
 |     s += ";" + QString::number(d->left); | 
 |     s += ";" + QString::number(d->bottom); | 
 |     s += ";" + QString::number(d->right); | 
 |     s += ";" + QString::number(d->top); | 
 |     s += ";" + QString::number(d->zoom); | 
 |     s += ";" + QString::number((qint8)d->changeLeft); | 
 |     s += ";" + QString::number((qint8)d->changeTop); | 
 |     s += ";" + QString::number((qint8)d->changeZoom); | 
 |     return s; | 
 | } | 
 |  | 
 | QString LinkDestination::destinationName() const | 
 | { | 
 |     return d->name; | 
 | } | 
 |  | 
 | LinkDestination &LinkDestination::operator=(const LinkDestination &other) | 
 | { | 
 |     if (this == &other) { | 
 |         return *this; | 
 |     } | 
 |  | 
 |     d = other.d; | 
 |     return *this; | 
 | } | 
 |  | 
 | // Link | 
 | Link::~Link() | 
 | { | 
 |     delete d_ptr; | 
 | } | 
 |  | 
 | Link::Link(const QRectF &linkArea) : d_ptr(new LinkPrivate(linkArea)) { } | 
 |  | 
 | Link::Link(LinkPrivate &dd) : d_ptr(&dd) { } | 
 |  | 
 | Link::LinkType Link::linkType() const | 
 | { | 
 |     return None; | 
 | } | 
 |  | 
 | QRectF Link::linkArea() const | 
 | { | 
 |     Q_D(const Link); | 
 |     return d->linkArea; | 
 | } | 
 |  | 
 | QVector<Link *> Link::nextLinks() const | 
 | { | 
 |     return d_ptr->nextLinks; | 
 | } | 
 |  | 
 | // LinkGoto | 
 | LinkGoto::LinkGoto(const QRectF &linkArea, QString extFileName, const LinkDestination &destination) // clazy:exclude=function-args-by-ref | 
 |     : Link(*new LinkGotoPrivate(linkArea, destination)) | 
 | { | 
 |     Q_D(LinkGoto); | 
 |     d->extFileName = std::move(extFileName); // TODO remove when extFileName moves to be a const & | 
 | } | 
 |  | 
 | LinkGoto::~LinkGoto() { } | 
 |  | 
 | bool LinkGoto::isExternal() const | 
 | { | 
 |     Q_D(const LinkGoto); | 
 |     return !d->extFileName.isEmpty(); | 
 | } | 
 |  | 
 | QString LinkGoto::fileName() const | 
 | { | 
 |     Q_D(const LinkGoto); | 
 |     return d->extFileName; | 
 | } | 
 |  | 
 | LinkDestination LinkGoto::destination() const | 
 | { | 
 |     Q_D(const LinkGoto); | 
 |     return d->destination; | 
 | } | 
 |  | 
 | Link::LinkType LinkGoto::linkType() const | 
 | { | 
 |     return Goto; | 
 | } | 
 |  | 
 | // LinkExecute | 
 | LinkExecute::LinkExecute(const QRectF &linkArea, const QString &file, const QString ¶ms) : Link(*new LinkExecutePrivate(linkArea)) | 
 | { | 
 |     Q_D(LinkExecute); | 
 |     d->fileName = file; | 
 |     d->parameters = params; | 
 | } | 
 |  | 
 | LinkExecute::~LinkExecute() { } | 
 |  | 
 | QString LinkExecute::fileName() const | 
 | { | 
 |     Q_D(const LinkExecute); | 
 |     return d->fileName; | 
 | } | 
 | QString LinkExecute::parameters() const | 
 | { | 
 |     Q_D(const LinkExecute); | 
 |     return d->parameters; | 
 | } | 
 |  | 
 | Link::LinkType LinkExecute::linkType() const | 
 | { | 
 |     return Execute; | 
 | } | 
 |  | 
 | // LinkBrowse | 
 | LinkBrowse::LinkBrowse(const QRectF &linkArea, const QString &url) : Link(*new LinkBrowsePrivate(linkArea)) | 
 | { | 
 |     Q_D(LinkBrowse); | 
 |     d->url = url; | 
 | } | 
 |  | 
 | LinkBrowse::~LinkBrowse() { } | 
 |  | 
 | QString LinkBrowse::url() const | 
 | { | 
 |     Q_D(const LinkBrowse); | 
 |     return d->url; | 
 | } | 
 |  | 
 | Link::LinkType LinkBrowse::linkType() const | 
 | { | 
 |     return Browse; | 
 | } | 
 |  | 
 | // LinkAction | 
 | LinkAction::LinkAction(const QRectF &linkArea, ActionType actionType) : Link(*new LinkActionPrivate(linkArea)) | 
 | { | 
 |     Q_D(LinkAction); | 
 |     d->type = actionType; | 
 | } | 
 |  | 
 | LinkAction::~LinkAction() { } | 
 |  | 
 | LinkAction::ActionType LinkAction::actionType() const | 
 | { | 
 |     Q_D(const LinkAction); | 
 |     return d->type; | 
 | } | 
 |  | 
 | Link::LinkType LinkAction::linkType() const | 
 | { | 
 |     return Action; | 
 | } | 
 |  | 
 | // LinkSound | 
 | LinkSound::LinkSound(const QRectF &linkArea, double volume, bool sync, bool repeat, bool mix, SoundObject *sound) : Link(*new LinkSoundPrivate(linkArea)) | 
 | { | 
 |     Q_D(LinkSound); | 
 |     d->volume = volume; | 
 |     d->sync = sync; | 
 |     d->repeat = repeat; | 
 |     d->mix = mix; | 
 |     d->sound = sound; | 
 | } | 
 |  | 
 | LinkSound::~LinkSound() { } | 
 |  | 
 | Link::LinkType LinkSound::linkType() const | 
 | { | 
 |     return Sound; | 
 | } | 
 |  | 
 | double LinkSound::volume() const | 
 | { | 
 |     Q_D(const LinkSound); | 
 |     return d->volume; | 
 | } | 
 |  | 
 | bool LinkSound::synchronous() const | 
 | { | 
 |     Q_D(const LinkSound); | 
 |     return d->sync; | 
 | } | 
 |  | 
 | bool LinkSound::repeat() const | 
 | { | 
 |     Q_D(const LinkSound); | 
 |     return d->repeat; | 
 | } | 
 |  | 
 | bool LinkSound::mix() const | 
 | { | 
 |     Q_D(const LinkSound); | 
 |     return d->mix; | 
 | } | 
 |  | 
 | SoundObject *LinkSound::sound() const | 
 | { | 
 |     Q_D(const LinkSound); | 
 |     return d->sound; | 
 | } | 
 |  | 
 | // LinkRendition | 
 | LinkRendition::LinkRendition(const QRectF &linkArea, ::MediaRendition *rendition, int operation, const QString &script, const Ref &annotationReference) // clazy:exclude=function-args-by-value | 
 |     : Link(*new LinkRenditionPrivate(linkArea, rendition, static_cast<enum ::LinkRendition::RenditionOperation>(operation), script, annotationReference)) | 
 | { | 
 | } | 
 |  | 
 | LinkRendition::~LinkRendition() { } | 
 |  | 
 | Link::LinkType LinkRendition::linkType() const | 
 | { | 
 |     return Rendition; | 
 | } | 
 |  | 
 | MediaRendition *LinkRendition::rendition() const | 
 | { | 
 |     Q_D(const LinkRendition); | 
 |     return d->rendition; | 
 | } | 
 |  | 
 | LinkRendition::RenditionAction LinkRendition::action() const | 
 | { | 
 |     Q_D(const LinkRendition); | 
 |     return d->action; | 
 | } | 
 |  | 
 | QString LinkRendition::script() const | 
 | { | 
 |     Q_D(const LinkRendition); | 
 |     return d->script; | 
 | } | 
 |  | 
 | bool LinkRendition::isReferencedAnnotation(const ScreenAnnotation *annotation) const | 
 | { | 
 |     Q_D(const LinkRendition); | 
 |     if (d->annotationReference != Ref::INVALID() && d->annotationReference == annotation->d_ptr->pdfObjectReference()) { | 
 |         return true; | 
 |     } | 
 |  | 
 |     return false; | 
 | } | 
 |  | 
 | // LinkJavaScript | 
 | LinkJavaScript::LinkJavaScript(const QRectF &linkArea, const QString &js) : Link(*new LinkJavaScriptPrivate(linkArea)) | 
 | { | 
 |     Q_D(LinkJavaScript); | 
 |     d->js = js; | 
 | } | 
 |  | 
 | LinkJavaScript::~LinkJavaScript() { } | 
 |  | 
 | Link::LinkType LinkJavaScript::linkType() const | 
 | { | 
 |     return JavaScript; | 
 | } | 
 |  | 
 | QString LinkJavaScript::script() const | 
 | { | 
 |     Q_D(const LinkJavaScript); | 
 |     return d->js; | 
 | } | 
 |  | 
 | // LinkMovie | 
 | LinkMovie::LinkMovie(const QRectF &linkArea, Operation operation, const QString &annotationTitle, const Ref &annotationReference) // clazy:exclude=function-args-by-value | 
 |     : Link(*new LinkMoviePrivate(linkArea, operation, annotationTitle, annotationReference)) | 
 | { | 
 | } | 
 |  | 
 | LinkMovie::~LinkMovie() { } | 
 |  | 
 | Link::LinkType LinkMovie::linkType() const | 
 | { | 
 |     return Movie; | 
 | } | 
 |  | 
 | LinkMovie::Operation LinkMovie::operation() const | 
 | { | 
 |     Q_D(const LinkMovie); | 
 |     return d->operation; | 
 | } | 
 |  | 
 | bool LinkMovie::isReferencedAnnotation(const MovieAnnotation *annotation) const | 
 | { | 
 |     Q_D(const LinkMovie); | 
 |     if (d->annotationReference != Ref::INVALID() && d->annotationReference == annotation->d_ptr->pdfObjectReference()) { | 
 |         return true; | 
 |     } else if (!d->annotationTitle.isNull()) { | 
 |         return (annotation->movieTitle() == d->annotationTitle); | 
 |     } | 
 |  | 
 |     return false; | 
 | } | 
 |  | 
 | LinkOCGState::LinkOCGState(LinkOCGStatePrivate *ocgp) : Link(*ocgp) { } | 
 |  | 
 | LinkOCGState::~LinkOCGState() { } | 
 |  | 
 | Link::LinkType LinkOCGState::linkType() const | 
 | { | 
 |     return OCGState; | 
 | } | 
 |  | 
 | // LinkHide | 
 | LinkHide::LinkHide(LinkHidePrivate *lhidep) : Link(*lhidep) { } | 
 |  | 
 | LinkHide::~LinkHide() { } | 
 |  | 
 | Link::LinkType LinkHide::linkType() const | 
 | { | 
 |     return Hide; | 
 | } | 
 |  | 
 | QVector<QString> LinkHide::targets() const | 
 | { | 
 |     Q_D(const LinkHide); | 
 |     return QVector<QString>() << d->targetName; | 
 | } | 
 |  | 
 | bool LinkHide::isShowAction() const | 
 | { | 
 |     Q_D(const LinkHide); | 
 |     return d->isShow; | 
 | } | 
 | } |