diff options
author | Caolán McNamara <caolanm@redhat.com> | 2012-05-05 10:25:52 +0100 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2012-05-05 10:27:47 +0100 |
commit | 567c1db25bd705faac44203e4a3d01d0f5e1385c (patch) | |
tree | 58a5f6246a8414e4f41eb2b94281409e8ac4353e /sw/source/core/frmedt/tblsel.cxx | |
parent | 4da69155054a661af5a405b3473affa2d44e6c90 (diff) |
Resolves: fdo#49342 crash merging cells, revert conversion to std::map
3af0c948254751eade9bff772b849720747c5494
868bd3b778b6c7b970c67d1dacc469967f69e551
b2e84f9a40fda7821d4e658f9102bcbc783a1ba3
7264d2767095150944ff1e6999c71be1dbdc6f83
858b5b4f36a357fe7192e7c2ed9cc3cdfc81fd8f
The problem is that a paragraph gets added to the document after the TableBox
selection is created, which changes the node ids of the following paragraphs in
the TableBox but the map has used cached SttNd value as its key, so it can't
recognize nodes using the new index.
This worked in the old implementation because that was effectively a
sorted-vector, so probably the best conversion to stl is a sorted vector
Change-Id: I1143d843b872eee15b016f82b68ecc020969f1b5
Diffstat (limited to 'sw/source/core/frmedt/tblsel.cxx')
-rw-r--r-- | sw/source/core/frmedt/tblsel.cxx | 101 |
1 files changed, 68 insertions, 33 deletions
diff --git a/sw/source/core/frmedt/tblsel.cxx b/sw/source/core/frmedt/tblsel.cxx index 9e5253e7b1d5..ade24da77b65 100644 --- a/sw/source/core/frmedt/tblsel.cxx +++ b/sw/source/core/frmedt/tblsel.cxx @@ -75,6 +75,41 @@ #undef DEL_EMPTY_BOXES_AT_START_AND_END #define DEL_ALL_EMPTY_BOXES +_SV_IMPL_SORTAR_ALG( SwSelBoxes, SwTableBoxPtr ) +sal_Bool SwSelBoxes::Seek_Entry( const SwTableBoxPtr rSrch, sal_uInt16* pFndPos ) const +{ + sal_uLong nIdx = rSrch->GetSttIdx(); + + sal_uInt16 nO = Count(), nM, nU = 0; + if( nO > 0 ) + { + nO--; + while( nU <= nO ) + { + nM = nU + ( nO - nU ) / 2; + if( (*this)[ nM ]->GetSttNd() == rSrch->GetSttNd() ) + { + if( pFndPos ) + *pFndPos = nM; + return sal_True; + } + else if( (*this)[ nM ]->GetSttIdx() < nIdx ) + nU = nM + 1; + else if( nM == 0 ) + { + if( pFndPos ) + *pFndPos = nU; + return sal_False; + } + else + nO = nM - 1; + } + } + if( pFndPos ) + *pFndPos = nU; + return sal_False; +} + struct _CmpLPt { Point aPos; @@ -137,29 +172,25 @@ const SwLayoutFrm *lcl_FindNextCellFrm( const SwLayoutFrm *pLay ) void GetTblSelCrs( const SwCrsrShell &rShell, SwSelBoxes& rBoxes ) { - rBoxes.clear(); - if( rShell.IsTableMode() && const_cast<SwCrsrShell&>(rShell).UpdateTblSelBoxes()) - { - const SwSelBoxes& rShellBoxes = rShell.GetTableCrsr()->GetBoxes(); - rBoxes.insert( rShellBoxes.begin(), rShellBoxes.end() ); - } + if( rBoxes.Count() ) + rBoxes.Remove( sal_uInt16(0), rBoxes.Count() ); + if( rShell.IsTableMode() && ((SwCrsrShell&)rShell).UpdateTblSelBoxes()) + rBoxes.Insert( &rShell.GetTableCrsr()->GetBoxes() ); } void GetTblSelCrs( const SwTableCursor& rTblCrsr, SwSelBoxes& rBoxes ) { - rBoxes.clear(); + if( rBoxes.Count() ) + rBoxes.Remove( sal_uInt16(0), rBoxes.Count() ); if( rTblCrsr.IsChgd() || !rTblCrsr.GetBoxesCount() ) { - SwTableCursor* pTCrsr = const_cast<SwTableCursor*>(&rTblCrsr); + SwTableCursor* pTCrsr = (SwTableCursor*)&rTblCrsr; pTCrsr->GetDoc()->GetCurrentLayout()->MakeTblCrsrs( *pTCrsr ); //swmod 080218 } if( rTblCrsr.GetBoxesCount() ) - { - const SwSelBoxes& rCursorBoxes = rTblCrsr.GetBoxes(); - rBoxes.insert( rCursorBoxes.begin(), rCursorBoxes.end() ); - } + rBoxes.Insert( &rTblCrsr.GetBoxes() ); } void GetTblSel( const SwCrsrShell& rShell, SwSelBoxes& rBoxes, @@ -233,7 +264,7 @@ void GetTblSel( const SwCursor& rCrsr, SwSelBoxes& rBoxes, // check for cell protection?? if( !bChkProtected || !pBox->GetFrmFmt()->GetProtect().IsCntntProtected() ) - rBoxes.insert( pBox ); + rBoxes.Insert( pBox ); } } } @@ -336,7 +367,7 @@ void GetTblSel( const SwLayoutFrm* pStart, const SwLayoutFrm* pEnd, // check for cell protection?? if( !bChkProtected || !pBox->GetFrmFmt()->GetProtect().IsCntntProtected() ) - rBoxes.insert( pBox ); + rBoxes.Insert( pBox ); if ( pCells ) { @@ -428,7 +459,8 @@ void GetTblSel( const SwLayoutFrm* pStart, const SwLayoutFrm* pEnd, break; } - rBoxes.clear(); + i = 0; + rBoxes.Remove( i, rBoxes.Count() ); --nLoopMax; } while( sal_True ); @@ -853,14 +885,14 @@ sal_Bool GetAutoSumSel( const SwCrsrShell& rShell, SwCellFrms& rBoxes ) sal_Bool HasProtectedCells( const SwSelBoxes& rBoxes ) { - for( SwSelBoxes::const_iterator it = rBoxes.begin(); it != rBoxes.end(); ++it ) - { - if( it->second->GetFrmFmt()->GetProtect().IsCntntProtected() ) + sal_Bool bRet = sal_False; + for( sal_uInt16 n = 0, nCnt = rBoxes.Count(); n < nCnt; ++n ) + if( rBoxes[ n ]->GetFrmFmt()->GetProtect().IsCntntProtected() ) { - return sal_True; + bRet = sal_True; + break; } - } - return sal_False; + return bRet; } @@ -927,7 +959,8 @@ sal_Bool IsEmptyBox( const SwTableBox& rBox, SwPaM& rPam ) void GetMergeSel( const SwPaM& rPam, SwSelBoxes& rBoxes, SwTableBox** ppMergeBox, SwUndoTblMerge* pUndo ) { - rBoxes.clear(); + if( rBoxes.Count() ) + rBoxes.Remove( sal_uInt16(0), rBoxes.Count() ); OSL_ENSURE( rPam.GetCntntNode() && rPam.GetCntntNode( sal_False ), "Tabselection not on Cnt." ); @@ -1007,7 +1040,7 @@ void GetMergeSel( const SwPaM& rPam, SwSelBoxes& rBoxes, pBox->GetFrmFmt()->SetFmtAttr( aNew ); // this box is selected pLastBox = pBox; - rBoxes.insert( pBox ); + rBoxes.Insert( pBox ); aPosArr.Insert( _CmpLPt( (pCell->Frm().*fnRect->fnGetPos)(), pBox, bVert ) ); @@ -1024,7 +1057,7 @@ void GetMergeSel( const SwPaM& rPam, SwSelBoxes& rBoxes, { // this box is selected pLastBox = pBox; - rBoxes.insert( pBox ); + rBoxes.Insert( pBox ); #if OSL_DEBUG_LEVEL > 1 Point aInsPoint( (pCell->Frm().*fnRect->fnGetPos)() ); #endif @@ -1075,7 +1108,7 @@ void GetMergeSel( const SwPaM& rPam, SwSelBoxes& rBoxes, // this box is selected pLastBox = pBox; - rBoxes.insert( pBox ); + rBoxes.Insert( pBox ); aPosArr.Insert( _CmpLPt( (pCell->Frm().*fnRect->fnGetPos)(), pBox, bVert ) ); @@ -1117,7 +1150,7 @@ void GetMergeSel( const SwPaM& rPam, SwSelBoxes& rBoxes, pBox->GetFrmFmt()->SetFmtAttr( aNew ); pLastBox = pBox; - rBoxes.insert( pBox ); + rBoxes.Insert( pBox ); aPosArr.Insert( _CmpLPt( Point( rUnion.Left(), pCell->Frm().Top()), pBox, bVert )); @@ -1141,7 +1174,7 @@ void GetMergeSel( const SwPaM& rPam, SwSelBoxes& rBoxes, } // no SSelection / no boxes found - if( 1 >= rBoxes.size() ) + if( 1 >= rBoxes.Count() ) return; // now search all horizontally adjacent boxes and connect @@ -1327,7 +1360,7 @@ void GetMergeSel( const SwPaM& rPam, SwSelBoxes& rBoxes, // first create new box { - SwTableBox* pTmpBox = rBoxes.begin()->second; + SwTableBox* pTmpBox = rBoxes[0]; SwTableLine* pInsLine = pTmpBox->GetUpper(); sal_uInt16 nInsPos = pInsLine->GetTabBoxes().C40_GETPOS( SwTableBox, pTmpBox ); @@ -1473,13 +1506,13 @@ sal_uInt16 CheckMergeSel( const SwPaM& rPam ) sal_uInt16 CheckMergeSel( const SwSelBoxes& rBoxes ) { sal_uInt16 eRet = TBLMERGE_NOSELECTION; - if( !rBoxes.empty() ) + if( rBoxes.Count() ) { eRet = TBLMERGE_OK; _FndBox aFndBox( 0, 0 ); _FndPara aPara( rBoxes, &aFndBox ); - const SwTableNode* pTblNd = aPara.rBoxes.begin()->second->GetSttNd()->FindTableNode(); + const SwTableNode* pTblNd = aPara.rBoxes[0]->GetSttNd()->FindTableNode(); ((SwTable&)pTblNd->GetTable()).GetTabLines().ForEach( &_FndLineCopyCol, &aPara ); if( !aFndBox.GetLines().empty() ) @@ -2082,7 +2115,9 @@ sal_Bool _FndBoxCopyCol( const SwTableBox*& rpBox, void* pPara ) } else { - if( 0 == pFndPara->rBoxes.count( rpBox ) ) + SwTableBoxPtr pSrch = (SwTableBoxPtr)rpBox; + sal_uInt16 nFndPos; + if( !pFndPara->rBoxes.Seek_Entry( pSrch, &nFndPos )) { delete pFndBox; return sal_True; @@ -2118,9 +2153,9 @@ void _FndBox::SetTableLines( const SwSelBoxes &rBoxes, const SwTable &rTable ) sal_uInt16 nStPos = USHRT_MAX; sal_uInt16 nEndPos= 0; - for ( SwSelBoxes::const_iterator it = rBoxes.begin(); it != rBoxes.end(); ++it ) + for ( sal_uInt16 i = 0; i < rBoxes.Count(); ++i ) { - SwTableLine *pLine = it->second->GetUpper(); + SwTableLine *pLine = rBoxes[i]->GetUpper(); while ( pLine->GetUpper() ) pLine = pLine->GetUpper()->GetUpper(); const sal_uInt16 nPos = rTable.GetTabLines().GetPos( |