Branch libreoffice-5-0-4
[LibreOffice.git] / tools / source / memtools / multisel.cxx
blobc385bc43fb98dce7aa7ed9474950db6b28222fd2
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 #include <tools/debug.hxx>
21 #include <tools/multisel.hxx>
23 #include <rtl/ustrbuf.hxx>
25 void MultiSelection::ImplClear()
27 // no selected indexes
28 nSelCount = 0;
30 for ( size_t i = 0, n = aSels.size(); i < n; ++i ) {
31 delete aSels[ i ];
33 aSels.clear();
36 size_t MultiSelection::ImplFindSubSelection( long nIndex ) const
38 // iterate through the sub selections
39 size_t n = 0;
40 for ( ;
41 n < aSels.size() && nIndex > aSels[ n ]->Max();
42 ++n ) {} /* empty loop */
43 return n;
46 bool MultiSelection::ImplMergeSubSelections( size_t nPos1, size_t nPos2 )
48 // didn't a sub selection at nPos2 exist?
49 if ( nPos2 >= aSels.size() )
50 return false;
52 // did the sub selections touch each other?
53 if ( (aSels[ nPos1 ]->Max() + 1) == aSels[ nPos2 ]->Min() )
55 // merge them
56 aSels[ nPos1 ]->Max() = aSels[ nPos2 ]->Max();
57 ImpSelList::iterator it = aSels.begin();
58 ::std::advance( it, nPos2 );
59 delete *it;
60 aSels.erase( it );
61 return true;
64 return false;
67 MultiSelection::MultiSelection():
68 aTotRange( 0, -1 ),
69 nCurSubSel(0),
70 nCurIndex(0),
71 nSelCount(0),
72 bInverseCur(false),
73 bCurValid(false),
74 bSelectNew(false)
78 MultiSelection::MultiSelection( const MultiSelection& rOrig ) :
79 aTotRange(rOrig.aTotRange),
80 nSelCount(rOrig.nSelCount),
81 bCurValid(rOrig.bCurValid),
82 bSelectNew(false)
84 if ( bCurValid )
86 nCurSubSel = rOrig.nCurSubSel;
87 nCurIndex = rOrig.nCurIndex;
88 bInverseCur = rOrig.bInverseCur;
90 else
92 nCurSubSel = 0;
93 nCurIndex = 0;
94 bInverseCur = false;
97 // copy the sub selections
98 for ( size_t n = 0; n < rOrig.aSels.size(); ++n )
99 aSels.push_back( new Range( *rOrig.aSels[ n ] ) );
102 MultiSelection::MultiSelection( const Range& rRange ):
103 aTotRange(rRange),
104 nCurSubSel(0),
105 nCurIndex(0),
106 nSelCount(0),
107 bInverseCur(false),
108 bCurValid(false),
109 bSelectNew(false)
113 MultiSelection::~MultiSelection()
115 for ( size_t i = 0, n = aSels.size(); i < n; ++i )
116 delete aSels[ i ];
117 aSels.clear();
120 MultiSelection& MultiSelection::operator= ( const MultiSelection& rOrig )
122 aTotRange = rOrig.aTotRange;
123 bCurValid = rOrig.bCurValid;
124 if ( bCurValid )
126 nCurSubSel = rOrig.nCurSubSel;
127 nCurIndex = rOrig.nCurIndex;
130 // clear the old and copy the sub selections
131 ImplClear();
132 for ( size_t n = 0; n < rOrig.aSels.size(); ++n )
133 aSels.push_back( new Range( *rOrig.aSels[ n ] ) );
134 nSelCount = rOrig.nSelCount;
136 return *this;
139 bool MultiSelection::operator== ( MultiSelection& rWith )
141 if ( aTotRange != rWith.aTotRange || nSelCount != rWith.nSelCount ||
142 aSels.size() != rWith.aSels.size() )
143 return false;
145 // compare the sub selections
146 for ( size_t n = 0; n < aSels.size(); ++n )
147 if ( *aSels[ n ] != *rWith.aSels[ n ] )
148 return false;
149 return true;
152 void MultiSelection::SelectAll( bool bSelect )
154 ImplClear();
155 if ( bSelect )
157 aSels.push_back( new Range(aTotRange) );
158 nSelCount = aTotRange.Len();
162 bool MultiSelection::Select( long nIndex, bool bSelect )
164 DBG_ASSERT( aTotRange.IsInside(nIndex), "selected index out of range" );
166 // out of range?
167 if ( !aTotRange.IsInside(nIndex) )
168 return false;
170 // find the virtual target position
171 size_t nSubSelPos = ImplFindSubSelection( nIndex );
173 if ( bSelect )
175 // is it included in the found sub selection?
176 if ( nSubSelPos < aSels.size() && aSels[ nSubSelPos ]->IsInside( nIndex ) )
177 // already selected, nothing to do
178 return false;
180 // it will become selected
181 ++nSelCount;
183 // is it at the end of the previous sub selection
184 if ( nSubSelPos > 0 &&
185 aSels[ nSubSelPos-1 ]->Max() == (nIndex-1) )
187 // expand the previous sub selection
188 aSels[ nSubSelPos-1 ]->Max() = nIndex;
190 // try to merge the previous sub selection
191 ImplMergeSubSelections( nSubSelPos-1, nSubSelPos );
193 // is it at the beginning of the found sub selection
194 else if ( nSubSelPos < aSels.size()
195 && aSels[ nSubSelPos ]->Min() == (nIndex+1)
197 // expand the found sub selection
198 aSels[ nSubSelPos ]->Min() = nIndex;
199 else
201 // create a new sub selection
202 if ( nSubSelPos < aSels.size() ) {
203 ImpSelList::iterator it = aSels.begin();
204 ::std::advance( it, nSubSelPos );
205 aSels.insert( it, new Range( nIndex, nIndex ) );
206 } else {
207 aSels.push_back( new Range( nIndex, nIndex ) );
209 if ( bCurValid && nCurSubSel >= nSubSelPos )
210 ++nCurSubSel;
213 else
215 // is it excluded from the found sub selection?
216 if ( nSubSelPos >= aSels.size()
217 || !aSels[ nSubSelPos ]->IsInside( nIndex )
219 // not selected, nothing to do
220 return false;
223 // it will become deselected
224 --nSelCount;
226 // is it the only index in the found sub selection?
227 if ( aSels[ nSubSelPos ]->Len() == 1 )
229 // remove the complete sub selection
230 ImpSelList::iterator it = aSels.begin();
231 ::std::advance( it, nSubSelPos );
232 delete *it;
233 aSels.erase( it );
234 return true;
237 // is it at the beginning of the found sub selection?
238 if ( aSels[ nSubSelPos ]->Min() == nIndex )
239 ++aSels[ nSubSelPos ]->Min();
240 // is it at the end of the found sub selection?
241 else if ( aSels[ nSubSelPos ]->Max() == nIndex )
242 --aSels[ nSubSelPos ]->Max();
243 // it is in the middle of the found sub selection?
244 else
246 // split the sub selection
247 if ( nSubSelPos < aSels.size() ) {
248 ImpSelList::iterator it = aSels.begin();
249 ::std::advance( it, nSubSelPos );
250 aSels.insert( it, new Range( aSels[ nSubSelPos ]->Min(), nIndex-1 ) );
251 } else {
252 aSels.push_back( new Range( aSels[ nSubSelPos ]->Min(), nIndex-1 ) );
254 aSels[ nSubSelPos+1 ]->Min() = nIndex + 1;
258 return true;
261 void MultiSelection::Select( const Range& rIndexRange, bool bSelect )
263 Range* pRange;
264 long nOld;
266 sal_uIntPtr nTmpMin = rIndexRange.Min();
267 sal_uIntPtr nTmpMax = rIndexRange.Max();
268 sal_uIntPtr nCurMin = FirstSelected();
269 sal_uIntPtr nCurMax = LastSelected();
270 DBG_ASSERT(aTotRange.IsInside(nTmpMax), "selected index out of range" );
271 DBG_ASSERT(aTotRange.IsInside(nTmpMin), "selected index out of range" );
273 // replace whole selection?
274 if( nTmpMin <= nCurMin && nTmpMax >= nCurMax )
276 ImplClear();
277 if ( bSelect )
279 aSels.push_back( new Range(rIndexRange) );
280 nSelCount = rIndexRange.Len();
282 return;
284 // expand on left side?
285 if( nTmpMax < nCurMin )
287 if( bSelect )
289 // extend first range?
290 if( nCurMin > (nTmpMax+1) )
292 pRange = new Range( rIndexRange );
293 aSels.insert( aSels.begin() , pRange );
294 nSelCount += pRange->Len();
296 else
298 pRange = aSels.front();
299 nOld = pRange->Min();
300 pRange->Min() = (long)nTmpMin;
301 nSelCount += ( nOld - nTmpMin );
303 bCurValid = false;
305 return;
307 // expand on right side?
308 else if( nTmpMin > nCurMax )
310 if( bSelect )
312 // extend last range?
313 if( nTmpMin > (nCurMax+1) )
315 pRange = new Range( rIndexRange );
316 aSels.push_back( pRange );
317 nSelCount += pRange->Len();
319 else
321 pRange = aSels.back();
322 nOld = pRange->Max();
323 pRange->Max() = (long)nTmpMax;
324 nSelCount += ( nTmpMax - nOld );
326 bCurValid = false;
328 return;
331 // TODO here is potential for optimization
332 while( nTmpMin <= nTmpMax )
334 Select( nTmpMin, bSelect );
335 nTmpMin++;
339 bool MultiSelection::IsSelected( long nIndex ) const
341 // find the virtual target position
342 size_t nSubSelPos = ImplFindSubSelection( nIndex );
344 return nSubSelPos < aSels.size() && aSels[ nSubSelPos ]->IsInside(nIndex);
347 void MultiSelection::Insert( long nIndex, long nCount )
349 // find the virtual target position
350 size_t nSubSelPos = ImplFindSubSelection( nIndex );
352 // did we need to shift the sub selections?
353 if ( nSubSelPos < aSels.size() )
354 { // did we insert an unselected into an existing sub selection?
355 if ( !bSelectNew
356 && aSels[ nSubSelPos ]->Min() != nIndex
357 && aSels[ nSubSelPos ]->IsInside(nIndex)
358 ) { // split the sub selection
359 if ( nSubSelPos < aSels.size() ) {
360 ImpSelList::iterator it = aSels.begin();
361 ::std::advance( it, nSubSelPos );
362 aSels.insert( it, new Range( aSels[ nSubSelPos ]->Min(), nIndex-1 ) );
363 } else {
364 aSels.push_back( new Range( aSels[ nSubSelPos ]->Min(), nIndex-1 ) );
366 ++nSubSelPos;
367 aSels[ nSubSelPos ]->Min() = nIndex;
370 // did we append an selected to an existing sub selection?
371 else if ( bSelectNew
372 && nSubSelPos > 0
373 && aSels[ nSubSelPos ]->Max() == nIndex-1
374 ) // expand the previous sub selection
375 aSels[ nSubSelPos-1 ]->Max() += nCount;
377 // did we insert an selected into an existing sub selection?
378 else if ( bSelectNew
379 && aSels[ nSubSelPos ]->Min() == nIndex
380 ) { // expand the sub selection
381 aSels[ nSubSelPos ]->Max() += nCount;
382 ++nSubSelPos;
385 // shift the sub selections behind the inserting position
386 for ( size_t nPos = nSubSelPos; nPos < aSels.size(); ++nPos )
388 aSels[ nPos ]->Min() += nCount;
389 aSels[ nPos ]->Max() += nCount;
393 bCurValid = false;
394 aTotRange.Max() += nCount;
395 if ( bSelectNew )
396 nSelCount += nCount;
399 void MultiSelection::Remove( long nIndex )
401 // find the virtual target position
402 size_t nSubSelPos = ImplFindSubSelection( nIndex );
404 // did we remove from an existing sub selection?
405 if ( nSubSelPos < aSels.size()
406 && aSels[ nSubSelPos ]->IsInside(nIndex)
408 // does this sub selection only contain the index to be deleted
409 if ( aSels[ nSubSelPos ]->Len() == 1 ) {
410 // completely remove the sub selection
411 ImpSelList::iterator it = aSels.begin();
412 ::std::advance( it, nSubSelPos );
413 delete *it;
414 aSels.erase( it );
415 } else {
416 // shorten this sub selection
417 --( aSels[ nSubSelPos++ ]->Max() );
420 // adjust the selected counter
421 --nSelCount;
424 // shift the sub selections behind the removed index
425 for ( size_t nPos = nSubSelPos; nPos < aSels.size(); ++nPos )
427 --( aSels[ nPos ]->Min() );
428 --( aSels[ nPos ]->Max() );
431 bCurValid = false;
432 aTotRange.Max() -= 1;
435 long MultiSelection::ImplFwdUnselected()
437 if ( !bCurValid )
438 return SFX_ENDOFSELECTION;
440 if ( ( nCurSubSel < aSels.size() )
441 && ( aSels[ nCurSubSel ]->Min() <= nCurIndex )
443 nCurIndex = aSels[ nCurSubSel++ ]->Max() + 1;
445 if ( nCurIndex <= aTotRange.Max() )
446 return nCurIndex;
447 else
448 return SFX_ENDOFSELECTION;
451 long MultiSelection::FirstSelected( bool bInverse )
453 bInverseCur = bInverse;
454 nCurSubSel = 0;
456 if ( bInverseCur )
458 bCurValid = nSelCount < sal_uIntPtr(aTotRange.Len());
459 if ( bCurValid )
461 nCurIndex = 0;
462 return ImplFwdUnselected();
465 else
467 bCurValid = !aSels.empty();
468 if ( bCurValid )
469 return nCurIndex = aSels[ 0 ]->Min();
472 return SFX_ENDOFSELECTION;
475 long MultiSelection::LastSelected()
477 nCurSubSel = aSels.size() - 1;
478 bCurValid = !aSels.empty();
480 if ( bCurValid )
481 return nCurIndex = aSels[ nCurSubSel ]->Max();
483 return SFX_ENDOFSELECTION;
486 long MultiSelection::NextSelected()
488 if ( !bCurValid )
489 return SFX_ENDOFSELECTION;
491 if ( bInverseCur )
493 ++nCurIndex;
494 return ImplFwdUnselected();
496 else
498 // is the next index in the current sub selection too?
499 if ( nCurIndex < aSels[ nCurSubSel ]->Max() )
500 return ++nCurIndex;
502 // are there further sub selections?
503 if ( ++nCurSubSel < aSels.size() )
504 return nCurIndex = aSels[ nCurSubSel ]->Min();
506 // we are at the end!
507 return SFX_ENDOFSELECTION;
511 void MultiSelection::SetTotalRange( const Range& rTotRange )
513 aTotRange = rTotRange;
515 // adjust lower boundary
516 Range* pRange = aSels.empty() ? NULL : aSels.front();
517 while( pRange )
519 if( pRange->Max() < aTotRange.Min() )
521 delete pRange;
522 aSels.erase( aSels.begin() );
524 else if( pRange->Min() < aTotRange.Min() )
526 pRange->Min() = aTotRange.Min();
527 break;
529 else
530 break;
532 pRange = aSels.empty() ? NULL : aSels.front();
535 // adjust upper boundary
536 size_t nCount = aSels.size();
537 while( nCount )
539 pRange = aSels[ nCount - 1 ];
540 if( pRange->Min() > aTotRange.Max() )
542 delete pRange;
543 aSels.pop_back();
545 else if( pRange->Max() > aTotRange.Max() )
547 pRange->Max() = aTotRange.Max();
548 break;
550 else
551 break;
553 nCount = aSels.size();
556 // re-calculate selection count
557 nSelCount = 0;
558 for ( size_t i = 0, n = aSels.size(); i < n; ++ i )
559 nSelCount += aSels[i]->Len();
561 bCurValid = false;
562 nCurIndex = 0;
565 // StringRangeEnumerator
567 StringRangeEnumerator::StringRangeEnumerator( const OUString& i_rInput,
568 sal_Int32 i_nMinNumber,
569 sal_Int32 i_nMaxNumber,
570 sal_Int32 i_nLogicalOffset
572 : mnCount( 0 )
573 , mnMin( i_nMinNumber )
574 , mnMax( i_nMaxNumber )
575 , mnOffset( i_nLogicalOffset )
576 , mbValidInput( false )
578 // Parse string only if boundaries are valid.
579 if( mnMin >= 0 && mnMax >= 0 && mnMin <= mnMax )
580 mbValidInput = setRange( i_rInput );
583 bool StringRangeEnumerator::checkValue( sal_Int32 i_nValue, const std::set< sal_Int32 >* i_pPossibleValues ) const
585 if( i_nValue < 0 || i_nValue < mnMin || i_nValue > mnMax )
586 return false;
587 if( i_pPossibleValues && i_pPossibleValues->find( i_nValue ) == i_pPossibleValues->end() )
588 return false;
589 return true;
592 bool StringRangeEnumerator::insertRange( sal_Int32 i_nFirst, sal_Int32 i_nLast, bool bSequence, bool bMayAdjust )
594 bool bSuccess = true;
595 if( bSequence )
597 if( bMayAdjust )
599 if( i_nFirst < mnMin )
600 i_nFirst = mnMin;
601 if( i_nFirst > mnMax )
602 i_nFirst = mnMax;
603 if( i_nLast < mnMin )
604 i_nLast = mnMin;
605 if( i_nLast > mnMax )
606 i_nLast = mnMax;
608 if( checkValue( i_nFirst ) && checkValue( i_nLast ) )
610 maSequence.push_back( Range( i_nFirst, i_nLast ) );
611 sal_Int32 nNumber = i_nLast - i_nFirst;
612 nNumber = nNumber < 0 ? -nNumber : nNumber;
613 mnCount += nNumber + 1;
615 else
616 bSuccess = false;
618 else
620 if( checkValue( i_nFirst ) )
622 maSequence.push_back( Range( i_nFirst, i_nFirst ) );
623 mnCount++;
625 else if( checkValue( i_nLast ) )
627 maSequence.push_back( Range( i_nLast, i_nLast ) );
628 mnCount++;
630 else
631 bSuccess = false;
634 return bSuccess;
637 bool StringRangeEnumerator::insertJoinedRanges(
638 const std::vector< sal_Int32 >& rNumbers, bool i_bStrict )
640 size_t nCount = rNumbers.size();
641 if( nCount == 0 )
642 return true;
644 if( nCount == 1 )
645 return insertRange( rNumbers[0], -1, false, ! i_bStrict );
647 for( size_t i = 0; i < nCount - 1; i++ )
649 sal_Int32 nFirst = rNumbers[i];
650 sal_Int32 nLast = rNumbers[i + 1];
651 if( i > 0 )
653 if ( nFirst > nLast ) nFirst--;
654 else if( nFirst < nLast ) nFirst++;
657 if ( ! insertRange( nFirst, nLast, nFirst != nLast, ! i_bStrict ) && i_bStrict)
658 return false;
661 return true;
664 bool StringRangeEnumerator::setRange( const OUString& i_rNewRange, bool i_bStrict )
666 mnCount = 0;
667 maSequence.clear();
669 const sal_Unicode* pInput = i_rNewRange.getStr();
670 OUStringBuffer aNumberBuf( 16 );
671 std::vector< sal_Int32 > aNumbers;
672 bool bSequence = false;
673 while( *pInput )
675 while( *pInput >= '0' && *pInput <= '9' )
676 aNumberBuf.append( *pInput++ );
677 if( !aNumberBuf.isEmpty() )
679 sal_Int32 nNumber = aNumberBuf.makeStringAndClear().toInt32() + mnOffset;
680 aNumbers.push_back( nNumber );
681 bSequence = false;
684 if( *pInput == '-' )
686 bSequence = true;
687 if( aNumbers.empty() )
688 aNumbers.push_back( mnMin );
690 else if( *pInput == ',' || *pInput == ';' )
692 if( bSequence && !aNumbers.empty() )
693 aNumbers.push_back( mnMax );
694 if( ! insertJoinedRanges( aNumbers, i_bStrict ) && i_bStrict )
695 return false;
697 aNumbers.clear();
698 bSequence = false;
700 else if( *pInput && *pInput != ' ' )
701 return false; // parse error
703 if( *pInput )
704 pInput++;
706 // insert last entries
707 if( bSequence && !aNumbers.empty() )
708 aNumbers.push_back( mnMax );
709 if( ! insertJoinedRanges( aNumbers, i_bStrict ) && i_bStrict )
710 return false;
712 return true;
715 bool StringRangeEnumerator::hasValue( sal_Int32 i_nValue, const std::set< sal_Int32 >* i_pPossibleValues ) const
717 if( i_pPossibleValues && i_pPossibleValues->find( i_nValue ) == i_pPossibleValues->end() )
718 return false;
719 size_t n = maSequence.size();
720 for( size_t i= 0; i < n; ++i )
722 const StringRangeEnumerator::Range rRange( maSequence[i] );
723 if( rRange.nFirst < rRange.nLast )
725 if( i_nValue >= rRange.nFirst && i_nValue <= rRange.nLast )
726 return true;
728 else
730 if( i_nValue >= rRange.nLast && i_nValue <= rRange.nFirst )
731 return true;
734 return false;
737 StringRangeEnumerator::Iterator& StringRangeEnumerator::Iterator::operator++()
739 if( nRangeIndex >= 0 && nCurrent >= 0 && pEnumerator )
741 const StringRangeEnumerator::Range& rRange( pEnumerator->maSequence[nRangeIndex] );
742 bool bRangeChange = false;
743 if( rRange.nLast < rRange.nFirst )
745 // backward range
746 if( nCurrent > rRange.nLast )
747 nCurrent--;
748 else
749 bRangeChange = true;
751 else
753 // forward range
754 if( nCurrent < rRange.nLast )
755 nCurrent++;
756 else
757 bRangeChange = true;
759 if( bRangeChange )
761 nRangeIndex++;
762 if( size_t(nRangeIndex) == pEnumerator->maSequence.size() )
764 // reached the end
765 nRangeIndex = nCurrent = -1;
767 else
768 nCurrent = pEnumerator->maSequence[nRangeIndex].nFirst;
770 if( nRangeIndex != -1 && nCurrent != -1 )
772 if( ! pEnumerator->checkValue( nCurrent, pPossibleValues ) )
773 return ++(*this);
776 return *this;
780 bool StringRangeEnumerator::Iterator::operator==( const Iterator& i_rCompare ) const
782 return i_rCompare.pEnumerator == pEnumerator && i_rCompare.nRangeIndex == nRangeIndex && i_rCompare.nCurrent == nCurrent;
785 StringRangeEnumerator::Iterator StringRangeEnumerator::begin( const std::set< sal_Int32 >* i_pPossibleValues ) const
787 StringRangeEnumerator::Iterator it( this,
788 i_pPossibleValues,
789 maSequence.empty() ? -1 : 0,
790 maSequence.empty() ? -1 : maSequence[0].nFirst );
791 if( ! checkValue(*it, i_pPossibleValues ) )
792 ++it;
793 return it;
796 StringRangeEnumerator::Iterator StringRangeEnumerator::end( const std::set< sal_Int32 >* i_pPossibleValues ) const
798 return StringRangeEnumerator::Iterator( this, i_pPossibleValues, -1, -1 );
801 bool StringRangeEnumerator::getRangesFromString( const OUString& i_rPageRange,
802 std::vector< sal_Int32 >& o_rPageVector,
803 sal_Int32 i_nMinNumber,
804 sal_Int32 i_nMaxNumber,
805 sal_Int32 i_nLogicalOffset,
806 std::set< sal_Int32 >* i_pPossibleValues
809 o_rPageVector.clear();
811 StringRangeEnumerator aEnum( i_rPageRange, i_nMinNumber, i_nMaxNumber, i_nLogicalOffset ) ;
813 //Even if the input range wasn't completely valid, return what ranges could
814 //be extracted from the input.
815 o_rPageVector.reserve( static_cast< size_t >( aEnum.size() ) );
816 for( StringRangeEnumerator::Iterator it = aEnum.begin( i_pPossibleValues );
817 it != aEnum.end( i_pPossibleValues ); ++it )
819 o_rPageVector.push_back( *it );
822 return aEnum.isValidInput();
825 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */