diff options
author | Philipp Lohmann <pl@openoffice.org> | 2009-07-08 16:27:08 +0000 |
---|---|---|
committer | Philipp Lohmann <pl@openoffice.org> | 2009-07-08 16:27:08 +0000 |
commit | e83bd2a5f6cab65ececd3a22722a41bbbeaf43b7 (patch) | |
tree | 9ff55c0bda4ce24a14e70557673f51d63be476ca /tools/source/memtools/multisel.cxx | |
parent | c8aed19d39abefd12d03b3c3fcc9a948344c4e94 (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.cxx | 172 |
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; +} + |