1 /* poppler-link.h: qt interface to poppler
2  * Copyright (C) 2006, 2013, 2016, 2018, 2019, 2021, Albert Astals Cid <aacid@kde.org>
3  * Copyright (C) 2007-2008, 2010, Pino Toscano <pino@kde.org>
4  * Copyright (C) 2010, 2012, Guillermo Amaral <gamaral@kdab.com>
5  * Copyright (C) 2012, Tobias Koenig <tokoe@kdab.com>
6  * Copyright (C) 2013, Anthony Granger <grangeranthony@gmail.com>
7  * Copyright (C) 2018 Intevation GmbH <intevation@intevation.de>
8  * Copyright (C) 2020 Oliver Sander <oliver.sander@tu-dresden.de>
9  * Adapting code from
10  *   Copyright (C) 2004 by Enrico Ros <eros.kde@email.it>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2, or (at your option)
15  * any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
25  */
26 
27 #ifndef _POPPLER_LINK_H_
28 #define _POPPLER_LINK_H_
29 
30 #include <QtCore/QString>
31 #include <QtCore/QRectF>
32 #include <QtCore/QSharedDataPointer>
33 #include <QtCore/QVector>
34 #include "poppler-export.h"
35 
36 struct Ref;
37 class MediaRendition;
38 
39 namespace Poppler {
40 
41 class LinkPrivate;
42 class LinkGotoPrivate;
43 class LinkExecutePrivate;
44 class LinkBrowsePrivate;
45 class LinkActionPrivate;
46 class LinkSoundPrivate;
47 class LinkJavaScriptPrivate;
48 class LinkMoviePrivate;
49 class LinkDestinationData;
50 class LinkDestinationPrivate;
51 class LinkRenditionPrivate;
52 class LinkOCGStatePrivate;
53 class LinkHidePrivate;
54 class MediaRendition;
55 class MovieAnnotation;
56 class ScreenAnnotation;
57 class SoundObject;
58 
59 /**
60  * \short A destination.
61  *
62  * The LinkDestination class represent a "destination" (in terms of visual
63  * viewport to be displayed) for \link Poppler::LinkGoto GoTo\endlink links,
64  * and items in the table of contents (TOC) of a document.
65  *
66  * Coordinates are in 0..1 range
67  */
68 class POPPLER_QT5_EXPORT LinkDestination
69 {
70 public:
71     /**
72      * The possible kind of "viewport destination".
73      */
74     enum Kind
75     {
76         /**
77          * The new viewport is specified in terms of:
78          * - possible new left coordinate (see isChangeLeft() )
79          * - possible new top coordinate (see isChangeTop() )
80          * - possible new zoom level (see isChangeZoom() )
81          */
82         destXYZ = 1,
83         destFit = 2,
84         destFitH = 3,
85         destFitV = 4,
86         destFitR = 5,
87         destFitB = 6,
88         destFitBH = 7,
89         destFitBV = 8
90     };
91 
92     /// \cond PRIVATE
93     explicit LinkDestination(const LinkDestinationData &data);
94     explicit LinkDestination(const QString &description);
95     /// \endcond
96     /**
97      * Copy constructor.
98      */
99     LinkDestination(const LinkDestination &other);
100     /**
101      * Destructor.
102      */
103     ~LinkDestination();
104 
105     // Accessors.
106     /**
107      * The kind of destination.
108      */
109     Kind kind() const;
110     /**
111      * Which page is the target of this destination.
112      *
113      * \note this number is 1-based, so for a 5 pages document the
114      *       valid page numbers go from 1 to 5 (both included).
115      */
116     int pageNumber() const;
117     /**
118      * The new left for the viewport of the target page, in case
119      * it is specified to be changed (see isChangeLeft() )
120      */
121     double left() const;
122     double bottom() const;
123     double right() const;
124     /**
125      * The new top for the viewport of the target page, in case
126      * it is specified to be changed (see isChangeTop() )
127      */
128     double top() const;
129     double zoom() const;
130     /**
131      * Whether the left of the viewport on the target page should
132      * be changed.
133      *
134      * \see left()
135      */
136     bool isChangeLeft() const;
137     /**
138      * Whether the top of the viewport on the target page should
139      * be changed.
140      *
141      * \see top()
142      */
143     bool isChangeTop() const;
144     /**
145      * Whether the zoom level should be changed.
146      *
147      * \see zoom()
148      */
149     bool isChangeZoom() const;
150 
151     /**
152      * Return a string repesentation of this destination.
153      */
154     QString toString() const;
155 
156     /**
157      * Return the name of this destination.
158      *
159      * \since 0.12
160      */
161     QString destinationName() const;
162 
163     /**
164      * Assignment operator.
165      */
166     LinkDestination &operator=(const LinkDestination &other);
167 
168 private:
169     QSharedDataPointer<LinkDestinationPrivate> d;
170 };
171 
172 /**
173  * \short Encapsulates data that describes a link.
174  *
175  * This is the base class for links. It makes mandatory for inherited
176  * kind of links to reimplement the linkType() method and return the type of
177  * the link described by the reimplemented class.
178  */
179 class POPPLER_QT5_EXPORT Link
180 {
181 public:
182     /// \cond PRIVATE
183     explicit Link(const QRectF &linkArea);
184     /// \endcond
185 
186     /**
187      * The possible kinds of link.
188      *
189      * Inherited classes must return an unique identifier
190      */
191     enum LinkType
192     {
193         None, ///< Unknown link
194         Goto, ///< A "Go To" link
195         Execute, ///< A command to be executed
196         Browse, ///< An URL to be browsed (eg "http://poppler.freedesktop.org")
197         Action, ///< A "standard" action to be executed in the viewer
198         Sound, ///< A link representing a sound to be played
199         Movie, ///< An action to be executed on a movie
200         Rendition, ///< A rendition link \since 0.20
201         JavaScript, ///< A JavaScript code to be interpreted \since 0.10
202         OCGState, ///< An Optional Content Group state change \since 0.50
203         Hide, ///< An action to hide a field \since 0.64
204     };
205 
206     /**
207      * The type of this link.
208      */
209     virtual LinkType linkType() const;
210 
211     /**
212      * Destructor.
213      */
214     virtual ~Link();
215 
216     /**
217      * The area of a Page where the link should be active.
218      *
219      * \note this can be a null rect, in this case the link represents
220      * a general action. The area is given in 0..1 range
221      */
222     QRectF linkArea() const;
223 
224     /**
225      * Get the next links to be activated / executed after this link.
226      *
227      * \since 0.64
228      */
229     QVector<Link *> nextLinks() const;
230 
231 protected:
232     /// \cond PRIVATE
233     explicit Link(LinkPrivate &dd);
234     Q_DECLARE_PRIVATE(Link)
235     LinkPrivate *d_ptr;
236     /// \endcond
237 
238 private:
239     Q_DISABLE_COPY(Link)
240 };
241 
242 /**
243  * \brief Viewport reaching request.
244  *
245  * With a LinkGoto link, the document requests the specified viewport to be
246  * reached (aka, displayed in a viewer). Furthermore, if a file name is specified,
247  * then the destination refers to that document (and not to the document the
248  * current LinkGoto belongs to).
249  */
250 class POPPLER_QT5_EXPORT LinkGoto : public Link
251 {
252 public:
253     /**
254      * Create a new Goto link.
255      *
256      * \param linkArea the active area of the link
257      * \param extFileName if not empty, the file name to be open
258      * \param destination the destination to be reached
259      */
260     // TODO Next ABI break, make extFileName const &
261     LinkGoto(const QRectF &linkArea, QString extFileName, const LinkDestination &destination);
262     /**
263      * Destructor.
264      */
265     ~LinkGoto() override;
266 
267     /**
268      * Whether the destination is in an external document
269      * (i.e. not the current document)
270      */
271     bool isExternal() const;
272     // query for goto parameters
273     /**
274      * The file name of the document the destination() refers to,
275      * or an empty string in case it refers to the current document.
276      */
277     QString fileName() const;
278     /**
279      * The destination to reach.
280      */
281     LinkDestination destination() const;
282     LinkType linkType() const override;
283 
284 private:
285     Q_DECLARE_PRIVATE(LinkGoto)
286     Q_DISABLE_COPY(LinkGoto)
287 };
288 
289 /**
290  * \brief Generic execution request.
291  *
292  * The LinkExecute link represent a "file name" execution request. The result
293  * depends on the \link fileName() file name\endlink:
294  * - if it is a document, then it is requested to be open
295  * - otherwise, it represents an executable to be run with the specified parameters
296  */
297 class POPPLER_QT5_EXPORT LinkExecute : public Link
298 {
299 public:
300     /**
301      * The file name to be executed
302      */
303     QString fileName() const;
304     /**
305      * The parameters for the command.
306      */
307     QString parameters() const;
308 
309     /**
310      * Create a new Execute link.
311      *
312      * \param linkArea the active area of the link
313      * \param file the file name to be open, or the program to be execute
314      * \param params the parameters for the program to execute
315      */
316     LinkExecute(const QRectF &linkArea, const QString &file, const QString &params);
317     /**
318      * Destructor.
319      */
320     ~LinkExecute() override;
321     LinkType linkType() const override;
322 
323 private:
324     Q_DECLARE_PRIVATE(LinkExecute)
325     Q_DISABLE_COPY(LinkExecute)
326 };
327 
328 /**
329  * \brief An URL to browse.
330  *
331  * The LinkBrowse link holds a URL (eg 'http://poppler.freedesktop.org',
332  * 'mailto:john@some.org', etc) to be open.
333  *
334  * The format of the URL is specified by RFC 2396 (http://www.ietf.org/rfc/rfc2396.txt)
335  */
336 class POPPLER_QT5_EXPORT LinkBrowse : public Link
337 {
338 public:
339     /**
340      * The URL to open
341      */
342     QString url() const;
343 
344     /**
345      * Create a new browse link.
346      *
347      * \param linkArea the active area of the link
348      * \param url the URL to be open
349      */
350     LinkBrowse(const QRectF &linkArea, const QString &url);
351     /**
352      * Destructor.
353      */
354     ~LinkBrowse() override;
355     LinkType linkType() const override;
356 
357 private:
358     Q_DECLARE_PRIVATE(LinkBrowse)
359     Q_DISABLE_COPY(LinkBrowse)
360 };
361 
362 /**
363  * \brief "Standard" action request.
364  *
365  * The LinkAction class represents a link that request a "standard" action
366  * to be performed by the viewer on the displayed document.
367  */
368 class POPPLER_QT5_EXPORT LinkAction : public Link
369 {
370 public:
371     /**
372      * The possible types of actions
373      */
374     enum ActionType
375     {
376         PageFirst = 1,
377         PagePrev = 2,
378         PageNext = 3,
379         PageLast = 4,
380         HistoryBack = 5,
381         HistoryForward = 6,
382         Quit = 7,
383         Presentation = 8,
384         EndPresentation = 9,
385         Find = 10,
386         GoToPage = 11,
387         Close = 12,
388         Print = 13 ///< \since 0.16
389     };
390 
391     /**
392      * The action of the current LinkAction
393      */
394     ActionType actionType() const;
395 
396     /**
397      * Create a new Action link, that executes a specified action
398      * on the document.
399      *
400      * \param linkArea the active area of the link
401      * \param actionType which action should be executed
402      */
403     LinkAction(const QRectF &linkArea, ActionType actionType);
404     /**
405      * Destructor.
406      */
407     ~LinkAction() override;
408     LinkType linkType() const override;
409 
410 private:
411     Q_DECLARE_PRIVATE(LinkAction)
412     Q_DISABLE_COPY(LinkAction)
413 };
414 
415 /**
416  * Sound: a sound to be played.
417  *
418  * \since 0.6
419  */
420 class POPPLER_QT5_EXPORT LinkSound : public Link
421 {
422 public:
423     // create a Link_Sound
424     LinkSound(const QRectF &linkArea, double volume, bool sync, bool repeat, bool mix, SoundObject *sound);
425     /**
426      * Destructor.
427      */
428     ~LinkSound() override;
429 
430     LinkType linkType() const override;
431 
432     /**
433      * The volume to be used when playing the sound.
434      *
435      * The volume is in the range [ -1, 1 ], where:
436      * - a negative number: no volume (mute)
437      * - 1: full volume
438      */
439     double volume() const;
440     /**
441      * Whether the playback of the sound should be synchronous
442      * (thus blocking, waiting for the end of the sound playback).
443      */
444     bool synchronous() const;
445     /**
446      * Whether the sound should be played continuously (that is,
447      * started again when it ends)
448      */
449     bool repeat() const;
450     /**
451      * Whether the playback of this sound can be mixed with
452      * playbacks with other sounds of the same document.
453      *
454      * \note When false, any other playback must be stopped before
455      *       playing the sound.
456      */
457     bool mix() const;
458     /**
459      * The sound object to be played
460      */
461     SoundObject *sound() const;
462 
463 private:
464     Q_DECLARE_PRIVATE(LinkSound)
465     Q_DISABLE_COPY(LinkSound)
466 };
467 
468 /**
469  * Rendition: Rendition link.
470  *
471  * \since 0.20
472  */
473 class POPPLER_QT5_EXPORT LinkRendition : public Link
474 {
475 public:
476     /**
477      * Describes the possible rendition actions.
478      *
479      * \since 0.22
480      */
481     enum RenditionAction
482     {
483         NoRendition,
484         PlayRendition,
485         StopRendition,
486         PauseRendition,
487         ResumeRendition
488     };
489 
490     /**
491      * Create a new rendition link.
492      *
493      * \param linkArea the active area of the link
494      * \param rendition the media rendition object. Ownership is taken
495      * \param operation the numeric operation (action) (@see ::LinkRendition::RenditionOperation)
496      * \param script the java script code
497      * \param annotationReference the object reference of the screen annotation associated with this rendition action
498      * \since 0.22
499      */
500     // TODO Next ABI break, remove & from annotationReference
501     LinkRendition(const QRectF &linkArea, ::MediaRendition *rendition, int operation, const QString &script, const Ref &annotationReference);
502 
503     /**
504      * Destructor.
505      */
506     ~LinkRendition() override;
507 
508     LinkType linkType() const override;
509 
510     /**
511      * Returns the media rendition object if the redition provides one, @c 0 otherwise
512      */
513     MediaRendition *rendition() const;
514 
515     /**
516      * Returns the action that should be executed if a rendition object is provided.
517      *
518      * \since 0.22
519      */
520     RenditionAction action() const;
521 
522     /**
523      * The JS code that shall be executed or an empty string.
524      *
525      * \since 0.22
526      */
527     QString script() const;
528 
529     /**
530      * Returns whether the given @p annotation is the referenced screen annotation for this rendition @p link.
531      *
532      * \since 0.22
533      */
534     bool isReferencedAnnotation(const ScreenAnnotation *annotation) const;
535 
536 private:
537     Q_DECLARE_PRIVATE(LinkRendition)
538     Q_DISABLE_COPY(LinkRendition)
539 };
540 
541 /**
542  * JavaScript: a JavaScript code to be interpreted.
543  *
544  * \since 0.10
545  */
546 class POPPLER_QT5_EXPORT LinkJavaScript : public Link
547 {
548 public:
549     /**
550      * Create a new JavaScript link.
551      *
552      * \param linkArea the active area of the link
553      * \param js the JS code to be interpreted
554      */
555     LinkJavaScript(const QRectF &linkArea, const QString &js);
556     /**
557      * Destructor.
558      */
559     ~LinkJavaScript() override;
560 
561     LinkType linkType() const override;
562 
563     /**
564      * The JS code
565      */
566     QString script() const;
567 
568 private:
569     Q_DECLARE_PRIVATE(LinkJavaScript)
570     Q_DISABLE_COPY(LinkJavaScript)
571 };
572 
573 /**
574  * Movie: a movie to be played.
575  *
576  * \since 0.20
577  */
578 class POPPLER_QT5_EXPORT LinkMovie : public Link
579 {
580 public:
581     /**
582      * Describes the operation to be performed on the movie.
583      */
584     enum Operation
585     {
586         Play,
587         Stop,
588         Pause,
589         Resume
590     };
591 
592     /**
593      * Create a new Movie link.
594      *
595      * \param linkArea the active area of the link
596      * \param operation the operation to be performed on the movie
597      * \param annotationTitle the title of the movie annotation identifying the movie to be played
598      * \param annotationReference the object reference of the movie annotation identifying the movie to be played
599      *
600      * Note: This constructor is supposed to be used by Poppler::Page only.
601      */
602     // TODO Next ABI break, remove & from annotationReference
603     LinkMovie(const QRectF &linkArea, Operation operation, const QString &annotationTitle, const Ref &annotationReference);
604     /**
605      * Destructor.
606      */
607     ~LinkMovie() override;
608     LinkType linkType() const override;
609     /**
610      * Returns the operation to be performed on the movie.
611      */
612     Operation operation() const;
613     /**
614      * Returns whether the given @p annotation is the referenced movie annotation for this movie @p link.
615      */
616     bool isReferencedAnnotation(const MovieAnnotation *annotation) const;
617 
618 private:
619     Q_DECLARE_PRIVATE(LinkMovie)
620     Q_DISABLE_COPY(LinkMovie)
621 };
622 
623 /**
624  * OCGState: an optional content group state change.
625  *
626  * \since 0.50
627  */
628 class POPPLER_QT5_EXPORT LinkOCGState : public Link
629 {
630     friend class OptContentModel;
631 
632 public:
633     /**
634      * Create a new OCGState link. This is only used by Poppler::Page.
635      */
636     explicit LinkOCGState(LinkOCGStatePrivate *ocgp);
637     /**
638      * Destructor.
639      */
640     ~LinkOCGState() override;
641 
642     LinkType linkType() const override;
643 
644 private:
645     Q_DECLARE_PRIVATE(LinkOCGState)
646     Q_DISABLE_COPY(LinkOCGState)
647 };
648 
649 /**
650  * Hide: an action to show / hide a field.
651  *
652  * \since 0.64
653  */
654 class POPPLER_QT5_EXPORT LinkHide : public Link
655 {
656 public:
657     /**
658      * Create a new Hide link. This is only used by Poppler::Page.
659      */
660     explicit LinkHide(LinkHidePrivate *lhidep);
661     /**
662      * Destructor.
663      */
664     ~LinkHide() override;
665 
666     LinkType linkType() const override;
667 
668     /**
669      * The fully qualified target names of the action.
670      */
671     QVector<QString> targets() const;
672 
673     /**
674      * Should this action change the visibility of the target to true.
675      */
676     bool isShowAction() const;
677 
678 private:
679     Q_DECLARE_PRIVATE(LinkHide)
680     Q_DISABLE_COPY(LinkHide)
681 };
682 
683 }
684 
685 #endif
686