File indexing completed on 2024-05-12 16:06:45

0001 /*
0002     SPDX-FileCopyrightText: 2008 Pino Toscano <pino@kde.org>
0003     SPDX-FileCopyrightText: 2012 Guillermo A. Amaral B. <gamaral@kde.org>
0004 
0005     Work sponsored by the LiMux project of the city of Munich:
0006     SPDX-FileCopyrightText: 2017 Klarälvdalens Datakonsult AB a KDAB Group company <info@kdab.com>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #include "annots.h"
0012 
0013 // qt/kde includes
0014 #include <QFileInfo>
0015 #include <QLoggingCategory>
0016 #include <QVariant>
0017 
0018 #include <core/annotations.h>
0019 #include <core/area.h>
0020 
0021 #include "debug_pdf.h"
0022 #include "generator_pdf.h"
0023 #include "popplerembeddedfile.h"
0024 
0025 Q_DECLARE_METATYPE(Poppler::Annotation *)
0026 
0027 extern Okular::Sound *createSoundFromPopplerSound(const Poppler::SoundObject *popplerSound);
0028 extern Okular::Movie *createMovieFromPopplerMovie(const Poppler::MovieObject *popplerMovie);
0029 extern Okular::Movie *createMovieFromPopplerScreen(const Poppler::LinkRendition *popplerScreen);
0030 extern QPair<Okular::Movie *, Okular::EmbeddedFile *> createMovieFromPopplerRichMedia(const Poppler::RichMediaAnnotation *popplerRichMedia);
0031 
0032 static void disposeAnnotation(const Okular::Annotation *ann)
0033 {
0034     Poppler::Annotation *popplerAnn = qvariant_cast<Poppler::Annotation *>(ann->nativeId());
0035     delete popplerAnn;
0036 }
0037 
0038 static QPointF normPointToPointF(const Okular::NormalizedPoint &pt)
0039 {
0040     return QPointF(pt.x, pt.y);
0041 }
0042 
0043 static QRectF normRectToRectF(const Okular::NormalizedRect &rect)
0044 {
0045     return QRectF(QPointF(rect.left, rect.top), QPointF(rect.right, rect.bottom));
0046 }
0047 
0048 // Poppler and Okular share the same flag values, but we don't want to export internal flags
0049 static int maskExportedFlags(int flags)
0050 {
0051     return flags &
0052         (Okular::Annotation::Hidden | Okular::Annotation::FixedSize | Okular::Annotation::FixedRotation | Okular::Annotation::DenyPrint | Okular::Annotation::DenyWrite | Okular::Annotation::DenyDelete |
0053          Okular::Annotation::ToggleHidingOnMouse);
0054 }
0055 
0056 // BEGIN PopplerAnnotationProxy implementation
0057 PopplerAnnotationProxy::PopplerAnnotationProxy(Poppler::Document *doc, QMutex *userMutex, QHash<Okular::Annotation *, Poppler::Annotation *> *annotsOnOpenHash)
0058     : ppl_doc(doc)
0059     , mutex(userMutex)
0060     , annotationsOnOpenHash(annotsOnOpenHash)
0061 {
0062 }
0063 
0064 PopplerAnnotationProxy::~PopplerAnnotationProxy()
0065 {
0066 }
0067 
0068 bool PopplerAnnotationProxy::supports(Capability cap) const
0069 {
0070     switch (cap) {
0071     case Addition:
0072     case Modification:
0073     case Removal:
0074         return true;
0075     default:
0076         return false;
0077     }
0078 }
0079 
0080 static Poppler::TextAnnotation::TextType okularToPoppler(Okular::TextAnnotation::TextType ott)
0081 {
0082     switch (ott) {
0083     case Okular::TextAnnotation::Linked:
0084         return Poppler::TextAnnotation::Linked;
0085     case Okular::TextAnnotation::InPlace:
0086         return Poppler::TextAnnotation::InPlace;
0087     default:
0088         qWarning() << Q_FUNC_INFO << "unknown value" << ott;
0089     }
0090 
0091     return Poppler::TextAnnotation::Linked;
0092 }
0093 
0094 static Poppler::Annotation::LineEffect okularToPoppler(Okular::Annotation::LineEffect ole)
0095 {
0096     switch (ole) {
0097     case Okular::Annotation::NoEffect:
0098         return Poppler::Annotation::NoEffect;
0099     case Okular::Annotation::Cloudy:
0100         return Poppler::Annotation::Cloudy;
0101     default:
0102         qWarning() << Q_FUNC_INFO << "unknown value" << ole;
0103     }
0104 
0105     return Poppler::Annotation::NoEffect;
0106 }
0107 
0108 static Poppler::Annotation::LineStyle okularToPoppler(Okular::Annotation::LineStyle ols)
0109 {
0110     switch (ols) {
0111     case Okular::Annotation::Solid:
0112         return Poppler::Annotation::Solid;
0113     case Okular::Annotation::Dashed:
0114         return Poppler::Annotation::Dashed;
0115     case Okular::Annotation::Beveled:
0116         return Poppler::Annotation::Beveled;
0117     case Okular::Annotation::Inset:
0118         return Poppler::Annotation::Inset;
0119     case Okular::Annotation::Underline:
0120         return Poppler::Annotation::Underline;
0121     default:
0122         qWarning() << Q_FUNC_INFO << "unknown value" << ols;
0123     }
0124 
0125     return Poppler::Annotation::Solid;
0126 }
0127 
0128 static Poppler::TextAnnotation::InplaceIntent okularToPoppler(Okular::TextAnnotation::InplaceIntent oii)
0129 {
0130     switch (oii) {
0131     case Okular::TextAnnotation::Unknown:
0132         return Poppler::TextAnnotation::Unknown;
0133     case Okular::TextAnnotation::Callout:
0134         return Poppler::TextAnnotation::Callout;
0135     case Okular::TextAnnotation::TypeWriter:
0136         return Poppler::TextAnnotation::TypeWriter;
0137     default:
0138         qWarning() << Q_FUNC_INFO << "unknown value" << oii;
0139     }
0140 
0141     return Poppler::TextAnnotation::Unknown;
0142 }
0143 
0144 static Poppler::LineAnnotation::TermStyle okularToPoppler(Okular::LineAnnotation::TermStyle ots)
0145 {
0146     switch (ots) {
0147     case Okular::LineAnnotation::Square:
0148         return Poppler::LineAnnotation::Square;
0149     case Okular::LineAnnotation::Circle:
0150         return Poppler::LineAnnotation::Circle;
0151     case Okular::LineAnnotation::Diamond:
0152         return Poppler::LineAnnotation::Diamond;
0153     case Okular::LineAnnotation::OpenArrow:
0154         return Poppler::LineAnnotation::OpenArrow;
0155     case Okular::LineAnnotation::ClosedArrow:
0156         return Poppler::LineAnnotation::ClosedArrow;
0157     case Okular::LineAnnotation::None:
0158         return Poppler::LineAnnotation::None;
0159     case Okular::LineAnnotation::Butt:
0160         return Poppler::LineAnnotation::Butt;
0161     case Okular::LineAnnotation::ROpenArrow:
0162         return Poppler::LineAnnotation::ROpenArrow;
0163     case Okular::LineAnnotation::RClosedArrow:
0164         return Poppler::LineAnnotation::RClosedArrow;
0165     case Okular::LineAnnotation::Slash:
0166         return Poppler::LineAnnotation::Slash;
0167     default:
0168         qWarning() << Q_FUNC_INFO << "unknown value" << ots;
0169     }
0170 
0171     return Poppler::LineAnnotation::None;
0172 }
0173 
0174 static Poppler::LineAnnotation::LineIntent okularToPoppler(Okular::LineAnnotation::LineIntent oli)
0175 {
0176     switch (oli) {
0177     case Okular::LineAnnotation::Unknown:
0178         return Poppler::LineAnnotation::Unknown;
0179     case Okular::LineAnnotation::Arrow:
0180         return Poppler::LineAnnotation::Arrow;
0181     case Okular::LineAnnotation::Dimension:
0182         return Poppler::LineAnnotation::Dimension;
0183     case Okular::LineAnnotation::PolygonCloud:
0184         return Poppler::LineAnnotation::PolygonCloud;
0185     default:
0186         qWarning() << Q_FUNC_INFO << "unknown value" << oli;
0187     }
0188 
0189     return Poppler::LineAnnotation::Unknown;
0190 }
0191 
0192 static Poppler::GeomAnnotation::GeomType okularToPoppler(Okular::GeomAnnotation::GeomType ogt)
0193 {
0194     switch (ogt) {
0195     case Okular::GeomAnnotation::InscribedSquare:
0196         return Poppler::GeomAnnotation::InscribedSquare;
0197     case Okular::GeomAnnotation::InscribedCircle:
0198         return Poppler::GeomAnnotation::InscribedCircle;
0199     default:
0200         qWarning() << Q_FUNC_INFO << "unknown value" << ogt;
0201     }
0202 
0203     return Poppler::GeomAnnotation::InscribedSquare;
0204 }
0205 
0206 static Poppler::HighlightAnnotation::HighlightType okularToPoppler(Okular::HighlightAnnotation::HighlightType oht)
0207 {
0208     switch (oht) {
0209     case Okular::HighlightAnnotation::Highlight:
0210         return Poppler::HighlightAnnotation::Highlight;
0211     case Okular::HighlightAnnotation::Squiggly:
0212         return Poppler::HighlightAnnotation::Squiggly;
0213     case Okular::HighlightAnnotation::Underline:
0214         return Poppler::HighlightAnnotation::Underline;
0215     case Okular::HighlightAnnotation::StrikeOut:
0216         return Poppler::HighlightAnnotation::StrikeOut;
0217     default:
0218         qWarning() << Q_FUNC_INFO << "unknown value" << oht;
0219     }
0220 
0221     return Poppler::HighlightAnnotation::Highlight;
0222 }
0223 
0224 static Poppler::CaretAnnotation::CaretSymbol okularToPoppler(Okular::CaretAnnotation::CaretSymbol ocs)
0225 {
0226     switch (ocs) {
0227     case Okular::CaretAnnotation::None:
0228         return Poppler::CaretAnnotation::None;
0229     case Okular::CaretAnnotation::P:
0230         return Poppler::CaretAnnotation::P;
0231     default:
0232         qWarning() << Q_FUNC_INFO << "unknown value" << ocs;
0233     }
0234 
0235     return Poppler::CaretAnnotation::None;
0236 }
0237 
0238 static Poppler::Annotation::Style okularToPoppler(const Okular::Annotation::Style &oStyle)
0239 {
0240     Poppler::Annotation::Style pStyle;
0241     pStyle.setColor(oStyle.color());
0242     pStyle.setOpacity(oStyle.opacity());
0243     pStyle.setLineEffect(okularToPoppler(oStyle.lineEffect()));
0244     pStyle.setEffectIntensity(oStyle.effectIntensity());
0245     pStyle.setWidth(oStyle.width());
0246     pStyle.setLineStyle(okularToPoppler(oStyle.lineStyle()));
0247     pStyle.setXCorners(oStyle.xCorners());
0248     pStyle.setYCorners(oStyle.yCorners());
0249 
0250     return pStyle;
0251 }
0252 
0253 static Poppler::Annotation::Popup okularToPoppler(const Okular::Annotation::Window &oWindow)
0254 {
0255     Poppler::Annotation::Popup pWindow;
0256     pWindow.setGeometry(QRectF(oWindow.topLeft().x, oWindow.topLeft().y, oWindow.width(), oWindow.height()));
0257     // flags being ints is super fragile, should be enums on both ends, but Poppler::Annotation::setPopup is a noop so it's not like it matters
0258     pWindow.setFlags(oWindow.flags());
0259     pWindow.setTitle(oWindow.title());
0260     pWindow.setSummary(oWindow.summary());
0261 
0262     return pWindow;
0263 }
0264 
0265 static void setSharedAnnotationPropertiesToPopplerAnnotation(const Okular::Annotation *okularAnnotation, Poppler::Annotation *popplerAnnotation)
0266 {
0267     popplerAnnotation->setAuthor(okularAnnotation->author());
0268     popplerAnnotation->setContents(okularAnnotation->contents());
0269     popplerAnnotation->setUniqueName(okularAnnotation->uniqueName());
0270 
0271     // Note: flags and boundary must be set first in order to correctly handle
0272     // FixedRotation annotations.
0273     popplerAnnotation->setFlags(static_cast<Poppler::Annotation::Flags>(maskExportedFlags(okularAnnotation->flags())));
0274     popplerAnnotation->setBoundary(normRectToRectF(okularAnnotation->boundingRectangle()));
0275 
0276     popplerAnnotation->setStyle(okularToPoppler(okularAnnotation->style()));
0277     popplerAnnotation->setPopup(okularToPoppler(okularAnnotation->window()));
0278 
0279     popplerAnnotation->setCreationDate(okularAnnotation->creationDate());
0280     popplerAnnotation->setModificationDate(okularAnnotation->modificationDate());
0281 }
0282 
0283 static void setPopplerStampAnnotationCustomImage(const Poppler::Page *page, Poppler::StampAnnotation *pStampAnnotation, const Okular::StampAnnotation *oStampAnnotation)
0284 {
0285     const QSize size = page->pageSize();
0286     const QRect rect = Okular::AnnotationUtils::annotationGeometry(oStampAnnotation, size.width(), size.height());
0287 
0288     QImage image = Okular::AnnotationUtils::loadStamp(oStampAnnotation->stampIconName(), qMax(rect.width(), rect.height())).toImage();
0289 
0290     if (!image.isNull()) {
0291         pStampAnnotation->setStampCustomImage(image);
0292     }
0293 }
0294 
0295 static void updatePopplerAnnotationFromOkularAnnotation(const Okular::TextAnnotation *oTextAnnotation, Poppler::TextAnnotation *pTextAnnotation)
0296 {
0297     pTextAnnotation->setTextIcon(oTextAnnotation->textIcon());
0298     pTextAnnotation->setTextFont(oTextAnnotation->textFont());
0299     pTextAnnotation->setTextColor(oTextAnnotation->textColor());
0300     pTextAnnotation->setInplaceAlign(static_cast<Poppler::TextAnnotation::InplaceAlignPosition>(oTextAnnotation->inplaceAlignment()));
0301     pTextAnnotation->setInplaceIntent(okularToPoppler(oTextAnnotation->inplaceIntent()));
0302     pTextAnnotation->setCalloutPoints(QVector<QPointF>());
0303 }
0304 
0305 static void updatePopplerAnnotationFromOkularAnnotation(const Okular::LineAnnotation *oLineAnnotation, Poppler::LineAnnotation *pLineAnnotation)
0306 {
0307     QVector<QPointF> points;
0308     const QList<Okular::NormalizedPoint> annotPoints = oLineAnnotation->linePoints();
0309     for (const Okular::NormalizedPoint &p : annotPoints) {
0310         points.append(normPointToPointF(p));
0311     }
0312     pLineAnnotation->setLinePoints(points);
0313     pLineAnnotation->setLineStartStyle(okularToPoppler(oLineAnnotation->lineStartStyle()));
0314     pLineAnnotation->setLineEndStyle(okularToPoppler(oLineAnnotation->lineEndStyle()));
0315     pLineAnnotation->setLineClosed(oLineAnnotation->lineClosed());
0316     pLineAnnotation->setLineInnerColor(oLineAnnotation->lineInnerColor());
0317     pLineAnnotation->setLineLeadingForwardPoint(oLineAnnotation->lineLeadingForwardPoint());
0318     pLineAnnotation->setLineLeadingBackPoint(oLineAnnotation->lineLeadingBackwardPoint());
0319     pLineAnnotation->setLineShowCaption(oLineAnnotation->showCaption());
0320     pLineAnnotation->setLineIntent(okularToPoppler(oLineAnnotation->lineIntent()));
0321 }
0322 
0323 static void updatePopplerAnnotationFromOkularAnnotation(const Okular::GeomAnnotation *oGeomAnnotation, Poppler::GeomAnnotation *pGeomAnnotation)
0324 {
0325     pGeomAnnotation->setGeomType(okularToPoppler(oGeomAnnotation->geometricalType()));
0326     pGeomAnnotation->setGeomInnerColor(oGeomAnnotation->geometricalInnerColor());
0327 }
0328 
0329 static void updatePopplerAnnotationFromOkularAnnotation(const Okular::HighlightAnnotation *oHighlightAnnotation, Poppler::HighlightAnnotation *pHighlightAnnotation)
0330 {
0331     pHighlightAnnotation->setHighlightType(okularToPoppler(oHighlightAnnotation->highlightType()));
0332 
0333     const QList<Okular::HighlightAnnotation::Quad> &oQuads = oHighlightAnnotation->highlightQuads();
0334     QList<Poppler::HighlightAnnotation::Quad> pQuads;
0335     for (const Okular::HighlightAnnotation::Quad &oQuad : oQuads) {
0336         Poppler::HighlightAnnotation::Quad pQuad;
0337         pQuad.points[0] = normPointToPointF(oQuad.point(3));
0338         pQuad.points[1] = normPointToPointF(oQuad.point(2));
0339         pQuad.points[2] = normPointToPointF(oQuad.point(1));
0340         pQuad.points[3] = normPointToPointF(oQuad.point(0));
0341         pQuad.capStart = oQuad.capStart();
0342         pQuad.capEnd = oQuad.capEnd();
0343         pQuad.feather = oQuad.feather();
0344         pQuads << pQuad;
0345     }
0346     pHighlightAnnotation->setHighlightQuads(pQuads);
0347 }
0348 
0349 static void updatePopplerAnnotationFromOkularAnnotation(const Okular::StampAnnotation *oStampAnnotation, Poppler::StampAnnotation *pStampAnnotation, const Poppler::Page *page)
0350 {
0351     setPopplerStampAnnotationCustomImage(page, pStampAnnotation, oStampAnnotation);
0352 }
0353 
0354 static void updatePopplerAnnotationFromOkularAnnotation(const Okular::InkAnnotation *oInkAnnotation, Poppler::InkAnnotation *pInkAnnotation)
0355 {
0356     QList<QVector<QPointF>> paths;
0357     const QList<QList<Okular::NormalizedPoint>> inkPathsList = oInkAnnotation->inkPaths();
0358     for (const QList<Okular::NormalizedPoint> &path : inkPathsList) {
0359         QVector<QPointF> points;
0360         for (const Okular::NormalizedPoint &p : path) {
0361             points.append(normPointToPointF(p));
0362         }
0363         paths.append(points);
0364     }
0365     pInkAnnotation->setInkPaths(paths);
0366 }
0367 
0368 static void updatePopplerAnnotationFromOkularAnnotation(const Okular::CaretAnnotation *oCaretAnnotation, Poppler::CaretAnnotation *pCaretAnnotation)
0369 {
0370     pCaretAnnotation->setCaretSymbol(okularToPoppler(oCaretAnnotation->caretSymbol()));
0371 }
0372 
0373 static Poppler::Annotation *createPopplerAnnotationFromOkularAnnotation(const Okular::TextAnnotation *oTextAnnotation)
0374 {
0375     Poppler::TextAnnotation *pTextAnnotation = new Poppler::TextAnnotation(okularToPoppler(oTextAnnotation->textType()));
0376 
0377     setSharedAnnotationPropertiesToPopplerAnnotation(oTextAnnotation, pTextAnnotation);
0378     updatePopplerAnnotationFromOkularAnnotation(oTextAnnotation, pTextAnnotation);
0379 
0380     return pTextAnnotation;
0381 }
0382 
0383 static Poppler::Annotation *createPopplerAnnotationFromOkularAnnotation(const Okular::LineAnnotation *oLineAnnotation)
0384 {
0385     const auto points = oLineAnnotation->linePoints();
0386     Poppler::LineAnnotation *pLineAnnotation = new Poppler::LineAnnotation(points.size() == 2 ? Poppler::LineAnnotation::StraightLine : Poppler::LineAnnotation::Polyline);
0387 
0388     setSharedAnnotationPropertiesToPopplerAnnotation(oLineAnnotation, pLineAnnotation);
0389     updatePopplerAnnotationFromOkularAnnotation(oLineAnnotation, pLineAnnotation);
0390 
0391     return pLineAnnotation;
0392 }
0393 
0394 static Poppler::Annotation *createPopplerAnnotationFromOkularAnnotation(const Okular::GeomAnnotation *oGeomAnnotation)
0395 {
0396     Poppler::GeomAnnotation *pGeomAnnotation = new Poppler::GeomAnnotation();
0397 
0398     setSharedAnnotationPropertiesToPopplerAnnotation(oGeomAnnotation, pGeomAnnotation);
0399     updatePopplerAnnotationFromOkularAnnotation(oGeomAnnotation, pGeomAnnotation);
0400 
0401     return pGeomAnnotation;
0402 }
0403 
0404 static Poppler::Annotation *createPopplerAnnotationFromOkularAnnotation(const Okular::HighlightAnnotation *oHighlightAnnotation)
0405 {
0406     Poppler::HighlightAnnotation *pHighlightAnnotation = new Poppler::HighlightAnnotation();
0407 
0408     setSharedAnnotationPropertiesToPopplerAnnotation(oHighlightAnnotation, pHighlightAnnotation);
0409     updatePopplerAnnotationFromOkularAnnotation(oHighlightAnnotation, pHighlightAnnotation);
0410 
0411     return pHighlightAnnotation;
0412 }
0413 
0414 static Poppler::Annotation *createPopplerAnnotationFromOkularAnnotation(const Okular::StampAnnotation *oStampAnnotation, Poppler::Page *page)
0415 {
0416     Poppler::StampAnnotation *pStampAnnotation = new Poppler::StampAnnotation();
0417 
0418     setSharedAnnotationPropertiesToPopplerAnnotation(oStampAnnotation, pStampAnnotation);
0419     updatePopplerAnnotationFromOkularAnnotation(oStampAnnotation, pStampAnnotation, page);
0420 
0421     return pStampAnnotation;
0422 }
0423 
0424 static Poppler::Annotation *createPopplerAnnotationFromOkularAnnotation(const Okular::InkAnnotation *oInkAnnotation)
0425 {
0426     Poppler::InkAnnotation *pInkAnnotation = new Poppler::InkAnnotation();
0427 
0428     setSharedAnnotationPropertiesToPopplerAnnotation(oInkAnnotation, pInkAnnotation);
0429     updatePopplerAnnotationFromOkularAnnotation(oInkAnnotation, pInkAnnotation);
0430 
0431     return pInkAnnotation;
0432 }
0433 
0434 static Poppler::Annotation *createPopplerAnnotationFromOkularAnnotation(const Okular::CaretAnnotation *oCaretAnnotation)
0435 {
0436     Poppler::CaretAnnotation *pCaretAnnotation = new Poppler::CaretAnnotation();
0437 
0438     setSharedAnnotationPropertiesToPopplerAnnotation(oCaretAnnotation, pCaretAnnotation);
0439     updatePopplerAnnotationFromOkularAnnotation(oCaretAnnotation, pCaretAnnotation);
0440 
0441     return pCaretAnnotation;
0442 }
0443 void PopplerAnnotationProxy::notifyAddition(Okular::Annotation *okl_ann, int page)
0444 {
0445     QMutexLocker ml(mutex);
0446 
0447     std::unique_ptr<Poppler::Page> ppl_page = ppl_doc->page(page);
0448 
0449     // Create poppler annotation
0450     Poppler::Annotation *ppl_ann = nullptr;
0451     switch (okl_ann->subType()) {
0452     case Okular::Annotation::AText:
0453         ppl_ann = createPopplerAnnotationFromOkularAnnotation(static_cast<Okular::TextAnnotation *>(okl_ann));
0454         break;
0455     case Okular::Annotation::ALine:
0456         ppl_ann = createPopplerAnnotationFromOkularAnnotation(static_cast<Okular::LineAnnotation *>(okl_ann));
0457         break;
0458     case Okular::Annotation::AGeom:
0459         ppl_ann = createPopplerAnnotationFromOkularAnnotation(static_cast<Okular::GeomAnnotation *>(okl_ann));
0460         break;
0461     case Okular::Annotation::AHighlight:
0462         ppl_ann = createPopplerAnnotationFromOkularAnnotation(static_cast<Okular::HighlightAnnotation *>(okl_ann));
0463         break;
0464     case Okular::Annotation::AStamp: {
0465         bool wasDenyWriteEnabled = okl_ann->flags() & Okular::Annotation::DenyWrite;
0466 
0467         if (wasDenyWriteEnabled) {
0468             okl_ann->setFlags(okl_ann->flags() & ~Okular::Annotation::DenyWrite);
0469         }
0470 
0471         ppl_ann = createPopplerAnnotationFromOkularAnnotation(static_cast<Okular::StampAnnotation *>(okl_ann), ppl_page.get());
0472         if (deletedStampsAnnotationAppearance.find(static_cast<Okular::StampAnnotation *>(okl_ann)) != deletedStampsAnnotationAppearance.end()) {
0473             ppl_ann->setAnnotationAppearance(*deletedStampsAnnotationAppearance[static_cast<Okular::StampAnnotation *>(okl_ann)].get());
0474             deletedStampsAnnotationAppearance.erase(static_cast<Okular::StampAnnotation *>(okl_ann));
0475 
0476             if (wasDenyWriteEnabled) {
0477                 okl_ann->setFlags(okl_ann->flags() | Okular::Annotation::DenyWrite);
0478             }
0479         }
0480     } break;
0481     case Okular::Annotation::AInk:
0482         ppl_ann = createPopplerAnnotationFromOkularAnnotation(static_cast<Okular::InkAnnotation *>(okl_ann));
0483         break;
0484     case Okular::Annotation::ACaret:
0485         ppl_ann = createPopplerAnnotationFromOkularAnnotation(static_cast<Okular::CaretAnnotation *>(okl_ann));
0486         break;
0487     default:
0488         qWarning() << "Unsupported annotation type" << okl_ann->subType();
0489         return;
0490     }
0491 
0492     okl_ann->setFlags(okl_ann->flags() | Okular::Annotation::ExternallyDrawn);
0493 
0494     // Bind poppler object to page
0495     ppl_page->addAnnotation(ppl_ann);
0496 
0497     // Set pointer to poppler annotation as native Id
0498     okl_ann->setNativeId(QVariant::fromValue(ppl_ann));
0499     okl_ann->setDisposeDataFunction(disposeAnnotation);
0500 
0501     qCDebug(OkularPdfDebug) << okl_ann->uniqueName();
0502 }
0503 
0504 void PopplerAnnotationProxy::notifyModification(const Okular::Annotation *okl_ann, int page, bool appearanceChanged)
0505 {
0506     Q_UNUSED(page);
0507     Q_UNUSED(appearanceChanged);
0508 
0509     Poppler::Annotation *ppl_ann = qvariant_cast<Poppler::Annotation *>(okl_ann->nativeId());
0510 
0511     if (!ppl_ann) { // Ignore non-native annotations
0512         return;
0513     }
0514 
0515     QMutexLocker ml(mutex);
0516 
0517     if (okl_ann->flags() & (Okular::Annotation::BeingMoved | Okular::Annotation::BeingResized)) {
0518         // Okular ui already renders the annotation on its own
0519         ppl_ann->setFlags(Poppler::Annotation::Hidden);
0520         return;
0521     }
0522 
0523     // Set basic properties
0524     // Note: flags and boundary must be set first in order to correctly handle
0525     // FixedRotation annotations.
0526     ppl_ann->setFlags(static_cast<Poppler::Annotation::Flags>(maskExportedFlags(okl_ann->flags())));
0527     ppl_ann->setBoundary(normRectToRectF(okl_ann->boundingRectangle()));
0528 
0529     ppl_ann->setAuthor(okl_ann->author());
0530     ppl_ann->setContents(okl_ann->contents());
0531 
0532     ppl_ann->setStyle(okularToPoppler(okl_ann->style()));
0533 
0534     // Set type-specific properties (if any)
0535     switch (ppl_ann->subType()) {
0536     case Poppler::Annotation::AText: {
0537         const Okular::TextAnnotation *okl_txtann = static_cast<const Okular::TextAnnotation *>(okl_ann);
0538         Poppler::TextAnnotation *ppl_txtann = static_cast<Poppler::TextAnnotation *>(ppl_ann);
0539         updatePopplerAnnotationFromOkularAnnotation(okl_txtann, ppl_txtann);
0540         break;
0541     }
0542     case Poppler::Annotation::ALine: {
0543         const Okular::LineAnnotation *okl_lineann = static_cast<const Okular::LineAnnotation *>(okl_ann);
0544         Poppler::LineAnnotation *ppl_lineann = static_cast<Poppler::LineAnnotation *>(ppl_ann);
0545         updatePopplerAnnotationFromOkularAnnotation(okl_lineann, ppl_lineann);
0546         break;
0547     }
0548     case Poppler::Annotation::AGeom: {
0549         const Okular::GeomAnnotation *okl_geomann = static_cast<const Okular::GeomAnnotation *>(okl_ann);
0550         Poppler::GeomAnnotation *ppl_geomann = static_cast<Poppler::GeomAnnotation *>(ppl_ann);
0551         updatePopplerAnnotationFromOkularAnnotation(okl_geomann, ppl_geomann);
0552         break;
0553     }
0554     case Poppler::Annotation::AHighlight: {
0555         const Okular::HighlightAnnotation *okl_hlann = static_cast<const Okular::HighlightAnnotation *>(okl_ann);
0556         Poppler::HighlightAnnotation *ppl_hlann = static_cast<Poppler::HighlightAnnotation *>(ppl_ann);
0557         updatePopplerAnnotationFromOkularAnnotation(okl_hlann, ppl_hlann);
0558         break;
0559     }
0560     case Poppler::Annotation::AStamp: {
0561         const Okular::StampAnnotation *okl_stampann = static_cast<const Okular::StampAnnotation *>(okl_ann);
0562         Poppler::StampAnnotation *ppl_stampann = static_cast<Poppler::StampAnnotation *>(ppl_ann);
0563         std::unique_ptr<Poppler::Page> ppl_page = ppl_doc->page(page);
0564         updatePopplerAnnotationFromOkularAnnotation(okl_stampann, ppl_stampann, ppl_page.get());
0565         break;
0566     }
0567     case Poppler::Annotation::AInk: {
0568         const Okular::InkAnnotation *okl_inkann = static_cast<const Okular::InkAnnotation *>(okl_ann);
0569         Poppler::InkAnnotation *ppl_inkann = static_cast<Poppler::InkAnnotation *>(ppl_ann);
0570         updatePopplerAnnotationFromOkularAnnotation(okl_inkann, ppl_inkann);
0571         break;
0572     }
0573     default:
0574         qCDebug(OkularPdfDebug) << "Type-specific property modification is not implemented for this annotation type";
0575         break;
0576     }
0577 
0578     qCDebug(OkularPdfDebug) << okl_ann->uniqueName();
0579 }
0580 
0581 void PopplerAnnotationProxy::notifyRemoval(Okular::Annotation *okl_ann, int page)
0582 {
0583     Poppler::Annotation *ppl_ann = qvariant_cast<Poppler::Annotation *>(okl_ann->nativeId());
0584 
0585     if (!ppl_ann) { // Ignore non-native annotations
0586         return;
0587     }
0588 
0589     QMutexLocker ml(mutex);
0590 
0591     std::unique_ptr<Poppler::Page> ppl_page = ppl_doc->page(page);
0592     annotationsOnOpenHash->remove(okl_ann);
0593     if (okl_ann->subType() == Okular::Annotation::AStamp) {
0594         deletedStampsAnnotationAppearance[static_cast<Okular::StampAnnotation *>(okl_ann)] = ppl_ann->annotationAppearance();
0595     }
0596     ppl_page->removeAnnotation(ppl_ann); // Also destroys ppl_ann
0597 
0598     okl_ann->setNativeId(QVariant::fromValue(0)); // So that we don't double-free in disposeAnnotation
0599 
0600     qCDebug(OkularPdfDebug) << okl_ann->uniqueName();
0601 }
0602 // END PopplerAnnotationProxy implementation
0603 
0604 static Okular::Annotation::LineStyle popplerToOkular(Poppler::Annotation::LineStyle s)
0605 {
0606     switch (s) {
0607     case Poppler::Annotation::Solid:
0608         return Okular::Annotation::Solid;
0609     case Poppler::Annotation::Dashed:
0610         return Okular::Annotation::Dashed;
0611     case Poppler::Annotation::Beveled:
0612         return Okular::Annotation::Beveled;
0613     case Poppler::Annotation::Inset:
0614         return Okular::Annotation::Inset;
0615     case Poppler::Annotation::Underline:
0616         return Okular::Annotation::Underline;
0617     default:
0618         qWarning() << Q_FUNC_INFO << "unknown value" << s;
0619     }
0620 
0621     return Okular::Annotation::Solid;
0622 }
0623 
0624 static Okular::Annotation::LineEffect popplerToOkular(Poppler::Annotation::LineEffect e)
0625 {
0626     switch (e) {
0627     case Poppler::Annotation::NoEffect:
0628         return Okular::Annotation::NoEffect;
0629     case Poppler::Annotation::Cloudy:
0630         return Okular::Annotation::Cloudy;
0631     default:
0632         qWarning() << Q_FUNC_INFO << "unknown value" << e;
0633     }
0634 
0635     return Okular::Annotation::NoEffect;
0636 }
0637 
0638 static Okular::Annotation::RevisionScope popplerToOkular(Poppler::Annotation::RevScope s)
0639 {
0640     switch (s) {
0641     case Poppler::Annotation::Root:
0642         Q_UNREACHABLE();
0643     case Poppler::Annotation::Reply:
0644         return Okular::Annotation::Reply;
0645     case Poppler::Annotation::Group:
0646         return Okular::Annotation::Group;
0647     case Poppler::Annotation::Delete:
0648         return Okular::Annotation::Delete;
0649     default:
0650         qWarning() << Q_FUNC_INFO << "unknown value" << s;
0651     }
0652 
0653     return Okular::Annotation::Reply;
0654 }
0655 
0656 static Okular::Annotation::RevisionType popplerToOkular(Poppler::Annotation::RevType t)
0657 {
0658     switch (t) {
0659     case Poppler::Annotation::None:
0660         return Okular::Annotation::None;
0661     case Poppler::Annotation::Marked:
0662         return Okular::Annotation::Marked;
0663     case Poppler::Annotation::Unmarked:
0664         return Okular::Annotation::Unmarked;
0665     case Poppler::Annotation::Accepted:
0666         return Okular::Annotation::Accepted;
0667     case Poppler::Annotation::Rejected:
0668         return Okular::Annotation::Rejected;
0669     case Poppler::Annotation::Cancelled:
0670         return Okular::Annotation::Cancelled;
0671     case Poppler::Annotation::Completed:
0672         return Okular::Annotation::Completed;
0673     default:
0674         qWarning() << Q_FUNC_INFO << "unknown value" << t;
0675     }
0676 
0677     return Okular::Annotation::None;
0678 }
0679 
0680 static Okular::TextAnnotation::TextType popplerToOkular(Poppler::TextAnnotation::TextType ptt)
0681 {
0682     switch (ptt) {
0683     case Poppler::TextAnnotation::Linked:
0684         return Okular::TextAnnotation::Linked;
0685     case Poppler::TextAnnotation::InPlace:
0686         return Okular::TextAnnotation::InPlace;
0687     default:
0688         qWarning() << Q_FUNC_INFO << "unknown value" << ptt;
0689     }
0690 
0691     return Okular::TextAnnotation::Linked;
0692 }
0693 
0694 static Okular::TextAnnotation::InplaceIntent popplerToOkular(Poppler::TextAnnotation::InplaceIntent pii)
0695 {
0696     switch (pii) {
0697     case Poppler::TextAnnotation::Unknown:
0698         return Okular::TextAnnotation::Unknown;
0699     case Poppler::TextAnnotation::Callout:
0700         return Okular::TextAnnotation::Callout;
0701     case Poppler::TextAnnotation::TypeWriter:
0702         return Okular::TextAnnotation::TypeWriter;
0703     default:
0704         qWarning() << Q_FUNC_INFO << "unknown value" << pii;
0705     }
0706 
0707     return Okular::TextAnnotation::Unknown;
0708 }
0709 
0710 static Okular::LineAnnotation::TermStyle popplerToOkular(Poppler::LineAnnotation::TermStyle pts)
0711 {
0712     switch (pts) {
0713     case Poppler::LineAnnotation::Square:
0714         return Okular::LineAnnotation::Square;
0715     case Poppler::LineAnnotation::Circle:
0716         return Okular::LineAnnotation::Circle;
0717     case Poppler::LineAnnotation::Diamond:
0718         return Okular::LineAnnotation::Diamond;
0719     case Poppler::LineAnnotation::OpenArrow:
0720         return Okular::LineAnnotation::OpenArrow;
0721     case Poppler::LineAnnotation::ClosedArrow:
0722         return Okular::LineAnnotation::ClosedArrow;
0723     case Poppler::LineAnnotation::None:
0724         return Okular::LineAnnotation::None;
0725     case Poppler::LineAnnotation::Butt:
0726         return Okular::LineAnnotation::Butt;
0727     case Poppler::LineAnnotation::ROpenArrow:
0728         return Okular::LineAnnotation::ROpenArrow;
0729     case Poppler::LineAnnotation::RClosedArrow:
0730         return Okular::LineAnnotation::RClosedArrow;
0731     case Poppler::LineAnnotation::Slash:
0732         return Okular::LineAnnotation::Slash;
0733     default:
0734         qWarning() << Q_FUNC_INFO << "unknown value" << pts;
0735     }
0736 
0737     return Okular::LineAnnotation::None;
0738 }
0739 
0740 static Okular::LineAnnotation::LineIntent popplerToOkular(Poppler::LineAnnotation::LineIntent pli)
0741 {
0742     switch (pli) {
0743     case Poppler::LineAnnotation::Unknown:
0744         return Okular::LineAnnotation::Unknown;
0745     case Poppler::LineAnnotation::Arrow:
0746         return Okular::LineAnnotation::Arrow;
0747     case Poppler::LineAnnotation::Dimension:
0748         return Okular::LineAnnotation::Dimension;
0749     case Poppler::LineAnnotation::PolygonCloud:
0750         return Okular::LineAnnotation::PolygonCloud;
0751     default:
0752         qWarning() << Q_FUNC_INFO << "unknown value" << pli;
0753     }
0754 
0755     return Okular::LineAnnotation::Unknown;
0756 }
0757 
0758 static Okular::GeomAnnotation::GeomType popplerToOkular(Poppler::GeomAnnotation::GeomType pgt)
0759 {
0760     switch (pgt) {
0761     case Poppler::GeomAnnotation::InscribedSquare:
0762         return Okular::GeomAnnotation::InscribedSquare;
0763     case Poppler::GeomAnnotation::InscribedCircle:
0764         return Okular::GeomAnnotation::InscribedCircle;
0765     default:
0766         qWarning() << Q_FUNC_INFO << "unknown value" << pgt;
0767     }
0768 
0769     return Okular::GeomAnnotation::InscribedSquare;
0770 }
0771 
0772 static Okular::HighlightAnnotation::HighlightType popplerToOkular(Poppler::HighlightAnnotation::HighlightType pht)
0773 {
0774     switch (pht) {
0775     case Poppler::HighlightAnnotation::Highlight:
0776         return Okular::HighlightAnnotation::Highlight;
0777     case Poppler::HighlightAnnotation::Squiggly:
0778         return Okular::HighlightAnnotation::Squiggly;
0779     case Poppler::HighlightAnnotation::Underline:
0780         return Okular::HighlightAnnotation::Underline;
0781     case Poppler::HighlightAnnotation::StrikeOut:
0782         return Okular::HighlightAnnotation::StrikeOut;
0783     default:
0784         qWarning() << Q_FUNC_INFO << "unknown value" << pht;
0785     }
0786 
0787     return Okular::HighlightAnnotation::Highlight;
0788 }
0789 
0790 static Okular::CaretAnnotation::CaretSymbol popplerToOkular(Poppler::CaretAnnotation::CaretSymbol pcs)
0791 {
0792     switch (pcs) {
0793     case Poppler::CaretAnnotation::None:
0794         return Okular::CaretAnnotation::None;
0795     case Poppler::CaretAnnotation::P:
0796         return Okular::CaretAnnotation::P;
0797     default:
0798         qWarning() << Q_FUNC_INFO << "unknown value" << pcs;
0799     }
0800 
0801     return Okular::CaretAnnotation::None;
0802 }
0803 
0804 static Okular::Annotation *createAnnotationFromPopplerAnnotation(Poppler::TextAnnotation *popplerAnnotation)
0805 {
0806     Okular::TextAnnotation *oTextAnn = new Okular::TextAnnotation();
0807 
0808     oTextAnn->setTextType(popplerToOkular(popplerAnnotation->textType()));
0809     oTextAnn->setTextIcon(popplerAnnotation->textIcon());
0810     oTextAnn->setTextFont(popplerAnnotation->textFont());
0811     oTextAnn->setTextColor(popplerAnnotation->textColor());
0812     // this works because we use the same 0:left, 1:center, 2:right meaning both in poppler and okular
0813     oTextAnn->setInplaceAlignment(popplerAnnotation->inplaceAlign());
0814     oTextAnn->setInplaceIntent(popplerToOkular(popplerAnnotation->inplaceIntent()));
0815     for (int i = 0; i < 3; ++i) {
0816         const QPointF p = popplerAnnotation->calloutPoint(i);
0817         oTextAnn->setInplaceCallout({p.x(), p.y()}, i);
0818     }
0819 
0820     return oTextAnn;
0821 }
0822 
0823 static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::LineAnnotation *popplerAnnotation)
0824 {
0825     Okular::LineAnnotation *oLineAnn = new Okular::LineAnnotation();
0826 
0827     oLineAnn->setLineStartStyle(popplerToOkular(popplerAnnotation->lineStartStyle()));
0828     oLineAnn->setLineEndStyle(popplerToOkular(popplerAnnotation->lineEndStyle()));
0829     oLineAnn->setLineClosed(popplerAnnotation->isLineClosed());
0830     oLineAnn->setLineInnerColor(popplerAnnotation->lineInnerColor());
0831     oLineAnn->setLineLeadingForwardPoint(popplerAnnotation->lineLeadingForwardPoint());
0832     oLineAnn->setLineLeadingBackwardPoint(popplerAnnotation->lineLeadingBackPoint());
0833     oLineAnn->setShowCaption(popplerAnnotation->lineShowCaption());
0834     oLineAnn->setLineIntent(popplerToOkular(popplerAnnotation->lineIntent()));
0835 
0836     QList<Okular::NormalizedPoint> points;
0837     const QVector<QPointF> popplerPoints = popplerAnnotation->linePoints();
0838     for (const QPointF &p : popplerPoints) {
0839         points << Okular::NormalizedPoint(p.x(), p.y());
0840     }
0841     oLineAnn->setLinePoints(points);
0842 
0843     return oLineAnn;
0844 }
0845 
0846 static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::GeomAnnotation *popplerAnnotation)
0847 {
0848     Okular::GeomAnnotation *oGeomAnn = new Okular::GeomAnnotation();
0849 
0850     oGeomAnn->setGeometricalType(popplerToOkular(popplerAnnotation->geomType()));
0851     oGeomAnn->setGeometricalInnerColor(popplerAnnotation->geomInnerColor());
0852 
0853     return oGeomAnn;
0854 }
0855 
0856 static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::HighlightAnnotation *popplerAnnotation)
0857 {
0858     Okular::HighlightAnnotation *oHighlightAnn = new Okular::HighlightAnnotation();
0859 
0860     oHighlightAnn->setHighlightType(popplerToOkular(popplerAnnotation->highlightType()));
0861 
0862     const QList<Poppler::HighlightAnnotation::Quad> popplerHq = popplerAnnotation->highlightQuads();
0863     QList<Okular::HighlightAnnotation::Quad> &okularHq = oHighlightAnn->highlightQuads();
0864 
0865     for (const Poppler::HighlightAnnotation::Quad &popplerQ : popplerHq) {
0866         Okular::HighlightAnnotation::Quad q;
0867 
0868         // Poppler stores highlight points in swapped order
0869         q.setPoint(Okular::NormalizedPoint(popplerQ.points[0].x(), popplerQ.points[0].y()), 3);
0870         q.setPoint(Okular::NormalizedPoint(popplerQ.points[1].x(), popplerQ.points[1].y()), 2);
0871         q.setPoint(Okular::NormalizedPoint(popplerQ.points[2].x(), popplerQ.points[2].y()), 1);
0872         q.setPoint(Okular::NormalizedPoint(popplerQ.points[3].x(), popplerQ.points[3].y()), 0);
0873 
0874         q.setCapStart(popplerQ.capStart);
0875         q.setCapEnd(popplerQ.capEnd);
0876         q.setFeather(popplerQ.feather);
0877         okularHq << q;
0878     }
0879 
0880     return oHighlightAnn;
0881 }
0882 
0883 static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::InkAnnotation *popplerAnnotation)
0884 {
0885     Okular::InkAnnotation *oInkAnn = new Okular::InkAnnotation();
0886 
0887     const QList<QVector<QPointF>> popplerInkPaths = popplerAnnotation->inkPaths();
0888     QList<QList<Okular::NormalizedPoint>> okularInkPaths;
0889     for (const QVector<QPointF> &popplerInkPath : popplerInkPaths) {
0890         QList<Okular::NormalizedPoint> okularInkPath;
0891         for (const QPointF &popplerPoint : popplerInkPath) {
0892             okularInkPath << Okular::NormalizedPoint(popplerPoint.x(), popplerPoint.y());
0893         }
0894         okularInkPaths << okularInkPath;
0895     }
0896 
0897     oInkAnn->setInkPaths(okularInkPaths);
0898 
0899     return oInkAnn;
0900 }
0901 
0902 static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::CaretAnnotation *popplerAnnotation)
0903 {
0904     Okular::CaretAnnotation *oCaretAnn = new Okular::CaretAnnotation();
0905 
0906     oCaretAnn->setCaretSymbol(popplerToOkular(popplerAnnotation->caretSymbol()));
0907 
0908     return oCaretAnn;
0909 }
0910 
0911 static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::StampAnnotation *popplerAnnotation)
0912 {
0913     Okular::StampAnnotation *oStampAnn = new Okular::StampAnnotation();
0914 
0915     oStampAnn->setStampIconName(popplerAnnotation->stampIconName());
0916 
0917     return oStampAnn;
0918 }
0919 
0920 Okular::Annotation *createAnnotationFromPopplerAnnotation(Poppler::Annotation *popplerAnnotation, const Poppler::Page &popplerPage, bool *doDelete)
0921 {
0922     Okular::Annotation *okularAnnotation = nullptr;
0923     *doDelete = true;
0924     bool tieToOkularAnn = false;
0925     bool externallyDrawn = false;
0926     switch (popplerAnnotation->subType()) {
0927     case Poppler::Annotation::AFileAttachment: {
0928         Poppler::FileAttachmentAnnotation *attachann = static_cast<Poppler::FileAttachmentAnnotation *>(popplerAnnotation);
0929         Okular::FileAttachmentAnnotation *f = new Okular::FileAttachmentAnnotation();
0930         okularAnnotation = f;
0931         tieToOkularAnn = true;
0932         *doDelete = false;
0933 
0934         f->setFileIconName(attachann->fileIconName());
0935         f->setEmbeddedFile(new PDFEmbeddedFile(attachann->embeddedFile()));
0936 
0937         break;
0938     }
0939     case Poppler::Annotation::ASound: {
0940         Poppler::SoundAnnotation *soundann = static_cast<Poppler::SoundAnnotation *>(popplerAnnotation);
0941         Okular::SoundAnnotation *s = new Okular::SoundAnnotation();
0942         okularAnnotation = s;
0943 
0944         s->setSoundIconName(soundann->soundIconName());
0945         s->setSound(createSoundFromPopplerSound(soundann->sound()));
0946 
0947         break;
0948     }
0949     case Poppler::Annotation::AMovie: {
0950         Poppler::MovieAnnotation *movieann = static_cast<Poppler::MovieAnnotation *>(popplerAnnotation);
0951         Okular::MovieAnnotation *m = new Okular::MovieAnnotation();
0952         okularAnnotation = m;
0953         tieToOkularAnn = true;
0954         *doDelete = false;
0955 
0956         m->setMovie(createMovieFromPopplerMovie(movieann->movie()));
0957 
0958         break;
0959     }
0960     case Poppler::Annotation::AWidget: {
0961         okularAnnotation = new Okular::WidgetAnnotation();
0962         break;
0963     }
0964     case Poppler::Annotation::AScreen: {
0965         Okular::ScreenAnnotation *m = new Okular::ScreenAnnotation();
0966         okularAnnotation = m;
0967         tieToOkularAnn = true;
0968         *doDelete = false;
0969         break;
0970     }
0971     case Poppler::Annotation::ARichMedia: {
0972         Poppler::RichMediaAnnotation *richmediaann = static_cast<Poppler::RichMediaAnnotation *>(popplerAnnotation);
0973         const QPair<Okular::Movie *, Okular::EmbeddedFile *> result = createMovieFromPopplerRichMedia(richmediaann);
0974 
0975         if (result.first) {
0976             Okular::RichMediaAnnotation *r = new Okular::RichMediaAnnotation();
0977             tieToOkularAnn = true;
0978             *doDelete = false;
0979             okularAnnotation = r;
0980 
0981             r->setMovie(result.first);
0982             r->setEmbeddedFile(result.second);
0983         }
0984 
0985         break;
0986     }
0987     case Poppler::Annotation::AText: {
0988         externallyDrawn = true;
0989         tieToOkularAnn = true;
0990         *doDelete = false;
0991         okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast<Poppler::TextAnnotation *>(popplerAnnotation));
0992         break;
0993     }
0994     case Poppler::Annotation::ALine: {
0995         externallyDrawn = true;
0996         tieToOkularAnn = true;
0997         *doDelete = false;
0998         okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast<Poppler::LineAnnotation *>(popplerAnnotation));
0999         break;
1000     }
1001     case Poppler::Annotation::AGeom: {
1002         externallyDrawn = true;
1003         tieToOkularAnn = true;
1004         *doDelete = false;
1005         okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast<Poppler::GeomAnnotation *>(popplerAnnotation));
1006         break;
1007     }
1008     case Poppler::Annotation::AHighlight: {
1009         externallyDrawn = true;
1010         tieToOkularAnn = true;
1011         *doDelete = false;
1012         okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast<Poppler::HighlightAnnotation *>(popplerAnnotation));
1013         break;
1014     }
1015     case Poppler::Annotation::AInk: {
1016         externallyDrawn = true;
1017         tieToOkularAnn = true;
1018         *doDelete = false;
1019         okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast<Poppler::InkAnnotation *>(popplerAnnotation));
1020         break;
1021     }
1022     case Poppler::Annotation::ACaret: {
1023         externallyDrawn = true;
1024         tieToOkularAnn = true;
1025         *doDelete = false;
1026         okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast<Poppler::CaretAnnotation *>(popplerAnnotation));
1027         break;
1028     }
1029     case Poppler::Annotation::AStamp:
1030         externallyDrawn = true;
1031         tieToOkularAnn = true;
1032         *doDelete = false;
1033         okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast<Poppler::StampAnnotation *>(popplerAnnotation));
1034         break;
1035     default: {
1036         break;
1037     }
1038     }
1039     if (okularAnnotation) {
1040         // the Contents field might have lines separated by \r
1041         QString contents = popplerAnnotation->contents();
1042         contents.replace(QLatin1Char('\r'), QLatin1Char('\n'));
1043 
1044         okularAnnotation->setAuthor(popplerAnnotation->author());
1045         okularAnnotation->setContents(contents);
1046         okularAnnotation->setUniqueName(popplerAnnotation->uniqueName());
1047         okularAnnotation->setModificationDate(popplerAnnotation->modificationDate());
1048         okularAnnotation->setCreationDate(popplerAnnotation->creationDate());
1049         okularAnnotation->setFlags(popplerAnnotation->flags() | Okular::Annotation::External);
1050         okularAnnotation->setBoundingRectangle(Okular::NormalizedRect::fromQRectF(popplerAnnotation->boundary()));
1051 
1052         if (externallyDrawn) {
1053             okularAnnotation->setFlags(okularAnnotation->flags() | Okular::Annotation::ExternallyDrawn);
1054         }
1055         if (okularAnnotation->subType() == Okular::Annotation::SubType::AStamp) {
1056             Okular::StampAnnotation *oStampAnn = static_cast<Okular::StampAnnotation *>(okularAnnotation);
1057             Poppler::StampAnnotation *pStampAnn = static_cast<Poppler::StampAnnotation *>(popplerAnnotation);
1058             QFileInfo stampIconFile {oStampAnn->stampIconName()};
1059             if (stampIconFile.exists() && stampIconFile.isFile()) {
1060                 setPopplerStampAnnotationCustomImage(&popplerPage, pStampAnn, oStampAnn);
1061             }
1062 
1063             oStampAnn->setFlags(okularAnnotation->flags() | Okular::Annotation::Flag::DenyWrite);
1064         }
1065 
1066         // Convert the poppler annotation style to Okular annotation style
1067         Okular::Annotation::Style &okularStyle = okularAnnotation->style();
1068         const Poppler::Annotation::Style popplerStyle = popplerAnnotation->style();
1069         okularStyle.setColor(popplerStyle.color());
1070         okularStyle.setOpacity(popplerStyle.opacity());
1071         okularStyle.setWidth(popplerStyle.width());
1072         okularStyle.setLineStyle(popplerToOkular(popplerStyle.lineStyle()));
1073         okularStyle.setXCorners(popplerStyle.xCorners());
1074         okularStyle.setYCorners(popplerStyle.yCorners());
1075         const QVector<double> &dashArray = popplerStyle.dashArray();
1076         if (dashArray.size() > 0) {
1077             okularStyle.setMarks(dashArray[0]);
1078         }
1079         if (dashArray.size() > 1) {
1080             okularStyle.setSpaces(dashArray[1]);
1081         }
1082         okularStyle.setLineEffect(popplerToOkular(popplerStyle.lineEffect()));
1083         okularStyle.setEffectIntensity(popplerStyle.effectIntensity());
1084 
1085         // Convert the poppler annotation popup to Okular annotation window
1086         Okular::Annotation::Window &okularWindow = okularAnnotation->window();
1087         const Poppler::Annotation::Popup popplerPopup = popplerAnnotation->popup();
1088         // This assumes that both "flags" int mean the same, but since we don't use the flags in okular anywhere it's not really that important
1089         okularWindow.setFlags(popplerPopup.flags());
1090         const QRectF popplerGeometry = popplerPopup.geometry();
1091         const QSize popplerPageSize = popplerPage.pageSize();
1092         okularWindow.setTopLeft(Okular::NormalizedPoint(popplerGeometry.top(), popplerGeometry.left(), popplerPageSize.width(), popplerPageSize.height()));
1093         okularWindow.setWidth(popplerGeometry.width());
1094         okularWindow.setHeight(popplerGeometry.height());
1095         okularWindow.setTitle(popplerPopup.title());
1096         okularWindow.setSummary(popplerPopup.summary());
1097 
1098         // Convert the poppler revisions to Okular revisions
1099         QList<Okular::Annotation::Revision> &okularRevisions = okularAnnotation->revisions();
1100         std::vector<std::unique_ptr<Poppler::Annotation>> popplerRevisions = popplerAnnotation->revisions();
1101         for (auto &popplerRevision : popplerRevisions) {
1102             bool deletePopplerRevision;
1103             Okular::Annotation::Revision okularRevision;
1104             okularRevision.setAnnotation(createAnnotationFromPopplerAnnotation(popplerRevision.get(), popplerPage, &deletePopplerRevision));
1105             okularRevision.setScope(popplerToOkular(popplerRevision->revisionScope()));
1106             okularRevision.setType(popplerToOkular(popplerRevision->revisionType()));
1107             okularRevisions << okularRevision;
1108 
1109             if (!deletePopplerRevision) {
1110                 (void)popplerRevision.release(); //
1111             }
1112         }
1113 
1114         if (tieToOkularAnn) {
1115             okularAnnotation->setNativeId(QVariant::fromValue(popplerAnnotation));
1116             okularAnnotation->setDisposeDataFunction(disposeAnnotation);
1117         }
1118     }
1119     return okularAnnotation;
1120 }