diff options
author | László Németh <nemeth@numbertext.org> | 2020-09-14 11:00:27 +0200 |
---|---|---|
committer | László Németh <nemeth@numbertext.org> | 2020-09-15 08:16:31 +0200 |
commit | 464a7b0631335a8f8729512b8c27f864747f56a7 (patch) | |
tree | 975336153f37de36adb4248b8097cff1d7162015 | |
parent | 0e27b1f364d9b36cb5f8431d9df36b5953237424 (diff) |
tdf#136667 DOCX import: fix crash of floating tables
with tracked changes of table structure (not only cell
text content), where text ranges of redlines aren't
connected to a cell. Support also different table names
of redline text ranges for sure.
Regression from commit 288db6eb47fbbd2b3ca34ffea0686d8ed8ed9be9
(tdf#132271 DOCX: import change tracking in floating tables).
Change-Id: I58b1b21c8016d682a292409165991dec2f8cfa3d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102655
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/tdf136667.docx | bin | 0 -> 12729 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport11.cxx | 8 | ||||
-rw-r--r-- | writerfilter/source/dmapper/PropertyMap.cxx | 57 |
3 files changed, 39 insertions, 26 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/tdf136667.docx b/sw/qa/extras/ooxmlexport/data/tdf136667.docx Binary files differnew file mode 100644 index 000000000000..e5b047ee3330 --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/tdf136667.docx diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx index 6cdecfd2c258..cd00389f063c 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport11.cxx @@ -979,6 +979,14 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf132271, "tdf132271.docx") assertXPath(pXmlDoc, "//w:ins", 2); } +DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf136667, "tdf136667.docx") +{ + xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); + // import change tracking in floating tables + assertXPath(pXmlDoc, "//w:del", 2); + assertXPath(pXmlDoc, "//w:ins", 4); +} + DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf128156, "tdf128156.docx") { xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx index 4e08279a8427..7a2807746141 100644 --- a/writerfilter/source/dmapper/PropertyMap.cxx +++ b/writerfilter/source/dmapper/PropertyMap.cxx @@ -1380,52 +1380,57 @@ void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl ) // convert redline ranges to cursor movement and character length std::vector<sal_Int32> redPos, redLen; std::vector<OUString> redCell; - OUString sTableName; + std::vector<OUString> redTable; for( size_t i = 0; i < aFramedRedlines.size(); i+=3) { uno::Reference<text::XText> xCell; uno::Reference< text::XTextRange > xRange; aFramedRedlines[i] >>= xRange; uno::Reference< beans::XPropertySet > xRangeProperties; + OUString sTableName; + OUString sCellName; if ( xRange.is() ) { xRangeProperties.set( xRange, uno::UNO_QUERY_THROW ); - - const uno::Sequence<beans::Property> aRangeProperties - = xRangeProperties->getPropertySetInfo()->getProperties(); - - for (const beans::Property& rProperty : aRangeProperties) + if (xRangeProperties->getPropertySetInfo()->hasPropertyByName("TextTable")) { - const OUString& rKey = rProperty.Name; - uno::Any aValue = xRangeProperties->getPropertyValue(rKey); - if ( rKey == "TextTable" ) + uno::Any aTable = xRangeProperties->getPropertyValue("TextTable"); + if ( aTable != uno::Any() ) { uno::Reference<text::XTextTable> xTable; - aValue >>= xTable; + aTable >>= xTable; uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY); xTableProperties->getPropertyValue("TableName") >>= sTableName; } - else if ( rKey == "Cell" ) + if (xRangeProperties->getPropertySetInfo()->hasPropertyByName("Cell")) { - OUString sCellName; - aValue >>= xCell; - uno::Reference<beans::XPropertySet> xCellProperties(xCell, uno::UNO_QUERY); - xCellProperties->getPropertyValue("CellName") >>= sCellName; - redCell.push_back(sCellName); + uno::Any aCell = xRangeProperties->getPropertyValue("Cell"); + if ( aCell != uno::Any() ) + { + aCell >>= xCell; + uno::Reference<beans::XPropertySet> xCellProperties(xCell, uno::UNO_QUERY); + xCellProperties->getPropertyValue("CellName") >>= sCellName; + } } } - - uno::Reference<text::XTextCursor> xRangeCursor = xCell->createTextCursorByRange( xRange ); - if ( xRangeCursor.is() ) + redTable.push_back(sTableName); + redCell.push_back(sCellName); + bool bOk = false; + if (!sTableName.isEmpty() && !sCellName.isEmpty()) { - sal_Int32 nLen = xRange->getString().getLength(); - redLen.push_back(nLen); - xRangeCursor->gotoStart(true); - redPos.push_back(xRangeCursor->getString().getLength() - nLen); + uno::Reference<text::XTextCursor> xRangeCursor = xCell->createTextCursorByRange( xRange ); + if ( xRangeCursor.is() ) + { + bOk = true; + sal_Int32 nLen = xRange->getString().getLength(); + redLen.push_back(nLen); + xRangeCursor->gotoStart(true); + redPos.push_back(xRangeCursor->getString().getLength() - nLen); + } } - else + if (!bOk) { - // failed createTextCursorByRange() + // missing cell or failed createTextCursorByRange() redLen.push_back(-1); redPos.push_back(-1); } @@ -1437,7 +1442,6 @@ void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl ) uno::Reference<text::XTextTablesSupplier> xTextDocument(rDM_Impl.GetTextDocument(), uno::UNO_QUERY); uno::Reference<container::XNameAccess> xTables = xTextDocument->getTextTables(); - uno::Reference<text::XTextTable> xTable(xTables->getByName(sTableName), uno::UNO_QUERY); for( size_t i = 0; i < aFramedRedlines.size(); i+=3) { OUString sType; @@ -1447,6 +1451,7 @@ void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl ) continue; aFramedRedlines[i+1] >>= sType; aFramedRedlines[i+2] >>= aRedlineProperties; + uno::Reference<text::XTextTable> xTable(xTables->getByName(redTable[i/3]), uno::UNO_QUERY); uno::Reference<text::XText> xCell(xTable->getCellByName(redCell[i/3]), uno::UNO_QUERY); uno::Reference<text::XTextCursor> xCrsr = xCell->createTextCursor(); xCrsr->goRight(redPos[i/3], false); |