1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#ifndef INCLUDED_TOOLS_MULTISEL_HXX
#define INCLUDED_TOOLS_MULTISEL_HXX
#include <tools/toolsdllapi.h>
#include <tools/gen.hxx>
#include <rtl/ustring.hxx>
#include <vector>
#include <set>
typedef ::std::vector< Range* > ImpSelList;
#define SFX_ENDOFSELECTION ULONG_MAX
class TOOLS_DLLPUBLIC MultiSelection
{
private:
ImpSelList aSels; // array of SV-selections
Range aTotRange; // total range of indexes
sal_uIntPtr nCurSubSel; // index in aSels of current selected index
long nCurIndex; // current selected entry
sal_uIntPtr nSelCount; // number of selected indexes
bool bInverseCur;// inverse cursor
bool bCurValid; // are nCurIndex and nCurSubSel valid
bool bSelectNew; // auto-select newly inserted indexes
TOOLS_DLLPRIVATE void ImplClear();
TOOLS_DLLPRIVATE size_t ImplFindSubSelection( long nIndex ) const;
TOOLS_DLLPRIVATE void ImplMergeSubSelections( size_t nPos1, size_t nPos2 );
TOOLS_DLLPRIVATE long ImplFwdUnselected();
public:
MultiSelection();
MultiSelection( const MultiSelection& rOrig );
MultiSelection( const Range& rRange );
~MultiSelection();
MultiSelection& operator= ( const MultiSelection& rOrig );
void SelectAll( bool bSelect = true );
bool Select( long nIndex, bool bSelect = true );
void Select( const Range& rIndexRange, bool bSelect = true );
bool IsSelected( long nIndex ) const;
bool IsAllSelected() const
{ return nSelCount == sal_uIntPtr(aTotRange.Len()); }
long GetSelectCount() const { return nSelCount; }
void SetTotalRange( const Range& rTotRange );
void Insert( long nIndex, long nCount = 1 );
void Remove( long nIndex );
const Range& GetTotalRange() const { return aTotRange; }
long FirstSelected();
long LastSelected();
long NextSelected();
size_t GetRangeCount() const { return aSels.size(); }
const Range& GetRange( size_t nRange ) const { return *aSels[nRange]; }
};
class TOOLS_DLLPUBLIC StringRangeEnumerator
{
struct Range
{
sal_Int32 nFirst;
sal_Int32 nLast;
Range() : nFirst( -1 ), nLast( -1 ) {}
Range( sal_Int32 i_nFirst, sal_Int32 i_nLast ) : nFirst( i_nFirst ), nLast( i_nLast ) {}
};
std::vector< StringRangeEnumerator::Range > maSequence;
sal_Int32 mnCount;
sal_Int32 mnMin;
sal_Int32 mnMax;
sal_Int32 mnOffset;
bool mbValidInput;
bool setRange( const OUString& i_rNewRange );
bool insertRange( sal_Int32 nFirst, sal_Int32 nLast, bool bSequence );
bool insertJoinedRanges( const std::vector< sal_Int32 >& rNumbers );
bool checkValue( sal_Int32, const std::set< sal_Int32 >* i_pPossibleValues = nullptr ) const;
public:
class TOOLS_DLLPUBLIC Iterator
{
const StringRangeEnumerator* pEnumerator;
const std::set< sal_Int32 >* pPossibleValues;
sal_Int32 nRangeIndex;
sal_Int32 nCurrent;
friend class StringRangeEnumerator;
Iterator( const StringRangeEnumerator* i_pEnum,
const std::set< sal_Int32 >* i_pPossibleValues,
sal_Int32 i_nRange,
sal_Int32 i_nCurrent )
: pEnumerator( i_pEnum ), pPossibleValues( i_pPossibleValues )
, nRangeIndex( i_nRange ), nCurrent( i_nCurrent ) {}
public:
Iterator& operator++();
sal_Int32 operator*() const { return nCurrent;}
bool operator==(const Iterator&) const;
bool operator!=(const Iterator& i_rComp) const
{ return ! (*this == i_rComp); }
};
friend class StringRangeEnumerator::Iterator;
StringRangeEnumerator( const OUString& i_rInput,
sal_Int32 i_nMinNumber,
sal_Int32 i_nMaxNumber,
sal_Int32 i_nLogicalOffset = -1
);
sal_Int32 size() const { return mnCount; }
Iterator begin( const std::set< sal_Int32 >* i_pPossibleValues = nullptr ) const;
Iterator end( const std::set< sal_Int32 >* i_pPossibleValues = nullptr ) const;
bool isValidInput() const { return mbValidInput; }
bool hasValue( sal_Int32 nValue, const std::set< sal_Int32 >* i_pPossibleValues = nullptr ) const;
/**
i_rPageRange: the string to be changed into a sequence of numbers
valid format example "5-3,9,9,7-8" ; instead of ',' ';' or ' ' are allowed as well
o_rPageVector: the output sequence of numbers
i_nLogicalOffset: an offset to be applied to each number in the string before inserting it in the resulting sequence
example: a user enters page numbers from 1 to n (since that is logical)
of course usable page numbers in code would start from 0 and end at n-1
so the logical offset would be -1
i_nMinNumber: the minimum allowed number
i_nMaxNumber: the maximum allowed number
@returns: true if the input string was valid, o_rPageVector will contain the resulting sequence
false if the input string was invalid, o_rPageVector will contain
the sequence that parser is able to extract
behavior:
- only non-negative sequence numbers are allowed
- only non-negative values in the input string are allowed
- the string "-3" means the sequence i_nMinNumber to 3
- the string "3-" means the sequence 3 to i_nMaxNumber
- the string "-" means the sequence i_nMinNumber to i_nMaxNumber
- single number that doesn't fit in [i_nMinNumber,i_nMaxNumber] will be ignored
- range that doesn't fit in [i_nMinNumber,i_nMaxNumber] will be adjusted
*/
static bool getRangesFromString( const OUString& i_rPageRange,
std::vector< sal_Int32 >& o_rPageVector,
sal_Int32 i_nMinNumber,
sal_Int32 i_nMaxNumber,
sal_Int32 i_nLogicalOffset = -1,
std::set< sal_Int32 >* i_pPossibleValues = nullptr
);
};
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|