diff options
author | Miklos Vajna <vmiklos@suse.cz> | 2013-05-21 14:56:45 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@suse.cz> | 2013-05-21 17:46:49 +0200 |
commit | 0b22370730ef1e8a34c2b15397484cbd2019dd57 (patch) | |
tree | b37b95f427ef4c73488e3057144ac05dd92fbef9 | |
parent | a9d593005b7b3ee4ff6352a883031adec5fd01f1 (diff) |
bnc#818997 RTF import: don't ignore page breaks between shapes
Change-Id: Ief71ba9a3c60356714e73d08e88d0a3105b17b1a
(cherry picked from commit b40fe8e5a5037d2745cc7b1c9cc408ce6c79b9d9)
-rw-r--r-- | sw/qa/extras/rtfimport/data/n818997.rtf | 77 | ||||
-rw-r--r-- | sw/qa/extras/rtfimport/rtfimport.cxx | 8 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper.cxx | 13 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.cxx | 15 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.hxx | 1 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfdocumentimpl.cxx | 4 | ||||
-rw-r--r-- | writerfilter/source/rtftok/rtfdocumentimpl.hxx | 2 |
7 files changed, 120 insertions, 0 deletions
diff --git a/sw/qa/extras/rtfimport/data/n818997.rtf b/sw/qa/extras/rtfimport/data/n818997.rtf new file mode 100644 index 000000000000..2ce44048626a --- /dev/null +++ b/sw/qa/extras/rtfimport/data/n818997.rtf @@ -0,0 +1,77 @@ +{\rtf
+{\shp
+{\*\shpinst\shpleft2310\shpright6060\shptop8685\shpbottom8985\shpbxpage
+\shpbypage\shpwr3\shpz2
+{\sp
+{\sn shapeType}
+{\sv 202}
+}
+{\sp
+{\sn dxTextLeft}
+{\sv
+0}
+}
+{\sp
+{\sn dxTextRight}
+{\sv 0}
+}
+{\sp
+{\sn dyTextTop}
+{\sv 0}
+}
+{\sp
+{\sn
+dyTextBottom}
+{\sv 0}
+}
+{\sp
+{\sn fLine}
+{\sv 0}
+}
+{\shptxt\plain\pard\f29\fs24
+On first page.\par}
+{\sp
+{\sn fFilled}
+{\sv 0}
+}
+}
+}
+\page
+{\shp
+{\*\shpinst\shpleft4800\shpright8025\shptop780\shpbottom1080\shpbxpage
+\shpbypage\shpwr3\shpz2
+{\sp
+{\sn shapeType}
+{\sv 202}
+}
+{\sp
+{\sn dxTextLeft}
+{\sv
+0}
+}
+{\sp
+{\sn dxTextRight}
+{\sv 0}
+}
+{\sp
+{\sn dyTextTop}
+{\sv 0}
+}
+{\sp
+{\sn
+dyTextBottom}
+{\sv 0}
+}
+{\sp
+{\sn fLine}
+{\sv 0}
+}
+{\shptxt\plain\pard\f29\fs24\b
+On second page.\par}
+{\sp
+{\sn fFilled}
+{\sv 0}
+}
+}
+}
+}
diff --git a/sw/qa/extras/rtfimport/rtfimport.cxx b/sw/qa/extras/rtfimport/rtfimport.cxx index d2ccfbae100a..c0ceabc989fc 100644 --- a/sw/qa/extras/rtfimport/rtfimport.cxx +++ b/sw/qa/extras/rtfimport/rtfimport.cxx @@ -135,6 +135,7 @@ public: void testFdo63023(); void testFdo42109(); void testFdo62977(); + void testN818997(); CPPUNIT_TEST_SUITE(Test); #if !defined(MACOSX) && !defined(WNT) @@ -259,6 +260,7 @@ void Test::run() {"fdo63023.rtf", &Test::testFdo63023}, {"fdo42109.rtf", &Test::testFdo42109}, {"fdo62977.rtf", &Test::testFdo62977}, + {"n818997.rtf", &Test::testN818997}, }; header(); for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i) @@ -1232,6 +1234,12 @@ void Test::testFdo62977() getRun(getParagraph(1), 1, OUString("\xE5\xB9\xB4\xEF\xBC\x94\xE6\x9C\x88", 9, RTL_TEXTENCODING_UTF8)); } +void Test::testN818997() +{ + // \page was ignored between two \shp tokens. + CPPUNIT_ASSERT_EQUAL(2, getPages()); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index 9de2fa68c9b6..10a018a066ea 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -3486,6 +3486,19 @@ void DomainMapper::lcl_startShape( uno::Reference< drawing::XShape > xShape ) { if (m_pImpl->GetTopContext()) { + // If there is a deferred page break, handle it now, so that the + // started shape will be on the correct page. + if (m_pImpl->isBreakDeferred(PAGE_BREAK)) + { + m_pImpl->clearDeferredBreak(PAGE_BREAK); + lcl_startCharacterGroup(); + sal_uInt8 sBreak[] = { 0xd }; + lcl_text(sBreak, 1); + lcl_endCharacterGroup(); + lcl_endParagraphGroup(); + lcl_startParagraphGroup(); + m_pImpl->GetTopContext()->Insert(PROP_BREAK_TYPE, true, uno::makeAny( com::sun::star::style::BreakType_PAGE_BEFORE)); + } m_pImpl->PushShapeContext( xShape ); lcl_startParagraphGroup(); } diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index c05750ce3d81..fa6b36d43d93 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -644,6 +644,21 @@ bool DomainMapper_Impl::isBreakDeferred( BreakType deferredBreakType ) } } +void DomainMapper_Impl::clearDeferredBreak(BreakType deferredBreakType) +{ + switch (deferredBreakType) + { + case COLUMN_BREAK: + m_bIsColumnBreakDeferred = false; + break; + case PAGE_BREAK: + m_bIsPageBreakDeferred = false; + break; + default: + break; + } +} + void DomainMapper_Impl::clearDeferredBreaks() { m_bIsColumnBreakDeferred = false; diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index 60faa83be428..b7da3a937a95 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -445,6 +445,7 @@ public: void deferBreak( BreakType deferredBreakType ); bool isBreakDeferred( BreakType deferredBreakType ); void clearDeferredBreaks(); + void clearDeferredBreak(BreakType deferredBreakType); void finishParagraph( PropertyMapPtr pPropertyMap ); void appendTextPortion( const OUString& rString, PropertyMapPtr pPropertyMap ); void appendTextContent( const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextContent >, diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx index 9943d7471147..a5e3f755cda4 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx @@ -230,6 +230,7 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x m_bFirstRun(true), m_bNeedPap(true), m_bNeedCr(false), + m_bNeedCrOrig(false), m_bNeedPar(true), m_bNeedFinalPar(false), m_aListTableSprms(), @@ -1317,6 +1318,7 @@ int RTFDocumentImpl::dispatchDestination(RTFKeyword nKeyword) m_aStates.top().nDestinationState = DESTINATION_SHAPEPROPERTYVALUE; break; case RTF_SHP: + m_bNeedCrOrig = m_bNeedCr; m_aStates.top().nDestinationState = DESTINATION_SHAPE; break; case RTF_SHPINST: @@ -1937,6 +1939,7 @@ int RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword) Mapper().text(sBreak, 1); if (!m_bNeedPap) parBreak(); + m_bNeedCr = true; } } break; @@ -4134,6 +4137,7 @@ int RTFDocumentImpl::popState() } break; case DESTINATION_SHAPE: + m_bNeedCr = m_bNeedCrOrig; if (aState.aFrame.inFrame()) { // parBreak modify m_aStates.top() so we can't apply resetFrame directly on aState diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx b/writerfilter/source/rtftok/rtfdocumentimpl.hxx index 163413b78542..d6216f48ee6d 100644 --- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx +++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx @@ -516,6 +516,8 @@ namespace writerfilter { bool m_bNeedPap; /// If we need to emit a CR at the end of substream. bool m_bNeedCr; + /// Original value of m_bNeedCr -- saved/restored before/after textframes. + bool m_bNeedCrOrig; bool m_bNeedPar; /// If set, an empty paragraph will be added at the end of the document. bool m_bNeedFinalPar; |