1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 #ifndef _SV_MULTISEL_HXX 28 #define _SV_MULTISEL_HXX 29 30 #include "tools/toolsdllapi.h" 31 #include <tools/gen.hxx> 32 #include <tools/list.hxx> 33 #include <tools/string.hxx> 34 35 #include <vector> 36 #include <set> 37 38 //------------------------------------------------------------------ 39 40 #ifdef _SV_MULTISEL_CXX 41 DECLARE_LIST( ImpSelList, Range* ) 42 #else 43 #define ImpSelList List 44 #endif 45 46 #define SFX_ENDOFSELECTION CONTAINER_ENTRY_NOTFOUND 47 48 //------------------------------------------------------------------ 49 50 // ------------------ 51 // - MultiSelection - 52 // ------------------ 53 54 class TOOLS_DLLPUBLIC MultiSelection 55 { 56 private: 57 ImpSelList aSels; // array of SV-selections 58 Range aTotRange; // total range of indexes 59 sal_uIntPtr nCurSubSel; // index in aSels of current selected index 60 long nCurIndex; // current selected entry 61 sal_uIntPtr nSelCount; // number of selected indexes 62 sal_Bool bInverseCur;// inverse cursor 63 sal_Bool bCurValid; // are nCurIndex and nCurSubSel valid 64 sal_Bool bSelectNew; // auto-select newly inserted indexes 65 66 #ifdef _SV_MULTISEL_CXX 67 TOOLS_DLLPRIVATE void ImplClear(); 68 TOOLS_DLLPRIVATE sal_uIntPtr ImplFindSubSelection( long nIndex ) const; 69 TOOLS_DLLPRIVATE sal_Bool ImplMergeSubSelections( sal_uIntPtr nPos1, sal_uIntPtr nPos2 ); 70 TOOLS_DLLPRIVATE long ImplFwdUnselected(); 71 TOOLS_DLLPRIVATE long ImplBwdUnselected(); 72 #endif 73 74 public: 75 MultiSelection(); 76 MultiSelection( const MultiSelection& rOrig ); 77 MultiSelection( const Range& rRange ); 78 MultiSelection( const UniString& rString, 79 sal_Unicode cRange = '-', 80 sal_Unicode cSep = ';' ); 81 ~MultiSelection(); 82 83 MultiSelection& operator= ( const MultiSelection& rOrig ); 84 sal_Bool operator== ( MultiSelection& rOrig ); 85 sal_Bool operator!= ( MultiSelection& rOrig ) 86 { return !operator==( rOrig ); } 87 sal_Bool operator !() const 88 { return nSelCount == 0; } 89 90 void SelectAll( sal_Bool bSelect = sal_True ); 91 sal_Bool Select( long nIndex, sal_Bool bSelect = sal_True ); 92 void Select( const Range& rIndexRange, sal_Bool bSelect = sal_True ); 93 sal_Bool IsSelected( long nIndex ) const; 94 sal_Bool IsAllSelected() const 95 { return nSelCount == sal_uIntPtr(aTotRange.Len()); } 96 long GetSelectCount() const { return nSelCount; } 97 98 void SetTotalRange( const Range& rTotRange ); 99 void Insert( long nIndex, long nCount = 1 ); 100 void Remove( long nIndex ); 101 void Append( long nCount = 1 ); 102 103 const Range& GetTotalRange() const { return aTotRange; } 104 sal_Bool IsCurValid() const { return bCurValid; } 105 long GetCurSelected() const { return nCurIndex; } 106 long FirstSelected( sal_Bool bInverse = sal_False ); 107 long LastSelected(); 108 long NextSelected(); 109 long PrevSelected(); 110 111 sal_uIntPtr GetRangeCount() const { return aSels.Count(); } 112 const Range& GetRange( sal_uIntPtr nRange ) const { return *(const Range*)aSels.GetObject(nRange); } 113 }; 114 115 class TOOLS_DLLPUBLIC StringRangeEnumerator 116 { 117 struct Range 118 { 119 sal_Int32 nFirst; 120 sal_Int32 nLast; 121 122 Range() : nFirst( -1 ), nLast( -1 ) {} 123 Range( sal_Int32 i_nFirst, sal_Int32 i_nLast ) : nFirst( i_nFirst ), nLast( i_nLast ) {} 124 }; 125 std::vector< StringRangeEnumerator::Range > maSequence; 126 sal_Int32 mnCount; 127 sal_Int32 mnMin; 128 sal_Int32 mnMax; 129 sal_Int32 mnOffset; 130 131 bool insertRange( sal_Int32 nFirst, sal_Int32 nLast, bool bSequence, bool bMayAdjust ); 132 bool checkValue( sal_Int32, const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const; 133 public: 134 class TOOLS_DLLPUBLIC Iterator 135 { 136 const StringRangeEnumerator* pEnumerator; 137 const std::set< sal_Int32 >* pPossibleValues; 138 sal_Int32 nRangeIndex; 139 sal_Int32 nCurrent; 140 141 friend class StringRangeEnumerator; 142 Iterator( const StringRangeEnumerator* i_pEnum, 143 const std::set< sal_Int32 >* i_pPossibleValues, 144 sal_Int32 i_nRange, 145 sal_Int32 i_nCurrent ) 146 : pEnumerator( i_pEnum ), pPossibleValues( i_pPossibleValues ) 147 , nRangeIndex( i_nRange ), nCurrent( i_nCurrent ) {} 148 public: 149 Iterator() : pEnumerator( NULL ), pPossibleValues( NULL ), nRangeIndex( -1 ), nCurrent( -1 ) {} 150 Iterator& operator++(); 151 sal_Int32 operator*() const; 152 bool operator==(const Iterator&) const; 153 bool operator!=(const Iterator& i_rComp) const 154 { return ! (*this == i_rComp); } 155 }; 156 157 friend class StringRangeEnumerator::Iterator; 158 159 StringRangeEnumerator() : mnCount( 0 ), mnMin( -1 ), mnMax( -1 ), mnOffset( -1 ) {} 160 StringRangeEnumerator( const rtl::OUString& i_rInput, 161 sal_Int32 i_nMinNumber = -1, 162 sal_Int32 i_nMaxNumber = -1, 163 sal_Int32 i_nLogicalOffset = -1 164 ); 165 166 size_t size() const { return size_t(mnCount); } 167 Iterator begin( const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const; 168 Iterator end( const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const; 169 170 sal_Int32 getMin() const { return mnMin; } 171 void setMin( sal_Int32 i_nMinValue ) { mnMin = i_nMinValue; } 172 sal_Int32 getMax() const { return mnMax; } 173 void setMax( sal_Int32 i_nMaxValue ) { mnMax = i_nMaxValue; } 174 sal_Int32 getLogicalOffset() const { return mnOffset; } 175 void setLogicalOffset( sal_Int32 i_nOffset ) { mnOffset = i_nOffset; } 176 177 bool setRange( const rtl::OUString& i_rNewRange, bool i_bStrict = false ); 178 bool hasValue( sal_Int32 nValue, const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const; 179 180 181 /** 182 i_rPageRange: the string to be changed into a sequence of numbers 183 valid format example "5-3,9,9,7-8" ; instead of ',' ';' or ' ' are allowed as well 184 o_rPageVector: the output sequence of numbers 185 i_nLogicalOffset: an offset to be applied to each number in the string before inserting it in the resulting sequence 186 example: a user enters page numbers from 1 to n (since that is logical) 187 of course usable page numbers in code would start from 0 and end at n-1 188 so the logical offset would be -1 189 i_nMinNumber: the minimum allowed number, a negative number means no minimum check 190 i_nMaxNumber: the maximum allowed number, a negative number means no maximum check 191 192 @returns: true if the input string was valid, o_rPageVector will contain the resulting sequence 193 false if the input string was invalid, o_rPageVector will be unchanged 194 195 behavior: 196 - only non-negative sequence numbers are allowed 197 - only non-negative values in the input string are allowed 198 - the string "-3" will be either 199 * an error if no minimum is given 200 * or result in the sequence i_nMinNumber to 3 201 - the string "3-" will be either 202 * an error if no maximum is given 203 * or result in the seqeuence 3 to i_nMaxNumber 204 - an empty string as input is valid and will result in the range [min,max] if given 205 or an empty vector, if not 206 */ 207 static bool getRangesFromString( const rtl::OUString& i_rPageRange, 208 std::vector< sal_Int32 >& o_rPageVector, 209 sal_Int32 i_nMinNumber = -1, 210 sal_Int32 i_nMaxNumber = -1, 211 sal_Int32 i_nLogicalOffset = -1, 212 std::set< sal_Int32 >* i_pPossibleValues = NULL 213 ); 214 }; 215 216 #endif // _SV_MULTISEL_HXX 217