summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/svx/annotation/Annotation.hxx35
-rw-r--r--include/svx/annotation/AnnotationObject.hxx57
-rw-r--r--include/svx/svdobjkind.hxx1
-rw-r--r--sd/Library_sd.mk1
-rw-r--r--sd/UIConfig_sdraw.mk1
-rw-r--r--sd/UIConfig_simpress.mk1
-rw-r--r--sd/inc/Annotation.hxx26
-rw-r--r--sd/qa/unit/tiledrendering/tiledrendering.cxx8
-rw-r--r--sd/source/core/annotations/Annotation.cxx15
-rw-r--r--sd/source/core/sdpage2.cxx11
-rw-r--r--sd/source/filter/pdf/sdpdffilter.cxx125
-rw-r--r--sd/source/ui/annotations/annotationmanager.cxx360
-rw-r--r--sd/source/ui/annotations/annotationmanagerimpl.hxx16
-rw-r--r--sd/source/ui/annotations/annotationtag.cxx669
-rw-r--r--sd/source/ui/annotations/annotationtag.hxx90
-rw-r--r--sd/source/ui/unoidl/unomodel.cxx42
-rw-r--r--sd/source/ui/unoidl/unopage.cxx4
-rw-r--r--sd/source/ui/view/drviews4.cxx3
-rw-r--r--sd/uiconfig/sdraw/popupmenu/annotation.xml12
-rw-r--r--sd/uiconfig/simpress/popupmenu/annotation.xml12
-rw-r--r--svx/Library_svxcore.mk1
-rw-r--r--svx/source/annotation/AnnotationObject.cxx209
-rw-r--r--svx/source/unodraw/unopage.cxx3
-rw-r--r--svx/source/unodraw/unoprov.cxx1
-rw-r--r--svx/source/unodraw/unoshape.cxx24
25 files changed, 680 insertions, 1047 deletions
diff --git a/include/svx/annotation/Annotation.hxx b/include/svx/annotation/Annotation.hxx
index be378d6a61de..4001d97f406f 100644
--- a/include/svx/annotation/Annotation.hxx
+++ b/include/svx/annotation/Annotation.hxx
@@ -41,6 +41,34 @@ SVXCORE_DLLPUBLIC void LOKCommentNotify(CommentNotificationType nType,
const SfxViewShell* pViewShell, Annotation& rAnnotation);
SVXCORE_DLLPUBLIC void LOKCommentNotifyAll(CommentNotificationType nType, Annotation& rAnnotation);
+enum class AnnotationType
+{
+ None,
+ Square,
+ Polygon,
+ Circle,
+ Ink,
+ Highlight,
+ Line,
+ FreeText,
+};
+
+struct CreationInfo
+{
+ AnnotationType meType = AnnotationType::None;
+
+ std::vector<basegfx::B2DPolygon> maPolygons;
+ basegfx::B2DRectangle maRectangle;
+
+ float mnWidth = 0.0f;
+
+ bool mbFillColor = false;
+ Color maFillColor = COL_TRANSPARENT;
+
+ bool mbColor = false;
+ Color maColor = COL_TRANSPARENT;
+};
+
struct SVXCORE_DLLPUBLIC AnnotationData
{
css::geometry::RealPoint2D m_Position;
@@ -73,7 +101,7 @@ protected:
css::util::DateTime m_DateTime;
rtl::Reference<sdr::annotation::TextApiObject> m_TextRange;
- bool m_bIsFreeText = false;
+ CreationInfo maCreationInfo;
std::unique_ptr<SdrUndoAction> createUndoAnnotation();
@@ -125,9 +153,8 @@ public:
sal_uInt32 GetId() const { return m_nId; }
- void setIsFreeText(bool value) { m_bIsFreeText = value; }
-
- bool isFreeText() const { return m_bIsFreeText; }
+ CreationInfo const& getCreationInfo() { return maCreationInfo; }
+ void setCreationInfo(CreationInfo const& rCreationInfo) { maCreationInfo = rCreationInfo; }
};
typedef std::vector<rtl::Reference<Annotation>> AnnotationVector;
diff --git a/include/svx/annotation/AnnotationObject.hxx b/include/svx/annotation/AnnotationObject.hxx
new file mode 100644
index 000000000000..d46f4e7c3150
--- /dev/null
+++ b/include/svx/annotation/AnnotationObject.hxx
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#pragma once
+
+#include <svx/svxdllapi.h>
+
+#include <svx/annotation/Annotation.hxx>
+#include <svx/svdorect.hxx>
+
+namespace sdr::annotation
+{
+struct SVXCORE_DLLPUBLIC AnnotationViewData
+{
+ sal_Int32 nIndex = -1;
+ sal_uInt16 nAuthorIndex = 0;
+};
+
+class SVXCORE_DLLPUBLIC AnnotationObject final : public SdrRectObj
+{
+private:
+ virtual ~AnnotationObject() override;
+
+ sdr::annotation::AnnotationViewData maViewData;
+
+public:
+ AnnotationObject(SdrModel& rSdrModel);
+ AnnotationObject(SdrModel& rSdrModel, AnnotationObject const& rSource);
+ AnnotationObject(SdrModel& rSdrModel, tools::Rectangle const& rRectangle,
+ sdr::annotation::AnnotationViewData const& aAnnotationViewData);
+
+ rtl::Reference<SdrObject> CloneSdrObject(SdrModel& rTargetModel) const override;
+
+ SdrObjKind GetObjIdentifier() const override;
+ OUString TakeObjNameSingul() const override;
+ OUString TakeObjNamePlural() const override;
+
+ void TakeObjInfo(SdrObjTransformInfoRec& rInfo) const override;
+
+ void ApplyAnnotationName();
+
+ bool HasTextEdit() const override;
+
+ bool hasSpecialDrag() const override { return true; }
+
+ bool beginSpecialDrag(SdrDragStat& /*rDrag*/) const override { return false; }
+};
+
+} // end sdr::annotation
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/svx/svdobjkind.hxx b/include/svx/svdobjkind.hxx
index d25eba0a0027..1517bbeba4aa 100644
--- a/include/svx/svdobjkind.hxx
+++ b/include/svx/svdobjkind.hxx
@@ -53,6 +53,7 @@ enum class SdrObjKind : sal_uInt16
CustomShape = 33, /// custom shape
Media = 34, /// media shape
Table = 35, /// table
+ Annotation = 36, /// annotation object
OLE2Applet = 100,
OLE2Plugin = 101,
diff --git a/sd/Library_sd.mk b/sd/Library_sd.mk
index 01f3a1d59610..5da9c10b2adf 100644
--- a/sd/Library_sd.mk
+++ b/sd/Library_sd.mk
@@ -212,7 +212,6 @@ $(eval $(call gb_Library_add_exception_objects,sd,\
sd/source/ui/animations/SlideTransitionPane \
sd/source/ui/animations/motionpathtag \
sd/source/ui/annotations/annotationmanager \
- sd/source/ui/annotations/annotationtag \
sd/source/ui/annotations/annotationwindow \
sd/source/ui/app/optsitem \
sd/source/ui/app/sddll \
diff --git a/sd/UIConfig_sdraw.mk b/sd/UIConfig_sdraw.mk
index a84f0f286cae..276a1efc5cd8 100644
--- a/sd/UIConfig_sdraw.mk
+++ b/sd/UIConfig_sdraw.mk
@@ -17,6 +17,7 @@ $(eval $(call gb_UIConfig_add_popupmenufiles,modules/sdraw,\
sd/uiconfig/sdraw/popupmenu/3dobject \
sd/uiconfig/sdraw/popupmenu/3dscene2 \
sd/uiconfig/sdraw/popupmenu/3dscene \
+ sd/uiconfig/sdraw/popupmenu/annotation \
sd/uiconfig/sdraw/popupmenu/bezier \
sd/uiconfig/sdraw/popupmenu/connector \
sd/uiconfig/sdraw/popupmenu/curve \
diff --git a/sd/UIConfig_simpress.mk b/sd/UIConfig_simpress.mk
index ee778eaeb91a..c70fc3bc9cb3 100644
--- a/sd/UIConfig_simpress.mk
+++ b/sd/UIConfig_simpress.mk
@@ -17,6 +17,7 @@ $(eval $(call gb_UIConfig_add_popupmenufiles,modules/simpress,\
sd/uiconfig/simpress/popupmenu/3dobject \
sd/uiconfig/simpress/popupmenu/3dscene2 \
sd/uiconfig/simpress/popupmenu/3dscene \
+ sd/uiconfig/simpress/popupmenu/annotation \
sd/uiconfig/simpress/popupmenu/bezier \
sd/uiconfig/simpress/popupmenu/connector \
sd/uiconfig/simpress/popupmenu/curve \
diff --git a/sd/inc/Annotation.hxx b/sd/inc/Annotation.hxx
index aba2d27d77b7..8d9f34501e0d 100644
--- a/sd/inc/Annotation.hxx
+++ b/sd/inc/Annotation.hxx
@@ -46,17 +46,10 @@ namespace sd
{
rtl::Reference<sdr::annotation::Annotation> createAnnotation(SdPage* pPage);
+rtl::Reference<sdr::annotation::Annotation> createAnnotationAndAddToPage(SdPage* pPage);
std::unique_ptr<SdrUndoAction> CreateUndoInsertOrRemoveAnnotation(rtl::Reference<sdr::annotation::Annotation>& xAnnotation, bool bInsert);
-struct SD_DLLPUBLIC CustomAnnotationMarker
-{
- Color maLineColor;
- Color maFillColor;
- float mnLineWidth;
- std::vector<basegfx::B2DPolygon> maPolygons;
-};
-
class SAL_DLLPUBLIC_RTTI Annotation final : public sdr::annotation::Annotation
{
public:
@@ -90,25 +83,8 @@ public:
void createChangeUndo();
- void createCustomAnnotationMarker()
- {
- m_pCustomAnnotationMarker = std::make_unique<CustomAnnotationMarker>();
- }
-
- CustomAnnotationMarker& getCustomAnnotationMarker()
- {
- return *m_pCustomAnnotationMarker;
- }
-
- bool hasCustomAnnotationMarker() const
- {
- return bool(m_pCustomAnnotationMarker);
- }
-
private:
void createChangeUndoImpl(std::unique_lock<std::mutex>& g);
-
- std::unique_ptr<CustomAnnotationMarker> m_pCustomAnnotationMarker;
};
}
diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx
index 67e4ef2a1f4e..2b2bdb7a9c56 100644
--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx
@@ -1808,7 +1808,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testCommentChangeImpress)
CPPUNIT_ASSERT(!aView1.m_aCommentCallbackResult.get<std::string>("parthash").empty());
CPPUNIT_ASSERT_EQUAL(std::string("Comment"), aView1.m_aCommentCallbackResult.get<std::string>("text"));
- CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 0, 0"), aView1.m_aCommentCallbackResult.get<std::string>("rectangle"));
+ CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 282, 282"), aView1.m_aCommentCallbackResult.get<std::string>("rectangle"));
// Edit this annotation now
aArgs = comphelper::InitPropertySequence(
@@ -1821,7 +1821,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testCommentChangeImpress)
CPPUNIT_ASSERT_EQUAL(std::string("Modify"), aView1.m_aCommentCallbackResult.get<std::string>("action"));
CPPUNIT_ASSERT_EQUAL(std::string("Comment"), aView1.m_aCommentCallbackResult.get<std::string>("text"));
- CPPUNIT_ASSERT_EQUAL(std::string("10, 20, 0, 0"), aView1.m_aCommentCallbackResult.get<std::string>("rectangle"));
+ CPPUNIT_ASSERT_EQUAL(std::string("10, 20, 282, 282"), aView1.m_aCommentCallbackResult.get<std::string>("rectangle"));
comphelper::LibreOfficeKit::setTiledAnnotations(true);
}
@@ -1854,7 +1854,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testCommentChangeDraw)
CPPUNIT_ASSERT(!aView1.m_aCommentCallbackResult.get<std::string>("parthash").empty());
CPPUNIT_ASSERT_EQUAL(std::string("Comment"), aView1.m_aCommentCallbackResult.get<std::string>("text"));
- CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 0, 0"), aView1.m_aCommentCallbackResult.get<std::string>("rectangle"));
+ CPPUNIT_ASSERT_EQUAL(std::string("0, 0, 282, 282"), aView1.m_aCommentCallbackResult.get<std::string>("rectangle"));
// Edit this annotation now
aArgs = comphelper::InitPropertySequence(
@@ -1867,7 +1867,7 @@ CPPUNIT_TEST_FIXTURE(SdTiledRenderingTest, testCommentChangeDraw)
CPPUNIT_ASSERT_EQUAL(std::string("Modify"), aView1.m_aCommentCallbackResult.get<std::string>("action"));
CPPUNIT_ASSERT_EQUAL(std::string("Comment"), aView1.m_aCommentCallbackResult.get<std::string>("text"));
- CPPUNIT_ASSERT_EQUAL(std::string("10, 20, 0, 0"), aView1.m_aCommentCallbackResult.get<std::string>("rectangle"));
+ CPPUNIT_ASSERT_EQUAL(std::string("10, 20, 282, 282"), aView1.m_aCommentCallbackResult.get<std::string>("rectangle"));
comphelper::LibreOfficeKit::setTiledAnnotations(true);
}
diff --git a/sd/source/core/annotations/Annotation.cxx b/sd/source/core/annotations/Annotation.cxx
index 44fe5397e456..f41b1507cf72 100644
--- a/sd/source/core/annotations/Annotation.cxx
+++ b/sd/source/core/annotations/Annotation.cxx
@@ -61,9 +61,14 @@ protected:
}
-rtl::Reference<sdr::annotation::Annotation> createAnnotation(SdPage* pPage )
+rtl::Reference<sdr::annotation::Annotation> createAnnotation(SdPage* pPage)
{
- rtl::Reference<Annotation> xAnnotation(new Annotation(comphelper::getProcessComponentContext(), pPage));
+ return rtl::Reference<Annotation>(new Annotation(comphelper::getProcessComponentContext(), pPage));
+}
+
+rtl::Reference<sdr::annotation::Annotation> createAnnotationAndAddToPage(SdPage* pPage)
+{
+ rtl::Reference<sdr::annotation::Annotation> xAnnotation = createAnnotation(pPage);
pPage->addAnnotation(xAnnotation, -1);
return xAnnotation;
}
@@ -268,7 +273,7 @@ void UndoInsertOrRemoveAnnotation::Undo()
if (mbInsert)
{
- pPage->removeAnnotation(mxAnnotation);
+ pPage->removeAnnotationNoNotify(mxAnnotation);
}
else
{
@@ -286,12 +291,12 @@ void UndoInsertOrRemoveAnnotation::Redo()
if (mbInsert)
{
- pPage->addAnnotation(mxAnnotation, mnIndex);
+ pPage->addAnnotationNoNotify(mxAnnotation, mnIndex);
LOKCommentNotifyAll(sdr::annotation::CommentNotificationType::Add, *mxAnnotation);
}
else
{
- pPage->removeAnnotation(mxAnnotation);
+ pPage->removeAnnotationNoNotify(mxAnnotation);
}
}
diff --git a/sd/source/core/sdpage2.cxx b/sd/source/core/sdpage2.cxx
index 915ed33e75a6..620871e1cae8 100644
--- a/sd/source/core/sdpage2.cxx
+++ b/sd/source/core/sdpage2.cxx
@@ -45,6 +45,7 @@
#include <DrawDocShell.hxx>
#include <svl/itemset.hxx>
+#include <svx/annotation/ObjectAnnotationData.hxx>
using namespace ::sd;
using namespace ::com::sun::star;
@@ -389,6 +390,7 @@ void SdPage::lateInit(const SdPage& rSrcPage)
uno::Reference<css::text::XTextCopy> xRange (aNewAnnotation->getTextRange(), uno::UNO_QUERY);
if(xSourceRange.is() && xRange.is())
xRange->copyText(xSourceRange);
+ addAnnotation(aNewAnnotation, -1);
}
// fix user calls for duplicated slide
@@ -612,6 +614,15 @@ void SdPage::removeAnnotationNoNotify(rtl::Reference<sdr::annotation::Annotation
rModel.AddUndo(std::move(pAction));
}
+ for (size_t nObjectIndex = 0; nObjectIndex < GetObjCount(); ++nObjectIndex)
+ {
+ SdrObject* pObject = GetObj(nObjectIndex);
+ if (pObject->isAnnotationObject() && pObject->getAnnotationData()->mxAnnotation == xAnnotation)
+ {
+ RemoveObject(nObjectIndex);
+ }
+ }
+
auto iterator = std::find(maAnnotations.begin(), maAnnotations.end(), xAnnotation);
if (iterator != maAnnotations.end())
maAnnotations.erase(iterator);
diff --git a/sd/source/filter/pdf/sdpdffilter.cxx b/sd/source/filter/pdf/sdpdffilter.cxx
index 89ff0dd134db..6b69530454c3 100644
--- a/sd/source/filter/pdf/sdpdffilter.cxx
+++ b/sd/source/filter/pdf/sdpdffilter.cxx
@@ -83,8 +83,10 @@ bool SdPdfFilter::Import()
// Make the page size match the rendered image.
pPage->SetSize(aSizeHMM);
- rtl::Reference<SdrGrafObj> pSdrGrafObj = new SdrGrafObj(
- pPage->getSdrModelFromSdrPage(), rGraphic, tools::Rectangle(Point(), aSizeHMM));
+ SdrModel& rModel = pPage->getSdrModelFromSdrPage();
+
+ rtl::Reference<SdrGrafObj> pSdrGrafObj
+ = new SdrGrafObj(rModel, rGraphic, tools::Rectangle(Point(), aSizeHMM));
pSdrGrafObj->SetResizeProtect(true);
pSdrGrafObj->SetMoveProtect(true);
@@ -101,97 +103,118 @@ bool SdPdfFilter::Import()
xText->setString(rPDFAnnotation.maText);
// position is in mm not 100thmm
geometry::RealPoint2D aUnoPosition(rPDFAnnotation.maRectangle.getMinX() / 100.0,
- rPDFAnnotation.maRectangle.getMinY() / 100.00);
+ rPDFAnnotation.maRectangle.getMinY() / 100.0);
geometry::RealSize2D aUnoSize(rPDFAnnotation.maRectangle.getWidth() / 100.0,
- rPDFAnnotation.maRectangle.getHeight() / 100.00);
+ rPDFAnnotation.maRectangle.getHeight() / 100.0);
xAnnotation->setPosition(aUnoPosition);
xAnnotation->setSize(aUnoSize);
xAnnotation->setDateTime(rPDFAnnotation.maDateTime);
if (rPDFAnnotation.mpMarker)
{
- auto* pAnnotation = static_cast<sd::Annotation*>(xAnnotation.get());
- pAnnotation->createCustomAnnotationMarker();
- sd::CustomAnnotationMarker& rCustomAnnotationMarker
- = pAnnotation->getCustomAnnotationMarker();
-
- rCustomAnnotationMarker.maLineColor = rPDFAnnotation.maColor;
+ sdr::annotation::CreationInfo aInfo;
+ aInfo.maRectangle = rPDFAnnotation.maRectangle;
if (rPDFAnnotation.meSubType == vcl::pdf::PDFAnnotationSubType::Polygon)
{
+ aInfo.meType = sdr::annotation::AnnotationType::Polygon;
+
auto* pMarker = static_cast<vcl::pdf::PDFAnnotationMarkerPolygon*>(
rPDFAnnotation.mpMarker.get());
- rCustomAnnotationMarker.mnLineWidth = pMarker->mnWidth;
- rCustomAnnotationMarker.maFillColor = pMarker->maFillColor;
- rCustomAnnotationMarker.maPolygons.push_back(pMarker->maPolygon);
+
+ aInfo.maPolygons.push_back(pMarker->maPolygon);
+ aInfo.mnWidth = pMarker->mnWidth;
+ aInfo.maColor = rPDFAnnotation.maColor;
+ aInfo.mbColor = true;
+ aInfo.maFillColor = pMarker->maFillColor;
+ aInfo.mbFillColor = true;
}
else if (rPDFAnnotation.meSubType == vcl::pdf::PDFAnnotationSubType::Square)
{
+ aInfo.meType = sdr::annotation::AnnotationType::Square;
+
auto* pMarker = static_cast<vcl::pdf::PDFAnnotationMarkerSquare*>(
rPDFAnnotation.mpMarker.get());
- basegfx::B2DPolygon aPoly
- = basegfx::utils::createPolygonFromRect(rPDFAnnotation.maRectangle);
- rCustomAnnotationMarker.mnLineWidth = pMarker->mnWidth;
- rCustomAnnotationMarker.maFillColor = pMarker->maFillColor;
- rCustomAnnotationMarker.maPolygons.push_back(aPoly);
+
+ aInfo.mnWidth = pMarker->mnWidth;
+ aInfo.maColor = rPDFAnnotation.maColor;
+ aInfo.mbColor = true;
+ aInfo.maFillColor = pMarker->maFillColor;
+ aInfo.mbFillColor = true;
}
else if (rPDFAnnotation.meSubType == vcl::pdf::PDFAnnotationSubType::Circle)
{
+ aInfo.meType = sdr::annotation::AnnotationType::Circle;
+
auto* pMarker = static_cast<vcl::pdf::PDFAnnotationMarkerCircle*>(
rPDFAnnotation.mpMarker.get());
- basegfx::B2DPoint rCenter = rPDFAnnotation.maRectangle.getCenter();
- double fRadiusX = rPDFAnnotation.maRectangle.getWidth() / 2;
- double fRadiusY = rPDFAnnotation.maRectangle.getHeight() / 2;
-
- basegfx::B2DPolygon aPoly
- = basegfx::utils::createPolygonFromEllipse(rCenter, fRadiusX, fRadiusY);
- rCustomAnnotationMarker.mnLineWidth = pMarker->mnWidth;
- rCustomAnnotationMarker.maFillColor = pMarker->maFillColor;
- rCustomAnnotationMarker.maPolygons.push_back(aPoly);
+ aInfo.mnWidth = pMarker->mnWidth;
+ aInfo.maColor = rPDFAnnotation.maColor;
+ aInfo.mbColor = true;
+ aInfo.maFillColor = pMarker->maFillColor;
+ aInfo.mbFillColor = true;
}
else if (rPDFAnnotation.meSubType == vcl::pdf::PDFAnnotationSubType::Ink)
{
+ aInfo.meType = sdr::annotation::AnnotationType::Ink;
+
auto* pMarker = static_cast<vcl::pdf::PDFAnnotationMarkerInk*>(
rPDFAnnotation.mpMarker.get());
- rCustomAnnotationMarker.maPolygons.insert(
- rCustomAnnotationMarker.maPolygons.end(), pMarker->maStrokes.begin(),
- pMarker->maStrokes.end());
- rCustomAnnotationMarker.mnLineWidth = pMarker->mnWidth;
- rCustomAnnotationMarker.maFillColor = pMarker->maFillColor;
+
+ aInfo.maPolygons = pMarker->maStrokes;
+
+ aInfo.mnWidth = pMarker->mnWidth;
+ aInfo.maColor = rPDFAnnotation.maColor;
+ aInfo.mbColor = true;
+ aInfo.maFillColor = pMarker->maFillColor;
+ aInfo.mbFillColor = true;
}
else if (rPDFAnnotation.meSubType == vcl::pdf::PDFAnnotationSubType::Highlight)
{
- if (!rCustomAnnotationMarker.maLineColor.IsTransparent())
- rCustomAnnotationMarker.maLineColor.SetAlpha(255 - 0x90);
+ aInfo.meType = sdr::annotation::AnnotationType::Highlight;
+
auto* pMarker = static_cast<vcl::pdf::PDFAnnotationMarkerHighlight*>(
rPDFAnnotation.mpMarker.get());
- rCustomAnnotationMarker.maPolygons.insert(
- rCustomAnnotationMarker.maPolygons.end(), pMarker->maQuads.begin(),
- pMarker->maQuads.end());
- rCustomAnnotationMarker.mnLineWidth = 1;
- rCustomAnnotationMarker.maFillColor = rPDFAnnotation.maColor;
- if (!rCustomAnnotationMarker.maFillColor.IsTransparent())
- rCustomAnnotationMarker.maFillColor.SetAlpha(255 - 0x90);
+
+ aInfo.maColor = rPDFAnnotation.maColor;
+ aInfo.maColor.SetAlpha(0xFF - 0x90);
+ aInfo.mbColor = true;
+
+ aInfo.mnWidth = 1;
+
+ aInfo.maFillColor = rPDFAnnotation.maColor;
+ aInfo.maFillColor.SetAlpha(0xFF - 0x90);
+ aInfo.mbFillColor = true;
+
+ aInfo.maPolygons = pMarker->maQuads;
}
else if (rPDFAnnotation.meSubType == vcl::pdf::PDFAnnotationSubType::Line)
{
auto* pMarker = static_cast<vcl::pdf::PDFAnnotationMarkerLine*>(
rPDFAnnotation.mpMarker.get());
- basegfx::B2DPolygon aPoly;
- aPoly.append(pMarker->maLineStart);
- aPoly.append(pMarker->maLineEnd);
- rCustomAnnotationMarker.maPolygons.push_back(aPoly);
+ aInfo.meType = sdr::annotation::AnnotationType::Line;
+
+ basegfx::B2DPolygon aPolygon;
+ aPolygon.append(pMarker->maLineStart);
+ aPolygon.append(pMarker->maLineEnd);
+ aInfo.maPolygons.push_back(aPolygon);
- rCustomAnnotationMarker.mnLineWidth = pMarker->mnWidth;
- rCustomAnnotationMarker.maFillColor = COL_TRANSPARENT;
+ aInfo.mnWidth = pMarker->mnWidth;
+ aInfo.maColor = rPDFAnnotation.maColor;
+ aInfo.mbColor = true;
+ aInfo.mbFillColor = false;
}
+ else if (rPDFAnnotation.meSubType == vcl::pdf::PDFAnnotationSubType::FreeText)
+ {
+ aInfo.meType = sdr::annotation::AnnotationType::FreeText;
+ }
+
+ xAnnotation->setCreationInfo(aInfo);
}
- else if (rPDFAnnotation.meSubType == vcl::pdf::PDFAnnotationSubType::FreeText)
- {
- xAnnotation->setIsFreeText(true);
- }
+
+ pPage->addAnnotation(xAnnotation, -1);
}
}
mrDocument.setLock(bWasLocked);
diff --git a/sd/source/ui/annotations/annotationmanager.cxx b/sd/source/ui/annotations/annotationmanager.cxx
index 1446756d339a..ee5662fd2bcf 100644
--- a/sd/source/ui/annotations/annotationmanager.cxx
+++ b/sd/source/ui/annotations/annotationmanager.cxx
@@ -29,6 +29,7 @@
#include <vcl/settings.hxx>
#include <vcl/svapp.hxx>
#include <vcl/weld.hxx>
+#include <tools/gen.hxx>
#include <sal/macros.h>
#include <svl/itempool.hxx>
@@ -70,9 +71,24 @@
#include <sdpage.hxx>
#include <drawdoc.hxx>
#include <svx/annotation/TextAPI.hxx>
+#include <svx/annotation/AnnotationObject.hxx>
+#include <svx/annotation/ObjectAnnotationData.hxx>
#include <optsitem.hxx>
#include <sdmod.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdocirc.hxx>
+#include <svx/svdorect.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/svdotext.hxx>
+
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xlineit0.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xlnstwit.hxx>
+#include <svx/xlnwtit.hxx>
+
#include <memory>
using namespace ::com::sun::star;
@@ -202,7 +218,6 @@ void AnnotationManagerImpl::disposing (std::unique_lock<std::mutex>&)
}
removeListener();
- DisposeTags();
if( mnUpdateTagsEvent )
{
@@ -328,8 +343,6 @@ void AnnotationManagerImpl::ExecuteInsertAnnotation(SfxRequest const & rReq)
void AnnotationManagerImpl::ExecuteDeleteAnnotation(SfxRequest const & rReq)
{
- ShowAnnotations( true );
-
const SfxItemSet* pArgs = rReq.GetArgs();
switch( rReq.GetSlot() )
@@ -440,50 +453,48 @@ void AnnotationManagerImpl::ExecuteEditAnnotation(SfxRequest const & rReq)
void AnnotationManagerImpl::InsertAnnotation(const OUString& rText)
{
SdPage* pPage = GetCurrentPage();
- if( !pPage )
+ if (!pPage)
return;
- if( mpDoc->IsUndoEnabled() )
- mpDoc->BegUndo( SdResId( STR_ANNOTATION_UNDO_INSERT ) );
+ if (mpDoc->IsUndoEnabled())
+ mpDoc->BegUndo(SdResId(STR_ANNOTATION_UNDO_INSERT));
// find free space for new annotation
- int y = 0, x = 0;
+ int y = 0;
+ int x = 0;
sdr::annotation::AnnotationVector aAnnotations(pPage->getAnnotations());
- if( !aAnnotations.empty() )
+ if (!aAnnotations.empty())
{
- const int page_width = pPage->GetSize().Width();
- const int width = 1000;
- const int height = 800;
- ::tools::Rectangle aTagRect;
+ const int fPageWidth = pPage->GetSize().Width();
+ const int fWidth = 1000;
+ const int fHeight = 800;
- while( true )
+ while (true)
{
- ::tools::Rectangle aNewRect( x, y, x + width - 1, y + height - 1 );
+ ::tools::Rectangle aNewRect(Point(x, y), Size(fWidth, fHeight));
bool bFree = true;
- for( const auto& rxAnnotation : aAnnotations )
+ for (const auto& rxAnnotation : aAnnotations)
{
- RealPoint2D aPoint( rxAnnotation->getPosition() );
- aTagRect.SetLeft( sal::static_int_cast< ::tools::Long >( aPoint.X * 100.0 ) );
- aTagRect.SetTop( sal::static_int_cast< ::tools::Long >( aPoint.Y * 100.0 ) );
- aTagRect.SetRight( aTagRect.Left() + width - 1 );
- aTagRect.SetBottom( aTagRect.Top() + height - 1 );
+ RealPoint2D aRealPoint2D(rxAnnotation->getPosition());
+ Point aPoint(::tools::Long(aRealPoint2D.X * 100.0), ::tools::Long(aRealPoint2D.Y * 100.0));
+ Size aSize(fWidth, fHeight);
- if( aNewRect.Overlaps( aTagRect ) )
+ if (aNewRect.Overlaps(::tools::Rectangle(aPoint, aSize)))
{
bFree = false;
break;
}
}
- if( !bFree )
+ if (!bFree)
{
- x += width;
- if( x > page_width )
+ x += fWidth;
+ if (x > fPageWidth)
{
x = 0;
- y += height;
+ y += fHeight;
}
}
else
@@ -517,17 +528,20 @@ void AnnotationManagerImpl::InsertAnnotation(const OUString& rText)
xAnnotation->setDateTime( getCurrentDateTime() );
// set position
- RealPoint2D aPos( static_cast<double>(x) / 100.0, static_cast<double>(y) / 100.0 );
- xAnnotation->setPosition( aPos );
+ RealPoint2D aPosition(x / 100.0, y / 100.0);
+ xAnnotation->setPosition(aPosition);
+ xAnnotation->setSize({5.0, 5.0});
- if( mpDoc->IsUndoEnabled() )
+ pPage->addAnnotation(xAnnotation, -1);
+
+ if (mpDoc->IsUndoEnabled())
mpDoc->EndUndo();
// Tell our LOK clients about new comment added
LOKCommentNotifyAll(sdr::annotation::CommentNotificationType::Add, *xAnnotation);
UpdateTags(true);
- SelectAnnotation( xAnnotation, true );
+ SelectAnnotation(xAnnotation, true);
}
void AnnotationManagerImpl::ExecuteReplyToAnnotation( SfxRequest const & rReq )
@@ -648,8 +662,6 @@ void AnnotationManagerImpl::DeleteAnnotation(rtl::Reference<sdr::annotation::Ann
if( mpDoc->IsUndoEnabled() )
mpDoc->EndUndo();
-
- UpdateTags();
}
}
@@ -693,8 +705,8 @@ void AnnotationManagerImpl::DeleteAllAnnotations()
if( pPage && !pPage->getAnnotations().empty() )
{
-
- for( const auto& rxAnnotation : pPage->getAnnotations())
+ std::vector<rtl::Reference<sdr::annotation::Annotation>> aAnnotations(pPage->getAnnotations()); // intentionally copy
+ for( const auto& rxAnnotation : aAnnotations)
{
pPage->removeAnnotation( rxAnnotation );
}
@@ -857,33 +869,9 @@ void AnnotationManagerImpl::SelectNextAnnotation(bool bForward)
while( true );
}
-void AnnotationManagerImpl::onTagSelected( AnnotationTag const & rTag )
-{
- mxSelectedAnnotation = rTag.GetAnnotation();
- invalidateSlots();
-}
-
-void AnnotationManagerImpl::onTagDeselected( AnnotationTag const & rTag )
-{
- if (rTag.GetAnnotation() == mxSelectedAnnotation)
- {
- mxSelectedAnnotation.clear();
- invalidateSlots();
- }
-}
-
-void AnnotationManagerImpl::SelectAnnotation(rtl::Reference<sdr::annotation::Annotation> const& xAnnotation, bool bEdit)
+void AnnotationManagerImpl::SelectAnnotation(rtl::Reference<sdr::annotation::Annotation> const& xAnnotation, bool /*bEdit*/)
{
mxSelectedAnnotation = xAnnotation;
-
- auto iter = std::find_if(maTagVector.begin(), maTagVector.end(),
- [&xAnnotation](const rtl::Reference<AnnotationTag>& rxTag) { return rxTag->GetAnnotation() == xAnnotation; });
- if (iter != maTagVector.end())
- {
- SmartTagReference xTag( *iter );
- mrBase.GetMainViewShell()->GetView()->getSmartTags().select( xTag );
- (*iter)->OpenPopup( bEdit );
- }
}
void AnnotationManagerImpl::GetSelectedAnnotation( rtl::Reference<sdr::annotation::Annotation>& xAnnotation )
@@ -908,109 +896,197 @@ void AnnotationManagerImpl::invalidateSlots()
void AnnotationManagerImpl::onSelectionChanged()
{
- if( !(mxView.is() && mrBase.GetDrawView()) )
+ if (!mxView.is() || !mrBase.GetDrawView())
return;
- try
+ rtl::Reference<SdPage> xPage = mrBase.GetMainViewShell()->getCurrentPage();
+ if (xPage != mxCurrentPage)
{
- rtl::Reference< SdPage > xPage = mrBase.GetMainViewShell()->getCurrentPage();
-
- if( xPage != mxCurrentPage )
- {
- mxCurrentPage = xPage;
-
- UpdateTags(true);
- }
- }
- catch( Exception& )
- {
- TOOLS_WARN_EXCEPTION( "sd", "sd::AnnotationManagerImpl::onSelectionChanged()" );
+ mxCurrentPage = xPage;
+ UpdateTags(true);
}
}
-void AnnotationManagerImpl::UpdateTags( bool bSynchron )
+void AnnotationManagerImpl::UpdateTags(bool bSynchron)
{
- if( bSynchron )
+ SyncAnnotationObjects();
+
+ invalidateSlots();
+
+ if (bSynchron)
{
- if( mnUpdateTagsEvent )
- Application::RemoveUserEvent( mnUpdateTagsEvent );
+ if (mnUpdateTagsEvent)
+ Application::RemoveUserEvent(mnUpdateTagsEvent);
UpdateTagsHdl(nullptr);
}
else
{
- if( !mnUpdateTagsEvent && mxView.is() )
- mnUpdateTagsEvent = Application::PostUserEvent( LINK( this, AnnotationManagerImpl, UpdateTagsHdl ) );
+ if (!mnUpdateTagsEvent && mxView.is())
+ mnUpdateTagsEvent = Application::PostUserEvent(LINK(this, AnnotationManagerImpl, UpdateTagsHdl));
}
}
IMPL_LINK_NOARG(AnnotationManagerImpl, UpdateTagsHdl, void*, void)
{
mnUpdateTagsEvent = nullptr;
- DisposeTags();
-
- if( mbShowAnnotations )
- CreateTags();
+ SyncAnnotationObjects();
- if( mrBase.GetDrawView() )
- static_cast< ::sd::View* >( mrBase.GetDrawView() )->updateHandles();
+ if (mrBase.GetDrawView())
+ static_cast<::sd::View*>(mrBase.GetDrawView())->updateHandles();
invalidateSlots();
}
-void AnnotationManagerImpl::CreateTags()
+SdrObject* AnnotationManagerImpl::findAnnotationObjectMatching(rtl::Reference<sdr::annotation::Annotation> const& xAnnotation)
+{
+ for (size_t i = 0; i < mxCurrentPage->GetObjCount(); ++i)
+ {
+ SdrObject* pObject = mxCurrentPage->GetObj(i);
+ if (pObject->isAnnotationObject() && pObject->getAnnotationData()->mxAnnotation == xAnnotation)
+ return pObject;
+ }
+ return nullptr;
+}
+
+namespace
+{
+
+void applyAnnotationCommon(SdrObject& rObject, rtl::Reference<sdr::annotation::Annotation> const& xAnnotation)
+{
+ rObject.setAsAnnotationObject(true);
+ auto& xAnnotationData = rObject.getAnnotationData();
+ xAnnotationData->mxAnnotation = xAnnotation;
+ rObject.SetPrintable(false);
+}
+
+void applyAnnotationProperties(SdrObject& rObject, sdr::annotation::CreationInfo const& rInfo)
+{
+ if (rInfo.mbColor)
+ {
+ rObject.SetMergedItem(XLineStyleItem(drawing::LineStyle_SOLID));
+ rObject.SetMergedItem(XLineColorItem(OUString(), rInfo.maColor));
+ }
+ rObject.SetMergedItem(XLineWidthItem(rInfo.mnWidth));
+
+ if (rInfo.mbFillColor)
+ {
+ rObject.SetMergedItem(XFillStyleItem(drawing::FillStyle_SOLID));
+ rObject.SetMergedItem(XFillColorItem(OUString(), rInfo.maFillColor));
+ }
+}
+
+}
+
+void AnnotationManagerImpl::SyncAnnotationObjects()
{
- if( !(mxCurrentPage.is() && mpDoc) )
+ if (!mxCurrentPage.is() || !mpDoc)
return;
auto xViewShell = mrBase.GetMainViewShell();
if (!xViewShell)
return;
- try
+ sal_Int32 nIndex = 1;
+ for (auto const& xAnnotation : mxCurrentPage->getAnnotations())
{
- int nIndex = 1;
- maFont = Application::GetSettings().GetStyleSettings().GetAppFont();
+ SdrObject* pObject = findAnnotationObjectMatching(xAnnotation);
+
+ if (pObject)
+ continue;
+
+ auto const& rInfo = xAnnotation->getCreationInfo();
+
+ auto* pView = xViewShell->GetView();
+ auto& rModel = pView->getSdrModelFromSdrView();
- rtl::Reference< AnnotationTag > xSelectedTag;
+ auto aRealPoint2D = xAnnotation->getPosition();
+ Point aPosition(::tools::Long(aRealPoint2D.X * 100.0), ::tools::Long(aRealPoint2D.Y * 100.0));
- for (rtl::Reference<sdr::annotation::Annotation> const& xAnnotation : mxCurrentPage->getAnnotations())
+ auto aRealSize2D = xAnnotation->getSize();
+ Size aSize(::tools::Long(aRealSize2D.Width * 100.0), ::tools::Long(aRealSize2D.Height * 100.0));
+
+ ::tools::Rectangle aRectangle(aPosition, aSize);
+
+ rtl::Reference<SdrObject> pNewObject;
+
+ if (rInfo.meType == sdr::annotation::AnnotationType::None)
{
- Color aColor( GetColorLight( mpDoc->GetAnnotationAuthorIndex( xAnnotation->getAuthor() ) ) );
- rtl::Reference< AnnotationTag > xTag( new AnnotationTag( *this, *xViewShell->GetView(), xAnnotation, aColor, nIndex++, maFont ) );
- maTagVector.push_back(xTag);
+ sal_uInt16 nAuthorIndex = mpDoc->GetAnnotationAuthorIndex(xAnnotation->getAuthor());
- if (xAnnotation == mxSelectedAnnotation)
+ sdr::annotation::AnnotationViewData aAnnotationViewData
{
- xSelectedTag = xTag;
- }
+ .nIndex = nIndex,
+ .nAuthorIndex = nAuthorIndex
+ };
+
+ rtl::Reference<sdr::annotation::AnnotationObject> pAnnotationObject = new sdr::annotation::AnnotationObject(rModel, aRectangle, aAnnotationViewData);
+ pNewObject = pAnnotationObject;
+
+ applyAnnotationCommon(*pNewObject, xAnnotation);
+
+ pAnnotationObject->ApplyAnnotationName();
+ }
+ else if (rInfo.meType == sdr::annotation::AnnotationType::FreeText)
+ {
+ rtl::Reference<SdrRectObj> pRectangleObject = new SdrRectObj(rModel, SdrObjKind::Text, aRectangle);
+ pNewObject = pRectangleObject;
+
+ applyAnnotationCommon(*pNewObject, xAnnotation);
+ applyAnnotationProperties(*pNewObject, rInfo);
+
+ OUString aString = xAnnotation->getTextRange()->getString();
+ pRectangleObject->SetText(aString);
}
+ else if (rInfo.meType == sdr::annotation::AnnotationType::Square)
+ {
+ pNewObject = new SdrRectObj(rModel, SdrObjKind::Rectangle, aRectangle);
- if( xSelectedTag.is() )
+ applyAnnotationCommon(*pNewObject, xAnnotation);
+ applyAnnotationProperties(*pNewObject, rInfo);
+ }
+ else if (rInfo.meType == sdr::annotation::AnnotationType::Circle)
{
- SmartTagReference xTag( xSelectedTag );
- mrBase.GetMainViewShell()->GetView()->getSmartTags().select( xTag );
+ pNewObject = new SdrCircObj(rModel, SdrCircKind::Full, aRectangle);
+
+ applyAnnotationCommon(*pNewObject, xAnnotation);
+ applyAnnotationProperties(*pNewObject, rInfo);
}
else
{
- // no tag, no selection!
- mxSelectedAnnotation.clear();
+ SdrObjKind ekind = SdrObjKind::Polygon;
+
+ switch (rInfo.meType)
+ {
+ case sdr::annotation::AnnotationType::Polygon:
+ ekind = SdrObjKind::Polygon;
+ break;
+ case sdr::annotation::AnnotationType::Line:
+ ekind = SdrObjKind::PolyLine;
+ break;
+ case sdr::annotation::AnnotationType::Ink:
+ ekind = SdrObjKind::FreehandLine;
+ break;
+ default:
+ break;
+ }
+
+ basegfx::B2DPolyPolygon aPolyPolygon;
+ for (auto const& rPolygon : rInfo.maPolygons)
+ aPolyPolygon.append(rPolygon);
+
+ pNewObject = new SdrPathObj(rModel, ekind, aPolyPolygon);
+
+ applyAnnotationCommon(*pNewObject, xAnnotation);
+ applyAnnotationProperties(*pNewObject, rInfo);
}
- }
- catch( Exception& )
- {
- TOOLS_WARN_EXCEPTION( "sd", "sd::AnnotationManagerImpl::onSelectionChanged()" );
- }
-}
-void AnnotationManagerImpl::DisposeTags()
-{
- for (auto& rxTag : maTagVector)
- {
- rxTag->Dispose();
- }
+ pNewObject->SetLogicRect(aRectangle);
- maTagVector.clear();
+ pView->InsertObjectAtView(pNewObject.get(), *pView->GetSdrPageView());
+
+ nIndex++;
+ }
}
void AnnotationManagerImpl::addListener()
@@ -1049,60 +1125,6 @@ IMPL_LINK(AnnotationManagerImpl,EventMultiplexerListener,
}
}
-void AnnotationManagerImpl::ExecuteAnnotationTagContextMenu(const rtl::Reference<sdr::annotation::Annotation>& xAnnotation, weld::Widget* pParent, const ::tools::Rectangle& rContextRect)
-{
- SfxDispatcher* pDispatcher( getDispatcher( mrBase ) );
- if( !pDispatcher )
- return;
-
- const bool bReadOnly = mrBase.GetDocShell()->IsReadOnly();
-
- if (bReadOnly)
- return;
-
- std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pParent, u"modules/simpress/ui/annotationtagmenu.ui"_ustr));
- std::unique_ptr<weld::Menu> xMenu(xBuilder->weld_menu(u"menu"_ustr));
-
- SvtUserOptions aUserOptions;
- OUString sCurrentAuthor( aUserOptions.GetFullName() );
- OUString sAuthor( xAnnotation->getAuthor() );
-
- OUString aStr(xMenu->get_label(u".uno:DeleteAllAnnotationByAuthor"_ustr));
- OUString aReplace( sAuthor );
- if( aReplace.isEmpty() )
- aReplace = SdResId( STR_ANNOTATION_NOAUTHOR );
- aStr = aStr.replaceFirst("%1", aReplace);
- xMenu->set_label(u".uno:DeleteAllAnnotationByAuthor"_ustr, aStr);
-
- bool bShowReply = sAuthor != sCurrentAuthor;
- xMenu->set_visible(u".uno:ReplyToAnnotation"_ustr, bShowReply);
- xMenu->set_visible(u"separator"_ustr, bShowReply);
- xMenu->set_visible(u".uno:DeleteAnnotation"_ustr, xAnnotation.is());
-
- auto sId = xMenu->popup_at_rect(pParent, rContextRect);
-
- if (sId == ".uno:ReplyToAnnotation")
- {
- const SfxUnoAnyItem aItem( SID_REPLYTO_POSTIT, Any( css::uno::Reference<XInterface>(static_cast<cppu::OWeakObject*>(xAnnotation.get())) ) );
- pDispatcher->ExecuteList(SID_REPLYTO_POSTIT,
- SfxCallMode::ASYNCHRON, { &aItem });
- }
- else if (sId == ".uno:DeleteAnnotation")
- {
- const SfxUnoAnyItem aItem( SID_REPLYTO_POSTIT, Any( css::uno::Reference<XInterface>(static_cast<cppu::OWeakObject*>(xAnnotation.get())) ) );
- pDispatcher->ExecuteList(SID_DELETE_POSTIT, SfxCallMode::ASYNCHRON,
- { &aItem });
- }
- else if (sId == ".uno:DeleteAllAnnotationByAuthor")
- {
- const SfxStringItem aItem( SID_DELETEALLBYAUTHOR_POSTIT, sAuthor );
- pDispatcher->ExecuteList( SID_DELETEALLBYAUTHOR_POSTIT,
- SfxCallMode::ASYNCHRON, { &aItem });
- }
- else if (sId == ".uno:DeleteAllAnnotation")
- pDispatcher->Execute( SID_DELETEALL_POSTIT );
-}
-
Color AnnotationManagerImpl::GetColor(sal_uInt16 aAuthorIndex)
{
if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
diff --git a/sd/source/ui/annotations/annotationmanagerimpl.hxx b/sd/source/ui/annotations/annotationmanagerimpl.hxx
index 1a7b60263089..a92883dec583 100644
--- a/sd/source/ui/annotations/annotationmanagerimpl.hxx
+++ b/sd/source/ui/annotations/annotationmanagerimpl.hxx
@@ -25,13 +25,12 @@
#include <comphelper/compbase.hxx>
-#include "annotationtag.hxx"
-
namespace com::sun::star::drawing { class XDrawView; }
namespace com::sun::star::office { class XAnnotationAccess; }
namespace com::sun::star::office { class XAnnotation; }
class SfxRequest;
+class SdrObject;
class SdPage;
class SdDrawDocument;
struct ImplSVEvent;
@@ -42,6 +41,7 @@ namespace sd
{
class Annotation;
class ViewShellBase;
+class View;
namespace tools { class EventMultiplexerEvent; }
@@ -87,10 +87,6 @@ public:
static Color GetColorLight(sal_uInt16 aAuthorIndex);
static Color GetColor(sal_uInt16 aAuthorIndex);
- // callbacks
- void onTagSelected( AnnotationTag const & rTag );
- void onTagDeselected( AnnotationTag const & rTag );
-
void onSelectionChanged();
void addListener();
@@ -102,8 +98,7 @@ public:
DECL_LINK(UpdateTagsHdl, void *, void);
void UpdateTags(bool bSynchron = false);
- void CreateTags();
- void DisposeTags();
+ void SyncAnnotationObjects();
SdPage* GetNextPage( SdPage const * pPage, bool bForward );
@@ -113,19 +108,18 @@ public:
void ShowAnnotations(bool bShow);
+ SdrObject* findAnnotationObjectMatching(rtl::Reference<sdr::annotation::Annotation> const& xAnnotation);
+
private:
ViewShellBase& mrBase;
SdDrawDocument* mpDoc;
- std::vector< rtl::Reference< AnnotationTag > > maTagVector;
-
css::uno::Reference< css::drawing::XDrawView > mxView;
rtl::Reference<SdPage> mxCurrentPage;
rtl::Reference<sdr::annotation::Annotation> mxSelectedAnnotation;
bool mbShowAnnotations;
ImplSVEvent * mnUpdateTagsEvent;
- vcl::Font maFont;
rtl::Reference<sdr::annotation::Annotation> GetAnnotationById(sal_uInt32 nAnnotationId);
};
diff --git a/sd/source/ui/annotations/annotationtag.cxx b/sd/source/ui/annotations/annotationtag.cxx
deleted file mode 100644
index 91cfcbbfbcfa..000000000000
--- a/sd/source/ui/annotations/annotationtag.cxx
+++ /dev/null
@@ -1,669 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include <com/sun/star/geometry/RealPoint2D.hpp>
-#include <com/sun/star/office/XAnnotation.hpp>
-
-#include <rtl/ustrbuf.hxx>
-
-#include <utility>
-#include <vcl/commandevent.hxx>
-#include <vcl/svapp.hxx>
-#include <vcl/settings.hxx>
-#include <vcl/weldutils.hxx>
-
-#include <svx/sdr/overlay/overlayanimatedbitmapex.hxx>
-#include <svx/sdr/overlay/overlaybitmapex.hxx>
-#include <svx/sdr/overlay/overlaypolypolygon.hxx>
-#include <svx/svdpagv.hxx>
-#include <svx/sdrpagewindow.hxx>
-#include <svx/sdrpaintwindow.hxx>
-#include <svx/svddrgmt.hxx>
-#include <tools/debug.hxx>
-
-#include <View.hxx>
-#include <sdresid.hxx>
-#include <strings.hrc>
-#include "annotationmanagerimpl.hxx"
-#include "annotationwindow.hxx"
-#include "annotationtag.hxx"
-#include <svx/annotation/Annotation.hxx>
-#include <Annotation.hxx>
-#include <ViewShell.hxx>
-#include <Window.hxx>
-#include <drawdoc.hxx>
-
-using namespace ::com::sun::star::uno;
-using namespace ::com::sun::star::geometry;
-
-namespace sd
-{
-
-const sal_uInt32 SMART_TAG_HDL_NUM = SAL_MAX_UINT32;
-const int DRGPIX = 2; // Drag MinMove in Pixel
-
-static OUString getInitials( const OUString& rName )
-{
- OUStringBuffer sInitials;
-
- const sal_Unicode * pStr = rName.getStr();
- sal_Int32 nLength = rName.getLength();
-
- while( nLength )
- {
- // skip whitespace
- while( nLength && (*pStr <= ' ') )
- {
- nLength--; pStr++;
- }
-
- // take letter
- if( nLength )
- {
- sInitials.append(*pStr);
- nLength--; pStr++;
- }
-
- // skip letters until whitespace
- while( nLength && (*pStr > ' ') )
- {
- nLength--; pStr++;
- }
- }
-
- return sInitials.makeStringAndClear();
-}
-
-namespace {
-
-class AnnotationDragMove : public SdrDragMove
-{
-public:
- AnnotationDragMove(SdrDragView& rNewView, rtl::Reference <AnnotationTag > xTag);
- virtual bool BeginSdrDrag() override;
- virtual bool EndSdrDrag(bool bCopy) override;
- virtual void MoveSdrDrag(const Point& rNoSnapPnt) override;
- virtual void CancelSdrDrag() override;
-
-private:
- rtl::Reference <AnnotationTag > mxTag;
- Point maOrigin;
-};
-
-}
-
-AnnotationDragMove::AnnotationDragMove(SdrDragView& rNewView, rtl::Reference <AnnotationTag > xTag)
-: SdrDragMove(rNewView)
-, mxTag(std::move( xTag ))
-{
-}
-
-bool AnnotationDragMove::BeginSdrDrag()
-{
- DragStat().SetRef1(GetDragHdl()->GetPos());
- DragStat().SetShown(!DragStat().IsShown());
-
- maOrigin = GetDragHdl()->GetPos();
- DragStat().SetActionRect(::tools::Rectangle(maOrigin,maOrigin));
-
- return true;
-}
-
-void AnnotationDragMove::MoveSdrDrag(const Point& rNoSnapPnt)
-{
- Point aPnt(rNoSnapPnt);
-
- if (DragStat().CheckMinMoved(rNoSnapPnt))
- {
- if (aPnt!=DragStat().GetNow())
- {
- Hide();
- DragStat().NextMove(aPnt);
- GetDragHdl()->SetPos( maOrigin + Point( DragStat().GetDX(), DragStat().GetDY() ) );
- Show();
- DragStat().SetActionRect(::tools::Rectangle(aPnt,aPnt));
- }
- }
-}
-
-bool AnnotationDragMove::EndSdrDrag(bool /*bCopy*/)
-{
- Hide();
- if( mxTag.is() )
- mxTag->Move( DragStat().GetDX(), DragStat().GetDY() );
- return true;
-}
-
-void AnnotationDragMove::CancelSdrDrag()
-{
- Hide();
-}
-
-namespace {
-
-class AnnotationHdl : public SmartHdl
-{
-public:
- AnnotationHdl( const SmartTagReference& xTag, rtl::Reference<sdr::annotation::Annotation> const& xAnnotation, const Point& rPnt );
-
- virtual void CreateB2dIAObject() override;
- virtual bool IsFocusHdl() const override;
-
-private:
- rtl::Reference<sdr::annotation::Annotation> mxAnnotation;
- rtl::Reference<AnnotationTag> mxTag;
-};
-
-}
-
-AnnotationHdl::AnnotationHdl( const SmartTagReference& xTag, rtl::Reference<sdr::annotation::Annotation> const& xAnnotation, const Point& rPnt )
- : SmartHdl(xTag, rPnt, SdrHdlKind::SmartTag)
- , mxAnnotation(xAnnotation)
- , mxTag(dynamic_cast<AnnotationTag*>(xTag.get()))
-{
-}
-
-void AnnotationHdl::CreateB2dIAObject()
-{
- // first throw away old one
- GetRidOfIAObject();
-
- if (!mxAnnotation.is())
- return;
-
- const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
-
- const Point aTagPos( GetPos() );
- basegfx::B2DPoint aPosition( aTagPos.X(), aTagPos.Y() );
-
- const bool bFocused = IsFocusHdl() && m_pHdlList && (m_pHdlList->GetFocusHdl() == this);
-
- BitmapEx aBitmapEx( mxTag->CreateAnnotationBitmap(mxTag->isSelected()) );
- BitmapEx aBitmapEx2;
- if( bFocused )
- aBitmapEx2 = mxTag->CreateAnnotationBitmap(!mxTag->isSelected() );
-
- if(!m_pHdlList)
- return;
-
- SdrMarkView* pView = m_pHdlList->GetView();
-
- if(!pView || pView->areMarkHandlesHidden())
- return;
-
- SdrPageView* pPageView = pView->GetSdrPageView();
-
- if(!pPageView)
- return;
-
- for(sal_uInt32 b = 0; b < pPageView->PageWindowCount(); b++)
- {
- // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b];
- const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
-
- SdrPaintWindow& rPaintWindow = rPageWindow.GetPaintWindow();
- const rtl::Reference< sdr::overlay::OverlayManager >& xManager = rPageWindow.GetOverlayManager();
- if(rPaintWindow.OutputToWindow() && xManager.is() )
- {
- std::unique_ptr<sdr::overlay::OverlayObject> pOverlayObject;
- auto pSdAnnotation = dynamic_cast<sd::Annotation*>(mxAnnotation.get());
- if (pSdAnnotation && pSdAnnotation->hasCustomAnnotationMarker())
- {
- CustomAnnotationMarker& rCustomAnnotationMarker = pSdAnnotation->getCustomAnnotationMarker();
-
- auto& rPolygons = rCustomAnnotationMarker.maPolygons;
- if (!rPolygons.empty())
- {
- basegfx::B2DPolyPolygon aPolyPolygon;
- for (auto const & rPolygon : rPolygons)
- aPolyPolygon.append(rPolygon);
-
- pOverlayObject.reset(new sdr::overlay::OverlayPolyPolygon(
- std::move(aPolyPolygon),
- rCustomAnnotationMarker.maLineColor,
- rCustomAnnotationMarker.mnLineWidth,
- rCustomAnnotationMarker.maFillColor));
- }
- }
- else
- {
- // animate focused handles
- if(bFocused)
- {
- const sal_uInt64 nBlinkTime = rStyleSettings.GetCursorBlinkTime();
-
- pOverlayObject.reset(new sdr::overlay::OverlayAnimatedBitmapEx(aPosition, aBitmapEx, aBitmapEx2, nBlinkTime, 0, 0, 0, 0 ));
- }
- else
- {
- pOverlayObject.reset(new sdr::overlay::OverlayBitmapEx( aPosition, aBitmapEx, 0, 0 ));
- }
- }
-
- // OVERLAYMANAGER
- insertNewlyCreatedOverlayObjectForSdrHdl(
- std::move(pOverlayObject),
- rPageWindow.GetObjectContact(),
- *xManager);
- }
- }
-}
-
-bool AnnotationHdl::IsFocusHdl() const
-{
- return true;
-}
-
-AnnotationTag::AnnotationTag(AnnotationManagerImpl& rManager, ::sd::View& rView, rtl::Reference<sdr::annotation::Annotation> const& xAnnotation, Color const & rColor, int nIndex, const vcl::Font& rFont)
-: SmartTag( rView )
-, mrManager( rManager )
-, mxAnnotation( xAnnotation )
-, maColor( rColor )
-, mnIndex( nIndex )
-, mrFont( rFont )
-, mpListenWindow( nullptr )
-{
-}
-
-AnnotationTag::~AnnotationTag()
-{
- DBG_ASSERT( !mxAnnotation.is(), "sd::AnnotationTag::~AnnotationTag(), dispose me first!" );
- Dispose();
-}
-
-/** returns true if the AnnotationTag handled the event. */
-bool AnnotationTag::MouseButtonDown( const MouseEvent& rMEvt, SmartHdl& /*rHdl*/ )
-{
- if( !mxAnnotation.is() )
- return false;
-
- bool bRet = false;
- if( !isSelected() )
- {
- SmartTagReference xTag( this );
- mrView.getSmartTags().select( xTag );
- bRet = true;
- }
-
- if( rMEvt.IsLeft() && !rMEvt.IsRight() )
- {
- vcl::Window* pWindow = mrView.GetViewShell()->GetActiveWindow();
- if( pWindow )
- {
- maMouseDownPos = pWindow->PixelToLogic( rMEvt.GetPosPixel() );
-
- if( mpListenWindow )
- mpListenWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler));
-
- mpListenWindow = pWindow;
- mpListenWindow->AddEventListener( LINK(this, AnnotationTag, WindowEventHandler));
- }
-
- bRet = true;
- }
-
- return bRet;
-}
-
-/** returns true if the SmartTag consumes this event. */
-bool AnnotationTag::KeyInput( const KeyEvent& rKEvt )
-{
- if( !mxAnnotation.is() )
- return false;
-
- sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode();
- switch( nCode )
- {
- case KEY_DELETE:
- mrManager.DeleteAnnotation( mxAnnotation );
- return true;
-
- case KEY_DOWN:
- case KEY_UP:
- case KEY_LEFT:
- case KEY_RIGHT:
- return OnMove( rKEvt );
-
- case KEY_ESCAPE:
- {
- SmartTagReference xThis( this );
- mrView.getSmartTags().deselect();
- return true;
- }
-
- case KEY_TAB:
- mrManager.SelectNextAnnotation(!rKEvt.GetKeyCode().IsShift());
- return true;
-
- case KEY_RETURN:
- case KEY_SPACE:
- OpenPopup( true );
- return true;
-
- default:
- return false;
- }
-}
-
-/** returns true if the SmartTag consumes this event. */
-bool AnnotationTag::Command( const CommandEvent& rCEvt )
-{
- if (rCEvt.GetCommand() != CommandEventId::ContextMenu)
- return false;
- if (vcl::Window* pWindow = mrView.GetViewShell()->GetActiveWindow())
- {
- ::tools::Rectangle aContextRect(rCEvt.GetMousePosPixel(),Size(1,1));
- weld::Window* pParent = weld::GetPopupParent(*pWindow, aContextRect);
- mrManager.ExecuteAnnotationTagContextMenu(mxAnnotation, pParent, aContextRect);
- return true;
- }
- return false;
-}
-
-void AnnotationTag::Move( int nDX, int nDY )
-{
- if( !mxAnnotation.is() )
- return;
-
- if( mrManager.GetDoc()->IsUndoEnabled() )
- mrManager.GetDoc()->BegUndo( SdResId( STR_ANNOTATION_UNDO_MOVE ) );
-
- RealPoint2D aPosition( mxAnnotation->getPosition() );
- aPosition.X += static_cast<double>(nDX) / 100.0;
- aPosition.Y += static_cast<double>(nDY) / 100.0;
- mxAnnotation->setPosition( aPosition );
-
- if( mrManager.GetDoc()->IsUndoEnabled() )
- mrManager.GetDoc()->EndUndo();
-
- mrView.updateHandles();
-}
-
-bool AnnotationTag::OnMove( const KeyEvent& rKEvt )
-{
- ::tools::Long nX = 0;
- ::tools::Long nY = 0;
-
- switch( rKEvt.GetKeyCode().GetCode() )
- {
- case KEY_UP: nY = -1; break;
- case KEY_DOWN: nY = 1; break;
- case KEY_LEFT: nX = -1; break;
- case KEY_RIGHT: nX = 1; break;
- default: break;
- }
-
- if(rKEvt.GetKeyCode().IsMod2())
- {
- OutputDevice* pOut = mrView.GetViewShell()->GetActiveWindow()->GetOutDev();
- Size aLogicSizeOnePixel = pOut ? pOut->PixelToLogic(Size(1,1)) : Size(100, 100);
- nX *= aLogicSizeOnePixel.Width();
- nY *= aLogicSizeOnePixel.Height();
- }
- else
- {
- // old, fixed move distance
- nX *= 100;
- nY *= 100;
- }
-
- if( nX || nY )
- {
- // move the annotation
- Move( nX, nY );
- }
-
- return true;
-}
-
-void AnnotationTag::CheckPossibilities()
-{
-}
-
-sal_Int32 AnnotationTag::GetMarkablePointCount() const
-{
- return 0;
-}
-
-sal_Int32 AnnotationTag::GetMarkedPointCount() const
-{
- return 0;
-}
-
-bool AnnotationTag::MarkPoint(SdrHdl& /*rHdl*/, bool /*bUnmark*/ )
-{
- return false;
-}
-
-bool AnnotationTag::MarkPoints(const ::tools::Rectangle* /*pRect*/, bool /*bUnmark*/ )
-{
- return false;
-}
-
-bool AnnotationTag::getContext( SdrViewContext& /*rContext*/ )
-{
- return false;
-}
-
-void AnnotationTag::addCustomHandles( SdrHdlList& rHandlerList )
-{
- if( !mxAnnotation.is() )
- return;
-
- SmartTagReference xThis( this );
- std::unique_ptr<AnnotationHdl> pHdl(new AnnotationHdl( xThis, mxAnnotation, Point() ));
- pHdl->SetObjHdlNum( SMART_TAG_HDL_NUM );
- pHdl->SetPageView( mrView.GetSdrPageView() );
-
- RealPoint2D aPosition( mxAnnotation->getPosition() );
- Point aBasePos( static_cast<::tools::Long>(aPosition.X * 100.0), static_cast<::tools::Long>(aPosition.Y * 100.0) );
- pHdl->SetPos( aBasePos );
-
- rHandlerList.AddHdl( std::move(pHdl) );
-}
-
-void AnnotationTag::disposing()
-{
- if( mpListenWindow )
- {
- mpListenWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler));
- }
-
- mxAnnotation.clear();
- ClosePopup();
- SmartTag::disposing();
-}
-
-void AnnotationTag::select()
-{
- SmartTag::select();
-
- mrManager.onTagSelected( *this );
-
- vcl::Window* pWindow = mrView.GetViewShell()->GetActiveWindow();
- if( pWindow )
- {
- RealPoint2D aPosition( mxAnnotation->getPosition() );
- Point aPos( static_cast<::tools::Long>(aPosition.X * 100.0), static_cast<::tools::Long>(aPosition.Y * 100.0) );
-
- ::tools::Rectangle aVisRect( aPos, pWindow->PixelToLogic(maSize) );
- mrView.MakeVisible(aVisRect, *pWindow);
- }
-}
-
-void AnnotationTag::deselect()
-{
- SmartTag::deselect();
-
- ClosePopup();
-
- mrManager.onTagDeselected( *this );
-}
-
-BitmapEx AnnotationTag::CreateAnnotationBitmap( bool bSelected )
-{
- ScopedVclPtrInstance< VirtualDevice > pVDev;
-
- OUString sText;
- if (mxAnnotation && mxAnnotation->isFreeText())
- {
- sText = mxAnnotation->getTextRange()->getString();
- }
- else
- {
- OUString sInitials(mxAnnotation->getInitials());
- if (sInitials.isEmpty())
- {
- sInitials = getInitials(mxAnnotation->getAuthor());
- }
-
- sText = sInitials + " " + OUString::number(mnIndex);
- }
-
- pVDev->SetFont( mrFont );
-
- const int BORDER_X = 4; // pixels
- const int BORDER_Y = 4; // pixels
-
- maSize = Size(pVDev->GetTextWidth(sText) + 2 * BORDER_X, pVDev->GetTextHeight() + 2 * BORDER_Y);
- pVDev->SetOutputSizePixel( maSize, false );
-
- Color aBorderColor( maColor );
-
- if( bSelected )
- {
- aBorderColor.Invert();
- }
- else
- {
- if( maColor.IsDark() )
- {
- aBorderColor.IncreaseLuminance( 32 );
- }
- else
- {
- aBorderColor.DecreaseLuminance( 32 );
- }
- }
-
- Point aPos;
- ::tools::Rectangle aBorderRect( aPos, maSize );
- pVDev->SetLineColor(aBorderColor);
- pVDev->SetFillColor(maColor);
- pVDev->DrawRect( aBorderRect );
-
- pVDev->SetTextColor( maColor.IsDark() ? COL_WHITE : COL_BLACK );
- pVDev->DrawText(Point(BORDER_X, BORDER_Y), sText);
-
- return pVDev->GetBitmapEx( aPos, maSize );
-}
-
-void AnnotationTag::OpenPopup( bool bEdit )
-{
- if( !mxAnnotation.is() )
- return;
-
- if( !mpAnnotationWindow )
- {
- OutputDevice* pOut = getView().GetFirstOutputDevice();
- vcl::Window* pWindow = pOut ? pOut->GetOwnerWindow() : nullptr;
- if( pWindow )
- {
- RealPoint2D aPosition( mxAnnotation->getPosition() );
- Point aPos(pWindow->LogicToPixel( Point( static_cast<::tools::Long>(aPosition.X * 100.0), static_cast<::tools::Long>(aPosition.Y * 100.0) ) ) );
-
- aPos.AdjustX(4 ); // magic!
- aPos.AdjustY(1 );
-
- ::tools::Rectangle aRect( aPos, maSize );
-
- weld::Window* pParent = weld::GetPopupParent(*pWindow, aRect);
- mpAnnotationWindow.reset(new AnnotationWindow(pParent, aRect, mrView.GetDocSh(), mxAnnotation));
- mpAnnotationWindow->connect_closed(LINK(this, AnnotationTag, PopupModeEndHdl));
- }
- }
-
- if (bEdit && mpAnnotationWindow)
- mpAnnotationWindow->StartEdit();
-}
-
-IMPL_LINK_NOARG(AnnotationTag, PopupModeEndHdl, weld::Popover&, void)
-{
- ClosePopup();
-}
-
-void AnnotationTag::ClosePopup()
-{
- if (mpAnnotationWindow)
- {
- mpAnnotationWindow->SaveToDocument();
- mpAnnotationWindow.reset();
- }
-}
-
-IMPL_LINK(AnnotationTag, WindowEventHandler, VclWindowEvent&, rEvent, void)
-{
- vcl::Window* pWindow = rEvent.GetWindow();
-
- if( !pWindow )
- return;
-
- if( pWindow != mpListenWindow )
- return;
-
- switch( rEvent.GetId() )
- {
- case VclEventId::WindowMouseButtonUp:
- {
- // if we stop pressing the button without a mouse move we open the popup
- mpListenWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler));
- mpListenWindow = nullptr;
- if( !mpAnnotationWindow )
- OpenPopup(false);
- }
- break;
- case VclEventId::WindowMouseMove:
- {
- // if we move the mouse after a button down we want to start dragging
- mpListenWindow->RemoveEventListener( LINK(this, AnnotationTag, WindowEventHandler));
- mpListenWindow = nullptr;
-
- SdrHdl* pHdl = mrView.PickHandle(maMouseDownPos);
- if( pHdl )
- {
- mrView.BrkAction();
- const sal_uInt16 nDrgLog = static_cast<sal_uInt16>(pWindow->PixelToLogic(Size(DRGPIX,0)).Width());
-
- rtl::Reference< AnnotationTag > xTag( this );
-
- SdrDragMethod* pDragMethod = new AnnotationDragMove( mrView, xTag );
- mrView.BegDragObj(maMouseDownPos, nullptr, pHdl, nDrgLog, pDragMethod );
- }
- }
- break;
- case VclEventId::ObjectDying:
- mpListenWindow = nullptr;
- break;
- default: break;
- }
-}
-
-} // end of namespace sd
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/annotations/annotationtag.hxx b/sd/source/ui/annotations/annotationtag.hxx
deleted file mode 100644
index afe6d134a829..000000000000
--- a/sd/source/ui/annotations/annotationtag.hxx
+++ /dev/null
@@ -1,90 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#pragma once
-
-#include <vcl/vclevent.hxx>
-
-#include <smarttag.hxx>
-#include "annotationwindow.hxx"
-
-namespace com::sun::star::office { class XAnnotation; }
-
-namespace sdr::annotation { class Annotation; }
-namespace sd
-{
-class View;
-class AnnotationManagerImpl;
-
-class AnnotationTag final : public SmartTag
-{
-public:
- AnnotationTag( AnnotationManagerImpl& rManager, ::sd::View& rView, rtl::Reference<sdr::annotation::Annotation> const& xAnnotation, Color const & rColor, int nIndex, const vcl::Font& rFont );
- virtual ~AnnotationTag() override;
-
- /// @return true if the SmartTag handled the event.
- virtual bool MouseButtonDown( const MouseEvent&, SmartHdl& ) override;
-
- /// @return true if the SmartTag consumes this event.
- virtual bool KeyInput( const KeyEvent& rKEvt ) override;
-
- /// @return true if the SmartTag consumes this event.
- virtual bool Command( const CommandEvent& rCEvt ) override;
-
- // callbacks from sdr view
- virtual sal_Int32 GetMarkablePointCount() const override;
- virtual sal_Int32 GetMarkedPointCount() const override;
- virtual bool MarkPoint(SdrHdl& rHdl, bool bUnmark) override;
- virtual void CheckPossibilities() override;
- virtual bool MarkPoints(const ::tools::Rectangle* pRect, bool bUnmark) override;
-
- void Move( int nDX, int nDY );
- bool OnMove( const KeyEvent& rKEvt );
-
- BitmapEx CreateAnnotationBitmap(bool);
-
- rtl::Reference<sdr::annotation::Annotation> const& GetAnnotation() const { return mxAnnotation; }
-
- void OpenPopup( bool bEdit );
- void ClosePopup();
-
-private:
- virtual void addCustomHandles( SdrHdlList& rHandlerList ) override;
- virtual bool getContext( SdrViewContext& rContext ) override;
- virtual void disposing() override;
- virtual void select() override;
- virtual void deselect() override;
-
- DECL_LINK( WindowEventHandler, VclWindowEvent&, void );
- DECL_LINK(PopupModeEndHdl, weld::Popover&, void);
-
- AnnotationManagerImpl& mrManager;
- rtl::Reference<sdr::annotation::Annotation> mxAnnotation;
- std::unique_ptr<AnnotationWindow> mpAnnotationWindow;
- Color maColor;
- int mnIndex;
- const vcl::Font& mrFont;
- Size maSize;
- VclPtr<vcl::Window> mpListenWindow;
- Point maMouseDownPos;
-};
-
-} // end of namespace sd
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx
index da1c4ca806e6..96a4e1c07100 100644
--- a/sd/source/ui/unoidl/unomodel.cxx
+++ b/sd/source/ui/unoidl/unomodel.cxx
@@ -1632,25 +1632,33 @@ static void ImplPDFExportComments( const uno::Reference< drawing::XDrawPage >& x
aNote.maContents = xText->getString();
aNote.maModificationDate = xAnnotation->getDateTime();
auto* pAnnotation = dynamic_cast<sd::Annotation*>(xAnnotation.get());
- if (pAnnotation && pAnnotation->isFreeText())
- {
- aNote.meType = vcl::pdf::PDFAnnotationSubType::FreeText;
- }
- if (pAnnotation && pAnnotation->hasCustomAnnotationMarker())
+
+ if (pAnnotation && pAnnotation->getCreationInfo().meType != sdr::annotation::AnnotationType::None)
{
- aNote.maPolygons = pAnnotation->getCustomAnnotationMarker().maPolygons;
- aNote.maAnnotationColor = pAnnotation->getCustomAnnotationMarker().maLineColor;
- aNote.maInteriorColor = pAnnotation->getCustomAnnotationMarker().maFillColor;
- if (aNote.maPolygons.size() == 1)
- {
- auto const& rPolygon = aNote.maPolygons[0];
- aNote.meType = rPolygon.isClosed()
- ? vcl::pdf::PDFAnnotationSubType::Polygon
- : vcl::pdf::PDFAnnotationSubType::Polyline;
- }
- else if (aNote.maPolygons.size() > 1)
+ sdr::annotation::CreationInfo const& rCreation = pAnnotation->getCreationInfo();
+ aNote.maPolygons = rCreation.maPolygons;
+ aNote.maAnnotationColor = rCreation.maColor;
+ aNote.maInteriorColor = rCreation.maFillColor;
+ aNote.mfWidth = rCreation.mnWidth;
+ switch (rCreation.meType)
{
- aNote.meType = vcl::pdf::PDFAnnotationSubType::Ink;
+ case sdr::annotation::AnnotationType::Square:
+ aNote.meType = vcl::pdf::PDFAnnotationSubType::Square; break;
+ case sdr::annotation::AnnotationType::Circle:
+ aNote.meType = vcl::pdf::PDFAnnotationSubType::Circle; break;
+ case sdr::annotation::AnnotationType::Polygon:
+ aNote.meType = vcl::pdf::PDFAnnotationSubType::Polygon; break;
+ case sdr::annotation::AnnotationType::Ink:
+ aNote.meType = vcl::pdf::PDFAnnotationSubType::Ink; break;
+ case sdr::annotation::AnnotationType::Highlight:
+ aNote.meType = vcl::pdf::PDFAnnotationSubType::Highlight; break;
+ case sdr::annotation::AnnotationType::Line:
+ aNote.meType = vcl::pdf::PDFAnnotationSubType::Line; break;
+ case sdr::annotation::AnnotationType::FreeText:
+ aNote.meType = vcl::pdf::PDFAnnotationSubType::FreeText; break;
+ default:
+ aNote.meType = vcl::pdf::PDFAnnotationSubType::Text;
+ break;
}
}
diff --git a/sd/source/ui/unoidl/unopage.cxx b/sd/source/ui/unoidl/unopage.cxx
index 6e0f2ad52b13..8f89dc0def6a 100644
--- a/sd/source/ui/unoidl/unopage.cxx
+++ b/sd/source/ui/unoidl/unopage.cxx
@@ -2529,7 +2529,9 @@ Reference< XAnnotation > SAL_CALL SdGenericDrawPage::createAndInsertAnnotation()
if( !GetPage() )
throw DisposedException();
- return GetPage()->createAnnotation();
+ auto xAnnotation = GetPage()->createAnnotation();
+ GetPage()->addAnnotation(xAnnotation);
+ return xAnnotation;
}
void SAL_CALL SdGenericDrawPage::removeAnnotation(const Reference< XAnnotation > & annotation)
diff --git a/sd/source/ui/view/drviews4.cxx b/sd/source/ui/view/drviews4.cxx
index 83ffcc9be39b..7bd35adfb4c9 100644
--- a/sd/source/ui/view/drviews4.cxx
+++ b/sd/source/ui/view/drviews4.cxx
@@ -758,6 +758,9 @@ void DrawViewShell::Command(const CommandEvent& rCEvt, ::sd::Window* pWin)
case SdrObjKind::Table:
aPopupId = "table";
break;
+ case SdrObjKind::Annotation:
+ aPopupId = "annotation";
+ break;
default: ;
}
}
diff --git a/sd/uiconfig/sdraw/popupmenu/annotation.xml b/sd/uiconfig/sdraw/popupmenu/annotation.xml
new file mode 100644
index 000000000000..4bb3cb0bcdcb
--- /dev/null
+++ b/sd/uiconfig/sdraw/popupmenu/annotation.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+-->
+<menu:menupopup xmlns:menu="http://openoffice.org/2001/menu">
+ <menu:menuitem menu:id=".uno:ObjectTitleDescription"/>
+</menu:menupopup>
diff --git a/sd/uiconfig/simpress/popupmenu/annotation.xml b/sd/uiconfig/simpress/popupmenu/annotation.xml
new file mode 100644
index 000000000000..4bb3cb0bcdcb
--- /dev/null
+++ b/sd/uiconfig/simpress/popupmenu/annotation.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+-->
+<menu:menupopup xmlns:menu="http://openoffice.org/2001/menu">
+ <menu:menuitem menu:id=".uno:ObjectTitleDescription"/>
+</menu:menupopup>
diff --git a/svx/Library_svxcore.mk b/svx/Library_svxcore.mk
index 5218e9582b43..7fe222959676 100644
--- a/svx/Library_svxcore.mk
+++ b/svx/Library_svxcore.mk
@@ -108,6 +108,7 @@ endif
$(eval $(call gb_Library_add_exception_objects,svxcore,\
svx/source/annotation/Annotation \
svx/source/annotation/AnnotationEnumeration \
+ svx/source/annotation/AnnotationObject \
svx/source/annotation/TextAPI \
svx/source/core/extedit \
svx/source/core/graphichelper \
diff --git a/svx/source/annotation/AnnotationObject.cxx b/svx/source/annotation/AnnotationObject.cxx
new file mode 100644
index 000000000000..35dc4807e1b8
--- /dev/null
+++ b/svx/source/annotation/AnnotationObject.cxx
@@ -0,0 +1,209 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column:100 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <config_features.h>
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <sal/log.hxx>
+#include <svx/svdmodel.hxx>
+
+#include <svx/annotation/AnnotationObject.hxx>
+#include <svx/annotation/ObjectAnnotationData.hxx>
+#include <sdr/properties/rectangleproperties.hxx>
+#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+
+#include <svx/xfillit0.hxx>
+#include <svx/xflclit.hxx>
+#include <svx/xlineit0.hxx>
+#include <svx/xlnclit.hxx>
+#include <svx/xlnwtit.hxx>
+#include <svx/sdtfsitm.hxx>
+#include <svx/sdooitm.hxx>
+#include <svx/sdtagitm.hxx>
+#include <svx/sdasitm.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/colritem.hxx>
+#include <o3tl/unit_conversion.hxx>
+
+using namespace css;
+
+namespace sdr::annotation
+{
+namespace
+{
+OUString createInitials(OUString const& rName)
+{
+ OUStringBuffer sInitials;
+
+ const sal_Unicode* pStr = rName.getStr();
+ sal_Int32 nLength = rName.getLength();
+
+ while (nLength)
+ {
+ // skip whitespace
+ while (nLength && (*pStr <= ' '))
+ {
+ nLength--;
+ pStr++;
+ }
+
+ // take letter
+ if (nLength)
+ {
+ sInitials.append(*pStr);
+ nLength--;
+ pStr++;
+ }
+
+ // skip letters until whitespace
+ while (nLength && (*pStr > ' '))
+ {
+ nLength--;
+ pStr++;
+ }
+ }
+
+ return sInitials.makeStringAndClear();
+}
+
+Color getColorLight(sal_uInt16 aAuthorIndex)
+{
+ if (!Application::GetSettings().GetStyleSettings().GetHighContrastMode())
+ {
+ constexpr const auto constArrayLight
+ = std::to_array<Color>({ COL_AUTHOR1_LIGHT, COL_AUTHOR2_LIGHT, COL_AUTHOR3_LIGHT,
+ COL_AUTHOR4_LIGHT, COL_AUTHOR5_LIGHT, COL_AUTHOR6_LIGHT,
+ COL_AUTHOR7_LIGHT, COL_AUTHOR8_LIGHT, COL_AUTHOR9_LIGHT });
+ return constArrayLight[aAuthorIndex % constArrayLight.size()];
+ }
+
+ return COL_WHITE;
+}
+}
+
+AnnotationObject::AnnotationObject(SdrModel& rSdrModel)
+ : SdrRectObj(rSdrModel)
+{
+ setAsAnnotationObject(true);
+}
+
+AnnotationObject::AnnotationObject(SdrModel& rSdrModel, AnnotationObject const& rSource)
+ : SdrRectObj(rSdrModel, rSource)
+{
+ setAsAnnotationObject(true);
+}
+
+AnnotationObject::AnnotationObject(SdrModel& rSdrModel, tools::Rectangle const& rRectangle,
+ sdr::annotation::AnnotationViewData const& rAnnotationViewData)
+ : SdrRectObj(rSdrModel, rRectangle)
+ , maViewData(rAnnotationViewData)
+{
+ osl_atomic_increment(&m_refCount);
+
+ const bool bUndo(rSdrModel.IsUndoEnabled());
+ rSdrModel.EnableUndo(false);
+ MakeNameUnique();
+ rSdrModel.EnableUndo(bUndo);
+
+ osl_atomic_decrement(&m_refCount);
+ setAsAnnotationObject(true);
+}
+
+void AnnotationObject::ApplyAnnotationName()
+{
+ if (mpAnnotationData->mxAnnotation)
+ {
+ OUString sInitials(mpAnnotationData->mxAnnotation->getInitials());
+ if (sInitials.isEmpty())
+ sInitials = createInitials(mpAnnotationData->mxAnnotation->getAuthor());
+ SetText(sInitials + " " + OUString::number(maViewData.nIndex));
+ }
+ else
+ {
+ SetText(u"Empty"_ustr);
+ }
+
+ Color aColor(getColorLight(maViewData.nAuthorIndex));
+
+ SetMergedItem(XFillStyleItem(drawing::FillStyle_SOLID));
+ SetMergedItem(XFillColorItem(OUString(), aColor));
+
+ Color aBorderColor(aColor);
+ if (aColor.IsDark())
+ aBorderColor.IncreaseLuminance(32);
+ else
+ aBorderColor.DecreaseLuminance(32);
+
+ SetMergedItem(XLineStyleItem(drawing::LineStyle_SOLID));
+ SetMergedItem(XLineColorItem(OUString(), aBorderColor));
+ SetMergedItem(XLineWidthItem(o3tl::convert(0, o3tl::Length::pt, o3tl::Length::mm100)));
+
+ SetMergedItem(SvxFontHeightItem(o3tl::convert(10, o3tl::Length::pt, o3tl::Length::mm100), 100,
+ EE_CHAR_FONTHEIGHT));
+
+ SetMergedItem(SvxColorItem(aColor.IsDark() ? COL_WHITE : COL_BLACK, EE_CHAR_COLOR));
+
+ SetMergedItem(SdrTextFitToSizeTypeItem(drawing::TextFitToSizeType_NONE));
+
+ SetMergedItem(makeSdrTextWordWrapItem(false));
+ SetMergedItem(makeSdrTextAutoGrowWidthItem(true));
+ SetMergedItem(makeSdrTextAutoGrowHeightItem(true));
+}
+
+AnnotationObject::~AnnotationObject() {}
+
+void AnnotationObject::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
+{
+ rInfo.bMoveAllowed = true;
+ rInfo.bResizeFreeAllowed = false;
+ rInfo.bResizePropAllowed = false;
+ rInfo.bRotateFreeAllowed = false;
+ rInfo.bRotate90Allowed = false;
+ rInfo.bMirrorFreeAllowed = false;
+ rInfo.bMirror45Allowed = false;
+ rInfo.bMirror90Allowed = false;
+ rInfo.bTransparenceAllowed = false;
+ rInfo.bShearAllowed = false;
+ rInfo.bEdgeRadiusAllowed = false;
+ rInfo.bNoOrthoDesired = false;
+ rInfo.bNoContortion = false;
+ rInfo.bCanConvToPath = false;
+ rInfo.bCanConvToPoly = false;
+ rInfo.bCanConvToContour = false;
+ rInfo.bCanConvToPathLineToArea = false;
+ rInfo.bCanConvToPolyLineToArea = false;
+}
+
+SdrObjKind AnnotationObject::GetObjIdentifier() const { return SdrObjKind::Annotation; }
+
+OUString AnnotationObject::TakeObjNameSingul() const
+{
+ OUString sName(u"Annotation"_ustr);
+ OUString aName(GetName());
+
+ if (!aName.isEmpty())
+ sName += " '" + aName + "'";
+
+ return sName;
+}
+
+OUString AnnotationObject::TakeObjNamePlural() const { return u"Annotations"_ustr; }
+
+rtl::Reference<SdrObject> AnnotationObject::CloneSdrObject(SdrModel& rTargetModel) const
+{
+ return new AnnotationObject(rTargetModel, *this);
+}
+
+bool AnnotationObject::HasTextEdit() const { return false; }
+
+} // end sdr::annotation
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/unodraw/unopage.cxx b/svx/source/unodraw/unopage.cxx
index fc613dd23f4a..9bf61e49af53 100644
--- a/svx/source/unodraw/unopage.cxx
+++ b/svx/source/unodraw/unopage.cxx
@@ -766,6 +766,9 @@ rtl::Reference<SvxShape> SvxDrawPage::CreateShapeByTypeAndInventor( SdrObjKind n
case SdrObjKind::Table:
pRet = new SvxTableShape( pObj );
break;
+ case SdrObjKind::Annotation:
+ pRet = new SvxShapeRect( pObj );
+ break;
default: // unknown 2D-object on page
assert(false && "Not implemented Starone-Shape created");
pRet = new SvxShapeText( pObj );
diff --git a/svx/source/unodraw/unoprov.cxx b/svx/source/unodraw/unoprov.cxx
index d210da214ee7..356894621c0a 100644
--- a/svx/source/unodraw/unoprov.cxx
+++ b/svx/source/unodraw/unoprov.cxx
@@ -822,6 +822,7 @@ const UHashMapImpl& GetUHashImpl()
{ "com.sun.star.drawing.AppletShape", SdrObjKind::OLE2Applet },
{ "com.sun.star.drawing.CustomShape", SdrObjKind::CustomShape },
{ "com.sun.star.drawing.MediaShape", SdrObjKind::Media },
+ { "com.sun.star.drawing.AnnotationShape", SdrObjKind::Annotation },
{ "com.sun.star.drawing.Shape3DSceneObject", SdrObjKind::E3D_Scene },
{ "com.sun.star.drawing.Shape3DCubeObject", SdrObjKind::E3D_Cube },
diff --git a/svx/source/unodraw/unoshape.cxx b/svx/source/unodraw/unoshape.cxx
index 934c72c85cfb..5c3807817a6f 100644
--- a/svx/source/unodraw/unoshape.cxx
+++ b/svx/source/unodraw/unoshape.cxx
@@ -3184,6 +3184,7 @@ constexpr OUString sUNO_service_drawing_PolyLineShape = u"com.sun.star.drawi
constexpr OUString sUNO_service_drawing_OpenBezierShape = u"com.sun.star.drawing.OpenBezierShape"_ustr;
constexpr OUString sUNO_service_drawing_ClosedBezierShape = u"com.sun.star.drawing.ClosedBezierShape"_ustr;
constexpr OUString sUNO_service_drawing_TextShape = u"com.sun.star.drawing.TextShape"_ustr;
+constexpr OUString sUNO_service_drawing_AnnotationShape = u"com.sun.star.drawing.AnnotationShape"_ustr;
constexpr OUString sUNO_service_drawing_GraphicObjectShape = u"com.sun.star.drawing.GraphicObjectShape"_ustr;
constexpr OUString sUNO_service_drawing_OLE2Shape = u"com.sun.star.drawing.OLE2Shape"_ustr;
constexpr OUString sUNO_service_drawing_PageShape = u"com.sun.star.drawing.PageShape"_ustr;
@@ -3442,6 +3443,29 @@ uno::Sequence< OUString > SvxShape::_getSupportedServiceNames()
sUNO_service_drawing_RotationDescriptor };
return aSvxShape_TextServices;
}
+ case SdrObjKind::Annotation:
+ {
+ static const uno::Sequence<OUString> aSvxShape_AnnotationServices = {
+ sUNO_service_drawing_AnnotationShape,
+
+ sUNO_service_drawing_Shape,
+ sUNO_service_drawing_FillProperties,
+ sUNO_service_drawing_LineProperties,
+
+ sUNO_service_drawing_Text,
+ sUNO_service_drawing_TextProperties,
+ sUNO_service_style_ParagraphProperties,
+ sUNO_service_style_ParagraphPropertiesComplex,
+ sUNO_service_style_ParagraphPropertiesAsian,
+ sUNO_service_style_CharacterProperties,
+ sUNO_service_style_CharacterPropertiesComplex,
+ sUNO_service_style_CharacterPropertiesAsian,
+
+ sUNO_service_drawing_ShadowProperties,
+ sUNO_service_drawing_RotationDescriptor
+ };
+ return aSvxShape_AnnotationServices;
+ }
case SdrObjKind::Graphic:
{