Create proper ScreenAnnotations in poppler generator

REVIEW: 106605
This commit is contained in:
Tobias Koenig 2012-09-27 13:00:20 +02:00
parent a41a727e21
commit 77ccbbcbaa
3 changed files with 100 additions and 36 deletions

View file

@ -29,6 +29,7 @@ extern Okular::Movie* createMovieFromPopplerMovie( const Poppler::MovieObject *p
extern Okular::Movie* createMovieFromPopplerScreen( const Poppler::LinkRendition *popplerScreen );
#endif
static void disposeAnnotation( const Okular::Annotation *ann )
{
Poppler::Annotation *popplerAnn = qvariant_cast< Poppler::Annotation * >( ann->nativeId() );
@ -320,12 +321,20 @@ Okular::Annotation* createAnnotationFromPopplerAnnotation( Poppler::Annotation *
#ifdef HAVE_POPPLER_0_20
case Poppler::Annotation::AScreen:
{
#ifdef HAVE_POPPLER_0_22
Okular::ScreenAnnotation * m = new Okular::ScreenAnnotation();
annotation = m;
tieToOkularAnn = true;
*doDelete = false;
#else
#ifdef HAVE_POPPLER_0_20
Poppler::ScreenAnnotation * screenann = static_cast< Poppler::ScreenAnnotation * >( ann );
Okular::MovieAnnotation * m = new Okular::MovieAnnotation();
annotation = m;
m->setMovie( createMovieFromPopplerScreen( screenann->action() ) );
#endif
#endif
break;
}
case Poppler::Annotation::AText:

View file

@ -61,6 +61,9 @@ Q_DECLARE_METATYPE(Poppler::FontInfo)
#ifdef HAVE_POPPLER_0_20
Q_DECLARE_METATYPE(const Poppler::LinkMovie*)
#endif
#ifdef HAVE_POPPLER_0_22
Q_DECLARE_METATYPE(const Poppler::LinkRendition*)
#endif
static const int defaultPageWidth = 595;
static const int defaultPageHeight = 842;
@ -218,6 +221,9 @@ Okular::Action* createLinkFromPopplerLink(const Poppler::Link *popplerLink)
const Poppler::LinkJavaScript *popplerLinkJS;
#ifdef HAVE_POPPLER_0_20
const Poppler::LinkMovie *popplerLinkMovie;
#endif
#ifdef HAVE_POPPLER_0_22
const Poppler::LinkRendition *popplerLinkRendition;
#endif
Okular::DocumentViewport viewport;
@ -276,16 +282,48 @@ Okular::Action* createLinkFromPopplerLink(const Poppler::Link *popplerLink)
}
break;
#ifdef HAVE_POPPLER_0_20
#ifdef HAVE_POPPLER_0_22
case Poppler::Link::Rendition:
// not implemented
{
deletePopplerLink = false; // we'll delete it inside resolveMediaLinkReferences() after we have resolved all references
popplerLinkRendition = static_cast<const Poppler::LinkRendition *>( popplerLink );
Okular::RenditionAction::OperationType operation = Okular::RenditionAction::None;
switch ( popplerLinkRendition->action() )
{
case Poppler::LinkRendition::NoRendition:
operation = Okular::RenditionAction::None;
break;
case Poppler::LinkRendition::PlayRendition:
operation = Okular::RenditionAction::Play;
break;
case Poppler::LinkRendition::StopRendition:
operation = Okular::RenditionAction::Stop;
break;
case Poppler::LinkRendition::PauseRendition:
operation = Okular::RenditionAction::Pause;
break;
case Poppler::LinkRendition::ResumeRendition:
operation = Okular::RenditionAction::Resume;
break;
};
Okular::Movie *movie = 0;
if ( popplerLinkRendition->rendition() )
movie = createMovieFromPopplerScreen( popplerLinkRendition );
Okular::RenditionAction *renditionAction = new Okular::RenditionAction( operation, movie, Okular::JavaScript, popplerLinkRendition->script() );
renditionAction->setNativeId( QVariant::fromValue( popplerLinkRendition ) );
link = renditionAction;
}
break;
#endif
#ifdef HAVE_POPPLER_0_20
case Poppler::Link::Movie:
{
deletePopplerLink = false; // we'll delete it inside resolveMovieLinkReferences() after we have resolved all references
deletePopplerLink = false; // we'll delete it inside resolveMediaLinkReferences() after we have resolved all references
popplerLinkMovie = static_cast<const Poppler::LinkMovie *>( popplerLink );
@ -895,7 +933,7 @@ QImage PDFGenerator::image( Okular::PixmapRequest * request )
page->setObjectRects( generateLinks(p->links()) );
rectsGenerated[ request->page()->number() ] = true;
resolveMovieLinkReferences( page );
resolveMediaLinkReferences( page );
}
// 3. UNLOCK [re-enables shared access]
@ -906,64 +944,79 @@ QImage PDFGenerator::image( Okular::PixmapRequest * request )
return img;
}
void PDFGenerator::resolveMovieLinkReference( Okular::Action *action, Okular::Page *page )
template <typename PopplerLinkType, typename OkularLinkType, typename PopplerAnnotationType, typename OkularAnnotationType>
void resolveMediaLinks( Okular::Action *action, enum Okular::Annotation::SubType subType, QHash<Okular::Annotation*, Poppler::Annotation*> &annotationsHash )
{
#ifdef HAVE_POPPLER_0_20
if ( !action )
return;
OkularLinkType *okularAction = static_cast<OkularLinkType*>( action );
if ( action->actionType() != Okular::Action::Movie )
return;
Okular::MovieAction *movieAction = static_cast<Okular::MovieAction*>( action );
const Poppler::LinkMovie *linkMovie = movieAction->nativeId().value<const Poppler::LinkMovie*>();
const PopplerLinkType *popplerLink = action->nativeId().value<const PopplerLinkType*>();
QHashIterator<Okular::Annotation*, Poppler::Annotation*> it( annotationsHash );
while ( it.hasNext() )
{
it.next();
if ( it.key()->subType() == Okular::Annotation::AMovie )
if ( it.key()->subType() == subType )
{
const Poppler::MovieAnnotation *movieAnnotation = static_cast<const Poppler::MovieAnnotation*>( it.value() );
const PopplerAnnotationType *popplerAnnotation = static_cast<const PopplerAnnotationType*>( it.value() );
if ( linkMovie->isReferencedAnnotation( movieAnnotation ) )
if ( popplerLink->isReferencedAnnotation( popplerAnnotation ) )
{
movieAction->setAnnotation( static_cast<Okular::MovieAnnotation*>( it.key() ) );
movieAction->setNativeId( QVariant() );
delete linkMovie; // delete the associated Poppler::LinkMovie object, it's not needed anymore
okularAction->setAnnotation( static_cast<OkularAnnotationType*>( it.key() ) );
okularAction->setNativeId( QVariant() );
delete popplerLink; // delete the associated Poppler::LinkMovie object, it's not needed anymore
break;
}
}
}
}
void PDFGenerator::resolveMediaLinkReference( Okular::Action *action )
{
#ifdef HAVE_POPPLER_0_20
if ( !action )
return;
#ifdef HAVE_POPPLER_0_22
if ( (action->actionType() != Okular::Action::Movie) && (action->actionType() != Okular::Action::Rendition) )
return;
resolveMediaLinks<Poppler::LinkMovie, Okular::MovieAction, Poppler::MovieAnnotation, Okular::MovieAnnotation>( action, Okular::Annotation::AMovie, annotationsHash );
resolveMediaLinks<Poppler::LinkRendition, Okular::RenditionAction, Poppler::ScreenAnnotation, Okular::ScreenAnnotation>( action, Okular::Annotation::AScreen, annotationsHash );
#else
if ( action->actionType() != Okular::Action::Movie )
return;
resolveMediaLinks<Poppler::LinkMovie, Okular::MovieAction, Poppler::MovieAnnotation, Okular::MovieAnnotation>( action, Okular::Annotation::AMovie, annotationsHash );
#endif
#endif
}
void PDFGenerator::resolveMovieLinkReferences( Okular::Page *page )
void PDFGenerator::resolveMediaLinkReferences( 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 );
resolveMediaLinkReference( const_cast<Okular::Action*>( page->pageAction( Okular::Page::Opening ) ) );
resolveMediaLinkReference( const_cast<Okular::Action*>( page->pageAction( Okular::Page::Closing ) ) );
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 );
resolveMediaLinkReference( screenAnnotation->additionalAction( Okular::Annotation::PageOpening ) );
resolveMediaLinkReference( screenAnnotation->additionalAction( Okular::Annotation::PageClosing ) );
}
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 );
resolveMediaLinkReference( widgetAnnotation->additionalAction( Okular::Annotation::PageOpening ) );
resolveMediaLinkReference( widgetAnnotation->additionalAction( Okular::Annotation::PageClosing ) );
}
}
foreach ( Okular::FormField *field, page->formFields() )
resolveMovieLinkReference( field->activationAction(), page );
resolveMediaLinkReference( field->activationAction() );
}
Okular::TextPage* PDFGenerator::textPage( Okular::Page *page )
@ -1396,13 +1449,15 @@ void PDFGenerator::addAnnotations( Poppler::Page * popplerPage, Okular::Page * p
#ifdef HAVE_POPPLER_0_22
if ( a->subType() == Poppler::Annotation::AScreen )
{
/*
// TODO: (tokoe) This has been disabled for the moment, since we return MovieAnnotation objects
// for AScreen annotations, which will lead to a crash down here.
Poppler::ScreenAnnotation *annotScreen = static_cast<Poppler::ScreenAnnotation*>( a );
Okular::ScreenAnnotation *screenAnnotation = static_cast<Okular::ScreenAnnotation*>( newann );
// The activation action
const Poppler::Link *actionLink = annotScreen->action();
if ( actionLink )
screenAnnotation->setAction( createLinkFromPopplerLink( actionLink ) );
// The additional actions
const Poppler::Link *pageOpeningLink = annotScreen->additionalAction( Poppler::Annotation::PageOpeningAction );
if ( pageOpeningLink )
screenAnnotation->setAdditionalAction( Okular::Annotation::PageOpening, createLinkFromPopplerLink( pageOpeningLink ) );
@ -1410,7 +1465,6 @@ void PDFGenerator::addAnnotations( Poppler::Page * popplerPage, Okular::Page * p
const Poppler::Link *pageClosingLink = annotScreen->additionalAction( Poppler::Annotation::PageClosingAction );
if ( pageClosingLink )
screenAnnotation->setAdditionalAction( Okular::Annotation::PageClosing, createLinkFromPopplerLink( pageClosingLink ) );
*/
}
if ( a->subType() == Poppler::Annotation::AWidget )
@ -1418,6 +1472,7 @@ void PDFGenerator::addAnnotations( Poppler::Page * popplerPage, Okular::Page * p
Poppler::WidgetAnnotation *annotWidget = static_cast<Poppler::WidgetAnnotation*>( a );
Okular::WidgetAnnotation *widgetAnnotation = static_cast<Okular::WidgetAnnotation*>( newann );
// The additional actions
const Poppler::Link *pageOpeningLink = annotWidget->additionalAction( Poppler::Annotation::PageOpeningAction );
if ( pageOpeningLink )
widgetAnnotation->setAdditionalAction( Okular::Annotation::PageOpening, createLinkFromPopplerLink( pageOpeningLink ) );

View file

@ -127,8 +127,8 @@ class PDFGenerator : public Okular::Generator, public Okular::ConfigInterface, p
Okular::TextPage * abstractTextPage(const QList<Poppler::TextBox*> &text, double height, double width, int rot);
void resolveMovieLinkReferences( Okular::Page *page );
void resolveMovieLinkReference( Okular::Action *action, Okular::Page *page );
void resolveMediaLinkReferences( Okular::Page *page );
void resolveMediaLinkReference( Okular::Action *action );
bool setDocumentRenderHints();