phonebookengines/contactsmodel/cntview/Range.cpp
changeset 0 e686773b3f54
child 24 0ba2181d7c28
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <cntview.h>
       
    17 #include "CNTSTD.H"
       
    18 #include <collate.h>
       
    19 
       
    20 
       
    21 
       
    22 //#define CNTVIEW_API_PROFILING
       
    23 
       
    24 
       
    25 //
       
    26 // CContactViewRangeBase
       
    27 //
       
    28 
       
    29 /**
       
    30 @internalComponent
       
    31 */
       
    32 CContactViewRangeBase::CContactViewRangeBase(const CContactViewBase& aView)
       
    33 	: iView(aView),iLow(KErrNotFound),iHigh(KErrNotFound)
       
    34 	{
       
    35 	}
       
    36 
       
    37 CContactViewRangeBase::~CContactViewRangeBase()
       
    38 	{
       
    39 	delete iCollateMethod;
       
    40 	}
       
    41 
       
    42 void CContactViewRangeBase::ConstructL()
       
    43 /** Called by derived classes to set the collation method iCollateMethod to be 
       
    44 the standard collation method for the current locale.
       
    45 @internalComponent
       
    46 */
       
    47 	{
       
    48 	// Needed to ensure unicode sorting / inserting into sorted lists works the same as ER5,
       
    49 	// i.e. that it encludes all spaces and punctuation.
       
    50 	iCollateMethod = new(ELeave) TCollationMethod;
       
    51 	*iCollateMethod = *Mem::CollationMethodByIndex(0);
       
    52 	iCollateMethod->iFlags|=TCollationMethod::EIgnoreNone;
       
    53 	}
       
    54 
       
    55 EXPORT_C TBool CContactViewRangeBase::IndicesValid() const
       
    56 /** Tests whether the lower and upper indexes are valid, i.e. not KErrNotFound.
       
    57 
       
    58 @return ETrue if the indexes are valid, EFalse if not. */
       
    59 	{
       
    60 	if (iLow==KErrNotFound)
       
    61 		{
       
    62 		ASSERT(iHigh==KErrNotFound);
       
    63 		return EFalse;
       
    64 		}
       
    65 	return ETrue;
       
    66 	}
       
    67 
       
    68 TInt CContactViewRangeBase::FindIndexL(const TDesC& aMatch,TCriteria aCriteria) const
       
    69 // Binary search through iView to find the first contact that matches aMatch according to aCritera.
       
    70 /** Called by implementations of SetL() to search the sub view's underlying view 
       
    71 for the index of the first item whose field content matches aMatch, using 
       
    72 the specified search criteria.
       
    73 
       
    74 @internalComponent
       
    75 @param aMatch The text to search for. 
       
    76 @param aCriteria The search criteria. 
       
    77 @return The index of the first matching item in the view. KErrNotFound if the 
       
    78 view is empty or if none match. */
       
    79 	{
       
    80 	const TInt NumberOfCharsToCompare=1;
       
    81 	TInt result=KErrNotFound;
       
    82 	TInt min=0;
       
    83 	TInt max=iView.CountL()-1;
       
    84 	if (max<0)
       
    85 		{
       
    86 		// The parent view is empty.
       
    87 		return KErrNotFound;
       
    88 		}
       
    89 	TBool finished=EFalse;
       
    90 
       
    91 	HBufC* sortableText;
       
    92 	while (!finished)
       
    93 		{
       
    94 		TInt guess;
       
    95 		if (max==min)
       
    96 			{
       
    97 			finished=ETrue;
       
    98 			}
       
    99 
       
   100 		guess=(max-min)/2+min;
       
   101 		sortableText = iView.AllFieldsLC(guess,KNullDesC);
       
   102 		TInt compare=sortableText->Left(NumberOfCharsToCompare).CompareC(aMatch.Left(NumberOfCharsToCompare),3,iCollateMethod);
       
   103 		CleanupStack::PopAndDestroy();//sortableText
       
   104 		switch (aCriteria)
       
   105 			{
       
   106 			case ELessThan: 
       
   107 				{ 
       
   108 				if (compare>0 || compare==0)
       
   109 					{
       
   110 					// String is greater than aMatch.
       
   111 					max=guess-1;
       
   112 					if (max<min)
       
   113 						{
       
   114 						finished=ETrue;
       
   115 						}
       
   116 					}
       
   117 				else if (compare<0)
       
   118 					{
       
   119 					// String is less than aMatch - could be a hit.
       
   120 					min=guess+1;
       
   121 					if (min>max)
       
   122 						{
       
   123 						finished=ETrue;
       
   124 						}
       
   125 					if (result==KErrNotFound || guess>result)
       
   126 						{
       
   127 						// guess is a closer match, so overwrite result.
       
   128 						result=guess;
       
   129 						}
       
   130 					}
       
   131 				break;
       
   132 				}
       
   133 			case ELessThanOrEqualTo: 
       
   134 				{
       
   135 				if (compare>0)
       
   136 					{
       
   137 					// String is greater than aMatch.
       
   138 					max=guess-1;
       
   139 					if (max<min)
       
   140 						{
       
   141 						finished=ETrue;
       
   142 						}
       
   143 					}
       
   144 				else if (compare<=0)
       
   145 					{
       
   146 					// String is less than or equal to aMatch - possible hit.
       
   147 					min=guess+1;
       
   148 					if (min>max)
       
   149 						{
       
   150 						finished=ETrue;
       
   151 						}
       
   152 					if (result==KErrNotFound || guess>result)
       
   153 						{
       
   154 						// guess is a closer match, so overwrite result.
       
   155 						result=guess;
       
   156 						}
       
   157 					}
       
   158 				break;
       
   159 				}
       
   160 			case EGreaterThan: 
       
   161 				{
       
   162 				if (compare<0 || compare==0)
       
   163 					{
       
   164 					// String is less than aMatch.
       
   165 					min=guess+1;
       
   166 					if (min>max)
       
   167 						{
       
   168 						finished=ETrue;
       
   169 						}
       
   170 					}
       
   171 				else if (compare>0)
       
   172 					{
       
   173 					// String is greater than aMatch - possible hit.
       
   174 					max=guess-1;
       
   175 					if (max<min)
       
   176 						{
       
   177 						finished=ETrue;
       
   178 						}
       
   179 					if (result==KErrNotFound || guess<result)
       
   180 						{
       
   181 						// guess is a closer match, so overwrite result.
       
   182 						result=guess;
       
   183 						}
       
   184 					}
       
   185 				break;
       
   186 				}
       
   187 			case EGreaterThanOrEqualTo:
       
   188 				{
       
   189 				if (compare<0)
       
   190 					{
       
   191 					// String is less than aMatch.
       
   192 					min=guess+1;
       
   193 					if (min>max)
       
   194 						{
       
   195 						finished=ETrue;
       
   196 						}
       
   197 					}
       
   198 				else if (compare>=0)
       
   199 					{
       
   200 					// String is >= aMatch - possible hit.
       
   201 					max=guess-1;
       
   202 					if (max<min)
       
   203 						{
       
   204 						finished=ETrue;
       
   205 						}
       
   206 					if (result==KErrNotFound || guess<result)
       
   207 						{
       
   208 						// guess is a closer match, so overwrite result.
       
   209 						result=guess;
       
   210 						}
       
   211 					}
       
   212 				break;
       
   213 				}
       
   214 			};
       
   215 		}
       
   216 	return result;
       
   217 	}
       
   218 
       
   219 /**
       
   220 @internalComponent
       
   221 */
       
   222 TBool CContactViewRangeBase::MatchesCriteriaL(TCriteria aCriteria,const TDesC& aMatch,TInt aIndex) const
       
   223 	{
       
   224 	TBool match=EFalse;
       
   225 	HBufC* sortableText=iView.AllFieldsLC(aIndex,KNullDesC);
       
   226 	TInt compare=sortableText->CompareC(aMatch,3,iCollateMethod);
       
   227 
       
   228 	switch(aCriteria)
       
   229 		{
       
   230 		case ELessThan:
       
   231 			{
       
   232 			if(compare<0)
       
   233 				{
       
   234 				//RDebug::Print(_L("Match of %S against < %S PASSED\x0D\x00\x0a\x00"),&sortableText,&aMatch);
       
   235 				match=ETrue;
       
   236 				}
       
   237 			else
       
   238 				{
       
   239 				//RDebug::Print(_L("Match of %S against < %S FAILED\x0D\x00\x0a\x00"),&sortableText,&aMatch);
       
   240 				}
       
   241 			break;
       
   242 			};
       
   243 		case ELessThanOrEqualTo:
       
   244 			{
       
   245 			if(compare<=0)
       
   246 				match=ETrue;
       
   247 			break;
       
   248 			};
       
   249 		case EGreaterThan:
       
   250 			{
       
   251 			if(compare>0)
       
   252 				match=ETrue;
       
   253 			break;
       
   254 			};
       
   255 		case EGreaterThanOrEqualTo:
       
   256 			{
       
   257 			if(compare>=0)
       
   258 				{
       
   259 				//RDebug::Print(_L("Match of %S against >= %S PASSED\x0D\x00\x0a\x00"),&sortableText,&aMatch);
       
   260 				match=ETrue;
       
   261 				}
       
   262 			else
       
   263 				{
       
   264 				//RDebug::Print(_L("Match of %S against >= %S FAILED\x0D\x00\x0a\x00"),&sortableText,&aMatch);
       
   265 				}
       
   266 			break;
       
   267 			};
       
   268 		};
       
   269 
       
   270 	return match;
       
   271 	}
       
   272 
       
   273 void CContactViewRangeBase::ValidateIndices()
       
   274 /** Called by derived classes to validate the upper and lower indexes (iLow and 
       
   275 iHigh).
       
   276 
       
   277 If either index is KErrNotFound, or iLow is greater than iHigh, then both 
       
   278 are set to KErrNotFound. 
       
   279 @internalComponent
       
   280 */
       
   281 	{
       
   282 	// Check that range isn't inside out, and both ranges are valid.
       
   283 	if (iLow>iHigh || iHigh==KErrNotFound || iLow==KErrNotFound)
       
   284 		{
       
   285 		// Invalidate both indicies.
       
   286 		iLow=KErrNotFound;
       
   287 		iHigh=KErrNotFound;
       
   288 		}
       
   289 	}
       
   290 
       
   291 //
       
   292 // CContactViewRange
       
   293 //
       
   294 
       
   295 
       
   296 CContactViewRange::CContactViewRange(const CContactViewBase& aView,const TDesC& aLowMatch,TCriteria aLowCriteria,const TDesC& aHighMatch,TCriteria aHighCriteria)
       
   297 	:CContactViewRangeBase(aView),iLowMatch(aLowMatch),iLowCriteria(aLowCriteria),iHighMatch(aHighMatch),iHighCriteria(aHighCriteria)
       
   298 	{
       
   299 	}
       
   300 
       
   301 EXPORT_C CContactViewRange* CContactViewRange::NewL(const CContactViewBase& aView,const TDesC& aLowMatch,TCriteria aLowCriteria,const TDesC& aHighMatch,TCriteria aHighCriteria)
       
   302 /** Allocates and constructs a new sub view range.
       
   303 
       
   304 @param aView The sub view's underlying view. 
       
   305 @param aLowMatch The match string for the bottom of the range. Only the first 
       
   306 character in the string is used.
       
   307 @param aLowCriteria The query search condition for the bottom of the range; 
       
   308 either CContactViewRangeBase::EGreaterThan or CContactViewRangeBase::EGreaterThanOrEqualTo.
       
   309 @param aHighMatch The match string for the top of the range. Only the first 
       
   310 character in the string is used. 
       
   311 @param aHighCriteria The query search condition for the top of the range; either 
       
   312 CContactViewRangeBase::ELessThan or CContactViewRangeBase::ELessThanOrEqualTo.
       
   313 @return Pointer to a newly created sub view range object    */
       
   314 	{
       
   315 #ifdef CNTVIEW_API_PROFILING
       
   316 	RDebug::Print(_L("[CNTMODEL] CContactViewRange::NewL()\n"));
       
   317 #endif
       
   318 	CContactViewRange* self=new(ELeave) CContactViewRange(aView,aLowMatch,aLowCriteria,aHighMatch,aHighCriteria);
       
   319 	CleanupStack::PushL(self);
       
   320 	self->ConstructL();
       
   321 	CleanupStack::Pop(); // self.
       
   322 	return self;
       
   323 	}
       
   324 
       
   325 CContactViewRange::~CContactViewRange()
       
   326 /** Destructor. */
       
   327 	{
       
   328 	}
       
   329 
       
   330 void CContactViewRange::ConstructL()
       
   331 	{
       
   332 	CContactViewRangeBase::ConstructL();
       
   333 	}
       
   334 
       
   335 void CContactViewRange::SetL()
       
   336 	{
       
   337 	iLow=FindIndexL(iLowMatch,iLowCriteria);
       
   338 	iHigh=FindIndexL(iHighMatch,iHighCriteria);
       
   339 	ValidateIndices();
       
   340 	}
       
   341 
       
   342 
       
   343 //
       
   344 // CContactViewLowRange
       
   345 //
       
   346 
       
   347 CContactViewLowRange::CContactViewLowRange(const CContactViewBase& aView,const TDesC& aMatch,TCriteria aCriteria)
       
   348 	: CContactViewRangeBase(aView),iMatch(aMatch),iCriteria(aCriteria)
       
   349 	{
       
   350 	}
       
   351 
       
   352 CContactViewLowRange::~CContactViewLowRange()
       
   353 	{
       
   354 	}
       
   355 
       
   356 EXPORT_C CContactViewLowRange* CContactViewLowRange::NewL(const CContactViewBase& aView,const TDesC& aMatch,TCriteria aCriteria)
       
   357 /** Allocates and constructs a CContactViewLowRange object.
       
   358 
       
   359 @param aView The sub view's underlying view.
       
   360 @param aMatch The string to match items against. Only the first character in 
       
   361 the string is used.
       
   362 @param aCriteria The query search condition; either CContactViewRangeBase::ELessThanOrEqualTo 
       
   363 or CContactViewRangeBase::ELessThan.
       
   364 @return Pointer to a newly created CContactViewLowRange object  */
       
   365 	{
       
   366 #ifdef CNTVIEW_API_PROFILING
       
   367 	RDebug::Print(_L("[CNTMODEL] CContactViewLowRange::NewL()\n"));
       
   368 #endif
       
   369 	CContactViewLowRange* self=new(ELeave) CContactViewLowRange(aView,aMatch,aCriteria);
       
   370 	CleanupStack::PushL(self);
       
   371 	self->ConstructL();
       
   372 	CleanupStack::Pop(); // self.
       
   373 	return self;
       
   374 	}
       
   375 
       
   376 void CContactViewLowRange::SetL()
       
   377 	{
       
   378 	iHigh=FindIndexL(iMatch,iCriteria);
       
   379 	if(iHigh!=KErrNotFound && iHigh >=0)
       
   380 		{
       
   381 		iLow=0;
       
   382 		}
       
   383 	ValidateIndices();
       
   384 	}
       
   385 
       
   386 
       
   387 //
       
   388 // CContactViewHighRange 
       
   389 //
       
   390 
       
   391 CContactViewHighRange::CContactViewHighRange (const CContactViewBase& aView,const TDesC& aMatch,TCriteria aCriteria)
       
   392 	: CContactViewRangeBase(aView),iMatch(aMatch),iCriteria(aCriteria)
       
   393 	{
       
   394 	}
       
   395 
       
   396 CContactViewHighRange::~CContactViewHighRange()
       
   397 	{
       
   398 	}
       
   399 
       
   400 EXPORT_C CContactViewHighRange * CContactViewHighRange::NewL(const CContactViewBase& aView,const TDesC& aMatch,TCriteria aCriteria)
       
   401 /** Allocates and constructs a CContactViewHighRange object.
       
   402 
       
   403 @param aView The sub view's underlying view.
       
   404 @param aMatch The string to match items against. Only the first character in 
       
   405 the string is used.
       
   406 @param aCriteria The query search condition; either CContactViewRangeBase::EGreaterThan 
       
   407 or CContactViewRangeBase::EGreaterThanOrEqualTo. 
       
   408 @return Pointer to newly created CContactViewHighRange object  */
       
   409 	{
       
   410 #ifdef CNTVIEW_API_PROFILING
       
   411 	RDebug::Print(_L("[CNTMODEL] CContactViewHighRange::NewL()\n"));
       
   412 #endif
       
   413 	CContactViewHighRange * self=new(ELeave) CContactViewHighRange (aView,aMatch,aCriteria);
       
   414 	CleanupStack::PushL(self);
       
   415 	self->ConstructL();
       
   416 	CleanupStack::Pop(); // self.
       
   417 	return self;
       
   418 	}
       
   419 
       
   420 void CContactViewHighRange::SetL()
       
   421 	{
       
   422 	iLow=FindIndexL(iMatch,iCriteria);
       
   423 	if (iLow!=KErrNotFound)
       
   424 		{
       
   425 		iHigh=iView.CountL()-1;
       
   426 		}
       
   427 	ValidateIndices();
       
   428 	}