diff --git a/poppler/Link.cc b/poppler/Link.cc index b90b1c1..718fdbd 100644 --- a/poppler/Link.cc +++ b/poppler/Link.cc @@ -712,8 +712,8 @@ LinkRendition::LinkRendition(Object *obj) { js = new GooString(tmp.getString()); } else if (tmp.isStream()) { Stream *stream = tmp.getStream(); - js = new GooString(); - stream->fillGooString(js); + js = new GooString(); + stream->fillGooString(js); } else { error(errSyntaxWarning, -1, "Invalid Rendition Action: JS not string or stream"); } @@ -730,15 +730,15 @@ LinkRendition::LinkRendition(Object *obj) { // retrieve rendition object if (obj->dictLookup("R", &renditionObj)->isDict()) { media = new MediaRendition(&renditionObj); - } else if (operation == 0 || operation == 4) { + } else if (operation == 0 || operation == 4) { error(errSyntaxWarning, -1, "Invalid Rendition Action: no R field with op = {0:d}", operation); - renditionObj.free(); - } + renditionObj.free(); + } - if (!obj->dictLookupNF("AN", &screenRef)->isRef() && operation >= 0 && operation <= 4) { - error(errSyntaxWarning, -1, "Invalid Rendition Action: no AN field with op = {0:d}", operation); - screenRef.free(); - } + if (!obj->dictLookupNF("AN", &screenRef)->isRef() && operation >= 0 && operation <= 4) { + error(errSyntaxWarning, -1, "Invalid Rendition Action: no AN field with op = {0:d}", operation); + screenRef.free(); + } } } else if (!js) { error(errSyntaxWarning, -1, "Invalid Rendition action: no OP or JS field defined"); diff --git a/poppler/Link.h b/poppler/Link.h index 8e2df24..6a5c25c 100644 --- a/poppler/Link.h +++ b/poppler/Link.h @@ -51,7 +51,7 @@ enum LinkActionKind { actionURI, // URI actionNamed, // named action actionMovie, // movie action - actionRendition, + actionRendition, // rendition action actionSound, // sound action actionJavaScript, // JavaScript action actionOCGState, // Set-OCG-State action diff --git a/qt4/src/poppler-annotation.cc b/qt4/src/poppler-annotation.cc index 825bbf6..5ecea80 100644 --- a/qt4/src/poppler-annotation.cc +++ b/qt4/src/poppler-annotation.cc @@ -527,8 +527,6 @@ Link* AnnotationPrivate::additionalAction( Annotation::AdditionalActionType type if ( linkAction ) link = PageData::convertLinkActionToLink( linkAction, parentDoc, QRectF() ); - delete linkAction; - return link; } diff --git a/qt4/src/poppler-annotation.h b/qt4/src/poppler-annotation.h index 5adc9a8..9208ca7 100644 --- a/qt4/src/poppler-annotation.h +++ b/qt4/src/poppler-annotation.h @@ -107,6 +107,7 @@ class POPPLER_QT4_EXPORT Annotation { friend class AnnotationUtils; friend class LinkMovie; + friend class LinkRendition; public: // enum definitions diff --git a/qt4/src/poppler-link.cc b/qt4/src/poppler-link.cc index a4bc55b..72257ad 100644 --- a/qt4/src/poppler-link.cc +++ b/qt4/src/poppler-link.cc @@ -168,16 +168,43 @@ class LinkSoundPrivate : public LinkPrivate class LinkRenditionPrivate : public LinkPrivate { public: - LinkRenditionPrivate( const QRectF &area, ::MediaRendition *rendition ); + LinkRenditionPrivate( const QRectF &area, ::MediaRendition *rendition, int operation, const QString &script, const Ref &annotationReference ); ~LinkRenditionPrivate(); MediaRendition *rendition; + LinkRendition::RenditionAction action; + QString script; + Ref annotationReference; }; - LinkRenditionPrivate::LinkRenditionPrivate( const QRectF &area, ::MediaRendition *r ) + LinkRenditionPrivate::LinkRenditionPrivate( const QRectF &area, ::MediaRendition *r, int operation, const QString &javaScript, const Ref &ref ) : LinkPrivate( area ) - , rendition( new MediaRendition( r ) ) + , rendition( r ? new MediaRendition( r ) : 0 ) + , action( LinkRendition::PlayRendition ) + , script( javaScript ) + , annotationReference( ref ) { + switch ( operation ) + { + case -1: + action = LinkRendition::NoRendition; + break; + case 0: + action = LinkRendition::PlayRendition; + break; + case 1: + action = LinkRendition::StopRendition; + break; + case 2: + action = LinkRendition::PauseRendition; + break; + case 3: + action = LinkRendition::ResumeRendition; + break; + case 4: + action = LinkRendition::PlayRendition; + break; + } } LinkRenditionPrivate::~LinkRenditionPrivate() @@ -578,26 +605,49 @@ class LinkMoviePrivate : public LinkPrivate } // LinkRendition - LinkRendition::LinkRendition( const QRectF &linkArea, ::MediaRendition *rendition ) - : Link( *new LinkRenditionPrivate( linkArea, rendition ) ) + LinkRendition::LinkRendition( const QRectF &linkArea, ::MediaRendition *rendition, int operation, const QString &script, const Ref &annotationReference ) + : Link( *new LinkRenditionPrivate( linkArea, rendition, 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.num != -1 && d->annotationReference == annotation->d_ptr->pdfObjectReference() ) + { + return true; + } + + return false; + } + // LinkJavaScript LinkJavaScript::LinkJavaScript( const QRectF &linkArea, const QString &js ) : Link( *new LinkJavaScriptPrivate( linkArea ) ) diff --git a/qt4/src/poppler-link.h b/qt4/src/poppler-link.h index a2ef2d3..58af627 100644 --- a/qt4/src/poppler-link.h +++ b/qt4/src/poppler-link.h @@ -455,12 +455,29 @@ class POPPLER_QT4_EXPORT LinkRendition : public Link { public: /** - * Create a new media rendition link. + * Describes the possible rendition actions. + * + * \since 0.22 + */ + enum RenditionAction { + NoRendition, + PlayRendition, + StopRendition, + PauseRendition, + ResumeRendition + }; + + /** + * Create a new rendition link. * * \param linkArea the active area of the link - * \param rendition + * \param rendition the media rendition object + * \param operation the numeric operation (action) + * \param script the java script code + * \param annotationReference the object reference of the screen annotation associated with this rendition action */ - LinkRendition( const QRectF &linkArea, ::MediaRendition *rendition ); + LinkRendition( const QRectF &linkArea, ::MediaRendition *rendition, int operation, const QString &script, const Ref &annotationReference ); + /** * Destructor. */ @@ -469,10 +486,31 @@ class POPPLER_QT4_EXPORT LinkRendition : public Link LinkType linkType() const; /** - * + * Returns the media rendition object if the redition provides one, @c 0 otherwise */ MediaRendition *rendition() const; + /** + * Returns the action that should be executed if a rendition object is provided. + * + * \since 0.22 + */ + RenditionAction action() const; + + /** + * The JS code that shall be executed or an empty string. + * + * \since 0.22 + */ + QString script() const; + + /** + * Returns whether the given @p annotation is the referenced screen annotation for this rendition @p link. + * + * \since 0.22 + */ + bool isReferencedAnnotation( const ScreenAnnotation *annotation ) const; + private: Q_DECLARE_PRIVATE( LinkRendition ) Q_DISABLE_COPY( LinkRendition ) diff --git a/qt4/src/poppler-page.cc b/qt4/src/poppler-page.cc index 349a1bb..03aa1bb 100644 --- a/qt4/src/poppler-page.cc +++ b/qt4/src/poppler-page.cc @@ -197,7 +197,13 @@ Link* PageData::convertLinkActionToLink(::LinkAction * a, DocumentData *parentDo case actionRendition: { ::LinkRendition *lrn = (::LinkRendition *)a; - popplerLink = new LinkRendition( linkArea, lrn->getMedia() ); + + Ref reference; + reference.num = reference.gen = -1; + if ( lrn->hasScreenAnnot() ) + reference = lrn->getScreenAnnot(); + + popplerLink = new LinkRendition( linkArea, lrn->getMedia(), lrn->getOperation(), UnicodeParsedString( lrn->getScript() ), reference ); } break;