LibreOffice Module tools (master) 1
multisel.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <cstddef>
23
24#include <o3tl/string_view.hxx>
25#include <tools/debug.hxx>
26#include <tools/multisel.hxx>
27
28#include <rtl/ustrbuf.hxx>
29
31{
32 // no selected indexes
33 nSelCount = 0;
34 aSels.clear();
35}
36
37std::size_t MultiSelection::ImplFindSubSelection( sal_Int32 nIndex ) const
38{
39 // iterate through the sub selections
40 std::size_t n = 0;
41 for ( ;
42 n < aSels.size() && nIndex > aSels[ n ].Max();
43 ++n ) {} /* empty loop */
44 return n;
45}
46
47void MultiSelection::ImplMergeSubSelections( sal_Int32 nPos1, std::size_t nPos2 )
48{
49 // didn't a sub selection at nPos2 exist?
50 if ( nPos2 >= aSels.size() )
51 return;
52
53 // did the sub selections touch each other?
54 if ( (aSels[ nPos1 ].Max() + 1) == aSels[ nPos2 ].Min() )
55 {
56 // merge them
57 aSels[ nPos1 ].Max() = aSels[ nPos2 ].Max();
58 aSels.erase( aSels.begin() + nPos2 );
59 }
60}
61
63 aTotRange( 0, -1 ),
64 nCurSubSel(0),
65 nCurIndex(0),
66 nSelCount(0),
67 bCurValid(false)
68{
69}
70
72{
73 aTotRange = Range(0, -1);
74 bCurValid = false;
75 // clear the old sub selections
76 ImplClear();
77}
78
80 aTotRange(rOrig.aTotRange),
81 nSelCount(rOrig.nSelCount),
82 bCurValid(rOrig.bCurValid)
83{
84 if ( bCurValid )
85 {
86 nCurSubSel = rOrig.nCurSubSel;
87 nCurIndex = rOrig.nCurIndex;
88 }
89 else
90 {
91 nCurSubSel = 0;
92 nCurIndex = 0;
93 }
94
95 // copy the sub selections
96 aSels.insert( aSels.end(), rOrig.aSels.begin(), rOrig.aSels.end() );
97}
98
100 aTotRange(rRange),
101 nCurSubSel(0),
102 nCurIndex(0),
103 nSelCount(0),
104 bCurValid(false)
105{
106}
107
109{
110}
111
113{
114 aTotRange = rOrig.aTotRange;
115 bCurValid = rOrig.bCurValid;
116 if ( bCurValid )
117 {
118 nCurSubSel = rOrig.nCurSubSel;
119 nCurIndex = rOrig.nCurIndex;
120 }
121
122 // clear the old and copy the sub selections
123 ImplClear();
124 aSels.insert( aSels.end(), rOrig.aSels.begin(), rOrig.aSels.end() );
125 nSelCount = rOrig.nSelCount;
126
127 return *this;
128}
129
130void MultiSelection::SelectAll( bool bSelect )
131{
132 ImplClear();
133 if ( bSelect )
134 {
135 aSels.push_back( aTotRange );
137 }
138}
139
140bool MultiSelection::Select( sal_Int32 nIndex, bool bSelect )
141{
142 DBG_ASSERT( aTotRange.Contains(nIndex), "selected index out of range" );
143
144 // out of range?
145 if ( !aTotRange.Contains(nIndex) )
146 return false;
147
148 // find the virtual target position
149 std::size_t nSubSelPos = ImplFindSubSelection( nIndex );
150
151 if ( bSelect )
152 {
153 // is it included in the found sub selection?
154 if ( nSubSelPos < aSels.size() && aSels[ nSubSelPos ].Contains( nIndex ) )
155 // already selected, nothing to do
156 return false;
157
158 // it will become selected
159 ++nSelCount;
160
161 // is it at the end of the previous sub selection
162 if ( nSubSelPos > 0 &&
163 aSels[ nSubSelPos-1 ].Max() == (nIndex-1) )
164 {
165 // expand the previous sub selection
166 aSels[ nSubSelPos-1 ].Max() = nIndex;
167
168 // try to merge the previous sub selection
169 ImplMergeSubSelections( nSubSelPos-1, nSubSelPos );
170 }
171 // is it at the beginning of the found sub selection
172 else if ( nSubSelPos < aSels.size()
173 && aSels[ nSubSelPos ].Min() == (nIndex+1)
174 )
175 // expand the found sub selection
176 aSels[ nSubSelPos ].Min() = nIndex;
177 else
178 {
179 // create a new sub selection
180 if ( nSubSelPos < aSels.size() ) {
181 aSels.insert( aSels.begin() + nSubSelPos, Range( nIndex, nIndex ) );
182 } else {
183 aSels.push_back( Range( nIndex, nIndex ) );
184 }
185 if ( bCurValid && nCurSubSel >= nSubSelPos )
186 ++nCurSubSel;
187 }
188 }
189 else
190 {
191 // is it excluded from the found sub selection?
192 if ( nSubSelPos >= aSels.size()
193 || !aSels[ nSubSelPos ].Contains( nIndex )
194 ) {
195 // not selected, nothing to do
196 return false;
197 }
198
199 // it will become deselected
200 --nSelCount;
201
202 // is it the only index in the found sub selection?
203 if ( aSels[ nSubSelPos ].Len() == 1 )
204 {
205 // remove the complete sub selection
206 aSels.erase( aSels.begin() + nSubSelPos );
207 return true;
208 }
209
210 // is it at the beginning of the found sub selection?
211 if ( aSels[ nSubSelPos ].Min() == nIndex )
212 ++aSels[ nSubSelPos ].Min();
213 // is it at the end of the found sub selection?
214 else if ( aSels[ nSubSelPos ].Max() == nIndex )
215 --aSels[ nSubSelPos ].Max();
216 // it is in the middle of the found sub selection?
217 else
218 {
219 // split the sub selection
220 if ( nSubSelPos < aSels.size() ) {
221 aSels.insert( aSels.begin() + nSubSelPos, Range( aSels[ nSubSelPos ].Min(), nIndex-1 ) );
222 } else {
223 aSels.push_back( Range( aSels[ nSubSelPos ].Min(), nIndex-1 ) );
224 }
225 aSels[ nSubSelPos+1 ].Min() = nIndex + 1;
226 }
227 }
228
229 return true;
230}
231
232void MultiSelection::Select( const Range& rIndexRange, bool bSelect )
233{
234 sal_Int32 nOld;
235
236 sal_Int32 nTmpMin = rIndexRange.Min();
237 sal_Int32 nTmpMax = rIndexRange.Max();
238 sal_Int32 nCurMin = FirstSelected();
239 sal_Int32 nCurMax = LastSelected();
240 DBG_ASSERT(aTotRange.Contains(nTmpMax), "selected index out of range" );
241 DBG_ASSERT(aTotRange.Contains(nTmpMin), "selected index out of range" );
242
243 // replace whole selection?
244 if( aSels.empty() || (nTmpMin <= nCurMin && nTmpMax >= nCurMax ) )
245 {
246 ImplClear();
247 if ( bSelect )
248 {
249 aSels.push_back( rIndexRange );
250 nSelCount = rIndexRange.Len();
251 }
252 return;
253 }
254 // expand on left side?
255 if( nTmpMax < nCurMin )
256 {
257 if( bSelect )
258 {
259 // extend first range?
260 if( nCurMin > (nTmpMax+1) )
261 {
262 aSels.insert( aSels.begin(), rIndexRange );
263 nSelCount += rIndexRange.Len();
264 }
265 else
266 {
267 auto & rRange = aSels.front();
268 nOld = rRange.Min();
269 rRange.Min() = nTmpMin;
270 nSelCount += ( nOld - nTmpMin );
271 }
272 bCurValid = false;
273 }
274 return;
275 }
276 // expand on right side?
277 else if( nTmpMin > nCurMax )
278 {
279 if( bSelect )
280 {
281 // extend last range?
282 if( nTmpMin > (nCurMax+1) )
283 {
284 aSels.push_back( rIndexRange );
285 nSelCount += rIndexRange.Len();
286 }
287 else
288 {
289 auto & rRange = aSels.back();
290 nOld = rRange.Max();
291 rRange.Max() = nTmpMax;
292 nSelCount += ( nTmpMax - nOld );
293 }
294 bCurValid = false;
295 }
296 return;
297 }
298
299 // TODO here is potential for optimization
300 while( nTmpMin <= nTmpMax )
301 {
302 Select( nTmpMin, bSelect );
303 nTmpMin++;
304 }
305}
306
307bool MultiSelection::IsSelected( sal_Int32 nIndex ) const
308{
309 // find the virtual target position
310 std::size_t nSubSelPos = ImplFindSubSelection( nIndex );
311
312 return nSubSelPos < aSels.size() && aSels[ nSubSelPos ].Contains(nIndex);
313}
314
315void MultiSelection::Insert( sal_Int32 nIndex, sal_Int32 nCount )
316{
317 // find the virtual target position
318 std::size_t nSubSelPos = ImplFindSubSelection( nIndex );
319
320 // did we need to shift the sub selections?
321 if ( nSubSelPos < aSels.size() )
322 { // did we insert an unselected into an existing sub selection?
323 if ( aSels[ nSubSelPos ].Min() != nIndex
324 && aSels[ nSubSelPos ].Contains(nIndex)
325 ) { // split the sub selection
326 if ( nSubSelPos < aSels.size() ) {
327 aSels.insert( aSels.begin() + nSubSelPos, Range( aSels[ nSubSelPos ].Min(), nIndex-1 ) );
328 } else {
329 aSels.push_back( Range( aSels[ nSubSelPos ].Min(), nIndex-1 ) );
330 }
331 ++nSubSelPos;
332 aSels[ nSubSelPos ].Min() = nIndex;
333 }
334
335 // shift the sub selections behind the inserting position
336 for ( std::size_t nPos = nSubSelPos; nPos < aSels.size(); ++nPos )
337 {
338 aSels[ nPos ].Min() += nCount;
339 aSels[ nPos ].Max() += nCount;
340 }
341 }
342
343 bCurValid = false;
344 aTotRange.Max() += nCount;
345}
346
347void MultiSelection::Remove( sal_Int32 nIndex )
348{
349 // find the virtual target position
350 std::size_t nSubSelPos = ImplFindSubSelection( nIndex );
351
352 // did we remove from an existing sub selection?
353 if ( nSubSelPos < aSels.size()
354 && aSels[ nSubSelPos ].Contains(nIndex)
355 ) {
356 // does this sub selection only contain the index to be deleted
357 if ( aSels[ nSubSelPos ].Len() == 1 ) {
358 // completely remove the sub selection
359 aSels.erase( aSels.begin() + nSubSelPos );
360 } else {
361 // shorten this sub selection
362 --( aSels[ nSubSelPos++ ].Max() );
363 }
364
365 // adjust the selected counter
366 --nSelCount;
367 }
368
369 // shift the sub selections behind the removed index
370 for ( std::size_t nPos = nSubSelPos; nPos < aSels.size(); ++nPos )
371 {
372 --( aSels[ nPos ].Min() );
373 --( aSels[ nPos ].Max() );
374 }
375
376 bCurValid = false;
377 aTotRange.Max() -= 1;
378}
379
381{
382 nCurSubSel = 0;
383
384 bCurValid = !aSels.empty();
385 if ( !bCurValid )
386 return SFX_ENDOFSELECTION;
387
388 nCurIndex = aSels[ 0 ].Min();
389 return nCurIndex;
390}
391
393{
394 bCurValid = !aSels.empty();
395
396 if ( !bCurValid )
397 return SFX_ENDOFSELECTION;
398
399 nCurSubSel = aSels.size() - 1;
400 nCurIndex = aSels[ nCurSubSel ].Max();
401 return nCurIndex;
402}
403
405{
406 if ( !bCurValid )
407 return SFX_ENDOFSELECTION;
408
409 // is the next index in the current sub selection too?
410 if ( nCurIndex < aSels[ nCurSubSel ].Max() )
411 return ++nCurIndex;
412
413 // are there further sub selections?
414 if ( ++nCurSubSel >= aSels.size() )
415 // we are at the end!
416 return SFX_ENDOFSELECTION;
417
418 nCurIndex = aSels[ nCurSubSel ].Min();
419 return nCurIndex;
420}
421
422void MultiSelection::SetTotalRange( const Range& rTotRange )
423{
424 aTotRange = rTotRange;
425
426 // adjust lower boundary
427 Range* pRange = aSels.empty() ? nullptr : &aSels.front();
428 while( pRange )
429 {
430 if( pRange->Max() < aTotRange.Min() )
431 {
432 aSels.erase( aSels.begin() );
433 }
434 else if( pRange->Min() < aTotRange.Min() )
435 {
436 pRange->Min() = aTotRange.Min();
437 break;
438 }
439 else
440 break;
441
442 pRange = aSels.empty() ? nullptr : &aSels.front();
443 }
444
445 // adjust upper boundary
446 sal_Int32 nCount = aSels.size();
447 while( nCount )
448 {
449 pRange = &aSels[ nCount - 1 ];
450 if( pRange->Min() > aTotRange.Max() )
451 {
452 aSels.pop_back();
453 }
454 else if( pRange->Max() > aTotRange.Max() )
455 {
456 pRange->Max() = aTotRange.Max();
457 break;
458 }
459 else
460 break;
461
462 nCount = aSels.size();
463 }
464
465 // re-calculate selection count
466 nSelCount = 0;
467 for (Range const & rSel : aSels)
468 nSelCount += rSel.Len();
469
470 bCurValid = false;
471 nCurIndex = 0;
472}
473
474// StringRangeEnumerator
475
477 sal_Int32 i_nMinNumber,
478 sal_Int32 i_nMaxNumber,
479 sal_Int32 i_nLogicalOffset
480 )
481 : mnCount( 0 )
482 , mnMin( i_nMinNumber )
483 , mnMax( i_nMaxNumber )
484 , mnOffset( i_nLogicalOffset )
485 , mbValidInput( false )
486{
487 // Parse string only if boundaries are valid.
488 if( mnMin >= 0 && mnMax >= 0 && mnMin <= mnMax )
489 mbValidInput = setRange( i_rInput );
490}
491
492bool StringRangeEnumerator::checkValue( sal_Int32 i_nValue, const o3tl::sorted_vector< sal_Int32 >* i_pPossibleValues ) const
493{
494 if( i_nValue < 0 || i_nValue < mnMin || i_nValue > mnMax )
495 return false;
496 if( i_pPossibleValues && i_pPossibleValues->find( i_nValue ) == i_pPossibleValues->end() )
497 return false;
498 return true;
499}
500
501bool StringRangeEnumerator::insertRange( sal_Int32 i_nFirst, sal_Int32 i_nLast, bool bSequence )
502{
503 bool bSuccess = true;
504 if( bSequence )
505 {
506 // Check if the range is completely outside of possible pages range
507 if ((i_nFirst < mnMin && i_nLast < mnMin) ||
508 (i_nFirst > mnMax && i_nLast > mnMax))
509 return false;
510 if( i_nFirst < mnMin )
511 i_nFirst = mnMin;
512 if( i_nFirst > mnMax )
513 i_nFirst = mnMax;
514 if( i_nLast < mnMin )
515 i_nLast = mnMin;
516 if( i_nLast > mnMax )
517 i_nLast = mnMax;
518 if( checkValue( i_nFirst ) && checkValue( i_nLast ) )
519 {
520 maSequence.push_back( Range( i_nFirst, i_nLast ) );
521 sal_Int32 nNumber = i_nLast - i_nFirst;
522 nNumber = nNumber < 0 ? -nNumber : nNumber;
523 mnCount += nNumber + 1;
524 }
525 else
526 bSuccess = false;
527 }
528 else
529 {
530 if( checkValue( i_nFirst ) )
531 {
532 maSequence.push_back( Range( i_nFirst, i_nFirst ) );
533 mnCount++;
534 }
535 else if( checkValue( i_nLast ) )
536 {
537 maSequence.push_back( Range( i_nLast, i_nLast ) );
538 mnCount++;
539 }
540 else
541 bSuccess = false;
542 }
543
544 return bSuccess;
545}
546
548 const std::vector< sal_Int32 >& rNumbers )
549{
550 size_t nCount = rNumbers.size();
551 if( nCount == 0 )
552 return;
553
554 if( nCount == 1 )
555 {
556 insertRange( rNumbers[0], -1, false );
557 return;
558 }
559
560 for( size_t i = 0; i < nCount - 1; i++ )
561 {
562 sal_Int32 nFirst = rNumbers[i];
563 sal_Int32 nLast = rNumbers[i + 1];
564 if( i > 0 )
565 {
566 if ( nFirst > nLast ) nFirst--;
567 else if( nFirst < nLast ) nFirst++;
568 }
569
570 insertRange( nFirst, nLast, nFirst != nLast );
571 }
572}
573
574bool StringRangeEnumerator::setRange( std::u16string_view aNewRange )
575{
576 mnCount = 0;
577 maSequence.clear();
578
579 auto pInput = aNewRange.begin();
580 auto pInputEnd = aNewRange.end();
581 OUStringBuffer aNumberBuf( 16 );
582 std::vector< sal_Int32 > aNumbers;
583 bool bSequence = false;
584 while( pInput != pInputEnd )
585 {
586 while( pInput != pInputEnd && *pInput >= '0' && *pInput <= '9' )
587 aNumberBuf.append( *pInput++ );
588 if( !aNumberBuf.isEmpty() )
589 {
590 sal_Int32 nNumber = o3tl::toInt32(aNumberBuf) + mnOffset;
591 aNumberBuf.setLength(0);
592 aNumbers.push_back( nNumber );
593 bSequence = false;
594 }
595 if (pInput == pInputEnd)
596 break;
597 if( *pInput == '-' )
598 {
599 bSequence = true;
600 if( aNumbers.empty() )
601 {
602 // push out-of-range small value, to exclude ranges totally outside of possible range
603 aNumbers.push_back( mnMin-1 );
604 }
605 }
606 else if( *pInput == ',' || *pInput == ';' )
607 {
608 if( bSequence && !aNumbers.empty() )
609 {
610 // push out-of-range large value, to exclude ranges totally outside of possible range
611 aNumbers.push_back( mnMax+1 );
612 }
613 insertJoinedRanges( aNumbers );
614
615 aNumbers.clear();
616 bSequence = false;
617 }
618 else if( *pInput != ' ' )
619 return false; // parse error
620
621 pInput++;
622 }
623 // insert last entries
624 if( bSequence && !aNumbers.empty() )
625 {
626 // push out-of-range large value, to exclude ranges totally outside of possible range
627 aNumbers.push_back( mnMax+1 );
628 }
629 insertJoinedRanges( aNumbers );
630
631 return true;
632}
633
634bool StringRangeEnumerator::hasValue( sal_Int32 i_nValue, const o3tl::sorted_vector< sal_Int32 >* i_pPossibleValues ) const
635{
636 if( i_pPossibleValues && i_pPossibleValues->find( i_nValue ) == i_pPossibleValues->end() )
637 return false;
638 size_t n = maSequence.size();
639 for( size_t i= 0; i < n; ++i )
640 {
642 if( rRange.nFirst < rRange.nLast )
643 {
644 if( i_nValue >= rRange.nFirst && i_nValue <= rRange.nLast )
645 return true;
646 }
647 else
648 {
649 if( i_nValue >= rRange.nLast && i_nValue <= rRange.nFirst )
650 return true;
651 }
652 }
653 return false;
654}
655
657{
658 if( nRangeIndex >= 0 && nCurrent >= 0 && pEnumerator )
659 {
661 bool bRangeChange = false;
662 if( rRange.nLast < rRange.nFirst )
663 {
664 // backward range
665 if( nCurrent > rRange.nLast )
666 nCurrent--;
667 else
668 bRangeChange = true;
669 }
670 else
671 {
672 // forward range
673 if( nCurrent < rRange.nLast )
674 nCurrent++;
675 else
676 bRangeChange = true;
677 }
678 if( bRangeChange )
679 {
680 nRangeIndex++;
681 if( size_t(nRangeIndex) == pEnumerator->maSequence.size() )
682 {
683 // reached the end
684 nRangeIndex = nCurrent = -1;
685 }
686 else
688 }
689 if( nRangeIndex != -1 && nCurrent != -1 )
690 {
692 return ++(*this);
693 }
694 }
695 return *this;
696}
697
698
700{
701 return i_rCompare.pEnumerator == pEnumerator && i_rCompare.nRangeIndex == nRangeIndex && i_rCompare.nCurrent == nCurrent;
702}
703
705{
707 i_pPossibleValues,
708 maSequence.empty() ? -1 : 0,
709 maSequence.empty() ? -1 : maSequence[0].nFirst );
710 if( ! checkValue(*it, i_pPossibleValues ) )
711 ++it;
712 return it;
713}
714
716{
717 return StringRangeEnumerator::Iterator( this, i_pPossibleValues, -1, -1 );
718}
719
720bool StringRangeEnumerator::getRangesFromString( std::u16string_view i_rPageRange,
721 std::vector< sal_Int32 >& o_rPageVector,
722 sal_Int32 i_nMinNumber,
723 sal_Int32 i_nMaxNumber,
724 sal_Int32 i_nLogicalOffset,
725 o3tl::sorted_vector< sal_Int32 > const * i_pPossibleValues
726 )
727{
728 o_rPageVector.clear();
729
730 StringRangeEnumerator aEnum( i_rPageRange, i_nMinNumber, i_nMaxNumber, i_nLogicalOffset ) ;
731
732 //Even if the input range wasn't completely valid, return what ranges could
733 //be extracted from the input.
734 o_rPageVector.reserve( static_cast< size_t >( aEnum.size() ) );
735 for( StringRangeEnumerator::Iterator it = aEnum.begin( i_pPossibleValues );
736 it != aEnum.end( i_pPossibleValues ); ++it )
737 {
738 o_rPageVector.push_back( *it );
739 }
740
741 return aEnum.mbValidInput;
742}
743
744/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void Remove(sal_Int32 nIndex)
Definition: multisel.cxx:347
void Insert(sal_Int32 nIndex, sal_Int32 nCount=1)
Definition: multisel.cxx:315
TOOLS_DLLPRIVATE void ImplClear()
Definition: multisel.cxx:30
Range aTotRange
Definition: multisel.hxx:37
void Reset()
Definition: multisel.cxx:71
sal_Int32 FirstSelected()
Definition: multisel.cxx:380
TOOLS_DLLPRIVATE void ImplMergeSubSelections(sal_Int32 nPos1, std::size_t nPos2)
Definition: multisel.cxx:47
sal_Int32 LastSelected()
Definition: multisel.cxx:392
sal_Int32 NextSelected()
Definition: multisel.cxx:404
MultiSelection & operator=(const MultiSelection &rOrig)
Definition: multisel.cxx:112
std::size_t nCurSubSel
Definition: multisel.hxx:38
bool Select(sal_Int32 nIndex, bool bSelect=true)
Definition: multisel.cxx:140
void SetTotalRange(const Range &rTotRange)
Definition: multisel.cxx:422
bool IsSelected(sal_Int32 nIndex) const
Definition: multisel.cxx:307
sal_Int32 nCurIndex
Definition: multisel.hxx:39
std::vector< Range > aSels
Definition: multisel.hxx:36
TOOLS_DLLPRIVATE std::size_t ImplFindSubSelection(sal_Int32 nIndex) const
Definition: multisel.cxx:37
void SelectAll(bool bSelect=true)
Definition: multisel.cxx:130
sal_Int32 nSelCount
Definition: multisel.hxx:40
Definition: gen.hxx:351
tools::Long Max() const
Definition: gen.hxx:357
tools::Long Len() const
Definition: gen.hxx:358
tools::Long Min() const
Definition: gen.hxx:356
bool Contains(tools::Long nIs) const
Definition: gen.hxx:373
const o3tl::sorted_vector< sal_Int32 > * pPossibleValues
Definition: multisel.hxx:101
const StringRangeEnumerator * pEnumerator
Definition: multisel.hxx:100
bool operator==(const Iterator &) const
Definition: multisel.cxx:699
void insertJoinedRanges(const std::vector< sal_Int32 > &rNumbers)
Definition: multisel.cxx:547
bool setRange(std::u16string_view i_rNewRange)
Definition: multisel.cxx:574
bool checkValue(sal_Int32, const o3tl::sorted_vector< sal_Int32 > *i_pPossibleValues=nullptr) const
Definition: multisel.cxx:492
bool hasValue(sal_Int32 nValue, const o3tl::sorted_vector< sal_Int32 > *i_pPossibleValues=nullptr) const
Definition: multisel.cxx:634
bool insertRange(sal_Int32 nFirst, sal_Int32 nLast, bool bSequence)
Definition: multisel.cxx:501
sal_Int32 size() const
Definition: multisel.hxx:129
static bool getRangesFromString(std::u16string_view i_rPageRange, std::vector< sal_Int32 > &o_rPageVector, sal_Int32 i_nMinNumber, sal_Int32 i_nMaxNumber, sal_Int32 i_nLogicalOffset=-1, o3tl::sorted_vector< sal_Int32 > const *i_pPossibleValues=nullptr)
i_rPageRange: the string to be changed into a sequence of numbers valid format example "5-3,...
Definition: multisel.cxx:720
std::vector< StringRangeEnumerator::Range > maSequence
Definition: multisel.hxx:86
Iterator end(const o3tl::sorted_vector< sal_Int32 > *i_pPossibleValues=nullptr) const
Definition: multisel.cxx:715
StringRangeEnumerator(std::u16string_view i_rInput, sal_Int32 i_nMinNumber, sal_Int32 i_nMaxNumber, sal_Int32 i_nLogicalOffset=-1)
Definition: multisel.cxx:476
Iterator begin(const o3tl::sorted_vector< sal_Int32 > *i_pPossibleValues=nullptr) const
Definition: multisel.cxx:704
const_iterator find(const Value &x) const
const_iterator end() const
int nCount
#define DBG_ASSERT(sCon, aError)
Definition: debug.hxx:57
std::size_t mnCount
sal_Int32 nIndex
sal_Int64 n
sal_uInt16 nPos
#define SFX_ENDOFSELECTION
Definition: multisel.hxx:30
int i
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)