diff --git a/qt4/src/CMakeLists.txt b/qt4/src/CMakeLists.txt index c958379..246c9a8 100644 --- a/qt4/src/CMakeLists.txt +++ b/qt4/src/CMakeLists.txt @@ -15,6 +15,7 @@ set(poppler_qt4_SRCS poppler-link.cc poppler-link-extractor.cc poppler-movie.cc + poppler-screen.cc poppler-objectreference.cc poppler-optcontent.cc poppler-page.cc @@ -26,6 +27,8 @@ set(poppler_qt4_SRCS poppler-sound.cc poppler-textbox.cc poppler-page-transition.cc + poppler-streamdevice.cc + poppler-media.cc ${CMAKE_SOURCE_DIR}/poppler/ArthurOutputDev.cc ) qt4_automoc(${poppler_qt4_SRCS}) @@ -45,5 +48,6 @@ install(FILES poppler-optcontent.h poppler-export.h poppler-page-transition.h + poppler-media.h DESTINATION include/poppler/qt4) diff --git a/qt4/src/poppler-annotation.cc b/qt4/src/poppler-annotation.cc index 0905ee3..0440acf 100644 --- a/qt4/src/poppler-annotation.cc +++ b/qt4/src/poppler-annotation.cc @@ -1616,6 +1616,11 @@ void LinkAnnotation::store( QDomNode & node, QDomDocument & document ) const hyperlinkElement.setAttribute( "type", "Movie" ); break; } + case Poppler::Link::Rendition: + { + hyperlinkElement.setAttribute( "type", "Rendition" ); + break; + } case Poppler::Link::Sound: { // FIXME: implement me @@ -2037,6 +2042,93 @@ void MovieAnnotation::setMovieTitle( const QString &title ) d->title = title; } +/** ScreenAnnotation [Annotation] */ +class ScreenAnnotationPrivate : public AnnotationPrivate +{ + public: + ScreenAnnotationPrivate(); + ~ScreenAnnotationPrivate(); + + // data fields + ScreenObject *screen; + QString title; +}; + +ScreenAnnotationPrivate::ScreenAnnotationPrivate() + : AnnotationPrivate(), screen( 0 ) +{ +} + +ScreenAnnotationPrivate::~ScreenAnnotationPrivate() +{ + delete screen; +} + +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 screenElement = document.createElement( "screen" ); + node.appendChild( screenElement ); +} + +Annotation::SubType ScreenAnnotation::subType() const +{ + return AScreen; +} + +ScreenObject* ScreenAnnotation::screen() const +{ + Q_D( const ScreenAnnotation ); + return d->screen; +} + +void ScreenAnnotation::setScreen( ScreenObject *screen ) +{ + Q_D( ScreenAnnotation ); + d->screen = screen; +} + +QString ScreenAnnotation::screenTitle() const +{ + Q_D( const ScreenAnnotation ); + return d->title; +} + +void ScreenAnnotation::setScreenTitle( const QString &title ) +{ + Q_D( ScreenAnnotation ); + d->title = title; +} + //BEGIN utility annotation functions QColor convertAnnotColor( AnnotColor *color ) { diff --git a/qt4/src/poppler-annotation.h b/qt4/src/poppler-annotation.h index 4124c74..0b38b9d 100644 --- a/qt4/src/poppler-annotation.h +++ b/qt4/src/poppler-annotation.h @@ -50,10 +50,12 @@ class CaretAnnotationPrivate; class FileAttachmentAnnotationPrivate; class SoundAnnotationPrivate; class MovieAnnotationPrivate; +class ScreenAnnotationPrivate; class EmbeddedFile; class Link; class SoundObject; class MovieObject; +class ScreenObject; /** * \short Helper class for (recursive) Annotation retrieval/storage. @@ -102,7 +104,7 @@ class POPPLER_QT4_EXPORT Annotation // WARNING!!! oKular uses that very same values so if you change them notify the author! enum SubType { AText = 1, ALine = 2, AGeom = 3, AHighlight = 4, AStamp = 5, AInk = 6, ALink = 7, ACaret = 8, AFileAttachment = 9, ASound = 10, - AMovie = 11, A_BASE = 0 }; + AMovie = 11, AScreen = 12, A_BASE = 0 }; enum Flag { Hidden = 1, FixedSize = 2, FixedRotation = 4, DenyPrint = 8, DenyWrite = 16, DenyDelete = 32, ToggleHidingOnMouse = 64, External = 128 }; enum LineStyle { Solid = 1, Dashed = 2, Beveled = 4, Inset = 8, Underline = 16 }; @@ -685,6 +687,49 @@ class POPPLER_QT4_EXPORT MovieAnnotation : public Annotation Q_DISABLE_COPY( MovieAnnotation ) }; +/** + * \short Screen annotation. + * + * The screen annotation represents a screen to be played when activated. + * + * \since 0.10 + */ +class POPPLER_QT4_EXPORT ScreenAnnotation : public Annotation +{ + public: + ScreenAnnotation(); + ScreenAnnotation( const QDomNode &node ); + virtual ~ScreenAnnotation(); + virtual void store( QDomNode &parentNode, QDomDocument &document ) const; + virtual SubType subType() const; + + /** + * Returns the ScreenObject of this annotation. + */ + ScreenObject* screen() const; + + /** + * Sets a new ScreenObject for this annotation. + * + * \note ScreenAnnotation takes ownership of the object + */ + void setScreen( ScreenObject *screen ); + + /** + * Returns the title of the screen of this annotation. + */ + QString screenTitle() const; + + /** + * Sets a new title for the screen of this annotation. + */ + void setScreenTitle( const QString &title ); + + private: + Q_DECLARE_PRIVATE( ScreenAnnotation ) + Q_DISABLE_COPY( ScreenAnnotation ) +}; + } #endif diff --git a/qt4/src/poppler-link.cc b/qt4/src/poppler-link.cc index 81ba39f..f4cc2af 100644 --- a/qt4/src/poppler-link.cc +++ b/qt4/src/poppler-link.cc @@ -158,6 +158,20 @@ class LinkSoundPrivate : public LinkPrivate delete sound; } +class LinkRenditionPrivate : public LinkPrivate +{ + public: + LinkRenditionPrivate( const QRectF &area ); + + MediaRendition *rendition; +}; + + LinkRenditionPrivate::LinkRenditionPrivate( const QRectF &area ) + : LinkPrivate( area ) + , rendition( 0 ) + { + } + class LinkJavaScriptPrivate : public LinkPrivate { public: @@ -550,6 +564,29 @@ class LinkMoviePrivate : public LinkPrivate return d->sound; } + // LinkRendition + LinkRendition::LinkRendition( const QRectF &linkArea, MediaRendition *rendition ) + : Link( *new LinkRenditionPrivate( linkArea ) ) + { + Q_D( LinkRendition ); + d->rendition = rendition; + } + + LinkRendition::~LinkRendition() + { + } + + Link::LinkType LinkRendition::linkType() const + { + return Rendition; + } + + MediaRendition * LinkRendition::rendition() const + { + Q_D( const LinkRendition ); + return d->rendition; + } + // LinkJavaScript LinkJavaScript::LinkJavaScript( const QRectF &linkArea, const QString &js ) : Link( *new LinkJavaScriptPrivate( linkArea ) ) diff --git a/qt4/src/poppler-link.h b/qt4/src/poppler-link.h index b12ce8b..946aeed 100644 --- a/qt4/src/poppler-link.h +++ b/qt4/src/poppler-link.h @@ -41,8 +41,10 @@ class LinkJavaScriptPrivate; class LinkMoviePrivate; class LinkDestinationData; class LinkDestinationPrivate; +class LinkRenditionPrivate; class ObjectReference; class SoundObject; +class MediaRendition; /** * \short A destination. @@ -185,6 +187,7 @@ class POPPLER_QT4_EXPORT Link Action, ///< A "standard" action to be executed in the viewer Sound, ///< A link representing a sound to be played Movie, ///< An action to be executed on a movie + Rendition, ///< A rendition link JavaScript ///< A JavaScript code to be interpreted \since 0.10 }; @@ -442,6 +445,36 @@ class POPPLER_QT4_EXPORT LinkSound : public Link }; /** + * Rendition: Rendition link. + */ +class POPPLER_QT4_EXPORT LinkRendition : public Link +{ + public: + /** + * Create a new media rendition link. + * + * \param linkArea the active area of the link + * \param rendition + */ + LinkRendition( const QRectF &linkArea, MediaRendition *rendition ); + /** + * Destructor. + */ + virtual ~LinkRendition(); + + LinkType linkType() const; + + /** + * + */ + MediaRendition *rendition() const; + + private: + Q_DECLARE_PRIVATE( LinkRendition ) + Q_DISABLE_COPY( LinkRendition ) +}; + +/** * JavaScript: a JavaScript code to be interpreted. * * \since 0.10 diff --git a/qt4/src/poppler-media.cc b/qt4/src/poppler-media.cc new file mode 100644 index 0000000..7c774eb --- /dev/null +++ b/qt4/src/poppler-media.cc @@ -0,0 +1,164 @@ +/* poppler-media.h: qt interface to poppler + * Copyright (C) 2012 Guillermo A. Amaral B. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "poppler-media.h" + +#include "Rendition.h" + +#include "poppler-private.h" +#include "poppler-streamdevice-private.h" + +namespace Poppler +{ + +class MediaRenditionPrivate +{ +public: + + MediaRenditionPrivate(::MediaRendition *rendition) + : rendition(rendition), device(0) + { + } + + ::MediaRendition *rendition; + QIODevice *device; +}; + +MediaRendition::MediaRendition(::MediaRendition *rendition) + : d_ptr(new MediaRenditionPrivate(rendition)) +{ + Q_D( MediaRendition ); + + if (d->rendition) + d->device = new StreamDevice(d->rendition->getEmbbededStream()); +} + +MediaRendition::~MediaRendition() +{ + delete d_ptr; +} + +bool +MediaRendition::isValid() +{ + Q_D( MediaRendition ); + return d->rendition && d->rendition->isOk(); +} + +MediaParameters* +MediaRendition::getMHParameters() +{ + Q_ASSERT(isValid() && "Invalid media rendition."); + Q_D( MediaRendition ); + return d->rendition->getMHParameters(); +} + +MediaParameters* +MediaRendition::getBEParameters() +{ + Q_ASSERT(isValid() && "Invalid media rendition."); + Q_D( MediaRendition ); + return d->rendition->getBEParameters(); +} + +QString +MediaRendition::contentType() +{ + Q_ASSERT(isValid() && "Invalid media rendition."); + Q_D( MediaRendition ); + return UnicodeParsedString(d->rendition->getContentType()); +} + +QString +MediaRendition::fileName() +{ + Q_ASSERT(isValid() && "Invalid media rendition."); + Q_D( MediaRendition ); + return UnicodeParsedString(d->rendition->getFileName()); +} + +bool +MediaRendition::isEmbedded() +{ + Q_ASSERT(isValid() && "Invalid media rendition."); + Q_D( MediaRendition ); + return d->rendition->getIsEmbedded(); +} + +QIODevice * +MediaRendition::streamDevice() const +{ + Q_D( const MediaRendition ); + return d->device; +} + +bool +MediaRendition::autoPlay() const +{ + Q_D( const MediaRendition ); + if (d->rendition->getBEParameters()) { + return d->rendition->getBEParameters()->autoPlay; + } else if (d->rendition->getMHParameters()) { + return d->rendition->getMHParameters()->autoPlay; + } else qDebug("No BE or MH paremeters to reference!"); + return false; +} + +bool +MediaRendition::showControls() const +{ + Q_D( const MediaRendition ); + if (d->rendition->getBEParameters()) { + return d->rendition->getBEParameters()->showControls; + } else if (d->rendition->getMHParameters()) { + return d->rendition->getMHParameters()->showControls; + } else qDebug("No BE or MH paremeters to reference!"); + return false; +} + +float +MediaRendition::repeatCount() const +{ + Q_D( const MediaRendition ); + if (d->rendition->getBEParameters()) { + return d->rendition->getBEParameters()->repeatCount; + } else if (d->rendition->getMHParameters()) { + return d->rendition->getMHParameters()->repeatCount; + } else qDebug("No BE or MH paremeters to reference!"); + return 1.f; +} + +QSize +MediaRendition::size() const +{ + Q_D( const MediaRendition ); + MediaParameters *mp = 0; + + if (d->rendition->getBEParameters()) + mp = d->rendition->getBEParameters(); + else if (d->rendition->getMHParameters()) + mp = d->rendition->getMHParameters(); + else qDebug("No BE or MH paremeters to reference!"); + + if (mp) + return QSize(mp->windowParams.width, mp->windowParams.height); + return QSize(); +} + +} + diff --git a/qt4/src/poppler-media.h b/qt4/src/poppler-media.h new file mode 100644 index 0000000..001c4b5 --- /dev/null +++ b/qt4/src/poppler-media.h @@ -0,0 +1,63 @@ +/* poppler-media-private.h: qt interface to poppler + * Copyright (C) 2012 Guillermo A. Amaral B. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __POPPLER_MEDIARENDITION_H__ +#define __POPPLER_MEDIARENDITION_H__ + +#include +#include + +class MediaRendition; +class QIODevice; + +struct MediaParameters; + +namespace Poppler +{ + class MediaRenditionPrivate; + + class MediaRendition { + public: + MediaRendition(::MediaRendition *rendition); + ~MediaRendition(); + + bool isValid(); + + MediaParameters* getMHParameters(); + MediaParameters* getBEParameters(); + + QString contentType(); + QString fileName(); + + bool isEmbedded(); + QIODevice *streamDevice() const; + + /* helper function */ + bool autoPlay() const; + bool showControls() const; + float repeatCount() const; + QSize size() const; + + private: + Q_DECLARE_PRIVATE( MediaRendition ) + MediaRenditionPrivate *d_ptr; + Q_DISABLE_COPY( MediaRendition ) + }; +} + +#endif /* __POPPLER_MEDIARENDITION_H__ */ diff --git a/qt4/src/poppler-page.cc b/qt4/src/poppler-page.cc index 34d8e5e..ce58cd3 100644 --- a/qt4/src/poppler-page.cc +++ b/qt4/src/poppler-page.cc @@ -45,6 +45,7 @@ #include #include #include +#include #if defined(HAVE_SPLASH) #include #include @@ -57,6 +58,8 @@ #include "poppler-annotation-helper.h" #include "poppler-annotation-private.h" #include "poppler-form.h" +#include "poppler-media.h" +#include "poppler-streamdevice-private.h" namespace Poppler { @@ -200,6 +203,13 @@ Link* PageData::convertLinkActionToLink(::LinkAction * a, DocumentData *parentDo } break; + case actionRendition: + { + ::LinkRendition *lrn = (::LinkRendition *)a; + popplerLink = new LinkRendition( linkArea, new MediaRendition(lrn->getMedia()) ); + } + break; + case actionUnknown: break; } @@ -994,6 +1004,29 @@ QList Page::annotations() const break; } + case Annot::typeScreen: + { + AnnotScreen * screenann = static_cast< AnnotScreen * >( ann ); + + if (!screenann->getAction()) + continue; + + ScreenAnnotation * s = new ScreenAnnotation(); + annotation = s; + + // -> screen + ScreenObject *screen = + new ScreenObject( screenann, + static_cast(m_page->convertLinkActionToLink( screenann->getAction(), QRectF() ) ) ); + s->setScreen( screen ); + + // -> screenTitle + GooString * screentitle = screenann->getTitle(); + if ( screentitle ) + s->setScreenTitle( QString::fromLatin1( screentitle->getCString() ) ); + + break; + } // special case for ignoring unknwon annotations case Annot::typeUnknown: continue; diff --git a/qt4/src/poppler-qt4.h b/qt4/src/poppler-qt4.h index 4ba27ed..af85aa4 100644 --- a/qt4/src/poppler-qt4.h +++ b/qt4/src/poppler-qt4.h @@ -42,6 +42,7 @@ class EmbFile; class Sound; class AnnotMovie; +class AnnotScreen; /** The %Poppler Qt4 binding. @@ -1718,6 +1719,28 @@ height = dummy.height(); MovieData *m_movieData; }; + /** + Container class for a screen object in a PDF document. + */ + class POPPLER_QT4_EXPORT ScreenObject { + friend class Page; + public: + ~ScreenObject(); + + /** + Link action + */ + LinkRendition *action() const; + + private: + /// \cond PRIVATE + ScreenObject( AnnotScreen *ann, LinkRendition *action ); + /// \endcond + + Q_DISABLE_COPY(ScreenObject) + LinkRendition *m_action; + }; + } Q_DECLARE_OPERATORS_FOR_FLAGS(Poppler::Page::PainterFlags) diff --git a/qt4/src/poppler-screen.cc b/qt4/src/poppler-screen.cc new file mode 100644 index 0000000..cb6fa2c --- /dev/null +++ b/qt4/src/poppler-screen.cc @@ -0,0 +1,45 @@ +/* poppler-sound.cc: qt interface to poppler + * Copyright (C) 2008, 2010, Pino Toscano + * Copyright (C) 2008, Albert Astals Cid + * Copyright (C) 2010, Carlos Garcia Campos + * Copyright (C) 2012, Guillermo A. Amaral B. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "poppler-qt4.h" + +#include "Object.h" +#include "Annot.h" + +namespace Poppler +{ + +ScreenObject::ScreenObject( AnnotScreen *ann, LinkRendition *action ) + : m_action( action ) +{ +} + +ScreenObject::~ScreenObject() +{ + delete m_action; +} + +LinkRendition *ScreenObject::action() const +{ + return m_action; +} + +} diff --git a/qt4/src/poppler-streamdevice-private.h b/qt4/src/poppler-streamdevice-private.h new file mode 100644 index 0000000..0c2adc5 --- /dev/null +++ b/qt4/src/poppler-streamdevice-private.h @@ -0,0 +1,48 @@ +/* poppler-streamdevice-private.h: Qt4 interface to poppler + * Copyright (C) 2012, Guiillermo A. Amaral B. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef POPPLER_STREAMDEVICE_PRIVATE_H +#define POPPLER_STREAMDEVICE_PRIVATE_H + +#include + +class Stream; + +namespace Poppler { + +class StreamDevice : public QIODevice +{ + public: + StreamDevice(Stream *stream, QObject *parent = 0); + virtual ~StreamDevice(); + + virtual bool isSequential() const + { return true; } + + protected: + virtual qint64 readData(char *data, qint64 maxSize); + inline virtual qint64 writeData(const char *, qint64) + { return 0; } + + private: + Stream *m_stream; +}; + +} + +#endif diff --git a/qt4/src/poppler-streamdevice.cc b/qt4/src/poppler-streamdevice.cc new file mode 100644 index 0000000..69da072 --- /dev/null +++ b/qt4/src/poppler-streamdevice.cc @@ -0,0 +1,49 @@ +/* poppler-streamdevice.cc: Qt4 interface to poppler + * Copyright (C) 2012, Guiillermo A. Amaral B. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "poppler-streamdevice-private.h" + +#include "Object.h" +#include "Stream.h" + +namespace Poppler { + +StreamDevice::StreamDevice(Stream *stream, QObject *parent) + : QIODevice(parent) + , m_stream(stream) +{ + Q_ASSERT(m_stream && "Invalid stream assigned."); + m_stream->incRef(); + m_stream->reset(); + setOpenMode(QIODevice::ReadOnly); +} + +StreamDevice::~StreamDevice() +{ + m_stream->decRef(); + m_stream = 0; +} + +qint64 +StreamDevice::readData(char *data, qint64 maxSize) +{ + return m_stream->doGetChars(maxSize, reinterpret_cast(data)); +} + +} +