summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorAttila Szűcs <szucs.attila3@nisz.hu>2021-07-27 11:45:58 +0200
committerXisco Fauli <xiscofauli@libreoffice.org>2021-09-06 23:54:47 +0200
commit7ec91bcb7d248c38522375c31f2b6f640b1b84e2 (patch)
treea78269db9ba5bbfdfb4916092dbd4b5069df7f91 /sw
parenta6d9abd6ab554a7684f5543c3b624fc3aaac777d (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.hxx2
-rw-r--r--sw/inc/unotextrange.hxx3
-rw-r--r--sw/qa/extras/ooxmlexport/data/tdf143384_tableInFoot_negativeMargins.docxbin0 -> 58566 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport11.cxx7
-rw-r--r--sw/source/core/unocore/unoframe.cxx8
-rw-r--r--sw/source/core/unocore/unoobj2.cxx15
-rw-r--r--sw/source/core/unocore/unotext.cxx56
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
new file mode 100644
index 000000000000..918c1029fb4a
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf143384_tableInFoot_negativeMargins.docx
Binary files differ
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)
{