xref: /trunk/main/tools/inc/tools/multisel.hxx (revision 8b851043)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #ifndef _SV_MULTISEL_HXX
24 #define _SV_MULTISEL_HXX
25 
26 #include "tools/toolsdllapi.h"
27 #include <tools/gen.hxx>
28 #include <tools/list.hxx>
29 #include <tools/string.hxx>
30 
31 #include <vector>
32 #include <set>
33 
34 //------------------------------------------------------------------
35 
36 #ifdef _SV_MULTISEL_CXX
37 DECLARE_LIST( ImpSelList, Range* )
38 #else
39 #define ImpSelList List
40 #endif
41 
42 #define SFX_ENDOFSELECTION		CONTAINER_ENTRY_NOTFOUND
43 
44 //------------------------------------------------------------------
45 
46 // ------------------
47 // - MultiSelection -
48 // ------------------
49 
50 class TOOLS_DLLPUBLIC MultiSelection
51 {
52 private:
53 	ImpSelList		aSels;		// array of SV-selections
54 	Range			aTotRange;	// total range of indexes
55 	sal_uIntPtr			nCurSubSel; // index in aSels of current selected index
56 	long			nCurIndex;	// current selected entry
57 	sal_uIntPtr			nSelCount;	// number of selected indexes
58 	sal_Bool			bInverseCur;// inverse cursor
59 	sal_Bool			bCurValid;	// are nCurIndex and nCurSubSel valid
60 	sal_Bool			bSelectNew; // auto-select newly inserted indexes
61 
62 #ifdef _SV_MULTISEL_CXX
63 	TOOLS_DLLPRIVATE void			ImplClear();
64 	TOOLS_DLLPRIVATE sal_uIntPtr			ImplFindSubSelection( long nIndex ) const;
65 	TOOLS_DLLPRIVATE sal_Bool			ImplMergeSubSelections( sal_uIntPtr nPos1, sal_uIntPtr nPos2 );
66 	TOOLS_DLLPRIVATE long			ImplFwdUnselected();
67 	TOOLS_DLLPRIVATE long			ImplBwdUnselected();
68 #endif
69 
70 public:
71 					MultiSelection();
72 					MultiSelection( const MultiSelection& rOrig );
73 					MultiSelection( const Range& rRange );
74 					MultiSelection( const UniString& rString,
75 									sal_Unicode cRange = '-',
76 									sal_Unicode cSep = ';' );
77 					~MultiSelection();
78 
79 	MultiSelection& operator= ( const MultiSelection& rOrig );
80 	sal_Bool			operator== ( MultiSelection& rOrig );
operator !=(MultiSelection & rOrig)81 	sal_Bool			operator!= ( MultiSelection& rOrig )
82 						{ return !operator==( rOrig ); }
operator !() const83 	sal_Bool			operator !() const
84 						{ return nSelCount == 0; }
85 
86 	void			SelectAll( sal_Bool bSelect = sal_True );
87 	sal_Bool			Select( long nIndex, sal_Bool bSelect = sal_True );
88 	void			Select( const Range& rIndexRange, sal_Bool bSelect = sal_True );
89 	sal_Bool			IsSelected( long nIndex ) const;
IsAllSelected() const90 	sal_Bool			IsAllSelected() const
91 						{ return nSelCount == sal_uIntPtr(aTotRange.Len()); }
GetSelectCount() const92 	long			GetSelectCount() const { return nSelCount; }
93 
94 	void			SetTotalRange( const Range& rTotRange );
95 	void			Insert( long nIndex, long nCount = 1 );
96 	void			Remove( long nIndex );
97 	void			Append( long nCount = 1 );
98 
GetTotalRange() const99 	const Range&	GetTotalRange() const { return aTotRange; }
IsCurValid() const100 	sal_Bool			IsCurValid() const { return bCurValid; }
GetCurSelected() const101 	long			GetCurSelected() const { return nCurIndex; }
102 	long			FirstSelected( sal_Bool bInverse = sal_False );
103 	long			LastSelected();
104 	long			NextSelected();
105 	long			PrevSelected();
106 
GetRangeCount() const107 	sal_uIntPtr			GetRangeCount() const { return aSels.Count(); }
GetRange(sal_uIntPtr nRange) const108 	const Range&	GetRange( sal_uIntPtr nRange ) const { return *(const Range*)aSels.GetObject(nRange); }
109 };
110 
111 class TOOLS_DLLPUBLIC StringRangeEnumerator
112 {
113     struct Range
114     {
115         sal_Int32   nFirst;
116         sal_Int32   nLast;
117 
RangeStringRangeEnumerator::Range118         Range() : nFirst( -1 ), nLast( -1 ) {}
RangeStringRangeEnumerator::Range119         Range( sal_Int32 i_nFirst, sal_Int32 i_nLast ) : nFirst( i_nFirst ), nLast( i_nLast ) {}
120     };
121     std::vector< StringRangeEnumerator::Range >            maSequence;
122     sal_Int32                                              mnCount;
123     sal_Int32                                              mnMin;
124     sal_Int32                                              mnMax;
125     sal_Int32                                              mnOffset;
126 
127     bool insertRange( sal_Int32 nFirst, sal_Int32 nLast, bool bSequence, bool bMayAdjust );
128     bool checkValue( sal_Int32, const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const;
129 public:
130     class TOOLS_DLLPUBLIC Iterator
131     {
132         const StringRangeEnumerator*      pEnumerator;
133         const std::set< sal_Int32 >*      pPossibleValues;
134         sal_Int32                         nRangeIndex;
135         sal_Int32                         nCurrent;
136 
137         friend class StringRangeEnumerator;
Iterator(const StringRangeEnumerator * i_pEnum,const std::set<sal_Int32> * i_pPossibleValues,sal_Int32 i_nRange,sal_Int32 i_nCurrent)138         Iterator( const StringRangeEnumerator* i_pEnum,
139                   const std::set< sal_Int32 >* i_pPossibleValues,
140                   sal_Int32 i_nRange,
141                   sal_Int32 i_nCurrent )
142         : pEnumerator( i_pEnum ), pPossibleValues( i_pPossibleValues )
143         , nRangeIndex( i_nRange ), nCurrent( i_nCurrent ) {}
144     public:
Iterator()145         Iterator() : pEnumerator( NULL ), pPossibleValues( NULL ), nRangeIndex( -1 ), nCurrent( -1 ) {}
146         Iterator& operator++();
147         sal_Int32 operator*() const;
148         bool operator==(const Iterator&) const;
operator !=(const Iterator & i_rComp) const149         bool operator!=(const Iterator& i_rComp) const
150         { return ! (*this == i_rComp); }
151     };
152 
153     friend class StringRangeEnumerator::Iterator;
154 
StringRangeEnumerator()155     StringRangeEnumerator() : mnCount( 0 ), mnMin( -1 ), mnMax( -1 ), mnOffset( -1 ) {}
156     StringRangeEnumerator( const rtl::OUString& i_rInput,
157                            sal_Int32 i_nMinNumber = -1,
158                            sal_Int32 i_nMaxNumber = -1,
159                            sal_Int32 i_nLogicalOffset = -1
160                            );
161 
size() const162     size_t size() const { return size_t(mnCount); }
163     Iterator begin( const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const;
164     Iterator end( const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const;
165 
getMin() const166     sal_Int32 getMin() const { return mnMin; }
setMin(sal_Int32 i_nMinValue)167     void setMin( sal_Int32 i_nMinValue ) { mnMin = i_nMinValue; }
getMax() const168     sal_Int32 getMax() const { return mnMax; }
setMax(sal_Int32 i_nMaxValue)169     void setMax( sal_Int32 i_nMaxValue ) { mnMax = i_nMaxValue; }
getLogicalOffset() const170     sal_Int32 getLogicalOffset() const { return mnOffset; }
setLogicalOffset(sal_Int32 i_nOffset)171     void setLogicalOffset( sal_Int32 i_nOffset ) { mnOffset = i_nOffset; }
172 
173     bool setRange( const rtl::OUString& i_rNewRange, bool i_bStrict = false );
174     bool hasValue( sal_Int32 nValue, const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const;
175 
176 
177     /**
178     i_rPageRange:     the string to be changed into a sequence of numbers
179                       valid format example "5-3,9,9,7-8" ; instead of ',' ';' or ' ' are allowed as well
180     o_rPageVector:    the output sequence of numbers
181     i_nLogicalOffset: an offset to be applied to each number in the string before inserting it in the resulting sequence
182                       example: a user enters page numbers from 1 to n (since that is logical)
183                                of course usable page numbers in code would start from 0 and end at n-1
184                                so the logical offset would be -1
185     i_nMinNumber:     the minimum allowed number, a negative number means no minimum check
186     i_nMaxNumber:     the maximum allowed number, a negative number means no maximum check
187 
188     @returns: true if the input string was valid, o_rPageVector will contain the resulting sequence
189               false if the input string was invalid, o_rPageVector will be unchanged
190 
191     behavior:
192     - only non-negative sequence numbers are allowed
193     - only non-negative values in the input string are allowed
194     - the string "-3" will be either
195       * an error if no minimum is given
196       * or result in the sequence i_nMinNumber to 3
197     - the string "3-" will be either
198       * an error if no maximum is given
199       * or result in the seqeuence 3 to i_nMaxNumber
200     - an empty string as input is valid and will result in the range [min,max] if given
201       or an empty vector, if not
202     */
203     static bool getRangesFromString( const rtl::OUString& i_rPageRange,
204                                      std::vector< sal_Int32 >& o_rPageVector,
205                                      sal_Int32 i_nMinNumber = -1,
206                                      sal_Int32 i_nMaxNumber = -1,
207                                      sal_Int32 i_nLogicalOffset = -1,
208                                      std::set< sal_Int32 >* i_pPossibleValues = NULL
209                                     );
210 };
211 
212 #endif	// _SV_MULTISEL_HXX
213