[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-6.0' - sw/inc sw/qa sw/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Wed Jul 10 14:06:56 UTC 2019


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

New commits:
commit c4b07455859c8ae7e5c3af12c36f03d52b7de4f8
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Tue Jul 9 17:48:14 2019 +0200
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Wed Jul 10 16:06:19 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/75347
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice at gmail.com>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/sw/inc/HandleAnchorNodeChg.hxx b/sw/inc/HandleAnchorNodeChg.hxx
index 576efa46890f..6cf907227de7 100644
--- a/sw/inc/HandleAnchorNodeChg.hxx
+++ b/sw/inc/HandleAnchorNodeChg.hxx
@@ -64,6 +64,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/inc/swrect.hxx b/sw/inc/swrect.hxx
index 924e4adc2ebd..03d252d3101f 100644
--- a/sw/inc/swrect.hxx
+++ b/sw/inc/swrect.hxx
@@ -23,6 +23,7 @@
 
 #include <sal/log.hxx>
 #include <tools/gen.hxx>
+#include "swdllapi.h"
 
 class SvStream;
 
@@ -30,7 +31,7 @@ class SvStream;
 /// This is half-open so m_Point.X() + m_Size.getWidth() is *not* included.
 /// Note the tools Rectangle is (usually? sometimes?) closed so there's a
 /// SVRect() to subtract 1 for the conversion.
-class SAL_WARN_UNUSED SwRect
+class SAL_WARN_UNUSED SW_DLLPUBLIC SwRect
 {
     Point m_Point;
     Size m_Size;
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 7f161e0d9369..954db3082ea1 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -29,6 +29,7 @@
 #include <sfx2/dispatch.hxx>
 #include <view.hxx>
 #include <cmdid.h>
+#include <fmtanchr.hxx>
 
 namespace
 {
@@ -570,6 +571,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);
 }
 
 CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest2);
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
index 118f551cbf4c..807816542d4b 100644
--- a/sw/source/core/layout/atrfrm.cxx
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -80,13 +80,13 @@
 #include <pagedeschint.hxx>
 #include <drawdoc.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;
 
@@ -3237,15 +3237,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() &&
@@ -3286,6 +3287,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()
@@ -3294,6 +3307,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);
 }
 
 //  class SwDrawFrameFormat


More information about the Libreoffice-commits mailing list