/*************************************************************************** * Copyright (C) 2008 by Pino Toscano * * Copyright (C) 2012 by Guillermo A. Amaral B. * * Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group * * company, info@kdab.com. Work sponsored by the * * LiMux project of the city of Munich * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * ***************************************************************************/ #include "annots.h" // qt/kde includes #include #include #include #include #include "debug_pdf.h" #include "generator_pdf.h" #include "popplerembeddedfile.h" Q_DECLARE_METATYPE(Poppler::Annotation *) extern Okular::Sound *createSoundFromPopplerSound(const Poppler::SoundObject *popplerSound); extern Okular::Movie *createMovieFromPopplerMovie(const Poppler::MovieObject *popplerMovie); extern Okular::Movie *createMovieFromPopplerScreen(const Poppler::LinkRendition *popplerScreen); extern QPair createMovieFromPopplerRichMedia(const Poppler::RichMediaAnnotation *popplerRichMedia); static void disposeAnnotation(const Okular::Annotation *ann) { Poppler::Annotation *popplerAnn = qvariant_cast(ann->nativeId()); delete popplerAnn; } static QPointF normPointToPointF(const Okular::NormalizedPoint &pt) { return QPointF(pt.x, pt.y); } static QRectF normRectToRectF(const Okular::NormalizedRect &rect) { return QRectF(QPointF(rect.left, rect.top), QPointF(rect.right, rect.bottom)); } // Poppler and Okular share the same flag values, but we don't want to export internal flags static int maskExportedFlags(int flags) { return flags & (Okular::Annotation::Hidden | Okular::Annotation::FixedSize | Okular::Annotation::FixedRotation | Okular::Annotation::DenyPrint | Okular::Annotation::DenyWrite | Okular::Annotation::DenyDelete | Okular::Annotation::ToggleHidingOnMouse); } // BEGIN PopplerAnnotationProxy implementation PopplerAnnotationProxy::PopplerAnnotationProxy(Poppler::Document *doc, QMutex *userMutex, QHash *annotsOnOpenHash) : ppl_doc(doc) , mutex(userMutex) , annotationsOnOpenHash(annotsOnOpenHash) { } PopplerAnnotationProxy::~PopplerAnnotationProxy() { } bool PopplerAnnotationProxy::supports(Capability cap) const { switch (cap) { case Addition: case Modification: case Removal: return true; default: return false; } } void PopplerAnnotationProxy::notifyAddition(Okular::Annotation *okl_ann, int page) { // Export annotation to DOM QDomDocument doc; QDomElement dom_ann = doc.createElement(QStringLiteral("root")); Okular::AnnotationUtils::storeAnnotation(okl_ann, dom_ann, doc); QMutexLocker ml(mutex); // Create poppler annotation Poppler::Annotation *ppl_ann = Poppler::AnnotationUtils::createAnnotation(dom_ann); // Poppler doesn't render StampAnnotations yet if (ppl_ann->subType() != Poppler::Annotation::AStamp) okl_ann->setFlags(okl_ann->flags() | Okular::Annotation::ExternallyDrawn); // Poppler stores highlight points in swapped order if (ppl_ann->subType() == Poppler::Annotation::AHighlight) { Poppler::HighlightAnnotation *hlann = static_cast(ppl_ann); QList quads = hlann->highlightQuads(); QMutableListIterator it(quads); while (it.hasNext()) { Poppler::HighlightAnnotation::Quad &q = it.next(); QPointF t; t = q.points[3]; q.points[3] = q.points[0]; q.points[0] = t; t = q.points[2]; q.points[2] = q.points[1]; q.points[1] = t; } hlann->setHighlightQuads(quads); } // Bind poppler object to page Poppler::Page *ppl_page = ppl_doc->page(page); ppl_page->addAnnotation(ppl_ann); delete ppl_page; // Set pointer to poppler annotation as native Id okl_ann->setNativeId(QVariant::fromValue(ppl_ann)); okl_ann->setDisposeDataFunction(disposeAnnotation); qCDebug(OkularPdfDebug) << okl_ann->uniqueName(); } void PopplerAnnotationProxy::notifyModification(const Okular::Annotation *okl_ann, int page, bool appearanceChanged) { Q_UNUSED(page); Q_UNUSED(appearanceChanged); Poppler::Annotation *ppl_ann = qvariant_cast(okl_ann->nativeId()); if (!ppl_ann) // Ignore non-native annotations return; QMutexLocker ml(mutex); if (okl_ann->flags() & (Okular::Annotation::BeingMoved | Okular::Annotation::BeingResized)) { // Okular ui already renders the annotation on its own ppl_ann->setFlags(Poppler::Annotation::Hidden); return; } // Set basic properties // Note: flags and boundary must be set first in order to correctly handle // FixedRotation annotations. ppl_ann->setFlags(maskExportedFlags(okl_ann->flags())); ppl_ann->setBoundary(normRectToRectF(okl_ann->boundingRectangle())); ppl_ann->setAuthor(okl_ann->author()); ppl_ann->setContents(okl_ann->contents()); // Set style Poppler::Annotation::Style s; s.setColor(okl_ann->style().color()); s.setWidth(okl_ann->style().width()); s.setOpacity(okl_ann->style().opacity()); ppl_ann->setStyle(s); // Set type-specific properties (if any) switch (ppl_ann->subType()) { case Poppler::Annotation::AText: { const Okular::TextAnnotation *okl_txtann = static_cast(okl_ann); Poppler::TextAnnotation *ppl_txtann = static_cast(ppl_ann); ppl_txtann->setTextIcon(okl_txtann->textIcon()); ppl_txtann->setTextFont(okl_txtann->textFont()); ppl_txtann->setTextColor(okl_txtann->textColor()); ppl_txtann->setInplaceAlign(okl_txtann->inplaceAlignment()); ppl_txtann->setCalloutPoints(QVector()); ppl_txtann->setInplaceIntent((Poppler::TextAnnotation::InplaceIntent)okl_txtann->inplaceIntent()); break; } case Poppler::Annotation::ALine: { const Okular::LineAnnotation *okl_lineann = static_cast(okl_ann); Poppler::LineAnnotation *ppl_lineann = static_cast(ppl_ann); QLinkedList points; const QLinkedList annotPoints = okl_lineann->linePoints(); for (const Okular::NormalizedPoint &p : annotPoints) { points.append(normPointToPointF(p)); } ppl_lineann->setLinePoints(points); ppl_lineann->setLineStartStyle((Poppler::LineAnnotation::TermStyle)okl_lineann->lineStartStyle()); ppl_lineann->setLineEndStyle((Poppler::LineAnnotation::TermStyle)okl_lineann->lineEndStyle()); ppl_lineann->setLineClosed(okl_lineann->lineClosed()); ppl_lineann->setLineInnerColor(okl_lineann->lineInnerColor()); ppl_lineann->setLineLeadingForwardPoint(okl_lineann->lineLeadingForwardPoint()); ppl_lineann->setLineLeadingBackPoint(okl_lineann->lineLeadingBackwardPoint()); ppl_lineann->setLineShowCaption(okl_lineann->showCaption()); ppl_lineann->setLineIntent((Poppler::LineAnnotation::LineIntent)okl_lineann->lineIntent()); break; } case Poppler::Annotation::AGeom: { const Okular::GeomAnnotation *okl_geomann = static_cast(okl_ann); Poppler::GeomAnnotation *ppl_geomann = static_cast(ppl_ann); ppl_geomann->setGeomType((Poppler::GeomAnnotation::GeomType)okl_geomann->geometricalType()); ppl_geomann->setGeomInnerColor(okl_geomann->geometricalInnerColor()); break; } case Poppler::Annotation::AHighlight: { const Okular::HighlightAnnotation *okl_hlann = static_cast(okl_ann); Poppler::HighlightAnnotation *ppl_hlann = static_cast(ppl_ann); ppl_hlann->setHighlightType((Poppler::HighlightAnnotation::HighlightType)okl_hlann->highlightType()); break; } case Poppler::Annotation::AStamp: { const Okular::StampAnnotation *okl_stampann = static_cast(okl_ann); Poppler::StampAnnotation *ppl_stampann = static_cast(ppl_ann); ppl_stampann->setStampIconName(okl_stampann->stampIconName()); break; } case Poppler::Annotation::AInk: { const Okular::InkAnnotation *okl_inkann = static_cast(okl_ann); Poppler::InkAnnotation *ppl_inkann = static_cast(ppl_ann); QList> paths; const QList> inkPathsList = okl_inkann->inkPaths(); for (const QLinkedList &path : inkPathsList) { QLinkedList points; for (const Okular::NormalizedPoint &p : path) { points.append(normPointToPointF(p)); } paths.append(points); } ppl_inkann->setInkPaths(paths); break; } default: qCDebug(OkularPdfDebug) << "Type-specific property modification is not implemented for this annotation type"; break; } qCDebug(OkularPdfDebug) << okl_ann->uniqueName(); } void PopplerAnnotationProxy::notifyRemoval(Okular::Annotation *okl_ann, int page) { Poppler::Annotation *ppl_ann = qvariant_cast(okl_ann->nativeId()); if (!ppl_ann) // Ignore non-native annotations return; QMutexLocker ml(mutex); Poppler::Page *ppl_page = ppl_doc->page(page); annotationsOnOpenHash->remove(okl_ann); ppl_page->removeAnnotation(ppl_ann); // Also destroys ppl_ann delete ppl_page; okl_ann->setNativeId(QVariant::fromValue(0)); // So that we don't double-free in disposeAnnotation qCDebug(OkularPdfDebug) << okl_ann->uniqueName(); } // END PopplerAnnotationProxy implementation static Okular::Annotation::LineStyle popplerToOkular(Poppler::Annotation::LineStyle s) { switch (s) { case Poppler::Annotation::Solid: return Okular::Annotation::Solid; case Poppler::Annotation::Dashed: return Okular::Annotation::Dashed; case Poppler::Annotation::Beveled: return Okular::Annotation::Beveled; case Poppler::Annotation::Inset: return Okular::Annotation::Inset; case Poppler::Annotation::Underline: return Okular::Annotation::Underline; default: qWarning() << Q_FUNC_INFO << "unknown value" << s; } return Okular::Annotation::Solid; } static Okular::Annotation::LineEffect popplerToOkular(Poppler::Annotation::LineEffect e) { switch (e) { case Poppler::Annotation::NoEffect: return Okular::Annotation::NoEffect; case Poppler::Annotation::Cloudy: return Okular::Annotation::Cloudy; default: qWarning() << Q_FUNC_INFO << "unknown value" << e; } return Okular::Annotation::NoEffect; } static Okular::Annotation::RevisionScope popplerToOkular(Poppler::Annotation::RevScope s) { switch (s) { case Poppler::Annotation::Root: Q_UNREACHABLE(); case Poppler::Annotation::Reply: return Okular::Annotation::Reply; case Poppler::Annotation::Group: return Okular::Annotation::Group; case Poppler::Annotation::Delete: return Okular::Annotation::Delete; default: qWarning() << Q_FUNC_INFO << "unknown value" << s; } return Okular::Annotation::Reply; } static Okular::Annotation::RevisionType popplerToOkular(Poppler::Annotation::RevType t) { switch (t) { case Poppler::Annotation::None: return Okular::Annotation::None; case Poppler::Annotation::Marked: return Okular::Annotation::Marked; case Poppler::Annotation::Unmarked: return Okular::Annotation::Unmarked; case Poppler::Annotation::Accepted: return Okular::Annotation::Accepted; case Poppler::Annotation::Rejected: return Okular::Annotation::Rejected; case Poppler::Annotation::Cancelled: return Okular::Annotation::Cancelled; case Poppler::Annotation::Completed: return Okular::Annotation::Completed; default: qWarning() << Q_FUNC_INFO << "unknown value" << t; } return Okular::Annotation::None; } static Okular::TextAnnotation::TextType popplerToOkular(Poppler::TextAnnotation::TextType ptt) { switch (ptt) { case Poppler::TextAnnotation::Linked: return Okular::TextAnnotation::Linked; case Poppler::TextAnnotation::InPlace: return Okular::TextAnnotation::Linked; default: qWarning() << Q_FUNC_INFO << "unknown value" << ptt; } return Okular::TextAnnotation::Linked; } static Okular::TextAnnotation::InplaceIntent popplerToOkular(Poppler::TextAnnotation::InplaceIntent pii) { switch (pii) { case Poppler::TextAnnotation::Unknown: return Okular::TextAnnotation::Unknown; case Poppler::TextAnnotation::Callout: return Okular::TextAnnotation::Callout; case Poppler::TextAnnotation::TypeWriter: return Okular::TextAnnotation::TypeWriter; default: qWarning() << Q_FUNC_INFO << "unknown value" << pii; } return Okular::TextAnnotation::Unknown; } static Okular::LineAnnotation::TermStyle popplerToOkular(Poppler::LineAnnotation::TermStyle pts) { switch (pts) { case Poppler::LineAnnotation::Square: return Okular::LineAnnotation::Square; case Poppler::LineAnnotation::Circle: return Okular::LineAnnotation::Circle; case Poppler::LineAnnotation::Diamond: return Okular::LineAnnotation::Diamond; case Poppler::LineAnnotation::OpenArrow: return Okular::LineAnnotation::OpenArrow; case Poppler::LineAnnotation::ClosedArrow: return Okular::LineAnnotation::ClosedArrow; case Poppler::LineAnnotation::None: return Okular::LineAnnotation::None; case Poppler::LineAnnotation::Butt: return Okular::LineAnnotation::Butt; case Poppler::LineAnnotation::ROpenArrow: return Okular::LineAnnotation::ROpenArrow; case Poppler::LineAnnotation::RClosedArrow: return Okular::LineAnnotation::RClosedArrow; case Poppler::LineAnnotation::Slash: return Okular::LineAnnotation::Slash; default: qWarning() << Q_FUNC_INFO << "unknown value" << pts; } return Okular::LineAnnotation::None; } static Okular::LineAnnotation::LineIntent popplerToOkular(Poppler::LineAnnotation::LineIntent pli) { switch (pli) { case Poppler::LineAnnotation::Unknown: return Okular::LineAnnotation::Unknown; case Poppler::LineAnnotation::Arrow: return Okular::LineAnnotation::Arrow; case Poppler::LineAnnotation::Dimension: return Okular::LineAnnotation::Dimension; case Poppler::LineAnnotation::PolygonCloud: return Okular::LineAnnotation::PolygonCloud; default: qWarning() << Q_FUNC_INFO << "unknown value" << pli; } return Okular::LineAnnotation::Unknown; } static Okular::GeomAnnotation::GeomType popplerToOkular(Poppler::GeomAnnotation::GeomType pgt) { switch (pgt) { case Poppler::GeomAnnotation::InscribedSquare: return Okular::GeomAnnotation::InscribedSquare; case Poppler::GeomAnnotation::InscribedCircle: return Okular::GeomAnnotation::InscribedCircle; default: qWarning() << Q_FUNC_INFO << "unknown value" << pgt; } return Okular::GeomAnnotation::InscribedSquare; } static Okular::HighlightAnnotation::HighlightType popplerToOkular(Poppler::HighlightAnnotation::HighlightType pht) { switch (pht) { case Poppler::HighlightAnnotation::Highlight: return Okular::HighlightAnnotation::Highlight; case Poppler::HighlightAnnotation::Squiggly: return Okular::HighlightAnnotation::Squiggly; case Poppler::HighlightAnnotation::Underline: return Okular::HighlightAnnotation::Underline; case Poppler::HighlightAnnotation::StrikeOut: return Okular::HighlightAnnotation::StrikeOut; default: qWarning() << Q_FUNC_INFO << "unknown value" << pht; } return Okular::HighlightAnnotation::Highlight; } static Okular::CaretAnnotation::CaretSymbol popplerToOkular(Poppler::CaretAnnotation::CaretSymbol pcs) { switch (pcs) { case Poppler::CaretAnnotation::None: return Okular::CaretAnnotation::None; case Poppler::CaretAnnotation::P: return Okular::CaretAnnotation::P; default: qWarning() << Q_FUNC_INFO << "unknown value" << pcs; } return Okular::CaretAnnotation::None; } static Okular::Annotation *createAnnotationFromPopplerAnnotation(Poppler::TextAnnotation *popplerAnnotation) { Okular::TextAnnotation *oTextAnn = new Okular::TextAnnotation(); oTextAnn->setTextType(popplerToOkular(popplerAnnotation->textType())); oTextAnn->setTextIcon(popplerAnnotation->textIcon()); oTextAnn->setTextFont(popplerAnnotation->textFont()); oTextAnn->setTextColor(popplerAnnotation->textColor()); // this works because we use the same 0:left, 1:center, 2:right meaning both in poppler and okular oTextAnn->setInplaceAlignment(popplerAnnotation->inplaceAlign()); oTextAnn->setInplaceIntent(popplerToOkular(popplerAnnotation->inplaceIntent())); for (int i = 0; i < 3; ++i) { const QPointF p = popplerAnnotation->calloutPoint(i); oTextAnn->setInplaceCallout({p.x(), p.y()}, i); } return oTextAnn; } static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::LineAnnotation *popplerAnnotation) { Okular::LineAnnotation *oLineAnn = new Okular::LineAnnotation(); oLineAnn->setLineStartStyle(popplerToOkular(popplerAnnotation->lineStartStyle())); oLineAnn->setLineEndStyle(popplerToOkular(popplerAnnotation->lineEndStyle())); oLineAnn->setLineClosed(popplerAnnotation->isLineClosed()); oLineAnn->setLineInnerColor(popplerAnnotation->lineInnerColor()); oLineAnn->setLineLeadingForwardPoint(popplerAnnotation->lineLeadingForwardPoint()); oLineAnn->setLineLeadingBackwardPoint(popplerAnnotation->lineLeadingBackPoint()); oLineAnn->setShowCaption(popplerAnnotation->lineShowCaption()); oLineAnn->setLineIntent(popplerToOkular(popplerAnnotation->lineIntent())); QLinkedList points; const QLinkedList popplerPoints = popplerAnnotation->linePoints(); for (const QPointF &p : popplerPoints) { points << Okular::NormalizedPoint(p.x(), p.y()); } oLineAnn->setLinePoints(points); return oLineAnn; } static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::GeomAnnotation *popplerAnnotation) { Okular::GeomAnnotation *oGeomAnn = new Okular::GeomAnnotation(); oGeomAnn->setGeometricalType(popplerToOkular(popplerAnnotation->geomType())); oGeomAnn->setGeometricalInnerColor(popplerAnnotation->geomInnerColor()); return oGeomAnn; } static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::HighlightAnnotation *popplerAnnotation) { Okular::HighlightAnnotation *oHighlightAnn = new Okular::HighlightAnnotation(); oHighlightAnn->setHighlightType(popplerToOkular(popplerAnnotation->highlightType())); const QList popplerHq = popplerAnnotation->highlightQuads(); QList &okularHq = oHighlightAnn->highlightQuads(); for (const Poppler::HighlightAnnotation::Quad &popplerQ : popplerHq) { Okular::HighlightAnnotation::Quad q; // Poppler stores highlight points in swapped order q.setPoint(Okular::NormalizedPoint(popplerQ.points[0].x(), popplerQ.points[0].y()), 3); q.setPoint(Okular::NormalizedPoint(popplerQ.points[1].x(), popplerQ.points[1].y()), 2); q.setPoint(Okular::NormalizedPoint(popplerQ.points[2].x(), popplerQ.points[2].y()), 1); q.setPoint(Okular::NormalizedPoint(popplerQ.points[3].x(), popplerQ.points[3].y()), 0); q.setCapStart(popplerQ.capStart); q.setCapEnd(popplerQ.capEnd); q.setFeather(popplerQ.feather); okularHq << q; } return oHighlightAnn; } static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::InkAnnotation *popplerAnnotation) { Okular::InkAnnotation *oInkAnn = new Okular::InkAnnotation(); const QList> popplerInkPaths = popplerAnnotation->inkPaths(); QList> okularInkPaths; for (const QLinkedList &popplerInkPath : popplerInkPaths) { QLinkedList okularInkPath; for (const QPointF &popplerPoint : popplerInkPath) { okularInkPath << Okular::NormalizedPoint(popplerPoint.x(), popplerPoint.y()); } okularInkPaths << okularInkPath; } oInkAnn->setInkPaths(okularInkPaths); return oInkAnn; } static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::CaretAnnotation *popplerAnnotation) { Okular::CaretAnnotation *oCaretAnn = new Okular::CaretAnnotation(); oCaretAnn->setCaretSymbol(popplerToOkular(popplerAnnotation->caretSymbol())); return oCaretAnn; } static Okular::Annotation *createAnnotationFromPopplerAnnotation(const Poppler::StampAnnotation *popplerAnnotation) { Okular::StampAnnotation *oStampAnn = new Okular::StampAnnotation(); oStampAnn->setStampIconName(popplerAnnotation->stampIconName()); return oStampAnn; } Okular::Annotation *createAnnotationFromPopplerAnnotation(Poppler::Annotation *popplerAnnotation, const Poppler::Page &popplerPage, bool *doDelete) { Okular::Annotation *okularAnnotation = nullptr; *doDelete = true; bool tieToOkularAnn = false; bool externallyDrawn = false; switch (popplerAnnotation->subType()) { case Poppler::Annotation::AFileAttachment: { Poppler::FileAttachmentAnnotation *attachann = static_cast(popplerAnnotation); Okular::FileAttachmentAnnotation *f = new Okular::FileAttachmentAnnotation(); okularAnnotation = f; tieToOkularAnn = true; *doDelete = false; f->setFileIconName(attachann->fileIconName()); f->setEmbeddedFile(new PDFEmbeddedFile(attachann->embeddedFile())); break; } case Poppler::Annotation::ASound: { Poppler::SoundAnnotation *soundann = static_cast(popplerAnnotation); Okular::SoundAnnotation *s = new Okular::SoundAnnotation(); okularAnnotation = s; s->setSoundIconName(soundann->soundIconName()); s->setSound(createSoundFromPopplerSound(soundann->sound())); break; } case Poppler::Annotation::AMovie: { Poppler::MovieAnnotation *movieann = static_cast(popplerAnnotation); Okular::MovieAnnotation *m = new Okular::MovieAnnotation(); okularAnnotation = m; tieToOkularAnn = true; *doDelete = false; m->setMovie(createMovieFromPopplerMovie(movieann->movie())); break; } case Poppler::Annotation::AWidget: { okularAnnotation = new Okular::WidgetAnnotation(); break; } case Poppler::Annotation::AScreen: { Okular::ScreenAnnotation *m = new Okular::ScreenAnnotation(); okularAnnotation = m; tieToOkularAnn = true; *doDelete = false; break; } case Poppler::Annotation::ARichMedia: { Poppler::RichMediaAnnotation *richmediaann = static_cast(popplerAnnotation); const QPair result = createMovieFromPopplerRichMedia(richmediaann); if (result.first) { Okular::RichMediaAnnotation *r = new Okular::RichMediaAnnotation(); tieToOkularAnn = true; *doDelete = false; okularAnnotation = r; r->setMovie(result.first); r->setEmbeddedFile(result.second); } break; } case Poppler::Annotation::AText: { externallyDrawn = true; tieToOkularAnn = true; *doDelete = false; okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast(popplerAnnotation)); break; } case Poppler::Annotation::ALine: { externallyDrawn = true; tieToOkularAnn = true; *doDelete = false; okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast(popplerAnnotation)); break; } case Poppler::Annotation::AGeom: { externallyDrawn = true; tieToOkularAnn = true; *doDelete = false; okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast(popplerAnnotation)); break; } case Poppler::Annotation::AHighlight: { externallyDrawn = true; tieToOkularAnn = true; *doDelete = false; okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast(popplerAnnotation)); break; } case Poppler::Annotation::AInk: { externallyDrawn = true; tieToOkularAnn = true; *doDelete = false; okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast(popplerAnnotation)); break; } case Poppler::Annotation::ACaret: { externallyDrawn = true; tieToOkularAnn = true; *doDelete = false; okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast(popplerAnnotation)); break; } case Poppler::Annotation::AStamp: tieToOkularAnn = true; *doDelete = false; okularAnnotation = createAnnotationFromPopplerAnnotation(static_cast(popplerAnnotation)); break; default: { break; } } if (okularAnnotation) { // the Contents field might have lines separated by \r QString contents = popplerAnnotation->contents(); contents.replace(QLatin1Char('\r'), QLatin1Char('\n')); okularAnnotation->setAuthor(popplerAnnotation->author()); okularAnnotation->setContents(contents); okularAnnotation->setUniqueName(popplerAnnotation->uniqueName()); okularAnnotation->setModificationDate(popplerAnnotation->modificationDate()); okularAnnotation->setCreationDate(popplerAnnotation->creationDate()); okularAnnotation->setFlags(popplerAnnotation->flags() | Okular::Annotation::External); okularAnnotation->setBoundingRectangle(Okular::NormalizedRect::fromQRectF(popplerAnnotation->boundary())); if (externallyDrawn) okularAnnotation->setFlags(okularAnnotation->flags() | Okular::Annotation::ExternallyDrawn); // Convert the poppler annotation style to Okular annotation style Okular::Annotation::Style &okularStyle = okularAnnotation->style(); const Poppler::Annotation::Style popplerStyle = popplerAnnotation->style(); okularStyle.setColor(popplerStyle.color()); okularStyle.setOpacity(popplerStyle.opacity()); okularStyle.setWidth(popplerStyle.width()); okularStyle.setLineStyle(popplerToOkular(popplerStyle.lineStyle())); okularStyle.setXCorners(popplerStyle.xCorners()); okularStyle.setYCorners(popplerStyle.yCorners()); const QVector &dashArray = popplerStyle.dashArray(); if (dashArray.size() > 0) okularStyle.setMarks(dashArray[0]); if (dashArray.size() > 1) okularStyle.setSpaces(dashArray[1]); okularStyle.setLineEffect(popplerToOkular(popplerStyle.lineEffect())); okularStyle.setEffectIntensity(popplerStyle.effectIntensity()); // Convert the poppler annotation popup to Okular annotation window Okular::Annotation::Window &okularWindow = okularAnnotation->window(); const Poppler::Annotation::Popup popplerPopup = popplerAnnotation->popup(); // 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 okularWindow.setFlags(popplerPopup.flags()); const QRectF popplerGeometry = popplerPopup.geometry(); const QSize popplerPageSize = popplerPage.pageSize(); okularWindow.setTopLeft(Okular::NormalizedPoint(popplerGeometry.top(), popplerGeometry.left(), popplerPageSize.width(), popplerPageSize.height())); okularWindow.setWidth(popplerGeometry.width()); okularWindow.setHeight(popplerGeometry.height()); okularWindow.setTitle(popplerPopup.title()); okularWindow.setSummary(popplerPopup.summary()); // Convert the poppler revisions to Okular revisions QLinkedList &okularRevisions = okularAnnotation->revisions(); okularRevisions.clear(); // We can remove this once we stop calling Okular::AnnotationUtils::createAnnotation const QList popplerRevisions = popplerAnnotation->revisions(); for (Poppler::Annotation *popplerRevision : popplerRevisions) { bool deletePopplerRevision; Okular::Annotation::Revision okularRevision; okularRevision.setAnnotation(createAnnotationFromPopplerAnnotation(popplerRevision, popplerPage, &deletePopplerRevision)); okularRevision.setScope(popplerToOkular(popplerRevision->revisionScope())); okularRevision.setType(popplerToOkular(popplerRevision->revisionType())); okularRevisions << okularRevision; if (deletePopplerRevision) { delete popplerRevision; } } if (tieToOkularAnn) { okularAnnotation->setNativeId(QVariant::fromValue(popplerAnnotation)); okularAnnotation->setDisposeDataFunction(disposeAnnotation); } } return okularAnnotation; }