summaryrefslogtreecommitdiff
path: root/sw/source/core/frmedt/tblsel.cxx
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2012-05-05 10:25:52 +0100
committerCaolán McNamara <caolanm@redhat.com>2012-05-05 10:27:47 +0100
commit567c1db25bd705faac44203e4a3d01d0f5e1385c (patch)
tree58a5f6246a8414e4f41eb2b94281409e8ac4353e /sw/source/core/frmedt/tblsel.cxx
parent4da69155054a661af5a405b3473affa2d44e6c90 (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.cxx101
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(