[Libreoffice-commits] core.git: Branch 'libreoffice-7-1' - sc/qa sc/source

Regina Henschel (via logerrit) logerrit at kemper.freedesktop.org
Thu Dec 3 09:18:41 UTC 2020


 sc/qa/unit/data/ods/ManualColWidthRowHeight.ods |binary
 sc/qa/unit/scshapetest.cxx                      |  121 ++++++++++++++++++++++++
 sc/source/core/data/drwlayer.cxx                |   22 ++--
 3 files changed, 135 insertions(+), 8 deletions(-)

New commits:
commit 9706790b1e4d34d0fac5eb10a51770f9d62f802c
Author:     Regina Henschel <rb.henschel at t-online.de>
AuthorDate: Tue Dec 1 00:05:43 2020 +0100
Commit:     Xisco Fauli <xiscofauli at libreoffice.org>
CommitDate: Thu Dec 3 10:18:06 2020 +0100

    tdf#137576 Improve cell anchored measure line in Calc
    
    Measure lines do not always have a logic rectangle. It might be empty
    or the 1cm x 1cm default square. But Calc needs it to calculate
    NonRotatedAnchor. The latter is needed for cell anchored shapes when
    saving in ODF. Always generating a logic rectangle in class
    SdrMeasureObj is difficult (I got crashes in Draw) and not necessary.
    Calc now forces the calculation of the logic rectangle where it is
    needed by Calc.
    
    Change-Id: I8689bc95985db1619eb5e72df99901bd52086cb2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106990
    Tested-by: Jenkins
    Reviewed-by: Regina Henschel <rb.henschel at t-online.de>
    Signed-off-by: Xisco Fauli <xiscofauli at libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/107131

diff --git a/sc/qa/unit/data/ods/ManualColWidthRowHeight.ods b/sc/qa/unit/data/ods/ManualColWidthRowHeight.ods
new file mode 100644
index 000000000000..1cc738e05244
Binary files /dev/null and b/sc/qa/unit/data/ods/ManualColWidthRowHeight.ods differ
diff --git a/sc/qa/unit/scshapetest.cxx b/sc/qa/unit/scshapetest.cxx
index 9362d3d76a87..4458c71e1d2f 100644
--- a/sc/qa/unit/scshapetest.cxx
+++ b/sc/qa/unit/scshapetest.cxx
@@ -16,10 +16,12 @@
 #include <comphelper/dispatchcommand.hxx>
 #include <comphelper/propertyvalue.hxx>
 #include <sfx2/dispatch.hxx>
+#include <sfx2/request.hxx>
 #include <svx/svdoashp.hxx>
 #include <svx/svdomeas.hxx>
 #include <svx/svdpage.hxx>
 #include <unotools/tempfile.hxx>
+#include <vcl/keycodes.hxx>
 
 #include <docsh.hxx>
 #include <drwlayer.hxx>
@@ -38,6 +40,8 @@ public:
     ScShapeTest();
     void saveAndReload(css::uno::Reference<css::lang::XComponent>& xComponent,
                        const OUString& rFilter);
+    void testTdf137576_LogicRectInDefaultMeasureline();
+    void testTdf137576_LogicRectInNewMeasureline();
     void testMeasurelineHideColSave();
     void testHideColsShow();
     void testTdf138138_MoveCellWithRotatedShape();
@@ -49,6 +53,8 @@ public:
     void testCustomShapeCellAnchoredRotatedShape();
 
     CPPUNIT_TEST_SUITE(ScShapeTest);
+    CPPUNIT_TEST(testTdf137576_LogicRectInDefaultMeasureline);
+    CPPUNIT_TEST(testTdf137576_LogicRectInNewMeasureline);
     CPPUNIT_TEST(testMeasurelineHideColSave);
     CPPUNIT_TEST(testHideColsShow);
     CPPUNIT_TEST(testTdf138138_MoveCellWithRotatedShape);
@@ -124,6 +130,121 @@ static void lcl_AssertPointEqualWithTolerance(const OString& sInfo, const Point
     CPPUNIT_ASSERT_MESSAGE(sMsg.getStr(), std::abs(rExpected.Y() - rActual.Y()) <= nTolerance);
 }
 
+void ScShapeTest::testTdf137576_LogicRectInDefaultMeasureline()
+{
+    // Error was, that the empty logical rectangle of a default measure line (Ctrl+Click)
+    // resulted in zeros in NonRotatedAnchor and a wrong position when reloading.
+
+    // Load an empty document.
+    OUString aFileURL;
+    createFileURL("ManualColWidthRowHeight.ods", aFileURL);
+    uno::Reference<css::lang::XComponent> xComponent = loadFromDesktop(aFileURL);
+    CPPUNIT_ASSERT(xComponent.is());
+
+    // Get ScDocShell
+    SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent);
+    CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell);
+    ScDocShell* pDocSh = dynamic_cast<ScDocShell*>(pFoundShell);
+    CPPUNIT_ASSERT_MESSAGE("No ScDocShell", pDocSh);
+
+    // Create default measureline by SfxRequest that corresponds to Ctrl+Click
+    ScTabViewShell* pTabViewShell = pDocSh->GetBestViewShell(false);
+    CPPUNIT_ASSERT_MESSAGE("No ScTabViewShell", pTabViewShell);
+    SfxRequest aReq(pTabViewShell->GetViewFrame(), SID_DRAW_MEASURELINE);
+    aReq.SetModifier(KEY_MOD1); // Ctrl
+    pTabViewShell->ExecDraw(aReq);
+
+    // Get document and newly created measure line.
+    ScDocument& rDoc = pDocSh->GetDocument();
+    ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
+    CPPUNIT_ASSERT_MESSAGE("No ScDrawLayer", pDrawLayer);
+    const SdrPage* pPage = pDrawLayer->GetPage(0);
+    CPPUNIT_ASSERT_MESSAGE("No draw page", pPage);
+    SdrObject* pObj = pPage->GetObj(0);
+    CPPUNIT_ASSERT_MESSAGE("No object found", pObj);
+
+    // Anchor "to Cell (resize with cell)"
+    ScDrawLayer::SetCellAnchoredFromPosition(*pObj, rDoc, 0 /*SCTAB*/, true /*bResizeWithCell*/);
+    // Deselect shape and switch to object selection type "Cell".
+    pTabViewShell->SetDrawShell(false);
+
+    // Hide column A.
+    uno::Sequence<beans::PropertyValue> aPropertyValues = {
+        comphelper::makePropertyValue("ToPoint", OUString("$A$1")),
+    };
+    dispatchCommand(xComponent, ".uno:GoToCell", aPropertyValues);
+    dispatchCommand(xComponent, ".uno:HideColumn", {});
+
+    // Get current position. I will not use absolute values for comparison, because document is loaded
+    // in full screen mode of unknown size and default object is placed in center of window.
+    Point aOldPos = pObj->GetRelativePos();
+
+    // Save and reload, get ScDocShell
+    saveAndReload(xComponent, "calc8");
+    CPPUNIT_ASSERT(xComponent);
+    pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent);
+    CPPUNIT_ASSERT_MESSAGE("Reload: Failed to access document shell", pFoundShell);
+    pDocSh = dynamic_cast<ScDocShell*>(pFoundShell);
+    CPPUNIT_ASSERT(pDocSh);
+
+    // Get document and object
+    ScDocument& rDoc2 = pDocSh->GetDocument();
+    pDrawLayer = rDoc2.GetDrawLayer();
+    CPPUNIT_ASSERT_MESSAGE("Reload: No ScDrawLayer", pDrawLayer);
+    pPage = pDrawLayer->GetPage(0);
+    CPPUNIT_ASSERT_MESSAGE("Reload: No draw page", pPage);
+    pObj = pPage->GetObj(0);
+    CPPUNIT_ASSERT_MESSAGE("Measure line lost", pObj);
+
+    // Assert object position is unchanged, besides Twips<->Hmm inaccuracy.
+    Point aNewPos = pObj->GetRelativePos();
+    lcl_AssertPointEqualWithTolerance("after reload", aOldPos, aNewPos, 1);
+
+    pDocSh->DoClose();
+}
+
+void ScShapeTest::testTdf137576_LogicRectInNewMeasureline()
+{
+    // Error was, that a new measure line had no logical rectangle. This resulted in zeros in
+    // NonRotatedAnchor. As a result the position was wrong when reloading.
+
+    // Load an empty document
+    OUString aFileURL;
+    createFileURL("ManualColWidthRowHeight.ods", aFileURL);
+    uno::Reference<css::lang::XComponent> xComponent = loadFromDesktop(aFileURL);
+    CPPUNIT_ASSERT(xComponent.is());
+
+    // Get ScDocShell
+    SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent);
+    CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell);
+    ScDocShell* pDocSh = dynamic_cast<ScDocShell*>(pFoundShell);
+    CPPUNIT_ASSERT(pDocSh);
+
+    // Get SdrPage
+    ScDocument& rDoc = pDocSh->GetDocument();
+    ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
+    CPPUNIT_ASSERT_MESSAGE("No ScDrawLayer", pDrawLayer);
+    SdrPage* pPage = pDrawLayer->GetPage(0);
+    CPPUNIT_ASSERT_MESSAGE("No draw page", pPage);
+
+    // Create a new measure line and insert it
+    Point aStartPoint(5000, 5500);
+    Point aEndPoint(13000, 8000);
+    SdrMeasureObj* pObj = new SdrMeasureObj(*pDrawLayer, aStartPoint, aEndPoint);
+    CPPUNIT_ASSERT_MESSAGE("Could not create measure line", pObj);
+    pPage->InsertObject(pObj);
+
+    // Anchor "to cell (resize with cell)" and examine NonRotatedAnchor
+    ScDrawLayer::SetCellAnchoredFromPosition(*pObj, rDoc, 0 /*SCTAB*/, true /*bResizeWithCell*/);
+    ScDrawObjData* pNData = ScDrawLayer::GetNonRotatedObjData(pObj);
+    CPPUNIT_ASSERT_MESSAGE("Failed to get NonRotatedAnchor", pNData);
+    // Without the fix all four values would be zero.
+    CPPUNIT_ASSERT(pNData->maStart.Col() == 1 && pNData->maStart.Row() == 2);
+    CPPUNIT_ASSERT(pNData->maEnd.Col() == 7 && pNData->maEnd.Row() == 2);
+
+    pDocSh->DoClose();
+}
+
 void ScShapeTest::testMeasurelineHideColSave()
 {
     // The document contains a SdrMeasureObj anchored "To Cell (resive with cell)" with start in cell
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 3901434df913..033602c4e43b 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -36,6 +36,7 @@
 #include <svx/svdobj.hxx>
 #include <svx/svdocapt.hxx>
 #include <svx/svdograf.hxx>
+#include <svx/svdomeas.hxx>
 #include <svx/svdoole2.hxx>
 #include <svx/svdopath.hxx>
 #include <svx/svdtrans.hxx>
@@ -934,14 +935,13 @@ void ScDrawLayer::InitializeCellAnchoredObj(SdrObject* pObj, ScDrawObjData& rDat
         else if (pObj->GetObjIdentifier() == OBJ_MEASURE)
         {
             // Measure lines might have got wrong start and end anchor from XML import. Recreate
-            // them from start and end point.
-            const Point aPoint0(pObj->GetPoint(0));
-            const Point aPoint1(pObj->GetPoint(1));
-            const Point aPointLT(std::min(aPoint0.X(), aPoint1.X()),
-                                 std::min(aPoint0.Y(), aPoint1.Y()));
-            const Point aPointRB(std::max(aPoint0.X(), aPoint1.X()),
-                                 std::max(aPoint0.Y(), aPoint1.Y()));
-            const tools::Rectangle aObjRect(aPointLT, aPointRB);
+            // anchor from start and end point.
+            SdrMeasureObj* pMeasureObj = dynamic_cast<SdrMeasureObj*>(pObj);
+            // tdf#137576. The logic rectangle has likely no current values here, but only the
+            // 1cm x 1cm default size. The call of TakeUnrotatedSnapRect is currently (LO 7.2)
+            // the only way to force a recalc of the logic rectangle.
+            tools::Rectangle aObjRect;
+            pMeasureObj->TakeUnrotatedSnapRect(aObjRect);
             GetCellAnchorFromPosition(aObjRect, rNoRotatedAnchor, *pDoc, rData.maStart.Tab(),
                                       false /*bHiddenAsZero*/);
         }
@@ -2229,6 +2229,12 @@ void ScDrawLayer::SetCellAnchoredFromPosition( SdrObject &rObj, const ScDocument
         aObjRect2 = rObj.GetLogicRect();
         rObj.NbcMirror(aLeft, aRight);
     }
+    else if (rObj.GetObjIdentifier() == OBJ_MEASURE)
+    {
+        // tdf#137576. A SdrMeasureObj might have a wrong logic rect here. TakeUnrotatedSnapRect
+        // calculates the current unrotated snap rectangle, sets logic rectangle and returns it.
+        static_cast<SdrObjCustomShape*>(&rObj)->TakeUnrotatedSnapRect(aObjRect2);
+    }
     else
         aObjRect2 = rObj.GetLogicRect();
 


More information about the Libreoffice-commits mailing list