diff -r 000000000000 -r 876b1a06bc25 plugins/contacts/symbian/contactsmodel/cntview/range.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/plugins/contacts/symbian/contactsmodel/cntview/range.cpp Wed Aug 25 15:49:42 2010 +0300 @@ -0,0 +1,431 @@ +/* +* Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + + +#include +#include "cntstd.h" +#include + + + +//#define CNTVIEW_API_PROFILING + + +// +// CContactViewRangeBase +// + +/** +@internalComponent +*/ +CContactViewRangeBase::CContactViewRangeBase(const CContactViewBase& aView) + : iView(aView),iLow(KErrNotFound),iHigh(KErrNotFound) + { + } + +CContactViewRangeBase::~CContactViewRangeBase() + { + delete iCollateMethod; + } + +void CContactViewRangeBase::ConstructL() +/** Called by derived classes to set the collation method iCollateMethod to be +the standard collation method for the current locale. +@internalComponent +*/ + { + // Needed to ensure unicode sorting / inserting into sorted lists works the same as ER5, + // i.e. that it encludes all spaces and punctuation. + iCollateMethod = new(ELeave) TCollationMethod; + *iCollateMethod = *Mem::CollationMethodByIndex(0); + iCollateMethod->iFlags|=TCollationMethod::EIgnoreNone; + } + +EXPORT_C TBool CContactViewRangeBase::IndicesValid() const +/** Tests whether the lower and upper indexes are valid, i.e. not KErrNotFound. + +@return ETrue if the indexes are valid, EFalse if not. */ + { + if (iLow==KErrNotFound) + { + ASSERT(iHigh==KErrNotFound); + return EFalse; + } + return ETrue; + } + +TInt CContactViewRangeBase::FindIndexL(const TDesC& aMatch,TCriteria aCriteria) const +// Binary search through iView to find the first contact that matches aMatch according to aCritera. +/** Called by implementations of SetL() to search the sub view's underlying view +for the index of the first item whose field content matches aMatch, using +the specified search criteria. + +@internalComponent +@param aMatch The text to search for. +@param aCriteria The search criteria. +@return The index of the first matching item in the view. KErrNotFound if the +view is empty or if none match. */ + { + const TInt NumberOfCharsToCompare=1; + TInt result=KErrNotFound; + TInt min=0; + TInt max=iView.CountL()-1; + if (max<0) + { + // The parent view is empty. + return KErrNotFound; + } + TBool finished=EFalse; + + HBufC* sortableText; + while (!finished) + { + TInt guess; + if (max==min) + { + finished=ETrue; + } + + guess=(max-min)/2+min; + sortableText = iView.AllFieldsLC(guess,KNullDesC); + TInt compare=sortableText->Left(NumberOfCharsToCompare).CompareC(aMatch.Left(NumberOfCharsToCompare),3,iCollateMethod); + CleanupStack::PopAndDestroy();//sortableText + switch (aCriteria) + { + case ELessThan: + { + if (compare>0 || compare==0) + { + // String is greater than aMatch. + max=guess-1; + if (maxmax) + { + finished=ETrue; + } + if (result==KErrNotFound || guess>result) + { + // guess is a closer match, so overwrite result. + result=guess; + } + } + break; + } + case ELessThanOrEqualTo: + { + if (compare>0) + { + // String is greater than aMatch. + max=guess-1; + if (maxmax) + { + finished=ETrue; + } + if (result==KErrNotFound || guess>result) + { + // guess is a closer match, so overwrite result. + result=guess; + } + } + break; + } + case EGreaterThan: + { + if (compare<0 || compare==0) + { + // String is less than aMatch. + min=guess+1; + if (min>max) + { + finished=ETrue; + } + } + else if (compare>0) + { + // String is greater than aMatch - possible hit. + max=guess-1; + if (maxmax) + { + finished=ETrue; + } + } + else if (compare>=0) + { + // String is >= aMatch - possible hit. + max=guess-1; + if (maxCompareC(aMatch,3,iCollateMethod); + + switch(aCriteria) + { + case ELessThan: + { + if(compare<0) + { + //RDebug::Print(_L("Match of %S against < %S PASSED\x0D\x00\x0a\x00"),&sortableText,&aMatch); + match=ETrue; + } + else + { + //RDebug::Print(_L("Match of %S against < %S FAILED\x0D\x00\x0a\x00"),&sortableText,&aMatch); + } + break; + }; + case ELessThanOrEqualTo: + { + if(compare<=0) + match=ETrue; + break; + }; + case EGreaterThan: + { + if(compare>0) + match=ETrue; + break; + }; + case EGreaterThanOrEqualTo: + { + if(compare>=0) + { + //RDebug::Print(_L("Match of %S against >= %S PASSED\x0D\x00\x0a\x00"),&sortableText,&aMatch); + match=ETrue; + } + else + { + //RDebug::Print(_L("Match of %S against >= %S FAILED\x0D\x00\x0a\x00"),&sortableText,&aMatch); + } + break; + }; + }; + + return match; + } + +void CContactViewRangeBase::ValidateIndices() +/** Called by derived classes to validate the upper and lower indexes (iLow and +iHigh). + +If either index is KErrNotFound, or iLow is greater than iHigh, then both +are set to KErrNotFound. +@internalComponent +*/ + { + // Check that range isn't inside out, and both ranges are valid. + if (iLow>iHigh || iHigh==KErrNotFound || iLow==KErrNotFound) + { + // Invalidate both indicies. + iLow=KErrNotFound; + iHigh=KErrNotFound; + } + } + +// +// CContactViewRange +// + + +CContactViewRange::CContactViewRange(const CContactViewBase& aView,const TDesC& aLowMatch,TCriteria aLowCriteria,const TDesC& aHighMatch,TCriteria aHighCriteria) + :CContactViewRangeBase(aView),iLowMatch(aLowMatch),iLowCriteria(aLowCriteria),iHighMatch(aHighMatch),iHighCriteria(aHighCriteria) + { + } + +EXPORT_C CContactViewRange* CContactViewRange::NewL(const CContactViewBase& aView,const TDesC& aLowMatch,TCriteria aLowCriteria,const TDesC& aHighMatch,TCriteria aHighCriteria) +/** Allocates and constructs a new sub view range. + +@param aView The sub view's underlying view. +@param aLowMatch The match string for the bottom of the range. Only the first +character in the string is used. +@param aLowCriteria The query search condition for the bottom of the range; +either CContactViewRangeBase::EGreaterThan or CContactViewRangeBase::EGreaterThanOrEqualTo. +@param aHighMatch The match string for the top of the range. Only the first +character in the string is used. +@param aHighCriteria The query search condition for the top of the range; either +CContactViewRangeBase::ELessThan or CContactViewRangeBase::ELessThanOrEqualTo. +@return Pointer to a newly created sub view range object */ + { +#ifdef CNTVIEW_API_PROFILING + RDebug::Print(_L("[CNTMODEL] CContactViewRange::NewL()\n")); +#endif + CContactViewRange* self=new(ELeave) CContactViewRange(aView,aLowMatch,aLowCriteria,aHighMatch,aHighCriteria); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); // self. + return self; + } + +CContactViewRange::~CContactViewRange() +/** Destructor. */ + { + } + +void CContactViewRange::ConstructL() + { + CContactViewRangeBase::ConstructL(); + } + +void CContactViewRange::SetL() + { + iLow=FindIndexL(iLowMatch,iLowCriteria); + iHigh=FindIndexL(iHighMatch,iHighCriteria); + ValidateIndices(); + } + + +// +// CContactViewLowRange +// + +CContactViewLowRange::CContactViewLowRange(const CContactViewBase& aView,const TDesC& aMatch,TCriteria aCriteria) + : CContactViewRangeBase(aView),iMatch(aMatch),iCriteria(aCriteria) + { + } + +CContactViewLowRange::~CContactViewLowRange() + { + } + +EXPORT_C CContactViewLowRange* CContactViewLowRange::NewL(const CContactViewBase& aView,const TDesC& aMatch,TCriteria aCriteria) +/** Allocates and constructs a CContactViewLowRange object. + +@param aView The sub view's underlying view. +@param aMatch The string to match items against. Only the first character in +the string is used. +@param aCriteria The query search condition; either CContactViewRangeBase::ELessThanOrEqualTo +or CContactViewRangeBase::ELessThan. +@return Pointer to a newly created CContactViewLowRange object */ + { +#ifdef CNTVIEW_API_PROFILING + RDebug::Print(_L("[CNTMODEL] CContactViewLowRange::NewL()\n")); +#endif + CContactViewLowRange* self=new(ELeave) CContactViewLowRange(aView,aMatch,aCriteria); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); // self. + return self; + } + +void CContactViewLowRange::SetL() + { + iHigh=FindIndexL(iMatch,iCriteria); + if(iHigh!=KErrNotFound && iHigh >=0) + { + iLow=0; + } + ValidateIndices(); + } + + +// +// CContactViewHighRange +// + +CContactViewHighRange::CContactViewHighRange (const CContactViewBase& aView,const TDesC& aMatch,TCriteria aCriteria) + : CContactViewRangeBase(aView),iMatch(aMatch),iCriteria(aCriteria) + { + } + +CContactViewHighRange::~CContactViewHighRange() + { + } + +EXPORT_C CContactViewHighRange * CContactViewHighRange::NewL(const CContactViewBase& aView,const TDesC& aMatch,TCriteria aCriteria) +/** Allocates and constructs a CContactViewHighRange object. + +@param aView The sub view's underlying view. +@param aMatch The string to match items against. Only the first character in +the string is used. +@param aCriteria The query search condition; either CContactViewRangeBase::EGreaterThan +or CContactViewRangeBase::EGreaterThanOrEqualTo. +@return Pointer to newly created CContactViewHighRange object */ + { +#ifdef CNTVIEW_API_PROFILING + RDebug::Print(_L("[CNTMODEL] CContactViewHighRange::NewL()\n")); +#endif + CContactViewHighRange * self=new(ELeave) CContactViewHighRange (aView,aMatch,aCriteria); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); // self. + return self; + } + +void CContactViewHighRange::SetL() + { + iLow=FindIndexL(iMatch,iCriteria); + if (iLow!=KErrNotFound) + { + iHigh=iView.CountL()-1; + } + ValidateIndices(); + }