merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / bastyp / index.cxx
blob84302c65c4f08b1f20f747d351c4310ea6a56b87
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: index.cxx,v $
10 * $Revision: 1.11 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <stdlib.h> // fuer qsort
36 #include <tools/solar.h>
38 #include "errhdl.hxx" // fuers ASSERT
39 #include "index.hxx"
40 #include "error.h" // fuers ASSERT
42 #ifndef PRODUCT
43 int SwIndex::nSerial = 0;
44 #endif
47 TYPEINIT0(SwIndexReg); // rtti
50 #ifdef CHK
52 #define IDX_CHK_ARRAY pArray->ChhkArr();
53 #define ARR_CHK_ARRAY ChhkArr();
56 void SwIndexReg::ChkArr()
58 ASSERT( (pFirst && pLast) || (!pFirst && !pLast),
59 "Array falsch Indiziert" );
61 if( !pFirst )
62 return;
64 xub_StrLen nVal = 0;
65 const SwIndex* pIdx = pFirst, *pPrev = 0;
66 ASSERT( !pIdx->pPrev, "Array-pFirst nicht am Anfang" );
68 while( pIdx != pLast )
70 ASSERT( pIdx->pPrev != pIdx && pIdx->pNext != pIdx,
71 "Index zeigt auf sich selbst" )
73 ASSERT( pIdx->nIndex >= nVal, "Reihenfolge stimmt nicht" );
74 ASSERT( pPrev == pIdx->pPrev, "Verkettung stimmt nicht" );
75 pPrev = pIdx;
76 pIdx = pIdx->pNext;
77 nVal = pPrev->nIndex;
81 #else // CHK
83 #define IDX_CHK_ARRAY
84 #define ARR_CHK_ARRAY
86 #endif // CHK
90 SwIndex::SwIndex( SwIndexReg* pArr, xub_StrLen nIdx )
91 : nIndex( nIdx ), pArray( pArr ), pNext( 0 ), pPrev( 0 )
93 if( !pArray )
95 pArray = SwIndexReg::pEmptyIndexArray;
96 nIndex = 0; // steht immer auf 0 !!!
99 if( !pArray->pFirst ) // 1. Index ??
100 pArray->pFirst = pArray->pLast = this;
101 else if( nIdx > ((pArray->pLast->nIndex - pArray->pFirst->nIndex) / 2) )
102 ChgValue( *pArray->pLast, nIdx );
103 else
104 ChgValue( *pArray->pFirst, nIdx );
106 #ifndef PRODUCT
107 MySerial = ++nSerial; // nur in der nicht PRODUCT-Version
108 #endif
109 IDX_CHK_ARRAY
113 SwIndex::SwIndex( const SwIndex& rIdx, short nIdx )
114 : pArray( rIdx.pArray ), pNext( 0 ), pPrev( 0 )
116 ChgValue( rIdx, rIdx.nIndex + nIdx );
118 #ifndef PRODUCT
119 MySerial = ++nSerial; // nur in der nicht PRODUCT-Version
120 #endif
121 IDX_CHK_ARRAY
125 SwIndex::SwIndex( const SwIndex& rIdx )
126 : nIndex( rIdx.nIndex ), pArray( rIdx.pArray ), pNext( 0 ), pPrev( 0 )
128 ChgValue( rIdx, rIdx.nIndex );
129 #ifndef PRODUCT
130 MySerial = ++nSerial; // nur in der nicht PRODUCT-Version
131 #endif
132 IDX_CHK_ARRAY
136 SwIndex& SwIndex::ChgValue( const SwIndex& rIdx, xub_StrLen nNewValue )
138 SwIndex* pFnd = (SwIndex*)&rIdx;
139 if( rIdx.nIndex > nNewValue ) // nach vorne versuchen
141 SwIndex* pPrv;
142 while( 0 != ( pPrv = pFnd->pPrev ) && pPrv->nIndex > nNewValue )
143 pFnd = pPrv;
145 if( pFnd != this )
147 // an alter Position ausketten
148 // erstmal an alter Position ausketten
149 if( pPrev )
150 pPrev->pNext = pNext;
151 else if( pArray->pFirst == this )
152 pArray->pFirst = pNext;
154 if( pNext )
155 pNext->pPrev = pPrev;
156 else if( pArray->pLast == this )
157 pArray->pLast = pPrev;
159 pNext = pFnd;
160 pPrev = pFnd->pPrev;
161 if( pPrev )
162 pPrev->pNext = this;
163 else
164 pArray->pFirst = this;
165 pFnd->pPrev = this;
168 else if( rIdx.nIndex < nNewValue )
170 SwIndex* pNxt;
171 while( 0 != ( pNxt = pFnd->pNext ) && pNxt->nIndex < nNewValue )
172 pFnd = pNxt;
174 if( pFnd != this )
176 // erstmal an alter Position ausketten
177 if( pPrev )
178 pPrev->pNext = pNext;
179 else if( pArray->pFirst == this )
180 pArray->pFirst = pNext;
182 if( pNext )
183 pNext->pPrev = pPrev;
184 else if( pArray->pLast == this )
185 pArray->pLast = pPrev;
187 pPrev = pFnd;
188 pNext = pFnd->pNext;
189 if( pNext )
190 pNext->pPrev = this;
191 else
192 pArray->pLast = this;
193 pFnd->pNext = this;
196 else if( pFnd != this )
198 // erstmal an alter Position ausketten
199 if( pPrev )
200 pPrev->pNext = pNext;
201 else if( pArray->pFirst == this )
202 pArray->pFirst = pNext;
204 if( pNext )
205 pNext->pPrev = pPrev;
206 else if( pArray->pLast == this )
207 pArray->pLast = pPrev;
209 pPrev = (SwIndex*)&rIdx;
210 pNext = rIdx.pNext;
211 pPrev->pNext = this;
213 if( !pNext ) // im IndexArray als letzes
214 pArray->pLast = this;
215 else
216 pNext->pPrev = this;
218 pArray = rIdx.pArray;
220 if( pArray->pFirst == pNext )
221 pArray->pFirst = this;
222 if( pArray->pLast == pPrev )
223 pArray->pLast = this;
225 nIndex = nNewValue;
227 IDX_CHK_ARRAY
229 return *this; }
232 void SwIndex::Remove()
234 if( !pPrev )
235 pArray->pFirst = pNext;
236 else
237 pPrev->pNext = pNext;
239 if( !pNext )
240 pArray->pLast = pPrev;
241 else
242 pNext->pPrev = pPrev;
244 IDX_CHK_ARRAY
247 /*************************************************************************
249 |* SwIndex & SwIndex::operator=( const SwIndex & aSwIndex )
251 |* Beschreibung
252 |* Ersterstellung JP 07.11.90
253 |* Letzte Aenderung JP 07.03.94
255 *************************************************************************/
258 SwIndex& SwIndex::operator=( const SwIndex& rIdx )
260 int bEqual;
261 if( rIdx.pArray != pArray ) // im alten abmelden !!
263 Remove();
264 pArray = rIdx.pArray;
265 pNext = pPrev = 0;
266 bEqual = FALSE;
268 else
269 bEqual = rIdx.nIndex == nIndex;
271 if( !bEqual )
272 ChgValue( rIdx, rIdx.nIndex );
273 return *this;
276 /*************************************************************************
278 |* SwIndex &SwIndex::Assign
280 |* Beschreibung
281 |* Ersterstellung VB 25.03.91
282 |* Letzte Aenderung JP 07.03.94
284 *************************************************************************/
287 SwIndex& SwIndex::Assign( SwIndexReg* pArr, xub_StrLen nIdx )
289 if( !pArr )
291 pArr = SwIndexReg::pEmptyIndexArray;
292 nIdx = 0; // steht immer auf 0 !!!
295 if( pArr != pArray ) // im alten abmelden !!
297 Remove();
298 pArray = pArr;
299 pNext = pPrev = 0;
300 if( !pArr->pFirst ) // 1. Index ??
302 pArr->pFirst = pArr->pLast = this;
303 nIndex = nIdx;
305 else if( pArr->pLast && (nIdx > ((pArr->pLast->nIndex - pArr->pFirst->nIndex) / 2)) )
306 ChgValue( *pArr->pLast, nIdx );
307 else
308 ChgValue( *pArr->pFirst, nIdx );
310 else if( nIndex != nIdx )
311 ChgValue( *this, nIdx );
312 IDX_CHK_ARRAY
313 return *this;
317 SwIndexReg::SwIndexReg()
318 : pFirst( 0 ), pLast( 0 )
324 SwIndexReg::~SwIndexReg()
326 ASSERT( !pFirst || !pLast, "Es sind noch Indizies angemeldet" );
331 void SwIndexReg::Update( SwIndex const & rIdx, const xub_StrLen nDiff,
332 const bool bNeg, const bool /* argument is only used in derived class*/ )
334 SwIndex* pStt = const_cast<SwIndex*>(&rIdx);
335 xub_StrLen nNewVal = rIdx.nIndex;
336 if( bNeg )
338 xub_StrLen nLast = rIdx.GetIndex() + nDiff;
339 while( pStt && pStt->nIndex == nNewVal )
341 pStt->nIndex = nNewVal;
342 pStt = pStt->pPrev;
344 pStt = rIdx.pNext;
345 while( pStt && pStt->nIndex >= nNewVal &&
346 pStt->nIndex <= nLast )
348 pStt->nIndex = nNewVal;
349 pStt = pStt->pNext;
351 while( pStt )
353 pStt->nIndex = pStt->nIndex - nDiff;
354 pStt = pStt->pNext;
357 else
359 while( pStt && pStt->nIndex == nNewVal )
361 pStt->nIndex = pStt->nIndex + nDiff;
362 pStt = pStt->pPrev;
364 pStt = rIdx.pNext;
365 while( pStt )
367 pStt->nIndex = pStt->nIndex + nDiff;
368 pStt = pStt->pNext;
371 ARR_CHK_ARRAY
374 #ifndef PRODUCT
375 #ifndef CFRONT
377 /*************************************************************************
379 |* SwIndex::operator++()
381 |* Beschreibung
382 |* Ersterstellung JP 07.11.90
383 |* Letzte Aenderung JP 07.03.94
385 *************************************************************************/
386 xub_StrLen SwIndex::operator++(int)
388 ASSERT_ID( nIndex < INVALID_INDEX, ERR_OUTOFSCOPE );
390 xub_StrLen nOldIndex = nIndex;
391 ChgValue( *this, nIndex+1 );
392 return nOldIndex;
395 #endif
397 xub_StrLen SwIndex::operator++()
399 ASSERT_ID( nIndex < INVALID_INDEX, ERR_OUTOFSCOPE );
401 ChgValue( *this, nIndex+1 );
402 return nIndex;
405 /*************************************************************************
407 |* SwIndex::operator--()
409 |* Beschreibung
410 |* Ersterstellung JP 07.11.90
411 |* Letzte Aenderung JP 07.03.94
413 *************************************************************************/
415 #ifndef CFRONT
417 xub_StrLen SwIndex::operator--(int)
419 ASSERT_ID( nIndex, ERR_OUTOFSCOPE );
421 xub_StrLen nOldIndex = nIndex;
422 ChgValue( *this, nIndex-1 );
423 return nOldIndex;
426 #endif
428 xub_StrLen SwIndex::operator--()
430 ASSERT_ID( nIndex, ERR_OUTOFSCOPE );
431 return ChgValue( *this, nIndex-1 ).nIndex;
434 /*************************************************************************
436 |* SwIndex::operator+=( xub_StrLen )
438 |* Beschreibung
439 |* Ersterstellung JP 07.11.90
440 |* Letzte Aenderung JP 07.03.94
442 *************************************************************************/
444 xub_StrLen SwIndex::operator+=( xub_StrLen nWert )
446 ASSERT_ID( nIndex < INVALID_INDEX - nWert, ERR_OUTOFSCOPE);
447 return ChgValue( *this, nIndex + nWert ).nIndex;
450 /*************************************************************************
452 |* SwIndex::operator-=( xub_StrLen )
454 |* Beschreibung
455 |* Ersterstellung JP 07.11.90
456 |* Letzte Aenderung JP 07.03.94
458 *************************************************************************/
460 xub_StrLen SwIndex::operator-=( xub_StrLen nWert )
462 ASSERT_ID( nIndex >= nWert, ERR_OUTOFSCOPE );
463 return ChgValue( *this, nIndex - nWert ).nIndex;
466 /*************************************************************************
468 |* SwIndex::operator+=( const SwIndex & )
470 |* Beschreibung
471 |* Ersterstellung JP 07.11.90
472 |* Letzte Aenderung JP 07.03.94
474 *************************************************************************/
476 xub_StrLen SwIndex::operator+=( const SwIndex & rIndex )
478 ASSERT_ID( nIndex < INVALID_INDEX - rIndex.nIndex, ERR_OUTOFSCOPE );
479 return ChgValue( *this, nIndex + rIndex.nIndex ).nIndex;
482 /*************************************************************************
484 |* SwIndex::operator-=( const SwIndex & )
486 |* Beschreibung
487 |* Ersterstellung JP 07.11.90
488 |* Letzte Aenderung JP 07.03.94
490 *************************************************************************/
492 xub_StrLen SwIndex::operator-=( const SwIndex & rIndex )
494 ASSERT_ID( nIndex >= rIndex.nIndex, ERR_OUTOFSCOPE );
495 return ChgValue( *this, nIndex - rIndex.nIndex ).nIndex;
498 /*************************************************************************
500 |* SwIndex::operator<( const SwIndex & )
502 |* Beschreibung
503 |* Ersterstellung JP 07.11.90
504 |* Letzte Aenderung JP 07.03.94
506 *************************************************************************/
508 BOOL SwIndex::operator<( const SwIndex & rIndex ) const
510 ASSERT( pArray == rIndex.pArray, "Attempt to compare indices into different arrays.");
511 return nIndex < rIndex.nIndex;
514 /*************************************************************************
516 |* SwIndex::operator<=( const SwIndex & )
518 |* Beschreibung
519 |* Ersterstellung JP 07.11.90
520 |* Letzte Aenderung JP 04.06.92
522 *************************************************************************/
524 BOOL SwIndex::operator<=( const SwIndex & rIndex ) const
526 ASSERT( pArray == rIndex.pArray, "Attempt to compare indices into different arrays.");
527 return nIndex <= rIndex.nIndex;
530 /*************************************************************************
532 |* SwIndex::operator>( const SwIndex & )
534 |* Beschreibung
535 |* Ersterstellung JP 07.11.90
536 |* Letzte Aenderung JP 04.06.92
538 *************************************************************************/
540 BOOL SwIndex::operator>( const SwIndex & rIndex ) const
542 ASSERT( pArray == rIndex.pArray, "Attempt to compare indices into different arrays.");
543 return nIndex > rIndex.nIndex;
546 /*************************************************************************
548 |* SwIndex::operator>=( const SwIndex & )
550 |* Beschreibung
551 |* Ersterstellung JP 07.11.90
552 |* Letzte Aenderung JP 04.06.92
554 *************************************************************************/
556 BOOL SwIndex::operator>=( const SwIndex & rIndex ) const
558 ASSERT( pArray == rIndex.pArray, "Attempt to compare indices into different arrays.");
559 return nIndex >= rIndex.nIndex;
562 /*************************************************************************
564 |* SwIndex & SwIndex::operator=( xub_StrLen )
566 |* Beschreibung
567 |* Ersterstellung JP 10.12.90
568 |* Letzte Aenderung JP 07.03.94
570 *************************************************************************/
572 SwIndex& SwIndex::operator=( xub_StrLen nWert )
574 // Werte kopieren und im neuen Array anmelden
575 if( nIndex != nWert )
576 ChgValue( *this, nWert );
578 return *this;
581 #endif // ifndef PRODUCT
583 void SwIndexReg::MoveTo( SwIndexReg& rArr )
585 if( this != &rArr && pFirst )
587 SwIndex* pIdx = (SwIndex*)pFirst, *pNext;
588 while( pIdx )
590 pNext = pIdx->pNext;
591 pIdx->Assign( &rArr, pIdx->GetIndex() );
592 pIdx = pNext;
594 pFirst = 0, pLast = 0;