Index: poppler/Link.h =================================================================== --- poppler/Link.h +++ poppler/Link.h @@ -65,12 +65,12 @@ class LinkAction { public: - LinkAction() = default; + LinkAction(); LinkAction(const LinkAction &) = delete; LinkAction& operator=(const LinkAction &other) = delete; // Destructor. - virtual ~LinkAction() {} + virtual ~LinkAction(); // Was the LinkAction created successfully? virtual GBool isOk() = 0; @@ -83,6 +83,16 @@ // Parse an action dictionary. static LinkAction *parseAction(Object *obj, GooString *baseURI = NULL); + + // A List of the next actions to execute in order. + // The list contains pointer to LinkAction objects. + GooList *nextActions() const; + // Sets the next action list. Takes ownership of the actions. + void setNextActions(GooList *actions); + +private: + + GooList *nextActionList; }; //------------------------------------------------------------------------ Index: poppler/Link.cc =================================================================== --- poppler/Link.cc +++ poppler/Link.cc @@ -51,6 +51,14 @@ //------------------------------------------------------------------------ // LinkAction //------------------------------------------------------------------------ +LinkAction::LinkAction(): nextActionList(nullptr) { +} + +LinkAction::~LinkAction() { + if (nextActionList) { + delete nextActionList; + } +} LinkAction *LinkAction::parseDest(Object *obj) { LinkAction *action; @@ -139,9 +147,48 @@ delete action; return nullptr; } + + if (!action) { + return nullptr; + } + + // parse the next actions + Object nextObj = obj->dictLookup("Next"); + GooList *actionList = nullptr; + if (nextObj.isDict()) { + // Single next action + actionList = new GooList(1); + actionList->append(parseAction(&nextObj)); + } else if (nextObj.isArray()) { + Array *a = nextObj.getArray(); + int n = a->getLength(); + actionList = new GooList(n); + for (int i = 0; i < n; ++i) { + Object obj3 = a->get(i); + if (!obj3.isDict()) { + error(errSyntaxWarning, -1, "parseAction: Next array does not contain only dicts"); + continue; + } + actionList->append(parseAction(&obj3)); + } + } + + action->setNextActions(actionList); + return action; } +GooList *LinkAction::nextActions() const { + return nextActionList; +} + +void LinkAction::setNextActions(GooList *actions) { + if (nextActionList) { + delete nextActionList; + } + nextActionList = actions; +} + //------------------------------------------------------------------------ // LinkDest //------------------------------------------------------------------------ Index: qt5/src/poppler-link-private.h =================================================================== --- qt5/src/poppler-link-private.h +++ qt5/src/poppler-link-private.h @@ -23,6 +23,8 @@ namespace Poppler { +class Link; + class LinkPrivate { public: @@ -33,12 +35,16 @@ virtual ~LinkPrivate() { + for (Link *l: nextLinks) { + delete l; + } } LinkPrivate(const LinkPrivate &) = delete; LinkPrivate& operator=(const LinkPrivate &) = delete; QRectF linkArea; + QVector nextLinks; }; Index: qt5/src/poppler-link.h =================================================================== --- qt5/src/poppler-link.h +++ qt5/src/poppler-link.h @@ -28,6 +28,7 @@ #include #include #include +#include #include "poppler-export.h" struct Ref; @@ -219,7 +220,23 @@ * a general action. The area is given in 0..1 range */ QRectF linkArea() const; - + + /** + * Get the next links to be activiated / executed after this link. + * + * \since 0.64 + */ + QVector nextLinks() const; + + /** + * Set the next links to be activated / executed after this link. + * + * Takes ownership of the link objects pointed to in the vector. + * + * \since 0.64 + */ + void setNextLinks( const QVector< Link * > &links ) const; + protected: /// \cond PRIVATE Link( LinkPrivate &dd ); Index: qt5/src/poppler-link.cc =================================================================== --- qt5/src/poppler-link.cc +++ qt5/src/poppler-link.cc @@ -441,7 +441,17 @@ Q_D( const Link ); return d->linkArea; } + + QVector< Link * > Link::nextLinks() const + { + return d_ptr->nextLinks; + } + void Link::setNextLinks( const QVector< Link * > &links ) const + { + d_ptr->nextLinks = links; + } + // LinkGoto LinkGoto::LinkGoto( const QRectF &linkArea, QString extFileName, const LinkDestination & destination ) : Link( *new LinkGotoPrivate( linkArea, destination ) ) Index: qt5/src/poppler-page.cc =================================================================== --- qt5/src/poppler-page.cc +++ qt5/src/poppler-page.cc @@ -355,6 +355,20 @@ break; } + if ( popplerLink ) + { + GooList *nextActions = a->nextActions(); + if ( nextActions ) + { + QVector links; + for ( int i = 0, N = nextActions->getLength(); i < N; ++i ) + { + links << convertLinkActionToLink( static_cast< ::LinkAction * >( nextActions->get( i ) ), parentDoc, linkArea ); + } + popplerLink->setNextLinks( links ); + } + } + return popplerLink; }