1 | /* poppler-link.h: qt interface to poppler |
2 | * Copyright (C) 2006, 2013, 2016, 2018, 2019, 2021, 2022, 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 ¶ms); |
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 | SaveAs = 14 ///< \since 22.04 |
387 | }; |
388 | |
389 | /** |
390 | * The action of the current LinkAction |
391 | */ |
392 | ActionType actionType() const; |
393 | |
394 | /** |
395 | * Create a new Action link, that executes a specified action |
396 | * on the document. |
397 | * |
398 | * \param linkArea the active area of the link |
399 | * \param actionType which action should be executed |
400 | */ |
401 | LinkAction(const QRectF &linkArea, ActionType actionType); |
402 | /** |
403 | * Destructor. |
404 | */ |
405 | ~LinkAction() override; |
406 | LinkType linkType() const override; |
407 | |
408 | private: |
409 | Q_DECLARE_PRIVATE(LinkAction) |
410 | Q_DISABLE_COPY(LinkAction) |
411 | }; |
412 | |
413 | /** |
414 | * Sound: a sound to be played. |
415 | */ |
416 | class POPPLER_QT6_EXPORT LinkSound : public Link |
417 | { |
418 | public: |
419 | // create a Link_Sound |
420 | LinkSound(const QRectF &linkArea, double volume, bool sync, bool repeat, bool mix, SoundObject *sound); |
421 | /** |
422 | * Destructor. |
423 | */ |
424 | ~LinkSound() override; |
425 | |
426 | LinkType linkType() const override; |
427 | |
428 | /** |
429 | * The volume to be used when playing the sound. |
430 | * |
431 | * The volume is in the range [ -1, 1 ], where: |
432 | * - a negative number: no volume (mute) |
433 | * - 1: full volume |
434 | */ |
435 | double volume() const; |
436 | /** |
437 | * Whether the playback of the sound should be synchronous |
438 | * (thus blocking, waiting for the end of the sound playback). |
439 | */ |
440 | bool synchronous() const; |
441 | /** |
442 | * Whether the sound should be played continuously (that is, |
443 | * started again when it ends) |
444 | */ |
445 | bool repeat() const; |
446 | /** |
447 | * Whether the playback of this sound can be mixed with |
448 | * playbacks with other sounds of the same document. |
449 | * |
450 | * \note When false, any other playback must be stopped before |
451 | * playing the sound. |
452 | */ |
453 | bool mix() const; |
454 | /** |
455 | * The sound object to be played |
456 | */ |
457 | SoundObject *sound() const; |
458 | |
459 | private: |
460 | Q_DECLARE_PRIVATE(LinkSound) |
461 | Q_DISABLE_COPY(LinkSound) |
462 | }; |
463 | |
464 | /** |
465 | * Rendition: Rendition link. |
466 | */ |
467 | class POPPLER_QT6_EXPORT LinkRendition : public Link |
468 | { |
469 | public: |
470 | /** |
471 | * Describes the possible rendition actions. |
472 | */ |
473 | enum RenditionAction |
474 | { |
475 | NoRendition, |
476 | PlayRendition, |
477 | StopRendition, |
478 | PauseRendition, |
479 | ResumeRendition |
480 | }; |
481 | |
482 | /** |
483 | * Create a new rendition link. |
484 | * |
485 | * \param linkArea the active area of the link |
486 | * \param rendition the media rendition object. Ownership is taken |
487 | * \param operation the numeric operation (action) (@see ::LinkRendition::RenditionOperation) |
488 | * \param script the java script code |
489 | * \param annotationReference the object reference of the screen annotation associated with this rendition action |
490 | */ |
491 | LinkRendition(const QRectF &linkArea, ::MediaRendition *rendition, int operation, const QString &script, const Ref annotationReference); |
492 | |
493 | /** |
494 | * Destructor. |
495 | */ |
496 | ~LinkRendition() override; |
497 | |
498 | LinkType linkType() const override; |
499 | |
500 | /** |
501 | * Returns the media rendition object if the redition provides one, @c 0 otherwise |
502 | */ |
503 | MediaRendition *rendition() const; |
504 | |
505 | /** |
506 | * Returns the action that should be executed if a rendition object is provided. |
507 | */ |
508 | RenditionAction action() const; |
509 | |
510 | /** |
511 | * The JS code that shall be executed or an empty string. |
512 | */ |
513 | QString script() const; |
514 | |
515 | /** |
516 | * Returns whether the given @p annotation is the referenced screen annotation for this rendition @p link. |
517 | */ |
518 | bool isReferencedAnnotation(const ScreenAnnotation *annotation) const; |
519 | |
520 | private: |
521 | Q_DECLARE_PRIVATE(LinkRendition) |
522 | Q_DISABLE_COPY(LinkRendition) |
523 | }; |
524 | |
525 | /** |
526 | * JavaScript: a JavaScript code to be interpreted. |
527 | */ |
528 | class POPPLER_QT6_EXPORT LinkJavaScript : public Link |
529 | { |
530 | public: |
531 | /** |
532 | * Create a new JavaScript link. |
533 | * |
534 | * \param linkArea the active area of the link |
535 | * \param js the JS code to be interpreted |
536 | */ |
537 | LinkJavaScript(const QRectF &linkArea, const QString &js); |
538 | /** |
539 | * Destructor. |
540 | */ |
541 | ~LinkJavaScript() override; |
542 | |
543 | LinkType linkType() const override; |
544 | |
545 | /** |
546 | * The JS code |
547 | */ |
548 | QString script() const; |
549 | |
550 | private: |
551 | Q_DECLARE_PRIVATE(LinkJavaScript) |
552 | Q_DISABLE_COPY(LinkJavaScript) |
553 | }; |
554 | |
555 | /** |
556 | * Movie: a movie to be played. |
557 | */ |
558 | class POPPLER_QT6_EXPORT LinkMovie : public Link |
559 | { |
560 | public: |
561 | /** |
562 | * Describes the operation to be performed on the movie. |
563 | */ |
564 | enum Operation |
565 | { |
566 | Play, |
567 | Stop, |
568 | Pause, |
569 | Resume |
570 | }; |
571 | |
572 | /** |
573 | * Create a new Movie link. |
574 | * |
575 | * \param linkArea the active area of the link |
576 | * \param operation the operation to be performed on the movie |
577 | * \param annotationTitle the title of the movie annotation identifying the movie to be played |
578 | * \param annotationReference the object reference of the movie annotation identifying the movie to be played |
579 | * |
580 | * Note: This constructor is supposed to be used by Poppler::Page only. |
581 | */ |
582 | LinkMovie(const QRectF &linkArea, Operation operation, const QString &annotationTitle, const Ref annotationReference); |
583 | /** |
584 | * Destructor. |
585 | */ |
586 | ~LinkMovie() override; |
587 | LinkType linkType() const override; |
588 | /** |
589 | * Returns the operation to be performed on the movie. |
590 | */ |
591 | Operation operation() const; |
592 | /** |
593 | * Returns whether the given @p annotation is the referenced movie annotation for this movie @p link. |
594 | */ |
595 | bool isReferencedAnnotation(const MovieAnnotation *annotation) const; |
596 | |
597 | private: |
598 | Q_DECLARE_PRIVATE(LinkMovie) |
599 | Q_DISABLE_COPY(LinkMovie) |
600 | }; |
601 | |
602 | /** |
603 | * OCGState: an optional content group state change. |
604 | */ |
605 | class POPPLER_QT6_EXPORT LinkOCGState : public Link |
606 | { |
607 | friend class OptContentModel; |
608 | |
609 | public: |
610 | /** |
611 | * Create a new OCGState link. This is only used by Poppler::Page. |
612 | */ |
613 | explicit LinkOCGState(LinkOCGStatePrivate *ocgp); |
614 | /** |
615 | * Destructor. |
616 | */ |
617 | ~LinkOCGState() override; |
618 | |
619 | LinkType linkType() const override; |
620 | |
621 | private: |
622 | Q_DECLARE_PRIVATE(LinkOCGState) |
623 | Q_DISABLE_COPY(LinkOCGState) |
624 | }; |
625 | |
626 | /** |
627 | * Hide: an action to show / hide a field. |
628 | */ |
629 | class POPPLER_QT6_EXPORT LinkHide : public Link |
630 | { |
631 | public: |
632 | /** |
633 | * Create a new Hide link. This is only used by Poppler::Page. |
634 | */ |
635 | explicit LinkHide(LinkHidePrivate *lhidep); |
636 | /** |
637 | * Destructor. |
638 | */ |
639 | ~LinkHide() override; |
640 | |
641 | LinkType linkType() const override; |
642 | |
643 | /** |
644 | * The fully qualified target names of the action. |
645 | */ |
646 | QVector<QString> targets() const; |
647 | |
648 | /** |
649 | * Should this action change the visibility of the target to true. |
650 | */ |
651 | bool isShowAction() const; |
652 | |
653 | private: |
654 | Q_DECLARE_PRIVATE(LinkHide) |
655 | Q_DISABLE_COPY(LinkHide) |
656 | }; |
657 | |
658 | } |
659 | |
660 | #endif |
661 | |