summaryrefslogtreecommitdiff
path: root/tools/source/memtools/multisel.cxx
diff options
context:
space:
mode:
authorPhilipp Lohmann <pl@openoffice.org>2009-07-08 16:27:08 +0000
committerPhilipp Lohmann <pl@openoffice.org>2009-07-08 16:27:08 +0000
commite83bd2a5f6cab65ececd3a22722a41bbbeaf43b7 (patch)
tree9ff55c0bda4ce24a14e70557673f51d63be476ca /tools/source/memtools/multisel.cxx
parentc8aed19d39abefd12d03b3c3fcc9a948344c4e94 (diff)
#i95216# get a new enumerator that parsers a page range
Diffstat (limited to 'tools/source/memtools/multisel.cxx')
-rw-r--r--tools/source/memtools/multisel.cxx172
1 files changed, 172 insertions, 0 deletions
diff --git a/tools/source/memtools/multisel.cxx b/tools/source/memtools/multisel.cxx
index 6b32badc283e..a28b54c2347e 100644
--- a/tools/source/memtools/multisel.cxx
+++ b/tools/source/memtools/multisel.cxx
@@ -47,6 +47,8 @@
#define DBG(x)
#endif
+using namespace rtl;
+
//==================================================================
#ifdef MI_DEBUG
@@ -865,3 +867,173 @@ void MultiSelection::SetTotalRange( const Range& rTotRange )
bCurValid = FALSE;
nCurIndex = 0;
}
+
+// -----------------------------------------------------------------------
+//
+// StringRangeEnumerator
+//
+// -----------------------------------------------------------------------
+
+static bool lcl_getSingleValue(
+ const OUString &rText,
+ sal_Int32 &rVal,
+ sal_Int32 nLogicalOffset,
+ sal_Int32 nMinNumber,
+ sal_Int32 nMaxNumber
+ )
+{
+ bool bRes = false;
+ const sal_Int32 nLen = rText.getLength();
+ if (nLen > 0)
+ {
+ // verify that text consists of decimal number 0..9 only
+ bool bValidText = true;
+ const sal_Unicode *pText = rText.getStr();
+ for (sal_Int32 i = 0; i < nLen && bValidText; ++i)
+ {
+ const sal_Unicode cChar = pText[i];
+ if (cChar < '0' || cChar > '9')
+ bValidText = false;
+ }
+
+ // get integer value if text is valid
+ if (bValidText)
+ {
+ sal_Int32 nTmpVal = rText.toInt32();
+ nTmpVal += nLogicalOffset;
+ if( nTmpVal >= 0 &&
+ (nMinNumber < 0 || nTmpVal >= nMinNumber) &&
+ (nMaxNumber < 0 || nTmpVal <= nMaxNumber)
+ )
+ {
+ bRes = true;
+ rVal = nTmpVal;
+ }
+ }
+ }
+ return bRes;
+}
+
+static bool lcl_getSubRangeBounds(
+ const OUString &rSubRange,
+ sal_Int32 &rFirst,
+ sal_Int32 &rLast,
+ sal_Int32 nLogicalOffset,
+ sal_Int32 nMinNumber,
+ sal_Int32 nMaxNumber
+ )
+{
+ bool bRes = false;
+
+ // check for page range...
+ sal_Int32 nPos = rSubRange.indexOf( (sal_Unicode)'-' );
+ if (nPos > 0)
+ {
+ // page range found...
+ nPos = 0;
+ const OUString aFirstPage( rSubRange.getToken( 0, '-', nPos ) );
+ const OUString aLastPage( rSubRange.getToken( 0, '-', nPos ) );
+ sal_Int32 nTmpFirst = -1;
+ sal_Int32 nTmpLast = -1;
+ if( aFirstPage.getLength() == 0 && nMinNumber >= 0 )
+ nTmpFirst = nMinNumber;
+ else
+ lcl_getSingleValue( aFirstPage, nTmpFirst, nLogicalOffset, nMinNumber, nMaxNumber );
+ if( aLastPage.getLength() == 0 && nMaxNumber >= 0 )
+ nTmpLast = nMaxNumber;
+ else
+ lcl_getSingleValue( aLastPage, nTmpLast, nLogicalOffset, nMinNumber, nMaxNumber );
+ if( nTmpFirst != -1 && nTmpLast != -1 )
+ {
+ rFirst = nTmpFirst;
+ rLast = nTmpLast;
+ bRes = true;
+ }
+ }
+ else
+ {
+ // single page value...
+ sal_Int32 nVal = -1;
+ if (lcl_getSingleValue( rSubRange, nVal, nLogicalOffset, nMinNumber, nMaxNumber ))
+ {
+ rFirst = rLast = nVal;
+ bRes = true;
+ }
+ }
+
+ return bRes;
+}
+
+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
+ )
+{
+ bool bRes = false;
+
+ // - strip leading and trailing whitespaces
+ // - unify token delimeters to ';'
+ // - remove duplicate delimiters
+ OUString aRange( i_rPageRange.trim() );
+ aRange = aRange.replace( (sal_Unicode)' ', (sal_Unicode)';' );
+ aRange = aRange.replace( (sal_Unicode)',', (sal_Unicode)';' );
+ sal_Int32 nPos = -1;
+ rtl::OUString aDoubleSemi( RTL_CONSTASCII_USTRINGPARAM(";;") );
+ rtl::OUString aSingleSemi( RTL_CONSTASCII_USTRINGPARAM(";;") );
+ while ((nPos = aRange.indexOf( aDoubleSemi )) >= 0)
+ aRange = aRange.replaceAt( nPos, 2, aSingleSemi );
+
+ if (aRange.getLength() > 0)
+ {
+ std::vector< sal_Int32 > aTmpVector;
+
+ // iterate over all sub ranges and add the respective pages to the
+ // vector while preserving the page order
+ bool bFailed = false;
+ nPos = 0;
+ do
+ {
+ const OUString aSubRange = aRange.getToken( 0, ';', nPos );
+ sal_Int32 nFirst = -1, nLast = -1;
+ if (lcl_getSubRangeBounds( aSubRange, nFirst, nLast, i_nLogicalOffset, i_nMinNumber, i_nMaxNumber )
+ && nFirst >= 0 && nLast >= 0)
+ {
+ // add pages of sub range to vector
+ if (nFirst == nLast)
+ aTmpVector.push_back( nFirst );
+ else if (nFirst < nLast)
+ {
+ for (sal_Int32 i = nFirst; i <= nLast; ++i)
+ aTmpVector.push_back( i );
+ }
+ else if (nFirst > nLast)
+ {
+ for (sal_Int32 i = nFirst; i >= nLast; --i)
+ aTmpVector.push_back( i );
+ }
+ else
+ OSL_ENSURE( 0, "unexpected case" );
+ }
+ else
+ bFailed = true;
+ }
+ while (!bFailed && 0 <= nPos && nPos < aRange.getLength());
+
+ if (!bFailed)
+ {
+ o_rPageVector = aTmpVector;
+ bRes = true;
+ }
+ }
+ else
+ {
+ // empty string ...
+ o_rPageVector.clear();
+ bRes = true;
+ }
+
+ return bRes;
+}
+