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
