[Libreoffice-commits] .: 3 commits - sw/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Mon Sep 24 04:52:56 PDT 2012


 sw/source/core/docnode/ndtbl.cxx    |  247 ++++++++++++++++--------------------
 sw/source/core/table/swnewtable.cxx |   34 +++-
 2 files changed, 137 insertions(+), 144 deletions(-)

New commits:
commit 5e21ad82ef769b944927b498a196ec82476e17e8
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Sep 24 13:44:50 2012 +0200

    de-duplicate SwNodes::TextToTable()
    
    Change-Id: I8a61b67cb5bd1333c05f9a98c7af6e3ed05c8fd0

diff --git a/sw/source/core/docnode/ndtbl.cxx b/sw/source/core/docnode/ndtbl.cxx
index 22e44f5..cc7e88f 100644
--- a/sw/source/core/docnode/ndtbl.cxx
+++ b/sw/source/core/docnode/ndtbl.cxx
@@ -889,6 +889,112 @@ const SwTable* SwDoc::TextToTable( const SwInsertTableOptions& rInsTblOpts,
     return pNdTbl;
 }
 
+static void lcl_RemoveBreaks(SwCntntNode & rNode, SwTableFmt *const pTableFmt)
+{
+    // delete old layout frames, new ones need to be created...
+    rNode.DelFrms();
+
+    if (!rNode.IsTxtNode())
+    {
+        return;
+    }
+
+    SwTxtNode & rTxtNode = static_cast<SwTxtNode&>(rNode);
+    // remove PageBreaks/PageDesc/ColBreak
+    SfxItemSet const* pSet = rTxtNode.GetpSwAttrSet();
+    if (pSet)
+    {
+        const SfxPoolItem* pItem;
+        if (SFX_ITEM_SET == pSet->GetItemState(RES_BREAK, false, &pItem))
+        {
+            if (pTableFmt)
+            {
+                pTableFmt->SetFmtAttr(*pItem);
+            }
+            rTxtNode.ResetAttr(RES_BREAK);
+            pSet = rTxtNode.GetpSwAttrSet();
+        }
+
+        if (pSet
+            && (SFX_ITEM_SET == pSet->GetItemState(RES_PAGEDESC, false, &pItem))
+            && static_cast<SwFmtPageDesc const*>(pItem)->GetPageDesc())
+        {
+            if (pTableFmt)
+            {
+                pTableFmt->SetFmtAttr(*pItem);
+            }
+            rTxtNode.ResetAttr(RES_PAGEDESC);
+        }
+    }
+}
+
+static void
+lcl_BalanceTable(SwTable & rTable, size_t const nMaxBoxes,
+    SwTableNode & rTblNd, SwTableBoxFmt & rBoxFmt, SwTxtFmtColl & rTxtColl,
+    SwUndoTxtToTbl *const pUndo, std::vector<sal_uInt16> *const pPositions)
+{
+    // balance lines in table, insert empty boxes so all lines have the size
+    for (size_t n = 0; n < rTable.GetTabLines().size(); ++n)
+    {
+        SwTableLine *const pCurrLine = rTable.GetTabLines()[ n ];
+        size_t const nBoxes = pCurrLine->GetTabBoxes().size();
+        if (nMaxBoxes != nBoxes)
+        {
+            rTblNd.GetNodes().InsBoxen(&rTblNd, pCurrLine, &rBoxFmt, &rTxtColl,
+                    0, nBoxes, nMaxBoxes - nBoxes);
+
+            if (pUndo)
+            {
+                for (size_t i = nBoxes; i < nMaxBoxes; ++i)
+                {
+                    pUndo->AddFillBox( *pCurrLine->GetTabBoxes()[i] );
+                }
+            }
+
+            // if the first line is missing boxes, the width array is useless!
+            if (!n && pPositions)
+            {
+                pPositions->clear();
+            }
+        }
+    }
+}
+
+static void
+lcl_SetTableBoxWidths(SwTable & rTable, size_t const nMaxBoxes,
+        SwTableBoxFmt & rBoxFmt, SwDoc & rDoc,
+        std::vector<sal_uInt16> *const pPositions)
+{
+    if (pPositions && !pPositions->empty())
+    {
+        SwTableLines& rLns = rTable.GetTabLines();
+        sal_uInt16 nLastPos = 0;
+        for (size_t n = 0; n < pPositions->size(); ++n)
+        {
+            SwTableBoxFmt *pNewFmt = rDoc.MakeTableBoxFmt();
+            pNewFmt->SetFmtAttr(
+                    SwFmtFrmSize(ATT_VAR_SIZE, (*pPositions)[n] - nLastPos));
+            for (size_t nTmpLine = 0; nTmpLine < rLns.size(); ++nTmpLine)
+            {
+                //JP 24.06.98: have to do an Add here, because the BoxFormat is
+                //             still needed by the caller
+                pNewFmt->Add( rLns[ nTmpLine ]->GetTabBoxes()[ n ] );
+            }
+
+            nLastPos = (*pPositions)[ n ];
+        }
+
+        // propagate size upwards from format, so the table gets the right size
+        SAL_WARN_IF(rBoxFmt.GetDepends(), "sw.core",
+                "who is still registered in the format?");
+        rBoxFmt.SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nLastPos ));
+    }
+    else
+    {
+        rBoxFmt.SetFmtAttr(SwFmtFrmSize(ATT_VAR_SIZE, USHRT_MAX / nMaxBoxes));
+    }
+}
+
 SwTableNode* SwNodes::TextToTable( const SwNodeRange& rRange, sal_Unicode cCh,
                                     SwTableFmt* pTblFmt,
                                     SwTableLineFmt* pLineFmt,
@@ -945,31 +1051,7 @@ SwTableNode* SwNodes::TextToTable( const SwNodeRange& rRange, sal_Unicode cCh,
             }
         }
 
-        // die alten Frames loeschen, es werden neue erzeugt
-        pTxtNd->DelFrms();
-
-        // PageBreaks/PageDesc/ColBreak rausschmeissen.
-        const SfxItemSet* pSet = pTxtNd->GetpSwAttrSet();
-        if( pSet )
-        {
-            const SfxPoolItem* pItem;
-            if( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, sal_False, &pItem ) )
-            {
-                if( !nLines )
-                    pTblFmt->SetFmtAttr( *pItem );
-                pTxtNd->ResetAttr( RES_BREAK );
-                pSet = pTxtNd->GetpSwAttrSet();
-            }
-
-            if( pSet && SFX_ITEM_SET == pSet->GetItemState(
-                RES_PAGEDESC, sal_False, &pItem ) &&
-                ((SwFmtPageDesc*)pItem)->GetPageDesc() )
-            {
-                if( !nLines )
-                    pTblFmt->SetFmtAttr( *pItem );
-                pTxtNd->ResetAttr( RES_PAGEDESC );
-            }
-        }
+        lcl_RemoveBreaks(*pTxtNd, (0 == nLines) ? pTblFmt : 0);
 
         // setze den bei allen TextNode in der Tabelle den TableNode
         // als StartNode
@@ -1032,54 +1114,10 @@ SwTableNode* SwNodes::TextToTable( const SwNodeRange& rRange, sal_Unicode cCh,
             nMaxBoxes = nBoxes;
     }
 
-    // die Tabelle ausgleichen, leere Sections einfuegen
-    sal_uInt16 n;
-
-    for( n = 0; n < pTable->GetTabLines().size(); ++n )
-    {
-        SwTableLine* pCurrLine = pTable->GetTabLines()[ n ];
-        if( nMaxBoxes != ( nBoxes = pCurrLine->GetTabBoxes().size() ))
-        {
-            InsBoxen( pTblNd, pCurrLine, pBoxFmt, pTxtColl, 0,
-                        nBoxes, nMaxBoxes - nBoxes );
-
-            if( pUndo )
-                for( sal_uInt16 i = nBoxes; i < nMaxBoxes; ++i )
-                    pUndo->AddFillBox( *pCurrLine->GetTabBoxes()[ i ] );
-
-            // fehlen der 1. Line Boxen, dann kann man das Breiten Array
-            // vergessen!
-            if( !n )
-                aPosArr.clear();
-        }
-    }
-
-    if( !aPosArr.empty() )
-    {
-        SwTableLines& rLns = pTable->GetTabLines();
-        sal_uInt16 nLastPos = 0;
-        for( n = 0; n < aPosArr.size(); ++n )
-        {
-            SwTableBoxFmt *pNewFmt = pDoc->MakeTableBoxFmt();
-            pNewFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE,
-                                                aPosArr[ n ] - nLastPos ));
-            for( sal_uInt16 nTmpLine = 0; nTmpLine < rLns.size(); ++nTmpLine )
-                //JP 24.06.98: hier muss ein Add erfolgen, da das BoxFormat
-                //              von der rufenden Methode noch gebraucht wird!
-                pNewFmt->Add( rLns[ nTmpLine ]->GetTabBoxes()[ n ] );
-
-            nLastPos = aPosArr[ n ];
-        }
+    lcl_BalanceTable(*pTable, nMaxBoxes, *pTblNd, *pBoxFmt, *pTxtColl,
+            pUndo, &aPosArr);
+    lcl_SetTableBoxWidths(*pTable, nMaxBoxes, *pBoxFmt, *pDoc, &aPosArr);
 
-        // damit die Tabelle die richtige Groesse bekommt, im BoxFormat die
-        // Groesse nach "oben" transportieren.
-        OSL_ENSURE( !pBoxFmt->GetDepends(), "wer ist in dem Format noch angemeldet" );
-        pBoxFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nLastPos ));
-    }
-    else
-        pBoxFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, USHRT_MAX / nMaxBoxes ));
-
-    // das wars doch wohl ??
     return pTblNd;
 }
 
@@ -1295,7 +1333,6 @@ SwTableNode* SwNodes::TextToTable( const SwNodes::TableRanges_t & rTableNodes,
 #endif
 
     SwDoc* pDoc = GetDoc();
-    std::vector<sal_uInt16> aPosArr;
     SwTable * pTable = &pTblNd->GetTable();
     SwTableLine* pLine;
     SwTableBox* pBox;
@@ -1308,36 +1345,8 @@ SwTableNode* SwNodes::TextToTable( const SwNodes::TableRanges_t & rTableNodes,
         SwNode& rNode = aNodeIndex.GetNode();
         if( rNode.IsCntntNode() )
         {
-            static_cast<SwCntntNode&>(rNode).DelFrms();
-            if(rNode.IsTxtNode())
-            {
-                SwTxtNode& rTxtNode = static_cast<SwTxtNode&>(rNode);
-                // setze den bei allen TextNode in der Tabelle den TableNode
-                // als StartNode
-
-                // remove PageBreaks/PageDesc/ColBreak
-                const SwAttrSet* pSet = rTxtNode.GetpSwAttrSet();
-                if( pSet )
-                {
-                    const SfxPoolItem* pItem;
-                    if( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, sal_False, &pItem ) )
-                    {
-                        if( !nLines )
-                            pTblFmt->SetFmtAttr( *pItem );
-                        rTxtNode.ResetAttr( RES_BREAK );
-                        pSet = rTxtNode.GetpSwAttrSet();
-                    }
-
-                    if( pSet && SFX_ITEM_SET == pSet->GetItemState(
-                        RES_PAGEDESC, sal_False, &pItem ) &&
-                        ((SwFmtPageDesc*)pItem)->GetPageDesc() )
-                    {
-                        if( !nLines )
-                            pTblFmt->SetFmtAttr( *pItem );
-                        rTxtNode.ResetAttr( RES_PAGEDESC );
-                    }
-                }
-            }
+            lcl_RemoveBreaks(static_cast<SwCntntNode&>(rNode),
+                    (0 == nLines) ? pTblFmt : 0);
         }
     }
 
@@ -1383,49 +1392,11 @@ SwTableNode* SwNodes::TextToTable( const SwNodes::TableRanges_t & rTableNodes,
             nMaxBoxes = nBoxes;
     }
 
-    // die Tabelle ausgleichen, leere Sections einfuegen
-    sal_uInt16 n;
-
-    for (n = 0; n < pTable->GetTabLines().size(); ++n )
-    {
-        // rhbz#820283: balance the cells in table rows
-        SwTableLine *const pCurrLine = pTable->GetTabLines()[ n ];
-        nBoxes = pCurrLine->GetTabBoxes().size();
-        SwTxtFmtColl *const pTxtColl(const_cast<SwTxtFmtColl*>(
-                GetDoc()->GetDfltTxtFmtColl()));
-        if (nMaxBoxes != nBoxes)
-        {
-            InsBoxen( pTblNd, pCurrLine, pBoxFmt, pTxtColl, 0,
-                        nBoxes, nMaxBoxes - nBoxes );
-        }
-    }
-
-    if( !aPosArr.empty() )
-    {
-        SwTableLines& rLns = pTable->GetTabLines();
-        sal_uInt16 nLastPos = 0;
-        for( n = 0; n < aPosArr.size(); ++n )
-        {
-            SwTableBoxFmt *pNewFmt = pDoc->MakeTableBoxFmt();
-            pNewFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE,
-                                                aPosArr[ n ] - nLastPos ));
-            for( sal_uInt16 nLines2 = 0; nLines2 < rLns.size(); ++nLines2 )
-                //JP 24.06.98: hier muss ein Add erfolgen, da das BoxFormat
-                //              von der rufenden Methode noch gebraucht wird!
-                pNewFmt->Add( rLns[ nLines2 ]->GetTabBoxes()[ n ] );
-
-            nLastPos = aPosArr[ n ];
-        }
-
-        // damit die Tabelle die richtige Groesse bekommt, im BoxFormat die
-        // Groesse nach "oben" transportieren.
-        OSL_ENSURE( !pBoxFmt->GetDepends(), "wer ist in dem Format noch angemeldet" );
-        pBoxFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nLastPos ));
-    }
-    else
-        pBoxFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, USHRT_MAX / nMaxBoxes ));
+    SwTxtFmtColl *const pTxtColl(const_cast<SwTxtFmtColl*>(
+            GetDoc()->GetDfltTxtFmtColl()));
+    lcl_BalanceTable(*pTable, nMaxBoxes, *pTblNd, *pBoxFmt, *pTxtColl, 0, 0);
+    lcl_SetTableBoxWidths(*pTable, nMaxBoxes, *pBoxFmt, *pDoc, 0);
 
-    // das wars doch wohl ??
     return pTblNd;
 }
 
commit 6d2e09db4a677068095b0bebd08fbbb96620d60c
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Sep 24 11:21:11 2012 +0200

    rhbz#820283: fix crashes in DOCX table import:
    
    It is apparently possible that writerfilter creates a table with
    irregular structure, where the lines have varying numbers of boxes in
    them.  This may cause crashes on later editing operations, e.g.
    when SwTable::NewInsertCol() is unable to find boxes covering a
    particular column.  To prevent this, add missing boxes in
    SwNodes::TextToTable().
    
    Change-Id: I423821645baeaf55595e4933e1ab8fb89b2099f3

diff --git a/sw/source/core/docnode/ndtbl.cxx b/sw/source/core/docnode/ndtbl.cxx
index a39e015..22e44f5 100644
--- a/sw/source/core/docnode/ndtbl.cxx
+++ b/sw/source/core/docnode/ndtbl.cxx
@@ -1386,6 +1386,20 @@ SwTableNode* SwNodes::TextToTable( const SwNodes::TableRanges_t & rTableNodes,
     // die Tabelle ausgleichen, leere Sections einfuegen
     sal_uInt16 n;
 
+    for (n = 0; n < pTable->GetTabLines().size(); ++n )
+    {
+        // rhbz#820283: balance the cells in table rows
+        SwTableLine *const pCurrLine = pTable->GetTabLines()[ n ];
+        nBoxes = pCurrLine->GetTabBoxes().size();
+        SwTxtFmtColl *const pTxtColl(const_cast<SwTxtFmtColl*>(
+                GetDoc()->GetDfltTxtFmtColl()));
+        if (nMaxBoxes != nBoxes)
+        {
+            InsBoxen( pTblNd, pCurrLine, pBoxFmt, pTxtColl, 0,
+                        nBoxes, nMaxBoxes - nBoxes );
+        }
+    }
+
     if( !aPosArr.empty() )
     {
         SwTableLines& rLns = pTable->GetTabLines();
commit 53c91152ea52d053fa85df9868b29524739ab0b7
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Sep 24 11:19:45 2012 +0200

    tweak assertions in SwTable::CheckConsistency()
    
    Change-Id: Ib06543b7e59694f240b2b5fadcd6b464ce9e5792

diff --git a/sw/source/core/table/swnewtable.cxx b/sw/source/core/table/swnewtable.cxx
index 6ba86f5..12f60e3 100644
--- a/sw/source/core/table/swnewtable.cxx
+++ b/sw/source/core/table/swnewtable.cxx
@@ -700,7 +700,7 @@ sal_Bool SwTable::NewInsertCol( SwDoc* pDoc, const SwSelBoxes& rBoxes,
     {
         SwTableLine* pLine = aLines[ i ];
         sal_uInt16 nInsPos = aInsPos[i];
-        OSL_ENSURE( nInsPos != USHRT_MAX, "Didn't found insert position" );
+        assert(nInsPos != USHRT_MAX); // didn't find insert position
         SwTableBox* pBox = pLine->GetTabBoxes()[ nInsPos ];
         if( bBehind )
             ++nInsPos;
@@ -2114,22 +2114,24 @@ void SwTable::CheckConsistency() const
     {
         SwTwips nWidth = 0;
         SwTableLine* pLine = GetTabLines()[nCurrLine];
-        SAL_WARN_IF( !pLine, "sw", "Missing Table Line" );
+        SAL_WARN_IF( !pLine, "sw.core", "Missing Table Line" );
         sal_uInt16 nColCount = pLine->GetTabBoxes().size();
-        SAL_WARN_IF( !nColCount, "sw", "Empty Table Line" );
+        SAL_WARN_IF( !nColCount, "sw.core", "Empty Table Line" );
         for( sal_uInt16 nCurrCol = 0; nCurrCol < nColCount; ++nCurrCol )
         {
             SwTableBox* pBox = pLine->GetTabBoxes()[nCurrCol];
-            SAL_WARN_IF( !pBox, "sw", "Missing Table Box" );
+            SAL_WARN_IF( !pBox, "sw.core", "Missing Table Box" );
             SwTwips nNewWidth = pBox->GetFrmFmt()->GetFrmSize().GetWidth() + nWidth;
             long nRowSp = pBox->getRowSpan();
             if( nRowSp < 0 )
             {
-                SAL_WARN_IF( aIter == aRowSpanCells.end(), "sw", "Missing master box" );
+                SAL_WARN_IF( aIter == aRowSpanCells.end(),
+                        "sw.core", "Missing master box");
                 SAL_WARN_IF( aIter->nLeft != nWidth || aIter->nRight != nNewWidth,
-                    "sw", "Wrong position/size of overlapped table box" );
+                    "sw.core", "Wrong position/size of overlapped table box");
                 --(aIter->nRowSpan);
-                SAL_WARN_IF( aIter->nRowSpan != -nRowSp, "sw", "Wrong row span value" );
+                SAL_WARN_IF( aIter->nRowSpan != -nRowSp, "sw.core",
+                        "Wrong row span value" );
                 if( nRowSp == -1 )
                 {
                     std::list< RowSpanCheck >::iterator aEraseIter = aIter;
@@ -2141,7 +2143,7 @@ void SwTable::CheckConsistency() const
             }
             else if( nRowSp != 1 )
             {
-                SAL_WARN_IF( !nRowSp, "sw", "Zero row span?!" );
+                SAL_WARN_IF( !nRowSp, "sw.core", "Zero row span?!" );
                 RowSpanCheck aEntry;
                 aEntry.nLeft = nWidth;
                 aEntry.nRight = nNewWidth;
@@ -2152,14 +2154,20 @@ void SwTable::CheckConsistency() const
         }
         if( !nCurrLine )
             nLineWidth = nWidth;
-        SAL_WARN_IF( nWidth != nLineWidth, "sw", "Different Line Widths" );
-        SAL_WARN_IF( nWidth != nTabSize, "sw", "Line's Boxes are too small or too large" );
-        SAL_WARN_IF( nWidth < 0 || nWidth > USHRT_MAX, "sw", "Width out of range" );
-        SAL_WARN_IF( aIter != aRowSpanCells.end(), "sw", "Missing overlapped box" );
+        SAL_WARN_IF( nWidth != nLineWidth, "sw.core",
+                "Different Line Widths: first: " << nLineWidth
+                << " current [" << nCurrLine << "]: " <<  nWidth);
+        SAL_WARN_IF( abs(nWidth - nTabSize) > 1 /* how tolerant? */, "sw.core",
+                "Line width differs from table width: " << nTabSize
+                << " current [" << nCurrLine << "]: " << nWidth);
+        SAL_WARN_IF( nWidth < 0 || nWidth > USHRT_MAX, "sw.core",
+                "Width out of range [" << nCurrLine << "]: " << nWidth);
+        SAL_WARN_IF( aIter != aRowSpanCells.end(), "sw.core",
+                "Missing overlapped box" );
         aIter = aRowSpanCells.begin();
     }
     bool bEmpty = aRowSpanCells.empty();
-    SAL_WARN_IF( !bEmpty, "sw", "Open row span detected" );
+    SAL_WARN_IF( !bEmpty, "sw.core", "Open row span detected" );
 }
 
 #endif


More information about the Libreoffice-commits mailing list