.gitreview                                            |    2 
 sw/inc/HandleAnchorNodeChg.hxx                        |    5 +
 sw/qa/extras/uiwriter/data2/image-comment-at-char.odt |binary
 sw/qa/extras/uiwriter/uiwriter2.cxx                   |   29 +++++++
 sw/source/core/layout/atrfrm.cxx                      |   69 ++++++++++++++++--
 5 files changed, 100 insertions(+), 5 deletions(-)

New commits:
commit b2a3254332b2a314297477dedfcfc9eafee614c3
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Jul 9 17:48:14 2019 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Jul 10 11:58:24 2019 +0200

    sw comments on frames: fix comment handling when changing at-char anchor
    
    If the user drags the at-char image and the anchor changes, then need to
    update the comment anchor (and its annotation range) as well. Use the
    same API that's used by SwTransferable::PrivateDrop(), except work with
    doc model positions, not with screen coordinates, like drag&drop does.
    
    (cherry picked from commit 5da29a31903e0c11802548327b41511519e61d7d)
    
    Change-Id: Ib9610b3eddc77f9973b68a1c5c8cdbe1f7079ab9
    Reviewed-on: https://gerrit.libreoffice.org/75338
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/.gitreview b/.gitreview
index b6f0665a9ba6..92209530c743 100644
--- a/.gitreview
+++ b/.gitreview
@@ -3,5 +3,5 @@ host=logerrit
 port=29418
 project=core
 defaultremote=logerrit
-defaultbranch=libreoffice-6-2
+defaultbranch=distro/collabora/cp-6.2
 
diff --git a/sw/inc/HandleAnchorNodeChg.hxx b/sw/inc/HandleAnchorNodeChg.hxx
index 7453e4e6b9be..e01da4c932a6 100644
--- a/sw/inc/HandleAnchorNodeChg.hxx
+++ b/sw/inc/HandleAnchorNodeChg.hxx
@@ -59,6 +59,11 @@ private:
     // and that re-creation of fly frames is necessary.
     bool mbAnchorNodeChanged;
 
+    /// If the fly frame has a comment, this points to the old comment anchor.
+    std::unique_ptr<SwPosition> mpCommentAnchor;
+
+    SwWrtShell* mpWrtShell;
+
     SwHandleAnchorNodeChg( const SwHandleAnchorNodeChg& ) = delete;
     void operator=( const SwHandleAnchorNodeChg ) = delete;
 };
diff --git a/sw/qa/extras/uiwriter/data2/image-comment-at-char.odt 
b/sw/qa/extras/uiwriter/data2/image-comment-at-char.odt
index a3638ffe7276..ac6a06780a81 100644
Binary files a/sw/qa/extras/uiwriter/data2/image-comment-at-char.odt and 
b/sw/qa/extras/uiwriter/data2/image-comment-at-char.odt differ
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx 
b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 58eb30a3953d..3ce98dcbfbd6 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -1200,6 +1200,35 @@ void SwUiWriterTest2::testImageCommentAtChar()
     // 1', i.e. the comment of the image was not deleted when the image was 
deleted.
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0),
                          
pDoc->getIDocumentMarkAccess()->getAnnotationMarksCount());
+
+    // Undo the deletion and move the image down, so the anchor changes.
+    pView->GetViewFrame()->GetDispatcher()->Execute(SID_UNDO, 
SfxCallMode::SYNCHRON);
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(1),
+                         
pDoc->getIDocumentMarkAccess()->getAnnotationMarksCount());
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    Point aNewAnchor = pWrtShell->GetFlyRect().TopLeft();
+    aNewAnchor.Move(0, 600);
+    pWrtShell->SetFlyPos(aNewAnchor);
+
+    // Get the image anchor doc model position.
+    SwFlyFrame* pFly = pWrtShell->GetCurrFlyFrame(false);
+    CPPUNIT_ASSERT(pFly);
+    SwFrameFormat& rFlyFormat = pFly->GetFrameFormat();
+    const SwPosition* pImageAnchor = rFlyFormat.GetAnchor().GetContentAnchor();
+    CPPUNIT_ASSERT(pImageAnchor);
+
+    // Get the annotation mark doc model start.
+    auto it = pDoc->getIDocumentMarkAccess()->getAnnotationMarksBegin();
+    CPPUNIT_ASSERT(it != 
pDoc->getIDocumentMarkAccess()->getAnnotationMarksEnd());
+    const std::shared_ptr<sw::mark::IMark> pMark(*it);
+    const SwPosition& rAnnotationMarkStart = pMark->GetMarkPos();
+
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: SwPosition (node 14, offset 15)
+    // - Actual  : SwPosition (node 12, offset 3)
+    // This means moving the image anchor did not move the comment anchor / 
annotation mark, so the
+    // image and its comment got out of sync.
+    CPPUNIT_ASSERT_EQUAL(*pImageAnchor, rAnnotationMarkStart);
 }
 
 void SwUiWriterTest2::testTdf124261()
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
index de02414bdaf5..404c360c14b1 100644
--- a/sw/source/core/layout/atrfrm.cxx
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -85,13 +85,13 @@
 #include <drawdoc.hxx>
 #include <hints.hxx>
 
-#ifndef NDEBUG
 #include <ndtxt.hxx>
-#endif
 
 #include <svx/sdr/attribute/sdrallfillattributeshelper.hxx>
 #include <svx/xfillit0.hxx>
 #include <svl/itemiter.hxx>
+#include <wrtsh.hxx>
+#include <txtfld.hxx>
 
 using namespace ::com::sun::star;
 
@@ -3259,15 +3259,16 @@ SwHandleAnchorNodeChg::SwHandleAnchorNodeChg( 
SwFlyFrameFormat& _rFlyFrameFormat
                                               const SwFormatAnchor& 
_rNewAnchorFormat,
                                               SwFlyFrame const * 
_pKeepThisFlyFrame )
     : mrFlyFrameFormat( _rFlyFrameFormat ),
-      mbAnchorNodeChanged( false )
+      mbAnchorNodeChanged( false ),
+      mpWrtShell(nullptr)
 {
+    const SwFormatAnchor& aOldAnchorFormat(_rFlyFrameFormat.GetAnchor());
     const RndStdIds nNewAnchorType( _rNewAnchorFormat.GetAnchorId() );
     if ( ((nNewAnchorType == RndStdIds::FLY_AT_PARA) ||
           (nNewAnchorType == RndStdIds::FLY_AT_CHAR)) &&
          _rNewAnchorFormat.GetContentAnchor() &&
          
_rNewAnchorFormat.GetContentAnchor()->nNode.GetNode().GetContentNode() )
     {
-        const SwFormatAnchor& aOldAnchorFormat( _rFlyFrameFormat.GetAnchor() );
         if ( aOldAnchorFormat.GetAnchorId() == nNewAnchorType &&
              aOldAnchorFormat.GetContentAnchor() &&
              
aOldAnchorFormat.GetContentAnchor()->nNode.GetNode().GetContentNode() &&
@@ -3310,6 +3311,18 @@ SwHandleAnchorNodeChg::SwHandleAnchorNodeChg( 
SwFlyFrameFormat& _rFlyFrameFormat
             }
         }
     }
+
+    if (aOldAnchorFormat.GetContentAnchor()
+        && aOldAnchorFormat.GetAnchorId() == RndStdIds::FLY_AT_CHAR)
+    {
+        mpCommentAnchor.reset(new 
SwPosition(*aOldAnchorFormat.GetContentAnchor()));
+    }
+
+    if (_pKeepThisFlyFrame)
+    {
+        SwViewShell* pViewShell = 
_pKeepThisFlyFrame->getRootFrame()->GetCurrShell();
+        mpWrtShell = dynamic_cast<SwWrtShell*>(pViewShell);
+    }
 }
 
 SwHandleAnchorNodeChg::~SwHandleAnchorNodeChg()
@@ -3318,6 +3331,54 @@ SwHandleAnchorNodeChg::~SwHandleAnchorNodeChg()
     {
         mrFlyFrameFormat.MakeFrames();
     }
+
+    // See if the fly frame had a comment: if so, move it to the new anchor as 
well.
+    if (!mpCommentAnchor)
+    {
+        return;
+    }
+
+    SwTextNode* pTextNode = mpCommentAnchor->nNode.GetNode().GetTextNode();
+    if (!pTextNode)
+    {
+        return;
+    }
+
+    const SwTextField* pField = 
pTextNode->GetFieldTextAttrAt(mpCommentAnchor->nContent.GetIndex());
+    if (!pField || pField->GetFormatField().GetField()->GetTyp()->Which() != 
SwFieldIds::Postit)
+    {
+        return;
+    }
+
+    if (!mpWrtShell)
+    {
+        return;
+    }
+
+    // Save current cursor position, so we can restore it later.
+    mpWrtShell->Push();
+
+    // Set up the source of the move: the old comment anchor.
+    {
+        SwPaM& rCursor = mpWrtShell->GetCurrentShellCursor();
+        *rCursor.GetPoint() = *mpCommentAnchor;
+        rCursor.SetMark();
+        *rCursor.GetMark() = *mpCommentAnchor;
+        ++rCursor.GetMark()->nContent;
+    }
+
+    // Set up the target of the move: the new comment anchor.
+    const SwFormatAnchor& rNewAnchorFormat = mrFlyFrameFormat.GetAnchor();
+    mpWrtShell->CreateCursor();
+    *mpWrtShell->GetCurrentShellCursor().GetPoint() = 
*rNewAnchorFormat.GetContentAnchor();
+
+    // Move by copying and deleting.
+    mpWrtShell->SwEditShell::Copy(mpWrtShell);
+    mpWrtShell->DestroyCursor();
+
+    mpWrtShell->Delete();
+
+    mpWrtShell->Pop(SwCursorShell::PopMode::DeleteCurrent);
 }
 
 namespace sw
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to