diff options
author | Vinaya Mandke <vinaya.mandke@synerzip.com> | 2014-04-18 15:50:51 +0530 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2014-04-24 12:57:51 +0200 |
commit | 2e8aad6d45c53d554ccaf26de998ede708cfc289 (patch) | |
tree | 544798fb9fd2268356056ed12c5841bfd3b2616f | |
parent | cf058da1e5664bc8c30a5777e2c1dbf059a6304f (diff) |
fdo#39056 fdo#75431 Section Properties if section starts with table
Section properties are not imported if the section starts with a table for DOCX,
and also for a few RTF files with combination of tables and section breaks.
SwXBodyText::createTextCursorByRange is not able to find the start of section and hence
section properties are not applied.
As a workaround added an empty paragraph at the beginning of every section
which has the the first element as a table. And then removed it when the
section ends ( DomainMapper::lcl_endSectionGroup is called).
Also handled to add the paragraph earlier, if there is a bookmark
so that the bookmark is not attached to the dummy paragraph.
Conflicts:
sw/qa/extras/ooxmlexport/ooxmlexport.cxx
Reviewed on:
https://gerrit.libreoffice.org/9097
Change-Id: I717ba40e22b055d974bc83d4414aeb2945e16d26
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/fdo75431.docx | bin | 0 -> 13275 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport.cxx | 12 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper.cxx | 22 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapperTableManager.hxx | 5 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.cxx | 74 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.hxx | 8 | ||||
-rw-r--r-- | writerfilter/source/dmapper/PropertyMap.hxx | 2 |
7 files changed, 120 insertions, 3 deletions
diff --git a/sw/qa/extras/ooxmlexport/data/fdo75431.docx b/sw/qa/extras/ooxmlexport/data/fdo75431.docx Binary files differnew file mode 100644 index 000000000000..492278403686 --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/fdo75431.docx diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx index ebc6500a8f98..631f415d2c86 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx @@ -3181,6 +3181,18 @@ DECLARE_OOXMLEXPORT_TEST(testFDO77117, "fdo77117.docx") // This checks textbox textrun size of font which is in group shape. CPPUNIT_ASSERT_EQUAL(11.f, getProperty<float>(xShape, "CharHeight")); } + +DECLARE_OOXMLEXPORT_TEST(testFDO75431, "fdo75431.docx") +{ + xmlDocPtr pXmlDoc = parseExport("word/document.xml"); + + if (!pXmlDoc) + return; + + assertXPath(pXmlDoc, "//w:tbl", 2); + assertXPath(pXmlDoc, "//w:p/w:pPr/w:sectPr/w:type", "val", "nextPage"); +} + #endif CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/writerfilter/source/dmapper/DomainMapper.cxx b/writerfilter/source/dmapper/DomainMapper.cxx index c73e14ceb80d..0b5219c09e4a 100644 --- a/writerfilter/source/dmapper/DomainMapper.cxx +++ b/writerfilter/source/dmapper/DomainMapper.cxx @@ -2323,7 +2323,20 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, PropertyMapPtr rContext ) } break; case NS_ooxml::LN_tblStart: + + /* + * Hack for Importing Section Properties + * LO is not able to import section properties if first element in the + * section is a table. So in case first element is a table add a dummy para + * and remove it again when lcl_endSectionGroup is called + */ + if(m_pImpl->m_nTableDepth == 0 && m_pImpl->GetIsFirstParagraphInSection() + && !m_pImpl->GetIsDummyParaAddedForTableInSection() && !m_pImpl->GetIsTextFrameInserted()) + { + m_pImpl->AddDummyParaForTableInSection(); + } m_pImpl->m_nTableDepth++; + break; case NS_ooxml::LN_tblEnd: m_pImpl->m_nTableDepth--; @@ -2450,6 +2463,7 @@ void DomainMapper::lcl_startSectionGroup() { m_pImpl->PushProperties(CONTEXT_SECTION); } + m_pImpl->SetIsFirstParagraphInSection(true); } void DomainMapper::lcl_endSectionGroup() @@ -2474,7 +2488,13 @@ void DomainMapper::lcl_endSectionGroup() SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() ); OSL_ENSURE(pSectionContext, "SectionContext unavailable!"); if(pSectionContext) + { pSectionContext->CloseSectionGroup( *m_pImpl ); + // Remove the dummy paragraph if added for + // handling the section properties if section starts with a table + if (m_pImpl->GetIsDummyParaAddedForTableInSection()) + m_pImpl->RemoveDummyParaForTableInSection(); + } m_pImpl->PopProperties(CONTEXT_SECTION); } } @@ -2765,7 +2785,7 @@ void DomainMapper::lcl_utext(const sal_uInt8 * data_, size_t len) bool bRemove = !m_pImpl->GetParaChanged() && m_pImpl->GetParaSectpr() && !bSingleParagraph; m_pImpl->SetParaSectpr(false); m_pImpl->finishParagraph(m_pImpl->GetTopContextOfType(CONTEXT_PARAGRAPH)); - if (bRemove) + if (bRemove && !m_pImpl->GetIsDummyParaAddedForTableInSection()) m_pImpl->RemoveLastParagraph(); } else diff --git a/writerfilter/source/dmapper/DomainMapperTableManager.hxx b/writerfilter/source/dmapper/DomainMapperTableManager.hxx index f6333f8503d0..47c2f7d7be5d 100644 --- a/writerfilter/source/dmapper/DomainMapperTableManager.hxx +++ b/writerfilter/source/dmapper/DomainMapperTableManager.hxx @@ -147,6 +147,11 @@ public: m_nLayoutType = nLayoutType; } + bool isInCell() + { + return TableManager::isInCell(); + } + }; }} diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 9c8800877dd0..26aa55065b80 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -178,6 +178,8 @@ DomainMapper_Impl::DomainMapper_Impl( m_bIsParaMarkerChange( false ), m_bParaChanged( false ), m_bIsFirstParaInSection( true ), + m_bDummyParaAddedForTableInSection( false ), + m_bTextFrameInserted(false), m_bIsLastParaInSection( false ), m_bIsInComments( false ), m_bParaSectpr( false ), @@ -280,6 +282,36 @@ void DomainMapper_Impl::SetDocumentSettingsProperty( const OUString& rPropName, } } } +void DomainMapper_Impl::RemoveDummyParaForTableInSection() +{ + SetIsDummyParaAddedForTableInSection(false); + PropertyMapPtr pContext = GetTopContextOfType(CONTEXT_SECTION); + SectionPropertyMap* pSectionContext = dynamic_cast< SectionPropertyMap* >( pContext.get() ); + uno::Reference< text::XTextCursor > xCursor = GetTopTextAppend()->createTextCursorByRange(pSectionContext->GetStartingRange()); + + uno::Reference<container::XEnumerationAccess> xEnumerationAccess(xCursor, uno::UNO_QUERY); + if (xEnumerationAccess.is() && m_aTextAppendStack.size() == 1 ) + { + uno::Reference<container::XEnumeration> xEnumeration = xEnumerationAccess->createEnumeration(); + uno::Reference<lang::XComponent> xParagraph(xEnumeration->nextElement(), uno::UNO_QUERY); + xParagraph->dispose(); + } +} +void DomainMapper_Impl::AddDummyParaForTableInSection() +{ + + if (!m_aTextAppendStack.empty()) + { + uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; + uno::Reference< text::XTextCursor > xCrsr = xTextAppend->getText()->createTextCursor(); + uno::Reference< text::XText > xText = xTextAppend->getText(); + if(xCrsr.is() && xText.is()) + { + xTextAppend->finishParagraph( uno::Sequence< beans::PropertyValue >() ); + SetIsDummyParaAddedForTableInSection(true); + } + } +} void DomainMapper_Impl::RemoveLastParagraph( ) { @@ -362,6 +394,27 @@ bool DomainMapper_Impl::GetIsFirstParagraphInSection() return m_bIsFirstParaInSection; } + +void DomainMapper_Impl::SetIsDummyParaAddedForTableInSection( bool bIsAdded ) +{ + m_bDummyParaAddedForTableInSection = bIsAdded; +} + +bool DomainMapper_Impl::GetIsDummyParaAddedForTableInSection() +{ + return m_bDummyParaAddedForTableInSection; +} + +void DomainMapper_Impl::SetIsTextFrameInserted( bool bIsInserted ) +{ + m_bTextFrameInserted = bIsInserted; +} + +bool DomainMapper_Impl::GetIsTextFrameInserted() +{ + return m_bTextFrameInserted; +} + void DomainMapper_Impl::SetParaSectpr(bool bParaSectpr) { m_bParaSectpr = bParaSectpr; @@ -1752,6 +1805,7 @@ void DomainMapper_Impl::PushShapeContext( const uno::Reference< drawing::XShape bool checkZOredrStatus = false; if (xSInfo->supportsService("com.sun.star.text.TextFrame")) { + SetIsTextFrameInserted(true); // Extract the special "btLr text frame" mode, requested by oox, if needed. // Extract vml ZOrder from FrameInteropGrabBag uno::Reference<beans::XPropertySet> xShapePropertySet(xShape, uno::UNO_QUERY); @@ -4122,6 +4176,18 @@ void DomainMapper_Impl::PopFieldContext() void DomainMapper_Impl::AddBookmark( const OUString& rBookmarkName, const OUString& rId ) { + /* + * Add the dummy paragraph to handle section properties + * iff the first element in the section is a table. If the dummy para is not added yet, then add it; + * So bookmark is not attched to the wrong paragraph. + */ + if(getTableManager( ).isInCell() && m_nTableDepth == 0 && GetIsFirstParagraphInSection() + && !GetIsDummyParaAddedForTableInSection() &&!GetIsTextFrameInserted()) + { + AddDummyParaForTableInSection(); + } + + bool bIsAfterDummyPara = GetIsDummyParaAddedForTableInSection() && GetIsFirstParagraphInSection(); if (m_aTextAppendStack.empty()) return; uno::Reference< text::XTextAppend > xTextAppend = m_aTextAppendStack.top().xTextAppend; @@ -4137,8 +4203,10 @@ void DomainMapper_Impl::AddBookmark( const OUString& rBookmarkName, const OUStri uno::Reference< text::XTextContent > xBookmark( m_xTextFactory->createInstance( sBookmarkService ), uno::UNO_QUERY_THROW ); uno::Reference< text::XTextCursor > xCursor; uno::Reference< text::XText > xText = aBookmarkIter->second.m_xTextRange->getText(); - if( aBookmarkIter->second.m_bIsStartOfText ) + if( aBookmarkIter->second.m_bIsStartOfText && !bIsAfterDummyPara) + { xCursor = xText->createTextCursorByRange( xText->getStart() ); + } else { xCursor = xText->createTextCursorByRange( aBookmarkIter->second.m_xTextRange ); @@ -4164,7 +4232,9 @@ void DomainMapper_Impl::AddBookmark( const OUString& rBookmarkName, const OUStri if (xTextAppend.is()) { uno::Reference< text::XTextCursor > xCursor = xTextAppend->createTextCursorByRange( xTextAppend->getEnd() ); - bIsStart = !xCursor->goLeft(1, false); + + if(!bIsAfterDummyPara) + bIsStart = !xCursor->goLeft(1, false); xCurrent = xCursor->getStart(); } m_aBookmarkMap.insert(BookmarkMap_t::value_type( rId, BookmarkInsertPosition( bIsStart, rBookmarkName, xCurrent ) )); diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.hxx b/writerfilter/source/dmapper/DomainMapper_Impl.hxx index 842a13b3bb03..ab98cfec4630 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.hxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.hxx @@ -378,6 +378,8 @@ private: /// If the current paragraph has any runs. bool m_bParaChanged; bool m_bIsFirstParaInSection; + bool m_bDummyParaAddedForTableInSection; + bool m_bTextFrameInserted; bool m_bIsLastParaInSection; bool m_bIsInComments; /// If the current paragraph contains section property definitions. @@ -451,11 +453,17 @@ public: void EndParaMarkerChange( ); void ChainTextFrames(); + void RemoveDummyParaForTableInSection(); + void AddDummyParaForTableInSection(); void RemoveLastParagraph( ); void SetIsLastParagraphInSection( bool bIsLast ); bool GetIsLastParagraphInSection(); void SetIsFirstParagraphInSection( bool bIsFirst ); bool GetIsFirstParagraphInSection(); + void SetIsDummyParaAddedForTableInSection( bool bIsAdded ); + bool GetIsDummyParaAddedForTableInSection(); + void SetIsTextFrameInserted( bool bIsInserted ); + bool GetIsTextFrameInserted(); void SetParaSectpr(bool bParaSectpr); bool GetParaSectpr(); /// Setter method for m_bSdt. diff --git a/writerfilter/source/dmapper/PropertyMap.hxx b/writerfilter/source/dmapper/PropertyMap.hxx index 710be096b56c..1769d5b90c3d 100644 --- a/writerfilter/source/dmapper/PropertyMap.hxx +++ b/writerfilter/source/dmapper/PropertyMap.hxx @@ -228,6 +228,8 @@ public: m_xStartingRange = xRange; } + ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > GetStartingRange() const { return m_xStartingRange; } + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > GetPageStyle( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >& xStyles, const ::com::sun::star::uno::Reference < ::com::sun::star::lang::XMultiServiceFactory >& xTextFactory, |