From 25b16ee09adbf9f621b6e19db55a7a2ecfe75233 Mon Sep 17 00:00:00 2001 From: Andre Heinecke Date: Thu, 22 Mar 2018 11:30:49 +0100 Subject: [PATCH] Add support for hide action The hide action can be used to show / hide fields. --- poppler/Link.cc | 31 +++++++++++++++++++++++++++++++ poppler/Link.h | 35 +++++++++++++++++++++++++++++++++++ qt5/src/poppler-annotation.cc | 5 +++++ qt5/src/poppler-link-private.h | 16 ++++++++++++++++ qt5/src/poppler-link.cc | 28 ++++++++++++++++++++++++++++ qt5/src/poppler-link.h | 38 +++++++++++++++++++++++++++++++++++++- qt5/src/poppler-page.cc | 10 ++++++++++ 7 files changed, 162 insertions(+), 1 deletion(-) diff --git a/poppler/Link.cc b/poppler/Link.cc index 9be6a8c1..64f17f99 100644 --- a/poppler/Link.cc +++ b/poppler/Link.cc @@ -21,6 +21,7 @@ // Copyright (C) 2009 Ilya Gorenbein // Copyright (C) 2012 Tobias Koening // Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, . Work sponsored by the LiMux project of the city of Munich +// Copyright (C) 2018 Intevation GmbH // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -120,6 +121,10 @@ LinkAction *LinkAction::parseAction(const Object *obj, const GooString *baseURI) } else if (obj2.isName("SetOCGState")) { action = new LinkOCGState(obj); + // Hide action + } else if (obj2.isName("Hide")) { + action = new LinkHide(obj); + // unknown action } else if (obj2.isName()) { action = new LinkUnknown(obj2.getName()); @@ -811,6 +816,32 @@ LinkOCGState::StateList::~StateList() { } //------------------------------------------------------------------------ +// LinkHide +//------------------------------------------------------------------------ + +LinkHide::LinkHide(const Object *hideObj) { + targetName = nullptr; + show = false; // Default + + if (hideObj->isDict()) { + Object targetObj = hideObj->dictLookup("T"); + if (targetObj.isString()) { + targetName = targetObj.getString()->copy(); + } + Object shouldHide = hideObj->dictLookup("H"); + if (shouldHide.isBool()) { + show = !shouldHide.getBool(); + } + } +} + +LinkHide::~LinkHide() { + if (targetName) { + delete targetName; + } +} + +//------------------------------------------------------------------------ // LinkUnknown //------------------------------------------------------------------------ diff --git a/poppler/Link.h b/poppler/Link.h index 90496c42..6142f927 100644 --- a/poppler/Link.h +++ b/poppler/Link.h @@ -19,6 +19,7 @@ // Copyright (C) 2012 Tobias Koening // Copyright (C) 2018 Albert Astals Cid // Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, . Work sponsored by the LiMux project of the city of Munich +// Copyright (C) 2018 Intevation GmbH // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -58,6 +59,7 @@ enum LinkActionKind { actionSound, // sound action actionJavaScript, // JavaScript action actionOCGState, // Set-OCG-State action + actionHide, // Hide action actionUnknown // anything else }; @@ -452,6 +454,39 @@ private: }; //------------------------------------------------------------------------ +// LinkHide +//------------------------------------------------------------------------ + +class LinkHide: public LinkAction { +public: + LinkHide(const Object *hideObj); + + ~LinkHide(); + + GBool isOk() const override { return targetName != nullptr; } + LinkActionKind getKind() const override { return actionHide; } + + // According to spec the target can be either: + // a) A text string containing the fully qualified name of the target + // field. + // b) An indirect reference to an annotation dictionary. + // c) An array of "such dictionaries or text strings". + // + // While b / c appear to be very uncommon and can't easily be + // created with Adobe Acrobat DC. So only support hide + // actions with named targets (yet). + GBool hasTargetName() { return targetName != nullptr; } + GooString *getTargetName() { return targetName; } + + // Should this action show or hide. + GBool isShowAction() { return show; } + +private: + GooString *targetName; + GBool show; +}; + +//------------------------------------------------------------------------ // LinkUnknown //------------------------------------------------------------------------ diff --git a/qt5/src/poppler-annotation.cc b/qt5/src/poppler-annotation.cc index 6a2ec893..530d058d 100644 --- a/qt5/src/poppler-annotation.cc +++ b/qt5/src/poppler-annotation.cc @@ -3946,6 +3946,11 @@ void LinkAnnotation::store( QDomNode & node, QDomDocument & document ) const hyperlinkElement.setAttribute( QStringLiteral("type"), QStringLiteral("OCGState") ); break; } + case Poppler::Link::Hide: + { + hyperlinkElement.setAttribute( QStringLiteral("type"), QStringLiteral("Hide") ); + break; + } case Poppler::Link::None: break; } diff --git a/qt5/src/poppler-link-private.h b/qt5/src/poppler-link-private.h index 6bc5cb9f..3ef29495 100644 --- a/qt5/src/poppler-link-private.h +++ b/qt5/src/poppler-link-private.h @@ -55,6 +55,22 @@ public: ::LinkOCGState *popplerLinkOCGState; }; + + +class LinkHidePrivate : public LinkPrivate +{ +public: + LinkHidePrivate( const QRectF &area, const QString &tName, bool show ) + : LinkPrivate( area ) + , targetName( tName ) + , isShow( show ) + { + } + + QString targetName; + bool isShow; +}; + } #endif diff --git a/qt5/src/poppler-link.cc b/qt5/src/poppler-link.cc index ffa3e74d..1279e0b2 100644 --- a/qt5/src/poppler-link.cc +++ b/qt5/src/poppler-link.cc @@ -4,6 +4,7 @@ * Copyright (C) 2010 Hib Eris * Copyright (C) 2012, Tobias Koenig * Copyright (C) 2012, Guillermo A. Amaral B. + * Copyright (C) 2018 Intevation GmbH * Adapting code from * Copyright (C) 2004 by Enrico Ros * @@ -704,4 +705,31 @@ class LinkMoviePrivate : public LinkPrivate { return OCGState; } + + // LinkHide + LinkHide::LinkHide( LinkHidePrivate *lhidep ) + : Link( *lhidep ) + { + } + + LinkHide::~LinkHide() + { + } + + Link::LinkType LinkHide::linkType() const + { + return Hide; + } + + QVector < QString > LinkHide::targets() const + { + Q_D( const LinkHide ); + return QVector< QString >() << d->targetName; + } + + bool LinkHide::isShowAction() const + { + Q_D( const LinkHide ); + return d->isShow; + } } diff --git a/qt5/src/poppler-link.h b/qt5/src/poppler-link.h index 0753ce99..3bb4bebe 100644 --- a/qt5/src/poppler-link.h +++ b/qt5/src/poppler-link.h @@ -49,6 +49,7 @@ class LinkDestinationData; class LinkDestinationPrivate; class LinkRenditionPrivate; class LinkOCGStatePrivate; +class LinkHidePrivate; class MediaRendition; class SoundObject; @@ -197,7 +198,8 @@ class POPPLER_QT5_EXPORT Link Movie, ///< An action to be executed on a movie Rendition, ///< A rendition link \since 0.20 JavaScript, ///< A JavaScript code to be interpreted \since 0.10 - OCGState ///< An Optional Content Group state change \since 0.50 + OCGState, ///< An Optional Content Group state change \since 0.50 + Hide, ///< An action to hide a field \since 0.64 }; /** @@ -627,6 +629,40 @@ class POPPLER_QT5_EXPORT LinkOCGState : public Link Q_DISABLE_COPY( LinkOCGState ) }; +/** + * Hide: an action to show / hide a field. + * + * \since 0.64 + */ +class POPPLER_QT5_EXPORT LinkHide: public Link +{ + public: + /** + * Create a new Hide link. This is only used by Poppler::Page. + */ + LinkHide( LinkHidePrivate *lhidep ); + /** + * Destructor. + */ + ~LinkHide(); + + LinkType linkType() const override; + + /** + * The fully qualified target names of the action. + */ + QVector< QString > targets() const; + + /** + * Should this action change the visibility of the target to true. + */ + bool isShowAction() const; + + private: + Q_DECLARE_PRIVATE( LinkHide ) + Q_DISABLE_COPY( LinkHide ) +}; + } #endif diff --git a/qt5/src/poppler-page.cc b/qt5/src/poppler-page.cc index 28ee1cd8..355d5e84 100644 --- a/qt5/src/poppler-page.cc +++ b/qt5/src/poppler-page.cc @@ -20,6 +20,7 @@ * Copyright (C) 2017, Oliver Sander * Copyright (C) 2017 Adrian Johnson * Copyright (C) 2017, 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, . Work sponsored by the LiMux project of the city of Munich + * Copyright (C) 2018 Intevation GmbH * * 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 @@ -343,6 +344,15 @@ Link* PageData::convertLinkActionToLink(::LinkAction * a, DocumentData *parentDo popplerLink = new LinkOCGState( locgp ); } + case actionHide: + { + ::LinkHide *lh = (::LinkHide *)a; + + LinkHidePrivate *lhp = new LinkHidePrivate( linkArea, lh->hasTargetName() ? UnicodeParsedString( lh->getTargetName() ) : QString(), lh->isShowAction() ); + popplerLink = new LinkHide( lhp ); + } + break; + case actionUnknown: break; } -- 2.11.0