summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Koenig <tobias.koenig@kdab.com>2015-08-04 09:11:29 (GMT)
committerTobias Koenig <tobias.koenig@kdab.com>2015-08-20 06:59:34 (GMT)
commit8b603c174dc288dcd83e19afb075853e459a82a7 (patch)
tree6a78dfed4edbb68836e34cb8d912bce23247ba99
parente60890896146118973e1b0b824433f1b16527193 (diff)
Add basic support for RichMedia annotations in PDF files
That patch extracts the video file, which is defined in a rich media annotation as parameter for the flash player, and uses the normal multimedia player, to playback the video file. This feature requires poppler-qt5 in version 0.36. FEATURE: 326230 REVIEW: 124612
-rw-r--r--cmake/modules/FindPoppler.cmake12
-rw-r--r--core/annotations.cpp108
-rw-r--r--core/annotations.h63
-rw-r--r--generators/poppler/annots.cpp22
-rw-r--r--generators/poppler/config-okular-poppler.h.cmake3
-rw-r--r--generators/poppler/generator_pdf.cpp96
-rw-r--r--ui/annotationpopup.cpp68
-rw-r--r--ui/guiutils.cpp3
-rw-r--r--ui/pageview.cpp18
-rw-r--r--ui/presentationwidget.cpp19
10 files changed, 394 insertions, 18 deletions
diff --git a/cmake/modules/FindPoppler.cmake b/cmake/modules/FindPoppler.cmake
index 98895ec..4362967 100644
--- a/cmake/modules/FindPoppler.cmake
+++ b/cmake/modules/FindPoppler.cmake
@@ -79,12 +79,24 @@ int main()
}
" HAVE_POPPLER_0_28)
+check_cxx_source_compiles("
+#include <poppler-qt5.h>
+int main()
+{
+ Poppler::Page *p = 0;
+ p->annotations( QSet<Poppler::Annotation::SubType>() << Poppler::Annotation::ARichMedia );
+ return 0;
+}
+" HAVE_POPPLER_0_36)
+
set(CMAKE_REQUIRED_INCLUDES)
set(CMAKE_REQUIRED_LIBRARIES)
if (HAVE_POPPLER_0_28)
set(popplerVersionMessage "0.28")
elseif (HAVE_POPPLER_0_24)
set(popplerVersionMessage "0.24")
+ elseif (HAVE_POPPLER_0_36)
+ set(popplerVersionMessage "0.36")
endif ()
if (NOT Poppler_FIND_QUIETLY)
message(STATUS "Found Poppler-Qt5: ${POPPLER_LIBRARY}, (>= ${popplerVersionMessage})")
diff --git a/core/annotations.cpp b/core/annotations.cpp
index ac45a5a..2461ef2 100644
--- a/core/annotations.cpp
+++ b/core/annotations.cpp
@@ -2935,3 +2935,111 @@ Action* WidgetAnnotation::additionalAction( AdditionalActionType type ) const
else
return d->m_additionalActions.value( type );
}
+
+/** RichMediaAnnotation [Annotation] */
+
+class Okular::RichMediaAnnotationPrivate : public Okular::AnnotationPrivate
+{
+ public:
+ RichMediaAnnotationPrivate();
+ ~RichMediaAnnotationPrivate();
+ virtual void setAnnotationProperties( const QDomNode& node );
+ virtual AnnotationPrivate* getNewAnnotationPrivate();
+
+ // data fields
+ Movie *movie;
+ EmbeddedFile *embeddedFile;
+};
+
+RichMediaAnnotationPrivate::RichMediaAnnotationPrivate()
+ : movie( 0 ), embeddedFile( 0 )
+{
+}
+
+RichMediaAnnotationPrivate::~RichMediaAnnotationPrivate()
+{
+ delete movie;
+ delete embeddedFile;
+}
+
+void RichMediaAnnotationPrivate::setAnnotationProperties( const QDomNode& node )
+{
+ Okular::AnnotationPrivate::setAnnotationProperties(node);
+
+ // loop through the whole children looking for a 'richMedia' element
+ QDomNode subNode = node.firstChild();
+ while( subNode.isElement() )
+ {
+ QDomElement e = subNode.toElement();
+ subNode = subNode.nextSibling();
+ if ( e.tagName() != "richMedia" )
+ continue;
+
+ // loading complete
+ break;
+ }
+}
+
+AnnotationPrivate* RichMediaAnnotationPrivate::getNewAnnotationPrivate()
+{
+ return new RichMediaAnnotationPrivate();
+}
+
+RichMediaAnnotation::RichMediaAnnotation()
+ : Annotation( *new RichMediaAnnotationPrivate() )
+{
+}
+
+RichMediaAnnotation::RichMediaAnnotation( const QDomNode & node )
+ : Annotation( *new RichMediaAnnotationPrivate, node )
+{
+}
+
+RichMediaAnnotation::~RichMediaAnnotation()
+{
+}
+
+void RichMediaAnnotation::store( QDomNode & node, QDomDocument & document ) const
+{
+ // recurse to parent objects storing properties
+ Annotation::store( node, document );
+
+ // create [richMedia] element
+ QDomElement movieElement = document.createElement( "richMedia" );
+ node.appendChild( movieElement );
+}
+
+Annotation::SubType RichMediaAnnotation::subType() const
+{
+ return ARichMedia;
+}
+
+void RichMediaAnnotation::setMovie( Movie *movie )
+{
+ Q_D( RichMediaAnnotation );
+
+ delete d->movie;
+ d->movie = movie;
+}
+
+Movie* RichMediaAnnotation::movie() const
+{
+ Q_D( const RichMediaAnnotation );
+
+ return d->movie;
+}
+
+EmbeddedFile* RichMediaAnnotation::embeddedFile() const
+{
+ Q_D( const RichMediaAnnotation );
+
+ return d->embeddedFile;
+}
+
+void RichMediaAnnotation::setEmbeddedFile( EmbeddedFile *embeddedFile )
+{
+ Q_D( RichMediaAnnotation );
+
+ delete d->embeddedFile;
+ d->embeddedFile = embeddedFile;
+}
diff --git a/core/annotations.h b/core/annotations.h
index bbe2c5c..5653097 100644
--- a/core/annotations.h
+++ b/core/annotations.h
@@ -45,6 +45,7 @@ class SoundAnnotationPrivate;
class MovieAnnotationPrivate;
class ScreenAnnotationPrivate;
class WidgetAnnotationPrivate;
+class RichMediaAnnotationPrivate;
/**
* @short Helper class for (recursive) annotation retrieval/storage.
@@ -116,6 +117,7 @@ class OKULARCORE_EXPORT Annotation
AMovie = 11, ///< A movie annotation
AScreen = 12, ///< A screen annotation
AWidget = 13, ///< A widget annotation
+ ARichMedia = 14,///< A rich media annotation
A_BASE = 0 ///< The annotation base class
};
@@ -1648,6 +1650,67 @@ class OKULARCORE_EXPORT WidgetAnnotation : public Annotation
Q_DISABLE_COPY( WidgetAnnotation )
};
+/**
+ * \short RichMedia annotation.
+ *
+ * The rich media annotation represents an video or sound on a page.
+ *
+ * @since 1.0
+ */
+class OKULARCORE_EXPORT RichMediaAnnotation : public Annotation
+{
+ public:
+ /**
+ * Creates a new rich media annotation.
+ */
+ RichMediaAnnotation();
+
+ /**
+ * Creates a new rich media annotation from the xml @p description
+ */
+ RichMediaAnnotation( const QDomNode &description );
+
+ /**
+ * Destroys the rich media annotation.
+ */
+ virtual ~RichMediaAnnotation();
+
+ /**
+ * Returns the sub type of the rich media annotation.
+ */
+ SubType subType() const;
+
+ /**
+ * Stores the rich media annotation as xml in @p document
+ * under the given @p parentNode.
+ */
+ void store( QDomNode &parentNode, QDomDocument &document ) const;
+
+ /**
+ * Gets the movie object.
+ */
+ Movie* movie() const;
+
+ /**
+ * Sets the new @p movie object.
+ */
+ void setMovie( Movie *movie );
+
+ /**
+ * Sets the @p object representing the embedded file.
+ */
+ void setEmbeddedFile( EmbeddedFile *object );
+
+ /**
+ * Gets the embedded file object.
+ */
+ EmbeddedFile* embeddedFile() const;
+
+ private:
+ Q_DECLARE_PRIVATE( RichMediaAnnotation )
+ Q_DISABLE_COPY( RichMediaAnnotation )
+};
+
}
#endif
diff --git a/generators/poppler/annots.cpp b/generators/poppler/annots.cpp
index 5aca423..9d32022 100644
--- a/generators/poppler/annots.cpp
+++ b/generators/poppler/annots.cpp
@@ -28,6 +28,9 @@ Q_DECLARE_METATYPE( Poppler::Annotation* )
extern Okular::Sound* createSoundFromPopplerSound( const Poppler::SoundObject *popplerSound );
extern Okular::Movie* createMovieFromPopplerMovie( const Poppler::MovieObject *popplerMovie );
extern Okular::Movie* createMovieFromPopplerScreen( const Poppler::LinkRendition *popplerScreen );
+#ifdef HAVE_POPPLER_0_36
+extern QPair<Okular::Movie*, Okular::EmbeddedFile*> createMovieFromPopplerRichMedia( const Poppler::RichMediaAnnotation *popplerRichMedia );
+#endif
static void disposeAnnotation( const Okular::Annotation *ann )
@@ -317,6 +320,25 @@ Okular::Annotation* createAnnotationFromPopplerAnnotation( Poppler::Annotation *
*doDelete = false;
break;
}
+#ifdef HAVE_POPPLER_0_36
+ case Poppler::Annotation::ARichMedia:
+ {
+ Poppler::RichMediaAnnotation * richmediaann = static_cast< Poppler::RichMediaAnnotation * >( ann );
+ const QPair<Okular::Movie*, Okular::EmbeddedFile*> result = createMovieFromPopplerRichMedia( richmediaann );
+
+ if ( result.first ) {
+ Okular::RichMediaAnnotation * r = new Okular::RichMediaAnnotation();
+ tieToOkularAnn = true;
+ *doDelete = false;
+ annotation = r;
+
+ r->setMovie( result.first );
+ r->setEmbeddedFile( result.second );
+ }
+
+ break;
+ }
+#endif
case Poppler::Annotation::AText:
case Poppler::Annotation::ALine:
case Poppler::Annotation::AGeom:
diff --git a/generators/poppler/config-okular-poppler.h.cmake b/generators/poppler/config-okular-poppler.h.cmake
index 17280e3..792dcf1 100644
--- a/generators/poppler/config-okular-poppler.h.cmake
+++ b/generators/poppler/config-okular-poppler.h.cmake
@@ -3,3 +3,6 @@
/* Defined if we have the 0.28 version of the Poppler library */
#cmakedefine HAVE_POPPLER_0_28 1
+
+/* Defined if we have the 0.36 version of the Poppler library */
+#cmakedefine HAVE_POPPLER_0_36 1
diff --git a/generators/poppler/generator_pdf.cpp b/generators/poppler/generator_pdf.cpp
index ae8599b..4c87c2d 100644
--- a/generators/poppler/generator_pdf.cpp
+++ b/generators/poppler/generator_pdf.cpp
@@ -199,6 +199,102 @@ Okular::Movie* createMovieFromPopplerScreen( const Poppler::LinkRendition *poppl
return movie;
}
+#ifdef HAVE_POPPLER_0_36
+QPair<Okular::Movie*, Okular::EmbeddedFile*> createMovieFromPopplerRichMedia( const Poppler::RichMediaAnnotation *popplerRichMedia )
+{
+ const QPair<Okular::Movie*, Okular::EmbeddedFile*> emptyResult(0, 0);
+
+ /**
+ * To convert a Flash/Video based RichMedia annotation to a movie, we search for the first
+ * Flash/Video richmedia instance and parse the flashVars parameter for the 'source' identifier.
+ * That identifier is then used to find the associated embedded file through the assets
+ * mapping.
+ */
+ const Poppler::RichMediaAnnotation::Content *content = popplerRichMedia->content();
+ if ( !content )
+ return emptyResult;
+
+ const QList<Poppler::RichMediaAnnotation::Configuration*> configurations = content->configurations();
+ if ( configurations.isEmpty() )
+ return emptyResult;
+
+ const Poppler::RichMediaAnnotation::Configuration *configuration = configurations[0];
+
+ const QList<Poppler::RichMediaAnnotation::Instance*> instances = configuration->instances();
+ if ( instances.isEmpty() )
+ return emptyResult;
+
+ const Poppler::RichMediaAnnotation::Instance *instance = instances[0];
+
+ if ( ( instance->type() != Poppler::RichMediaAnnotation::Instance::TypeFlash ) &&
+ ( instance->type() != Poppler::RichMediaAnnotation::Instance::TypeVideo ) )
+ return emptyResult;
+
+ const Poppler::RichMediaAnnotation::Params *params = instance->params();
+ if ( !params )
+ return emptyResult;
+
+ QString sourceId;
+ bool playbackLoops = false;
+
+ const QStringList flashVars = params->flashVars().split( QLatin1Char( '&' ) );
+ foreach ( const QString & flashVar, flashVars ) {
+ const int pos = flashVar.indexOf( QLatin1Char( '=' ) );
+ if ( pos == -1 )
+ continue;
+
+ const QString key = flashVar.left( pos );
+ const QString value = flashVar.mid( pos + 1 );
+
+ if ( key == QLatin1String( "source" ) )
+ sourceId = value;
+ else if ( key == QLatin1String( "loop" ) )
+ playbackLoops = ( value == QLatin1String( "true" ) ? true : false );
+ }
+
+ if ( sourceId.isEmpty() )
+ return emptyResult;
+
+ const QList<Poppler::RichMediaAnnotation::Asset*> assets = content->assets();
+ if ( assets.isEmpty() )
+ return emptyResult;
+
+ Poppler::RichMediaAnnotation::Asset *matchingAsset = 0;
+ foreach ( Poppler::RichMediaAnnotation::Asset *asset, assets ) {
+ if ( asset->name() == sourceId ) {
+ matchingAsset = asset;
+ break;
+ }
+ }
+
+ if ( !matchingAsset )
+ return emptyResult;
+
+ Poppler::EmbeddedFile *embeddedFile = matchingAsset->embeddedFile();
+ if ( !embeddedFile )
+ return emptyResult;
+
+ Okular::EmbeddedFile *pdfEmbeddedFile = new PDFEmbeddedFile( embeddedFile );
+
+ Okular::Movie *movie = new Okular::Movie( embeddedFile->name(), embeddedFile->data() );
+ movie->setPlayMode( playbackLoops ? Okular::Movie::PlayRepeat : Okular::Movie::PlayOnce );
+
+ if ( popplerRichMedia && popplerRichMedia->settings() && popplerRichMedia->settings()->activation() ) {
+ if ( popplerRichMedia->settings()->activation()->condition() == Poppler::RichMediaAnnotation::Activation::PageOpened ||
+ popplerRichMedia->settings()->activation()->condition() == Poppler::RichMediaAnnotation::Activation::PageVisible ) {
+ movie->setAutoPlay( true );
+ } else {
+ movie->setAutoPlay( false );
+ }
+
+ } else {
+ movie->setAutoPlay( false );
+ }
+
+ return qMakePair(movie, pdfEmbeddedFile);
+}
+#endif
+
/**
* Note: the function will take ownership of the popplerLink object.
*/
diff --git a/ui/annotationpopup.cpp b/ui/annotationpopup.cpp
index 65fa598..da42b6a 100644
--- a/ui/annotationpopup.cpp
+++ b/ui/annotationpopup.cpp
@@ -21,6 +21,33 @@
Q_DECLARE_METATYPE( AnnotationPopup::AnnotPagePair )
+namespace {
+
+bool annotationHasFileAttachment( Okular::Annotation *annotation )
+{
+ return ( annotation->subType() == Okular::Annotation::AFileAttachment || annotation->subType() == Okular::Annotation::ARichMedia );
+}
+
+Okular::EmbeddedFile* embeddedFileFromAnnotation( Okular::Annotation *annotation )
+{
+ if ( annotation->subType() == Okular::Annotation::AFileAttachment )
+ {
+ const Okular::FileAttachmentAnnotation *fileAttachAnnot = static_cast<Okular::FileAttachmentAnnotation*>( annotation );
+ return fileAttachAnnot->embeddedFile();
+ }
+ else if ( annotation->subType() == Okular::Annotation::ARichMedia )
+ {
+ const Okular::RichMediaAnnotation *richMediaAnnot = static_cast<Okular::RichMediaAnnotation*>( annotation );
+ return richMediaAnnot->embeddedFile();
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+}
+
AnnotationPopup::AnnotationPopup( Okular::Document *document, MenuMode mode,
QWidget *parent )
: mParent( parent ), mDocument( document ), mMenuMode( mode )
@@ -42,7 +69,6 @@ void AnnotationPopup::exec( const QPoint &point )
QMenu menu( mParent );
QAction *action = 0;
- Okular::FileAttachmentAnnotation *fileAttachAnnot = 0;
const char *actionTypeId = "actionType";
@@ -80,15 +106,18 @@ void AnnotationPopup::exec( const QPoint &point )
action->setEnabled( onlyOne );
action->setProperty( actionTypeId, propertiesId );
- if ( onlyOne && pair.annotation->subType() == Okular::Annotation::AFileAttachment )
+ if ( onlyOne && annotationHasFileAttachment( pair.annotation ) )
{
- menu.addSeparator();
- fileAttachAnnot = static_cast< Okular::FileAttachmentAnnotation * >( pair.annotation );
- const QString saveText = i18nc( "%1 is the name of the file to save", "&Save '%1'...", fileAttachAnnot->embeddedFile()->name() );
+ const Okular::EmbeddedFile *embeddedFile = embeddedFileFromAnnotation( pair.annotation );
+ if ( embeddedFile )
+ {
+ const QString saveText = i18nc( "%1 is the name of the file to save", "&Save '%1'...", embeddedFile->name() );
- action = menu.addAction( QIcon::fromTheme( "document-save" ), saveText );
- action->setData( QVariant::fromValue( pair ) );
- action->setProperty( actionTypeId, saveId );
+ menu.addSeparator();
+ action = menu.addAction( QIcon::fromTheme( "document-save" ), saveText );
+ action->setData( QVariant::fromValue( pair ) );
+ action->setProperty( actionTypeId, saveId );
+ }
}
}
else
@@ -111,15 +140,18 @@ void AnnotationPopup::exec( const QPoint &point )
action->setData( QVariant::fromValue( pair ) );
action->setProperty( actionTypeId, propertiesId );
- if ( pair.annotation->subType() == Okular::Annotation::AFileAttachment )
+ if ( annotationHasFileAttachment( pair.annotation ) )
{
- menu.addSeparator();
- fileAttachAnnot = static_cast< Okular::FileAttachmentAnnotation * >( pair.annotation );
- const QString saveText = i18nc( "%1 is the name of the file to save", "&Save '%1'...", fileAttachAnnot->embeddedFile()->name() );
-
- action = menu.addAction( QIcon::fromTheme( "document-save" ), saveText );
- action->setData( QVariant::fromValue( pair ) );
- action->setProperty( actionTypeId, saveId );
+ const Okular::EmbeddedFile *embeddedFile = embeddedFileFromAnnotation( pair.annotation );
+ if ( embeddedFile )
+ {
+ const QString saveText = i18nc( "%1 is the name of the file to save", "&Save '%1'...", embeddedFile->name() );
+
+ menu.addSeparator();
+ action = menu.addAction( QIcon::fromTheme( "document-save" ), saveText );
+ action->setData( QVariant::fromValue( pair ) );
+ action->setProperty( actionTypeId, saveId );
+ }
}
}
}
@@ -148,8 +180,8 @@ void AnnotationPopup::exec( const QPoint &point )
propdialog.exec();
}
} else if( actionType == saveId ) {
- const Okular::FileAttachmentAnnotation * fileAttachAnnot = static_cast< Okular::FileAttachmentAnnotation * >( pair.annotation );
- GuiUtils::saveEmbeddedFile( fileAttachAnnot->embeddedFile(), mParent );
+ Okular::EmbeddedFile *embeddedFile = embeddedFileFromAnnotation( pair.annotation );
+ GuiUtils::saveEmbeddedFile( embeddedFile, mParent );
}
}
}
diff --git a/ui/guiutils.cpp b/ui/guiutils.cpp
index 86d01eb..3d7f1d6 100644
--- a/ui/guiutils.cpp
+++ b/ui/guiutils.cpp
@@ -122,6 +122,9 @@ QString captionForAnnotation( const Okular::Annotation * ann )
case Okular::Annotation::AWidget:
ret = i18nc( "Caption for a widget annotation", "Widget" );
break;
+ case Okular::Annotation::ARichMedia:
+ ret = i18nc( "Caption for a rich media annotation", "Rich Media" );
+ break;
case Okular::Annotation::A_BASE:
break;
}
diff --git a/ui/pageview.cpp b/ui/pageview.cpp
index ce75644..4528691 100644
--- a/ui/pageview.cpp
+++ b/ui/pageview.cpp
@@ -973,6 +973,13 @@ void PageView::notifySetup( const QVector< Okular::Page * > & pageSet, int setup
item->videoWidgets().insert( movieAnn->movie(), vw );
vw->pageInitialized();
}
+ else if ( a->subType() == Okular::Annotation::ARichMedia )
+ {
+ Okular::RichMediaAnnotation * richMediaAnn = static_cast< Okular::RichMediaAnnotation * >( a );
+ VideoWidget * vw = new VideoWidget( richMediaAnn, richMediaAnn->movie(), d->document, viewport() );
+ item->videoWidgets().insert( richMediaAnn->movie(), vw );
+ vw->pageInitialized();
+ }
else if ( a->subType() == Okular::Annotation::AScreen )
{
const Okular::ScreenAnnotation * screenAnn = static_cast< Okular::ScreenAnnotation * >( a );
@@ -2426,6 +2433,12 @@ void PageView::mouseReleaseEvent( QMouseEvent * e )
vw->show();
vw->play();
}
+ else if ( ann->subType() == Okular::Annotation::ARichMedia )
+ {
+ VideoWidget *vw = pageItem->videoWidgets().value( static_cast<Okular::RichMediaAnnotation*>( ann )->movie() );
+ vw->show();
+ vw->play();
+ }
else if ( ann->subType() == Okular::Annotation::AScreen )
{
d->document->processAction( static_cast<Okular::ScreenAnnotation*>( ann )->action() );
@@ -3914,6 +3927,11 @@ void PageView::updateCursor( const QPoint &p )
d->mouseOnRect = true;
setCursor( Qt::PointingHandCursor );
}
+ else if ( annotation->subType() == Okular::Annotation::ARichMedia )
+ {
+ d->mouseOnRect = true;
+ setCursor( Qt::PointingHandCursor );
+ }
else if ( annotation->subType() == Okular::Annotation::AScreen )
{
if ( GuiUtils::renditionMovieFromScreenAnnotation( static_cast< const Okular::ScreenAnnotation * >( annotation ) ) != 0 )
diff --git a/ui/presentationwidget.cpp b/ui/presentationwidget.cpp
index 4b90849..76ffe82 100644
--- a/ui/presentationwidget.cpp
+++ b/ui/presentationwidget.cpp
@@ -335,6 +335,15 @@ void PresentationWidget::notifySetup( const QVector< Okular::Page * > & pageSet,
frame->videoWidgets.insert( movieAnn->movie(), vw );
vw->pageInitialized();
}
+ else if ( a->subType() == Okular::Annotation::ARichMedia )
+ {
+ Okular::RichMediaAnnotation * richMediaAnn = static_cast< Okular::RichMediaAnnotation * >( a );
+ if ( richMediaAnn->movie() ) {
+ VideoWidget * vw = new VideoWidget( richMediaAnn, richMediaAnn->movie(), m_document, this );
+ frame->videoWidgets.insert( richMediaAnn->movie(), vw );
+ vw->pageInitialized();
+ }
+ }
else if ( a->subType() == Okular::Annotation::AScreen )
{
const Okular::ScreenAnnotation * screenAnn = static_cast< Okular::ScreenAnnotation * >( a );
@@ -629,6 +638,15 @@ void PresentationWidget::mousePressEvent( QMouseEvent * e )
vw->play();
return;
}
+ else if ( annotation->subType() == Okular::Annotation::ARichMedia )
+ {
+ const Okular::RichMediaAnnotation *richMediaAnnotation = static_cast<const Okular::RichMediaAnnotation*>( annotation );
+
+ VideoWidget *vw = m_frames[ m_frameIndex ]->videoWidgets.value( richMediaAnnotation->movie() );
+ vw->show();
+ vw->play();
+ return;
+ }
else if ( annotation->subType() == Okular::Annotation::AScreen )
{
m_document->processAction( static_cast<const Okular::ScreenAnnotation*>( annotation )->action() );
@@ -893,6 +911,7 @@ void PresentationWidget::testCursorOnLink( int x, int y )
const bool needsHandCursor = ( ( link != 0 ) ||
( ( annotation != 0 ) && ( annotation->subType() == Okular::Annotation::AMovie ) ) ||
+ ( ( annotation != 0 ) && ( annotation->subType() == Okular::Annotation::ARichMedia ) ) ||
( ( annotation != 0 ) && ( annotation->subType() == Okular::Annotation::AScreen ) && ( GuiUtils::renditionMovieFromScreenAnnotation( static_cast< const Okular::ScreenAnnotation * >( annotation ) ) != 0 ) ) );
// only react on changes (in/out from a link)