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