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