From 592367ac711d9bf9fbd2ba4ecc41cb49da7a44ec Mon Sep 17 00:00:00 2001 From: Michael Stahl Date: Tue, 24 Nov 2020 15:33:44 +0100 Subject: sw: fix SwXTextRange::createEnumeration() inside table cell This would set CursorType::SelectionInTable but leave m_pOwnTable and m_pOwnStartNode uninitialised, causing sw/source/core/unocore/unoobj2.cxx:399: SwXParagraphEnumeration: table type but no start node or table and then the enumeration would return the table it's in as the first element, which is quite annoying. Refactor the creation of SwXParagraphEnumeration to prevent this. Change-Id: I4e9e3456bdf66b9822d19ad985a20b094e6bbba4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106532 Tested-by: Jenkins Reviewed-by: Michael Stahl (cherry picked from commit ecc3c621fe5a7e962f0e40cb3709ad5772a5d744) --- sw/inc/unoparagraph.hxx | 6 +- sw/qa/extras/unowriter/data/bookmarkintable.fodt | 82 ++++++++++++++++++++++++ sw/qa/extras/unowriter/unowriter.cxx | 27 ++++++++ sw/source/core/unocore/unoobj.cxx | 7 +- sw/source/core/unocore/unoobj2.cxx | 32 +++++++-- sw/source/core/unocore/unotbl.cxx | 3 +- 6 files changed, 140 insertions(+), 17 deletions(-) create mode 100644 sw/qa/extras/unowriter/data/bookmarkintable.fodt diff --git a/sw/inc/unoparagraph.hxx b/sw/inc/unoparagraph.hxx index 64a8defd83fc..eb89ce47249e 100644 --- a/sw/inc/unoparagraph.hxx +++ b/sw/inc/unoparagraph.hxx @@ -43,7 +43,7 @@ class SwPaM; class SwUnoCursor; class SwStartNode; class SwTextNode; -class SwTable; +class SwTableBox; class SwXText; typedef ::cppu::ImplInheritanceHelper @@ -216,8 +216,8 @@ struct SwXParagraphEnumeration css::uno::Reference< css::text::XText > const & xParent, const std::shared_ptr& pCursor, const CursorType eType, - SwStartNode const*const pStartNode = nullptr, - SwTable const*const pTable = nullptr); + /// only for CursorType::TableText + SwTableBox const*const pTableBox = nullptr); }; #endif // INCLUDED_SW_INC_UNOPARAGRAPH_HXX diff --git a/sw/qa/extras/unowriter/data/bookmarkintable.fodt b/sw/qa/extras/unowriter/data/bookmarkintable.fodt new file mode 100644 index 000000000000..641200fef93e --- /dev/null +++ b/sw/qa/extras/unowriter/data/bookmarkintable.fodt @@ -0,0 +1,82 @@ + + + 2020-11-24T13:16:34.2483766402020-11-24T14:47:04.359492742PT2M22S2LibreOfficeDev/7.1.0.0.alpha1$Linux_X86_64 LibreOffice_project/a871df849fad8f923db945cf0606f30603380ef7 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + afoob + + + + + + + diff --git a/sw/qa/extras/unowriter/unowriter.cxx b/sw/qa/extras/unowriter/unowriter.cxx index 4a23082ccc74..fd3fe08a5a13 100644 --- a/sw/qa/extras/unowriter/unowriter.cxx +++ b/sw/qa/extras/unowriter/unowriter.cxx @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -480,6 +481,32 @@ CPPUNIT_TEST_FIXTURE(SwUnoWriter, testSectionAnchorCopyTableAtEnd) xCursor->getString()); } +CPPUNIT_TEST_FIXTURE(SwUnoWriter, testTextRangeInTable) +{ + load(DATA_DIRECTORY, "bookmarkintable.fodt"); + + uno::Reference const xBS(mxComponent, uno::UNO_QUERY); + uno::Reference const xMarks(xBS->getBookmarks()); + uno::Reference const xMark(xMarks->getByName("Bookmark 1"), uno::UNO_QUERY); + uno::Reference const xAnchor(xMark->getAnchor(), uno::UNO_QUERY); + uno::Reference const xEnum(xAnchor->createEnumeration()); + uno::Reference const xPara(xEnum->nextElement(), uno::UNO_QUERY); + // not the top-level table! + CPPUNIT_ASSERT(!xPara->supportsService("com.sun.star.text.TextTable")); + CPPUNIT_ASSERT(!xEnum->hasMoreElements()); + uno::Reference const xParaEA(xPara, uno::UNO_QUERY); + uno::Reference const xPortions(xParaEA->createEnumeration()); + uno::Reference const xP1(xPortions->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("Bookmark"), getProperty(xP1, "TextPortionType")); + uno::Reference const xP2(xPortions->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("Text"), getProperty(xP2, "TextPortionType")); + uno::Reference const xP2R(xP2, uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("foo"), xP2R->getString()); + uno::Reference const xP3(xPortions->nextElement(), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(OUString("Bookmark"), getProperty(xP3, "TextPortionType")); + CPPUNIT_ASSERT(!xPortions->hasMoreElements()); +} + CPPUNIT_TEST_FIXTURE(SwUnoWriter, testXURI) { uno::Reference xContext(::comphelper::getProcessComponentContext()); diff --git a/sw/source/core/unocore/unoobj.cxx b/sw/source/core/unocore/unoobj.cxx index 1f8b4d02edfd..4238f8287ccd 100644 --- a/sw/source/core/unocore/unoobj.cxx +++ b/sw/source/core/unocore/unoobj.cxx @@ -2945,12 +2945,7 @@ SwXTextCursor::createEnumeration() } const CursorType eSetType = (CursorType::TableText == m_pImpl->m_eType) ? CursorType::SelectionInTable : CursorType::Selection; - SwTableNode const*const pStartNode( (CursorType::TableText == m_pImpl->m_eType) - ? rUnoCursor.GetPoint()->nNode.GetNode().FindTableNode() - : nullptr); - SwTable const*const pTable( - pStartNode ? & pStartNode->GetTable() : nullptr ); - return SwXParagraphEnumeration::Create(pParentText, pNewCursor, eSetType, pStartNode, pTable); + return SwXParagraphEnumeration::Create(pParentText, pNewCursor, eSetType); } uno::Type SAL_CALL diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx index 718f977b5345..8e17f700c4d9 100644 --- a/sw/source/core/unocore/unoobj2.cxx +++ b/sw/source/core/unocore/unoobj2.cxx @@ -435,10 +435,9 @@ struct SwXParagraphEnumerationImpl final : public SwXParagraphEnumeration , m_pCursor(pCursor) { OSL_ENSURE(m_xParentText.is(), "SwXParagraphEnumeration: no parent?"); - OSL_ENSURE( !((CursorType::SelectionInTable == eType) || - (CursorType::TableText == eType)) - || (m_pOwnTable && m_pOwnStartNode), - "SwXParagraphEnumeration: table type but no start node or table?"); + assert( !((CursorType::SelectionInTable == eType) + || (CursorType::TableText == eType)) + || (m_pOwnTable && m_pOwnStartNode)); if ((CursorType::Selection == m_eCursorType) || (CursorType::SelectionInTable == m_eCursorType)) @@ -489,9 +488,30 @@ SwXParagraphEnumeration* SwXParagraphEnumeration::Create( uno::Reference< text::XText > const& xParent, const std::shared_ptr& pCursor, const CursorType eType, - SwStartNode const*const pStartNode, - SwTable const*const pTable) + SwTableBox const*const pTableBox) { + SwStartNode const* pStartNode(nullptr); + SwTable const* pTable(nullptr); + assert((eType == CursorType::TableText) == (pTableBox != nullptr)); + switch (eType) + { + case CursorType::TableText: + { + pStartNode = pTableBox->GetSttNd(); + pTable = & pStartNode->FindTableNode()->GetTable(); + break; + } + case CursorType::SelectionInTable: + { + SwTableNode const*const pTableNode( + pCursor->GetPoint()->nNode.GetNode().FindTableNode()); + pStartNode = pTableNode; + pTable = & pTableNode->GetTable(); + break; + } + default: + break; + } return new SwXParagraphEnumerationImpl(xParent, pCursor, eType, pStartNode, pTable); } diff --git a/sw/source/core/unocore/unotbl.cxx b/sw/source/core/unocore/unotbl.cxx index fbce960453b6..e2e5e123871e 100644 --- a/sw/source/core/unocore/unotbl.cxx +++ b/sw/source/core/unocore/unotbl.cxx @@ -1154,8 +1154,7 @@ uno::Reference SwXCell::createEnumeration() pUnoCursor->Move(fnMoveForward, GoInNode); // remember table and start node for later travelling // (used in export of tables in tables) - SwTable const*const pTable(&pSttNd->FindTableNode()->GetTable()); - return SwXParagraphEnumeration::Create(this, pUnoCursor, CursorType::TableText, pSttNd, pTable); + return SwXParagraphEnumeration::Create(this, pUnoCursor, CursorType::TableText, m_pBox); } uno::Type SAL_CALL SwXCell::getElementType() -- cgit