diff options
author | Miklos Vajna <vmiklos@suse.cz> | 2012-12-27 23:37:35 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@suse.cz> | 2012-12-28 13:43:45 +0100 |
commit | 1d7287f8d7984eae98a577f60a8bc0a740fc5e9e (patch) | |
tree | 3c3c4fb09e6e7a9efad4bc1c8e4a987715613b98 | |
parent | d7223549a5ee1b7900b6db33c116ababd8db63e8 (diff) |
fdo#45183 fix RTF import of tables with different row widths
(cherry picked from commit c3b0f13546b30e5db3aecd311c7178e4e0933208)
-rw-r--r-- | sw/qa/extras/rtfimport/data/fdo45183.rtf | 34 | ||||
-rw-r--r-- | sw/qa/extras/rtfimport/rtfimport.cxx | 15 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfdocumentimpl.cxx | 13 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfdocumentimpl.hxx | 2 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfsprm.cxx | 11 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfsprm.hxx | 2 |
6 files changed, 72 insertions, 5 deletions
diff --git a/sw/qa/extras/rtfimport/data/fdo45183.rtf b/sw/qa/extras/rtfimport/data/fdo45183.rtf new file mode 100644 index 000000000000..edc1faf8b763 --- /dev/null +++ b/sw/qa/extras/rtfimport/data/fdo45183.rtf @@ -0,0 +1,34 @@ +{\rtf1 +\titlepg +{\headerf \pard\plain \s18\ql \li0\ri0\widctlpar\tqc\tx4536\tqr\tx9072\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1029\langfe1029\cgrid\langnp1029\langfenp1029 +{\lang1024\langfe1024\noproof +{\shp +{\*\shpinst\shpleft0\shptop0\shpright9632\shpbottom14448\shpfhdr1\shpbxcolumn\shpbxignore\shpbypara\shpbyignore\shpwr3\shpwrk0\shpfblwtxt1\shpz0\shplid2055 +{\sp +{\sn shapeType} +{\sv 75} +} +{\sp +{\sn pib} +{\sv +{\pict\picscalex111\picscaley111\piccropl0\piccropr0\piccropt0\piccropb0\picw15238\pich22856\picwgoal8639\pichgoal12958\pngblip\bliptag-1542381464 +{\*\blipuid a41120687e26e79d08f14204528a39df} +47494638396110001000d5ff00000000ffffffc0c0c0555f00ffffaafcfcfcf6f6f6eaeaeae6e6e6e4e4e4e3e3e3c2c2c2c1c1c1bcbcbcb5b5b5b3b3b3b0b0b0adadada5a5a5a2a2a2a1a1a19f9f9f9494948a8a8a8888888686867b7b7b6c6c6c5c5c5c4e4e4e4b4b4b4747474646463d3d3d3c3c3c2e2e2e2525251b1b1b18181810101009090906060603030300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021f90401000002002c0000000010001000000684408170482c0a06c8a4728924389f506833b281302a8e6b164b18103024c52111504cca67332102e0042e9a40d9319f8300a343c1200f54e47f7e2a00001e0b0a7d0d728a010d838400261a7c0d94947784252700127e9d159f6c8411140019080ea7a9a85f842122281612b1b3b25d6b1f29291d0fbbbdbc5d5e51c34e4cc64a46c94341003b} +} +} +} +\par} +} +} +\pard\plain +\par +\trowd\cellx9205 +\pard\plain aaa\par +\pard bbb +\cell +\trowd\cellx9205\row +\trowd\cellx140 +\pard\cell +\trowd\cellx140\row +\pard\par +} diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx index 513ea2c2f65d..8de192291158 100644 --- a/sw/qa/extras/rtfimport/rtfimport.cxx +++ b/sw/qa/extras/rtfimport/rtfimport.cxx @@ -132,6 +132,7 @@ public: void testFdo57886(); void testFdo58076(); void testFdo57678(); + void testFdo45183(); CPPUNIT_TEST_SUITE(Test); #if !defined(MACOSX) && !defined(WNT) @@ -214,6 +215,7 @@ void Test::run() {"fdo57886.rtf", &Test::testFdo57886}, {"fdo58076.rtf", &Test::testFdo58076}, {"fdo57678.rtf", &Test::testFdo57678}, + {"fdo45183.rtf", &Test::testFdo45183}, }; for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i) { @@ -988,6 +990,19 @@ void Test::testFdo57678() CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xIndexAccess->getCount()); } +void Test::testFdo45183() +{ + uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xDraws(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY); + // Was text::WrapTextMode_PARALLEL, i.e. shpfblwtxt didn't send the shape below text. + CPPUNIT_ASSERT_EQUAL(text::WrapTextMode_THROUGHT, getProperty<text::WrapTextMode>(xDraws->getByIndex(0), "Surround")); + + uno::Reference<text::XTextTablesSupplier> xTextTablesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xTables(xTextTablesSupplier->getTextTables(), uno::UNO_QUERY); + // Was 247, resulting in a table having width almost zero and height of 10+ pages. + CPPUNIT_ASSERT_EQUAL(sal_Int32(16237), getProperty<sal_Int32>(xTables->getByIndex(0), "Width")); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx index 0de85f61bb45..378e9f57067c 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx @@ -276,7 +276,8 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x m_bNeedSect(true), m_bWasInFrame(false), m_bHadPicture(false), - m_bHadSect(false) + m_bHadSect(false), + m_nCellxMax(0) { OSL_ASSERT(xInputStream.is()); m_pInStream.reset(utl::UcbStreamHelper::CreateStream(xInputStream, sal_True)); @@ -1619,7 +1620,11 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) if (bNeedPap) runProps(); if (!m_pCurrentBuffer) + { parBreak(); + // Not in table? Reset max width. + m_nCellxMax = 0; + } else if (m_aStates.top().nDestinationState != DESTINATION_SHAPETEXT) { RTFValue::Pointer_t pValue; @@ -1683,6 +1688,11 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) case RTF_ROW: case RTF_NESTROW: { + // If the right edge of the last cell (row width) is smaller than the width of some other row, mimic the WW8 import: add a fake cell. + RTFValue::Pointer_t pLastCellx = m_aStates.top().aTableRowSprms.find(NS_ooxml::LN_CT_TblGridBase_gridCol, false); + if (pLastCellx.get() && pLastCellx->getInt() < m_nCellxMax) + dispatchValue(RTF_CELLX, m_nCellxMax); + if (m_aStates.top().nCells) { // Make a backup before we start popping elements @@ -2945,6 +2955,7 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) m_aStates.top().aTableCellAttributes = m_aDefaultState.aTableCellAttributes; // We assume text after a row definition always belongs to the table, to handle text before the real INTBL token dispatchFlag(RTF_INTBL); + m_nCellxMax = std::max(m_nCellxMax, nParam); } break; case RTF_TRRH: diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx index 283faec9b531..d61efef493b7 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx @@ -592,6 +592,8 @@ namespace writerfilter { bool m_bHadPicture; /// The document has multiple sections. bool m_bHadSect; + /// Max width of the rows in the current table. + int m_nCellxMax; }; } // namespace rtftok } // namespace writerfilter diff --git a/writerfilter/source/rtftok/rtfsprm.cxx b/writerfilter/source/rtftok/rtfsprm.cxx index 2cbf6d620133..ed25dafe490f 100644 --- a/writerfilter/source/rtftok/rtfsprm.cxx +++ b/writerfilter/source/rtftok/rtfsprm.cxx @@ -98,12 +98,17 @@ std::string RTFSprm::toString() const return aBuf.makeStringAndClear().getStr(); } -RTFValue::Pointer_t RTFSprms::find(Id nKeyword) +RTFValue::Pointer_t RTFSprms::find(Id nKeyword, bool bFirst) { + RTFValue::Pointer_t pValue; for (RTFSprms::Iterator_t i = m_pSprms->begin(); i != m_pSprms->end(); ++i) if (i->first == nKeyword) - return i->second; - RTFValue::Pointer_t pValue; + { + if (bFirst) + return i->second; + else + pValue = i->second; + } return pValue; } diff --git a/writerfilter/source/rtftok/rtfsprm.hxx b/writerfilter/source/rtftok/rtfsprm.hxx index 5f7a793cb28a..58955c4cd339 100644 --- a/writerfilter/source/rtftok/rtfsprm.hxx +++ b/writerfilter/source/rtftok/rtfsprm.hxx @@ -65,7 +65,7 @@ namespace writerfilter { RTFSprms(const RTFSprms& rSprms); ~RTFSprms(); RTFSprms& operator=(const RTFSprms& rOther); - RTFValue::Pointer_t find(Id nKeyword); + RTFValue::Pointer_t find(Id nKeyword, bool bFirst = true); /// Does the same as ->push_back(), except that it can overwrite existing entries. void set(Id nKeyword, RTFValue::Pointer_t pValue, bool bOverwrite = true); bool erase(Id nKeyword); |