dev/null |binary sw/inc/textboxhelper.hxx | 16 -- sw/qa/uitest/writer_tests2/ComplexGroupShapeTest.py | 127 -------------------- sw/source/core/doc/docdraw.cxx | 56 +------- sw/source/core/doc/textboxhelper.cxx | 82 +----------- sw/source/core/draw/dcontact.cxx | 6 sw/source/core/draw/dview.cxx | 9 - sw/source/core/unocore/unodraw.cxx | 15 -- 8 files changed, 32 insertions(+), 279 deletions(-)
New commits: commit 6263b7bbff3bdbe1bba0f168fb363b07f60377cf Author: Justin Luth <[email protected]> AuthorDate: Wed Apr 12 09:27:29 2023 -0400 Commit: Andras Timar <[email protected]> CommitDate: Wed Apr 12 21:33:37 2023 +0200 Revert "tdf#143574 sw: textboxes in group shapes - part 3 take 2" This reverts commit d3daa7ed0361785d8667f726340538ada1607937. It was added for T38690 and removed for T41585 There was no urgency to get T38690 out, so these regression-prone patches should not have been backported into to a stable product. All of these patches are in master and LO 7.4, so they will be part of 23.05 already. So T38690 is solved still in 23.05. Change-Id: I113fb13ea9ca62f63d6e74a0da77108ba32cc440 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/150296 Reviewed-by: Andras Timar <[email protected]> Tested-by: Andras Timar <[email protected]> diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx index 924b3e6b5c91..2e5b27cfccb0 100644 --- a/sw/inc/textboxhelper.hxx +++ b/sw/inc/textboxhelper.hxx @@ -65,8 +65,7 @@ public: /// to the given pObject shape. static void destroy(const SwFrameFormat* pShape, const SdrObject* pObject); /// Get interface of a shape's TextBox, if there is any. - static css::uno::Any queryInterface(const SwFrameFormat* pShape, const css::uno::Type& rType, - SdrObject* pObj); + static css::uno::Any queryInterface(const SwFrameFormat* pShape, const css::uno::Type& rType); /// Sync property of TextBox with the one of the shape. static void syncProperty(SwFrameFormat* pShape, sal_uInt16 nWID, sal_uInt8 nMemberID, @@ -108,9 +107,6 @@ public: /// this function, and returns true in that case too. static std::optional<bool> isAnchorTypeDifferent(const SwFrameFormat* pShape); - /// Sets the correct size of textframe depending on the given SdrObject. - static bool syncTextBoxSize(SwFrameFormat* pShape, SdrObject* pObj); - /// Returns true if the given shape has a valid textframe. static bool isTextBoxShapeHasValidTextFrame(const SwFrameFormat* pShape); @@ -181,14 +177,6 @@ public: /// Undo the effect of saveLinks() + individual resetLink() calls. static void restoreLinks(std::set<ZSortFly>& rOld, std::vector<SwFrameFormat*>& rNew, SavedLink& rSavedLinks); - - /// Calls the method given by pFunc with every textboxes of the group given by pFormat. - static void synchronizeGroupTextBoxProperty(bool pFunc(SwFrameFormat*, SdrObject*), - SwFrameFormat* pFormat, SdrObject* pObj); - /// Collect all textboxes of the group given by the pGoupObj Parameter. Returns with a - /// vector filled with the textboxes. - static std::vector<SwFrameFormat*> CollectTextBoxes(SdrObject* pGroupObject, - SwFrameFormat* pFormat); }; /// Textboxes are basically textframe + shape pairs. This means one shape has one frame. @@ -254,8 +242,6 @@ public: SwFrameFormat* GetOwnerShape() { return m_pOwnerShapeFormat; }; // This will give the current number of textboxes. size_t GetTextBoxCount() const { return m_pTextBoxes.size(); }; - // Returns with a const collection of textboxes owned by this node. - std::map<SdrObject*, SwFrameFormat*> GetAllTextBoxes() const; }; #endif // INCLUDED_SW_INC_TEXTBOXHELPER_HXX diff --git a/sw/qa/uitest/data/ComplexGroupShapeTest.odt b/sw/qa/uitest/data/ComplexGroupShapeTest.odt deleted file mode 100644 index 8fe093203690..000000000000 Binary files a/sw/qa/uitest/data/ComplexGroupShapeTest.odt and /dev/null differ diff --git a/sw/qa/uitest/writer_tests2/ComplexGroupShapeTest.py b/sw/qa/uitest/writer_tests2/ComplexGroupShapeTest.py deleted file mode 100644 index 7e219d8d7976..000000000000 --- a/sw/qa/uitest/writer_tests2/ComplexGroupShapeTest.py +++ /dev/null @@ -1,127 +0,0 @@ -# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-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/. -# - -from uitest.framework import UITestCase -from uitest.uihelper.common import get_state_as_dict -from uitest.uihelper.common import select_pos -from uitest.uihelper.common import get_url_for_data_file -from libreoffice.uno.propertyvalue import mkPropertyValues -import time - -class ComplexGroupShapeTest(UITestCase): - def test_ComplexGroupShape(self): - with self.ui_test.load_file(get_url_for_data_file("ComplexGroupShapeTest.odt")): - xWriterDoc = self.xUITest.getTopFocusWindow() - xWriterEdit = xWriterDoc.getChild("writer_edit") - document = self.ui_test.get_component() - - # check the shape type - self.assertEqual("com.sun.star.drawing.GroupShape", document.DrawPage.getByIndex(1).ShapeType) - - # select the shape - self.xUITest.executeCommand(".uno:JumpToNextFrame") - self.ui_test.wait_until_child_is_available('metricfield') - - # go inside the group - self.xUITest.executeCommand(".uno:EnterGroup") - - # select a shape in the group - xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"})) - - # add a textbox to this subshape - self.xUITest.executeCommand(".uno:AddTextBox") - - # select the next shape in the group - xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"})) - - # add a textbox to this subshape - self.xUITest.executeCommand(".uno:AddTextBox") - - # leave the groupshape - self.xUITest.executeCommand(".uno:LeaveGroup") - - # select the other shape - self.xUITest.executeCommand(".uno:JumpToNextFrame") - self.ui_test.wait_until_child_is_available('metricfield') - - # get the current selection - ShapeCollection = document.getCurrentSelection() - - # extend the selection with the grouped shape - ShapeCollection.add(document.DrawPage.getByIndex(0)) - ShapeCollection.add(document.DrawPage.getByIndex(1)) - - # select these shapes - document.getCurrentController().select(ShapeCollection) - - # do ungroup - self.xUITest.executeCommand(".uno:FormatGroup") - - # deselect - xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE":"ESC"})) - time.sleep(0.1) - - # select the group - self.xUITest.executeCommand(".uno:JumpToNextFrame") - self.ui_test.wait_until_child_is_available('metricfield') - - # move it down - for i in range(1, 30): - xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"})) - time.sleep(0.1) - - # select again - self.xUITest.executeCommand(".uno:JumpToNextFrame") - self.ui_test.wait_until_child_is_available('metricfield') - - # do ungroup - self.xUITest.executeCommand(".uno:FormatUngroup") - - # deselect everything - xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE":"ESC"})) - time.sleep(0.1) - - # select the first ex-group member shape - self.xUITest.executeCommand(".uno:JumpToNextFrame") - self.ui_test.wait_until_child_is_available('metricfield') - xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"})) - - # check if it is a textbox - self.assertEqual(True,document.getCurrentSelection().getByIndex(0).TextBox) - - # go to the other one - xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"})) - xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"})) - - # this is still a group, so it cannot be a textbox - self.assertEqual(False,document.getCurrentSelection().getByIndex(0).TextBox) - - # do ungroup - self.xUITest.executeCommand(".uno:FormatUngroup") - - # deselect - xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE":"ESC"})) - time.sleep(0.1) - - # select one shape of the last group - self.xUITest.executeCommand(".uno:JumpToNextFrame") - self.ui_test.wait_until_child_is_available('metricfield') - xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"})) - xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"})) - xWriterEdit.executeAction("TYPE", mkPropertyValues({"KEYCODE": "TAB"})) - - # check if it is a textbox - self.assertEqual(True,document.getCurrentSelection().getByIndex(0).TextBox) - - # Without the fix in place, the following problems occurred during this test: - # - After the grouping old textbox frames detached from their shape before - # - Moving caused messed layout - # - After ungroup, the shapes in the embed group lost their textbox - -# vim: set shiftwidth=4 softtabstop=4 expandtab: diff --git a/sw/source/core/doc/docdraw.cxx b/sw/source/core/doc/docdraw.cxx index 6445ab757a0e..0aff4b8993ff 100644 --- a/sw/source/core/doc/docdraw.cxx +++ b/sw/source/core/doc/docdraw.cxx @@ -209,7 +209,7 @@ SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView ) bGroupMembersNotPositioned = pAnchoredDrawObj->NotYetPositioned(); } - std::map<const SdrObject*, SwFrameFormat*> vSavedTextBoxes; + std::vector<std::pair<SwFrameFormat*, SdrObject*>> vSavedTextBoxes; // Destroy ContactObjects and formats. for( size_t i = 0; i < rMrkList.GetMarkCount(); ++i ) { @@ -224,10 +224,8 @@ SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView ) "<SwDoc::GroupSelection(..)> - group members have different positioning status!" ); #endif // Before the format will be killed, save its textbox for later use. - if (auto pShapeFormat = pContact->GetFormat()) - if (auto pTextBoxNode = pShapeFormat->GetOtherTextBoxFormat()) - for (const auto& rTextBoxElement : pTextBoxNode->GetAllTextBoxes()) - vSavedTextBoxes.emplace(rTextBoxElement); + if (auto pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(pContact->GetFormat(), RES_DRAWFRMFMT, pObj)) + vSavedTextBoxes.push_back(std::pair<SwFrameFormat*, SdrObject*>(pTextBox, pObj)); pFormat = static_cast<SwDrawFrameFormat*>(pContact->GetFormat()); // Deletes itself! @@ -256,11 +254,10 @@ SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView ) // Add the saved textboxes to the new format. auto pTextBoxNode = new SwTextBoxNode(pFormat); - for (const auto& pTextBoxEntry : vSavedTextBoxes) + for (auto& pTextBoxEntry : vSavedTextBoxes) { - pTextBoxNode->AddTextBox(const_cast<SdrObject*>(pTextBoxEntry.first), - pTextBoxEntry.second); - pTextBoxEntry.second->SetOtherTextBoxFormat(pTextBoxNode); + pTextBoxNode->AddTextBox(pTextBoxEntry.second, pTextBoxEntry.first); + pTextBoxEntry.first->SetOtherTextBoxFormat(pTextBoxNode); } pFormat->SetOtherTextBoxFormat(pTextBoxNode); vSavedTextBoxes.clear(); @@ -302,27 +299,6 @@ SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView ) return pNewContact; } -static void lcl_CollectTextBoxesForSubGroupObj(SwFrameFormat* pTargetFormat, SwTextBoxNode* pTextBoxNode, - SdrObject* pSourceObjs) -{ - if (auto pChildrenObjs = pSourceObjs->getChildrenOfSdrObject()) - for (size_t i = 0; i < pChildrenObjs->GetObjCount(); ++i) - lcl_CollectTextBoxesForSubGroupObj(pTargetFormat, pTextBoxNode, pChildrenObjs->GetObj(i)); - else - { - if (auto pTextBox = pTextBoxNode->GetTextBox(pSourceObjs)) - { - if (!pTargetFormat->GetOtherTextBoxFormat()) - { - pTargetFormat->SetOtherTextBoxFormat(new SwTextBoxNode(pTargetFormat)); - } - pTargetFormat->GetOtherTextBoxFormat()->AddTextBox(pSourceObjs, pTextBox); - pTextBox->SetOtherTextBoxFormat(pTargetFormat->GetOtherTextBoxFormat()); - } - } -} - - void SwDoc::UnGroupSelection( SdrView& rDrawView ) { bool const bUndo = GetIDocumentUndoRedo().DoesUndo(); @@ -373,22 +349,14 @@ void SwDoc::UnGroupSelection( SdrView& rDrawView ) pFormat->SetFormatAttr( aAnch ); if (pTextBoxNode) - { - if (!pObj->getChildrenOfSdrObject()) + if (auto pTextBoxFormat = pTextBoxNode->GetTextBox(pSubObj)) { - if (auto pTextBoxFormat = pTextBoxNode->GetTextBox(pSubObj)) - { - auto pNewTextBoxNode = new SwTextBoxNode(pFormat); - pNewTextBoxNode->AddTextBox(pSubObj, pTextBoxFormat); - pFormat->SetOtherTextBoxFormat(pNewTextBoxNode); - pTextBoxFormat->SetOtherTextBoxFormat(pNewTextBoxNode); - } + auto pNewTextBoxNode = new SwTextBoxNode(pFormat); + pNewTextBoxNode->AddTextBox(pSubObj, pTextBoxFormat); + pFormat->SetOtherTextBoxFormat(pNewTextBoxNode); + pTextBoxFormat->SetOtherTextBoxFormat(pNewTextBoxNode); } - else - { - lcl_CollectTextBoxesForSubGroupObj(pFormat, pTextBoxNode, pSubObj); - } - } + // #i36010# - set layout direction of the position pFormat->SetPositionLayoutDir( text::PositionLayoutDir::PositionInLayoutDirOfAnchor ); diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx index 7889fd443b89..4cfebf732b1c 100644 --- a/sw/source/core/doc/textboxhelper.cxx +++ b/sw/source/core/doc/textboxhelper.cxx @@ -359,8 +359,7 @@ SwFrameFormat* SwTextBoxHelper::getOtherTextBoxFormat(uno::Reference<drawing::XS return nullptr; SwFrameFormat* pFormat = pShape->GetFrameFormat(); - return getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT, - SdrObject::getSdrObjectFromXShape(xShape)); + return getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT); } uno::Reference<text::XTextFrame> @@ -381,11 +380,9 @@ SwTextBoxHelper::getUnoTextFrame(uno::Reference<drawing::XShape> const& xShape) return {}; } -template <typename T> -static void lcl_queryInterface(const SwFrameFormat* pShape, uno::Any& rAny, SdrObject* pObj) +template <typename T> static void lcl_queryInterface(const SwFrameFormat* pShape, uno::Any& rAny) { - if (SwFrameFormat* pFormat - = SwTextBoxHelper::getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj)) + if (SwFrameFormat* pFormat = SwTextBoxHelper::getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT)) { uno::Reference<T> const xInterface( SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), pFormat), uno::UNO_QUERY); @@ -393,22 +390,21 @@ static void lcl_queryInterface(const SwFrameFormat* pShape, uno::Any& rAny, SdrO } } -uno::Any SwTextBoxHelper::queryInterface(const SwFrameFormat* pShape, const uno::Type& rType, - SdrObject* pObj) +uno::Any SwTextBoxHelper::queryInterface(const SwFrameFormat* pShape, const uno::Type& rType) { uno::Any aRet; if (rType == cppu::UnoType<css::text::XTextAppend>::get()) { - lcl_queryInterface<text::XTextAppend>(pShape, aRet, pObj); + lcl_queryInterface<text::XTextAppend>(pShape, aRet); } else if (rType == cppu::UnoType<css::text::XText>::get()) { - lcl_queryInterface<text::XText>(pShape, aRet, pObj); + lcl_queryInterface<text::XText>(pShape, aRet); } else if (rType == cppu::UnoType<css::text::XTextRange>::get()) { - lcl_queryInterface<text::XTextRange>(pShape, aRet, pObj); + lcl_queryInterface<text::XTextRange>(pShape, aRet); } return aRet; @@ -1304,25 +1300,6 @@ std::optional<bool> SwTextBoxHelper::isAnchorTypeDifferent(const SwFrameFormat* return bRet; } -bool SwTextBoxHelper::syncTextBoxSize(SwFrameFormat* pShape, SdrObject* pObj) -{ - if (!pShape || !pObj) - return false; - - if (auto pTextBox = getOtherTextBoxFormat(pShape, RES_DRAWFRMFMT, pObj)) - { - const auto& rSize = getTextRectangle(pObj, false).GetSize(); - if (!rSize.IsEmpty()) - { - SwFormatFrameSize aSize(pTextBox->GetFrameSize()); - aSize.SetSize(rSize); - return pTextBox->SetFormatAttr(aSize); - } - } - - return false; -} - bool SwTextBoxHelper::isTextBoxShapeHasValidTextFrame(const SwFrameFormat* pShape) { if (pShape && pShape->Which() == RES_DRAWFRMFMT) @@ -1397,41 +1374,6 @@ bool SwTextBoxHelper::DoTextBoxZOrderCorrection(SwFrameFormat* pShape, const Sdr return false; } -void SwTextBoxHelper::synchronizeGroupTextBoxProperty(bool pFunc(SwFrameFormat*, SdrObject*), - SwFrameFormat* pShape, SdrObject* pObj) -{ - if (auto pChildren = pObj->getChildrenOfSdrObject()) - { - for (size_t i = 0; i < pChildren->GetObjCount(); ++i) - synchronizeGroupTextBoxProperty(pFunc, pShape, pChildren->GetObj(i)); - } - else - { - (*pFunc)(pShape, pObj); - } -} - -std::vector<SwFrameFormat*> SwTextBoxHelper::CollectTextBoxes(SdrObject* pGroupObject, - SwFrameFormat* pFormat) -{ - std::vector<SwFrameFormat*> vRet; - if (auto pChildren = pGroupObject->getChildrenOfSdrObject()) - { - for (size_t i = 0; i < pChildren->GetObjCount(); ++i) - { - auto pChildTextBoxes = CollectTextBoxes(pChildren->GetObj(i), pFormat); - for (auto& rChildTextBox : pChildTextBoxes) - vRet.push_back(rChildTextBox); - } - } - else - { - if (isTextBox(pFormat, RES_DRAWFRMFMT, pGroupObject)) - vRet.push_back(getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT, pGroupObject)); - } - return vRet; -} - SwTextBoxNode::SwTextBoxNode(SwFrameFormat* pOwnerShape) { assert(pOwnerShape); @@ -1555,14 +1497,4 @@ void SwTextBoxNode::SetTextBoxInactive(const SdrObject* pDrawObject) bool SwTextBoxNode::IsGroupTextBox() const { return m_pTextBoxes.size() > 1; } -std::map<SdrObject*, SwFrameFormat*> SwTextBoxNode::GetAllTextBoxes() const -{ - std::map<SdrObject*, SwFrameFormat*> aRet; - for (auto& rElem : m_pTextBoxes) - { - aRet.emplace(rElem.m_pDrawObject, rElem.m_pTextBoxFormat); - } - return aRet; -} - /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/draw/dcontact.cxx b/sw/source/core/draw/dcontact.cxx index e397964ba4ec..a467e53174fc 100644 --- a/sw/source/core/draw/dcontact.cxx +++ b/sw/source/core/draw/dcontact.cxx @@ -1250,8 +1250,10 @@ void SwDrawContact::Changed_( const SdrObject& rObj, // use geometry of drawing object aObjRect = pGroupObj->GetSnapRect(); - SwTextBoxHelper::synchronizeGroupTextBoxProperty(&SwTextBoxHelper::changeAnchor, GetFormat(), &const_cast<SdrObject&>(rObj)); - SwTextBoxHelper::synchronizeGroupTextBoxProperty(&SwTextBoxHelper::syncTextBoxSize, GetFormat(), &const_cast<SdrObject&>(rObj)); + for (size_t i = 0; i < pGroupObj->getChildrenOfSdrObject()->GetObjCount(); ++i ) + { + SwTextBoxHelper::doTextBoxPositioning(GetFormat(), pGroupObj->getChildrenOfSdrObject()->GetObj(i)); + } } SwTwips nXPosDiff(0); diff --git a/sw/source/core/draw/dview.cxx b/sw/source/core/draw/dview.cxx index 12b955d04ee5..510addf10a9c 100644 --- a/sw/source/core/draw/dview.cxx +++ b/sw/source/core/draw/dview.cxx @@ -967,11 +967,12 @@ void SwDrawView::DeleteMarked() SdrObject *pObject = rMarkList.GetMark(i)->GetMarkedSdrObj(); SwContact* pContact = GetUserCall(pObject); SwFrameFormat* pFormat = pContact->GetFormat(); - if (pObject->getChildrenOfSdrObject()) + if (auto pChildren = pObject->getChildrenOfSdrObject()) { - auto pChildTextBoxes = SwTextBoxHelper::CollectTextBoxes(pObject, pFormat); - for (auto& rChildTextBox : pChildTextBoxes) - aTextBoxesToDelete.push_back(rChildTextBox); + for (size_t it = 0; it < pChildren->GetObjCount(); ++it) + if (SwFrameFormat* pTextBox = SwTextBoxHelper::getOtherTextBoxFormat( + pFormat, RES_DRAWFRMFMT, pChildren->GetObj(it))) + aTextBoxesToDelete.push_back(pTextBox); } else if (SwFrameFormat* pTextBox = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_DRAWFRMFMT)) diff --git a/sw/source/core/unocore/unodraw.cxx b/sw/source/core/unocore/unodraw.cxx index 4d0b404e9a1c..5c5811ee3934 100644 --- a/sw/source/core/unocore/unodraw.cxx +++ b/sw/source/core/unocore/unodraw.cxx @@ -965,19 +965,10 @@ SwXShape::~SwXShape() uno::Any SwXShape::queryInterface( const uno::Type& aType ) { - uno::Any aRet; - SdrObject* pObj = nullptr; - - if ((aType == cppu::UnoType<text::XText>::get()) - || (aType == cppu::UnoType<text::XTextRange>::get()) - || (aType == cppu::UnoType<text::XTextAppend>::get())) - { - pObj = SdrObject::getSdrObjectFromXShape(mxShape); + uno::Any aRet = SwTextBoxHelper::queryInterface(GetFrameFormat(), aType); + if (aRet.hasValue()) + return aRet; - aRet = SwTextBoxHelper::queryInterface(GetFrameFormat(), aType, pObj); - if (aRet.hasValue()) - return aRet; - } aRet = SwXShapeBaseClass::queryInterface(aType); // #i53320# - follow-up of #i31698# // interface drawing::XShape is overloaded. Thus, provide
