plugins/contacts/symbian/contactsmodel/cntplsql/src/csqlitelocalview.cpp
changeset 0 876b1a06bc25
equal deleted inserted replaced
-1:000000000000 0:876b1a06bc25
       
     1 /*
       
     2 * Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 /**
       
    20  @file
       
    21  @internalComponent
       
    22  @released
       
    23 */
       
    24 
       
    25 #include <cntviewbase.h>
       
    26 #include <cntitem.h>
       
    27 #include "cntviewprivate.h"
       
    28 #include <cntviewsortplugin.h>
       
    29 #include "persistencelayer.h"
       
    30 #include "cviewcontactmanager.h"
       
    31 #include "cntstd.h"
       
    32 #include <phbksync.h>
       
    33 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    34 #include <cntviewsortpluginbase.h>
       
    35 #endif
       
    36 //uncomment to test
       
    37 //#define __PROFILE_SORT__
       
    38 
       
    39 //uncomment for commonly required debug printing
       
    40 //#define __VERBOSE_DEBUG__
       
    41 
       
    42 //Define the patchable constants for the number of CViewContacts to read into memory 
       
    43 //before merging them into a larger sorted list (via a heap sort).This is actually used
       
    44 //in cviewcontactmanager.cpp but must be defined here so that the compiler can not 
       
    45 //perform any "constant folding" with the value   
       
    46 EXPORT_C extern const TInt KNumberOfContactsToReadPerMerge = 500;
       
    47 
       
    48 extern void DebugLogNotification(const TDesC& aMethod, const TContactDbObserverEvent &aEvent);
       
    49 
       
    50 
       
    51 //
       
    52 // CContactLocalView.
       
    53 //
       
    54 CContactLocalView::CContactLocalView(const CContactDatabase& aDb,TContactViewPreferences aContactTypes, MLplPersistenceLayerFactory* aFactory) 
       
    55 : CContactViewBase(aDb), 
       
    56   iFactory(aFactory),
       
    57   iContacts(), 
       
    58   iUnSortedContacts(),
       
    59   iViewPreferences(aContactTypes)
       
    60 	{
       
    61 	}
       
    62 
       
    63 	
       
    64 /**
       
    65 Protected C++ constructor.
       
    66 
       
    67 Called by NewL().
       
    68 
       
    69 @param aDb The underlying database that contains the contact items.
       
    70 @param aContactTypes Specifies which types of contact items should be included 
       
    71 in the view and the behaviour for items that do not have content in any of 
       
    72 the fields specified in the sort order. 
       
    73 */
       
    74 EXPORT_C CContactLocalView::CContactLocalView(const CContactDatabase& aDb,TContactViewPreferences aContactTypes) 
       
    75 : CContactViewBase(aDb), 
       
    76   iContacts(), 
       
    77   iUnSortedContacts(),
       
    78   iViewPreferences(aContactTypes)
       
    79 	{
       
    80 	}
       
    81 
       
    82 	
       
    83 /**
       
    84 Destructor.
       
    85 
       
    86 Deletes all resources owned by the object, and removes itself as the contact 
       
    87 database observer. 
       
    88 */
       
    89 EXPORT_C CContactLocalView::~CContactLocalView()
       
    90 	{
       
    91 #ifdef CONTACTS_API_PROFILING
       
    92 	TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewDestructor);
       
    93 #endif
       
    94 	delete iTextDef;
       
    95 	iContacts.ResetAndDestroy();
       
    96 	iUnSortedContacts.ResetAndDestroy();
       
    97 	iOutstandingEvents.Close();
       
    98 	iSortOrder.Close();
       
    99 
       
   100 	if (&iDb != NULL)
       
   101 		{
       
   102         const_cast<CContactDatabase&>(iDb).RemoveObserver(*this);
       
   103 		}
       
   104 		
       
   105 	delete iAsyncSorter; //Add this though we don't use it in local view any more
       
   106 	delete iViewCntMgr;
       
   107 	}
       
   108 
       
   109 	
       
   110 /**
       
   111 Allocates and constructs the local view object.
       
   112 
       
   113 The view is sorted according to the sort order and view preferences specified, 
       
   114 using a low priority idle time active object. The specified view observer 
       
   115 is notified when the view is sorted and ready for use.
       
   116 
       
   117 @param aObserver An observer that receives notifications when this view is 
       
   118 ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady 
       
   119 event when the view is ready. Any attempt to use the view before this notification will Leave with KErrNotReady
       
   120 @param aDb The underlying database that contains the contact items. The view 
       
   121 observes the database, so that it handles change events sent from the database.
       
   122 @param aSortOrder Specifies the fields to use to sort the items in the view.
       
   123 @param aContactTypes Specifies which types of contact items should be included 
       
   124 in the view and the behaviour for items that do not have content in any of 
       
   125 the fields specified in the sort order.
       
   126 @return The newly constructed local view object. 
       
   127 */
       
   128 EXPORT_C CContactLocalView* CContactLocalView::NewL(MContactViewObserver& aObserver,const CContactDatabase& aDb,
       
   129 													const RContactViewSortOrder& aSortOrder,TContactViewPreferences aContactTypes)
       
   130 	{
       
   131 #ifdef CONTACTS_API_PROFILING
       
   132 	TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiNewL, aSortOrder, aContactTypes);
       
   133 #endif
       
   134 	CContactLocalView* self = new(ELeave) CContactLocalView(aDb, aContactTypes);
       
   135 	CleanupStack::PushL(self);
       
   136 	self->ConstructL(aObserver, aSortOrder);
       
   137 	CleanupStack::Pop(self); 
       
   138 	return self;
       
   139 	}
       
   140 
       
   141 	
       
   142 /**
       
   143 Protected second phase constructor.
       
   144 
       
   145 The view is sorted according to the sort order and view preferences specified, 
       
   146 using a low priority idle time active object. The specified view observer 
       
   147 is notified when the view is sorted and ready for use.
       
   148 
       
   149 Called by NewL().
       
   150 
       
   151 @param aObserver An observer that receives notifications when this view is 
       
   152 ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady 
       
   153 event when the view is ready. Any attempt to use the view before this notification will Leave with KErrNotReady.
       
   154 @param aSortOrder Specifies the fields to use to sort the items in the view. 
       
   155 */
       
   156 EXPORT_C void CContactLocalView::ConstructL(MContactViewObserver& aObserver, const RContactViewSortOrder& aSortOrder)
       
   157 	{
       
   158 	// call new ConstructL
       
   159 	ConstructL(aObserver, aSortOrder, EFalse, KNullDesC8);
       
   160 	}
       
   161 
       
   162 	
       
   163 /**
       
   164 Allocates and constructs the local view object.
       
   165 
       
   166 The view is sorted according to the sort order and view preferences specified, 
       
   167 using a low priority idle time active object. The specified view observer 
       
   168 is notified when the view is sorted and ready for use.
       
   169 
       
   170 @param aObserver An observer that receives notifications when this view is 
       
   171 ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady 
       
   172 event when the view is ready. Any attempt to use the view before this notification will Leave with KErrNotReady
       
   173 @param aDb The underlying database that contains the contact items. The view 
       
   174 observes the database, so that it handles change events sent from the database.
       
   175 @param aSortOrder Specifies the fields to use to sort the items in the view.
       
   176 @param aContactTypes Specifies which types of contact items should be included 
       
   177 in the view and the behaviour for items that do not have content in any of 
       
   178 the fields specified in the sort order.
       
   179 @param aSortPluginName Specifies a plug-in that will be used to compare view contacts
       
   180 when the the view is sorted. This name is used by ECOM to select the plugin, and is matched
       
   181 with the "default_data" of all ECOM plugins that support the required interface.
       
   182 @return The newly constructed local view object. 
       
   183 */
       
   184 EXPORT_C CContactLocalView* CContactLocalView::NewL(MContactViewObserver& aObserver,const CContactDatabase& aDb, const RContactViewSortOrder& aSortOrder, TContactViewPreferences aContactTypes, const TDesC8& aSortPluginName)
       
   185 	{
       
   186 #ifdef CONTACTS_API_PROFILING
       
   187 	TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiNewL, aSortOrder, aContactTypes, aSortPluginName);
       
   188 #endif
       
   189 	CContactLocalView* self = new(ELeave) CContactLocalView(aDb, aContactTypes);
       
   190 	CleanupStack::PushL(self);
       
   191 	self->ConstructL(aObserver, aSortOrder, ETrue, aSortPluginName);
       
   192 	CleanupStack::Pop(self); 
       
   193 	return self;
       
   194 	}
       
   195 
       
   196 	
       
   197 /**
       
   198 CContactLocalView contructor, used in the server
       
   199 @internalTechnology 
       
   200 */
       
   201 EXPORT_C CContactLocalView* CContactLocalView::NewL(MContactViewObserver& aObserver,const CContactDatabase& aDb,const RContactViewSortOrder& aSortOrder,TContactViewPreferences aContactTypes, MLplPersistenceLayerFactory* aFactory, const TDesC8& aSortPluginName)
       
   202 	{
       
   203 	CContactLocalView* self = new (ELeave) CContactLocalView(aDb, aContactTypes, aFactory);
       
   204 	CleanupStack::PushL(self);
       
   205 	self->ConstructL(aObserver, aSortOrder, ETrue, aSortPluginName);
       
   206 	CleanupStack::Pop(self); 
       
   207 	return self;
       
   208 	}
       
   209 
       
   210 	
       
   211 /**
       
   212 Protected second phase constructor.
       
   213 
       
   214 The view is sorted according to the sort order and view preferences specified, 
       
   215 using a low priority idle time active object. The specified view observer 
       
   216 is notified when the view is sorted and ready for use.
       
   217 
       
   218 Called by NewL().
       
   219 
       
   220 @param aObserver An observer that receives notifications when this view is 
       
   221 ready for use and when changes take place in it. The observer receives a TContactViewEvent::EReady 
       
   222 event when the view is ready. Any attempt to use the view before this notification will Leave with KErrNotReady.
       
   223 @param aSortOrder Specifies the fields to use to sort the items in the view. 
       
   224 @param aUseNamedPlugin A flag indicates whether the aSortPluginName parameter is valid.
       
   225 @param aSortPluginName Specifies a plug-in that will be used to compare view contacts
       
   226 when the the view is sorted. This name is used by ECOM to select the plugin, and is matched
       
   227 with the "default_data" of all ECOM plugins that support the required interface.
       
   228 */
       
   229 void CContactLocalView::ConstructL(MContactViewObserver& aObserver,const RContactViewSortOrder& aSortOrder, TBool aUseNamedPlugin, const TDesC8& aSortPluginName)
       
   230 	{
       
   231 	CContactViewBase::ConstructL();
       
   232 	if(iFactory == NULL)
       
   233 		{
       
   234 		iFactory = const_cast<CContactDatabase&>(iDb).FactoryL();
       
   235 		}
       
   236     
       
   237 	OpenL(aObserver);
       
   238 	if (aUseNamedPlugin)
       
   239 		{
       
   240 		// find and load Sort plug-in
       
   241 		if (aSortPluginName.Length())
       
   242 			{
       
   243 			TUid sortPluginUid = FindSortPluginImplL (aSortPluginName);
       
   244 			LoadViewSortPluginL(sortPluginUid, iViewPreferences);
       
   245 			}
       
   246 		}
       
   247 	else
       
   248 		{
       
   249 		// find and load default Sort plug-in (if any)
       
   250 		TUid sortPluginUid = FindDefaultViewSortPluginImplL();
       
   251 		if (sortPluginUid != KNullUid)
       
   252 			{
       
   253 			LoadViewSortPluginL(sortPluginUid, iViewPreferences);
       
   254 			}
       
   255 		}
       
   256 	
       
   257 	//Initialise sort order and textdef.
       
   258 	SetSortOrderL(aSortOrder);
       
   259 	
       
   260 	//Create view contact manager to handle sorting
       
   261     iViewCntMgr = CViewContactManager::NewL(*this, *iFactory, *iTextDef, iViewPreferences, SortPluginImpl());
       
   262 	
       
   263 	if (&iDb != NULL)
       
   264 		{
       
   265         const_cast<CContactDatabase&>(iDb).AddObserverL(*this);
       
   266 		}
       
   267 	
       
   268 	//Doing the sort.
       
   269 	SortL();
       
   270 	}
       
   271 
       
   272 
       
   273 /**
       
   274 Gets the sort order, as set during construction.
       
   275 
       
   276 @return The sort order. 
       
   277 */
       
   278 EXPORT_C const RContactViewSortOrder& CContactLocalView::SortOrder() const
       
   279 	{
       
   280 #ifdef CONTACTS_API_PROFILING
       
   281 	TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiSortOrder);
       
   282 #endif
       
   283 	return iSortOrder;
       
   284 	}
       
   285 
       
   286 	
       
   287 /**
       
   288 Returns the ID of the contact item at a specified index into the view.
       
   289 
       
   290 @param aIndex An index into the view.
       
   291 @leave KErrNotFound The index is out of bounds.
       
   292 @return The ID of the contact item at the specified index.
       
   293 @leave KErrNotReady The view is not ready for use.  
       
   294 */
       
   295 TContactItemId CContactLocalView::AtL(TInt aIndex) const
       
   296 	{
       
   297 #ifdef CONTACTS_API_PROFILING
       
   298 	TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiAtL, aIndex);
       
   299 #endif
       
   300 	return iViewCntMgr->AtL(aIndex);
       
   301 	}
       
   302 
       
   303 	
       
   304 /**
       
   305 Returns the contact item at a specified index into the view.
       
   306 
       
   307 @param aIndex An index into the view.
       
   308 @leave KErrNotFound The index is out of bounds.
       
   309 @leave KErrNotReady The view is not ready for use.
       
   310 @return The reference to the copy of contact item at the specified index. 
       
   311 */
       
   312 const CViewContact& CContactLocalView::ContactAtL(TInt aIndex) const
       
   313 	{
       
   314 #ifdef CONTACTS_API_PROFILING
       
   315 	TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiContactAtL, aIndex);
       
   316 #endif
       
   317 	// state cannot be EInitializing or ENotReady
       
   318 	if( iState != EReady )
       
   319 		{
       
   320 		User::Leave(KErrNotReady);
       
   321 		}
       
   322 
       
   323 	return iViewCntMgr->ContactAtL(aIndex);
       
   324 	}
       
   325 
       
   326 	
       
   327 /**
       
   328 Gets the total number of contact items in the view.
       
   329 
       
   330 @return The number of contact items in the view. This includes both sorted 
       
   331 and unsorted items.
       
   332 @leave KErrNotReady The view is not ready for use. 
       
   333 */
       
   334 TInt CContactLocalView::CountL() const
       
   335 	{
       
   336 #ifdef CONTACTS_API_PROFILING
       
   337 	TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiCountL);
       
   338 #endif
       
   339 	// state cannot be EInitializing or ENotReady
       
   340 	if( iState != EReady )
       
   341 		{
       
   342 		User::Leave(KErrNotReady);
       
   343 		}
       
   344 	
       
   345 	return iViewCntMgr->Count();
       
   346 	}
       
   347 
       
   348 	
       
   349 /**
       
   350 Searches for a contact item in the view with the specified ID.
       
   351 
       
   352 @param aId The ID of the contact item to search for.
       
   353 @return If found, the index into the view of the matching item. Otherwise, 
       
   354 KErrNotFound.
       
   355 @leave KErrNotReady The view is not ready for use.  
       
   356 */
       
   357 TInt CContactLocalView::FindL(TContactItemId aId) const
       
   358 	{
       
   359 #ifdef CONTACTS_API_PROFILING
       
   360 	TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiFindL, aId);
       
   361 #endif
       
   362 	// state cannot be EInitializing or ENotReady
       
   363 	if( iState != EReady )
       
   364 		{
       
   365 		User::Leave(KErrNotReady);
       
   366 		}
       
   367 
       
   368 	return iViewCntMgr->FindL(aId);
       
   369 	}
       
   370 
       
   371 	
       
   372 /**
       
   373 Gets a descriptor containing the contents of all fields specified in the view's 
       
   374 sort order for an item in the view.
       
   375 
       
   376 The field separator is used to separate the contents of each field. It is 
       
   377 not appended to the last field.
       
   378 
       
   379 @param aIndex The index of the contact item into the view.
       
   380 @param aSeparator The string to use to separate the fields.
       
   381 @return Pointer to the contact item descriptor. 
       
   382 */
       
   383 HBufC* CContactLocalView::AllFieldsLC(TInt aIndex,const TDesC& aSeparator) const
       
   384 	{
       
   385 #ifdef CONTACTS_API_PROFILING
       
   386 	TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiAllFieldsLC, aIndex);
       
   387 #endif
       
   388 	if( iState != EReady )
       
   389 		{
       
   390 		User::Leave(KErrNotReady);
       
   391 		}
       
   392 
       
   393 	return iViewCntMgr->AllFieldsLC(aIndex, aSeparator);
       
   394 	}
       
   395 
       
   396 	
       
   397 /**
       
   398 Sorts the view using the specified sort order, using a low priority idle time 
       
   399 active object.
       
   400 
       
   401 This function is called during view construction and on receipt of certain 
       
   402 change events from the underlying database.
       
   403 
       
   404 @param aSortOrder Specifies the fields to use to sort the items in the view. 
       
   405 */
       
   406 EXPORT_C void CContactLocalView::SortL(const RContactViewSortOrder& aSortOrder)
       
   407 	{
       
   408 #ifdef CONTACTS_API_PROFILING
       
   409 	TContactsApiProfile::CntViewMethodLog(TContactsApiProfile::ECntVwClassLocalView, TContactsApiProfile::ECntViewApiSortL);
       
   410 #endif
       
   411 
       
   412 	if (&iDb != NULL)
       
   413 		{
       
   414 		if (!iDb.DatabaseReadyL())
       
   415 			{
       
   416 			User::Leave(KErrNotReady);
       
   417 			}
       
   418 		}
       
   419 	
       
   420 	//set new sort order which also updates iTextDef.
       
   421 	SetSortOrderL(aSortOrder);	
       
   422 	
       
   423 	// reset sort error
       
   424 	iExtension->iError = KErrNone;
       
   425 	iViewCntMgr->SortL(*iTextDef);
       
   426 	}
       
   427 
       
   428 
       
   429 /**
       
   430  Set sort order used to sorting the view contacts.
       
   431  */
       
   432 void CContactLocalView::SetSortOrderL(const RContactViewSortOrder& aSortOrder)
       
   433 	{
       
   434 	// copy new sort order
       
   435 	iSortOrder.CopyL(aSortOrder);
       
   436 	
       
   437 	// New sort order for Sort Plugin
       
   438 	CViewContactSortPlugin* sortPluginImpl = SortPluginImpl();
       
   439 	if (sortPluginImpl)
       
   440 		{
       
   441 		sortPluginImpl->SetSortOrderL(aSortOrder);
       
   442 		}
       
   443 
       
   444 	// Initialisation for each explicitly requested sort or initialise sort
       
   445 	// Construct a text def to read out the required fields from the db.
       
   446 	CContactTextDef* textDef=CContactTextDef::NewLC();
       
   447 	TInt sortOrderCount=iSortOrder.Count();
       
   448 
       
   449 	for (TInt sortIndex=0;sortIndex<sortOrderCount;sortIndex++)
       
   450 		{
       
   451 		textDef->AppendL(TContactTextDefItem(iSortOrder[sortIndex]));
       
   452 		}
       
   453 	CleanupStack::Pop(); // textDef.
       
   454 	
       
   455 	delete iTextDef;
       
   456 	iTextDef=textDef;
       
   457 	}
       
   458 
       
   459 
       
   460 /**
       
   461 Start sorting if database is ready
       
   462 */
       
   463 void CContactLocalView::SortL()
       
   464 	{
       
   465 	// View can Sort only if database is 'ready'.
       
   466 	if (&iDb != NULL)
       
   467 		{
       
   468 		if (!iDb.DatabaseReadyL())
       
   469 			{
       
   470 			return;
       
   471 			}
       
   472 		}
       
   473 
       
   474 	// reset sort error
       
   475 	iExtension->iError = KErrNone;
       
   476 	iViewCntMgr->SortL();
       
   477 	}
       
   478 
       
   479 
       
   480 /**
       
   481 Unleavable(safe) resorting
       
   482 */
       
   483 void CContactLocalView::SafeResort()
       
   484 	{
       
   485 	TRAPD(sortError, SortL());
       
   486 
       
   487 	// notify any error
       
   488 	if (sortError)
       
   489 		{
       
   490 		NotifySortError(sortError);
       
   491 		}
       
   492 	}
       
   493 
       
   494 	
       
   495 /**
       
   496 Inserts a contact item into the view, maintaining the view's sort order.
       
   497 
       
   498 For the item to be inserted, it must exist in the underlying database, and 
       
   499 it must be of the correct type according to the view preferences.
       
   500 
       
   501 This function is called when a contact item or group is added to or changed 
       
   502 in the underlying database.
       
   503 
       
   504 @param aId The ID of a contact item that exists in the underlying database.
       
   505 @return The index at which the item was inserted into the view, or KErrNotFound 
       
   506 if the contact item was not found in the underlying database, or it already 
       
   507 exists in the view. 
       
   508 */
       
   509 EXPORT_C TInt CContactLocalView::InsertL(TContactItemId aId)
       
   510 	{
       
   511 #if defined(__VERBOSE_DEBUG__)
       
   512 	RDebug::Print(_L("[CNTMODEL] CContactLocalView{ViewPrefs = 0x%08X}::InsertL into view Contact Id %i\r\n"), 
       
   513 		iViewPreferences, aId);
       
   514 #endif
       
   515 
       
   516 	TContactViewPreferences view = iViewPreferences;
       
   517 	return iViewCntMgr->InsertL(aId, view);
       
   518 	}
       
   519 
       
   520 	
       
   521 /**
       
   522 Removes a contact item from the view.
       
   523 
       
   524 This function is called when a contact item or group is deleted from or changed 
       
   525 in the underlying database.
       
   526 
       
   527 @param aId The ID of the contact item to remove from the view.
       
   528 @return The index of the removed item into the view's list of sorted or unsorted 
       
   529 contact items, or KErrNotFound if the item was not found in the view. 
       
   530 */
       
   531 EXPORT_C TInt CContactLocalView::RemoveL(TContactItemId aId)
       
   532 	{
       
   533 	return iViewCntMgr->RemoveL(aId);
       
   534 	}
       
   535 
       
   536 EXPORT_C void CContactLocalView::CContactLocalView_Reserved_1()
       
   537 	{
       
   538 	}
       
   539 
       
   540 EXPORT_C void CContactLocalView::CContactLocalView_Reserved_2()
       
   541 	{
       
   542 	}
       
   543 
       
   544 
       
   545 /**
       
   546 Database event handler.
       
   547 
       
   548 @param aEvent the database event.
       
   549 */
       
   550 void CContactLocalView::HandleDatabaseEventL(TContactDbObserverEvent aEvent)
       
   551 	{
       
   552 	// handle Backup / Restore notifications before checking View State
       
   553 	switch (aEvent.iType)
       
   554 		{
       
   555 		case EContactDbObserverEventBackupBeginning:
       
   556 		case EContactDbObserverEventRestoreBeginning:
       
   557 #if defined(__VERBOSE_DEBUG__)
       
   558 			RDebug::Print(_L("[CNTMODEL] CContactLocalView{ViewPrefs = 0x%08X}::HandleDatabaseEventL -> Backup/Restore Beginning, state = %i\r\n"), 
       
   559 				iViewPreferences, iState);
       
   560 #endif
       
   561 			if (iState == EReady)
       
   562 				{
       
   563 				SetState(ENotReady);
       
   564 				}
       
   565 			else
       
   566 				{
       
   567 				// stop sorting
       
   568 				iViewCntMgr->StopSortL();
       
   569 				}
       
   570 			return;
       
   571 
       
   572 		case EContactDbObserverEventBackupRestoreCompleted:
       
   573 #if defined(__VERBOSE_DEBUG__)
       
   574 			RDebug::Print(_L("[CNTMODEL] CContactLocalView{ViewPrefs = 0x%08X}::HandleDatabaseEventL -> Backup/Restore Completed, state = %i, old sort error %i\r\n"), 
       
   575 				iViewPreferences, iState, iExtension->iError);
       
   576 #endif
       
   577 			if (iState == ENotReady && iExtension->iError == KErrNone)
       
   578 				{
       
   579 				// view was ready before tables were closed
       
   580 				SetState(EReady);
       
   581 				}
       
   582 			else // view was Initializing (sorting) before tables were closed
       
   583 				{
       
   584 				// re-read database and sort
       
   585 				SafeResort();
       
   586 				}
       
   587 			return;
       
   588 
       
   589 		default:
       
   590 			// other events dealt with below
       
   591 			break;
       
   592 		}
       
   593 
       
   594 
       
   595 	if (iState!=EReady)
       
   596 		{
       
   597 		if (iViewCntMgr->IsICCSynchronised())
       
   598 			{
       
   599 			/*
       
   600 			 * View events are only queued when the ICC has been synchronised. This prevents
       
   601 			 * duplicate contacts in an ICC view because add events are not queued until the 
       
   602 			 * SIM is fully synchronised. 
       
   603 			 * 
       
   604 			 * See LUD-5EBHZF "ICC contacts view broadcasts add item events after view is 
       
   605 			 * ready" for more detail.
       
   606        		 */
       
   607 			
       
   608 #if defined(__VERBOSE_DEBUG__)
       
   609 			DebugLogNotification(_L("[CNTMODEL] . . . . . Queueing Database Event "), aEvent);
       
   610 #endif
       
   611 			iOutstandingEvents.AppendL(aEvent);
       
   612 			
       
   613             // The view state is set to ENotReady when a recovery takes place, and also when the tables
       
   614             // are closed, so set ready here.
       
   615             if (iState == ENotReady && (aEvent.iType
       
   616                     == EContactDbObserverEventRecover || aEvent.iType
       
   617                     == EContactDbObserverEventTablesOpened))
       
   618                 {
       
   619                 SetState(EReady);
       
   620                 }
       
   621             // view was Initializing (sorting) before recovery or compression started!  
       
   622             if (iState == EInitializing && (aEvent.iType
       
   623                     == EContactDbObserverEventRecover || aEvent.iType
       
   624                     == EContactDbObserverEventCompress))
       
   625                 {
       
   626                 // re-read database and sort
       
   627                 SafeResort();
       
   628                 }
       
   629                 
       
   630 			}		
       
   631 			
       
   632 			
       
   633 #if defined(__VERBOSE_DEBUG__)
       
   634 		else
       
   635 			{
       
   636 			DebugLogNotification(_L("[CNTMODEL] . . . . . Discarding Database Event "), aEvent);
       
   637 			}
       
   638 #endif
       
   639 		}
       
   640 	else
       
   641 		{
       
   642 		TContactViewEvent event;
       
   643 		event.iInt = KErrNone;
       
   644 		switch(aEvent.iType)
       
   645 			{
       
   646 			case EContactDbObserverEventGroupChanged:
       
   647 			case EContactDbObserverEventContactChanged:
       
   648 			case EContactDbObserverEventOwnCardChanged:
       
   649 				{
       
   650 				if (aEvent.iType == EContactDbObserverEventGroupChanged)
       
   651 				    {
       
   652 	    			//Groups are a special case the base view may not contain the group
       
   653     				//but a sub view may be such a group and need to know its changed
       
   654 				    event.iEventType=TContactViewEvent::EGroupChanged;
       
   655 				    event.iContactId=aEvent.iContactId;
       
   656 				    NotifyObservers(event);
       
   657 				    }
       
   658 				
       
   659 				// Remove from old position, and notify.
       
   660 				TRAPD(err,event.iInt=RemoveL(aEvent.iContactId));
       
   661 
       
   662                 if (err == KErrNone && event.iInt != KErrNotFound)
       
   663                     {
       
   664 				    event.iEventType=TContactViewEvent::EItemRemoved;
       
   665 				    event.iContactId=aEvent.iContactId;
       
   666 				    NotifyObservers(event);
       
   667 					}
       
   668 				
       
   669 				// Insert at new position, and notify.
       
   670 				event.iInt=InsertL(aEvent.iContactId);
       
   671                 if (event.iInt != KErrNotFound)
       
   672 					{
       
   673 				    event.iEventType=TContactViewEvent::EItemAdded;
       
   674 				    event.iContactId=aEvent.iContactId;
       
   675 				    NotifyObservers(event);
       
   676                     }
       
   677 				break;
       
   678 				}
       
   679 			case EContactDbObserverEventContactAdded:
       
   680 			case EContactDbObserverEventGroupAdded:
       
   681 #if defined(__VERBOSE_DEBUG__)
       
   682 			DebugLogNotification(_L("[CNTMODEL] DatabaseEvent -> Contact/Group Added"), aEvent);
       
   683 #endif
       
   684 				event.iInt=InsertL(aEvent.iContactId);
       
   685 				if (event.iInt != KErrNotFound)
       
   686 					{
       
   687 					event.iEventType=TContactViewEvent::EItemAdded;
       
   688 					event.iContactId=aEvent.iContactId;
       
   689 					NotifyObservers(event);
       
   690 					}
       
   691 				break;
       
   692 			case EContactDbObserverEventContactDeleted:
       
   693 				if(aEvent.iContactId == KNullContactId) // KNullContactId indicates a bulk delete.
       
   694 					{ 
       
   695 					SetState(EInitializing); // Use initializing state to avoid ESortOrderChanged event being sent to observers. 
       
   696 					SafeResort(); 
       
   697 					} 
       
   698 				else 
       
   699 					{ 
       
   700 					event.iInt=RemoveL(aEvent.iContactId); 
       
   701 					if (event.iInt != KErrNotFound) 
       
   702 						{ 
       
   703 						event.iEventType=TContactViewEvent::EItemRemoved; 
       
   704 						event.iContactId=aEvent.iContactId; 
       
   705 						NotifyObservers(event); 
       
   706 						} 
       
   707 					} 
       
   708 				break; 
       
   709 			case EContactDbObserverEventGroupDeleted:
       
   710 			case EContactDbObserverEventOwnCardDeleted:
       
   711 				event.iInt=RemoveL(aEvent.iContactId);
       
   712 				if (event.iInt != KErrNotFound)
       
   713 					{
       
   714 					event.iEventType=TContactViewEvent::EItemRemoved;
       
   715 					event.iContactId=aEvent.iContactId;
       
   716 					NotifyObservers(event);
       
   717 					}
       
   718 				break;
       
   719 			case EContactDbObserverEventUnknownChanges:
       
   720 			case EContactDbObserverEventCurrentDatabaseChanged:
       
   721 				SetState(EInitializing); // Use initializing state to avoid ESortOrderChanged event being sent to observers.
       
   722 				SafeResort();
       
   723 				break;
       
   724 			case EContactDbObserverEventSortOrderChanged: // event is not currently used
       
   725 				SetState(ENotReady);
       
   726 				SafeResort();
       
   727 				break;
       
   728 			case EContactDbObserverEventTablesClosed:
       
   729 				if (iState == EReady)
       
   730 					{
       
   731 					SetState(ENotReady);
       
   732 					}
       
   733 				break;
       
   734 			case EContactDbObserverEventTablesOpened:
       
   735 				// re-read database and sort
       
   736 				SafeResort();
       
   737 				break;
       
   738 
       
   739 			case EContactDbObserverEventNull:
       
   740 			case EContactDbObserverEventUnused:
       
   741 			case EContactDbObserverEventRecover:
       
   742 			case EContactDbObserverEventCompress:
       
   743 			case EContactDbObserverEventRollback:
       
   744 			case EContactDbObserverEventTemplateChanged:
       
   745 			case EContactDbObserverEventTemplateDeleted:
       
   746 			case EContactDbObserverEventTemplateAdded:
       
   747 			case EContactDbObserverEventCurrentItemDeleted:
       
   748 			case EContactDbObserverEventCurrentItemChanged:				
       
   749 			case EContactDbObserverEventPreferredTemplateChanged:
       
   750 			case EContactDbObserverEventSpeedDialsChanged:
       
   751 			case EContactDbObserverEventRestoreBadDatabase:
       
   752 				break;
       
   753 
       
   754 			// these events should not come here, but be dealt with at the top of HandleDatabaseEventL
       
   755 			case EContactDbObserverEventBackupBeginning:
       
   756 			case EContactDbObserverEventRestoreBeginning:
       
   757 			case EContactDbObserverEventBackupRestoreCompleted:
       
   758 				break;
       
   759 				
       
   760 			default:
       
   761 				ASSERT(EFalse);
       
   762 			}
       
   763 		}
       
   764 	}
       
   765 
       
   766 	
       
   767 /**
       
   768 Called from view contact item manager to notify the sorting has finished.
       
   769 
       
   770 @param aSortErr error occurs in sorting or KErrNone if sorting completes without error.
       
   771 */
       
   772 void CContactLocalView::SortComplete(TInt aSortErr)
       
   773 	{
       
   774     if(aSortErr != KErrNone)
       
   775         {
       
   776 		NotifySortError(aSortErr);
       
   777 		return;
       
   778         }
       
   779         
       
   780 	if (iState != EInitializing)
       
   781 		{
       
   782 		//The view has just been re-sorted, notifiy observers ESortOrderChanged
       
   783 		iState = EReady;
       
   784 		NotifyObservers(TContactViewEvent(TContactViewEvent::ESortOrderChanged));
       
   785 		HandleOutstandingEvents();
       
   786 		}
       
   787 	else
       
   788 		{
       
   789 		// Sorted for the first time, notifiy ready
       
   790 		SetState(EReady);
       
   791 		}
       
   792 	}
       
   793 
       
   794 	
       
   795 /**
       
   796 Set database state
       
   797 
       
   798 @param aState database state to set.
       
   799 */
       
   800 void CContactLocalView::SetState(TState aState)
       
   801 	{
       
   802 	switch (iState)
       
   803 		{
       
   804 		case EInitializing:
       
   805 		case ENotReady:
       
   806 			ASSERT(aState==EReady);
       
   807 			iState=EReady;
       
   808 			NotifyObservers(TContactViewEvent(TContactViewEvent::EReady));
       
   809 			HandleOutstandingEvents();
       
   810 			break;
       
   811 		case EReady:
       
   812 			ASSERT(aState==ENotReady || aState==EInitializing);
       
   813 			// ensure sort error is reset
       
   814 			iExtension->iError = KErrNone;
       
   815 			iState=aState;
       
   816 			NotifyObservers(TContactViewEvent(TContactViewEvent::EUnavailable));
       
   817 			break;
       
   818 		default:
       
   819 			ASSERT(EFalse);
       
   820 		}
       
   821 	}
       
   822 
       
   823 
       
   824 /**
       
   825 Handle a particular queued event 
       
   826 */
       
   827 void CContactLocalView::HandleOutstandingEventL()
       
   828 	{
       
   829 	TContactDbObserverEvent event = iOutstandingEvents[0];
       
   830 	iOutstandingEvents.Remove(0);
       
   831 	HandleDatabaseEventL(event);
       
   832 	}
       
   833 
       
   834 /**
       
   835 Handle queued events when view is ready - sorting completes
       
   836 */
       
   837 void CContactLocalView::HandleOutstandingEvents()
       
   838 	{
       
   839 	while (iOutstandingEvents.Count() > 0)
       
   840 		{
       
   841 		// loop through as many events as possible in the one Trap harness
       
   842 		TRAP_IGNORE(HandleOutstandingEventL());
       
   843 		// if HandleDatabaseEventL left we must remove the event
       
   844 		}
       
   845 	}
       
   846 
       
   847 /**
       
   848 Gets the view preferences, as set during construction.
       
   849 
       
   850 @return The view preferences. 
       
   851 */
       
   852 TContactViewPreferences CContactLocalView::ContactViewPreferences()
       
   853 	{
       
   854 	return iViewPreferences;
       
   855 	}
       
   856 
       
   857 
       
   858 /**
       
   859 Gets the sort order, as set during construction.
       
   860 
       
   861 This function cannot leave.
       
   862 
       
   863 @return The sort order. 
       
   864 */
       
   865 const RContactViewSortOrder& CContactLocalView::SortOrderL() const
       
   866 	{
       
   867 	return iSortOrder;
       
   868 	}
       
   869 
       
   870 
       
   871 /**
       
   872 Notify observers that view construction failed.
       
   873 The error is stored so that if another client tries to open the view
       
   874 they will receive the same error.
       
   875 
       
   876 @param aError Leave code from CIdleContactSorter::RunL
       
   877 */
       
   878 void CContactLocalView::NotifySortError(TInt aError)
       
   879 	{
       
   880 	iExtension->iError = aError;
       
   881 	NotifyObservers(TContactViewEvent(TContactViewEvent::ESortError, aError));
       
   882 	}
       
   883 
       
   884 
       
   885 /**
       
   886 This is a reserved virtual exported function that is used for BC proofing 
       
   887 against present and future additions of new exported virtual functions.
       
   888 
       
   889 @return Any return values of the helper methods called from this function or NULL.
       
   890 */
       
   891 EXPORT_C TAny* CContactLocalView::CContactViewBase_Reserved_1(TFunction aFunction,TAny* aParams)
       
   892 	{
       
   893 	return CContactViewBase::CContactViewBase_Reserved_1(aFunction,aParams);
       
   894 	}
       
   895