diff options
author | Attila Szűcs <szucs.attila3@nisz.hu> | 2021-07-27 11:45:58 +0200 |
---|---|---|
committer | Xisco Fauli <xiscofauli@libreoffice.org> | 2021-09-06 23:54:47 +0200 |
commit | 7ec91bcb7d248c38522375c31f2b6f640b1b84e2 (patch) | |
tree | a78269db9ba5bbfdfb4916092dbd4b5069df7f91 /sw | |
parent | a6d9abd6ab554a7684f5543c3b624fc3aaac777d (diff) |
tdf#143384 DOCX import: fix SAXException at header with table
Regression from commit d656191ec308d4280b93c7169372e543a255d108
"tdf#119952 DOCX import: fix negative page margins".
Add SwXHeadFootText::CreateTextCursor(bool bIgnoreTables = false)
(modeled after SwXBodyText::CreateTextCursor) to create text cursor
for copying the header/footer also started with table during
fly frame creation in convertoToTextFrame().
Note: add hidden property PROP_CURSOR_NOT_IGNORE_TABLES_IN_HF
to use the new feature in domainmapper (followed
commit af4e5ee0f93c1ff442d08caed5c875f2b2c1fd43
"tdf#97128 DOCX import: fix frame direction").
Co-authored-by: Tibor Nagy (NISZ)
Change-Id: I96e2cf2dddcecd146c53c12d7fdb44fc4d90fa0d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119549
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
(cherry picked from commit c1ad429d925855c1baacbdeca1ef42f4486eb9c2)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120985
Tested-by: Jenkins
Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/unotextbodyhf.hxx | 2 | ||||
-rw-r--r-- | sw/inc/unotextrange.hxx | 3 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/tdf143384_tableInFoot_negativeMargins.docx | bin | 0 -> 58566 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport11.cxx | 7 | ||||
-rw-r--r-- | sw/source/core/unocore/unoframe.cxx | 8 | ||||
-rw-r--r-- | sw/source/core/unocore/unoobj2.cxx | 15 | ||||
-rw-r--r-- | sw/source/core/unocore/unotext.cxx | 56 |
7 files changed, 74 insertions, 17 deletions
diff --git a/sw/inc/unotextbodyhf.hxx b/sw/inc/unotextbodyhf.hxx index fbccc982ef04..99887c6beb5c 100644 --- a/sw/inc/unotextbodyhf.hxx +++ b/sw/inc/unotextbodyhf.hxx @@ -115,6 +115,8 @@ public: static css::uno::Reference< css::text::XText > CreateXHeadFootText(SwFrameFormat & rHeadFootFormat, const bool bIsHeader); + css::uno::Reference<css::text::XTextCursor> CreateTextCursor(const bool bIgnoreTables = false); + // XInterface virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& rType) override; diff --git a/sw/inc/unotextrange.hxx b/sw/inc/unotextrange.hxx index f3ed06fb4a06..4d8ed2df2c06 100644 --- a/sw/inc/unotextrange.hxx +++ b/sw/inc/unotextrange.hxx @@ -57,7 +57,8 @@ namespace sw { enum class TextRangeMode { RequireTextNode, - AllowNonTextNode + AllowNonTextNode, + AllowTableNode }; void DeepCopyPaM(SwPaM const & rSource, SwPaM & rTarget); diff --git a/sw/qa/extras/ooxmlexport/data/tdf143384_tableInFoot_negativeMargins.docx b/sw/qa/extras/ooxmlexport/data/tdf143384_tableInFoot_negativeMargins.docx Binary files differnew file mode 100644 index 000000000000..918c1029fb4a --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/tdf143384_tableInFoot_negativeMargins.docx diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx index 431d5d71753d..17f05d1dcd16 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx @@ -1599,6 +1599,13 @@ DECLARE_OOXMLEXPORT_TEST(testTdf119952_negativeMargins, "tdf119952_negativeMargi CPPUNIT_ASSERT_EQUAL(OUString(" aaaa bbbb cccc dddd eeee"), parseDump("/root/page[3]/header/txt/anchored/fly")); } +DECLARE_OOXMLEXPORT_TEST(testTdf143384_tableInFoot_negativeMargins, "tdf143384_tableInFoot_negativeMargins.docx") +{ + // There should be no crash during loading of the document + // so, let's check just how much pages we have + CPPUNIT_ASSERT_EQUAL(1, getPages()); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/unocore/unoframe.cxx b/sw/source/core/unocore/unoframe.cxx index a430d92f5b7f..8fd930322a38 100644 --- a/sw/source/core/unocore/unoframe.cxx +++ b/sw/source/core/unocore/unoframe.cxx @@ -1417,7 +1417,13 @@ void SwXFrame::setPropertyValue(const OUString& rPropertyName, const ::uno::Any& const ::SfxItemPropertyMapEntry* pEntry = m_pPropSet->getPropertyMap().getByName(rPropertyName); if (!pEntry) - throw beans::UnknownPropertyException( "Unknown property: " + rPropertyName, static_cast < cppu::OWeakObject * > ( this ) ); + { + // Hack to skip the dummy CursorNotIgnoreTables property + if (rPropertyName == "CursorNotIgnoreTables") + return; + else + throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, static_cast <cppu::OWeakObject*> (this)); + } const sal_uInt8 nMemberId(pEntry->nMemberId); uno::Any aValue(_rValue); diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx index 2103220de62b..e99450378bac 100644 --- a/sw/source/core/unocore/unoobj2.cxx +++ b/sw/source/core/unocore/unoobj2.cxx @@ -1116,6 +1116,7 @@ bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill, SwXTextPortion* pPortion = nullptr; SwXText* pText = nullptr; SwXParagraph* pPara = nullptr; + SwXHeadFootText* pHeadText = nullptr; if(xRangeTunnel.is()) { pRange = ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel); @@ -1125,12 +1126,26 @@ bool XTextRangeToSwPaM( SwUnoInternalPaM & rToFill, ::sw::UnoTunnelGetImplementation<SwXTextPortion>(xRangeTunnel); pText = ::sw::UnoTunnelGetImplementation<SwXText>(xRangeTunnel); pPara = ::sw::UnoTunnelGetImplementation<SwXParagraph>(xRangeTunnel); + if (eMode == TextRangeMode::AllowTableNode) + pHeadText = dynamic_cast<SwXHeadFootText*>(pText); } // if it's a text then create a temporary cursor there and re-use // the pCursor variable // #i108489#: Reference in outside scope to keep cursor alive uno::Reference< text::XTextCursor > xTextCursor; + if (pHeadText) + { + // if it is a header / footer text, and eMode == TextRangeMode::AllowTableNode + // then set the cursor to the beginning of the text + // if it is started with a table then set into the table + xTextCursor.set(pHeadText->CreateTextCursor(true)); + xTextCursor->gotoEnd(true); + pCursor = + comphelper::getUnoTunnelImplementation<OTextCursorHelper>(xTextCursor); + pCursor->GetPaM()->Normalize(); + } + else if (pText) { xTextCursor.set( pText->CreateCursor() ); diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx index 7e0c73d8c778..fa779d95abd8 100644 --- a/sw/source/core/unocore/unotext.cxx +++ b/sw/source/core/unocore/unotext.cxx @@ -1537,14 +1537,31 @@ SwXText::convertToTextFrame( { throw uno::RuntimeException(); } + // tdf#143384 recognize dummy property, that was set to make createTextCursor + // to not ignore tables. + // It is enough to use this hack only for the range start, + // because as far as I know, the range cannot end with table when this property is set. + ::sw::TextRangeMode eMode = ::sw::TextRangeMode::RequireTextNode; + for (const auto& rCellProperty : rFrameProperties) + { + if (rCellProperty.Name == "CursorNotIgnoreTables") + { + bool bAllowNonTextNode = false; + rCellProperty.Value >>= bAllowNonTextNode; + if (bAllowNonTextNode) + eMode = ::sw::TextRangeMode::AllowTableNode; + break; + } + } uno::Reference< text::XTextContent > xRet; std::optional<SwUnoInternalPaM> pTempStartPam(*GetDoc()); std::optional<SwUnoInternalPaM> pEndPam(*GetDoc()); - if (!::sw::XTextRangeToSwPaM(*pTempStartPam, xStart) || - !::sw::XTextRangeToSwPaM(*pEndPam, xEnd)) + if (!::sw::XTextRangeToSwPaM(*pTempStartPam, xStart, eMode) + || !::sw::XTextRangeToSwPaM(*pEndPam, xEnd)) { throw lang::IllegalArgumentException(); } + auto pStartPam(GetDoc()->CreateUnoCursor(*pTempStartPam->GetPoint())); if (pTempStartPam->HasMark()) { @@ -2613,8 +2630,7 @@ uno::Any SAL_CALL SwXHeadFootText::queryInterface(const uno::Type& rType) : ret; } -uno::Reference<text::XTextCursor> SAL_CALL -SwXHeadFootText::createTextCursor() +uno::Reference<text::XTextCursor> SwXHeadFootText::CreateTextCursor(const bool bIgnoreTables) { SolarMutexGuard aGuard; @@ -2632,18 +2648,22 @@ SwXHeadFootText::createTextCursor() // after the table - otherwise the cursor would be in the body text! SwStartNode const*const pOwnStartNode = rNode.FindSttNodeByType( (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode); - // is there a table here? - SwTableNode* pTableNode = rUnoCursor.GetNode().FindTableNode(); - SwContentNode* pCont = nullptr; - while (pTableNode) - { - rUnoCursor.GetPoint()->nNode = *pTableNode->EndOfSectionNode(); - pCont = GetDoc()->GetNodes().GoNext(&rUnoCursor.GetPoint()->nNode); - pTableNode = pCont->FindTableNode(); - } - if (pCont) + + if (!bIgnoreTables) { - rUnoCursor.GetPoint()->nContent.Assign(pCont, 0); + // is there a table here? + SwTableNode* pTableNode = rUnoCursor.GetNode().FindTableNode(); + SwContentNode* pCont = nullptr; + while (pTableNode) + { + rUnoCursor.GetPoint()->nNode = *pTableNode->EndOfSectionNode(); + pCont = GetDoc()->GetNodes().GoNext(&rUnoCursor.GetPoint()->nNode); + pTableNode = pCont->FindTableNode(); + } + if (pCont) + { + rUnoCursor.GetPoint()->nContent.Assign(pCont, 0); + } } SwStartNode const*const pNewStartNode = rUnoCursor.GetNode().FindSttNodeByType( (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode); @@ -2656,6 +2676,12 @@ SwXHeadFootText::createTextCursor() return static_cast<text::XWordCursor*>(pXCursor.get()); } +uno::Reference<text::XTextCursor> SAL_CALL +SwXHeadFootText::createTextCursor() +{ + return CreateTextCursor(false); +} + uno::Reference<text::XTextCursor> SAL_CALL SwXHeadFootText::createTextCursorByRange( const uno::Reference<text::XTextRange>& xTextPosition) { |