diff options
author | Regina Henschel <rb.henschel@t-online.de> | 2019-11-28 19:28:29 +0100 |
---|---|---|
committer | Regina Henschel <rb.henschel@t-online.de> | 2019-12-11 23:42:39 +0100 |
commit | f44140bebb9c493d97ba5aef26c9692c53a6b93f (patch) | |
tree | 6673c5852aed328a2d884f8615bb84a3a86a28c3 /sc | |
parent | 2ae964f88a4f1002a4fd8a804a079559c3d64196 (diff) |
tdf#119191 Implement SdrObjCustomShape::AdjustToMaxRect
and use in ScDrawLayer::RecalcPos and in ScDrawView::FitToCellSize().
Error was, that it was assumed, that SdObjCustomShape::SetSnapRect()
changes the shape so, that it fits into the passed rectangle. That is
true for other type of shapes, but not for custom shapes.
Change-Id: Ib00d52087509f459165000abf43c7f244980a01b
Reviewed-on: https://gerrit.libreoffice.org/84216
Tested-by: Jenkins
Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/CppunitTest_sc_shapetest.mk | 53 | ||||
-rw-r--r-- | sc/Module_sc.mk | 1 | ||||
-rw-r--r-- | sc/qa/unit/data/ods/tdf119191_FitToCellSize.ods | bin | 0 -> 10623 bytes | |||
-rw-r--r-- | sc/qa/unit/data/ods/tdf119191_transformedShape.ods | bin | 0 -> 10269 bytes | |||
-rw-r--r-- | sc/qa/unit/scshapetest.cxx | 189 | ||||
-rw-r--r-- | sc/source/core/data/drwlayer.cxx | 5 | ||||
-rw-r--r-- | sc/source/ui/view/drawvie4.cxx | 6 |
7 files changed, 251 insertions, 3 deletions
diff --git a/sc/CppunitTest_sc_shapetest.mk b/sc/CppunitTest_sc_shapetest.mk new file mode 100644 index 000000000000..cf97cf99da13 --- /dev/null +++ b/sc/CppunitTest_sc_shapetest.mk @@ -0,0 +1,53 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +#************************************************************************* +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#************************************************************************* + +$(eval $(call gb_CppunitTest_CppunitTest,sc_shapetest)) + +$(eval $(call gb_CppunitTest_use_external,sc_shapetest,boost_headers)) + +$(eval $(call gb_CppunitTest_use_common_precompiled_header,sc_shapetest)) + +$(eval $(call gb_CppunitTest_add_exception_objects,sc_shapetest, \ + sc/qa/unit/scshapetest \ +)) + +$(eval $(call gb_CppunitTest_use_libraries,sc_shapetest, \ + cppu \ + sal \ + sc \ + sfx \ + subsequenttest \ + svx \ + svxcore \ + test \ + tl \ + unotest \ + utl \ +)) + +$(eval $(call gb_CppunitTest_set_include,sc_shapetest,\ + -I$(SRCDIR)/sc/source/ui/inc \ + -I$(SRCDIR)/sc/inc \ + $$(INCLUDE) \ +)) + +$(eval $(call gb_CppunitTest_use_sdk_api,sc_shapetest)) + +$(eval $(call gb_CppunitTest_use_ure,sc_shapetest)) +$(eval $(call gb_CppunitTest_use_vcl,sc_shapetest)) + +$(eval $(call gb_CppunitTest_use_components,sc_shapetest,\ + $(sc_unoapi_common_components) \ +)) + +$(eval $(call gb_CppunitTest_use_configuration,sc_shapetest)) + +# vim: set noet sw=4 ts=4: diff --git a/sc/Module_sc.mk b/sc/Module_sc.mk index cbe32e32ebc2..d52537f1c908 100644 --- a/sc/Module_sc.mk +++ b/sc/Module_sc.mk @@ -48,6 +48,7 @@ $(eval $(call gb_Module_add_check_targets,sc,\ CppunitTest_sc_dataprovider \ CppunitTest_sc_datatransformation \ CppunitTest_sc_cache_test \ + CppunitTest_sc_shapetest \ )) ifneq ($(DISABLE_GUI),TRUE) diff --git a/sc/qa/unit/data/ods/tdf119191_FitToCellSize.ods b/sc/qa/unit/data/ods/tdf119191_FitToCellSize.ods Binary files differnew file mode 100644 index 000000000000..ff43af5f7589 --- /dev/null +++ b/sc/qa/unit/data/ods/tdf119191_FitToCellSize.ods diff --git a/sc/qa/unit/data/ods/tdf119191_transformedShape.ods b/sc/qa/unit/data/ods/tdf119191_transformedShape.ods Binary files differnew file mode 100644 index 000000000000..c3936a269627 --- /dev/null +++ b/sc/qa/unit/data/ods/tdf119191_transformedShape.ods diff --git a/sc/qa/unit/scshapetest.cxx b/sc/qa/unit/scshapetest.cxx new file mode 100644 index 000000000000..8e3cbe2c7802 --- /dev/null +++ b/sc/qa/unit/scshapetest.cxx @@ -0,0 +1,189 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <test/calc_unoapi_test.hxx> + +#include <sfx2/dispatch.hxx> +#include <svx/svdoashp.hxx> +#include <svx/svdpage.hxx> + +#include <docsh.hxx> +#include <drwlayer.hxx> +#include <tabvwsh.hxx> +#include <userdat.hxx> + +#include <sc.hrc> // defines of slot-IDs + +using namespace css; + +namespace sc_apitest +{ +class ScShapeTest : public CalcUnoApiTest +{ +public: + ScShapeTest(); + + virtual void tearDown() override; + + void testFitToCellSize(); + void testCustomShapeCellAnchoredRotatedShape(); + + CPPUNIT_TEST_SUITE(ScShapeTest); + CPPUNIT_TEST(testFitToCellSize); + CPPUNIT_TEST(testCustomShapeCellAnchoredRotatedShape); + CPPUNIT_TEST_SUITE_END(); + +private: + uno::Reference<lang::XComponent> mxComponent; +}; + +ScShapeTest::ScShapeTest() + : CalcUnoApiTest("sc/qa/unit/data/ods") +{ +} + +static OUString lcl_compareRectWithTolerance(const tools::Rectangle& rExpected, + const tools::Rectangle& rActual, + const sal_Int32 nTolerance) +{ + OUString sErrors; + if (labs(rExpected.Left() - rActual.Left()) > nTolerance) + sErrors += "\nLeft expected " + OUString::number(rExpected.Left()) + " actual " + + OUString::number(rActual.Left()) + " Tolerance " + + OUString::number(nTolerance); + if (labs(rExpected.Top() - rActual.Top()) > nTolerance) + sErrors += "\nTop expected " + OUString::number(rExpected.Top()) + " actual " + + OUString::number(rActual.Top()) + " Tolerance " + OUString::number(nTolerance); + if (labs(rExpected.GetWidth() - rActual.GetWidth()) > nTolerance) + sErrors += "\nWidth expected " + OUString::number(rExpected.GetWidth()) + " actual " + + OUString::number(rActual.GetWidth()) + " Tolerance " + + OUString::number(nTolerance); + if (labs(rExpected.GetHeight() - rActual.GetHeight()) > nTolerance) + sErrors += "\nHeight expected " + OUString::number(rExpected.GetHeight()) + " actual " + + OUString::number(rActual.GetHeight()) + " Tolerance " + + OUString::number(nTolerance); + return sErrors; +} + +void ScShapeTest::testFitToCellSize() +{ + // The document has a cell anchored custom shape. Applying + // FitToCellSize should resize and position the shape so, + // that it fits into its anchor cell. That did not happened. + OUString aFileURL; + createFileURL("tdf119191_FitToCellSize.ods", aFileURL); + uno::Reference<css::lang::XComponent> xComponent = loadFromDesktop(aFileURL); + CPPUNIT_ASSERT(xComponent.is()); + + // Get the document model + SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent); + CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell); + + ScDocShell* pDocSh = dynamic_cast<ScDocShell*>(pFoundShell); + CPPUNIT_ASSERT(pDocSh); + + // Get the shape + ScDocument& rDoc = pDocSh->GetDocument(); + ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer(); + CPPUNIT_ASSERT(pDrawLayer); + + const SdrPage* pPage = pDrawLayer->GetPage(0); + CPPUNIT_ASSERT(pPage); + + SdrObjCustomShape* pObj = dynamic_cast<SdrObjCustomShape*>(pPage->GetObj(0)); + CPPUNIT_ASSERT(pObj); + + // Get the document controller + ScTabViewShell* pViewShell = pDocSh->GetBestViewShell(false); + CPPUNIT_ASSERT(pViewShell); + + // Get the draw view of the document + ScDrawView* pDrawView = pViewShell->GetViewData().GetScDrawView(); + CPPUNIT_ASSERT(pDrawView); + + // Select the shape + pDrawView->MarkNextObj(); + CPPUNIT_ASSERT(pDrawView->AreObjectsMarked()); + + // Fit selected shape into cell + pViewShell->GetViewData().GetDispatcher().Execute(SID_FITCELLSIZE); + + const tools::Rectangle& rShapeRect(pObj->GetSnapRect()); + const tools::Rectangle aCellRect = rDoc.GetMMRect(1, 1, 1, 1, 0); + const OUString sErrors(lcl_compareRectWithTolerance(aCellRect, rShapeRect, 1)); + CPPUNIT_ASSERT_EQUAL(OUString(), sErrors); + + pDocSh->DoClose(); +} + +void ScShapeTest::testCustomShapeCellAnchoredRotatedShape() +{ + // The example doc contains a cell anchored custom shape that is rotated + // and sheared. Error was, that the shape lost position and size on + // loading. + OUString aFileURL; + createFileURL("tdf119191_transformedShape.ods", aFileURL); + uno::Reference<css::lang::XComponent> xComponent = loadFromDesktop(aFileURL); + CPPUNIT_ASSERT(xComponent.is()); + + // Get the document model + SfxObjectShell* pFoundShell = SfxObjectShell::GetShellFromComponent(xComponent); + CPPUNIT_ASSERT_MESSAGE("Failed to access document shell", pFoundShell); + + ScDocShell* pDocSh = dynamic_cast<ScDocShell*>(pFoundShell); + CPPUNIT_ASSERT(pDocSh); + + // Get the shape + ScDocument& rDoc = pDocSh->GetDocument(); + ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer(); + CPPUNIT_ASSERT(pDrawLayer); + + const SdrPage* pPage = pDrawLayer->GetPage(0); + CPPUNIT_ASSERT(pPage); + + SdrObjCustomShape* pObj = dynamic_cast<SdrObjCustomShape*>(pPage->GetObj(0)); + CPPUNIT_ASSERT(pObj); + + // Check Position and Size + tools::Rectangle aRect(2406, 754, 5774, 3692); // expected snap rect + rDoc.SetDrawPageSize(0); // trigger recalcpos + const tools::Rectangle& rShapeRect(pObj->GetSnapRect()); + const OUString sPosSizeErrors(lcl_compareRectWithTolerance(aRect, rShapeRect, 1)); + CPPUNIT_ASSERT_EQUAL(OUString(), sPosSizeErrors); + + // Check anchor + ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj); + CPPUNIT_ASSERT_MESSAGE("expected object meta data", pData); + + const OUString sExpected("start col 1 row 1 end col 2 row 8"); + const OUString sActual("start col " + OUString::number(pData->maStart.Col()) + " row " + + OUString::number(pData->maStart.Row()) + " end col " + + OUString::number(pData->maEnd.Col()) + " row " + + OUString::number(pData->maEnd.Row())); + CPPUNIT_ASSERT_EQUAL(sExpected, sActual); + + pDocSh->DoClose(); +} + +void ScShapeTest::tearDown() +{ + if (mxComponent.is()) + { + closeDocument(mxComponent); + } + + CalcUnoApiTest::tearDown(); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(ScShapeTest); +} + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx index 4dd80df9a85a..515118d84c23 100644 --- a/sc/source/core/data/drwlayer.cxx +++ b/sc/source/core/data/drwlayer.cxx @@ -1038,7 +1038,10 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati // order of these lines is important, modify rData.maLastRect carefully it is used as both // a value and a flag for initialisation rData.setShapeRect(GetDocument(), lcl_makeSafeRectangle(rData.getShapeRect()), pObj->IsVisible()); - pObj->SetSnapRect(rData.getShapeRect()); + if (pObj->GetObjIdentifier() == OBJ_CUSTOMSHAPE) + pObj->AdjustToMaxRect(rData.getShapeRect()); + else + pObj->SetSnapRect(rData.getShapeRect()); // update 'unrotated anchor' it's the anchor we persist, it must be kept in sync // with the normal Anchor ResizeLastRectFromAnchor( pObj, rNoRotatedAnchor, true, bNegativePage, bCanResize ); diff --git a/sc/source/ui/view/drawvie4.cxx b/sc/source/ui/view/drawvie4.cxx index e1f0d04da7a4..25c64c2e5ef3 100644 --- a/sc/source/ui/view/drawvie4.cxx +++ b/sc/source/ui/view/drawvie4.cxx @@ -569,8 +569,10 @@ void ScDrawView::FitToCellSize() } pUndoGroup->AddAction( std::make_unique<SdrUndoGeoObj>( *pObj ) ); - - pObj->SetSnapRect(aCellRect); + if (pObj->GetObjIdentifier() == OBJ_CUSTOMSHAPE) + pObj->AdjustToMaxRect(aCellRect); + else + pObj->SetSnapRect(aCellRect); pUndoGroup->SetComment(ScResId( STR_UNDO_FITCELLSIZE )); ScDocShell* pDocSh = pViewData->GetDocShell(); |