sw/qa/extras/uiwriter/data2/shape-page-move.odt |binary
 sw/qa/extras/uiwriter/uiwriter2.cxx             |   59 ++++++++++++++++++++++--
 sw/source/uibase/shells/drwbassh.cxx            |   15 ++++++
 3 files changed, 71 insertions(+), 3 deletions(-)

New commits:
commit 50ed2c28aeb5598d51b61278cc38b05d13b83a43
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Jul 10 16:04:05 2019 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon Jul 15 15:32:18 2019 +0200

    sw: fix TransformDialog with args when the shape moves to a different page
    
    When a macro or Online invokes .uno:TransformDialog with arguments, then
    instead of showing the dialog, we apply the position/size/etc settings
    to the currently selected shape.
    
    This was not working correctly when setting an absolute twips position
    where the old and the new containing page frame was different.
    
    The desktop case drag&drop invokes SwFEShell::EndDrag(), which uses
    SwFEShell::ChgAnchor() to maintain the invariant that a draw shape
    position and its anchor is contained within the same page frame.
    
    The same was not true when SwDrawBaseShell::Execute() calls
    SdrEditView::SetGeoAttrToMarked(), so extend that a bit to also update
    the anchor position.
    
    With this, moving down a shape from the 1st page to the 2nd one via the
    API works and updates the anchor correctly, while in the past the move
    was only possible within the bounds of the current page frame. (See the
    "determine and set position" code in SwAnchoredDrawObject that enforces
    this invariant when the anchor is not updated.)
    
    (cherry picked from commit c54597a8905b07807952aebc24237549302fb941)
    
    Conflicts:
            sw/qa/extras/uiwriter/uiwriter2.cxx
    
    Change-Id: Ia54470f6f3679ddc78a2f0a842f2fca10d20084d
    Reviewed-on: https://gerrit.libreoffice.org/75365
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/qa/extras/uiwriter/data2/shape-page-move.odt 
b/sw/qa/extras/uiwriter/data2/shape-page-move.odt
new file mode 100644
index 000000000000..80672b2448a2
Binary files /dev/null and b/sw/qa/extras/uiwriter/data2/shape-page-move.odt 
differ
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx 
b/sw/qa/extras/uiwriter/uiwriter2.cxx
index d19db15bae8f..7bff975e94c2 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -27,9 +27,11 @@
 #include <fmtornt.hxx>
 #include <sfx2/viewfrm.hxx>
 #include <sfx2/dispatch.hxx>
+#include <svx/svxids.hrc>
 #include <view.hxx>
 #include <cmdid.h>
 #include <fmtanchr.hxx>
+#include <txtfrm.hxx>
 
 namespace
 {
@@ -57,6 +59,7 @@ public:
     void testDateFormFieldContentOperations();
     void testDateFormFieldCurrentDateHandling();
     void testDateFormFieldCurrentDateInvalidation();
+    void testShapePageMove();
 
     CPPUNIT_TEST_SUITE(SwUiWriterTest2);
     CPPUNIT_TEST(testTdf101534);
@@ -75,6 +78,7 @@ public:
     CPPUNIT_TEST(testDateFormFieldContentOperations);
     CPPUNIT_TEST(testDateFormFieldCurrentDateHandling);
     CPPUNIT_TEST(testDateFormFieldCurrentDateInvalidation);
+    CPPUNIT_TEST(testShapePageMove);
     CPPUNIT_TEST_SUITE_END();
 
 private:
@@ -662,7 +666,8 @@ void SwUiWriterTest2::testDateFormFieldContentOperations()
     // Check whether the fieldmark is created
     auto aIter = pMarkAccess->getAllMarksBegin();
     CPPUNIT_ASSERT(aIter != pMarkAccess->getAllMarksEnd());
-    ::sw::mark::IDateFieldmark* pFieldmark = 
dynamic_cast<::sw::mark::IDateFieldmark*>(aIter->get());
+    ::sw::mark::IDateFieldmark* pFieldmark
+        = dynamic_cast<::sw::mark::IDateFieldmark*>(aIter->get());
     CPPUNIT_ASSERT(pFieldmark);
     CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname());
 
@@ -695,7 +700,8 @@ void SwUiWriterTest2::testDateFormFieldCurrentDateHandling()
     // Check whether the fieldmark is created
     auto aIter = pMarkAccess->getAllMarksBegin();
     CPPUNIT_ASSERT(aIter != pMarkAccess->getAllMarksEnd());
-    ::sw::mark::IDateFieldmark* pFieldmark = 
dynamic_cast<::sw::mark::IDateFieldmark*>(aIter->get());
+    ::sw::mark::IDateFieldmark* pFieldmark
+        = dynamic_cast<::sw::mark::IDateFieldmark*>(aIter->get());
     CPPUNIT_ASSERT(pFieldmark);
     CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname());
 
@@ -748,7 +754,8 @@ void 
SwUiWriterTest2::testDateFormFieldCurrentDateInvalidation()
     // Check whether the fieldmark is created
     auto aIter = pMarkAccess->getAllMarksBegin();
     CPPUNIT_ASSERT(aIter != pMarkAccess->getAllMarksEnd());
-    ::sw::mark::IDateFieldmark* pFieldmark = 
dynamic_cast<::sw::mark::IDateFieldmark*>(aIter->get());
+    ::sw::mark::IDateFieldmark* pFieldmark
+        = dynamic_cast<::sw::mark::IDateFieldmark*>(aIter->get());
     CPPUNIT_ASSERT(pFieldmark);
     CPPUNIT_ASSERT_EQUAL(OUString(ODF_FORMDATE), pFieldmark->GetFieldname());
 
@@ -790,6 +797,52 @@ void 
SwUiWriterTest2::testDateFormFieldCurrentDateInvalidation()
     CPPUNIT_ASSERT_EQUAL(OUString(""), sCurrentDate);
 }
 
+void SwUiWriterTest2::testShapePageMove()
+{
+    // Load a document with 2 pages, shape on the first page.
+    SwDoc* pDoc = createDoc("shape-page-move.odt");
+    SwView* pView = pDoc->GetDocShell()->GetView();
+    // Make sure that the 2nd page is below the 1st one.
+    pView->SetViewLayout(/*nColumns=*/1, /*bBookMode=*/false);
+    calcLayout();
+
+    // Select the shape.
+    pView->GetViewFrame()->GetDispatcher()->Execute(FN_CNTNT_TO_NEXT_FRAME, 
SfxCallMode::SYNCHRON);
+    // Make sure SwTextShell is replaced with SwDrawShell right now, not after 
120 ms, as set in the
+    // SwView ctor.
+    pView->StopShellTimer();
+
+    // Move the shape down to the 2nd page.
+    SfxInt32Item aXItem(SID_ATTR_TRANSFORM_POS_X, 4000);
+    SfxInt32Item aYItem(SID_ATTR_TRANSFORM_POS_Y, 12000);
+    pView->GetViewFrame()->GetDispatcher()->ExecuteList(SID_ATTR_TRANSFORM, 
SfxCallMode::SYNCHRON,
+                                                        { &aXItem, &aYItem });
+
+    // Check if the shape anchor was moved to the 2nd page as well.
+    SwFrameFormats* pShapeFormats = pDoc->GetSpzFrameFormats();
+    CPPUNIT_ASSERT(!pShapeFormats->empty());
+    auto it = pShapeFormats->begin();
+    SwFrameFormat* pShapeFormat = *it;
+    const SwPosition* pAnchor = pShapeFormat->GetAnchor().GetContentAnchor();
+    CPPUNIT_ASSERT(pAnchor);
+
+    // Find out the node index of the 1st para on the 2nd page.
+    SwRootFrame* pLayout = pDoc->getIDocumentLayoutAccess().GetCurrentLayout();
+    SwFrame* pFirstPage = pLayout->Lower();
+    SwFrame* pSecondPage = pFirstPage->GetNext();
+    CPPUNIT_ASSERT(pSecondPage->IsLayoutFrame());
+    SwFrame* pBodyFrame = static_cast<SwLayoutFrame*>(pSecondPage)->GetLower();
+    CPPUNIT_ASSERT(pBodyFrame->IsLayoutFrame());
+    SwFrame* pTextFrame = static_cast<SwLayoutFrame*>(pBodyFrame)->GetLower();
+    CPPUNIT_ASSERT(pTextFrame->IsTextFrame());
+    sal_uLong nNodeIndex = 
static_cast<SwTextFrame*>(pTextFrame)->GetTextNode()->GetIndex();
+
+    // Without the accompanying fix in place, this test would have failed with 
"Expected: 13;
+    // Actual: 12", i.e. the shape was anchored to the last paragraph of the 
1st page, not to a
+    // paragraph on the 2nd page.
+    CPPUNIT_ASSERT_EQUAL(nNodeIndex, pAnchor->nNode.GetIndex());
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(SwUiWriterTest2);
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/shells/drwbassh.cxx 
b/sw/source/uibase/shells/drwbassh.cxx
index 5674182d08db..e47fd6aafc4f 100644
--- a/sw/source/uibase/shells/drwbassh.cxx
+++ b/sw/source/uibase/shells/drwbassh.cxx
@@ -349,7 +349,22 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq)
                 }
                 else
                 {
+                    pSh->StartAllAction();
                     pSdrView->SetGeoAttrToMarked( *pArgs );
+                    const SdrMarkList& rMarkList = 
pSdrView->GetMarkedObjectList();
+                    SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+                    if (pObj)
+                    {
+                        SwFrameFormat* pFrameFormat = FindFrameFormat(pObj);
+                        if (pFrameFormat)
+                        {
+                            const SwFormatAnchor& rAnchor = 
pFrameFormat->GetAnchor();
+                            // Don't change shape position / size, just update 
the anchor doc model
+                            // position.
+                            pSh->ChgAnchor(rAnchor.GetAnchorId(), 
/*bSameOnly=*/true);
+                        }
+                    }
+                    pSh->EndAllAction();
                 }
             }
         }
_______________________________________________
Libreoffice-commits mailing list
libreoffice-comm...@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits

Reply via email to