include/svx/annotation/Annotation.hxx          |    2 ++
 sd/inc/Annotation.hxx                          |    4 +++-
 sd/source/core/annotations/Annotation.cxx      |   21 ++++++++++++++++++++-
 sd/source/core/sdpage2.cxx                     |   16 ----------------
 sd/source/ui/annotations/annotationmanager.cxx |   22 +++++++++++++++++-----
 svx/source/annotation/Annotation.cxx           |    3 +++
 svx/source/svdraw/svdpage.cxx                  |   21 ++++++++++++++++-----
 7 files changed, 61 insertions(+), 28 deletions(-)

New commits:
commit c3281e071526f7efa9b7646a993476fc3f6ff8db
Author:     Tomaž Vajngerl <[email protected]>
AuthorDate: Thu Jun 20 17:10:01 2024 +0900
Commit:     Michael Meeks <[email protected]>
CommitDate: Thu Jun 20 11:17:56 2024 +0200

    annot: clone annotations in SdrObjects when the page is duplicated
    
    When the page is duplicated we need to clone all SdrObjects and
    with that also all the annotations contained in the SdrObjects.
    The annotations must also be added to the page, so that we can
    find them quickly.
    
    Previously we only cloned the annotations and relied that the
    SdrObjects would be automagically be created, but as the SdrObject
    are also cloned this creates a mess with duplicated objects with
    annotatins for the wrong page or annotation objects with missing
    annotation.
    
    Change-Id: I4bf53e4bd387fad9b0a8e4f43edd57c3d0fd34cc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169256
    Reviewed-by: Szymon Kłos <[email protected]>
    Tested-by: Michael Meeks <[email protected]>
    Reviewed-by: Michael Meeks <[email protected]>

diff --git a/include/svx/annotation/Annotation.hxx 
b/include/svx/annotation/Annotation.hxx
index 21e6b76261ad..76ccef3af30e 100644
--- a/include/svx/annotation/Annotation.hxx
+++ b/include/svx/annotation/Annotation.hxx
@@ -180,6 +180,8 @@ public:
     void setCreationInfo(CreationInfo const& rCreationInfo) { maCreationInfo = 
rCreationInfo; }
 
     SdrObject* findAnnotationObject();
+
+    virtual rtl::Reference<Annotation> clone(SdrPage* pTargetPage) = 0;
 };
 
 /** Vector of annotations */
diff --git a/sd/inc/Annotation.hxx b/sd/inc/Annotation.hxx
index d774ae0c63c2..d9a6929c76f0 100644
--- a/sd/inc/Annotation.hxx
+++ b/sd/inc/Annotation.hxx
@@ -60,7 +60,7 @@ struct SD_DLLPUBLIC CustomAnnotationMarker
 class SD_DLLPUBLIC Annotation final : public sdr::annotation::Annotation
 {
 public:
-    explicit Annotation( const 
css::uno::Reference<css::uno::XComponentContext>& context, SdPage* pPage );
+    explicit Annotation(const 
css::uno::Reference<css::uno::XComponentContext>& context, SdrPage* pPage);
     Annotation(const Annotation&) = delete;
     Annotation& operator=(const Annotation&) = delete;
 
@@ -87,6 +87,8 @@ public:
     virtual void SAL_CALL setDateTime(const css::util::DateTime & the_value) 
override;
 
     void createChangeUndo();
+
+    rtl::Reference<sdr::annotation::Annotation> clone(SdrPage* pTargetPage) 
override;
 };
 
 }
diff --git a/sd/source/core/annotations/Annotation.cxx 
b/sd/source/core/annotations/Annotation.cxx
index 2906e641e86d..ed93d35cb2bf 100644
--- a/sd/source/core/annotations/Annotation.cxx
+++ b/sd/source/core/annotations/Annotation.cxx
@@ -78,7 +78,7 @@ rtl::Reference<sdr::annotation::Annotation> 
createAnnotationAndAddToPage(SdPage*
     return xAnnotation;
 }
 
-Annotation::Annotation(const uno::Reference<uno::XComponentContext>& context, 
SdPage* pPage)
+Annotation::Annotation(const uno::Reference<uno::XComponentContext>& context, 
SdrPage* pPage)
     : sdr::annotation::Annotation(context, pPage)
 {
 }
@@ -230,6 +230,25 @@ void Annotation::createChangeUndo()
     }
 }
 
+rtl::Reference<sdr::annotation::Annotation> Annotation::clone(SdrPage* 
pTargetPage)
+{
+    rtl::Reference<sdr::annotation::Annotation> aNewAnnotation;
+    aNewAnnotation = new 
sd::Annotation(comphelper::getProcessComponentContext(), pTargetPage);
+    aNewAnnotation->setPosition(getPosition());
+    aNewAnnotation->setSize(getSize());
+    aNewAnnotation->setAuthor(getAuthor());
+    aNewAnnotation->setInitials(getInitials());
+    aNewAnnotation->setDateTime(getDateTime());
+    aNewAnnotation->setCreationInfo(getCreationInfo());
+
+    uno::Reference<css::text::XTextCopy> xSourceRange (getTextRange(), 
uno::UNO_QUERY);
+    uno::Reference<css::text::XTextCopy> xRange 
(aNewAnnotation->getTextRange(), uno::UNO_QUERY);
+    if (xSourceRange.is() && xRange.is())
+        xRange->copyText(xSourceRange);
+
+    return aNewAnnotation;
+}
+
 std::unique_ptr<SdrUndoAction> 
CreateUndoInsertOrRemoveAnnotation(rtl::Reference<sdr::annotation::Annotation>& 
xAnnotation, bool bInsert)
 {
     if (xAnnotation)
diff --git a/sd/source/core/sdpage2.cxx b/sd/source/core/sdpage2.cxx
index da415e8e5a8e..efdcdae56e91 100644
--- a/sd/source/core/sdpage2.cxx
+++ b/sd/source/core/sdpage2.cxx
@@ -378,22 +378,6 @@ void SdPage::lateInit(const SdPage& rSrcPage)
     // animations
     rSrcPage.cloneAnimations(*this);
 
-    // annotations
-    for (auto const& rSourceAnnotation : rSrcPage.maAnnotations)
-    {
-        rtl::Reference<sdr::annotation::Annotation> aNewAnnotation = 
createAnnotation();
-        aNewAnnotation->setPosition(rSourceAnnotation->getPosition());
-        aNewAnnotation->setSize(rSourceAnnotation->getSize());
-        aNewAnnotation->setAuthor(rSourceAnnotation->getAuthor());
-        aNewAnnotation->setInitials(rSourceAnnotation->getInitials());
-        aNewAnnotation->setDateTime(rSourceAnnotation->getDateTime());
-        uno::Reference<css::text::XTextCopy> xSourceRange 
(rSourceAnnotation->getTextRange(), uno::UNO_QUERY);
-        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
     SdrObjListIter aSourceIter( &rSrcPage, SdrIterMode::DeepWithGroups );
     SdrObjListIter aTargetIter( this, SdrIterMode::DeepWithGroups );
diff --git a/sd/source/ui/annotations/annotationmanager.cxx 
b/sd/source/ui/annotations/annotationmanager.cxx
index 27f06efb20f9..d05ce18d5844 100644
--- a/sd/source/ui/annotations/annotationmanager.cxx
+++ b/sd/source/ui/annotations/annotationmanager.cxx
@@ -991,10 +991,25 @@ void AnnotationManagerImpl::SyncAnnotationObjects()
     if (!mxCurrentPage.is() || !mpDoc)
         return;
 
-    auto xViewShell = mrBase.GetMainViewShell();
-    if (!xViewShell)
+    sd::DrawDocShell* pDocShell = 
dynamic_cast<sd::DrawDocShell*>(SfxObjectShell::Current());
+    sd::ViewShell* pViewShell = pDocShell ? pDocShell->GetViewShell() : 
nullptr;
+
+    if (!pViewShell)
+    {
+        pViewShell = mrBase.GetMainViewShell().get();
+        if (!pViewShell)
+            return;
+    }
+
+    auto* pView = pViewShell->GetView();
+    if (!pView)
         return;
 
+    if (!pView->GetSdrPageView())
+        return;
+
+    auto& rModel = pView->getSdrModelFromSdrView();
+
     sal_Int32 nIndex = 1;
     bool bAnnotatonInserted = false;
     for (auto const& xAnnotation : mxCurrentPage->getAnnotations())
@@ -1011,9 +1026,6 @@ void AnnotationManagerImpl::SyncAnnotationObjects()
 
         auto const& rInfo = xAnnotation->getCreationInfo();
 
-        auto* pView = xViewShell->GetView();
-        auto& rModel = pView->getSdrModelFromSdrView();
-
         auto aRealPoint2D = xAnnotation->getPosition();
         Point aPosition(::tools::Long(aRealPoint2D.X * 100.0), 
::tools::Long(aRealPoint2D.Y * 100.0));
 
diff --git a/svx/source/annotation/Annotation.cxx 
b/svx/source/annotation/Annotation.cxx
index 6f96af5e7300..512280d29b4f 100644
--- a/svx/source/annotation/Annotation.cxx
+++ b/svx/source/annotation/Annotation.cxx
@@ -205,6 +205,9 @@ SdrObject* Annotation::findAnnotationObject()
 {
     SdrPage const* pPage = getPage();
 
+    if (!pPage)
+        return nullptr;
+
     for (size_t i = 0; i < pPage->GetObjCount(); ++i)
     {
         SdrObject* pObject = pPage->GetObj(i);
diff --git a/svx/source/svdraw/svdpage.cxx b/svx/source/svdraw/svdpage.cxx
index ba41dcbdba8c..9da7c5a63978 100644
--- a/svx/source/svdraw/svdpage.cxx
+++ b/svx/source/svdraw/svdpage.cxx
@@ -52,6 +52,7 @@
 #include <svx/sdr/contact/viewobjectcontact.hxx>
 #include <svx/sdr/contact/displayinfo.hxx>
 #include <svx/annotation/Annotation.hxx>
+#include <svx/annotation/ObjectAnnotationData.hxx>
 #include <algorithm>
 #include <clonelist.hxx>
 #include <svl/hint.hxx>
@@ -155,14 +156,24 @@ void SdrObjList::CopyObjects(const SdrObjList& rSrcList)
         ? getSdrPageFromSdrObjList()->getSdrModelFromSdrPage()
         : getSdrObjectFromSdrObjList()->getSdrModelFromSdrObject());
 
-    for (const rtl::Reference<SdrObject>& pSO : rSrcList)
+    for (const rtl::Reference<SdrObject>& pSourceObject : rSrcList)
     {
-        rtl::Reference<SdrObject> pDO(pSO->CloneSdrObject(rTargetSdrModel));
+        rtl::Reference<SdrObject> 
pTargetObject(pSourceObject->CloneSdrObject(rTargetSdrModel));
 
-        if(pDO)
+        if (pTargetObject)
         {
-            NbcInsertObject(pDO.get(), SAL_MAX_SIZE);
-            aCloneList.AddPair(pSO.get(), pDO.get());
+            NbcInsertObject(pTargetObject.get(), SAL_MAX_SIZE);
+            aCloneList.AddPair(pSourceObject.get(), pTargetObject.get());
+            if (pSourceObject->isAnnotationObject())
+            {
+                pTargetObject->setAsAnnotationObject(true);
+                pTargetObject->SetPrintable(false);
+                rtl::Reference<sdr::annotation::Annotation> xNewAnnotation;
+                SdrPage* pPage = pTargetObject->getSdrPageFromSdrObject();
+                xNewAnnotation = 
pSourceObject->getAnnotationData()->mxAnnotation->clone(pPage);
+                pTargetObject->getAnnotationData()->mxAnnotation = 
xNewAnnotation;
+                pPage->addAnnotationNoNotify(xNewAnnotation, -1);
+            }
         }
 #ifdef DBG_UTIL
         else

Reply via email to