[Libreoffice-commits] core.git: sw/qa writerfilter/source

Vinaya Mandke vinaya.mandke at synerzip.com
Thu Apr 24 03:58:35 PDT 2014


 sw/qa/extras/ooxmlexport/data/fdo75431.docx              |binary
 sw/qa/extras/ooxmlexport/ooxmlexport.cxx                 |   12 ++
 writerfilter/source/dmapper/DomainMapper.cxx             |   22 ++++
 writerfilter/source/dmapper/DomainMapperTableManager.hxx |    5 +
 writerfilter/source/dmapper/DomainMapper_Impl.cxx        |   74 ++++++++++++++-
 writerfilter/source/dmapper/DomainMapper_Impl.hxx        |    8 +
 writerfilter/source/dmapper/PropertyMap.hxx              |    2 
 7 files changed, 120 insertions(+), 3 deletions(-)

New commits:
commit 2e8aad6d45c53d554ccaf26de998ede708cfc289
Author: Vinaya Mandke <vinaya.mandke at synerzip.com>
Date:   Fri Apr 18 15:50:51 2014 +0530

    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

diff --git a/sw/qa/extras/ooxmlexport/data/fdo75431.docx b/sw/qa/extras/ooxmlexport/data/fdo75431.docx
new file mode 100644
index 0000000..4922784
Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/fdo75431.docx differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport.cxx
index ebc6500..631f415 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 c73e14c..0b5219c 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 f6333f8..47c2f7d 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 9c88008..26aa550 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 842a13b..ab98cfe 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 710be09..1769d5b 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,


More information about the Libreoffice-commits mailing list