sw/qa/extras/rtfimport/data/fdo57708.rtf | 8 ++ sw/qa/extras/rtfimport/rtfimport.cxx | 12 ++++ writerfilter/source/rtftok/rtfdocumentimpl.cxx | 70 +++++++++++++++---------- writerfilter/source/rtftok/rtfdocumentimpl.hxx | 13 +++- 4 files changed, 73 insertions(+), 30 deletions(-)
New commits: commit 7baca04727fbd3297c6e4b9815bf2a4695175e2e Author: Miklos Vajna <[email protected]> Date: Fri Nov 30 17:15:35 2012 +0100 fdo#57708 testcase Change-Id: I5064cb9bb9700483eac4d56a56e671a392e82f73 diff --git a/sw/qa/extras/rtfimport/data/fdo57708.rtf b/sw/qa/extras/rtfimport/data/fdo57708.rtf new file mode 100644 index 0000000..54a7579 --- /dev/null +++ b/sw/qa/extras/rtfimport/data/fdo57708.rtf @@ -0,0 +1,8 @@ +{\rtf1\ansi\ansicpg1250\deff0\deflang1033{\fonttbl{\f0\fswiss\fcharset238 Metrostyle Extended;}}{\colortbl;\red0\green0\blue0;}{\info{\title }{\author Crystal Reports}{\doccomm Powered By Crystal}{\company Crystal Decisions}}{\*\userprops {\propname Business Objects Context Information}\proptype30{\staticval 01734361CD07C3C85B968AA4B2781C480C308DEB5E1F83247788228D3179576779474C0EDA07FA11789515F5C58418E566CFBE6A992AA227B056A18BF687A22CF4C7A2A60E137F6E64ADB5B69ED3464CA2298397B1C63A46E7CA415DF52DCCA4B3EE086B2778F5C67ADA7979DE0AB40BE865BD20C51228AC3938C7268BEB053}{\propname Business Objects Context Information1}\proptype30{\staticval 196223CE7A2CA417EF871437DC7F0AFC626}} +\paperw11904\paperh16834\margl1416\margr849\margt849\margb849\gutter0\windowctrl\ftnbj\viewkind1\viewscale100\sectd\linex0\sbknone +\sect {\shp{\*\shpinst\shpleft1416\shptop879\shpright2719\shpbottom2138\shpfhdr0\shpbxpage\shpbypage\shpwr3\shpwrk0\shpfblwtxt1{\sp{\sn txflTextFlow}{\sv 0}}{\sp{\sn shapeType}{\sv 75}}{\sp{\sn fBehindDocument}{\sv 1}}{\sp{\sn fLockAspectRatio}{\sv 0}}{\sp{\sn fPreferRelativeResize}{\sv 0}}{\sp{\sn pib}{\sv {\pict\wmetafile6\picw1303\pich1259\picwgoal1303\pichgoal1259\picscalex100\picscaley100 89504e470d0a1a0a0000000d4948445200000010000000100802000000909168360000015049444154789c9592c14a02511486bf99714ccb322d7521140541cb +6a11448b164150fb8a363d41f4083d40cba0655044d0a637a837682fd1a6a2488b10b23475bcb77b671c491dc1cee23077e67cf7fcff39139252f29f08b59e3e +1dae8b4c45998ff501a82e070f5cbd3366733acb5c6fa609fc0872651236df0deeca7d002a6cc33d1b941a146ab49ca937e37610e0c590c5c92b67f926a07243 +b293613f8b1108a8a84aadb01575c9799edd0c895010a0ae71048e77b99b6a92e53861a387a48a6033c5d208c297a43ca8a3697601d217b010632dd9a9f34be0 +9968021698bea4c76ab72f5dd0d6216c3211e1bec2a0c5e59bce9303baa770c7bd38aca7d729692bcd4d512b53bb3b7cc2f45dd604ab098e67b499366025ce5e +96a317fd2162e2d76bbbb725bdcd80b12a603aca4581e7aade97e14ec2916ca719ed96e4c54692f5241f755de7019641eacfaff10b469261dc6a800dd30000000049454e44ae426082}}}}}{\pard \pvpg\phpg\posx2969\posy1070\absw7935\absh-423\qc\vertalt\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320\tx4680\tx5040\tx5400\tx5760\tx6120\tx6480\tx6840\tx7200\tx7560\tx7920{\ltrch\f0 \b\i0\ul0\strike0\fs35 \cf1 PM1 TEST\par}}} diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx index a201c36..7853fc3 100644 --- a/sw/qa/extras/rtfimport/rtfimport.cxx +++ b/sw/qa/extras/rtfimport/rtfimport.cxx @@ -126,6 +126,7 @@ public: void testFdo52989(); void testFdo48442(); void testFdo55525(); + void testFdo57708(); CPPUNIT_TEST_SUITE(Test); #if !defined(MACOSX) && !defined(WNT) @@ -202,6 +203,7 @@ void Test::run() {"fdo52989.rtf", &Test::testFdo52989}, {"fdo48442.rtf", &Test::testFdo48442}, {"fdo55525.rtf", &Test::testFdo55525}, + {"fdo57708.rtf", &Test::testFdo57708}, }; for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i) { @@ -929,6 +931,16 @@ void Test::testFdo55525() CPPUNIT_ASSERT_EQUAL(sal_Int16(1016), getProperty< uno::Sequence<text::TableColumnSeparator> >(xTableRows->getByIndex(0), "TableColumnSeparators")[0].Position); } +void Test::testFdo57708() +{ + // There were two issues: the doc was of 2 pages and the picture was missing. + CPPUNIT_ASSERT_EQUAL(1, getPages()); + uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xDraws(xDrawPageSupplier->getDrawPage(), uno::UNO_QUERY); + // Two objects: a picture and a textframe. + CPPUNIT_ASSERT_EQUAL(sal_Int32(2), xDraws->getCount()); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); commit 8063e36115a11ddf3db05928db9287947beee74d Author: Miklos Vajna <[email protected]> Date: Fri Nov 30 16:32:56 2012 +0100 fdo#57708 fix RTF import of pictures right before text frames Change-Id: Ibfeaadd5b48fd48c2c1f20de5dc272d9a326bfc4 diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx index 5a2f9b6..9c988d7 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx @@ -274,7 +274,8 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x m_aHexBuffer(), m_bIgnoreNextContSectBreak(false), m_bNeedSect(true), - m_bWasInFrame(false) + m_bWasInFrame(false), + m_bHadPicture(false) { OSL_ASSERT(xInputStream.is()); m_pInStream.reset(utl::UcbStreamHelper::CreateStream(xInputStream, sal_True)); @@ -497,6 +498,8 @@ void RTFDocumentImpl::parBreak() Mapper().endCharacterGroup(); Mapper().endParagraphGroup(); + m_bHadPicture = false; + // start new one Mapper().startParagraphGroup(); } @@ -813,6 +816,8 @@ int RTFDocumentImpl::resolvePict(bool bInline) m_pCurrentBuffer->push_back(make_pair(BUFFER_PROPS, pValue)); } + // Make sure we don't loose these properties with a too early reset. + m_bHadPicture = true; return 0; } @@ -2055,6 +2060,8 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) } break; case RTF_PARD: + if (m_bHadPicture) + dispatchSymbol(RTF_PAR); m_aStates.top().aParagraphSprms = m_aDefaultState.aParagraphSprms; m_aStates.top().aParagraphAttributes = m_aDefaultState.aParagraphAttributes; m_aStates.top().resetFrame(); diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx index 7147fa7..fad32e6 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx @@ -587,6 +587,8 @@ namespace writerfilter { bool m_bNeedSect; /// If aFrame.inFrame() was true in the previous state. bool m_bWasInFrame; + /// A picture was seen in the current paragraph. + bool m_bHadPicture; }; } // namespace rtftok } // namespace writerfilter commit b836bf389d1150c9cafbb0aefa641af2316e536c Author: Miklos Vajna <[email protected]> Date: Fri Nov 30 15:33:52 2012 +0100 fdo#57708 fix fake page break problem during RTF import The core of this change is: so far the continous section break at the end of the document was sent as a normal section break. This was introduced in commit 892d33c8d5033b4f8f7889bf91d257f55adf0e1f, probably as a workaround (sadly it's not documented and I no longer remember). Don't do this, since it causes additional page breaks during import. Instead, fix properly whatever was broken after getting rid of this workaround. Change-Id: I28c372d539c150fe21ff9db31209f9935a5e9063 diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx index d1888dc..5a2f9b6 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx @@ -272,7 +272,9 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x m_bIsInFrame(false), m_aUnicodeBuffer(), m_aHexBuffer(), - m_bDeferredContSectBreak(false) + m_bIgnoreNextContSectBreak(false), + m_bNeedSect(true), + m_bWasInFrame(false) { OSL_ASSERT(xInputStream.is()); m_pInStream.reset(utl::UcbStreamHelper::CreateStream(xInputStream, sal_True)); @@ -399,6 +401,11 @@ void RTFDocumentImpl::setNeedPar(bool bNeedPar) m_bNeedPar = bNeedPar; } +void RTFDocumentImpl::setNeedSect(bool bNeedSect) +{ + m_bNeedSect = bNeedSect; +} + writerfilter::Reference<Properties>::Pointer_t RTFDocumentImpl::getProperties(RTFSprms& rAttributes, RTFSprms& rSprms) { int nStyle = m_aStates.top().nCurrentStyleIndex; @@ -496,6 +503,8 @@ void RTFDocumentImpl::parBreak() void RTFDocumentImpl::sectBreak(bool bFinal = false) { + SAL_INFO("writerfilter", OSL_THIS_FUNC << ": final? " << bFinal << ", needed? " << m_bNeedSect); + bool bNeedSect = m_bNeedSect; // If there is no paragraph in this section, then insert a dummy one, as required by Writer if (m_bNeedPar) dispatchSymbol(RTF_PAR); @@ -512,10 +521,15 @@ void RTFDocumentImpl::sectBreak(bool bFinal = false) resolveSubstream(aPair.second, aPair.first); } - RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc); - // In case the last section is a continous one, we don't need to output a section break. - if (bFinal && pBreak.get() && !pBreak->getInt()) - m_aStates.top().aSectionSprms.erase(NS_sprm::LN_SBkc); + // Normally a section break at the end of the doc is necessary. Unless the + // last control word in the document is a section break itself. + if (!bNeedSect) + { + RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc); + // In case the last section is a continous one, we don't need to output a section break. + if (bFinal && pBreak.get() && !pBreak->getInt()) + m_aStates.top().aSectionSprms.erase(NS_sprm::LN_SBkc); + } // Section properties are a paragraph sprm. RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aSectionAttributes, m_aStates.top().aSectionSprms)); @@ -536,6 +550,7 @@ void RTFDocumentImpl::sectBreak(bool bFinal = false) Mapper().startParagraphGroup(); } m_bNeedPar = true; + m_bNeedSect = false; } void RTFDocumentImpl::seek(sal_uInt32 nPos) @@ -1126,7 +1141,7 @@ void RTFDocumentImpl::replayBuffer(RTFBuffer_t& rBuffer) int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword) { checkUnicode(); - checkDeferredContSectBreak(); + setNeedSect(); RTFSkipDestination aSkip(*this); switch (nKeyword) { @@ -1551,7 +1566,7 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) { if (nKeyword != RTF_HEXCHAR) checkUnicode(); - checkDeferredContSectBreak(); + setNeedSect(); RTFSkipDestination aSkip(*this); sal_uInt8 cCh = 0; @@ -1609,13 +1624,8 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) break; case RTF_SECT: { - RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc); - if (pBreak.get() && !pBreak->getInt()) - { - // This is a continous section break, don't send it yet. - // It's possible that we'll have nothing after this token, and then we should ignore it. - m_bDeferredContSectBreak = true; - } + if (m_bIgnoreNextContSectBreak) + m_bIgnoreNextContSectBreak = false; else sectBreak(); } @@ -1759,9 +1769,17 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) RTFValue::Pointer_t pBreak = m_aStates.top().aSectionSprms.find(NS_sprm::LN_SBkc); if (pBreak.get() && !pBreak->getInt()) { + if (m_bWasInFrame) + { + dispatchSymbol(RTF_PAR); + m_bWasInFrame = false; + } dispatchFlag(RTF_SBKPAGE); sectBreak(); dispatchFlag(RTF_SBKNONE); + if (m_bNeedPar) + dispatchSymbol(RTF_PAR); + m_bIgnoreNextContSectBreak = true; } else { @@ -1792,7 +1810,7 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) { checkUnicode(); - checkDeferredContSectBreak(); + setNeedSect(); RTFSkipDestination aSkip(*this); int nParam = -1; int nSprm = -1; @@ -2474,7 +2492,7 @@ int RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword) int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) { checkUnicode(nKeyword != RTF_U, true); - checkDeferredContSectBreak(); + setNeedSect(); RTFSkipDestination aSkip(*this); int nSprm = 0; RTFValue::Pointer_t pIntValue(new RTFValue(nParam)); @@ -3282,7 +3300,7 @@ int RTFDocumentImpl::dispatchValue(RTFKeyword nKeyword, int nParam) int RTFDocumentImpl::dispatchToggle(RTFKeyword nKeyword, bool bParam, int nParam) { checkUnicode(); - checkDeferredContSectBreak(); + setNeedSect(); RTFSkipDestination aSkip(*this); int nSprm = -1; RTFValue::Pointer_t pBoolValue(new RTFValue(!bParam || nParam != 0)); @@ -3477,6 +3495,7 @@ int RTFDocumentImpl::popState() checkUnicode(); RTFParserState aState(m_aStates.top()); + m_bWasInFrame = aState.aFrame.inFrame(); sal_Int32 nMathToken = 0; switch (m_aStates.top().nDestinationState) @@ -3950,7 +3969,6 @@ int RTFDocumentImpl::popState() { if (m_bNeedCr) dispatchSymbol(RTF_PAR); - m_bDeferredContSectBreak = false; sectBreak(true); } @@ -4170,15 +4188,6 @@ void RTFDocumentImpl::checkUnicode(bool bUnicode, bool bHex) } } -void RTFDocumentImpl::checkDeferredContSectBreak() -{ - if (m_bDeferredContSectBreak) - { - m_bDeferredContSectBreak = false; - sectBreak(); - } -} - RTFParserState::RTFParserState(RTFDocumentImpl *pDocumentImpl) : m_pDocumentImpl(pDocumentImpl), nInternalState(INTERNAL_NORMAL), diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx index 9801164..7147fa7 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx @@ -487,8 +487,8 @@ namespace writerfilter { void replayBuffer(RTFBuffer_t& rBuffer); /// If we have some unicode or hex characters to send. void checkUnicode(bool bUnicode = true, bool bHex = true); - /// If we have a pending continous section break. - void checkDeferredContSectBreak(); + /// If we need a final section break at the end of the document. + void setNeedSect(bool bNeedSect = true); uno::Reference<uno::XComponentContext> const& m_xContext; uno::Reference<io::XInputStream> const& m_xInputStream; @@ -581,7 +581,12 @@ namespace writerfilter { rtl::OStringBuffer m_aHexBuffer; /// Formula import. oox::formulaimport::XmlStreamBuilder m_aMathBuffer; - bool m_bDeferredContSectBreak; + /// If the next continous section break should be ignored. + bool m_bIgnoreNextContSectBreak; + /// If a section break is needed before the end of the doc (false right after a section break). + bool m_bNeedSect; + /// If aFrame.inFrame() was true in the previous state. + bool m_bWasInFrame; }; } // namespace rtftok } // namespace writerfilter _______________________________________________ Libreoffice-commits mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
