[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [okular] /: Evaluate additional actions of screen and widget annotations
From: Tobias Koenig <tokoe () kde ! org>
Date: 2012-09-21 8:51:10
Message-ID: 20120921085110.044BBA6094 () git ! kde ! org
[Download RAW message or body]
Git commit 770e2818bb149211330ddbc35877c20624a71862 by Tobias Koenig.
Committed on 16/08/2012 at 11:53.
Pushed by tokoe into branch 'master'.
Evaluate additional actions of screen and widget annotations
This fixes the auto-start feature of PDFs generated with the LaTeX movie
package, which uses the additional action of a widget annotation to start
the movie when entering the page.
BUG: 300051
REVIEW: 106430
FIXED-IN: 4.10
M +4 -0 cmake/modules/FindPoppler.cmake
M +147 -0 core/annotations.cpp
M +127 -0 core/annotations.h
M +7 -0 generators/poppler/annots.cpp
M +47 -0 generators/poppler/generator_pdf.cpp
M +6 -0 ui/guiutils.cpp
M +28 -0 ui/presentationwidget.cpp
http://commits.kde.org/okular/770e2818bb149211330ddbc35877c20624a71862
diff --git a/cmake/modules/FindPoppler.cmake b/cmake/modules/FindPoppler.cmake
index 06e7117..1763ee9 100644
--- a/cmake/modules/FindPoppler.cmake
+++ b/cmake/modules/FindPoppler.cmake
@@ -99,11 +99,15 @@ int main()
check_cxx_source_compiles("
#include <poppler-qt4.h>
+#include <poppler-annotation.h>
int main()
{
Poppler::MovieObject *movie = 0;
movie->showPosterImage();
+
+ const Poppler::Annotation::AdditionalActionType type = \
Poppler::Annotation::PageOpeningAction; +
return 0;
}
" HAVE_POPPLER_0_22)
diff --git a/core/annotations.cpp b/core/annotations.cpp
index ceb571c..21114af 100644
--- a/core/annotations.cpp
+++ b/core/annotations.cpp
@@ -15,6 +15,7 @@
#include <QtGui/QColor>
// local includes
+#include "action.h"
#include "document.h"
#include "document_p.h"
#include "movie.h"
@@ -2411,3 +2412,149 @@ void MovieAnnotation::setMovie( Movie *movie )
Q_D( MovieAnnotation );
d->movie = movie;
}
+
+/** ScreenAnnotation [Annotation] */
+
+class Okular::ScreenAnnotationPrivate : public Okular::AnnotationPrivate
+{
+ public:
+ ~ScreenAnnotationPrivate();
+ QMap< Okular::Annotation::AdditionalActionType, Okular::Action* > \
m_additionalActions; +};
+
+ScreenAnnotationPrivate::~ScreenAnnotationPrivate()
+{
+ qDeleteAll( m_additionalActions );
+}
+
+ScreenAnnotation::ScreenAnnotation()
+ : Annotation( *new ScreenAnnotationPrivate() )
+{
+}
+
+ScreenAnnotation::ScreenAnnotation( const QDomNode & node )
+ : Annotation( *new ScreenAnnotationPrivate(), node )
+{
+ // loop through the whole children looking for a 'screen' element
+ QDomNode subNode = node.firstChild();
+ while( subNode.isElement() )
+ {
+ QDomElement e = subNode.toElement();
+ subNode = subNode.nextSibling();
+ if ( e.tagName() != "screen" )
+ continue;
+
+ // loading complete
+ break;
+ }
+}
+
+ScreenAnnotation::~ScreenAnnotation()
+{
+}
+
+void ScreenAnnotation::store( QDomNode & node, QDomDocument & document ) const
+{
+ // recurse to parent objects storing properties
+ Annotation::store( node, document );
+
+ // create [screen] element
+ QDomElement movieElement = document.createElement( "screen" );
+ node.appendChild( movieElement );
+}
+
+Annotation::SubType ScreenAnnotation::subType() const
+{
+ return AScreen;
+}
+
+void ScreenAnnotation::setAdditionalAction( AdditionalActionType type, Action \
*action ) +{
+ Q_D( ScreenAnnotation );
+ if ( d->m_additionalActions.contains( type ) )
+ delete d->m_additionalActions.value( type );
+
+ d->m_additionalActions.insert( type, action );
+}
+
+Action* ScreenAnnotation::additionalAction( AdditionalActionType type ) const
+{
+ Q_D( const ScreenAnnotation );
+ if ( !d->m_additionalActions.contains( type ) )
+ return 0;
+ else
+ return d->m_additionalActions.value( type );
+}
+
+/** WidgetAnnotation [Annotation] */
+
+class Okular::WidgetAnnotationPrivate : public Okular::AnnotationPrivate
+{
+ public:
+ ~WidgetAnnotationPrivate();
+ QMap< Okular::Annotation::AdditionalActionType, Okular::Action* > \
m_additionalActions; +};
+
+WidgetAnnotationPrivate::~WidgetAnnotationPrivate()
+{
+ qDeleteAll( m_additionalActions );
+}
+
+WidgetAnnotation::WidgetAnnotation()
+ : Annotation( *new WidgetAnnotationPrivate() )
+{
+}
+
+WidgetAnnotation::WidgetAnnotation( const QDomNode & node )
+ : Annotation( *new WidgetAnnotationPrivate(), node )
+{
+ // loop through the whole children looking for a 'widget' element
+ QDomNode subNode = node.firstChild();
+ while( subNode.isElement() )
+ {
+ QDomElement e = subNode.toElement();
+ subNode = subNode.nextSibling();
+ if ( e.tagName() != "widget" )
+ continue;
+
+ // loading complete
+ break;
+ }
+}
+
+WidgetAnnotation::~WidgetAnnotation()
+{
+}
+
+void WidgetAnnotation::store( QDomNode & node, QDomDocument & document ) const
+{
+ // recurse to parent objects storing properties
+ Annotation::store( node, document );
+
+ // create [widget] element
+ QDomElement movieElement = document.createElement( "widget" );
+ node.appendChild( movieElement );
+}
+
+Annotation::SubType WidgetAnnotation::subType() const
+{
+ return AWidget;
+}
+
+void WidgetAnnotation::setAdditionalAction( AdditionalActionType type, Action \
*action ) +{
+ Q_D( WidgetAnnotation );
+ if ( d->m_additionalActions.contains( type ) )
+ delete d->m_additionalActions.value( type );
+
+ d->m_additionalActions.insert( type, action );
+}
+
+Action* WidgetAnnotation::additionalAction( AdditionalActionType type ) const
+{
+ Q_D( const WidgetAnnotation );
+ if ( !d->m_additionalActions.contains( type ) )
+ return 0;
+ else
+ return d->m_additionalActions.value( type );
+}
diff --git a/core/annotations.h b/core/annotations.h
index e2b04bc..5fefb29 100644
--- a/core/annotations.h
+++ b/core/annotations.h
@@ -23,6 +23,7 @@
namespace Okular {
+class Action;
class Annotation;
class AnnotationObjectRect;
class AnnotationPrivate;
@@ -42,6 +43,8 @@ class CaretAnnotationPrivate;
class FileAttachmentAnnotationPrivate;
class SoundAnnotationPrivate;
class MovieAnnotationPrivate;
+class ScreenAnnotationPrivate;
+class WidgetAnnotationPrivate;
/**
* @short Helper class for (recursive) annotation retrieval/storage.
@@ -109,6 +112,8 @@ class OKULAR_EXPORT Annotation
AFileAttachment = 9, ///< A file attachment annotation
ASound = 10, ///< A sound annotation
AMovie = 11, ///< A movie annotation
+ AScreen = 12, ///< A screen annotation
+ AWidget = 13, ///< A widget annotation
A_BASE = 0 ///< The annotation base class
};
@@ -175,6 +180,17 @@ class OKULAR_EXPORT Annotation
};
/**
+ * Describes the type of additional actions.
+ *
+ * @since 0.16 (KDE 4.10)
+ */
+ enum AdditionalActionType
+ {
+ PageOpening, ///< Performed when the page containing the annotation is \
opened. + PageClosing ///< Performed when the page containing the \
annotation is closed. + };
+
+ /**
* A function to be called when the annotation is destroyed.
*
* @warning the function must *not* call any virtual function,
@@ -1511,6 +1527,117 @@ class OKULAR_EXPORT MovieAnnotation : public Annotation
Q_DISABLE_COPY( MovieAnnotation )
};
+/**
+ * \short Screen annotation.
+ *
+ * The screen annotation specifies a region of a page upon which media clips
+ * may be played. It also serves as an object from which actions can be triggered.
+ *
+ * @since 0.16 (KDE 4.10)
+ */
+class OKULAR_EXPORT ScreenAnnotation : public Annotation
+{
+ public:
+ /**
+ * Creates a new screen annotation.
+ */
+ ScreenAnnotation();
+
+ /**
+ * Creates a new screen annotation from the xml @p description
+ */
+ ScreenAnnotation( const QDomNode &description );
+
+ /**
+ * Destroys the screen annotation.
+ */
+ virtual ~ScreenAnnotation();
+
+ /**
+ * Returns the sub type of the screen annotation.
+ */
+ SubType subType() const;
+
+ /**
+ * Stores the screen annotation as xml in @p document
+ * under the given @p parentNode.
+ */
+ void store( QDomNode &parentNode, QDomDocument &document ) const;
+
+ /**
+ * Sets the additional @p action of the given @p type.
+ *
+ * @since 0.16 (KDE 4.10)
+ */
+ void setAdditionalAction( AdditionalActionType type, Action *action );
+
+ /**
+ * Returns the additional action of the given @p type or @c 0 if no action \
has been defined. + *
+ * @since 0.16 (KDE 4.10)
+ */
+ Action* additionalAction( AdditionalActionType type ) const;
+
+ private:
+ Q_DECLARE_PRIVATE( ScreenAnnotation )
+ Q_DISABLE_COPY( ScreenAnnotation )
+};
+
+/**
+ * \short Widget annotation.
+ *
+ * The widget annotation represents a widget on a page.
+ *
+ * @since 0.16 (KDE 4.10)
+ */
+class OKULAR_EXPORT WidgetAnnotation : public Annotation
+{
+ public:
+ /**
+ * Creates a new widget annotation.
+ */
+ WidgetAnnotation();
+
+ /**
+ * Creates a new widget annotation from the xml @p description
+ */
+ WidgetAnnotation( const QDomNode &description );
+
+ /**
+ * Destroys the widget annotation.
+ */
+ virtual ~WidgetAnnotation();
+
+ /**
+ * Returns the sub type of the widget annotation.
+ */
+ SubType subType() const;
+
+ /**
+ * Stores the widget annotation as xml in @p document
+ * under the given @p parentNode.
+ */
+ void store( QDomNode &parentNode, QDomDocument &document ) const;
+
+ /**
+ * Sets the additional @p action of the given @p type.
+ *
+ * @since 0.16 (KDE 4.10)
+ */
+ void setAdditionalAction( AdditionalActionType type, Action *action );
+
+ /**
+ * Returns the additional action of the given @p type or @c 0 if no action \
has been defined. + *
+ * @since 0.16 (KDE 4.10)
+ */
+ Action* additionalAction( AdditionalActionType type ) const;
+
+ private:
+ Q_DECLARE_PRIVATE( WidgetAnnotation )
+ Q_DISABLE_COPY( WidgetAnnotation )
+};
+
}
#endif
diff --git a/generators/poppler/annots.cpp b/generators/poppler/annots.cpp
index 06128c5..02813a1 100644
--- a/generators/poppler/annots.cpp
+++ b/generators/poppler/annots.cpp
@@ -310,6 +310,13 @@ Okular::Annotation* createAnnotationFromPopplerAnnotation( \
Poppler::Annotation *
break;
}
+#ifdef HAVE_POPPLER_0_22
+ case Poppler::Annotation::AWidget:
+ {
+ annotation = new Okular::WidgetAnnotation();
+ break;
+ }
+#endif
#ifdef HAVE_POPPLER_0_20
case Poppler::Annotation::AScreen:
{
diff --git a/generators/poppler/generator_pdf.cpp \
b/generators/poppler/generator_pdf.cpp index c63753e..9462195 100644
--- a/generators/poppler/generator_pdf.cpp
+++ b/generators/poppler/generator_pdf.cpp
@@ -945,6 +945,23 @@ void PDFGenerator::resolveMovieLinkReferences( Okular::Page \
*page )
resolveMovieLinkReference( const_cast<Okular::Action*>( page->pageAction( \
Okular::Page::Opening ) ), page );
resolveMovieLinkReference( const_cast<Okular::Action*>( page->pageAction( \
Okular::Page::Closing ) ), page );
+ foreach ( Okular::Annotation *annotation, page->annotations() )
+ {
+ if ( annotation->subType() == Okular::Annotation::AScreen )
+ {
+ Okular::ScreenAnnotation *screenAnnotation = \
static_cast<Okular::ScreenAnnotation*>( annotation ); + \
resolveMovieLinkReference( screenAnnotation->additionalAction( \
Okular::Annotation::PageOpening ), page ); + resolveMovieLinkReference( \
screenAnnotation->additionalAction( Okular::Annotation::PageClosing ), page ); + \
} +
+ if ( annotation->subType() == Okular::Annotation::AWidget )
+ {
+ Okular::WidgetAnnotation *widgetAnnotation = \
static_cast<Okular::WidgetAnnotation*>( annotation ); + \
resolveMovieLinkReference( widgetAnnotation->additionalAction( \
Okular::Annotation::PageOpening ), page ); + resolveMovieLinkReference( \
widgetAnnotation->additionalAction( Okular::Annotation::PageClosing ), page ); + \
} + }
+
foreach ( Okular::FormField *field, page->formFields() )
resolveMovieLinkReference( field->activationAction(), page );
}
@@ -1376,6 +1393,36 @@ void PDFGenerator::addAnnotations( Poppler::Page * \
popplerPage, Okular::Page * p {
page->addAnnotation(newann);
+#ifdef HAVE_POPPLER_0_22
+ if ( a->subType() == Poppler::Annotation::AScreen )
+ {
+ Poppler::ScreenAnnotation *annotScreen = \
static_cast<Poppler::ScreenAnnotation*>( a ); + \
Okular::ScreenAnnotation *screenAnnotation = static_cast<Okular::ScreenAnnotation*>( \
newann ); +
+ const Poppler::Link *pageOpeningLink = \
annotScreen->additionalAction( Poppler::Annotation::PageOpeningAction ); + \
if ( pageOpeningLink ) + screenAnnotation->setAdditionalAction( \
Okular::Annotation::PageOpening, createLinkFromPopplerLink( pageOpeningLink ) ); +
+ const Poppler::Link *pageClosingLink = \
annotScreen->additionalAction( Poppler::Annotation::PageClosingAction ); + \
if ( pageClosingLink ) + screenAnnotation->setAdditionalAction( \
Okular::Annotation::PageClosing, createLinkFromPopplerLink( pageClosingLink ) ); + \
} +
+ if ( a->subType() == Poppler::Annotation::AWidget )
+ {
+ Poppler::WidgetAnnotation *annotWidget = \
static_cast<Poppler::WidgetAnnotation*>( a ); + \
Okular::WidgetAnnotation *widgetAnnotation = static_cast<Okular::WidgetAnnotation*>( \
newann ); +
+ const Poppler::Link *pageOpeningLink = \
annotWidget->additionalAction( Poppler::Annotation::PageOpeningAction ); + \
if ( pageOpeningLink ) + widgetAnnotation->setAdditionalAction( \
Okular::Annotation::PageOpening, createLinkFromPopplerLink( pageOpeningLink ) ); +
+ const Poppler::Link *pageClosingLink = \
annotWidget->additionalAction( Poppler::Annotation::PageClosingAction ); + \
if ( pageClosingLink ) + widgetAnnotation->setAdditionalAction( \
Okular::Annotation::PageClosing, createLinkFromPopplerLink( pageClosingLink ) ); + \
} +#endif
+
if ( !doDelete )
annotationsHash.insert( newann, a );
}
diff --git a/ui/guiutils.cpp b/ui/guiutils.cpp
index f66dc47..30be525 100644
--- a/ui/guiutils.cpp
+++ b/ui/guiutils.cpp
@@ -99,6 +99,12 @@ QString captionForAnnotation( const Okular::Annotation * ann )
case Okular::Annotation::AMovie:
ret = i18n( "Movie" );
break;
+ case Okular::Annotation::AScreen:
+ ret = i18nc( "Caption for a screen annotation", "Screen" );
+ break;
+ case Okular::Annotation::AWidget:
+ ret = i18nc( "Caption for a widget annotation", "Widget" );
+ break;
case Okular::Annotation::A_BASE:
break;
}
diff --git a/ui/presentationwidget.cpp b/ui/presentationwidget.cpp
index 3f3796b..95e78d4 100644
--- a/ui/presentationwidget.cpp
+++ b/ui/presentationwidget.cpp
@@ -379,6 +379,20 @@ void PresentationWidget::notifyCurrentPageChanged( int \
previousPage, int current // perform the page closing action, if any
if ( m_document->page( previousPage )->pageAction( Okular::Page::Closing ) )
m_document->processAction( m_document->page( previousPage )->pageAction( \
Okular::Page::Closing ) ); +
+ // perform the additional actions of the page's annotations, if any
+ Q_FOREACH ( const Okular::Annotation *annotation, m_document->page( \
m_frameIndex )->annotations() ) + {
+ Okular::Action *action = 0;
+
+ if ( annotation->subType() == Okular::Annotation::AScreen )
+ action = static_cast<const Okular::ScreenAnnotation*>( annotation \
)->additionalAction( Okular::Annotation::PageClosing ); + else if ( \
annotation->subType() == Okular::Annotation::AWidget ) + action = \
static_cast<const Okular::WidgetAnnotation*>( annotation )->additionalAction( \
Okular::Annotation::PageClosing ); +
+ if ( action )
+ m_document->processAction( action );
+ }
}
if ( currentPage != -1 )
@@ -411,6 +425,20 @@ void PresentationWidget::notifyCurrentPageChanged( int \
previousPage, int current
if ( m_document->page( m_frameIndex )->pageAction( Okular::Page::Opening ) )
m_document->processAction( m_document->page( m_frameIndex )->pageAction( \
Okular::Page::Opening ) );
+ // perform the additional actions of the page's annotations, if any
+ Q_FOREACH ( const Okular::Annotation *annotation, m_document->page( \
m_frameIndex )->annotations() ) + {
+ Okular::Action *action = 0;
+
+ if ( annotation->subType() == Okular::Annotation::AScreen )
+ action = static_cast<const Okular::ScreenAnnotation*>( annotation \
)->additionalAction( Okular::Annotation::PageOpening ); + else if ( \
annotation->subType() == Okular::Annotation::AWidget ) + action = \
static_cast<const Okular::WidgetAnnotation*>( annotation )->additionalAction( \
Okular::Annotation::PageOpening ); +
+ if ( action )
+ m_document->processAction( action );
+ }
+
// start autoplay video playback
Q_FOREACH ( VideoWidget *vw, m_frames[ m_frameIndex ]->videoWidgets )
vw->pageEntered();
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic