diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2020-02-24 21:24:33 +0100 |
---|---|---|
committer | Michael Stahl <michael.stahl@cib.de> | 2020-02-27 11:39:30 +0100 |
commit | 0aaa48adee4c2f330f93bf1f1cf7e095c2e9768a (patch) | |
tree | badfc2d819a9f34f4f0060cd397b420b11f44f94 /sw | |
parent | b66415692433a7a63d8cfcaf14d0714efda02105 (diff) |
tdf#91219 sw: don't allow anchoring a shape+textbox into itself
We already have code that detects this in the simple fly frame case,
extend that to cover the "paired fly frame + draw shape" case as well.
Change-Id: I4b3c1d600407436b239fee311ae6bfe837804241
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89381
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89536
Reviewed-by: Michael Stahl <michael.stahl@cib.de>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/CppunitTest_sw_core_frmedt.mk | 73 | ||||
-rw-r--r-- | sw/Module_sw.mk | 1 | ||||
-rw-r--r-- | sw/qa/core/frmedt/data/textbox-reanchor.odt | bin | 0 -> 9364 bytes | |||
-rw-r--r-- | sw/qa/core/frmedt/frmedt.cxx | 63 | ||||
-rw-r--r-- | sw/source/core/frmedt/fefly1.cxx | 19 |
5 files changed, 155 insertions, 1 deletions
diff --git a/sw/CppunitTest_sw_core_frmedt.mk b/sw/CppunitTest_sw_core_frmedt.mk new file mode 100644 index 000000000000..5f283bdadfba --- /dev/null +++ b/sw/CppunitTest_sw_core_frmedt.mk @@ -0,0 +1,73 @@ +# -*- 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,sw_core_frmedt)) + +$(eval $(call gb_CppunitTest_use_common_precompiled_header,sw_core_frmedt)) + +$(eval $(call gb_CppunitTest_add_exception_objects,sw_core_frmedt, \ + sw/qa/core/frmedt/frmedt \ +)) + +$(eval $(call gb_CppunitTest_use_libraries,sw_core_frmedt, \ + comphelper \ + cppu \ + cppuhelper \ + sal \ + sfx \ + svxcore \ + sw \ + test \ + unotest \ + utl \ + vcl \ + svt \ + tl \ + svl \ +)) + +$(eval $(call gb_CppunitTest_use_externals,sw_core_frmedt,\ + boost_headers \ + libxml2 \ +)) + +$(eval $(call gb_CppunitTest_set_include,sw_core_frmedt,\ + -I$(SRCDIR)/sw/inc \ + -I$(SRCDIR)/sw/source/core/inc \ + -I$(SRCDIR)/sw/source/uibase/inc \ + -I$(SRCDIR)/sw/qa/inc \ + $$(INCLUDE) \ +)) + +$(eval $(call gb_CppunitTest_use_api,sw_core_frmedt,\ + udkapi \ + offapi \ + oovbaapi \ +)) + +$(eval $(call gb_CppunitTest_use_ure,sw_core_frmedt)) +$(eval $(call gb_CppunitTest_use_vcl,sw_core_frmedt)) + +$(eval $(call gb_CppunitTest_use_rdb,sw_core_frmedt,services)) + +$(eval $(call gb_CppunitTest_use_custom_headers,sw_core_frmedt,\ + officecfg/registry \ +)) + +$(eval $(call gb_CppunitTest_use_configuration,sw_core_frmedt)) + +$(eval $(call gb_CppunitTest_use_uiconfigs,sw_core_frmedt, \ + modules/swriter \ +)) + +$(eval $(call gb_CppunitTest_use_more_fonts,sw_core_frmedt)) + +# vim: set noet sw=4 ts=4: diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk index 06ab4c8f8fa3..470e7b545971 100644 --- a/sw/Module_sw.mk +++ b/sw/Module_sw.mk @@ -107,6 +107,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sw,\ CppunitTest_sw_core_text \ CppunitTest_sw_core_doc \ CppunitTest_sw_uibase_shells \ + CppunitTest_sw_core_frmedt \ )) ifneq ($(DISABLE_GUI),TRUE) diff --git a/sw/qa/core/frmedt/data/textbox-reanchor.odt b/sw/qa/core/frmedt/data/textbox-reanchor.odt Binary files differnew file mode 100644 index 000000000000..dd4eb69d1701 --- /dev/null +++ b/sw/qa/core/frmedt/data/textbox-reanchor.odt diff --git a/sw/qa/core/frmedt/frmedt.cxx b/sw/qa/core/frmedt/frmedt.cxx new file mode 100644 index 000000000000..cf3d1945e049 --- /dev/null +++ b/sw/qa/core/frmedt/frmedt.cxx @@ -0,0 +1,63 @@ +/* -*- 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 <swmodeltestbase.hxx> + +#include <vcl/gdimtf.hxx> +#include <comphelper/classids.hxx> +#include <tools/globname.hxx> +#include <svtools/embedhlp.hxx> +#include <svx/svdpage.hxx> + +#include <wrtsh.hxx> +#include <fmtanchr.hxx> +#include <IDocumentDrawModelAccess.hxx> +#include <drawdoc.hxx> +#include <dcontact.hxx> + +static char const DATA_DIRECTORY[] = "/sw/qa/core/frmedt/data/"; + +/// Covers sw/source/core/frmedt/ fixes. +class SwCoreFrmedtTest : public SwModelTestBase +{ +}; + +CPPUNIT_TEST_FIXTURE(SwCoreFrmedtTest, testTextboxReanchor) +{ + // Load a document with a textframe and a textbox(shape+textframe). + load(DATA_DIRECTORY, "textbox-reanchor.odt"); + SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + SwDoc* pDoc = pTextDoc->GetDocShell()->GetDoc(); + SdrPage* pDrawPage = pDoc->getIDocumentDrawModelAccess().GetDrawModel()->GetPage(0); + SdrObject* pDrawShape = pDrawPage->GetObj(1); + CPPUNIT_ASSERT_EQUAL(OUString("draw shape"), pDrawShape->GetName()); + + // Select the shape of the textbox. + Point aPoint; + SwWrtShell* pShell = pDoc->GetDocShell()->GetWrtShell(); + pShell->SelectObj(aPoint, /*nFlag=*/0, pDrawShape); + + // Anchor the shape of the textbox into its own textframe. + SdrObject* pTextFrameObj = pDrawPage->GetObj(2); + SwFrameFormat* pTextFrameFormat = FindFrameFormat(pTextFrameObj); + CPPUNIT_ASSERT_EQUAL(OUString("Frame2"), pTextFrameFormat->GetName()); + SwFrameFormat* pDrawShapeFormat = FindFrameFormat(pDrawShape); + sal_uLong nOldAnchor = pDrawShapeFormat->GetAnchor().GetContentAnchor()->nNode.GetIndex(); + pShell->FindAnchorPos(pTextFrameObj->GetLastBoundRect().Center(), true); + sal_uLong nNewAnchor = pDrawShapeFormat->GetAnchor().GetContentAnchor()->nNode.GetIndex(); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 6 + // - Actual : 9 + // i.e. SwFEShell allowed to anchor the textframe of a textbox into itself. + CPPUNIT_ASSERT_EQUAL(nOldAnchor, nNewAnchor); +} + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/frmedt/fefly1.cxx b/sw/source/core/frmedt/fefly1.cxx index 0a55c4f969dd..8bb00f312bf4 100644 --- a/sw/source/core/frmedt/fefly1.cxx +++ b/sw/source/core/frmedt/fefly1.cxx @@ -77,6 +77,7 @@ #include <editeng/opaqitem.hxx> #include <fefly.hxx> #include <fmtcnct.hxx> +#include <textboxhelper.hxx> using namespace ::com::sun::star; @@ -447,6 +448,12 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt ) bool bFlyFrame = dynamic_cast<SwVirtFlyDrawObj *>(pObj) != nullptr; + bool bTextBox = false; + if (rFormat.Which() == RES_DRAWFRMFMT) + { + bTextBox = SwTextBoxHelper::isTextBox(&rFormat, RES_DRAWFRMFMT); + } + SwFlyFrame* pFly = nullptr; const SwFrame* pFooterOrHeader = nullptr; @@ -467,6 +474,16 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt ) pFooterOrHeader = pContent->FindFooterOrHeader(); } } + else if (bTextBox) + { + auto pFlyFormat = dynamic_cast<const SwFlyFrameFormat*>( + SwTextBoxHelper::getOtherTextBoxFormat(&rFormat, RES_DRAWFRMFMT)); + if (pFlyFormat) + { + pFly = pFlyFormat->GetFrame(); + } + } + // set <pFooterOrHeader> also for drawing // objects, but not for control objects. // Necessary for moving 'anchor symbol' at the user interface inside header/footer. @@ -514,7 +531,7 @@ Point SwFEShell::FindAnchorPos( const Point& rAbsPos, bool bMoveIt ) if( pNewAnch && !pNewAnch->IsProtected() ) { - const SwFlyFrame* pCheck = bFlyFrame ? pNewAnch->FindFlyFrame() : nullptr; + const SwFlyFrame* pCheck = (bFlyFrame || bTextBox) ? pNewAnch->FindFlyFrame() : nullptr; // If we land inside the frame, make sure // that the frame does not land inside its own content while( pCheck ) |