diff --git a/qt4/src/poppler-annotation.cc b/qt4/src/poppler-annotation.cc index 364e9d0..651cf92 100644 --- a/qt4/src/poppler-annotation.cc +++ b/qt4/src/poppler-annotation.cc @@ -568,6 +568,170 @@ QList AnnotationPrivate::findAnnotations(::Page *pdfPage, DocumentD continue; annotation = new WidgetAnnotation(); break; + case Annot::typeRichMedia: + { + const AnnotRichMedia * annotRichMedia = static_cast< AnnotRichMedia * >( ann ); + + RichMediaAnnotation *richMediaAnnotation = new RichMediaAnnotation; + + const AnnotRichMedia::Settings *annotSettings = annotRichMedia->getSettings(); + if ( annotSettings ) { + RichMediaAnnotation::Settings *settings = new RichMediaAnnotation::Settings; + + if ( annotSettings->getActivation() ) { + RichMediaAnnotation::Activation *activation = new RichMediaAnnotation::Activation; + + switch ( annotSettings->getActivation()->getCondition() ) + { + case AnnotRichMedia::Activation::conditionPageOpened: + activation->setCondition( RichMediaAnnotation::Activation::PageOpened ); + break; + case AnnotRichMedia::Activation::conditionPageVisible: + activation->setCondition( RichMediaAnnotation::Activation::PageVisible ); + break; + case AnnotRichMedia::Activation::conditionUserAction: + activation->setCondition( RichMediaAnnotation::Activation::UserAction ); + break; + } + + settings->setActivation( activation ); + } + + if ( annotSettings->getDeactivation() ) { + RichMediaAnnotation::Deactivation *deactivation = new RichMediaAnnotation::Deactivation; + + switch ( annotSettings->getDeactivation()->getCondition() ) + { + case AnnotRichMedia::Deactivation::conditionPageClosed: + deactivation->setCondition( RichMediaAnnotation::Deactivation::PageClosed ); + break; + case AnnotRichMedia::Deactivation::conditionPageInvisible: + deactivation->setCondition( RichMediaAnnotation::Deactivation::PageInvisible ); + break; + case AnnotRichMedia::Deactivation::conditionUserAction: + deactivation->setCondition( RichMediaAnnotation::Deactivation::UserAction ); + break; + } + + settings->setDeactivation( deactivation ); + } + + richMediaAnnotation->setSettings( settings ); + } + + const AnnotRichMedia::Content *annotContent = annotRichMedia->getContent(); + if ( annotContent ) { + RichMediaAnnotation::Content *content = new RichMediaAnnotation::Content; + + const int configurationsCount = annotContent->getConfigurationsCount(); + if ( configurationsCount > 0 ) { + QList< RichMediaAnnotation::Configuration* > configurations; + + for ( int i = 0; i < configurationsCount; ++i ) { + const AnnotRichMedia::Configuration *annotConfiguration = annotContent->getConfiguration( i ); + if ( !annotConfiguration ) + continue; + + RichMediaAnnotation::Configuration *configuration = new RichMediaAnnotation::Configuration; + + if ( annotConfiguration->getName() ) + configuration->setName( UnicodeParsedString( annotConfiguration->getName() ) ); + + switch ( annotConfiguration->getType() ) + { + case AnnotRichMedia::Configuration::type3D: + configuration->setType( RichMediaAnnotation::Configuration::Type3D ); + break; + case AnnotRichMedia::Configuration::typeFlash: + configuration->setType( RichMediaAnnotation::Configuration::TypeFlash ); + break; + case AnnotRichMedia::Configuration::typeSound: + configuration->setType( RichMediaAnnotation::Configuration::TypeSound ); + break; + case AnnotRichMedia::Configuration::typeVideo: + configuration->setType( RichMediaAnnotation::Configuration::TypeVideo ); + break; + } + + const int instancesCount = annotConfiguration->getInstancesCount(); + if ( instancesCount > 0 ) { + QList< RichMediaAnnotation::Instance* > instances; + + for ( int j = 0; j < instancesCount; ++j ) { + const AnnotRichMedia::Instance *annotInstance = annotConfiguration->getInstance( j ); + if ( !annotInstance ) + continue; + + RichMediaAnnotation::Instance *instance = new RichMediaAnnotation::Instance; + + switch ( annotInstance->getType() ) + { + case AnnotRichMedia::Instance::type3D: + instance->setType( RichMediaAnnotation::Instance::Type3D ); + break; + case AnnotRichMedia::Instance::typeFlash: + instance->setType( RichMediaAnnotation::Instance::TypeFlash ); + break; + case AnnotRichMedia::Instance::typeSound: + instance->setType( RichMediaAnnotation::Instance::TypeSound ); + break; + case AnnotRichMedia::Instance::typeVideo: + instance->setType( RichMediaAnnotation::Instance::TypeVideo ); + break; + } + + const AnnotRichMedia::Params *annotParams = annotInstance->getParams(); + if ( annotParams ) { + RichMediaAnnotation::Params *params = new RichMediaAnnotation::Params; + + if ( annotParams->getFlashVars() ) + params->setFlashVars( UnicodeParsedString( annotParams->getFlashVars() ) ); + + instance->setParams( params ); + } + + instances.append( instance ); + } + + configuration->setInstances( instances ); + } + + configurations.append( configuration ); + } + + content->setConfigurations( configurations ); + } + + const int assetsCount = annotContent->getAssetsCount(); + if ( assetsCount > 0 ) { + QList< RichMediaAnnotation::Asset* > assets; + + for ( int i = 0; i < assetsCount; ++i ) { + const AnnotRichMedia::Asset *annotAsset = annotContent->getAsset( i ); + if ( !annotAsset ) + continue; + + RichMediaAnnotation::Asset *asset = new RichMediaAnnotation::Asset; + + if ( annotAsset->getName() ) + asset->setName( UnicodeParsedString( annotAsset->getName() ) ); + + FileSpec *fileSpec = new FileSpec( annotAsset->getFileSpec() ); + asset->setEmbeddedFile( new EmbeddedFile( *new EmbeddedFileData( fileSpec ) ) ); + + assets.append( asset ); + } + + content->setAssets( assets ); + } + + richMediaAnnotation->setContent( content ); + } + + annotation = richMediaAnnotation; + + break; + } default: { #define CASE_FOR_TYPE( thetype ) \ @@ -4436,6 +4600,455 @@ Link* WidgetAnnotation::additionalAction( AdditionalActionType type ) const return d->additionalAction( type ); } +/** RichMediaAnnotation [Annotation] */ +class RichMediaAnnotation::Params::Private +{ + public: + Private() {} + + QString flashVars; +}; + +RichMediaAnnotation::Params::Params() + : d( new Private ) +{ +} + +RichMediaAnnotation::Params::~Params() +{ +} + +void RichMediaAnnotation::Params::setFlashVars( const QString &flashVars ) +{ + d->flashVars = flashVars; +} + +QString RichMediaAnnotation::Params::flashVars() const +{ + return d->flashVars; +} + + +class RichMediaAnnotation::Instance::Private +{ + public: + Private() + : params( 0 ) + { + } + + ~Private() + { + delete params; + } + + RichMediaAnnotation::Instance::Type type; + RichMediaAnnotation::Params *params; +}; + +RichMediaAnnotation::Instance::Instance() + : d( new Private ) +{ +} + +RichMediaAnnotation::Instance::~Instance() +{ +} + +void RichMediaAnnotation::Instance::setType( Type type ) +{ + d->type = type; +} + +RichMediaAnnotation::Instance::Type RichMediaAnnotation::Instance::type() const +{ + return d->type; +} + +void RichMediaAnnotation::Instance::setParams( RichMediaAnnotation::Params *params ) +{ + delete d->params; + d->params = params; +} + +RichMediaAnnotation::Params* RichMediaAnnotation::Instance::params() const +{ + return d->params; +} + + +class RichMediaAnnotation::Configuration::Private +{ + public: + Private() {} + ~Private() + { + qDeleteAll( instances ); + instances.clear(); + } + + RichMediaAnnotation::Configuration::Type type; + QString name; + QList< RichMediaAnnotation::Instance* > instances; +}; + +RichMediaAnnotation::Configuration::Configuration() + : d( new Private ) +{ +} + +RichMediaAnnotation::Configuration::~Configuration() +{ +} + +void RichMediaAnnotation::Configuration::setType( Type type ) +{ + d->type = type; +} + +RichMediaAnnotation::Configuration::Type RichMediaAnnotation::Configuration::type() const +{ + return d->type; +} + +void RichMediaAnnotation::Configuration::setName( const QString &name ) +{ + d->name = name; +} + +QString RichMediaAnnotation::Configuration::name() const +{ + return d->name; +} + +void RichMediaAnnotation::Configuration::setInstances( const QList< RichMediaAnnotation::Instance* > &instances ) +{ + qDeleteAll( d->instances ); + d->instances.clear(); + + d->instances = instances; +} + +QList< RichMediaAnnotation::Instance* > RichMediaAnnotation::Configuration::instances() const +{ + return d->instances; +} + + +class RichMediaAnnotation::Asset::Private +{ + public: + Private() + : embeddedFile( 0 ) + { + } + + ~Private() + { + delete embeddedFile; + } + + QString name; + EmbeddedFile *embeddedFile; +}; + +RichMediaAnnotation::Asset::Asset() + : d( new Private ) +{ +} + +RichMediaAnnotation::Asset::~Asset() +{ +} + +void RichMediaAnnotation::Asset::setName( const QString &name ) +{ + d->name = name; +} + +QString RichMediaAnnotation::Asset::name() const +{ + return d->name; +} + +void RichMediaAnnotation::Asset::setEmbeddedFile( EmbeddedFile * embeddedFile ) +{ + delete d->embeddedFile; + d->embeddedFile = embeddedFile; +} + +EmbeddedFile* RichMediaAnnotation::Asset::embeddedFile() const +{ + return d->embeddedFile; +} + + +class RichMediaAnnotation::Content::Private +{ + public: + Private() {} + ~Private() + { + qDeleteAll( configurations ); + configurations.clear(); + + qDeleteAll( assets ); + assets.clear(); + } + + QList< RichMediaAnnotation::Configuration* > configurations; + QList< RichMediaAnnotation::Asset* > assets; +}; + +RichMediaAnnotation::Content::Content() + : d( new Private ) +{ +} + +RichMediaAnnotation::Content::~Content() +{ +} + +void RichMediaAnnotation::Content::setConfigurations( const QList< RichMediaAnnotation::Configuration* > &configurations ) +{ + qDeleteAll( d->configurations ); + d->configurations.clear(); + + d->configurations = configurations; +} + +QList< RichMediaAnnotation::Configuration* > RichMediaAnnotation::Content::configurations() const +{ + return d->configurations; +} + +void RichMediaAnnotation::Content::setAssets( const QList< RichMediaAnnotation::Asset* > &assets ) +{ + qDeleteAll( d->assets ); + d->assets.clear(); + + d->assets = assets; +} + +QList< RichMediaAnnotation::Asset* > RichMediaAnnotation::Content::assets() const +{ + return d->assets; +} + + +class RichMediaAnnotation::Activation::Private +{ + public: + Private() + : condition( RichMediaAnnotation::Activation::UserAction ) + { + } + + RichMediaAnnotation::Activation::Condition condition; +}; + +RichMediaAnnotation::Activation::Activation() + : d( new Private ) +{ +} + +RichMediaAnnotation::Activation::~Activation() +{ +} + +void RichMediaAnnotation::Activation::setCondition( Condition condition ) +{ + d->condition = condition; +} + +RichMediaAnnotation::Activation::Condition RichMediaAnnotation::Activation::condition() const +{ + return d->condition; +} + + +class RichMediaAnnotation::Deactivation::Private : public QSharedData +{ + public: + Private() + : condition( RichMediaAnnotation::Deactivation::UserAction ) + { + } + + RichMediaAnnotation::Deactivation::Condition condition; +}; + +RichMediaAnnotation::Deactivation::Deactivation() + : d( new Private ) +{ +} + +RichMediaAnnotation::Deactivation::~Deactivation() +{ +} + +void RichMediaAnnotation::Deactivation::setCondition( Condition condition ) +{ + d->condition = condition; +} + +RichMediaAnnotation::Deactivation::Condition RichMediaAnnotation::Deactivation::condition() const +{ + return d->condition; +} + + +class RichMediaAnnotation::Settings::Private : public QSharedData +{ + public: + Private() + : activation( 0 ), deactivation( 0 ) + { + } + + RichMediaAnnotation::Activation *activation; + RichMediaAnnotation::Deactivation *deactivation; +}; + +RichMediaAnnotation::Settings::Settings() + : d( new Private ) +{ +} + +RichMediaAnnotation::Settings::~Settings() +{ +} + +void RichMediaAnnotation::Settings::setActivation( RichMediaAnnotation::Activation *activation ) +{ + delete d->activation; + d->activation = activation; +} + +RichMediaAnnotation::Activation* RichMediaAnnotation::Settings::activation() const +{ + return d->activation; +} + +void RichMediaAnnotation::Settings::setDeactivation( RichMediaAnnotation::Deactivation *deactivation ) +{ + delete d->deactivation; + d->deactivation = deactivation; +} + +RichMediaAnnotation::Deactivation* RichMediaAnnotation::Settings::deactivation() const +{ + return d->deactivation; +} + + +class RichMediaAnnotationPrivate : public AnnotationPrivate +{ + public: + RichMediaAnnotationPrivate() + : settings( 0 ), content( 0 ) + { + } + + ~RichMediaAnnotationPrivate() + { + delete settings; + delete content; + } + + Annotation * makeAlias() + { + return new RichMediaAnnotation( *this ); + } + + Annot* createNativeAnnot( ::Page *destPage, DocumentData *doc ) + { + Q_UNUSED( destPage ); + Q_UNUSED( doc ); + + return 0; + } + + RichMediaAnnotation::Settings *settings; + RichMediaAnnotation::Content *content; +}; + +RichMediaAnnotation::RichMediaAnnotation() + : Annotation( *new RichMediaAnnotationPrivate() ) +{ +} + +RichMediaAnnotation::RichMediaAnnotation( RichMediaAnnotationPrivate &dd ) + : Annotation( dd ) +{ +} + +RichMediaAnnotation::RichMediaAnnotation( const QDomNode & node ) + : Annotation( *new RichMediaAnnotationPrivate(), 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; + } +} + +RichMediaAnnotation::~RichMediaAnnotation() +{ +} + +void RichMediaAnnotation::store( QDomNode & node, QDomDocument & document ) const +{ + // store base annotation properties + storeBaseAnnotationProperties( node, document ); + + // create [richMedia] element + QDomElement richMediaElement = document.createElement( "richMedia" ); + node.appendChild( richMediaElement ); +} + +Annotation::SubType RichMediaAnnotation::subType() const +{ + return ARichMedia; +} + +void RichMediaAnnotation::setSettings( RichMediaAnnotation::Settings *settings ) +{ + Q_D( RichMediaAnnotation ); + + delete d->settings; + d->settings = settings; +} + +RichMediaAnnotation::Settings* RichMediaAnnotation::settings() const +{ + Q_D( const RichMediaAnnotation ); + + return d->settings; +} + +void RichMediaAnnotation::setContent( RichMediaAnnotation::Content *content ) +{ + Q_D( RichMediaAnnotation ); + + delete d->content; + d->content = content; +} + +RichMediaAnnotation::Content* RichMediaAnnotation::content() const +{ + Q_D( const RichMediaAnnotation ); + + return d->content; +} + //BEGIN utility annotation functions QColor convertAnnotColor( AnnotColor *color ) { diff --git a/qt4/src/poppler-annotation.h b/qt4/src/poppler-annotation.h index 03f5e26..a5d9097 100644 --- a/qt4/src/poppler-annotation.h +++ b/qt4/src/poppler-annotation.h @@ -3,7 +3,7 @@ * Copyright (C) 2006, 2008 Pino Toscano * Copyright (C) 2007, Brad Hards * Copyright (C) 2010, Philip Lorenz - * Copyright (C) 2012, Tobias Koenig + * Copyright (C) 2012-2015, Tobias Koenig * Copyright (C) 2012, Guillermo A. Amaral B. * Copyright (C) 2012, 2013 Fabio D'Urso * Adapting code from @@ -56,6 +56,7 @@ class SoundAnnotationPrivate; class MovieAnnotationPrivate; class ScreenAnnotationPrivate; class WidgetAnnotationPrivate; +class RichMediaAnnotationPrivate; class EmbeddedFile; class Link; class SoundObject; @@ -196,6 +197,7 @@ class POPPLER_QT4_EXPORT Annotation AMovie = 11, ///< MovieAnnotation AScreen = 12, ///< ScreenAnnotation \since 0.20 AWidget = 13, ///< WidgetAnnotation \since 0.22 + ARichMedia = 14, ///< RichMediaAnnotation \since 0.35 A_BASE = 0 }; @@ -1042,6 +1044,332 @@ class POPPLER_QT4_EXPORT WidgetAnnotation : public Annotation Q_DISABLE_COPY( WidgetAnnotation ) }; +/** + * \short RichMedia annotation. + * + * The RichMedia annotation represents a video or sound on a page. + * + * \since 0.35 + */ +class POPPLER_QT4_EXPORT RichMediaAnnotation : public Annotation +{ + friend class AnnotationPrivate; + + public: + virtual ~RichMediaAnnotation(); + + virtual SubType subType() const; + + /** + * The params object of a RichMediaAnnotation::Instance object. + * + * The params object provides media specific parameters, to play + * back the media inside the PDF viewer. + * + * At the moment only parameters for flash player are supported. + */ + class POPPLER_QT4_EXPORT Params + { + friend class AnnotationPrivate; + + public: + Params(); + ~Params(); + + /** + * Returns the parameters for the flash player. + */ + QString flashVars() const; + + private: + void setFlashVars( const QString &flashVars ); + + class Private; + QScopedPointer d; + }; + + /** + * The instance object of a RichMediaAnnotation::Configuration object. + * + * The instance object represents one media object, that should be shown + * on the page. It has a media type and a Params object, to define the + * media specific parameters. + */ + class POPPLER_QT4_EXPORT Instance + { + friend class AnnotationPrivate; + + public: + /** + * Describes the media type of the instance. + */ + enum Type + { + Type3D, ///< A 3D media file. + TypeFlash, ///< A Flash media file. + TypeSound, ///< A sound media file. + TypeVideo ///< A video media file. + }; + + Instance(); + ~Instance(); + + /** + * Returns the media type of the instance. + */ + Type type() const; + + /** + * Returns the params object of the instance or @c 0 if it doesn't exist. + */ + RichMediaAnnotation::Params* params() const; + + private: + void setType( Type type ); + void setParams( RichMediaAnnotation::Params *params ); + + class Private; + QScopedPointer d; + }; + + /** + * The configuration object of a RichMediaAnnotation::Content object. + * + * The configuration object provides access to the various Instance objects + * of the rich media annotation. + */ + class POPPLER_QT4_EXPORT Configuration + { + friend class AnnotationPrivate; + + public: + /** + * Describes the media type of the configuration. + */ + enum Type + { + Type3D, ///< A 3D media file. + TypeFlash, ///< A Flash media file. + TypeSound, ///< A sound media file. + TypeVideo ///< A video media file. + }; + + Configuration(); + ~Configuration(); + + /** + * Returns the media type of the configuration. + */ + Type type() const; + + /** + * Returns the name of the configuration. + */ + QString name() const; + + /** + * Returns the list of Instance objects of the configuration. + */ + QList< RichMediaAnnotation::Instance* > instances() const; + + private: + void setType( Type type ); + void setName( const QString &name ); + void setInstances( const QList< RichMediaAnnotation::Instance* > &instances ); + + class Private; + QScopedPointer d; + }; + + /** + * The asset object of a RichMediaAnnotation::Content object. + * + * The asset object provides a mapping between identifier name, as + * used in the flash vars string of RichMediaAnnotation::Params, and the + * associated file spec object. + */ + class POPPLER_QT4_EXPORT Asset + { + friend class AnnotationPrivate; + + public: + Asset(); + ~Asset(); + + /** + * Returns the identifier name of the asset. + */ + QString name() const; + + /** + * Returns the embedded file the asset points to. + */ + EmbeddedFile* embeddedFile() const; + + private: + void setName( const QString &name ); + void setEmbeddedFile( EmbeddedFile *embeddedFile ); + + class Private; + QScopedPointer d; + }; + + /** + * The content object of a RichMediaAnnotation. + * + * The content object provides access to the list of configurations + * and assets of the rich media annotation. + */ + class POPPLER_QT4_EXPORT Content + { + friend class AnnotationPrivate; + + public: + Content(); + ~Content(); + + /** + * Returns the list of configuration objects of the content object. + */ + QList< RichMediaAnnotation::Configuration* > configurations() const; + + /** + * Returns the list of asset objects of the content object. + */ + QList< RichMediaAnnotation::Asset* > assets() const; + + private: + void setConfigurations( const QList< RichMediaAnnotation::Configuration* > &configurations ); + void setAssets( const QList< RichMediaAnnotation::Asset* > &assets ); + + class Private; + QScopedPointer d; + }; + + /** + * The activation object of the RichMediaAnnotation::Settings object. + * + * The activation object is a wrapper around the settings for the activation + * state. At the moment it provides only the activation condition. + */ + class POPPLER_QT4_EXPORT Activation + { + friend class AnnotationPrivate; + + public: + /** + * Describes the condition for activating the rich media. + */ + enum Condition { + PageOpened, ///< Activate when page is opened. + PageVisible, ///< Activate when page becomes visible. + UserAction ///< Activate when user interacts with the annotation. + }; + + Activation(); + ~Activation(); + + /** + * Returns the activation condition. + */ + Condition condition() const; + + private: + void setCondition( Condition condition ); + + class Private; + QScopedPointer d; + }; + + /** + * The deactivation object of the RichMediaAnnotation::Settings object. + * + * The deactivation object is a wrapper around the settings for the deactivation + * state. At the moment it provides only the deactivation condition. + */ + class POPPLER_QT4_EXPORT Deactivation + { + friend class AnnotationPrivate; + + public: + /** + * Describes the condition for deactivating the rich media. + */ + enum Condition { + PageClosed, ///< Deactivate when page is closed. + PageInvisible, ///< Deactivate when page becomes invisible. + UserAction ///< Deactivate when user interacts with the annotation. + }; + + Deactivation(); + ~Deactivation(); + + /** + * Returns the deactivation condition. + */ + Condition condition() const; + + private: + void setCondition( Condition condition ); + + class Private; + QScopedPointer d; + }; + + /** + * The settings object of a RichMediaAnnotation. + * + * The settings object provides access to the configuration objects + * for annotation activation and deactivation. + */ + class POPPLER_QT4_EXPORT Settings + { + friend class AnnotationPrivate; + + public: + Settings(); + ~Settings(); + + /** + * Returns the Activation object of the settings object or @c 0 if it doesn't exist. + */ + RichMediaAnnotation::Activation* activation() const; + + /** + * Returns the Deactivation object of the settings object or @c 0 if it doesn't exist. + */ + RichMediaAnnotation::Deactivation* deactivation() const; + + private: + void setActivation( RichMediaAnnotation::Activation *activation ); + void setDeactivation( RichMediaAnnotation::Deactivation *deactivation ); + + class Private; + QScopedPointer d; + }; + + /** + * Returns the Settings object of the rich media annotation or @c 0 if it doesn't exist. + */ + RichMediaAnnotation::Settings* settings() const; + + /** + * Returns the Content object of the rich media annotation or @c 0 if it doesn't exist. + */ + RichMediaAnnotation::Content* content() const; + + private: + void setSettings( RichMediaAnnotation::Settings *settings ); + void setContent( RichMediaAnnotation::Content *content ); + + RichMediaAnnotation(); + RichMediaAnnotation( const QDomNode &node ); + RichMediaAnnotation( RichMediaAnnotationPrivate &dd ); + virtual void store( QDomNode &parentNode, QDomDocument &document ) const; + Q_DECLARE_PRIVATE( RichMediaAnnotation ) + Q_DISABLE_COPY( RichMediaAnnotation ) +}; + } #endif diff --git a/qt5/src/poppler-annotation.cc b/qt5/src/poppler-annotation.cc index 57e8e74..39e42ce 100644 --- a/qt5/src/poppler-annotation.cc +++ b/qt5/src/poppler-annotation.cc @@ -3,7 +3,7 @@ * Copyright (C) 2006, 2008, 2010 Pino Toscano * Copyright (C) 2012, Guillermo A. Amaral B. * Copyright (C) 2012-2014 Fabio D'Urso - * Copyright (C) 2012, Tobias Koenig + * Copyright (C) 2012-2015, Tobias Koenig * Adapting code from * Copyright (C) 2004 by Enrico Ros * @@ -568,6 +568,170 @@ QList AnnotationPrivate::findAnnotations(::Page *pdfPage, DocumentD continue; annotation = new WidgetAnnotation(); break; + case Annot::typeRichMedia: + { + const AnnotRichMedia * annotRichMedia = static_cast< AnnotRichMedia * >( ann ); + + RichMediaAnnotation *richMediaAnnotation = new RichMediaAnnotation; + + const AnnotRichMedia::Settings *annotSettings = annotRichMedia->getSettings(); + if ( annotSettings ) { + RichMediaAnnotation::Settings *settings = new RichMediaAnnotation::Settings; + + if ( annotSettings->getActivation() ) { + RichMediaAnnotation::Activation *activation = new RichMediaAnnotation::Activation; + + switch ( annotSettings->getActivation()->getCondition() ) + { + case AnnotRichMedia::Activation::conditionPageOpened: + activation->setCondition( RichMediaAnnotation::Activation::PageOpened ); + break; + case AnnotRichMedia::Activation::conditionPageVisible: + activation->setCondition( RichMediaAnnotation::Activation::PageVisible ); + break; + case AnnotRichMedia::Activation::conditionUserAction: + activation->setCondition( RichMediaAnnotation::Activation::UserAction ); + break; + } + + settings->setActivation( activation ); + } + + if ( annotSettings->getDeactivation() ) { + RichMediaAnnotation::Deactivation *deactivation = new RichMediaAnnotation::Deactivation; + + switch ( annotSettings->getDeactivation()->getCondition() ) + { + case AnnotRichMedia::Deactivation::conditionPageClosed: + deactivation->setCondition( RichMediaAnnotation::Deactivation::PageClosed ); + break; + case AnnotRichMedia::Deactivation::conditionPageInvisible: + deactivation->setCondition( RichMediaAnnotation::Deactivation::PageInvisible ); + break; + case AnnotRichMedia::Deactivation::conditionUserAction: + deactivation->setCondition( RichMediaAnnotation::Deactivation::UserAction ); + break; + } + + settings->setDeactivation( deactivation ); + } + + richMediaAnnotation->setSettings( settings ); + } + + const AnnotRichMedia::Content *annotContent = annotRichMedia->getContent(); + if ( annotContent ) { + RichMediaAnnotation::Content *content = new RichMediaAnnotation::Content; + + const int configurationsCount = annotContent->getConfigurationsCount(); + if ( configurationsCount > 0 ) { + QList< RichMediaAnnotation::Configuration* > configurations; + + for ( int i = 0; i < configurationsCount; ++i ) { + const AnnotRichMedia::Configuration *annotConfiguration = annotContent->getConfiguration( i ); + if ( !annotConfiguration ) + continue; + + RichMediaAnnotation::Configuration *configuration = new RichMediaAnnotation::Configuration; + + if ( annotConfiguration->getName() ) + configuration->setName( UnicodeParsedString( annotConfiguration->getName() ) ); + + switch ( annotConfiguration->getType() ) + { + case AnnotRichMedia::Configuration::type3D: + configuration->setType( RichMediaAnnotation::Configuration::Type3D ); + break; + case AnnotRichMedia::Configuration::typeFlash: + configuration->setType( RichMediaAnnotation::Configuration::TypeFlash ); + break; + case AnnotRichMedia::Configuration::typeSound: + configuration->setType( RichMediaAnnotation::Configuration::TypeSound ); + break; + case AnnotRichMedia::Configuration::typeVideo: + configuration->setType( RichMediaAnnotation::Configuration::TypeVideo ); + break; + } + + const int instancesCount = annotConfiguration->getInstancesCount(); + if ( instancesCount > 0 ) { + QList< RichMediaAnnotation::Instance* > instances; + + for ( int j = 0; j < instancesCount; ++j ) { + const AnnotRichMedia::Instance *annotInstance = annotConfiguration->getInstance( j ); + if ( !annotInstance ) + continue; + + RichMediaAnnotation::Instance *instance = new RichMediaAnnotation::Instance; + + switch ( annotInstance->getType() ) + { + case AnnotRichMedia::Instance::type3D: + instance->setType( RichMediaAnnotation::Instance::Type3D ); + break; + case AnnotRichMedia::Instance::typeFlash: + instance->setType( RichMediaAnnotation::Instance::TypeFlash ); + break; + case AnnotRichMedia::Instance::typeSound: + instance->setType( RichMediaAnnotation::Instance::TypeSound ); + break; + case AnnotRichMedia::Instance::typeVideo: + instance->setType( RichMediaAnnotation::Instance::TypeVideo ); + break; + } + + const AnnotRichMedia::Params *annotParams = annotInstance->getParams(); + if ( annotParams ) { + RichMediaAnnotation::Params *params = new RichMediaAnnotation::Params; + + if ( annotParams->getFlashVars() ) + params->setFlashVars( UnicodeParsedString( annotParams->getFlashVars() ) ); + + instance->setParams( params ); + } + + instances.append( instance ); + } + + configuration->setInstances( instances ); + } + + configurations.append( configuration ); + } + + content->setConfigurations( configurations ); + } + + const int assetsCount = annotContent->getAssetsCount(); + if ( assetsCount > 0 ) { + QList< RichMediaAnnotation::Asset* > assets; + + for ( int i = 0; i < assetsCount; ++i ) { + const AnnotRichMedia::Asset *annotAsset = annotContent->getAsset( i ); + if ( !annotAsset ) + continue; + + RichMediaAnnotation::Asset *asset = new RichMediaAnnotation::Asset; + + if ( annotAsset->getName() ) + asset->setName( UnicodeParsedString( annotAsset->getName() ) ); + + FileSpec *fileSpec = new FileSpec( annotAsset->getFileSpec() ); + asset->setEmbeddedFile( new EmbeddedFile( *new EmbeddedFileData( fileSpec ) ) ); + + assets.append( asset ); + } + + content->setAssets( assets ); + } + + richMediaAnnotation->setContent( content ); + } + + annotation = richMediaAnnotation; + + break; + } default: { #define CASE_FOR_TYPE( thetype ) \ @@ -4423,6 +4587,456 @@ Link* WidgetAnnotation::additionalAction( AdditionalActionType type ) const return d->additionalAction( type ); } +/** RichMediaAnnotation [Annotation] */ +class RichMediaAnnotation::Params::Private +{ + public: + Private() {} + + QString flashVars; +}; + +RichMediaAnnotation::Params::Params() + : d( new Private ) +{ +} + +RichMediaAnnotation::Params::~Params() +{ +} + +void RichMediaAnnotation::Params::setFlashVars( const QString &flashVars ) +{ + d->flashVars = flashVars; +} + +QString RichMediaAnnotation::Params::flashVars() const +{ + return d->flashVars; +} + + +class RichMediaAnnotation::Instance::Private +{ + public: + Private() + : params( 0 ) + { + } + + ~Private() + { + delete params; + } + + RichMediaAnnotation::Instance::Type type; + RichMediaAnnotation::Params *params; +}; + +RichMediaAnnotation::Instance::Instance() + : d( new Private ) +{ +} + +RichMediaAnnotation::Instance::~Instance() +{ +} + +void RichMediaAnnotation::Instance::setType( Type type ) +{ + d->type = type; +} + +RichMediaAnnotation::Instance::Type RichMediaAnnotation::Instance::type() const +{ + return d->type; +} + +void RichMediaAnnotation::Instance::setParams( RichMediaAnnotation::Params *params ) +{ + delete d->params; + d->params = params; +} + +RichMediaAnnotation::Params* RichMediaAnnotation::Instance::params() const +{ + return d->params; +} + + +class RichMediaAnnotation::Configuration::Private +{ + public: + Private() {} + ~Private() + { + qDeleteAll( instances ); + instances.clear(); + } + + RichMediaAnnotation::Configuration::Type type; + QString name; + QList< RichMediaAnnotation::Instance* > instances; +}; + +RichMediaAnnotation::Configuration::Configuration() + : d( new Private ) +{ +} + +RichMediaAnnotation::Configuration::~Configuration() +{ +} + +void RichMediaAnnotation::Configuration::setType( Type type ) +{ + d->type = type; +} + +RichMediaAnnotation::Configuration::Type RichMediaAnnotation::Configuration::type() const +{ + return d->type; +} + +void RichMediaAnnotation::Configuration::setName( const QString &name ) +{ + d->name = name; +} + +QString RichMediaAnnotation::Configuration::name() const +{ + return d->name; +} + +void RichMediaAnnotation::Configuration::setInstances( const QList< RichMediaAnnotation::Instance* > &instances ) +{ + qDeleteAll( d->instances ); + d->instances.clear(); + + d->instances = instances; +} + +QList< RichMediaAnnotation::Instance* > RichMediaAnnotation::Configuration::instances() const +{ + return d->instances; +} + + +class RichMediaAnnotation::Asset::Private +{ + public: + Private() + : embeddedFile( 0 ) + { + } + + ~Private() + { + delete embeddedFile; + } + + QString name; + EmbeddedFile *embeddedFile; +}; + +RichMediaAnnotation::Asset::Asset() + : d( new Private ) +{ +} + +RichMediaAnnotation::Asset::~Asset() +{ +} + +void RichMediaAnnotation::Asset::setName( const QString &name ) +{ + d->name = name; +} + +QString RichMediaAnnotation::Asset::name() const +{ + return d->name; +} + +void RichMediaAnnotation::Asset::setEmbeddedFile( EmbeddedFile * embeddedFile ) +{ + delete d->embeddedFile; + d->embeddedFile = embeddedFile; +} + +EmbeddedFile* RichMediaAnnotation::Asset::embeddedFile() const +{ + return d->embeddedFile; +} + + +class RichMediaAnnotation::Content::Private +{ + public: + Private() {} + ~Private() + { + qDeleteAll( configurations ); + configurations.clear(); + + qDeleteAll( assets ); + assets.clear(); + } + + QList< RichMediaAnnotation::Configuration* > configurations; + QList< RichMediaAnnotation::Asset* > assets; +}; + +RichMediaAnnotation::Content::Content() + : d( new Private ) +{ +} + +RichMediaAnnotation::Content::~Content() +{ +} + +void RichMediaAnnotation::Content::setConfigurations( const QList< RichMediaAnnotation::Configuration* > &configurations ) +{ + qDeleteAll( d->configurations ); + d->configurations.clear(); + + d->configurations = configurations; +} + +QList< RichMediaAnnotation::Configuration* > RichMediaAnnotation::Content::configurations() const +{ + return d->configurations; +} + +void RichMediaAnnotation::Content::setAssets( const QList< RichMediaAnnotation::Asset* > &assets ) +{ + qDeleteAll( d->assets ); + d->assets.clear(); + + d->assets = assets; +} + +QList< RichMediaAnnotation::Asset* > RichMediaAnnotation::Content::assets() const +{ + return d->assets; +} + + +class RichMediaAnnotation::Activation::Private +{ + public: + Private() + : condition( RichMediaAnnotation::Activation::UserAction ) + { + } + + RichMediaAnnotation::Activation::Condition condition; +}; + +RichMediaAnnotation::Activation::Activation() + : d( new Private ) +{ +} + +RichMediaAnnotation::Activation::~Activation() +{ +} + +void RichMediaAnnotation::Activation::setCondition( Condition condition ) +{ + d->condition = condition; +} + +RichMediaAnnotation::Activation::Condition RichMediaAnnotation::Activation::condition() const +{ + return d->condition; +} + + +class RichMediaAnnotation::Deactivation::Private : public QSharedData +{ + public: + Private() + : condition( RichMediaAnnotation::Deactivation::UserAction ) + { + } + + RichMediaAnnotation::Deactivation::Condition condition; +}; + +RichMediaAnnotation::Deactivation::Deactivation() + : d( new Private ) +{ +} + +RichMediaAnnotation::Deactivation::~Deactivation() +{ +} + +void RichMediaAnnotation::Deactivation::setCondition( Condition condition ) +{ + d->condition = condition; +} + +RichMediaAnnotation::Deactivation::Condition RichMediaAnnotation::Deactivation::condition() const +{ + return d->condition; +} + + +class RichMediaAnnotation::Settings::Private : public QSharedData +{ + public: + Private() + : activation( 0 ), deactivation( 0 ) + { + } + + RichMediaAnnotation::Activation *activation; + RichMediaAnnotation::Deactivation *deactivation; +}; + +RichMediaAnnotation::Settings::Settings() + : d( new Private ) +{ +} + +RichMediaAnnotation::Settings::~Settings() +{ +} + +void RichMediaAnnotation::Settings::setActivation( RichMediaAnnotation::Activation *activation ) +{ + delete d->activation; + d->activation = activation; +} + +RichMediaAnnotation::Activation* RichMediaAnnotation::Settings::activation() const +{ + return d->activation; +} + +void RichMediaAnnotation::Settings::setDeactivation( RichMediaAnnotation::Deactivation *deactivation ) +{ + delete d->deactivation; + d->deactivation = deactivation; +} + +RichMediaAnnotation::Deactivation* RichMediaAnnotation::Settings::deactivation() const +{ + return d->deactivation; +} + + +class RichMediaAnnotationPrivate : public AnnotationPrivate +{ + public: + RichMediaAnnotationPrivate() + : settings( 0 ), content( 0 ) + { + } + + ~RichMediaAnnotationPrivate() + { + delete settings; + delete content; + } + + Annotation * makeAlias() + { + return new RichMediaAnnotation( *this ); + } + + Annot* createNativeAnnot( ::Page *destPage, DocumentData *doc ) + { + Q_UNUSED( destPage ); + Q_UNUSED( doc ); + + return 0; + } + + RichMediaAnnotation::Settings *settings; + RichMediaAnnotation::Content *content; +}; + +RichMediaAnnotation::RichMediaAnnotation() + : Annotation( *new RichMediaAnnotationPrivate() ) +{ +} + +RichMediaAnnotation::RichMediaAnnotation( RichMediaAnnotationPrivate &dd ) + : Annotation( dd ) +{ +} + +RichMediaAnnotation::RichMediaAnnotation( const QDomNode & node ) + : Annotation( *new RichMediaAnnotationPrivate(), 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; + } +} + +RichMediaAnnotation::~RichMediaAnnotation() +{ +} + +void RichMediaAnnotation::store( QDomNode & node, QDomDocument & document ) const +{ + // store base annotation properties + storeBaseAnnotationProperties( node, document ); + + // create [richMedia] element + QDomElement richMediaElement = document.createElement( "richMedia" ); + node.appendChild( richMediaElement ); +} + +Annotation::SubType RichMediaAnnotation::subType() const +{ + return ARichMedia; +} + +void RichMediaAnnotation::setSettings( RichMediaAnnotation::Settings *settings ) +{ + Q_D( RichMediaAnnotation ); + + delete d->settings; + d->settings = settings; +} + +RichMediaAnnotation::Settings* RichMediaAnnotation::settings() const +{ + Q_D( const RichMediaAnnotation ); + + return d->settings; +} + +void RichMediaAnnotation::setContent( RichMediaAnnotation::Content *content ) +{ + Q_D( RichMediaAnnotation ); + + delete d->content; + d->content = content; +} + +RichMediaAnnotation::Content* RichMediaAnnotation::content() const +{ + Q_D( const RichMediaAnnotation ); + + return d->content; +} + + //BEGIN utility annotation functions QColor convertAnnotColor( AnnotColor *color ) { diff --git a/qt5/src/poppler-annotation.h b/qt5/src/poppler-annotation.h index bbcb9de..3b34576 100644 --- a/qt5/src/poppler-annotation.h +++ b/qt5/src/poppler-annotation.h @@ -3,7 +3,7 @@ * Copyright (C) 2006, 2008 Pino Toscano * Copyright (C) 2007, Brad Hards * Copyright (C) 2010, Philip Lorenz - * Copyright (C) 2012, Tobias Koenig + * Copyright (C) 2012-2015, Tobias Koenig * Copyright (C) 2012, Guillermo A. Amaral B. * Copyright (C) 2012, 2013 Fabio D'Urso * Copyright (C) 2013, Anthony Granger @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,7 @@ class SoundAnnotationPrivate; class MovieAnnotationPrivate; class ScreenAnnotationPrivate; class WidgetAnnotationPrivate; +class RichMediaAnnotationPrivate; class EmbeddedFile; class Link; class SoundObject; @@ -197,6 +199,7 @@ class POPPLER_QT5_EXPORT Annotation AMovie = 11, ///< MovieAnnotation AScreen = 12, ///< ScreenAnnotation \since 0.20 AWidget = 13, ///< WidgetAnnotation \since 0.22 + ARichMedia = 14, ///< RichMediaAnnotation \since 0.35 A_BASE = 0 }; @@ -1025,6 +1028,332 @@ class POPPLER_QT5_EXPORT WidgetAnnotation : public Annotation Q_DISABLE_COPY( WidgetAnnotation ) }; +/** + * \short RichMedia annotation. + * + * The RichMedia annotation represents a video or sound on a page. + * + * \since 0.35 + */ +class POPPLER_QT5_EXPORT RichMediaAnnotation : public Annotation +{ + friend class AnnotationPrivate; + + public: + virtual ~RichMediaAnnotation(); + + virtual SubType subType() const; + + /** + * The params object of a RichMediaAnnotation::Instance object. + * + * The params object provides media specific parameters, to play + * back the media inside the PDF viewer. + * + * At the moment only parameters for flash player are supported. + */ + class POPPLER_QT5_EXPORT Params + { + friend class AnnotationPrivate; + + public: + Params(); + ~Params(); + + /** + * Returns the parameters for the flash player. + */ + QString flashVars() const; + + private: + void setFlashVars( const QString &flashVars ); + + class Private; + QScopedPointer d; + }; + + /** + * The instance object of a RichMediaAnnotation::Configuration object. + * + * The instance object represents one media object, that should be shown + * on the page. It has a media type and a Params object, to define the + * media specific parameters. + */ + class POPPLER_QT5_EXPORT Instance + { + friend class AnnotationPrivate; + + public: + /** + * Describes the media type of the instance. + */ + enum Type + { + Type3D, ///< A 3D media file. + TypeFlash, ///< A Flash media file. + TypeSound, ///< A sound media file. + TypeVideo ///< A video media file. + }; + + Instance(); + ~Instance(); + + /** + * Returns the media type of the instance. + */ + Type type() const; + + /** + * Returns the params object of the instance or @c 0 if it doesn't exist. + */ + RichMediaAnnotation::Params* params() const; + + private: + void setType( Type type ); + void setParams( RichMediaAnnotation::Params *params ); + + class Private; + QScopedPointer d; + }; + + /** + * The configuration object of a RichMediaAnnotation::Content object. + * + * The configuration object provides access to the various Instance objects + * of the rich media annotation. + */ + class POPPLER_QT5_EXPORT Configuration + { + friend class AnnotationPrivate; + + public: + /** + * Describes the media type of the configuration. + */ + enum Type + { + Type3D, ///< A 3D media file. + TypeFlash, ///< A Flash media file. + TypeSound, ///< A sound media file. + TypeVideo ///< A video media file. + }; + + Configuration(); + ~Configuration(); + + /** + * Returns the media type of the configuration. + */ + Type type() const; + + /** + * Returns the name of the configuration. + */ + QString name() const; + + /** + * Returns the list of Instance objects of the configuration. + */ + QList< RichMediaAnnotation::Instance* > instances() const; + + private: + void setType( Type type ); + void setName( const QString &name ); + void setInstances( const QList< RichMediaAnnotation::Instance* > &instances ); + + class Private; + QScopedPointer d; + }; + + /** + * The asset object of a RichMediaAnnotation::Content object. + * + * The asset object provides a mapping between identifier name, as + * used in the flash vars string of RichMediaAnnotation::Params, and the + * associated file spec object. + */ + class POPPLER_QT5_EXPORT Asset + { + friend class AnnotationPrivate; + + public: + Asset(); + ~Asset(); + + /** + * Returns the identifier name of the asset. + */ + QString name() const; + + /** + * Returns the embedded file the asset points to. + */ + EmbeddedFile* embeddedFile() const; + + private: + void setName( const QString &name ); + void setEmbeddedFile( EmbeddedFile *embeddedFile ); + + class Private; + QScopedPointer d; + }; + + /** + * The content object of a RichMediaAnnotation. + * + * The content object provides access to the list of configurations + * and assets of the rich media annotation. + */ + class POPPLER_QT5_EXPORT Content + { + friend class AnnotationPrivate; + + public: + Content(); + ~Content(); + + /** + * Returns the list of configuration objects of the content object. + */ + QList< RichMediaAnnotation::Configuration* > configurations() const; + + /** + * Returns the list of asset objects of the content object. + */ + QList< RichMediaAnnotation::Asset* > assets() const; + + private: + void setConfigurations( const QList< RichMediaAnnotation::Configuration* > &configurations ); + void setAssets( const QList< RichMediaAnnotation::Asset* > &assets ); + + class Private; + QScopedPointer d; + }; + + /** + * The activation object of the RichMediaAnnotation::Settings object. + * + * The activation object is a wrapper around the settings for the activation + * state. At the moment it provides only the activation condition. + */ + class POPPLER_QT5_EXPORT Activation + { + friend class AnnotationPrivate; + + public: + /** + * Describes the condition for activating the rich media. + */ + enum Condition { + PageOpened, ///< Activate when page is opened. + PageVisible, ///< Activate when page becomes visible. + UserAction ///< Activate when user interacts with the annotation. + }; + + Activation(); + ~Activation(); + + /** + * Returns the activation condition. + */ + Condition condition() const; + + private: + void setCondition( Condition condition ); + + class Private; + QScopedPointer d; + }; + + /** + * The deactivation object of the RichMediaAnnotation::Settings object. + * + * The deactivation object is a wrapper around the settings for the deactivation + * state. At the moment it provides only the deactivation condition. + */ + class POPPLER_QT5_EXPORT Deactivation + { + friend class AnnotationPrivate; + + public: + /** + * Describes the condition for deactivating the rich media. + */ + enum Condition { + PageClosed, ///< Deactivate when page is closed. + PageInvisible, ///< Deactivate when page becomes invisible. + UserAction ///< Deactivate when user interacts with the annotation. + }; + + Deactivation(); + ~Deactivation(); + + /** + * Returns the deactivation condition. + */ + Condition condition() const; + + private: + void setCondition( Condition condition ); + + class Private; + QScopedPointer d; + }; + + /** + * The settings object of a RichMediaAnnotation. + * + * The settings object provides access to the configuration objects + * for annotation activation and deactivation. + */ + class POPPLER_QT5_EXPORT Settings + { + friend class AnnotationPrivate; + + public: + Settings(); + ~Settings(); + + /** + * Returns the Activation object of the settings object or @c 0 if it doesn't exist. + */ + RichMediaAnnotation::Activation* activation() const; + + /** + * Returns the Deactivation object of the settings object or @c 0 if it doesn't exist. + */ + RichMediaAnnotation::Deactivation* deactivation() const; + + private: + void setActivation( RichMediaAnnotation::Activation *activation ); + void setDeactivation( RichMediaAnnotation::Deactivation *deactivation ); + + class Private; + QScopedPointer d; + }; + + /** + * Returns the Settings object of the rich media annotation or @c 0 if it doesn't exist. + */ + RichMediaAnnotation::Settings* settings() const; + + /** + * Returns the Content object of the rich media annotation or @c 0 if it doesn't exist. + */ + RichMediaAnnotation::Content* content() const; + + private: + void setSettings( RichMediaAnnotation::Settings *settings ); + void setContent( RichMediaAnnotation::Content *content ); + + RichMediaAnnotation(); + RichMediaAnnotation( const QDomNode &node ); + RichMediaAnnotation( RichMediaAnnotationPrivate &dd ); + virtual void store( QDomNode &parentNode, QDomDocument &document ) const; + Q_DECLARE_PRIVATE( RichMediaAnnotation ) + Q_DISABLE_COPY( RichMediaAnnotation ) +}; + } #endif