1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: index.cxx,v $
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
40 #include "error.h" // fuers ASSERT
43 int SwIndex::nSerial
= 0;
47 TYPEINIT0(SwIndexReg
); // rtti
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" );
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" );
90 SwIndex::SwIndex( SwIndexReg
* pArr
, xub_StrLen nIdx
)
91 : nIndex( nIdx
), pArray( pArr
), pNext( 0 ), pPrev( 0 )
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
);
104 ChgValue( *pArray
->pFirst
, nIdx
);
107 MySerial
= ++nSerial
; // nur in der nicht PRODUCT-Version
113 SwIndex::SwIndex( const SwIndex
& rIdx
, short nIdx
)
114 : pArray( rIdx
.pArray
), pNext( 0 ), pPrev( 0 )
116 ChgValue( rIdx
, rIdx
.nIndex
+ nIdx
);
119 MySerial
= ++nSerial
; // nur in der nicht PRODUCT-Version
125 SwIndex::SwIndex( const SwIndex
& rIdx
)
126 : nIndex( rIdx
.nIndex
), pArray( rIdx
.pArray
), pNext( 0 ), pPrev( 0 )
128 ChgValue( rIdx
, rIdx
.nIndex
);
130 MySerial
= ++nSerial
; // nur in der nicht PRODUCT-Version
136 SwIndex
& SwIndex::ChgValue( const SwIndex
& rIdx
, xub_StrLen nNewValue
)
138 SwIndex
* pFnd
= (SwIndex
*)&rIdx
;
139 if( rIdx
.nIndex
> nNewValue
) // nach vorne versuchen
142 while( 0 != ( pPrv
= pFnd
->pPrev
) && pPrv
->nIndex
> nNewValue
)
147 // an alter Position ausketten
148 // erstmal an alter Position ausketten
150 pPrev
->pNext
= pNext
;
151 else if( pArray
->pFirst
== this )
152 pArray
->pFirst
= pNext
;
155 pNext
->pPrev
= pPrev
;
156 else if( pArray
->pLast
== this )
157 pArray
->pLast
= pPrev
;
164 pArray
->pFirst
= this;
168 else if( rIdx
.nIndex
< nNewValue
)
171 while( 0 != ( pNxt
= pFnd
->pNext
) && pNxt
->nIndex
< nNewValue
)
176 // erstmal an alter Position ausketten
178 pPrev
->pNext
= pNext
;
179 else if( pArray
->pFirst
== this )
180 pArray
->pFirst
= pNext
;
183 pNext
->pPrev
= pPrev
;
184 else if( pArray
->pLast
== this )
185 pArray
->pLast
= pPrev
;
192 pArray
->pLast
= this;
196 else if( pFnd
!= this )
198 // erstmal an alter Position ausketten
200 pPrev
->pNext
= pNext
;
201 else if( pArray
->pFirst
== this )
202 pArray
->pFirst
= pNext
;
205 pNext
->pPrev
= pPrev
;
206 else if( pArray
->pLast
== this )
207 pArray
->pLast
= pPrev
;
209 pPrev
= (SwIndex
*)&rIdx
;
213 if( !pNext
) // im IndexArray als letzes
214 pArray
->pLast
= this;
218 pArray
= rIdx
.pArray
;
220 if( pArray
->pFirst
== pNext
)
221 pArray
->pFirst
= this;
222 if( pArray
->pLast
== pPrev
)
223 pArray
->pLast
= this;
232 void SwIndex::Remove()
235 pArray
->pFirst
= pNext
;
237 pPrev
->pNext
= pNext
;
240 pArray
->pLast
= pPrev
;
242 pNext
->pPrev
= pPrev
;
247 /*************************************************************************
249 |* SwIndex & SwIndex::operator=( const SwIndex & aSwIndex )
252 |* Ersterstellung JP 07.11.90
253 |* Letzte Aenderung JP 07.03.94
255 *************************************************************************/
258 SwIndex
& SwIndex::operator=( const SwIndex
& rIdx
)
261 if( rIdx
.pArray
!= pArray
) // im alten abmelden !!
264 pArray
= rIdx
.pArray
;
269 bEqual
= rIdx
.nIndex
== nIndex
;
272 ChgValue( rIdx
, rIdx
.nIndex
);
276 /*************************************************************************
278 |* SwIndex &SwIndex::Assign
281 |* Ersterstellung VB 25.03.91
282 |* Letzte Aenderung JP 07.03.94
284 *************************************************************************/
287 SwIndex
& SwIndex::Assign( SwIndexReg
* pArr
, xub_StrLen nIdx
)
291 pArr
= SwIndexReg::pEmptyIndexArray
;
292 nIdx
= 0; // steht immer auf 0 !!!
295 if( pArr
!= pArray
) // im alten abmelden !!
300 if( !pArr
->pFirst
) // 1. Index ??
302 pArr
->pFirst
= pArr
->pLast
= this;
305 else if( pArr
->pLast
&& (nIdx
> ((pArr
->pLast
->nIndex
- pArr
->pFirst
->nIndex
) / 2)) )
306 ChgValue( *pArr
->pLast
, nIdx
);
308 ChgValue( *pArr
->pFirst
, nIdx
);
310 else if( nIndex
!= nIdx
)
311 ChgValue( *this, nIdx
);
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
;
338 xub_StrLen nLast
= rIdx
.GetIndex() + nDiff
;
339 while( pStt
&& pStt
->nIndex
== nNewVal
)
341 pStt
->nIndex
= nNewVal
;
345 while( pStt
&& pStt
->nIndex
>= nNewVal
&&
346 pStt
->nIndex
<= nLast
)
348 pStt
->nIndex
= nNewVal
;
353 pStt
->nIndex
= pStt
->nIndex
- nDiff
;
359 while( pStt
&& pStt
->nIndex
== nNewVal
)
361 pStt
->nIndex
= pStt
->nIndex
+ nDiff
;
367 pStt
->nIndex
= pStt
->nIndex
+ nDiff
;
377 /*************************************************************************
379 |* SwIndex::operator++()
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 );
397 xub_StrLen
SwIndex::operator++()
399 ASSERT_ID( nIndex
< INVALID_INDEX
, ERR_OUTOFSCOPE
);
401 ChgValue( *this, nIndex
+1 );
405 /*************************************************************************
407 |* SwIndex::operator--()
410 |* Ersterstellung JP 07.11.90
411 |* Letzte Aenderung JP 07.03.94
413 *************************************************************************/
417 xub_StrLen
SwIndex::operator--(int)
419 ASSERT_ID( nIndex
, ERR_OUTOFSCOPE
);
421 xub_StrLen nOldIndex
= nIndex
;
422 ChgValue( *this, nIndex
-1 );
428 xub_StrLen
SwIndex::operator--()
430 ASSERT_ID( nIndex
, ERR_OUTOFSCOPE
);
431 return ChgValue( *this, nIndex
-1 ).nIndex
;
434 /*************************************************************************
436 |* SwIndex::operator+=( xub_StrLen )
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 )
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 & )
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 & )
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 & )
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 & )
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 & )
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 & )
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 )
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
);
581 #endif // ifndef PRODUCT
583 void SwIndexReg::MoveTo( SwIndexReg
& rArr
)
585 if( this != &rArr
&& pFirst
)
587 SwIndex
* pIdx
= (SwIndex
*)pFirst
, *pNext
;
591 pIdx
->Assign( &rArr
, pIdx
->GetIndex() );
594 pFirst
= 0, pLast
= 0;