update credits
[LibreOffice.git] / tools / source / memtools / multisel.cxx
blobd91c499834265862c5cd987760f6b9e73f71282b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifdef MI_DEBUG
21 #define private public
22 #include <stdio.h>
23 #endif
25 #include <tools/debug.hxx>
26 #include <tools/multisel.hxx>
28 #include "rtl/ustrbuf.hxx"
30 #ifdef MI_DEBUG
31 #define DBG(x) x
32 #else
33 #define DBG(x)
34 #endif
37 #ifdef MI_DEBUG
38 static void Print( const MultiSelection* pSel )
40 DbgOutf( "TotRange: %4ld-%4ld\n",
41 pSel->aTotRange.Min(), pSel->aTotRange.Max() );
42 if ( pSel->bCurValid )
44 DbgOutf( "CurSubSel: %4ld\n", pSel->nCurSubSel );
45 DbgOutf( "CurIndex: %4ld\n", pSel->nCurIndex );
47 DbgOutf( "SelCount: %4ld\n", pSel->nSelCount );
48 DbgOutf( "SubCount: %4ld\n", pSel->aSels.Count() );
49 for ( sal_uIntPtr nPos = 0; nPos < pSel->aSels.Count(); ++nPos )
51 DbgOutf( "SubSel #%2ld: %4ld-%4ld\n", nPos,
52 pSel->aSels.GetObject(nPos)->Min(),
53 pSel->aSels.GetObject(nPos)->Max() );
55 DbgOutf( "\n" );
56 fclose( pFile );
58 #endif
60 void MultiSelection::ImplClear()
62 // no selected indexes
63 nSelCount = 0;
65 for ( size_t i = 0, n = aSels.size(); i < n; ++i ) {
66 delete aSels[ i ];
68 aSels.clear();
71 size_t MultiSelection::ImplFindSubSelection( long nIndex ) const
73 // iterate through the sub selections
74 size_t n = 0;
75 for ( ;
76 n < aSels.size() && nIndex > aSels[ n ]->Max();
77 ++n ) {} /* empty loop */
78 return n;
81 sal_Bool MultiSelection::ImplMergeSubSelections( size_t nPos1, size_t nPos2 )
83 // didn't a sub selection at nPos2 exist?
84 if ( nPos2 >= aSels.size() )
85 return sal_False;
87 // did the sub selections touch each other?
88 if ( (aSels[ nPos1 ]->Max() + 1) == aSels[ nPos2 ]->Min() )
90 // merge them
91 aSels[ nPos1 ]->Max() = aSels[ nPos2 ]->Max();
92 ImpSelList::iterator it = aSels.begin();
93 ::std::advance( it, nPos2 );
94 delete *it;
95 aSels.erase( it );
96 return sal_True;
99 return sal_False;
102 MultiSelection::MultiSelection():
103 aTotRange( 0, -1 ),
104 nCurSubSel(0),
105 nSelCount(0),
106 bCurValid(sal_False),
107 bSelectNew(sal_False)
111 MultiSelection::MultiSelection( const MultiSelection& rOrig ) :
112 aTotRange(rOrig.aTotRange),
113 nSelCount(rOrig.nSelCount),
114 bCurValid(rOrig.bCurValid),
115 bSelectNew(sal_False)
117 if ( bCurValid )
119 nCurSubSel = rOrig.nCurSubSel;
120 nCurIndex = rOrig.nCurIndex;
123 // copy the sub selections
124 for ( size_t n = 0; n < rOrig.aSels.size(); ++n )
125 aSels.push_back( new Range( *rOrig.aSels[ n ] ) );
128 MultiSelection::MultiSelection( const Range& rRange ):
129 aTotRange(rRange),
130 nCurSubSel(0),
131 nSelCount(0),
132 bCurValid(sal_False),
133 bSelectNew(sal_False)
137 MultiSelection::~MultiSelection()
139 for ( size_t i = 0, n = aSels.size(); i < n; ++i )
140 delete aSels[ i ];
141 aSels.clear();
144 MultiSelection& MultiSelection::operator= ( const MultiSelection& rOrig )
146 aTotRange = rOrig.aTotRange;
147 bCurValid = rOrig.bCurValid;
148 if ( bCurValid )
150 nCurSubSel = rOrig.nCurSubSel;
151 nCurIndex = rOrig.nCurIndex;
154 // clear the old and copy the sub selections
155 ImplClear();
156 for ( size_t n = 0; n < rOrig.aSels.size(); ++n )
157 aSels.push_back( new Range( *rOrig.aSels[ n ] ) );
158 nSelCount = rOrig.nSelCount;
160 return *this;
163 sal_Bool MultiSelection::operator== ( MultiSelection& rWith )
165 if ( aTotRange != rWith.aTotRange || nSelCount != rWith.nSelCount ||
166 aSels.size() != rWith.aSels.size() )
167 return sal_False;
169 // compare the sub seletions
170 for ( size_t n = 0; n < aSels.size(); ++n )
171 if ( *aSels[ n ] != *rWith.aSels[ n ] )
172 return sal_False;
173 return sal_True;
176 void MultiSelection::SelectAll( sal_Bool bSelect )
178 DBG(DbgOutf( "::SelectAll(%s)\n", bSelect ? "sal_True" : "sal_False" ));
180 ImplClear();
181 if ( bSelect )
183 aSels.push_back( new Range(aTotRange) );
184 nSelCount = aTotRange.Len();
187 DBG(Print( this ));
190 sal_Bool MultiSelection::Select( long nIndex, sal_Bool bSelect )
192 DBG_ASSERT( aTotRange.IsInside(nIndex), "selected index out of range" );
194 // out of range?
195 if ( !aTotRange.IsInside(nIndex) )
196 return sal_False;
198 // find the virtual target position
199 size_t nSubSelPos = ImplFindSubSelection( nIndex );
201 if ( bSelect )
203 // is it included in the found sub selection?
204 if ( nSubSelPos < aSels.size() && aSels[ nSubSelPos ]->IsInside( nIndex ) )
205 // already selected, nothing to do
206 return sal_False;
208 // it will become selected
209 ++nSelCount;
211 // is it at the end of the previous sub selection
212 if ( nSubSelPos > 0 &&
213 aSels[ nSubSelPos-1 ]->Max() == (nIndex-1) )
215 // expand the previous sub selection
216 aSels[ nSubSelPos-1 ]->Max() = nIndex;
218 // try to merge the previous sub selection
219 ImplMergeSubSelections( nSubSelPos-1, nSubSelPos );
221 // is is at the beginning of the found sub selection
222 else if ( nSubSelPos < aSels.size()
223 && aSels[ nSubSelPos ]->Min() == (nIndex+1)
225 // expand the found sub selection
226 aSels[ nSubSelPos ]->Min() = nIndex;
227 else
229 // create a new sub selection
230 if ( nSubSelPos < aSels.size() ) {
231 ImpSelList::iterator it = aSels.begin();
232 ::std::advance( it, nSubSelPos );
233 aSels.insert( it, new Range( nIndex, nIndex ) );
234 } else {
235 aSels.push_back( new Range( nIndex, nIndex ) );
237 if ( bCurValid && nCurSubSel >= nSubSelPos )
238 ++nCurSubSel;
241 else
243 // is it excluded from the found sub selection?
244 if ( nSubSelPos >= aSels.size()
245 || !aSels[ nSubSelPos ]->IsInside( nIndex )
247 // not selected, nothing to do
248 DBG(Print( this ));
249 return sal_False;
252 // it will become deselected
253 --nSelCount;
255 // is it the only index in the found sub selection?
256 if ( aSels[ nSubSelPos ]->Len() == 1 )
258 // remove the complete sub selection
259 ImpSelList::iterator it = aSels.begin();
260 ::std::advance( it, nSubSelPos );
261 delete *it;
262 aSels.erase( it );
263 DBG(Print( this ));
264 return sal_True;
267 // is it at the beginning of the found sub selection?
268 if ( aSels[ nSubSelPos ]->Min() == nIndex )
269 ++aSels[ nSubSelPos ]->Min();
270 // is it at the end of the found sub selection?
271 else if ( aSels[ nSubSelPos ]->Max() == nIndex )
272 --aSels[ nSubSelPos ]->Max();
273 // it is in the middle of the found sub selection?
274 else
276 // split the sub selection
277 if ( nSubSelPos < aSels.size() ) {
278 ImpSelList::iterator it = aSels.begin();
279 ::std::advance( it, nSubSelPos );
280 aSels.insert( it, new Range( aSels[ nSubSelPos ]->Min(), nIndex-1 ) );
281 } else {
282 aSels.push_back( new Range( aSels[ nSubSelPos ]->Min(), nIndex-1 ) );
284 aSels[ nSubSelPos+1 ]->Min() = nIndex + 1;
288 DBG(Print( this ));
290 return sal_True;
293 void MultiSelection::Select( const Range& rIndexRange, sal_Bool bSelect )
295 Range* pRange;
296 long nOld;
298 sal_uIntPtr nTmpMin = rIndexRange.Min();
299 sal_uIntPtr nTmpMax = rIndexRange.Max();
300 sal_uIntPtr nCurMin = FirstSelected();
301 sal_uIntPtr nCurMax = LastSelected();
302 DBG_ASSERT(aTotRange.IsInside(nTmpMax), "selected index out of range" );
303 DBG_ASSERT(aTotRange.IsInside(nTmpMin), "selected index out of range" );
305 // replace whole selection?
306 if( nTmpMin <= nCurMin && nTmpMax >= nCurMax )
308 ImplClear();
309 if ( bSelect )
311 aSels.push_back( new Range(rIndexRange) );
312 nSelCount = rIndexRange.Len();
314 return;
316 // expand on left side?
317 if( nTmpMax < nCurMin )
319 if( bSelect )
321 // extend first range?
322 if( nCurMin > (nTmpMax+1) )
324 pRange = new Range( rIndexRange );
325 aSels.insert( aSels.begin() , pRange );
326 nSelCount += pRange->Len();
328 else
330 pRange = aSels.front();
331 nOld = pRange->Min();
332 pRange->Min() = (long)nTmpMin;
333 nSelCount += ( nOld - nTmpMin );
335 bCurValid = sal_False;
337 return;
339 // expand on right side?
340 else if( nTmpMin > nCurMax )
342 if( bSelect )
344 // extend last range?
345 if( nTmpMin > (nCurMax+1) )
347 pRange = new Range( rIndexRange );
348 aSels.push_back( pRange );
349 nSelCount += pRange->Len();
351 else
353 pRange = aSels.back();
354 nOld = pRange->Max();
355 pRange->Max() = (long)nTmpMax;
356 nSelCount += ( nTmpMax - nOld );
358 bCurValid = sal_False;
360 return;
363 // TODO here is potential for optimization
364 while( nTmpMin <= nTmpMax )
366 Select( nTmpMin, bSelect );
367 nTmpMin++;
371 sal_Bool MultiSelection::IsSelected( long nIndex ) const
373 // find the virtual target position
374 size_t nSubSelPos = ImplFindSubSelection( nIndex );
376 return nSubSelPos < aSels.size() && aSels[ nSubSelPos ]->IsInside(nIndex);
379 void MultiSelection::Insert( long nIndex, long nCount )
381 DBG(DbgOutf( "::Insert(%ld, %ld)\n", nIndex, nCount ));
383 // find the virtual target position
384 size_t nSubSelPos = ImplFindSubSelection( nIndex );
386 // did we need to shift the sub selections?
387 if ( nSubSelPos < aSels.size() )
388 { // did we insert an unselected into an existing sub selection?
389 if ( !bSelectNew
390 && aSels[ nSubSelPos ]->Min() != nIndex
391 && aSels[ nSubSelPos ]->IsInside(nIndex)
392 ) { // split the sub selection
393 if ( nSubSelPos < aSels.size() ) {
394 ImpSelList::iterator it = aSels.begin();
395 ::std::advance( it, nSubSelPos );
396 aSels.insert( it, new Range( aSels[ nSubSelPos ]->Min(), nIndex-1 ) );
397 } else {
398 aSels.push_back( new Range( aSels[ nSubSelPos ]->Min(), nIndex-1 ) );
400 ++nSubSelPos;
401 aSels[ nSubSelPos ]->Min() = nIndex;
404 // did we append an selected to an existing sub selection?
405 else if ( bSelectNew
406 && nSubSelPos > 0
407 && aSels[ nSubSelPos ]->Max() == nIndex-1
408 ) // expand the previous sub selection
409 aSels[ nSubSelPos-1 ]->Max() += nCount;
411 // did we insert an selected into an existing sub selection?
412 else if ( bSelectNew
413 && aSels[ nSubSelPos ]->Min() == nIndex
414 ) { // expand the sub selection
415 aSels[ nSubSelPos ]->Max() += nCount;
416 ++nSubSelPos;
419 // shift the sub selections behind the inserting position
420 for ( size_t nPos = nSubSelPos; nPos < aSels.size(); ++nPos )
422 aSels[ nPos ]->Min() += nCount;
423 aSels[ nPos ]->Max() += nCount;
427 bCurValid = sal_False;
428 aTotRange.Max() += nCount;
429 if ( bSelectNew )
430 nSelCount += nCount;
432 DBG(Print( this ));
435 void MultiSelection::Remove( long nIndex )
437 DBG(DbgOutf( "::Remove(%ld)\n", nIndex ));
439 // find the virtual target position
440 size_t nSubSelPos = ImplFindSubSelection( nIndex );
442 // did we remove from an existing sub selection?
443 if ( nSubSelPos < aSels.size()
444 && aSels[ nSubSelPos ]->IsInside(nIndex)
446 // does this sub selection only contain the index to be deleted
447 if ( aSels[ nSubSelPos ]->Len() == 1 ) {
448 // completely remove the sub selection
449 ImpSelList::iterator it = aSels.begin();
450 ::std::advance( it, nSubSelPos );
451 delete *it;
452 aSels.erase( it );
453 } else {
454 // shorten this sub selection
455 --( aSels[ nSubSelPos++ ]->Max() );
458 // adjust the selected counter
459 --nSelCount;
462 // shift the sub selections behind the removed index
463 for ( size_t nPos = nSubSelPos; nPos < aSels.size(); ++nPos )
465 --( aSels[ nPos ]->Min() );
466 --( aSels[ nPos ]->Max() );
469 bCurValid = sal_False;
470 aTotRange.Max() -= 1;
472 DBG(Print( this ));
475 long MultiSelection::ImplFwdUnselected()
477 if ( !bCurValid )
478 return SFX_ENDOFSELECTION;
480 if ( ( nCurSubSel < aSels.size() )
481 && ( aSels[ nCurSubSel ]->Min() <= nCurIndex )
483 nCurIndex = aSels[ nCurSubSel++ ]->Max() + 1;
485 if ( nCurIndex <= aTotRange.Max() )
486 return nCurIndex;
487 else
488 return SFX_ENDOFSELECTION;
491 long MultiSelection::FirstSelected( sal_Bool bInverse )
493 bInverseCur = bInverse;
494 nCurSubSel = 0;
496 if ( bInverseCur )
498 bCurValid = nSelCount < sal_uIntPtr(aTotRange.Len());
499 if ( bCurValid )
501 nCurIndex = 0;
502 return ImplFwdUnselected();
505 else
507 bCurValid = !aSels.empty();
508 if ( bCurValid )
509 return nCurIndex = aSels[ 0 ]->Min();
512 return SFX_ENDOFSELECTION;
515 long MultiSelection::LastSelected()
517 nCurSubSel = aSels.size() - 1;
518 bCurValid = !aSels.empty();
520 if ( bCurValid )
521 return nCurIndex = aSels[ nCurSubSel ]->Max();
523 return SFX_ENDOFSELECTION;
526 long MultiSelection::NextSelected()
528 if ( !bCurValid )
529 return SFX_ENDOFSELECTION;
531 if ( bInverseCur )
533 ++nCurIndex;
534 return ImplFwdUnselected();
536 else
538 // is the next index in the current sub selection too?
539 if ( nCurIndex < aSels[ nCurSubSel ]->Max() )
540 return ++nCurIndex;
542 // are there further sub selections?
543 if ( ++nCurSubSel < aSels.size() )
544 return nCurIndex = aSels[ nCurSubSel ]->Min();
546 // we are at the end!
547 return SFX_ENDOFSELECTION;
551 void MultiSelection::SetTotalRange( const Range& rTotRange )
553 aTotRange = rTotRange;
555 // adjust lower boundary
556 Range* pRange = aSels.empty() ? NULL : aSels.front();
557 while( pRange )
559 if( pRange->Max() < aTotRange.Min() )
561 delete pRange;
562 aSels.erase( aSels.begin() );
564 else if( pRange->Min() < aTotRange.Min() )
566 pRange->Min() = aTotRange.Min();
567 break;
569 else
570 break;
572 pRange = aSels.empty() ? NULL : aSels.front();
575 // adjust upper boundary
576 size_t nCount = aSels.size();
577 while( nCount )
579 pRange = aSels[ nCount - 1 ];
580 if( pRange->Min() > aTotRange.Max() )
582 delete pRange;
583 aSels.pop_back();
585 else if( pRange->Max() > aTotRange.Max() )
587 pRange->Max() = aTotRange.Max();
588 break;
590 else
591 break;
593 nCount = aSels.size();
596 // re-calculate selection count
597 nSelCount = 0;
598 for ( size_t i = 0, n = aSels.size(); i < n; ++ i )
599 nSelCount += aSels[i]->Len();
601 bCurValid = sal_False;
602 nCurIndex = 0;
605 // StringRangeEnumerator
607 StringRangeEnumerator::StringRangeEnumerator( const OUString& i_rInput,
608 sal_Int32 i_nMinNumber,
609 sal_Int32 i_nMaxNumber,
610 sal_Int32 i_nLogicalOffset
612 : mnCount( 0 )
613 , mnMin( i_nMinNumber )
614 , mnMax( i_nMaxNumber )
615 , mnOffset( i_nLogicalOffset )
616 , mbValidInput( false )
618 // Parse string only if boundaries are valid.
619 if( mnMin >= 0 && mnMax >= 0 && mnMin <= mnMax )
620 mbValidInput = setRange( i_rInput );
623 bool StringRangeEnumerator::checkValue( sal_Int32 i_nValue, const std::set< sal_Int32 >* i_pPossibleValues ) const
625 if( i_nValue < 0 || i_nValue < mnMin || i_nValue > mnMax )
626 return false;
627 if( i_pPossibleValues && i_pPossibleValues->find( i_nValue ) == i_pPossibleValues->end() )
628 return false;
629 return true;
632 bool StringRangeEnumerator::insertRange( sal_Int32 i_nFirst, sal_Int32 i_nLast, bool bSequence, bool bMayAdjust )
634 bool bSuccess = true;
635 if( bSequence )
637 if( bMayAdjust )
639 if( i_nFirst < mnMin )
640 i_nFirst = mnMin;
641 if( i_nFirst > mnMax )
642 i_nFirst = mnMax;
643 if( i_nLast < mnMin )
644 i_nLast = mnMin;
645 if( i_nLast > mnMax )
646 i_nLast = mnMax;
648 if( checkValue( i_nFirst ) && checkValue( i_nLast ) )
650 maSequence.push_back( Range( i_nFirst, i_nLast ) );
651 sal_Int32 nNumber = i_nLast - i_nFirst;
652 nNumber = nNumber < 0 ? -nNumber : nNumber;
653 mnCount += nNumber + 1;
655 else
656 bSuccess = false;
658 else
660 if( checkValue( i_nFirst ) )
662 maSequence.push_back( Range( i_nFirst, i_nFirst ) );
663 mnCount++;
665 else if( checkValue( i_nLast ) )
667 maSequence.push_back( Range( i_nLast, i_nLast ) );
668 mnCount++;
670 else
671 bSuccess = false;
674 return bSuccess;
677 bool StringRangeEnumerator::insertJoinedRanges(
678 const std::vector< sal_Int32 >& rNumbers, bool i_bStrict )
680 size_t nCount = rNumbers.size();
681 if( nCount == 0 )
682 return true;
684 if( nCount == 1 )
685 return insertRange( rNumbers[0], -1, false, ! i_bStrict );
687 for( size_t i = 0; i < nCount - 1; i++ )
689 sal_Int32 nFirst = rNumbers[i];
690 sal_Int32 nLast = rNumbers[i + 1];
691 if( i > 0 )
693 if ( nFirst > nLast ) nFirst--;
694 else if( nFirst < nLast ) nFirst++;
697 if ( ! insertRange( nFirst, nLast, nFirst != nLast, ! i_bStrict ) && i_bStrict)
698 return false;
701 return true;
704 bool StringRangeEnumerator::setRange( const OUString& i_rNewRange, bool i_bStrict )
706 mnCount = 0;
707 maSequence.clear();
709 const sal_Unicode* pInput = i_rNewRange.getStr();
710 OUStringBuffer aNumberBuf( 16 );
711 std::vector< sal_Int32 > aNumbers;
712 bool bSequence = false;
713 while( *pInput )
715 while( *pInput >= sal_Unicode('0') && *pInput <= sal_Unicode('9') )
716 aNumberBuf.append( *pInput++ );
717 if( aNumberBuf.getLength() )
719 sal_Int32 nNumber = aNumberBuf.makeStringAndClear().toInt32() + mnOffset;
720 aNumbers.push_back( nNumber );
721 bSequence = false;
724 if( *pInput == sal_Unicode('-') )
726 bSequence = true;
727 if( aNumbers.empty() )
728 aNumbers.push_back( mnMin );
730 else if( *pInput == sal_Unicode(',') || *pInput == sal_Unicode(';') )
732 if( bSequence && !aNumbers.empty() )
733 aNumbers.push_back( mnMax );
734 if( ! insertJoinedRanges( aNumbers, i_bStrict ) && i_bStrict )
735 return false;
737 aNumbers.clear();
738 bSequence = false;
740 else if( *pInput && *pInput != sal_Unicode(' ') )
741 return false; // parse error
743 if( *pInput )
744 pInput++;
746 // insert last entries
747 if( bSequence && !aNumbers.empty() )
748 aNumbers.push_back( mnMax );
749 if( ! insertJoinedRanges( aNumbers, i_bStrict ) && i_bStrict )
750 return false;
752 return true;
755 bool StringRangeEnumerator::hasValue( sal_Int32 i_nValue, const std::set< sal_Int32 >* i_pPossibleValues ) const
757 if( i_pPossibleValues && i_pPossibleValues->find( i_nValue ) == i_pPossibleValues->end() )
758 return false;
759 size_t n = maSequence.size();
760 for( size_t i= 0; i < n; ++i )
762 const StringRangeEnumerator::Range rRange( maSequence[i] );
763 if( rRange.nFirst < rRange.nLast )
765 if( i_nValue >= rRange.nFirst && i_nValue <= rRange.nLast )
766 return true;
768 else
770 if( i_nValue >= rRange.nLast && i_nValue <= rRange.nFirst )
771 return true;
774 return false;
777 StringRangeEnumerator::Iterator& StringRangeEnumerator::Iterator::operator++()
779 if( nRangeIndex >= 0 && nCurrent >= 0 && pEnumerator )
781 const StringRangeEnumerator::Range& rRange( pEnumerator->maSequence[nRangeIndex] );
782 bool bRangeChange = false;
783 if( rRange.nLast < rRange.nFirst )
785 // backward range
786 if( nCurrent > rRange.nLast )
787 nCurrent--;
788 else
789 bRangeChange = true;
791 else
793 // forward range
794 if( nCurrent < rRange.nLast )
795 nCurrent++;
796 else
797 bRangeChange = true;
799 if( bRangeChange )
801 nRangeIndex++;
802 if( size_t(nRangeIndex) == pEnumerator->maSequence.size() )
804 // reached the end
805 nRangeIndex = nCurrent = -1;
807 else
808 nCurrent = pEnumerator->maSequence[nRangeIndex].nFirst;
810 if( nRangeIndex != -1 && nCurrent != -1 )
812 if( ! pEnumerator->checkValue( nCurrent, pPossibleValues ) )
813 return ++(*this);
816 return *this;
819 sal_Int32 StringRangeEnumerator::Iterator::operator*() const
821 return nCurrent;
824 bool StringRangeEnumerator::Iterator::operator==( const Iterator& i_rCompare ) const
826 return i_rCompare.pEnumerator == pEnumerator && i_rCompare.nRangeIndex == nRangeIndex && i_rCompare.nCurrent == nCurrent;
829 StringRangeEnumerator::Iterator StringRangeEnumerator::begin( const std::set< sal_Int32 >* i_pPossibleValues ) const
831 StringRangeEnumerator::Iterator it( this,
832 i_pPossibleValues,
833 maSequence.empty() ? -1 : 0,
834 maSequence.empty() ? -1 : maSequence[0].nFirst );
835 if( ! checkValue(*it, i_pPossibleValues ) )
836 ++it;
837 return it;
840 StringRangeEnumerator::Iterator StringRangeEnumerator::end( const std::set< sal_Int32 >* i_pPossibleValues ) const
842 return StringRangeEnumerator::Iterator( this, i_pPossibleValues, -1, -1 );
845 bool StringRangeEnumerator::getRangesFromString( const OUString& i_rPageRange,
846 std::vector< sal_Int32 >& o_rPageVector,
847 sal_Int32 i_nMinNumber,
848 sal_Int32 i_nMaxNumber,
849 sal_Int32 i_nLogicalOffset,
850 std::set< sal_Int32 >* i_pPossibleValues
853 o_rPageVector.clear();
855 StringRangeEnumerator aEnum( i_rPageRange, i_nMinNumber, i_nMaxNumber, i_nLogicalOffset ) ;
857 //Even if the input range wasn't completely valid, return what ranges could
858 //be extracted from the input.
859 o_rPageVector.reserve( static_cast< size_t >( aEnum.size() ) );
860 for( StringRangeEnumerator::Iterator it = aEnum.begin( i_pPossibleValues );
861 it != aEnum.end( i_pPossibleValues ); ++it )
863 o_rPageVector.push_back( *it );
866 return aEnum.isValidInput();
869 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */