diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2023-03-17 15:14:37 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2023-03-17 19:24:40 +0000 |
commit | 9a9ee21ec237eda5df6ea70bfa3bec07b44b4d21 (patch) | |
tree | 5761d4f52b03e8a26e6c91dcc69b0668d43eba7b | |
parent | 32b2d00853d049bacb60cfb40e732602da048c89 (diff) |
sw floattable: fix redline import from DOCX
The problem was that sw/qa/extras/ooxmlexport/data/tdf149388.docx
contained redlines but those were not imported for split flys.
This happened because split flys get imported directly in
DomainMapperTableHandler::endTable(), and the redling handling for
floating tables was only implemented in
SectionPropertyMap::CloseSectionGroup() (where delayed floating tables
are imported).
Fix this by extracting the redline import code for floating tables into
2 functions and then calling those also from
DomainMapperTableHandler::endTable().
Note that the !isExported() branch of the testcase looks like dead code,
since we always run this code after an export.
Change-Id: I860ee0168807077eb5ed33d79888f4cc1de9a717
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149057
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport12.cxx | 1 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapperTableHandler.cxx | 10 | ||||
-rw-r--r-- | writerfilter/source/dmapper/PropertyMap.cxx | 175 | ||||
-rw-r--r-- | writerfilter/source/dmapper/PropertyMap.hxx | 5 |
4 files changed, 108 insertions, 83 deletions
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx index b3c2bceef5bb..d5ca8435b82b 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport12.cxx @@ -1509,6 +1509,7 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf149388) CPPUNIT_TEST_FIXTURE(Test, testTdf132271) { + SwModelTestBase::FlySplitGuard aGuard; // see also testTdf149388 loadAndSave("tdf149388.docx"); xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml"); diff --git a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx index 968e3c0835a7..bd81fb9df941 100644 --- a/writerfilter/source/dmapper/DomainMapperTableHandler.cxx +++ b/writerfilter/source/dmapper/DomainMapperTableHandler.cxx @@ -1619,7 +1619,17 @@ void DomainMapperTableHandler::endTable(unsigned int nestedTableLevel, bool bTab // the start of an outer table cell, that's not yet // implemented. if (xTextAppendAndConvert.is() && !bTableStartsAtCellStart) + { + std::deque<css::uno::Any> aFramedRedlines = m_rDMapper_Impl.m_aStoredRedlines[StoredRedlines::FRAME]; + std::vector<sal_Int32> redPos, redLen; + std::vector<OUString> redCell; + std::vector<OUString> redTable; + BeforeConvertToTextFrame(aFramedRedlines, redPos, redLen, redCell, redTable); + xTextAppendAndConvert->convertToTextFrame(xStart, xEnd, comphelper::containerToSequence(aFrameProperties)); + + AfterConvertToTextFrame(m_rDMapper_Impl, aFramedRedlines, redPos, redLen, redCell, redTable); + } } } diff --git a/writerfilter/source/dmapper/PropertyMap.cxx b/writerfilter/source/dmapper/PropertyMap.cxx index 2c917873c455..40d9eec86b7f 100644 --- a/writerfilter/source/dmapper/PropertyMap.cxx +++ b/writerfilter/source/dmapper/PropertyMap.cxx @@ -1354,6 +1354,96 @@ void SectionPropertyMap::HandleIncreasedAnchoredObjectSpacing(DomainMapper_Impl& rAnchoredObjectAnchors.clear(); } +void BeforeConvertToTextFrame(std::deque<css::uno::Any>& rFramedRedlines, std::vector<sal_Int32>& redPos, std::vector<sal_Int32>& redLen, std::vector<OUString>& redCell, std::vector<OUString>& redTable) +{ + // convert redline ranges to cursor movement and character length + for( size_t i = 0; i < rFramedRedlines.size(); i+=3) + { + uno::Reference<text::XText> xCell; + uno::Reference< text::XTextRange > xRange; + rFramedRedlines[i] >>= xRange; + uno::Reference< beans::XPropertySet > xRangeProperties; + if ( xRange.is() ) + { + OUString sTableName; + OUString sCellName; + xRangeProperties.set( xRange, uno::UNO_QUERY_THROW ); + if (xRangeProperties->getPropertySetInfo()->hasPropertyByName("TextTable")) + { + uno::Any aTable = xRangeProperties->getPropertyValue("TextTable"); + if ( aTable != uno::Any() ) + { + uno::Reference<text::XTextTable> xTable; + aTable >>= xTable; + uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY); + xTableProperties->getPropertyValue("TableName") >>= sTableName; + } + if (xRangeProperties->getPropertySetInfo()->hasPropertyByName("Cell")) + { + 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; + } + } + } + redTable.push_back(sTableName); + redCell.push_back(sCellName); + bool bOk = false; + if (!sTableName.isEmpty() && !sCellName.isEmpty()) + { + 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); + } + } + if (!bOk) + { + // missing cell or failed createTextCursorByRange() + redLen.push_back(-1); + redPos.push_back(-1); + } + } + } +} + +void AfterConvertToTextFrame(DomainMapper_Impl& rDM_Impl, std::deque<css::uno::Any>& aFramedRedlines, std::vector<sal_Int32>& redPos, std::vector<sal_Int32>& redLen, std::vector<OUString>& redCell, std::vector<OUString>& redTable) +{ + uno::Reference<text::XTextTablesSupplier> xTextDocument(rDM_Impl.GetTextDocument(), uno::UNO_QUERY); + uno::Reference<container::XNameAccess> xTables = xTextDocument->getTextTables(); + for( size_t i = 0; i < aFramedRedlines.size(); i+=3) + { + OUString sType; + beans::PropertyValues aRedlineProperties( 3 ); + // skip failed createTextCursorByRange() + if (redPos[i/3] == -1) + 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); + xCrsr->goRight(redLen[i/3], true); + uno::Reference < text::XRedline > xRedline( xCrsr, uno::UNO_QUERY_THROW ); + try + { + xRedline->makeRedline( sType, aRedlineProperties ); + } + catch (const uno::Exception&) + { + DBG_UNHANDLED_EXCEPTION("writerfilter", "makeRedline() failed"); + } + } +} + void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl ) { SectionPropertyMap* pPrevSection = rDM_Impl.GetLastSectionContext(); @@ -1409,66 +1499,10 @@ void SectionPropertyMap::CloseSectionGroup( DomainMapper_Impl& rDM_Impl ) std::deque<css::uno::Any> aFramedRedlines = rDM_Impl.m_aStoredRedlines[StoredRedlines::FRAME]; try { - // convert redline ranges to cursor movement and character length std::vector<sal_Int32> redPos, redLen; std::vector<OUString> redCell; 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; - if ( xRange.is() ) - { - OUString sTableName; - OUString sCellName; - xRangeProperties.set( xRange, uno::UNO_QUERY_THROW ); - if (xRangeProperties->getPropertySetInfo()->hasPropertyByName("TextTable")) - { - uno::Any aTable = xRangeProperties->getPropertyValue("TextTable"); - if ( aTable != uno::Any() ) - { - uno::Reference<text::XTextTable> xTable; - aTable >>= xTable; - uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY); - xTableProperties->getPropertyValue("TableName") >>= sTableName; - } - if (xRangeProperties->getPropertySetInfo()->hasPropertyByName("Cell")) - { - 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; - } - } - } - redTable.push_back(sTableName); - redCell.push_back(sCellName); - bool bOk = false; - if (!sTableName.isEmpty() && !sCellName.isEmpty()) - { - 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); - } - } - if (!bOk) - { - // missing cell or failed createTextCursorByRange() - redLen.push_back(-1); - redPos.push_back(-1); - } - } - } - + BeforeConvertToTextFrame(aFramedRedlines, redPos, redLen, redCell, redTable); const uno::Reference< text::XTextContent >& xTextContent = xBodyText->convertToTextFrame(rInfo.m_xStart, rInfo.m_xEnd, rInfo.m_aFrameProperties); @@ -1489,32 +1523,7 @@ 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(); - for( size_t i = 0; i < aFramedRedlines.size(); i+=3) - { - OUString sType; - beans::PropertyValues aRedlineProperties( 3 ); - // skip failed createTextCursorByRange() - if (redPos[i/3] == -1) - 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); - xCrsr->goRight(redLen[i/3], true); - uno::Reference < text::XRedline > xRedline( xCrsr, uno::UNO_QUERY_THROW ); - try - { - xRedline->makeRedline( sType, aRedlineProperties ); - } - catch (const uno::Exception&) - { - DBG_UNHANDLED_EXCEPTION("writerfilter", "makeRedline() failed"); - } - } + AfterConvertToTextFrame(rDM_Impl, aFramedRedlines, redPos, redLen, redCell, redTable); } catch (const uno::Exception&) { diff --git a/writerfilter/source/dmapper/PropertyMap.hxx b/writerfilter/source/dmapper/PropertyMap.hxx index 719233d1ee73..23c25bec3bb2 100644 --- a/writerfilter/source/dmapper/PropertyMap.hxx +++ b/writerfilter/source/dmapper/PropertyMap.hxx @@ -34,6 +34,7 @@ #include <utility> #include <vector> #include <set> +#include <deque> namespace com::sun::star { namespace beans { @@ -412,6 +413,10 @@ public: void ClearHeaderFooterLinkToPrevious( bool bHeader, PageType eType ); }; +void BeforeConvertToTextFrame(std::deque<css::uno::Any>& rFramedRedlines, std::vector<sal_Int32>& redPos, std::vector<sal_Int32>& redLen, std::vector<OUString>& redCell, std::vector<OUString>& redTable); + +void AfterConvertToTextFrame(DomainMapper_Impl& rDM_Impl, std::deque<css::uno::Any>& aFramedRedlines, std::vector<sal_Int32>& redPos, std::vector<sal_Int32>& redLen, std::vector<OUString>& redCell, std::vector<OUString>& redTable); + class ParagraphProperties : public SvRefBase { private: |