summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorKurt Zenker <kz@openoffice.org>2010-01-15 16:47:42 +0100
committerKurt Zenker <kz@openoffice.org>2010-01-15 16:47:42 +0100
commit8ad567a9f81ac92a5bf7592eab0179876c1dafab (patch)
tree2504a400d1b5214a38926f8d2cdd008c88f3ef54 /tools
parent4eeae16d41ddb88df9b4aec1fe2ea975b8ef5ec7 (diff)
parenta2637545e1419956096899a82a9c79511d83fbc5 (diff)
CWS-TOOLING: integrate CWS printerpullpages
Diffstat (limited to 'tools')
-rw-r--r--tools/inc/tools/multisel.hxx104
-rw-r--r--tools/source/memtools/makefile.mk2
-rw-r--r--tools/source/memtools/multisel.cxx298
3 files changed, 404 insertions, 0 deletions
diff --git a/tools/inc/tools/multisel.hxx b/tools/inc/tools/multisel.hxx
index 46fd8947e21b..9de3cc172e70 100644
--- a/tools/inc/tools/multisel.hxx
+++ b/tools/inc/tools/multisel.hxx
@@ -35,6 +35,9 @@
#include <tools/list.hxx>
#include <tools/string.hxx>
+#include <vector>
+#include <set>
+
//------------------------------------------------------------------
#ifdef _SV_MULTISEL_CXX
@@ -112,4 +115,105 @@ public:
const Range& GetRange( ULONG nRange ) const { return *(const Range*)aSels.GetObject(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 insertRange( sal_Int32 nFirst, sal_Int32 nLast, bool bSequence, bool bMayAdjust );
+ bool checkValue( sal_Int32, const std::set< sal_Int32 >* i_pPossibleValues = NULL ) 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() : pEnumerator( NULL ), pPossibleValues( NULL ), nRangeIndex( -1 ), nCurrent( -1 ) {}
+ Iterator& operator++();
+ sal_Int32 operator*() const;
+ bool operator==(const Iterator&) const;
+ bool operator!=(const Iterator& i_rComp) const
+ { return ! (*this == i_rComp); }
+ };
+
+ friend class StringRangeEnumerator::Iterator;
+
+ StringRangeEnumerator() : mnCount( 0 ), mnMin( -1 ), mnMax( -1 ), mnOffset( -1 ) {}
+ StringRangeEnumerator( const rtl::OUString& i_rInput,
+ sal_Int32 i_nMinNumber = -1,
+ sal_Int32 i_nMaxNumber = -1,
+ sal_Int32 i_nLogicalOffset = -1
+ );
+
+ size_t size() const { return size_t(mnCount); }
+ Iterator begin( const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const;
+ Iterator end( const std::set< sal_Int32 >* i_pPossibleValues = NULL ) const;
+
+ sal_Int32 getMin() const { return mnMin; }
+ void setMin( sal_Int32 i_nMinValue ) { mnMin = i_nMinValue; }
+ sal_Int32 getMax() const { return mnMax; }
+ void setMax( sal_Int32 i_nMaxValue ) { mnMax = i_nMaxValue; }
+ sal_Int32 getLogicalOffset() const { return mnOffset; }
+ void setLogicalOffset( sal_Int32 i_nOffset ) { mnOffset = i_nOffset; }
+
+ bool setRange( const rtl::OUString& i_rNewRange, bool i_bStrict = false );
+ bool hasValue( sal_Int32 nValue, const std::set< sal_Int32 >* i_pPossibleValues = NULL ) 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, a negative number means no minimum check
+ i_nMaxNumber: the maximum allowed number, a negative number means no maximum check
+
+ @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 be unchanged
+
+ behavior:
+ - only non-negative sequence numbers are allowed
+ - only non-negative values in the input string are allowed
+ - the string "-3" will be either
+ * an error if no minimum is given
+ * or result in the sequence i_nMinNumber to 3
+ - the string "3-" will be either
+ * an error if no maximum is given
+ * or result in the seqeuence 3 to i_nMaxNumber
+ - an empty string as input is valid and will result in the range [min,max] if given
+ or an empty vector, if not
+ */
+ static bool getRangesFromString( const rtl::OUString& i_rPageRange,
+ std::vector< sal_Int32 >& o_rPageVector,
+ sal_Int32 i_nMinNumber = -1,
+ sal_Int32 i_nMaxNumber = -1,
+ sal_Int32 i_nLogicalOffset = -1,
+ std::set< sal_Int32 >* i_pPossibleValues = NULL
+ );
+};
+
#endif // _SV_MULTISEL_HXX
diff --git a/tools/source/memtools/makefile.mk b/tools/source/memtools/makefile.mk
index 037dadbf4a46..51d831ec0fed 100644
--- a/tools/source/memtools/makefile.mk
+++ b/tools/source/memtools/makefile.mk
@@ -47,6 +47,8 @@ SLOFILES= $(SLO)$/contnr.obj \
$(SLO)$/mempool.obj \
$(SLO)$/multisel.obj
+EXCEPTIONSFILES= $(SLO)$/multisel.obj $(OBJ)$/multisel.obj
+
OBJFILES= $(OBJ)$/contnr.obj \
$(OBJ)$/table.obj \
$(OBJ)$/unqidx.obj \
diff --git a/tools/source/memtools/multisel.cxx b/tools/source/memtools/multisel.cxx
index 6b32badc283e..5fe920b6998a 100644
--- a/tools/source/memtools/multisel.cxx
+++ b/tools/source/memtools/multisel.cxx
@@ -41,12 +41,16 @@
#include <tools/debug.hxx>
#include <tools/multisel.hxx>
+#include "rtl/ustrbuf.hxx"
+
#ifdef MI_DEBUG
#define DBG(x) x
#else
#define DBG(x)
#endif
+using namespace rtl;
+
//==================================================================
#ifdef MI_DEBUG
@@ -865,3 +869,297 @@ void MultiSelection::SetTotalRange( const Range& rTotRange )
bCurValid = FALSE;
nCurIndex = 0;
}
+
+// -----------------------------------------------------------------------
+//
+// StringRangeEnumerator
+//
+// -----------------------------------------------------------------------
+StringRangeEnumerator::StringRangeEnumerator( const rtl::OUString& i_rInput,
+ sal_Int32 i_nMinNumber,
+ sal_Int32 i_nMaxNumber,
+ sal_Int32 i_nLogicalOffset
+ )
+ : mnCount( 0 )
+ , mnMin( i_nMinNumber )
+ , mnMax( i_nMaxNumber )
+ , mnOffset( i_nLogicalOffset )
+{
+ setRange( i_rInput );
+}
+
+bool StringRangeEnumerator::checkValue( sal_Int32 i_nValue, const std::set< sal_Int32 >* i_pPossibleValues ) const
+{
+ if( mnMin >= 0 && i_nValue < mnMin )
+ return false;
+ if( mnMax >= 0 && i_nValue > mnMax )
+ return false;
+ if( i_nValue < 0 )
+ return false;
+ if( i_pPossibleValues && i_pPossibleValues->find( i_nValue ) == i_pPossibleValues->end() )
+ return false;
+ return true;
+}
+
+bool StringRangeEnumerator::insertRange( sal_Int32 i_nFirst, sal_Int32 i_nLast, bool bSequence, bool bMayAdjust )
+{
+ bool bSuccess = true;
+ if( bSequence )
+ {
+ if( i_nFirst == -1 )
+ i_nFirst = mnMin;
+ if( i_nLast == -1 )
+ i_nLast = mnMax;
+ if( bMayAdjust )
+ {
+ if( i_nFirst < mnMin )
+ i_nFirst = mnMin;
+ if( i_nFirst > mnMax )
+ i_nFirst = mnMax;
+ if( i_nLast < mnMin )
+ i_nLast = mnMin;
+ if( i_nLast > mnMax )
+ i_nLast = mnMax;
+ }
+ if( checkValue( i_nFirst ) && checkValue( i_nLast ) )
+ {
+ maSequence.push_back( Range( i_nFirst, i_nLast ) );
+ sal_Int32 nNumber = i_nLast - i_nFirst;
+ nNumber = nNumber < 0 ? -nNumber : nNumber;
+ mnCount += nNumber + 1;
+ }
+ else
+ bSuccess = false;
+ }
+ else
+ {
+ if( i_nFirst >= 0 )
+ {
+ if( checkValue( i_nFirst ) )
+ {
+ maSequence.push_back( Range( i_nFirst, i_nFirst ) );
+ mnCount++;
+ }
+ else
+ bSuccess = false;
+ }
+ if( i_nLast >= 0 )
+ {
+ if( checkValue( i_nLast ) )
+ {
+ maSequence.push_back( Range( i_nLast, i_nLast ) );
+ mnCount++;
+ }
+ else
+ bSuccess = false;
+ }
+ }
+
+ return bSuccess;
+}
+
+bool StringRangeEnumerator::setRange( const rtl::OUString& i_rNewRange, bool i_bStrict )
+{
+ mnCount = 0;
+ maSequence.clear();
+
+ // we love special cases
+ if( i_rNewRange.getLength() == 0 )
+ {
+ if( mnMin >= 0 && mnMax >= 0 )
+ {
+ insertRange( mnMin, mnMax, mnMin != mnMax, ! i_bStrict );
+ }
+ return true;
+ }
+
+ const sal_Unicode* pInput = i_rNewRange.getStr();
+ rtl::OUStringBuffer aNumberBuf( 16 );
+ sal_Int32 nLastNumber = -1, nNumber = -1;
+ bool bSequence = false;
+ bool bSuccess = true;
+ while( *pInput )
+ {
+ while( *pInput >= sal_Unicode('0') && *pInput <= sal_Unicode('9') )
+ aNumberBuf.append( *pInput++ );
+ if( aNumberBuf.getLength() )
+ {
+ if( nNumber != -1 )
+ {
+ if( bSequence )
+ {
+ if( ! insertRange( nLastNumber, nNumber, true, ! i_bStrict ) && i_bStrict )
+ {
+ bSuccess = false;
+ break;
+ }
+ nLastNumber = -1;
+ }
+ else
+ {
+ if( ! insertRange( nNumber, nNumber, false, ! i_bStrict ) && i_bStrict )
+ {
+ bSuccess = false;
+ break;
+ }
+ }
+ }
+ nNumber = aNumberBuf.makeStringAndClear().toInt32();
+ nNumber += mnOffset;
+ }
+ bool bInsertRange = false;
+ if( *pInput == sal_Unicode('-') )
+ {
+ nLastNumber = nNumber;
+ nNumber = -1;
+ bSequence = true;
+ }
+ else if( *pInput == ' ' )
+ {
+ }
+ else if( *pInput == sal_Unicode(',') || *pInput == sal_Unicode(';') )
+ bInsertRange = true;
+ else if( *pInput )
+ {
+
+ bSuccess = false;
+ break; // parse error
+ }
+
+ if( bInsertRange )
+ {
+ if( ! insertRange( nLastNumber, nNumber, bSequence, ! i_bStrict ) && i_bStrict )
+ {
+ bSuccess = false;
+ break;
+ }
+ nNumber = nLastNumber = -1;
+ bSequence = false;
+ }
+ if( *pInput )
+ pInput++;
+ }
+ // insert last entries
+ insertRange( nLastNumber, nNumber, bSequence, ! i_bStrict );
+
+ return bSuccess;
+}
+
+bool StringRangeEnumerator::hasValue( sal_Int32 i_nValue, const std::set< sal_Int32 >* i_pPossibleValues ) const
+{
+ if( i_pPossibleValues && i_pPossibleValues->find( i_nValue ) == i_pPossibleValues->end() )
+ return false;
+ size_t n = maSequence.size();
+ for( size_t i= 0; i < n; ++i )
+ {
+ const StringRangeEnumerator::Range rRange( maSequence[i] );
+ if( rRange.nFirst < rRange.nLast )
+ {
+ if( i_nValue >= rRange.nFirst && i_nValue <= rRange.nLast )
+ return true;
+ }
+ else
+ {
+ if( i_nValue >= rRange.nLast && i_nValue <= rRange.nFirst )
+ return true;
+ }
+ }
+ return false;
+}
+
+StringRangeEnumerator::Iterator& StringRangeEnumerator::Iterator::operator++()
+{
+ if( nRangeIndex >= 0 && nCurrent >= 0 && pEnumerator )
+ {
+ const StringRangeEnumerator::Range& rRange( pEnumerator->maSequence[nRangeIndex] );
+ bool bRangeChange = false;
+ if( rRange.nLast < rRange.nFirst )
+ {
+ // backward range
+ if( nCurrent > rRange.nLast )
+ nCurrent--;
+ else
+ bRangeChange = true;
+ }
+ else
+ {
+ // forward range
+ if( nCurrent < rRange.nLast )
+ nCurrent++;
+ else
+ bRangeChange = true;
+ }
+ if( bRangeChange )
+ {
+ nRangeIndex++;
+ if( size_t(nRangeIndex) == pEnumerator->maSequence.size() )
+ {
+ // reached the end
+ nRangeIndex = nCurrent = -1;
+ }
+ else
+ nCurrent = pEnumerator->maSequence[nRangeIndex].nFirst;
+ }
+ if( nRangeIndex != -1 && nCurrent != -1 )
+ {
+ if( ! pEnumerator->checkValue( nCurrent, pPossibleValues ) )
+ return ++(*this);
+ }
+ }
+ return *this;
+}
+
+sal_Int32 StringRangeEnumerator::Iterator::operator*() const
+{
+ return nCurrent;
+}
+
+bool StringRangeEnumerator::Iterator::operator==( const Iterator& i_rCompare ) const
+{
+ return i_rCompare.pEnumerator == pEnumerator && i_rCompare.nRangeIndex == nRangeIndex && i_rCompare.nCurrent == nCurrent;
+}
+
+StringRangeEnumerator::Iterator StringRangeEnumerator::begin( const std::set< sal_Int32 >* i_pPossibleValues ) const
+{
+ StringRangeEnumerator::Iterator it( this,
+ i_pPossibleValues,
+ maSequence.empty() ? -1 : 0,
+ maSequence.empty() ? -1 : maSequence[0].nFirst );
+ if( ! checkValue(*it, i_pPossibleValues ) )
+ ++it;
+ return it;
+}
+
+StringRangeEnumerator::Iterator StringRangeEnumerator::end( const std::set< sal_Int32 >* i_pPossibleValues ) const
+{
+ return StringRangeEnumerator::Iterator( this, i_pPossibleValues, -1, -1 );
+}
+
+bool StringRangeEnumerator::getRangesFromString( const OUString& i_rPageRange,
+ std::vector< sal_Int32 >& o_rPageVector,
+ sal_Int32 i_nMinNumber,
+ sal_Int32 i_nMaxNumber,
+ sal_Int32 i_nLogicalOffset,
+ std::set< sal_Int32 >* i_pPossibleValues
+ )
+{
+ StringRangeEnumerator aEnum;
+ aEnum.setMin( i_nMinNumber );
+ aEnum.setMax( i_nMaxNumber );
+ aEnum.setLogicalOffset( i_nLogicalOffset );
+
+ bool bRes = aEnum.setRange( i_rPageRange );
+ if( bRes )
+ {
+ o_rPageVector.clear();
+ o_rPageVector.reserve( aEnum.size() );
+ for( StringRangeEnumerator::Iterator it = aEnum.begin( i_pPossibleValues );
+ it != aEnum.end( i_pPossibleValues ); ++it )
+ {
+ o_rPageVector.push_back( *it );
+ }
+ }
+
+ return bRes;
+}
+