1 | /* poppler-link.cc: qt interface to poppler |
2 | * Copyright (C) 2006-2007, 2013, 2016-2021, Albert Astals Cid |
3 | * Copyright (C) 2007-2008, Pino Toscano <pino@kde.org> |
4 | * Copyright (C) 2010 Hib Eris <hib@hiberis.nl> |
5 | * Copyright (C) 2012, Tobias Koenig <tokoe@kdab.com> |
6 | * Copyright (C) 2012, Guillermo A. Amaral B. <gamaral@kde.org> |
7 | * Copyright (C) 2018 Intevation GmbH <intevation@intevation.de> |
8 | * Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de> |
9 | * Copyright (C) 2020, 2021 Oliver Sander <oliver.sander@tu-dresden.de> |
10 | * Adapting code from |
11 | * Copyright (C) 2004 by Enrico Ros <eros.kde@email.it> |
12 | * |
13 | * This program is free software; you can redistribute it and/or modify |
14 | * it under the terms of the GNU General Public License as published by |
15 | * the Free Software Foundation; either version 2, or (at your option) |
16 | * any later version. |
17 | * |
18 | * This program is distributed in the hope that it will be useful, |
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
21 | * GNU General Public License for more details. |
22 | * |
23 | * You should have received a copy of the GNU General Public License |
24 | * along with this program; if not, write to the Free Software |
25 | * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. |
26 | */ |
27 | |
28 | #include <poppler-qt6.h> |
29 | #include <poppler-link-private.h> |
30 | #include <poppler-private.h> |
31 | #include <poppler-media.h> |
32 | |
33 | #include <QtCore/QStringList> |
34 | |
35 | #include "poppler-annotation-private.h" |
36 | |
37 | #include "Link.h" |
38 | #include "Rendition.h" |
39 | |
40 | namespace Poppler { |
41 | |
42 | class LinkDestinationPrivate : public QSharedData |
43 | { |
44 | public: |
45 | LinkDestinationPrivate(); |
46 | |
47 | LinkDestination::Kind kind; // destination type |
48 | QString name; |
49 | int pageNum; // page number |
50 | double left, bottom; // position |
51 | double right, top; |
52 | double zoom; // zoom factor |
53 | bool changeLeft : 1, changeTop : 1; // for destXYZ links, which position |
54 | bool changeZoom : 1; // components to change |
55 | }; |
56 | |
57 | LinkDestinationPrivate::LinkDestinationPrivate() |
58 | { |
59 | // sane defaults |
60 | kind = LinkDestination::destXYZ; |
61 | pageNum = 0; |
62 | left = 0; |
63 | bottom = 0; |
64 | right = 0; |
65 | top = 0; |
66 | zoom = 1; |
67 | changeLeft = true; |
68 | changeTop = true; |
69 | changeZoom = false; |
70 | } |
71 | |
72 | LinkPrivate::~LinkPrivate() = default; |
73 | |
74 | LinkOCGStatePrivate::~LinkOCGStatePrivate() = default; |
75 | |
76 | LinkHidePrivate::~LinkHidePrivate() = default; |
77 | |
78 | class LinkGotoPrivate : public LinkPrivate |
79 | { |
80 | public: |
81 | LinkGotoPrivate(const QRectF &area, const LinkDestination &dest); |
82 | ~LinkGotoPrivate() override; |
83 | |
84 | QString extFileName; |
85 | LinkDestination destination; |
86 | }; |
87 | |
88 | LinkGotoPrivate::LinkGotoPrivate(const QRectF &area, const LinkDestination &dest) : LinkPrivate(area), destination(dest) { } |
89 | |
90 | LinkGotoPrivate::~LinkGotoPrivate() = default; |
91 | |
92 | class LinkExecutePrivate : public LinkPrivate |
93 | { |
94 | public: |
95 | explicit LinkExecutePrivate(const QRectF &area); |
96 | ~LinkExecutePrivate() override; |
97 | |
98 | QString fileName; |
99 | QString parameters; |
100 | }; |
101 | |
102 | LinkExecutePrivate::LinkExecutePrivate(const QRectF &area) : LinkPrivate(area) { } |
103 | |
104 | LinkExecutePrivate::~LinkExecutePrivate() = default; |
105 | |
106 | class LinkBrowsePrivate : public LinkPrivate |
107 | { |
108 | public: |
109 | explicit LinkBrowsePrivate(const QRectF &area); |
110 | ~LinkBrowsePrivate() override; |
111 | |
112 | QString url; |
113 | }; |
114 | |
115 | LinkBrowsePrivate::LinkBrowsePrivate(const QRectF &area) : LinkPrivate(area) { } |
116 | |
117 | LinkBrowsePrivate::~LinkBrowsePrivate() = default; |
118 | |
119 | class LinkActionPrivate : public LinkPrivate |
120 | { |
121 | public: |
122 | explicit LinkActionPrivate(const QRectF &area); |
123 | ~LinkActionPrivate() override; |
124 | |
125 | LinkAction::ActionType type; |
126 | }; |
127 | |
128 | LinkActionPrivate::LinkActionPrivate(const QRectF &area) : LinkPrivate(area) { } |
129 | |
130 | LinkActionPrivate::~LinkActionPrivate() = default; |
131 | |
132 | class LinkSoundPrivate : public LinkPrivate |
133 | { |
134 | public: |
135 | explicit LinkSoundPrivate(const QRectF &area); |
136 | ~LinkSoundPrivate() override; |
137 | |
138 | double volume; |
139 | bool sync : 1; |
140 | bool repeat : 1; |
141 | bool mix : 1; |
142 | SoundObject *sound; |
143 | }; |
144 | |
145 | LinkSoundPrivate::LinkSoundPrivate(const QRectF &area) : LinkPrivate(area), sound(nullptr) { } |
146 | |
147 | LinkSoundPrivate::~LinkSoundPrivate() |
148 | { |
149 | delete sound; |
150 | } |
151 | |
152 | class LinkRenditionPrivate : public LinkPrivate |
153 | { |
154 | public: |
155 | LinkRenditionPrivate(const QRectF &area, ::MediaRendition *rendition, ::LinkRendition::RenditionOperation operation, const QString &script, const Ref ref); |
156 | ~LinkRenditionPrivate() override; |
157 | |
158 | MediaRendition *rendition; |
159 | LinkRendition::RenditionAction action; |
160 | QString script; |
161 | Ref annotationReference; |
162 | }; |
163 | |
164 | LinkRenditionPrivate::LinkRenditionPrivate(const QRectF &area, ::MediaRendition *r, ::LinkRendition::RenditionOperation operation, const QString &javaScript, const Ref ref) |
165 | : LinkPrivate(area), rendition(r ? new MediaRendition(r) : nullptr), action(LinkRendition::PlayRendition), script(javaScript), annotationReference(ref) |
166 | { |
167 | switch (operation) { |
168 | case ::LinkRendition::NoRendition: |
169 | action = LinkRendition::NoRendition; |
170 | break; |
171 | case ::LinkRendition::PlayRendition: |
172 | action = LinkRendition::PlayRendition; |
173 | break; |
174 | case ::LinkRendition::StopRendition: |
175 | action = LinkRendition::StopRendition; |
176 | break; |
177 | case ::LinkRendition::PauseRendition: |
178 | action = LinkRendition::PauseRendition; |
179 | break; |
180 | case ::LinkRendition::ResumeRendition: |
181 | action = LinkRendition::ResumeRendition; |
182 | break; |
183 | } |
184 | } |
185 | |
186 | LinkRenditionPrivate::~LinkRenditionPrivate() |
187 | { |
188 | delete rendition; |
189 | } |
190 | |
191 | class LinkJavaScriptPrivate : public LinkPrivate |
192 | { |
193 | public: |
194 | explicit LinkJavaScriptPrivate(const QRectF &area); |
195 | ~LinkJavaScriptPrivate() override; |
196 | |
197 | QString js; |
198 | }; |
199 | |
200 | LinkJavaScriptPrivate::LinkJavaScriptPrivate(const QRectF &area) : LinkPrivate(area) { } |
201 | |
202 | LinkJavaScriptPrivate::~LinkJavaScriptPrivate() = default; |
203 | |
204 | class LinkMoviePrivate : public LinkPrivate |
205 | { |
206 | public: |
207 | LinkMoviePrivate(const QRectF &area, LinkMovie::Operation operation, const QString &title, const Ref reference); |
208 | ~LinkMoviePrivate() override; |
209 | |
210 | LinkMovie::Operation operation; |
211 | QString annotationTitle; |
212 | Ref annotationReference; |
213 | }; |
214 | |
215 | LinkMoviePrivate::LinkMoviePrivate(const QRectF &area, LinkMovie::Operation _operation, const QString &title, const Ref reference) : LinkPrivate(area), operation(_operation), annotationTitle(title), annotationReference(reference) { } |
216 | |
217 | LinkMoviePrivate::~LinkMoviePrivate() = default; |
218 | |
219 | static void cvtUserToDev(::Page *page, double xu, double yu, int *xd, int *yd) |
220 | { |
221 | double ctm[6]; |
222 | |
223 | page->getDefaultCTM(ctm, hDPI: 72.0, vDPI: 72.0, rotate: 0, useMediaBox: false, upsideDown: true); |
224 | *xd = (int)(ctm[0] * xu + ctm[2] * yu + ctm[4] + 0.5); |
225 | *yd = (int)(ctm[1] * xu + ctm[3] * yu + ctm[5] + 0.5); |
226 | } |
227 | |
228 | LinkDestination::LinkDestination(const LinkDestinationData &data) : d(new LinkDestinationPrivate) |
229 | { |
230 | bool deleteDest = false; |
231 | const LinkDest *ld = data.ld; |
232 | |
233 | if (data.namedDest && !ld && !data.externalDest) { |
234 | deleteDest = true; |
235 | ld = data.doc->doc->findDest(name: data.namedDest).release(); |
236 | } |
237 | // in case this destination was named one, and it was not resolved |
238 | if (data.namedDest && !ld) { |
239 | d->name = QString::fromLatin1(ba: data.namedDest->c_str()); |
240 | } |
241 | |
242 | if (!ld) { |
243 | return; |
244 | } |
245 | |
246 | if (ld->getKind() == ::destXYZ) { |
247 | d->kind = destXYZ; |
248 | } else if (ld->getKind() == ::destFit) { |
249 | d->kind = destFit; |
250 | } else if (ld->getKind() == ::destFitH) { |
251 | d->kind = destFitH; |
252 | } else if (ld->getKind() == ::destFitV) { |
253 | d->kind = destFitV; |
254 | } else if (ld->getKind() == ::destFitR) { |
255 | d->kind = destFitR; |
256 | } else if (ld->getKind() == ::destFitB) { |
257 | d->kind = destFitB; |
258 | } else if (ld->getKind() == ::destFitBH) { |
259 | d->kind = destFitBH; |
260 | } else if (ld->getKind() == ::destFitBV) { |
261 | d->kind = destFitBV; |
262 | } |
263 | |
264 | if (!ld->isPageRef()) { |
265 | d->pageNum = ld->getPageNum(); |
266 | } else { |
267 | const Ref ref = ld->getPageRef(); |
268 | d->pageNum = data.doc->doc->findPage(ref); |
269 | } |
270 | double left = ld->getLeft(); |
271 | double bottom = ld->getBottom(); |
272 | double right = ld->getRight(); |
273 | double top = ld->getTop(); |
274 | d->zoom = ld->getZoom(); |
275 | d->changeLeft = ld->getChangeLeft(); |
276 | d->changeTop = ld->getChangeTop(); |
277 | d->changeZoom = ld->getChangeZoom(); |
278 | |
279 | int leftAux = 0, topAux = 0, rightAux = 0, bottomAux = 0; |
280 | |
281 | if (!data.externalDest) { |
282 | ::Page *page; |
283 | if (d->pageNum > 0 && d->pageNum <= data.doc->doc->getNumPages() && (page = data.doc->doc->getPage(page: d->pageNum))) { |
284 | cvtUserToDev(page, xu: left, yu: top, xd: &leftAux, yd: &topAux); |
285 | cvtUserToDev(page, xu: right, yu: bottom, xd: &rightAux, yd: &bottomAux); |
286 | |
287 | d->left = leftAux / (double)page->getCropWidth(); |
288 | d->top = topAux / (double)page->getCropHeight(); |
289 | d->right = rightAux / (double)page->getCropWidth(); |
290 | d->bottom = bottomAux / (double)page->getCropHeight(); |
291 | } else { |
292 | d->pageNum = 0; |
293 | } |
294 | } |
295 | |
296 | if (deleteDest) { |
297 | delete ld; |
298 | } |
299 | } |
300 | |
301 | LinkDestination::LinkDestination(const QString &description) : d(new LinkDestinationPrivate) |
302 | { |
303 | const QStringList tokens = description.split(sep: ';'); |
304 | if (tokens.size() >= 10) { |
305 | d->kind = static_cast<Kind>(tokens.at(i: 0).toInt()); |
306 | d->pageNum = tokens.at(i: 1).toInt(); |
307 | d->left = tokens.at(i: 2).toDouble(); |
308 | d->bottom = tokens.at(i: 3).toDouble(); |
309 | d->right = tokens.at(i: 4).toDouble(); |
310 | d->top = tokens.at(i: 5).toDouble(); |
311 | d->zoom = tokens.at(i: 6).toDouble(); |
312 | d->changeLeft = static_cast<bool>(tokens.at(i: 7).toInt()); |
313 | d->changeTop = static_cast<bool>(tokens.at(i: 8).toInt()); |
314 | d->changeZoom = static_cast<bool>(tokens.at(i: 9).toInt()); |
315 | } |
316 | } |
317 | |
318 | LinkDestination::LinkDestination(const LinkDestination &other) : d(other.d) { } |
319 | |
320 | LinkDestination::~LinkDestination() { } |
321 | |
322 | LinkDestination::Kind LinkDestination::kind() const |
323 | { |
324 | return d->kind; |
325 | } |
326 | |
327 | int LinkDestination::pageNumber() const |
328 | { |
329 | return d->pageNum; |
330 | } |
331 | |
332 | double LinkDestination::left() const |
333 | { |
334 | return d->left; |
335 | } |
336 | |
337 | double LinkDestination::bottom() const |
338 | { |
339 | return d->bottom; |
340 | } |
341 | |
342 | double LinkDestination::right() const |
343 | { |
344 | return d->right; |
345 | } |
346 | |
347 | double LinkDestination::top() const |
348 | { |
349 | return d->top; |
350 | } |
351 | |
352 | double LinkDestination::zoom() const |
353 | { |
354 | return d->zoom; |
355 | } |
356 | |
357 | bool LinkDestination::isChangeLeft() const |
358 | { |
359 | return d->changeLeft; |
360 | } |
361 | |
362 | bool LinkDestination::isChangeTop() const |
363 | { |
364 | return d->changeTop; |
365 | } |
366 | |
367 | bool LinkDestination::isChangeZoom() const |
368 | { |
369 | return d->changeZoom; |
370 | } |
371 | |
372 | QString LinkDestination::toString() const |
373 | { |
374 | QString s = QString::number((qint8)d->kind); |
375 | s += ";" + QString::number(d->pageNum); |
376 | s += ";" + QString::number(d->left); |
377 | s += ";" + QString::number(d->bottom); |
378 | s += ";" + QString::number(d->right); |
379 | s += ";" + QString::number(d->top); |
380 | s += ";" + QString::number(d->zoom); |
381 | s += ";" + QString::number((qint8)d->changeLeft); |
382 | s += ";" + QString::number((qint8)d->changeTop); |
383 | s += ";" + QString::number((qint8)d->changeZoom); |
384 | return s; |
385 | } |
386 | |
387 | QString LinkDestination::destinationName() const |
388 | { |
389 | return d->name; |
390 | } |
391 | |
392 | LinkDestination &LinkDestination::operator=(const LinkDestination &other) |
393 | { |
394 | if (this == &other) { |
395 | return *this; |
396 | } |
397 | |
398 | d = other.d; |
399 | return *this; |
400 | } |
401 | |
402 | // Link |
403 | Link::~Link() |
404 | { |
405 | delete d_ptr; |
406 | } |
407 | |
408 | Link::Link(const QRectF &linkArea) : d_ptr(new LinkPrivate(linkArea)) { } |
409 | |
410 | Link::Link(LinkPrivate &dd) : d_ptr(&dd) { } |
411 | |
412 | Link::LinkType Link::linkType() const |
413 | { |
414 | return None; |
415 | } |
416 | |
417 | QRectF Link::linkArea() const |
418 | { |
419 | Q_D(const Link); |
420 | return d->linkArea; |
421 | } |
422 | |
423 | QVector<Link *> Link::nextLinks() const |
424 | { |
425 | QVector<Link *> links(d_ptr->nextLinks.size()); |
426 | for (qsizetype i = 0; i < links.size(); i++) { |
427 | links[i] = d_ptr->nextLinks[i].get(); |
428 | } |
429 | |
430 | return links; |
431 | } |
432 | |
433 | // LinkGoto |
434 | LinkGoto::LinkGoto(const QRectF &linkArea, const QString &extFileName, const LinkDestination &destination) : Link(*new LinkGotoPrivate(linkArea, destination)) |
435 | { |
436 | Q_D(LinkGoto); |
437 | d->extFileName = extFileName; |
438 | } |
439 | |
440 | LinkGoto::~LinkGoto() { } |
441 | |
442 | bool LinkGoto::isExternal() const |
443 | { |
444 | Q_D(const LinkGoto); |
445 | return !d->extFileName.isEmpty(); |
446 | } |
447 | |
448 | QString LinkGoto::fileName() const |
449 | { |
450 | Q_D(const LinkGoto); |
451 | return d->extFileName; |
452 | } |
453 | |
454 | LinkDestination LinkGoto::destination() const |
455 | { |
456 | Q_D(const LinkGoto); |
457 | return d->destination; |
458 | } |
459 | |
460 | Link::LinkType LinkGoto::linkType() const |
461 | { |
462 | return Goto; |
463 | } |
464 | |
465 | // LinkExecute |
466 | LinkExecute::LinkExecute(const QRectF &linkArea, const QString &file, const QString ¶ms) : Link(*new LinkExecutePrivate(linkArea)) |
467 | { |
468 | Q_D(LinkExecute); |
469 | d->fileName = file; |
470 | d->parameters = params; |
471 | } |
472 | |
473 | LinkExecute::~LinkExecute() { } |
474 | |
475 | QString LinkExecute::fileName() const |
476 | { |
477 | Q_D(const LinkExecute); |
478 | return d->fileName; |
479 | } |
480 | QString LinkExecute::parameters() const |
481 | { |
482 | Q_D(const LinkExecute); |
483 | return d->parameters; |
484 | } |
485 | |
486 | Link::LinkType LinkExecute::linkType() const |
487 | { |
488 | return Execute; |
489 | } |
490 | |
491 | // LinkBrowse |
492 | LinkBrowse::LinkBrowse(const QRectF &linkArea, const QString &url) : Link(*new LinkBrowsePrivate(linkArea)) |
493 | { |
494 | Q_D(LinkBrowse); |
495 | d->url = url; |
496 | } |
497 | |
498 | LinkBrowse::~LinkBrowse() { } |
499 | |
500 | QString LinkBrowse::url() const |
501 | { |
502 | Q_D(const LinkBrowse); |
503 | return d->url; |
504 | } |
505 | |
506 | Link::LinkType LinkBrowse::linkType() const |
507 | { |
508 | return Browse; |
509 | } |
510 | |
511 | // LinkAction |
512 | LinkAction::LinkAction(const QRectF &linkArea, ActionType actionType) : Link(*new LinkActionPrivate(linkArea)) |
513 | { |
514 | Q_D(LinkAction); |
515 | d->type = actionType; |
516 | } |
517 | |
518 | LinkAction::~LinkAction() { } |
519 | |
520 | LinkAction::ActionType LinkAction::actionType() const |
521 | { |
522 | Q_D(const LinkAction); |
523 | return d->type; |
524 | } |
525 | |
526 | Link::LinkType LinkAction::linkType() const |
527 | { |
528 | return Action; |
529 | } |
530 | |
531 | // LinkSound |
532 | LinkSound::LinkSound(const QRectF &linkArea, double volume, bool sync, bool repeat, bool mix, SoundObject *sound) : Link(*new LinkSoundPrivate(linkArea)) |
533 | { |
534 | Q_D(LinkSound); |
535 | d->volume = volume; |
536 | d->sync = sync; |
537 | d->repeat = repeat; |
538 | d->mix = mix; |
539 | d->sound = sound; |
540 | } |
541 | |
542 | LinkSound::~LinkSound() { } |
543 | |
544 | Link::LinkType LinkSound::linkType() const |
545 | { |
546 | return Sound; |
547 | } |
548 | |
549 | double LinkSound::volume() const |
550 | { |
551 | Q_D(const LinkSound); |
552 | return d->volume; |
553 | } |
554 | |
555 | bool LinkSound::synchronous() const |
556 | { |
557 | Q_D(const LinkSound); |
558 | return d->sync; |
559 | } |
560 | |
561 | bool LinkSound::repeat() const |
562 | { |
563 | Q_D(const LinkSound); |
564 | return d->repeat; |
565 | } |
566 | |
567 | bool LinkSound::mix() const |
568 | { |
569 | Q_D(const LinkSound); |
570 | return d->mix; |
571 | } |
572 | |
573 | SoundObject *LinkSound::sound() const |
574 | { |
575 | Q_D(const LinkSound); |
576 | return d->sound; |
577 | } |
578 | |
579 | // LinkRendition |
580 | LinkRendition::LinkRendition(const QRectF &linkArea, ::MediaRendition *rendition, int operation, const QString &script, const Ref annotationReference) |
581 | : Link(*new LinkRenditionPrivate(linkArea, rendition, static_cast<enum ::LinkRendition::RenditionOperation>(operation), script, annotationReference)) |
582 | { |
583 | } |
584 | |
585 | LinkRendition::~LinkRendition() { } |
586 | |
587 | Link::LinkType LinkRendition::linkType() const |
588 | { |
589 | return Rendition; |
590 | } |
591 | |
592 | MediaRendition *LinkRendition::rendition() const |
593 | { |
594 | Q_D(const LinkRendition); |
595 | return d->rendition; |
596 | } |
597 | |
598 | LinkRendition::RenditionAction LinkRendition::action() const |
599 | { |
600 | Q_D(const LinkRendition); |
601 | return d->action; |
602 | } |
603 | |
604 | QString LinkRendition::script() const |
605 | { |
606 | Q_D(const LinkRendition); |
607 | return d->script; |
608 | } |
609 | |
610 | bool LinkRendition::isReferencedAnnotation(const ScreenAnnotation *annotation) const |
611 | { |
612 | Q_D(const LinkRendition); |
613 | if (d->annotationReference != Ref::INVALID() && d->annotationReference == annotation->d_ptr->pdfObjectReference()) { |
614 | return true; |
615 | } |
616 | |
617 | return false; |
618 | } |
619 | |
620 | // LinkJavaScript |
621 | LinkJavaScript::LinkJavaScript(const QRectF &linkArea, const QString &js) : Link(*new LinkJavaScriptPrivate(linkArea)) |
622 | { |
623 | Q_D(LinkJavaScript); |
624 | d->js = js; |
625 | } |
626 | |
627 | LinkJavaScript::~LinkJavaScript() { } |
628 | |
629 | Link::LinkType LinkJavaScript::linkType() const |
630 | { |
631 | return JavaScript; |
632 | } |
633 | |
634 | QString LinkJavaScript::script() const |
635 | { |
636 | Q_D(const LinkJavaScript); |
637 | return d->js; |
638 | } |
639 | |
640 | // LinkMovie |
641 | LinkMovie::LinkMovie(const QRectF &linkArea, Operation operation, const QString &annotationTitle, const Ref annotationReference) : Link(*new LinkMoviePrivate(linkArea, operation, annotationTitle, annotationReference)) { } |
642 | |
643 | LinkMovie::~LinkMovie() { } |
644 | |
645 | Link::LinkType LinkMovie::linkType() const |
646 | { |
647 | return Movie; |
648 | } |
649 | |
650 | LinkMovie::Operation LinkMovie::operation() const |
651 | { |
652 | Q_D(const LinkMovie); |
653 | return d->operation; |
654 | } |
655 | |
656 | bool LinkMovie::isReferencedAnnotation(const MovieAnnotation *annotation) const |
657 | { |
658 | Q_D(const LinkMovie); |
659 | if (d->annotationReference != Ref::INVALID() && d->annotationReference == annotation->d_ptr->pdfObjectReference()) { |
660 | return true; |
661 | } else if (!d->annotationTitle.isNull()) { |
662 | return (annotation->movieTitle() == d->annotationTitle); |
663 | } |
664 | |
665 | return false; |
666 | } |
667 | |
668 | LinkOCGState::LinkOCGState(LinkOCGStatePrivate *ocgp) : Link(*ocgp) { } |
669 | |
670 | LinkOCGState::~LinkOCGState() { } |
671 | |
672 | Link::LinkType LinkOCGState::linkType() const |
673 | { |
674 | return OCGState; |
675 | } |
676 | |
677 | // LinkHide |
678 | LinkHide::LinkHide(LinkHidePrivate *lhidep) : Link(*lhidep) { } |
679 | |
680 | LinkHide::~LinkHide() { } |
681 | |
682 | Link::LinkType LinkHide::linkType() const |
683 | { |
684 | return Hide; |
685 | } |
686 | |
687 | QVector<QString> LinkHide::targets() const |
688 | { |
689 | Q_D(const LinkHide); |
690 | return QVector<QString>() << d->targetName; |
691 | } |
692 | |
693 | bool LinkHide::isShowAction() const |
694 | { |
695 | Q_D(const LinkHide); |
696 | return d->isShow; |
697 | } |
698 | } |
699 | |