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, 2021 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_QT6_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     QString destinationName() const;
160 
161     /**
162      * Assignment operator.
163      */
164     LinkDestination &operator=(const LinkDestination &other);
165 
166 private:
167     QSharedDataPointer<LinkDestinationPrivate> d;
168 };
169 
170 /**
171  * \short Encapsulates data that describes a link.
172  *
173  * This is the base class for links. It makes mandatory for inherited
174  * kind of links to reimplement the linkType() method and return the type of
175  * the link described by the reimplemented class.
176  */
177 class POPPLER_QT6_EXPORT Link
178 {
179 public:
180     /// \cond PRIVATE
181     explicit Link(const QRectF &linkArea);
182     /// \endcond
183 
184     /**
185      * The possible kinds of link.
186      *
187      * Inherited classes must return an unique identifier
188      */
189     enum LinkType
190     {
191         None, ///< Unknown link
192         Goto, ///< A "Go To" link
193         Execute, ///< A command to be executed
194         Browse, ///< An URL to be browsed (eg "http://poppler.freedesktop.org")
195         Action, ///< A "standard" action to be executed in the viewer
196         Sound, ///< A link representing a sound to be played
197         Movie, ///< An action to be executed on a movie
198         Rendition, ///< A rendition link
199         JavaScript, ///< A JavaScript code to be interpreted
200         OCGState, ///< An Optional Content Group state change
201         Hide, ///< An action to hide a field
202     };
203 
204     /**
205      * The type of this link.
206      */
207     virtual LinkType linkType() const;
208 
209     /**
210      * Destructor.
211      */
212     virtual ~Link();
213 
214     /**
215      * The area of a Page where the link should be active.
216      *
217      * \note this can be a null rect, in this case the link represents
218      * a general action. The area is given in 0..1 range
219      */
220     QRectF linkArea() const;
221 
222     /**
223      * Get the next links to be activated / executed after this link.
224      *
225      * \note The caller does not get ownership of the returned objects.
226      */
227     QVector<Link *> nextLinks() const;
228 
229 protected:
230     /// \cond PRIVATE
231     explicit Link(LinkPrivate &dd);
232     Q_DECLARE_PRIVATE(Link)
233     LinkPrivate *d_ptr;
234     /// \endcond
235 
236 private:
237     Q_DISABLE_COPY(Link)
238 };
239 
240 /**
241  * \brief Viewport reaching request.
242  *
243  * With a LinkGoto link, the document requests the specified viewport to be
244  * reached (aka, displayed in a viewer). Furthermore, if a file name is specified,
245  * then the destination refers to that document (and not to the document the
246  * current LinkGoto belongs to).
247  */
248 class POPPLER_QT6_EXPORT LinkGoto : public Link
249 {
250 public:
251     /**
252      * Create a new Goto link.
253      *
254      * \param linkArea the active area of the link
255      * \param extFileName if not empty, the file name to be open
256      * \param destination the destination to be reached
257      */
258     LinkGoto(const QRectF &linkArea, const QString &extFileName, const LinkDestination &destination);
259     /**
260      * Destructor.
261      */
262     ~LinkGoto() override;
263 
264     /**
265      * Whether the destination is in an external document
266      * (i.e. not the current document)
267      */
268     bool isExternal() const;
269     // query for goto parameters
270     /**
271      * The file name of the document the destination() refers to,
272      * or an empty string in case it refers to the current document.
273      */
274     QString fileName() const;
275     /**
276      * The destination to reach.
277      */
278     LinkDestination destination() const;
279     LinkType linkType() const override;
280 
281 private:
282     Q_DECLARE_PRIVATE(LinkGoto)
283     Q_DISABLE_COPY(LinkGoto)
284 };
285 
286 /**
287  * \brief Generic execution request.
288  *
289  * The LinkExecute link represent a "file name" execution request. The result
290  * depends on the \link fileName() file name\endlink:
291  * - if it is a document, then it is requested to be open
292  * - otherwise, it represents an executable to be run with the specified parameters
293  */
294 class POPPLER_QT6_EXPORT LinkExecute : public Link
295 {
296 public:
297     /**
298      * The file name to be executed
299      */
300     QString fileName() const;
301     /**
302      * The parameters for the command.
303      */
304     QString parameters() const;
305 
306     /**
307      * Create a new Execute link.
308      *
309      * \param linkArea the active area of the link
310      * \param file the file name to be open, or the program to be execute
311      * \param params the parameters for the program to execute
312      */
313     LinkExecute(const QRectF &linkArea, const QString &file, const QString &params);
314     /**
315      * Destructor.
316      */
317     ~LinkExecute() override;
318     LinkType linkType() const override;
319 
320 private:
321     Q_DECLARE_PRIVATE(LinkExecute)
322     Q_DISABLE_COPY(LinkExecute)
323 };
324 
325 /**
326  * \brief An URL to browse.
327  *
328  * The LinkBrowse link holds a URL (eg 'http://poppler.freedesktop.org',
329  * 'mailto:john@some.org', etc) to be open.
330  *
331  * The format of the URL is specified by RFC 2396 (http://www.ietf.org/rfc/rfc2396.txt)
332  */
333 class POPPLER_QT6_EXPORT LinkBrowse : public Link
334 {
335 public:
336     /**
337      * The URL to open
338      */
339     QString url() const;
340 
341     /**
342      * Create a new browse link.
343      *
344      * \param linkArea the active area of the link
345      * \param url the URL to be open
346      */
347     LinkBrowse(const QRectF &linkArea, const QString &url);
348     /**
349      * Destructor.
350      */
351     ~LinkBrowse() override;
352     LinkType linkType() const override;
353 
354 private:
355     Q_DECLARE_PRIVATE(LinkBrowse)
356     Q_DISABLE_COPY(LinkBrowse)
357 };
358 
359 /**
360  * \brief "Standard" action request.
361  *
362  * The LinkAction class represents a link that request a "standard" action
363  * to be performed by the viewer on the displayed document.
364  */
365 class POPPLER_QT6_EXPORT LinkAction : public Link
366 {
367 public:
368     /**
369      * The possible types of actions
370      */
371     enum ActionType
372     {
373         PageFirst = 1,
374         PagePrev = 2,
375         PageNext = 3,
376         PageLast = 4,
377         HistoryBack = 5,
378         HistoryForward = 6,
379         Quit = 7,
380         Presentation = 8,
381         EndPresentation = 9,
382         Find = 10,
383         GoToPage = 11,
384         Close = 12,
385         Print = 13
386     };
387 
388     /**
389      * The action of the current LinkAction
390      */
391     ActionType actionType() const;
392 
393     /**
394      * Create a new Action link, that executes a specified action
395      * on the document.
396      *
397      * \param linkArea the active area of the link
398      * \param actionType which action should be executed
399      */
400     LinkAction(const QRectF &linkArea, ActionType actionType);
401     /**
402      * Destructor.
403      */
404     ~LinkAction() override;
405     LinkType linkType() const override;
406 
407 private:
408     Q_DECLARE_PRIVATE(LinkAction)
409     Q_DISABLE_COPY(LinkAction)
410 };
411 
412 /**
413  * Sound: a sound to be played.
414  */
415 class POPPLER_QT6_EXPORT LinkSound : public Link
416 {
417 public:
418     // create a Link_Sound
419     LinkSound(const QRectF &linkArea, double volume, bool sync, bool repeat, bool mix, SoundObject *sound);
420     /**
421      * Destructor.
422      */
423     ~LinkSound() override;
424 
425     LinkType linkType() const override;
426 
427     /**
428      * The volume to be used when playing the sound.
429      *
430      * The volume is in the range [ -1, 1 ], where:
431      * - a negative number: no volume (mute)
432      * - 1: full volume
433      */
434     double volume() const;
435     /**
436      * Whether the playback of the sound should be synchronous
437      * (thus blocking, waiting for the end of the sound playback).
438      */
439     bool synchronous() const;
440     /**
441      * Whether the sound should be played continuously (that is,
442      * started again when it ends)
443      */
444     bool repeat() const;
445     /**
446      * Whether the playback of this sound can be mixed with
447      * playbacks with other sounds of the same document.
448      *
449      * \note When false, any other playback must be stopped before
450      *       playing the sound.
451      */
452     bool mix() const;
453     /**
454      * The sound object to be played
455      */
456     SoundObject *sound() const;
457 
458 private:
459     Q_DECLARE_PRIVATE(LinkSound)
460     Q_DISABLE_COPY(LinkSound)
461 };
462 
463 /**
464  * Rendition: Rendition link.
465  */
466 class POPPLER_QT6_EXPORT LinkRendition : public Link
467 {
468 public:
469     /**
470      * Describes the possible rendition actions.
471      */
472     enum RenditionAction
473     {
474         NoRendition,
475         PlayRendition,
476         StopRendition,
477         PauseRendition,
478         ResumeRendition
479     };
480 
481     /**
482      * Create a new rendition link.
483      *
484      * \param linkArea the active area of the link
485      * \param rendition the media rendition object. Ownership is taken
486      * \param operation the numeric operation (action) (@see ::LinkRendition::RenditionOperation)
487      * \param script the java script code
488      * \param annotationReference the object reference of the screen annotation associated with this rendition action
489      */
490     LinkRendition(const QRectF &linkArea, ::MediaRendition *rendition, int operation, const QString &script, const Ref annotationReference);
491 
492     /**
493      * Destructor.
494      */
495     ~LinkRendition() override;
496 
497     LinkType linkType() const override;
498 
499     /**
500      * Returns the media rendition object if the redition provides one, @c 0 otherwise
501      */
502     MediaRendition *rendition() const;
503 
504     /**
505      * Returns the action that should be executed if a rendition object is provided.
506      */
507     RenditionAction action() const;
508 
509     /**
510      * The JS code that shall be executed or an empty string.
511      */
512     QString script() const;
513 
514     /**
515      * Returns whether the given @p annotation is the referenced screen annotation for this rendition @p link.
516      */
517     bool isReferencedAnnotation(const ScreenAnnotation *annotation) const;
518 
519 private:
520     Q_DECLARE_PRIVATE(LinkRendition)
521     Q_DISABLE_COPY(LinkRendition)
522 };
523 
524 /**
525  * JavaScript: a JavaScript code to be interpreted.
526  */
527 class POPPLER_QT6_EXPORT LinkJavaScript : public Link
528 {
529 public:
530     /**
531      * Create a new JavaScript link.
532      *
533      * \param linkArea the active area of the link
534      * \param js the JS code to be interpreted
535      */
536     LinkJavaScript(const QRectF &linkArea, const QString &js);
537     /**
538      * Destructor.
539      */
540     ~LinkJavaScript() override;
541 
542     LinkType linkType() const override;
543 
544     /**
545      * The JS code
546      */
547     QString script() const;
548 
549 private:
550     Q_DECLARE_PRIVATE(LinkJavaScript)
551     Q_DISABLE_COPY(LinkJavaScript)
552 };
553 
554 /**
555  * Movie: a movie to be played.
556  */
557 class POPPLER_QT6_EXPORT LinkMovie : public Link
558 {
559 public:
560     /**
561      * Describes the operation to be performed on the movie.
562      */
563     enum Operation
564     {
565         Play,
566         Stop,
567         Pause,
568         Resume
569     };
570 
571     /**
572      * Create a new Movie link.
573      *
574      * \param linkArea the active area of the link
575      * \param operation the operation to be performed on the movie
576      * \param annotationTitle the title of the movie annotation identifying the movie to be played
577      * \param annotationReference the object reference of the movie annotation identifying the movie to be played
578      *
579      * Note: This constructor is supposed to be used by Poppler::Page only.
580      */
581     LinkMovie(const QRectF &linkArea, Operation operation, const QString &annotationTitle, const Ref annotationReference);
582     /**
583      * Destructor.
584      */
585     ~LinkMovie() override;
586     LinkType linkType() const override;
587     /**
588      * Returns the operation to be performed on the movie.
589      */
590     Operation operation() const;
591     /**
592      * Returns whether the given @p annotation is the referenced movie annotation for this movie @p link.
593      */
594     bool isReferencedAnnotation(const MovieAnnotation *annotation) const;
595 
596 private:
597     Q_DECLARE_PRIVATE(LinkMovie)
598     Q_DISABLE_COPY(LinkMovie)
599 };
600 
601 /**
602  * OCGState: an optional content group state change.
603  */
604 class POPPLER_QT6_EXPORT LinkOCGState : public Link
605 {
606     friend class OptContentModel;
607 
608 public:
609     /**
610      * Create a new OCGState link. This is only used by Poppler::Page.
611      */
612     explicit LinkOCGState(LinkOCGStatePrivate *ocgp);
613     /**
614      * Destructor.
615      */
616     ~LinkOCGState() override;
617 
618     LinkType linkType() const override;
619 
620 private:
621     Q_DECLARE_PRIVATE(LinkOCGState)
622     Q_DISABLE_COPY(LinkOCGState)
623 };
624 
625 /**
626  * Hide: an action to show / hide a field.
627  */
628 class POPPLER_QT6_EXPORT LinkHide : public Link
629 {
630 public:
631     /**
632      * Create a new Hide link. This is only used by Poppler::Page.
633      */
634     explicit LinkHide(LinkHidePrivate *lhidep);
635     /**
636      * Destructor.
637      */
638     ~LinkHide() override;
639 
640     LinkType linkType() const override;
641 
642     /**
643      * The fully qualified target names of the action.
644      */
645     QVector<QString> targets() const;
646 
647     /**
648      * Should this action change the visibility of the target to true.
649      */
650     bool isShowAction() const;
651 
652 private:
653     Q_DECLARE_PRIVATE(LinkHide)
654     Q_DISABLE_COPY(LinkHide)
655 };
656 
657 }
658 
659 #endif
660