summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVinaya Mandke <vinaya.mandke@synerzip.com>2014-04-18 15:50:51 +0530
committerMiklos Vajna <vmiklos@collabora.co.uk>2014-04-24 12:57:51 +0200
commit2e8aad6d45c53d554ccaf26de998ede708cfc289 (patch)
tree544798fb9fd2268356056ed12c5841bfd3b2616f
parentcf058da1e5664bc8c30a5777e2c1dbf059a6304f (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.docxbin0 -> 13275 bytes
-rw-r--r--sw/qa/extras/ooxmlexport/ooxmlexport.cxx12
-rw-r--r--writerfilter/source/dmapper/DomainMapper.cxx22
-rw-r--r--writerfilter/source/dmapper/DomainMapperTableManager.hxx5
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.cxx74
-rw-r--r--writerfilter/source/dmapper/DomainMapper_Impl.hxx8
-rw-r--r--writerfilter/source/dmapper/PropertyMap.hxx2
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
new file mode 100644
index 000000000000..492278403686
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/fdo75431.docx
Binary files differ
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,