[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