From 5d0ae90546d46a39bb42ea60e3f835ca68e6abdb Mon Sep 17 00:00:00 2001 From: Markus Mohrhard Date: Fri, 2 Nov 2012 00:07:06 +0100 Subject: implement top/bottom n percent Change-Id: I463cd96831cd47b4e2ed878761e7196098a2e163 --- sc/inc/conditio.hxx | 7 ++++++ sc/source/core/data/conditio.cxx | 50 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/sc/inc/conditio.hxx b/sc/inc/conditio.hxx index ee2d9c9121f2..51b3dba67c87 100644 --- a/sc/inc/conditio.hxx +++ b/sc/inc/conditio.hxx @@ -72,6 +72,8 @@ enum ScConditionMode SC_COND_DIRECT, SC_COND_TOP10, SC_COND_BOTTOM10, + SC_COND_TOP_PERCENT, + SC_COND_BOTTOM_PERCENT, SC_COND_NONE }; @@ -253,6 +255,8 @@ private: bool IsDuplicate(double nArg, const rtl::OUString& rStr, const ScRangeList& rRanges) const; bool IsTopNElement( double nArg, const ScRangeList& rRanges ) const; bool IsTopNPercent( double nArg, const ScRangeList& rRanges ) const; + bool IsBottomNElement( double nArg, const ScRangeList& rRanges ) const; + bool IsBottomNPercent( double nArg, const ScRangeList& rRanges ) const; void FillCache(const ScRangeList& rRanges) const; @@ -265,6 +269,9 @@ private: // cache them for easier access size_t nValueItems; + + ScConditionEntryCache(): + nValueItems(0) {} }; mutable boost::scoped_ptr mpCache; diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx index 13abd3ac5198..6e7724c47536 100644 --- a/sc/source/core/data/conditio.cxx +++ b/sc/source/core/data/conditio.cxx @@ -865,10 +865,10 @@ bool ScConditionEntry::IsTopNElement( double nArg, const ScRangeList& rRanges ) for(ScConditionEntryCache::ValueCacheType::const_reverse_iterator itr = mpCache->maValues.rbegin(), itrEnd = mpCache->maValues.rend(); itr != itrEnd; ++itr) { - if(nCells >= nVal1) - return false; if(itr->first <= nArg) return true; + if(nCells >= nVal1) + return false; nCells += itr->second; } @@ -886,10 +886,48 @@ bool ScConditionEntry::IsBottomNElement( double nArg, const ScRangeList& rRanges for(ScConditionEntryCache::ValueCacheType::const_iterator itr = mpCache->maValues.begin(), itrEnd = mpCache->maValues.end(); itr != itrEnd; ++itr) { + if(itr->first >= nArg) + return true; if(nCells >= nVal1) return false; + nCells += itr->second; + } + + return true; +} + +bool ScConditionEntry::IsTopNPercent( double nArg, const ScRangeList& rRanges ) const +{ + FillCache( rRanges ); + + size_t nCells = 0; + size_t nLimitCells = static_cast(mpCache->nValueItems*nVal1/100); + for(ScConditionEntryCache::ValueCacheType::const_reverse_iterator itr = mpCache->maValues.rbegin(), + itrEnd = mpCache->maValues.rend(); itr != itrEnd; ++itr) + { + if(itr->first <= nArg) + return true; + if(nCells >= nLimitCells) + return false; + nCells += itr->second; + } + + return true; +} + +bool ScConditionEntry::IsBottomNPercent( double nArg, const ScRangeList& rRanges ) const +{ + FillCache( rRanges ); + + size_t nCells = 0; + size_t nLimitCells = static_cast(mpCache->nValueItems*nVal1/100); + for(ScConditionEntryCache::ValueCacheType::const_iterator itr = mpCache->maValues.begin(), + itrEnd = mpCache->maValues.end(); itr != itrEnd; ++itr) + { if(itr->first >= nArg) return true; + if(nCells >= nLimitCells) + return false; nCells += itr->second; } @@ -973,6 +1011,12 @@ bool ScConditionEntry::IsValid( double nArg ) const case SC_COND_BOTTOM10: bValid = IsBottomNElement( nArg, pCondFormat->GetRange() ); break; + case SC_COND_TOP_PERCENT: + bValid = IsTopNPercent( nArg, pCondFormat->GetRange() ); + break; + case SC_COND_BOTTOM_PERCENT: + bValid = IsBottomNPercent( nArg, pCondFormat->GetRange() ); + break; default: OSL_FAIL("unbekannte Operation bei ScConditionEntry"); break; @@ -1029,6 +1073,8 @@ bool ScConditionEntry::IsValidStr( const String& rArg ) const bValid = (ScGlobal::GetCollator()->compareString( rArg, aUpVal1 ) != COMPARE_EQUAL); break; + case SC_COND_TOP_PERCENT: + case SC_COND_BOTTOM_PERCENT: case SC_COND_TOP10: case SC_COND_BOTTOM10: return false; -- cgit v1.2.3