[Libreoffice-commits] .: Branch 'libreoffice-3-5' - 5 commits - sw/source writerfilter/source

Cédric Bosdonnat cbosdo at kemper.freedesktop.org
Mon Feb 13 05:59:11 PST 2012


 sw/source/core/frmedt/tblsel.cxx               |    2 -
 sw/source/core/inc/flowfrm.hxx                 |   28 ++++++------------
 sw/source/core/layout/flowfrm.cxx              |   37 ++++++++++++++++++++++---
 sw/source/core/layout/laycache.cxx             |    1 
 sw/source/core/layout/sectfrm.cxx              |   11 -------
 sw/source/core/layout/ssfrm.cxx                |    3 --
 sw/source/core/layout/tabfrm.cxx               |    1 
 sw/source/core/text/frmform.cxx                |    5 +--
 sw/source/core/text/xmldump.cxx                |   12 ++++----
 sw/source/filter/ww8/rtfattributeoutput.cxx    |   28 ++++++++++++++++--
 sw/source/filter/ww8/rtfattributeoutput.hxx    |    6 ++++
 writerfilter/source/rtftok/rtfdocumentimpl.cxx |   14 ++++++++-
 12 files changed, 96 insertions(+), 52 deletions(-)

New commits:
commit 47ce6dc0ecb4503d87564d08d3f86fb3e01c39ac
Author: Michael Stahl <mstahl at redhat.com>
Date:   Sun Feb 12 22:16:53 2012 +0100

    fdo#41712: sw: remove superfluous flag:
    
    This removes SwFlowFrm::bIsFollow, which is pointless duplication of
    m_pPrecede; this fixes lots of assertions (probably some real problem as
    well).
    
    Signed-off-by: Cédric Bosdonnat <cedric.bosdonnat.ooo at free.fr>

diff --git a/sw/source/core/frmedt/tblsel.cxx b/sw/source/core/frmedt/tblsel.cxx
index 1848a02..4d18a40 100644
--- a/sw/source/core/frmedt/tblsel.cxx
+++ b/sw/source/core/frmedt/tblsel.cxx
@@ -2208,7 +2208,7 @@ void _FndBox::SetTableLines( const SwTable &rTable )
 
 inline void UnsetFollow( SwFlowFrm *pTab )
 {
-    pTab->bIsFollow = sal_False;
+    pTab->m_pPrecede = 0;
 }
 
 void _FndBox::DelFrms( SwTable &rTable )
diff --git a/sw/source/core/inc/flowfrm.hxx b/sw/source/core/inc/flowfrm.hxx
index 99e12a1..d0aad08 100644
--- a/sw/source/core/inc/flowfrm.hxx
+++ b/sw/source/core/inc/flowfrm.hxx
@@ -117,7 +117,6 @@ protected:
     SwFlowFrm *m_pFollow;
     SwFlowFrm *m_pPrecede;
 
-    sal_Bool bIsFollow  :1; //Ist's ein Follow
     sal_Bool bLockJoin  :1; //Join (und damit deleten) verboten wenn sal_True!
     sal_Bool bUndersized:1; // wir sind kleiner als gewuenscht
     sal_Bool bFlyLock   :1; //  Stop positioning of at-character flyframes
@@ -163,8 +162,7 @@ public:
     void MoveSubTree( SwLayoutFrm* pParent, SwFrm* pSibling = 0 );
 
            sal_Bool       HasFollow() const    { return m_pFollow ? sal_True : sal_False; }
-           sal_Bool       IsFollow()     const { return bIsFollow; }
-    inline void       _SetIsFollow( sal_Bool bSet ) { bIsFollow = bSet; }
+           sal_Bool       IsFollow()     const { return 0 != m_pPrecede; }
     const  SwFlowFrm *GetFollow() const    { return m_pFollow;   }
            SwFlowFrm *GetFollow()          { return m_pFollow;   }
            sal_Bool       IsAnFollow( const SwFlowFrm *pFlow ) const;
diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx
index a7ef489..9b25c4b 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -81,7 +81,6 @@ SwFlowFrm::SwFlowFrm( SwFrm &rFrm ) :
     rThis( rFrm ),
     m_pFollow( 0 ),
     m_pPrecede( 0 ),
-    bIsFollow( false ),
     bLockJoin( false ),
     bUndersized( false ),
     bFlyLock( false )
diff --git a/sw/source/core/layout/laycache.cxx b/sw/source/core/layout/laycache.cxx
index b04de85..d5f041d 100644
--- a/sw/source/core/layout/laycache.cxx
+++ b/sw/source/core/layout/laycache.cxx
@@ -924,7 +924,6 @@ sal_Bool SwLayHelper::CheckInsert( sal_uLong nNodeIndex )
                         {
                             SwTxtFrm *pNew = new SwTxtFrm( ((SwTxtFrm*)rpFrm)->
                                                             GetTxtNode(), rpFrm );
-                            pNew->_SetIsFollow( sal_True );
                             pNew->ManipOfst( nOfst );
                             pNew->SetFollow( ((SwTxtFrm*)rpFrm)->GetFollow() );
                             ((SwTxtFrm*)rpFrm)->SetFollow( pNew );
diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx
index 4ff80e1..3f2ea28 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -102,15 +102,11 @@ SwSectionFrm::SwSectionFrm( SwSectionFrm &rSect, sal_Bool bMaster ) :
         {
             SwSectionFrm* pMaster = rSect.FindMaster();
             pMaster->SetFollow( this );
-            bIsFollow = sal_True;
         }
-        else
-            rSect.bIsFollow = sal_True;
         SetFollow( &rSect );
     }
     else
     {
-        bIsFollow = sal_True;
         SetFollow( rSect.GetFollow() );
         rSect.SetFollow( this );
         if( !GetFollow() )
@@ -171,7 +167,6 @@ SwSectionFrm::~SwSectionFrm()
         else if( HasFollow() )
         {
             PROTOCOL( this, PROT_SECTION, ACT_DEL_MASTER, GetFollow() )
-            GetFollow()->bIsFollow = sal_False;
         }
     }
 }
@@ -218,10 +213,7 @@ void SwSectionFrm::DelEmpty( sal_Bool bRemove )
         // freigeben, deshalb wird die Size des Masters invalidiert.
         if( !GetFollow() && !pMaster->IsColLocked() )
             pMaster->InvalidateSize();
-        bIsFollow = sal_False;
     }
-    else if( HasFollow() )
-        GetFollow()->bIsFollow = sal_False;
     SetFollow(0);
     if( pUp )
     {
@@ -504,7 +496,6 @@ void SwSectionFrm::MergeNext( SwSectionFrm* pNxt )
         }
         SetFollow( pNxt->GetFollow() );
         pNxt->SetFollow( NULL );
-        pNxt->bIsFollow = sal_False;
         pNxt->Cut();
         delete pNxt;
         InvalidateSize();
diff --git a/sw/source/core/layout/ssfrm.cxx b/sw/source/core/layout/ssfrm.cxx
index adc552d..d0515ef 100644
--- a/sw/source/core/layout/ssfrm.cxx
+++ b/sw/source/core/layout/ssfrm.cxx
@@ -518,13 +518,10 @@ void SwCntntFrm::DelFrms( const SwCntntNode& rNode )
                             dynamic_cast<SwTxtFrm*>(pFrm->FindPrevCnt( true )) );
             }
         }
-        if( pFrm->HasFollow() )
-            pFrm->GetFollow()->_SetIsFollow( pFrm->IsFollow() );
         if( pFrm->IsFollow() )
         {
             SwCntntFrm* pMaster = (SwTxtFrm*)pFrm->FindMaster();
             pMaster->SetFollow( pFrm->GetFollow() );
-            pFrm->_SetIsFollow( sal_False );
         }
         pFrm->SetFollow( 0 );//Damit er nicht auf dumme Gedanken kommt.
                                 //Andernfalls kann es sein, dass ein Follow
diff --git a/sw/source/core/layout/tabfrm.cxx b/sw/source/core/layout/tabfrm.cxx
index 44be6ba..983772b 100644
--- a/sw/source/core/layout/tabfrm.cxx
+++ b/sw/source/core/layout/tabfrm.cxx
@@ -121,7 +121,6 @@ SwTabFrm::SwTabFrm( SwTabFrm &rTab ) :
     SwFlowFrm( (SwFrm&)*this ),
     pTable( rTab.GetTable() )
 {
-    bIsFollow = sal_True;
     bComplete = bONECalcLowers = bCalcLowers = bLowersFormatted = bLockBackMove =
     bResizeHTMLTable = bHasFollowFlowLine = bIsRebuildLastLine =
     bRestrictTableGrowth = bRemoveFollowFlowLinePending = sal_False;
diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx
index 0731b10..e417e84 100755
--- a/sw/source/core/text/frmform.cxx
+++ b/sw/source/core/text/frmform.cxx
@@ -697,7 +697,6 @@ SwCntntFrm *SwTxtFrm::SplitFrm( const xub_StrLen nTxtPos )
     // Damit meine Daten nicht verschwinden, locke ich mich.
     SwTxtFrmLocker aLock( this );
     SwTxtFrm *pNew = (SwTxtFrm *)(GetTxtNode()->MakeFrm( this ));
-    pNew->bIsFollow = sal_True;
 
     pNew->SetFollow( GetFollow() );
     SetFollow( pNew );
commit 074a1a32507f663077ac3e3f4a2ac11649d9f5a3
Author: Michael Stahl <mstahl at redhat.com>
Date:   Sun Feb 12 22:11:37 2012 +0100

    fdo#41712: sw: fix crash in layout frame linked lists:
    
    The pPrecede member is not maintained properly when setting the
    corresponding pFollow member.
    The change in SwTxtFrm::JoinFrm() fixes the crash, the other changes
    are perhaps fixes for other crashes...
    (regression from cc3d0d182cafef9649e45f4657233ac2221fdd0a)
    
    Signed-off-by: Cédric Bosdonnat <cedric.bosdonnat.ooo at free.fr>

diff --git a/sw/source/core/inc/flowfrm.hxx b/sw/source/core/inc/flowfrm.hxx
index d0fe5af..99e12a1 100644
--- a/sw/source/core/inc/flowfrm.hxx
+++ b/sw/source/core/inc/flowfrm.hxx
@@ -145,6 +145,7 @@ protected:
 
 public:
     SwFlowFrm( SwFrm &rFrm );
+    virtual ~SwFlowFrm();
 
     const SwFrm *GetFrm() const            { return &rThis; }
           SwFrm *GetFrm()                  { return &rThis; }
diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx
index d3dceb6..a7ef489 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -87,12 +87,33 @@ SwFlowFrm::SwFlowFrm( SwFrm &rFrm ) :
     bFlyLock( false )
 {}
 
+SwFlowFrm::~SwFlowFrm()
+{
+    if (m_pFollow)
+    {
+        m_pFollow->m_pPrecede = 0;
+    }
+    if (m_pPrecede)
+    {
+        m_pPrecede->m_pFollow = 0;
+    }
+}
 
 void SwFlowFrm::SetFollow(SwFlowFrm *const pFollow)
 {
+    if (m_pFollow)
+    {
+        assert(this == m_pFollow->m_pPrecede);
+        m_pFollow->m_pPrecede = 0;
+    }
     m_pFollow = pFollow;
     if (m_pFollow != NULL)
     {
+        if (m_pFollow->m_pPrecede) // re-chaining pFollow?
+        {
+            assert(m_pFollow == m_pFollow->m_pPrecede->m_pFollow);
+            m_pFollow->m_pPrecede->m_pFollow = 0;
+        }
         m_pFollow->m_pPrecede = this;
     }
 }
diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx
index 581c123..4ff80e1 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -222,7 +222,7 @@ void SwSectionFrm::DelEmpty( sal_Bool bRemove )
     }
     else if( HasFollow() )
         GetFollow()->bIsFollow = sal_False;
-    m_pFollow = NULL;
+    SetFollow(0);
     if( pUp )
     {
         Frm().Height( 0 );
diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx
index 1b34187..0731b10 100755
--- a/sw/source/core/text/frmform.cxx
+++ b/sw/source/core/text/frmform.cxx
@@ -680,8 +680,8 @@ SwCntntFrm *SwTxtFrm::JoinFrm()
         }
     }
     pFoll->Cut();
+    SetFollow(pNxt);
     delete pFoll;
-    m_pFollow = pNxt;
     return pNxt;
 }
 
commit bfc931b6440aff6c8cf0c10b3be8fb390302d57a
Author: Michael Stahl <mstahl at redhat.com>
Date:   Sun Feb 12 22:02:55 2012 +0100

    fdo#41712: rename members to track down assignments
    
    Signed-off-by: Cédric Bosdonnat <cedric.bosdonnat.ooo at free.fr>

diff --git a/sw/source/core/inc/flowfrm.hxx b/sw/source/core/inc/flowfrm.hxx
index e1c47c2..d0fe5af 100644
--- a/sw/source/core/inc/flowfrm.hxx
+++ b/sw/source/core/inc/flowfrm.hxx
@@ -114,8 +114,8 @@ class SwFlowFrm
 
 protected:
 
-    SwFlowFrm *pFollow;
-    SwFlowFrm *pPrecede;
+    SwFlowFrm *m_pFollow;
+    SwFlowFrm *m_pPrecede;
 
     sal_Bool bIsFollow  :1; //Ist's ein Follow
     sal_Bool bLockJoin  :1; //Join (und damit deleten) verboten wenn sal_True!
@@ -161,16 +161,16 @@ public:
     //neuen Parent Moven.
     void MoveSubTree( SwLayoutFrm* pParent, SwFrm* pSibling = 0 );
 
-           sal_Bool       HasFollow() const    { return pFollow ? sal_True : sal_False; }
+           sal_Bool       HasFollow() const    { return m_pFollow ? sal_True : sal_False; }
            sal_Bool       IsFollow()     const { return bIsFollow; }
     inline void       _SetIsFollow( sal_Bool bSet ) { bIsFollow = bSet; }
-    const  SwFlowFrm *GetFollow() const    { return pFollow;   }
-           SwFlowFrm *GetFollow()          { return pFollow;   }
+    const  SwFlowFrm *GetFollow() const    { return m_pFollow;   }
+           SwFlowFrm *GetFollow()          { return m_pFollow;   }
            sal_Bool       IsAnFollow( const SwFlowFrm *pFlow ) const;
-    inline void       SetFollow( SwFlowFrm *pNew );
+           void       SetFollow(SwFlowFrm *const pFollow);
 
-    const  SwFlowFrm *GetPrecede() const   { return pPrecede;   }
-           SwFlowFrm *GetPrecede()         { return pPrecede;   }
+    const  SwFlowFrm *GetPrecede() const   { return m_pPrecede;   }
+           SwFlowFrm *GetPrecede()         { return m_pPrecede;   }
 
 
     sal_Bool IsJoinLocked() const { return bLockJoin; }
@@ -239,13 +239,6 @@ inline sal_Bool SwFlowFrm::IsFwdMoveAllowed()
     return rThis.GetIndPrev() != 0;
 }
 
-inline void SwFlowFrm::SetFollow( SwFlowFrm *pNew )
-{
-    pFollow = pNew;
-    if ( pFollow != NULL )
-        pFollow->pPrecede = this;
-}
-
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/flowfrm.cxx b/sw/source/core/layout/flowfrm.cxx
index 6cc1f02..d3dceb6 100644
--- a/sw/source/core/layout/flowfrm.cxx
+++ b/sw/source/core/layout/flowfrm.cxx
@@ -79,8 +79,8 @@ sal_Bool SwFlowFrm::bMoveBwdJump = sal_False;
 
 SwFlowFrm::SwFlowFrm( SwFrm &rFrm ) :
     rThis( rFrm ),
-    pFollow( 0 ),
-    pPrecede( 0 ),
+    m_pFollow( 0 ),
+    m_pPrecede( 0 ),
     bIsFollow( false ),
     bLockJoin( false ),
     bUndersized( false ),
@@ -88,6 +88,15 @@ SwFlowFrm::SwFlowFrm( SwFrm &rFrm ) :
 {}
 
 
+void SwFlowFrm::SetFollow(SwFlowFrm *const pFollow)
+{
+    m_pFollow = pFollow;
+    if (m_pFollow != NULL)
+    {
+        m_pFollow->m_pPrecede = this;
+    }
+}
+
 /*************************************************************************
 |*
 |*  SwFlowFrm::IsFollowLocked()
@@ -214,7 +223,7 @@ sal_Bool SwFlowFrm::IsKeep( const SwAttrSet& rAttrs, bool bCheckIfLastRowShouldK
         {
             SwFrm *pNxt;
             if( 0 != (pNxt = rThis.FindNextCnt()) &&
-                (!pFollow || pNxt != pFollow->GetFrm()))
+                (!m_pFollow || pNxt != m_pFollow->GetFrm()))
             {
                 // #135914#
                 // The last row of a table only keeps with the next content
diff --git a/sw/source/core/layout/sectfrm.cxx b/sw/source/core/layout/sectfrm.cxx
index 6a0e3d9..581c123 100644
--- a/sw/source/core/layout/sectfrm.cxx
+++ b/sw/source/core/layout/sectfrm.cxx
@@ -222,7 +222,7 @@ void SwSectionFrm::DelEmpty( sal_Bool bRemove )
     }
     else if( HasFollow() )
         GetFollow()->bIsFollow = sal_False;
-    pFollow = NULL;
+    m_pFollow = NULL;
     if( pUp )
     {
         Frm().Height( 0 );
diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx
index 1d7c15e..1b34187 100755
--- a/sw/source/core/text/frmform.cxx
+++ b/sw/source/core/text/frmform.cxx
@@ -681,7 +681,7 @@ SwCntntFrm *SwTxtFrm::JoinFrm()
     }
     pFoll->Cut();
     delete pFoll;
-    pFollow = pNxt;
+    m_pFollow = pNxt;
     return pNxt;
 }
 
@@ -2065,7 +2065,7 @@ sal_Bool SwTxtFrm::FormatQuick( bool bForceQuickFormat )
         return sal_False;
     }
 
-    if( pFollow && nStart != ((SwTxtFrm*)pFollow)->GetOfst() )
+    if (m_pFollow && nStart != (static_cast<SwTxtFrm*>(m_pFollow))->GetOfst())
         return sal_False; // kann z.B. durch Orphans auftreten (35083,35081)
 
     // Geschafft, wir sind durch ...
diff --git a/sw/source/core/text/xmldump.cxx b/sw/source/core/text/xmldump.cxx
index 83419bd..25e8347 100644
--- a/sw/source/core/text/xmldump.cxx
+++ b/sw/source/core/text/xmldump.cxx
@@ -366,8 +366,8 @@ void SwTxtFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer )
     if ( HasFollow() )
         xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%p", GetFollow() );
 
-    if ( pPrecede != NULL )
-        xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%p", (SwTxtFrm*)pPrecede );
+    if (m_pPrecede != NULL)
+        xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%p", (SwTxtFrm*)m_pPrecede );
 }
 
 void SwSectionFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer )
@@ -376,8 +376,8 @@ void SwSectionFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer )
     if ( HasFollow() )
         xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%p", GetFollow() );
 
-    if ( pPrecede != NULL )
-        xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%p", (SwSectionFrm*)pPrecede );
+    if (m_pPrecede != NULL)
+        xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%p", (SwSectionFrm*)m_pPrecede );
 }
 
 void SwTabFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer )
@@ -386,8 +386,8 @@ void SwTabFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer )
     if ( HasFollow() )
         xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%p", GetFollow() );
 
-    if ( pPrecede != NULL )
-        xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%p", (SwTabFrm*)pPrecede );
+    if (m_pPrecede != NULL)
+        xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%p", (SwTabFrm*)m_pPrecede );
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
commit 9e9a824674411282a5eacf7f5bb7b3c3e802772f
Author: Miklos Vajna <vmiklos at frugalware.org>
Date:   Thu Feb 2 09:21:25 2012 +0100

    n#703032 fix RTF import of page breaks right before text frames
    
    Signed-off-by: Cédric Bosdonnat <cedric.bosdonnat.ooo at free.fr>

diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index e87e880..f0aa513 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -411,12 +411,25 @@ void RTFDocumentImpl::checkNeedPap()
 {
     if (m_bNeedPap)
     {
+        m_bNeedPap = false; // reset early, so we can avoid recursion when calling ourselves
         if (!m_pCurrentBuffer)
         {
             writerfilter::Reference<Properties>::Pointer_t const pParagraphProperties(
                     new RTFReferenceProperties(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms)
                     );
+
+            // Writer will ignore a page break before a text frame, so guard it with empty paragraphs
+            bool hasBreakBeforeFrame = m_aStates.top().aFrame.hasProperties() &&
+                m_aStates.top().aParagraphSprms.find(NS_sprm::LN_PFPageBreakBefore).get();
+            if (hasBreakBeforeFrame)
+            {
+                dispatchSymbol(RTF_PAR);
+                m_bNeedPap = false;
+                m_aStates.top().aParagraphSprms.erase(NS_sprm::LN_PFPageBreakBefore);
+            }
             Mapper().props(pParagraphProperties);
+            if (hasBreakBeforeFrame)
+                dispatchSymbol(RTF_PAR);
 
             if (m_aStates.top().aFrame.hasProperties())
             {
@@ -430,7 +443,6 @@ void RTFDocumentImpl::checkNeedPap()
             RTFValue::Pointer_t pValue(new RTFValue(m_aStates.top().aParagraphAttributes, m_aStates.top().aParagraphSprms));
             m_pCurrentBuffer->push_back(make_pair(BUFFER_PROPS, pValue));
         }
-        m_bNeedPap = false;
     }
 }
 
commit e6fef2a97eaf0eba5384f2d99d5f0f3b03080951
Author: Miklos Vajna <vmiklos at frugalware.org>
Date:   Wed Feb 8 16:49:57 2012 +0100

    n#203704 fix RTF export table output for subtables
    
    Older ODT files containing <table:table table:is-sub-table="true">
    confused the RTF exporter. Add a few sanity checks to make sure the
    output is still valid.
    
    Signed-off-by: Cédric Bosdonnat <cedric.bosdonnat.ooo at free.fr>

diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
index b66f84f..e66d5be 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -250,13 +250,19 @@ void RtfAttributeOutput::StartParagraph( ww8::WW8TableNodeInfo::Pointer_t pTextN
         {
             ww8::WW8TableNodeInfoInner::Pointer_t pDeepInner( pTextNodeInfo->getInnerForDepth( m_nTableDepth ) );
             OSL_ENSURE( pDeepInner, "TableNodeInfoInner not found");
-            if ( pDeepInner && pDeepInner->getCell() == 0 )
+            // Make sure we always start a row between ending one and starting a cell.
+            // In case of subtables, we may not get the first cell.
+            if ((pDeepInner && pDeepInner->getCell() == 0) || m_bTableRowEnded)
+            {
+                m_bTableRowEnded = false;
                 StartTableRow( pDeepInner );
+            }
 
             StartTableCell( pDeepInner );
         }
 
-        if ( nRow == 0 && nCell == 0 )
+        // Again, if depth was incremented, start a new table even if we skipped the first cell.
+        if ((nRow == 0 && nCell == 0) || (m_nTableDepth == 0 && pTextNodeInfo->getDepth()))
         {
             // Do we have to start the table?
             // [If we are at the rigth depth already, it means that we
@@ -609,7 +615,10 @@ void RtfAttributeOutput::TableDefinition( ww8::WW8TableNodeInfoInner::Pointer_t
                         rLR.GetLeft() - rLR.GetRight();
     }
     SwTwips nTblSz = pFmt->GetFrmSize().GetWidth();
-    for( sal_uInt16 i = 0; i < pRow->GetCells().Count(); i++ )
+    // Not using m_nTableDepth, which is not yet incremented here.
+    sal_uInt32 nCurrentDepth = pTableTextNodeInfoInner->getDepth();
+    m_aCells[nCurrentDepth] = pRow->GetCells().Count();
+    for( sal_uInt16 i = 0; i < m_aCells[nCurrentDepth]; i++ )
     {
         SwWriteTableCell *pCell = pRow->GetCells( )[ i ];
         const SwFrmFmt *pCellFmt = pCell->GetBox()->GetFrmFmt();
@@ -907,6 +916,9 @@ void RtfAttributeOutput::StartTableRow( ww8::WW8TableNodeInfoInner::Pointer_t pT
     // We'll write the table definition for nested tables later
     if ( nCurrentDepth > 1 )
         return;
+    // Empty the previous row closing buffer before starting the new one,
+    // necessary for subtables.
+    m_rExport.Strm() << m_aAfterRuns.makeStringAndClear().getStr();
     m_rExport.Strm() << m_aRowDefs.makeStringAndClear().getStr();
     }
 }
@@ -945,12 +957,17 @@ void RtfAttributeOutput::EndTableCell( )
     m_bTableCellOpen = false;
     m_bTblAfterCell = true;
     m_bWroteCellInfo = false;
+    m_aCells[m_nTableDepth]--;
 }
 
 void RtfAttributeOutput::EndTableRow( )
 {
     OSL_TRACE("%s, (depth is %d)", OSL_THIS_FUNC, (int)m_nTableDepth);
 
+    // Trying to end the row without writing the required number of cells? Fill with empty ones.
+    for( sal_uInt16 i = 0; i < m_aCells[m_nTableDepth]; i++ )
+        m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_CELL);
+
     if ( m_nTableDepth > 1 )
     {
         m_aAfterRuns.append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_NESTTABLEPROPRS);
@@ -972,6 +989,7 @@ void RtfAttributeOutput::EndTableRow( )
         }
         m_aAfterRuns.append(OOO_STRING_SVTOOLS_RTF_ROW).append(OOO_STRING_SVTOOLS_RTF_PARD);
     }
+    m_bTableRowEnded = true;
 }
 
 void RtfAttributeOutput::EndTable()
@@ -3000,7 +3018,9 @@ RtfAttributeOutput::RtfAttributeOutput( RtfExport &rExport )
     m_bBufferSectionHeaders( false ),
     m_bLastTable( true ),
     m_bWroteCellInfo( false ),
-    m_bHadFieldResult( false )
+    m_bHadFieldResult( false ),
+    m_bTableRowEnded( false ),
+    m_aCells()
 {
     OSL_TRACE("%s", OSL_THIS_FUNC);
 }
diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx
index 8766c5a..eea4b8c 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.hxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.hxx
@@ -533,6 +533,12 @@ private:
      * If we had a field result in the URL.
      */
     bool m_bHadFieldResult;
+
+    /// If we ended a table row without starting a new one.
+    bool m_bTableRowEnded;
+
+    /// Number of cells from the table definition, by depth.
+    std::map<sal_uInt32,sal_uInt32> m_aCells;
 public:
     RtfAttributeOutput( RtfExport &rExport );
 


More information about the Libreoffice-commits mailing list