phonebookengines/VirtualPhonebook/VPbkCntModel/src/CContactStore.cpp
changeset 0 e686773b3f54
child 3 04ab22b956c2
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2002-2007 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:  Contacts Model store contact store implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDES
       
    20 #include "CContactStore.h"
       
    21 
       
    22 // VPbkCntModel
       
    23 #include "CFieldFactory.h"
       
    24 #include "CFieldTypeMap.h"
       
    25 #include "CAsyncContactOperation.h"
       
    26 #include "CContact.h"
       
    27 #include "CContactLink.h"
       
    28 #include "CContactBookmark.h"
       
    29 #include "CContactView.h"
       
    30 #include "CFilteredContactView.h"
       
    31 #include "CFilteredGroupView.h"
       
    32 #include "CGroupView.h"
       
    33 #include "CContactStoreDomain.h"
       
    34 #include "CFieldInfo.h"
       
    35 #include "CContactRetriever.h"
       
    36 #include "CDeleteContactsOperation.h"
       
    37 #include "CCommitContactsOperation.h"
       
    38 #include "CMatchPhoneNumberOperation.h"
       
    39 #include "CFindOperation.h"
       
    40 #include "CFindInTextDefOperation.h"
       
    41 #include "CContactStoreInfo.h"
       
    42 #include "CVPbkDiskSpaceCheck.h"
       
    43 #include "CNamedRemoteViewHandle.h"
       
    44 #include "CSortOrderAcquirerList.h"
       
    45 #include "VoiceTagSupport.h"
       
    46 #include "CContactLink.h"
       
    47 #include "COwnContactLinkOperation.h"
       
    48 #include <VPbkCntModelRes.rsg>
       
    49 
       
    50 // Virtual Phonebook
       
    51 #include <VPbkError.h>
       
    52 #include <MVPbkContactStoreObserver.h>
       
    53 #include <TVPbkContactStoreUriPtr.h>
       
    54 #include <CVPbkContactStoreUri.h>
       
    55 #include <CVPbkAsyncOperation.h>
       
    56 #include <RLocalizedResourceFile.h>
       
    57 #include <CVPbkAsyncCallback.h>
       
    58 #include <CVPbkContactViewDefinition.h>
       
    59 #include <VPbkContactView.hrh>
       
    60 #include <CVPbkContactStoreProperties.h>
       
    61 #include <CVPbkLocalVariationManager.h>
       
    62 #include <CVPbkFieldTypeSelector.h>
       
    63 #include <VPbkUtils.h>
       
    64 #include <TVPbkContactStoreUriPtr.h>
       
    65 #include <VPbkDataCaging.hrh>
       
    66 #include <VPbkContactStoreUris.h>
       
    67 #include <MVPbkSingleContactLinkOperationObserver.h>
       
    68 
       
    69 // Contacts Model
       
    70 #include <cntdb.h>
       
    71 #include <cntitem.h>
       
    72 #include <cntmodel.rsg>
       
    73 
       
    74 // System includes
       
    75 #include <barsc.h>
       
    76 #include <barsread.h>
       
    77 #include <featmgr.h>
       
    78 #include <shareddataclient.h>
       
    79 #include <coemain.h>
       
    80 
       
    81 // Debugging headers
       
    82 #include <VPbkDebug.h>
       
    83 
       
    84 
       
    85 namespace VPbkCntModel {
       
    86 
       
    87 #ifdef _DEBUG
       
    88 _LIT( KContactStorePanicCat, "VPbkCntModel_CContactStore" );
       
    89 void ContactStorePanic( TContactStorePanic aPanic )
       
    90 	{
       
    91 	User::Panic( KContactStorePanicCat, aPanic);
       
    92 	}
       
    93 #endif // _DEBUG
       
    94 
       
    95 /// Unnamed namespace for local definitions
       
    96 namespace {
       
    97 
       
    98 // LOCAL
       
    99 _LIT(KCntResFile, "cntmodel.rsc");
       
   100 _LIT(KCntExtResFile, "VPbkCntModelRes.rsc");
       
   101 
       
   102 // CONSTANTS
       
   103 const TInt KDefaultArrayGranularity = 4;
       
   104 const TInt KDiskSpaceForDbOpening = 140 * 1024; // 140 kB space for db opening
       
   105 
       
   106 inline void SendEventL(MVPbkContactStoreObserver* aObserver,
       
   107                        void (MVPbkContactStoreObserver::*aEventFunc)(MVPbkContactStore&),
       
   108                        MVPbkContactStore& aStore)
       
   109     {
       
   110     (aObserver->*aEventFunc)(aStore);
       
   111     }
       
   112 
       
   113 inline void SendEventL(
       
   114         MVPbkContactStoreObserver* aObserver,
       
   115         void (MVPbkContactStoreObserver::*aEventFunc)(MVPbkContactStore&,TVPbkContactStoreEvent),
       
   116         MVPbkContactStore& aStore,
       
   117         TVPbkContactStoreEvent aEvent)
       
   118     {
       
   119     (aObserver->*aEventFunc)(aStore, aEvent);
       
   120     }
       
   121 
       
   122 inline void SendErrorEvent(MVPbkContactStoreObserver* aObserver,
       
   123                            void (MVPbkContactStoreObserver::*aEventFunc)(MVPbkContactStore&,TInt),
       
   124                            MVPbkContactStore& aStore, TInt aError)
       
   125     {
       
   126     (aObserver->*aEventFunc)(aStore, aError);
       
   127     }
       
   128 
       
   129 void SendEventL
       
   130         (RPointerArray<MVPbkContactStoreObserver>& aObservers,
       
   131         void (MVPbkContactStoreObserver::*aEventFunc)(MVPbkContactStore&),
       
   132         MVPbkContactStore& aStore)
       
   133     {
       
   134     for (TInt i = aObservers.Count() - 1; i >= 0; --i)
       
   135         {
       
   136         SendEventL(aObservers[i], aEventFunc, aStore);
       
   137         }
       
   138     }
       
   139 
       
   140 void SendEventL
       
   141         (RPointerArray<MVPbkContactStoreObserver>& aObservers,
       
   142         void (MVPbkContactStoreObserver::*aEventFunc)(MVPbkContactStore&,TVPbkContactStoreEvent),
       
   143         MVPbkContactStore& aStore,
       
   144         TVPbkContactStoreEvent aEvent)
       
   145     {
       
   146     for (TInt i = aObservers.Count() - 1; i >= 0; --i)
       
   147         {
       
   148         SendEventL(aObservers[i], aEventFunc, aStore, aEvent);
       
   149         }
       
   150     }
       
   151 
       
   152 void SendErrorEvent
       
   153         (RPointerArray<MVPbkContactStoreObserver>& aObservers,
       
   154         void (MVPbkContactStoreObserver::*aEventFunc)(MVPbkContactStore&,TInt),
       
   155         MVPbkContactStore& aStore, TInt aError)
       
   156     {
       
   157     for (TInt i = aObservers.Count() - 1; i >= 0; --i)
       
   158         {
       
   159         SendErrorEvent(aObservers[i], aEventFunc, aStore, aError);
       
   160         }
       
   161     }
       
   162 
       
   163 TBool UpdateSystemTemplateFieldL(CContactItem& aSystemTemplate,
       
   164         const CFieldInfo& aFieldInfo )
       
   165     {
       
   166     TBool updated = EFalse;
       
   167     // Scan system template field set for the field
       
   168     CContactItemFieldSet& fieldSet = aSystemTemplate.CardFields();
       
   169     const TInt fieldCount = fieldSet.Count();
       
   170     TInt i = 0;
       
   171     for (; i < fieldCount; ++i)
       
   172         {
       
   173         CContactItemField& sysTemplateField = fieldSet[i];
       
   174         if (aFieldInfo.IsEqualType(sysTemplateField))
       
   175             {
       
   176             // Field was found, just check the label
       
   177             if (!aFieldInfo.IsEqualLabel(sysTemplateField))
       
   178                 {
       
   179                 sysTemplateField.SetLabelL(aFieldInfo.FieldName());
       
   180                 updated = ETrue;
       
   181                 }
       
   182             break;
       
   183             }
       
   184         }
       
   185 
       
   186     if ( i == fieldCount )
       
   187         {
       
   188         // Field was not found, add it
       
   189         CContactItemField* field = aFieldInfo.CreateFieldL();
       
   190         CleanupStack::PushL( field );
       
   191         fieldSet.AddL( *field );
       
   192         CleanupStack::Pop( field );
       
   193         updated = ETrue;
       
   194         }
       
   195 
       
   196     return updated;
       
   197     }
       
   198 
       
   199 TBool UpdateSystemTemplateFieldsL(CContactItem& aSystemTemplate, const CFieldsInfo& aFieldsInfo)
       
   200     {
       
   201     TBool updated = EFalse;
       
   202     const TInt fieldInfoCount = aFieldsInfo.Count();
       
   203 
       
   204     for (TInt i = 0; i < fieldInfoCount; ++i)
       
   205         {
       
   206         if (UpdateSystemTemplateFieldL(aSystemTemplate, *aFieldsInfo.At(i)))
       
   207             {
       
   208             updated = ETrue;
       
   209             }
       
   210         }
       
   211     return updated;
       
   212     }
       
   213 
       
   214 
       
   215 TVPbkContactStoreEvent MapDbEventToStoreEvent(TContactDbObserverEvent aEvent)
       
   216     {
       
   217     TVPbkContactStoreEvent result(TVPbkContactStoreEvent::ENullEvent, NULL);
       
   218 
       
   219     switch (aEvent.iType)
       
   220         {
       
   221         case EContactDbObserverEventContactAdded:
       
   222             {
       
   223             result.iEventType = TVPbkContactStoreEvent::EContactAdded;
       
   224             break;
       
   225             }
       
   226         case EContactDbObserverEventContactDeleted:
       
   227         case EContactDbObserverEventOwnCardDeleted:
       
   228             {
       
   229             result.iEventType = TVPbkContactStoreEvent::EContactDeleted;
       
   230             break;
       
   231             }
       
   232 	    case EContactDbObserverEventContactChanged:
       
   233 	    case EContactDbObserverEventSpeedDialsChanged:
       
   234         case EContactDbObserverEventOwnCardChanged:
       
   235             {
       
   236             result.iEventType = TVPbkContactStoreEvent::EContactChanged;
       
   237             break;
       
   238             }
       
   239 	    case EContactDbObserverEventGroupAdded:
       
   240             {
       
   241             result.iEventType = TVPbkContactStoreEvent::EGroupAdded;
       
   242             break;
       
   243             }
       
   244         case EContactDbObserverEventGroupDeleted:
       
   245             {
       
   246             result.iEventType = TVPbkContactStoreEvent::EGroupDeleted;
       
   247             break;
       
   248             }
       
   249         case EContactDbObserverEventGroupChanged:
       
   250             {
       
   251             result.iEventType = TVPbkContactStoreEvent::EGroupChanged;
       
   252             break;
       
   253             }
       
   254 	    case EContactDbObserverEventUnknownChanges:
       
   255             {
       
   256             result.iEventType = TVPbkContactStoreEvent::EUnknownChanges;
       
   257             break;
       
   258             }
       
   259 	    case EContactDbObserverEventBackupBeginning:
       
   260             {
       
   261             result.iEventType = TVPbkContactStoreEvent::EStoreBackupBeginning;
       
   262             break;
       
   263             }
       
   264 	    case EContactDbObserverEventRestoreBeginning:
       
   265             {
       
   266             result.iEventType = TVPbkContactStoreEvent::EStoreRestoreBeginning;
       
   267             break;
       
   268             }
       
   269 	    case EContactDbObserverEventBackupRestoreCompleted:
       
   270             {
       
   271             result.iEventType = TVPbkContactStoreEvent::EStoreBackupRestoreCompleted;
       
   272             break;
       
   273             }
       
   274         case EContactDbObserverEventCurrentItemDeleted:         // FALLTHROUGH
       
   275 	    case EContactDbObserverEventCurrentItemChanged:         // FALLTHROUGH
       
   276 	    case EContactDbObserverEventCurrentDatabaseChanged:     // FALLTHROUGH
       
   277 	    case EContactDbObserverEventRestoreBadDatabase:         // FALLTHROUGH
       
   278 	    case EContactDbObserverEventSortOrderChanged:           // FALLTHROUGH
       
   279 	    case EContactDbObserverEventPreferredTemplateChanged:   // FALLTHROUGH
       
   280 	    case EContactDbObserverEventRecover:                    // FALLTHROUGH
       
   281 	    case EContactDbObserverEventRollback:                   // FALLTHROUGH
       
   282 	    case EContactDbObserverEventTablesClosed:               // FALLTHROUGH
       
   283 	    case EContactDbObserverEventTablesOpened:               // FALLTHROUGH
       
   284 	    case EContactDbObserverEventTemplateChanged:            // FALLTHROUGH
       
   285 	    case EContactDbObserverEventTemplateDeleted:            // FALLTHROUGH
       
   286 	    case EContactDbObserverEventTemplateAdded:              // FALLTHROUGH
       
   287         case EContactDbObserverEventNull:                       // FALLTHROUGH
       
   288 	    case EContactDbObserverEventUnused:                     // FALLTHROUGH
       
   289         default:
       
   290             {
       
   291             result.iEventType = TVPbkContactStoreEvent::ENullEvent;
       
   292             break;
       
   293             }
       
   294         }
       
   295 
       
   296     return result;
       
   297     }
       
   298 
       
   299 }  // unnamed namespace
       
   300 
       
   301 
       
   302 
       
   303 // --------------------------------------------------------------------------
       
   304 // CContactStore::CContactStore
       
   305 // --------------------------------------------------------------------------
       
   306 //
       
   307 CContactStore::CContactStore( CContactStoreDomain& aStoreDomain ) :
       
   308         iStoreDomain( aStoreDomain )
       
   309     {
       
   310     }
       
   311 
       
   312 // --------------------------------------------------------------------------
       
   313 // CContactStore::~CContactStore
       
   314 // --------------------------------------------------------------------------
       
   315 //
       
   316 CContactStore::~CContactStore()
       
   317     {
       
   318     VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   319         ("CContactStore::~CContactStore(0x%x)"), this);
       
   320 
       
   321     iNamedViewContainer.ResetAndDestroy();
       
   322     CloseSystemTemplate(iContactDb);
       
   323     iObservers.Close();
       
   324     delete iStoreInfo;
       
   325     delete iDbNotifier;
       
   326     delete iContactDb;
       
   327     delete iAsyncContactOperation;
       
   328     delete iAsyncOpenOp;
       
   329     delete iStoreURI;
       
   330     delete iFieldFactory;
       
   331     delete iFieldsInfo;
       
   332     delete iProperties;
       
   333     delete iDiskSpaceCheck;
       
   334     FeatureManager::UnInitializeLib();
       
   335     }
       
   336 
       
   337 // --------------------------------------------------------------------------
       
   338 // CContactStore::NewL
       
   339 // --------------------------------------------------------------------------
       
   340 //
       
   341 CContactStore* CContactStore::NewL
       
   342         (const TVPbkContactStoreUriPtr& aURI,
       
   343         CContactStoreDomain& aStoreDomain)
       
   344     {
       
   345     CContactStore* self = new(ELeave) CContactStore(aStoreDomain);
       
   346     CleanupStack::PushL(self);
       
   347     self->ConstructL(aURI);
       
   348     CleanupStack::Pop(self);
       
   349     return self;
       
   350     }
       
   351 
       
   352 // --------------------------------------------------------------------------
       
   353 // CContactStore::ConstructL
       
   354 // --------------------------------------------------------------------------
       
   355 //
       
   356 inline void CContactStore::ConstructL(
       
   357         const TVPbkContactStoreUriPtr& aURI)
       
   358     {
       
   359     VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   360         ("CContactStore::ConstructL(%S)"), &aURI.UriDes());
       
   361 
       
   362     FeatureManager::InitializeLibL();
       
   363     iProperties = CVPbkContactStoreProperties::NewL();
       
   364     iStoreURI = CVPbkContactStoreUri::NewL(aURI);
       
   365     iProperties->SetName(iStoreURI->Uri());
       
   366 
       
   367     // open and read the contacts model resource file cntmodel.rsc
       
   368     VPbkEngUtils::RLocalizedResourceFile resFile;
       
   369     resFile.OpenLC(iStoreDomain.FsSession(),
       
   370         KVPbkRomFileDrive, KDC_CONTACTS_RESOURCE_DIR, KCntResFile);
       
   371 
       
   372     TResourceReader reader;
       
   373     reader.SetBuffer( resFile.AllocReadLC(R_CNTUI_NEW_FIELD_DEFNS) );
       
   374     // create the fields info structure from the contacts model fields
       
   375     iFieldsInfo = CFieldsInfo::NewL(reader);
       
   376     CleanupStack::PopAndDestroy(2); // R_CNTUI_NEW_FIELD_DEFNS buffer, resFile
       
   377 
       
   378     // Extend the contacts model golden template with variant fields
       
   379     DoAddFieldTypesL();
       
   380 
       
   381     iAsyncOpenOp =
       
   382         CVPbkAsyncObjectOperation<MVPbkContactStoreObserver>::NewL();
       
   383     iAsyncContactOperation = CAsyncContactOperation::NewL(*this);
       
   384 
       
   385     iStoreInfo = CContactStoreInfo::NewL(*this, iStoreDomain);
       
   386 
       
   387     // Get contact store location drive for disk space check
       
   388     const TPtrC ptr( iStoreURI->Uri().Component
       
   389         ( TVPbkContactStoreUriPtr::EContactStoreUriStoreDrive ) );
       
   390     TInt drive( EDriveA ); // c is usually the default location
       
   391     User::LeaveIfError( iStoreDomain.FsSession().CharToDrive
       
   392         ( ptr[0], drive) );
       
   393     iDiskSpaceCheck = VPbkEngUtils::CVPbkDiskSpaceCheck::NewL
       
   394             ( iStoreDomain.FsSession(), drive );
       
   395 
       
   396     VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   397         ("CContactStore::ConstructL end"));
       
   398     }
       
   399 
       
   400 // --------------------------------------------------------------------------
       
   401 // CContactStore::FieldTypeMap
       
   402 // --------------------------------------------------------------------------
       
   403 //
       
   404 const CFieldTypeMap& CContactStore::FieldTypeMap() const
       
   405     {
       
   406     return iStoreDomain.FieldTypeMap();
       
   407     }
       
   408 
       
   409 // --------------------------------------------------------------------------
       
   410 // CContactStore::FieldFactory
       
   411 // --------------------------------------------------------------------------
       
   412 //
       
   413 const CFieldFactory& CContactStore::FieldFactory() const
       
   414     {
       
   415     return *iFieldFactory;
       
   416     }
       
   417 
       
   418 // --------------------------------------------------------------------------
       
   419 // CContactStore::MasterFieldTypeList
       
   420 // --------------------------------------------------------------------------
       
   421 //
       
   422 const MVPbkFieldTypeList& CContactStore::MasterFieldTypeList() const
       
   423     {
       
   424     return iStoreDomain.MasterFieldTypeList();
       
   425     }
       
   426 
       
   427 // --------------------------------------------------------------------------
       
   428 // CContactStore::CreateFieldLC
       
   429 // --------------------------------------------------------------------------
       
   430 //
       
   431 CContactItemField* CContactStore::CreateFieldLC
       
   432         (const MVPbkFieldType& aFieldType) const
       
   433     {
       
   434     return iFieldFactory->CreateFieldLC(aFieldType);
       
   435     }
       
   436 
       
   437 // --------------------------------------------------------------------------
       
   438 // CContactStore::ReadContactL
       
   439 // --------------------------------------------------------------------------
       
   440 //
       
   441 void CContactStore::ReadContactL
       
   442         (TContactItemId aContactId, MVPbkContactObserver& aObserver)
       
   443     {
       
   444     iAsyncContactOperation->PrepareL
       
   445         (MVPbkContactObserver::EContactRead, aContactId, aObserver);
       
   446     iAsyncContactOperation->Execute();
       
   447     }
       
   448 
       
   449 // --------------------------------------------------------------------------
       
   450 // CContactStore::LockContactL
       
   451 // --------------------------------------------------------------------------
       
   452 //
       
   453 void CContactStore::LockContactL
       
   454         (const CContact& aContact, MVPbkContactObserver& aObserver)
       
   455     {
       
   456     iAsyncContactOperation->PrepareL
       
   457         (MVPbkContactObserver::EContactLock, aContact, aObserver);
       
   458     iAsyncContactOperation->Execute();
       
   459     }
       
   460 
       
   461 // --------------------------------------------------------------------------
       
   462 // CContactStore::ReadAndLockContactL
       
   463 // --------------------------------------------------------------------------
       
   464 //
       
   465 void CContactStore::ReadAndLockContactL
       
   466         (TContactItemId aContactId, MVPbkContactObserver& aObserver)
       
   467     {
       
   468     iAsyncContactOperation->PrepareL
       
   469         (MVPbkContactObserver::EContactReadAndLock, aContactId, aObserver);
       
   470     iAsyncContactOperation->Execute();
       
   471     }
       
   472 
       
   473 // --------------------------------------------------------------------------
       
   474 // CContactStore::DeleteContactL
       
   475 // --------------------------------------------------------------------------
       
   476 //
       
   477 void CContactStore::DeleteContactL
       
   478         (TContactItemId aContactId, MVPbkContactObserver& aObserver)
       
   479     {
       
   480     iAsyncContactOperation->PrepareL
       
   481         (MVPbkContactObserver::EContactDelete, aContactId, aObserver);
       
   482     iAsyncContactOperation->Execute();
       
   483     }
       
   484 
       
   485 // --------------------------------------------------------------------------
       
   486 // CContactStore::CommitContactL
       
   487 // --------------------------------------------------------------------------
       
   488 //
       
   489 void CContactStore::CommitContactL(
       
   490         const CContact& aContactItem,
       
   491         MVPbkContactObserver& aObserver)
       
   492     {
       
   493     VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   494         ("CContactStore::CommitContactL(0x%x,0x%x)"),
       
   495         &aContactItem, &aObserver);
       
   496 
       
   497     iDiskSpaceCheck->DiskSpaceCheckL();
       
   498 
       
   499     // verify sync field content
       
   500     VPbkUtils::VerifySyncronizationFieldL(
       
   501         iStoreDomain.FsSession(),
       
   502         StoreProperties().SupportedFields(),
       
   503         const_cast<CContact&>(aContactItem));
       
   504 
       
   505     iAsyncContactOperation->PrepareL
       
   506         (MVPbkContactObserver::EContactCommit, aContactItem, aObserver);
       
   507     iAsyncContactOperation->Execute();
       
   508     }
       
   509 
       
   510 // --------------------------------------------------------------------------
       
   511 // CContactStore::CreateLinkLC
       
   512 // --------------------------------------------------------------------------
       
   513 //
       
   514 MVPbkContactLink* CContactStore::CreateLinkLC(TContactItemId aContactId) const
       
   515     {
       
   516     MVPbkContactLink* ret = NULL;
       
   517     // if  aContactId is KGoldenTemplateId then it is probably new contact
       
   518     // which is not commited to contactdb, return null then
       
   519     if ( aContactId != KGoldenTemplateId &&
       
   520          aContactId != KNullContactId )
       
   521         {
       
   522         // Contact store constness casted away, no reason to be const
       
   523         ret = CContactLink::NewLC(const_cast<CContactStore&>(*this), aContactId);
       
   524         }
       
   525     return ret;
       
   526     }
       
   527 
       
   528 // --------------------------------------------------------------------------
       
   529 // CContactStore::ContactDestroyed
       
   530 // --------------------------------------------------------------------------
       
   531 //
       
   532 void CContactStore::ContactDestroyed(CContactItem* aContactItem, TBool aCloseContact )
       
   533     {
       
   534     // Release any lock on contact.
       
   535     if (aContactItem)
       
   536         {
       
   537         // Check that contact store is open
       
   538         __ASSERT_DEBUG( iContactDb,
       
   539             ContactStorePanic( EPreCond_ContactDestroyed ) );
       
   540 
       
   541         // Cancel async operation if any
       
   542         iAsyncContactOperation->Cancel( aContactItem );
       
   543 
       
   544         if ( aCloseContact )
       
   545         	{
       
   546 	        // CloseContactL doesn't leave despite its name.
       
   547 	        iContactDb->CloseContactL(aContactItem->Id());
       
   548         	}
       
   549         }
       
   550     }
       
   551 
       
   552 // --------------------------------------------------------------------------
       
   553 // CContactStore::MatchContactStore
       
   554 // --------------------------------------------------------------------------
       
   555 //
       
   556 TBool CContactStore::MatchContactStore(const TDesC& aContactStoreUri) const
       
   557     {
       
   558     if (iStoreURI->Uri().Compare(
       
   559         TVPbkContactStoreUriPtr(aContactStoreUri),
       
   560         TVPbkContactStoreUriPtr::EContactStoreUriAllComponents) == 0)
       
   561         {
       
   562         return ETrue;
       
   563         }
       
   564     return EFalse;
       
   565     }
       
   566 
       
   567 // --------------------------------------------------------------------------
       
   568 // CContactStore::MatchContactStoreDomain
       
   569 // --------------------------------------------------------------------------
       
   570 //
       
   571 TBool CContactStore::MatchContactStoreDomain(const TDesC& aContactStoreDomain) const
       
   572     {
       
   573     if (iStoreURI->Uri().Compare(
       
   574         aContactStoreDomain,
       
   575         TVPbkContactStoreUriPtr::EContactStoreUriStoreType) == 0)
       
   576         {
       
   577         return ETrue;
       
   578         }
       
   579     return EFalse;
       
   580     }
       
   581 
       
   582 // --------------------------------------------------------------------------
       
   583 // CContactStore::CreateBookmarkLC
       
   584 // --------------------------------------------------------------------------
       
   585 //
       
   586 MVPbkContactBookmark* CContactStore::CreateBookmarkLC(
       
   587         TContactItemId aContactId) const
       
   588     {
       
   589     // Contact store constness casted away, no reason to be const
       
   590     return CContactBookmark::NewLC( aContactId,
       
   591         const_cast<CContactStore&>(*this) );
       
   592     }
       
   593 
       
   594 // --------------------------------------------------------------------------
       
   595 // CContactStore::StoreProperties
       
   596 // --------------------------------------------------------------------------
       
   597 //
       
   598 const MVPbkContactStoreProperties& CContactStore::StoreProperties() const
       
   599     {
       
   600     return *iProperties;
       
   601     }
       
   602 
       
   603 // --------------------------------------------------------------------------
       
   604 // CContactStore::OpenL
       
   605 // --------------------------------------------------------------------------
       
   606 //
       
   607 void CContactStore::OpenL(
       
   608         MVPbkContactStoreObserver& aObserver)
       
   609     {
       
   610     VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   611         ("CContactStore::OpenL(0x%x)"), &aObserver);
       
   612 
       
   613     AddObserverL(aObserver);
       
   614     CVPbkAsyncObjectCallback<MVPbkContactStoreObserver>* openCallback =
       
   615         VPbkEngUtils::CreateAsyncObjectCallbackLC(
       
   616             *this,
       
   617             &CContactStore::DoOpenL,
       
   618             TBool(EFalse),
       
   619             &CContactStore::OpenError,
       
   620             aObserver);
       
   621     iAsyncOpenOp->CallbackL(openCallback);
       
   622     CleanupStack::Pop( openCallback );
       
   623     }
       
   624 
       
   625 // --------------------------------------------------------------------------
       
   626 // CContactStore::ReplaceL
       
   627 // --------------------------------------------------------------------------
       
   628 //
       
   629 void CContactStore::ReplaceL(MVPbkContactStoreObserver& aObserver)
       
   630     {
       
   631     VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   632         ("CContactStore::ReplaceL(0x%x)"), &aObserver);
       
   633 
       
   634     AddObserverL(aObserver);
       
   635     CVPbkAsyncObjectCallback<MVPbkContactStoreObserver>* openCallback =
       
   636         VPbkEngUtils::CreateAsyncObjectCallbackLC(
       
   637             *this,
       
   638             &CContactStore::DoOpenL,
       
   639             TBool(ETrue),
       
   640             &CContactStore::OpenError,
       
   641             aObserver);
       
   642     iAsyncOpenOp->CallbackL(openCallback);
       
   643     CleanupStack::Pop(openCallback);
       
   644     }
       
   645 
       
   646 // --------------------------------------------------------------------------
       
   647 // CContactStore::Close
       
   648 // --------------------------------------------------------------------------
       
   649 //
       
   650 void CContactStore::Close( MVPbkContactStoreObserver& aObserver)
       
   651     {
       
   652     VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   653         ("CContactStore::Close(0x%x)"), &aObserver);
       
   654 
       
   655     // Cancel open callback, If not active then it does nothing.
       
   656     iAsyncOpenOp->CancelCallback( &aObserver );
       
   657     // Remove the observer from the observer list.
       
   658     RemoveObserver(aObserver);
       
   659     if (iObservers.Count() == 0)
       
   660         {
       
   661         iNamedViewContainer.ResetAndDestroy();
       
   662         // Zero observers left, clean the resources.
       
   663         iAsyncOpenOp->Purge();
       
   664         delete iFieldFactory;
       
   665         iFieldFactory = NULL;
       
   666         delete iDbNotifier;
       
   667         iDbNotifier = NULL;
       
   668         delete iContactDb;
       
   669         iContactDb = NULL;
       
   670         }
       
   671     }
       
   672 
       
   673 // --------------------------------------------------------------------------
       
   674 // CContactStore::CreateNewContactLC
       
   675 // --------------------------------------------------------------------------
       
   676 //
       
   677 MVPbkStoreContact* CContactStore::CreateNewContactLC()
       
   678     {
       
   679     TRAPD( err, iDiskSpaceCheck->DiskSpaceCheckL() );
       
   680     if ( err != KErrNone )
       
   681         {
       
   682         CCoeEnv::Static()->HandleError( err );
       
   683         }
       
   684     CContactItem* newContact = CContactCard::NewLC();
       
   685     CContact* result = CContact::NewL(*this, newContact, ETrue);
       
   686     CleanupStack::Pop(newContact);
       
   687     CleanupStack::PushL(result);
       
   688     return result;
       
   689     }
       
   690 
       
   691 // --------------------------------------------------------------------------
       
   692 // CContactStore::CreateNewContactGroupLC
       
   693 // --------------------------------------------------------------------------
       
   694 //
       
   695 MVPbkContactGroup* CContactStore::CreateNewContactGroupLC()
       
   696     {
       
   697     // Check that store has been opened
       
   698     __ASSERT_DEBUG( iContactDb,
       
   699         ContactStorePanic( EPreCond_CreateNewContactGroupLC ) );
       
   700 
       
   701     iDiskSpaceCheck->DiskSpaceCheckL();
       
   702     CContactItem* newGroup = iContactDb->CreateContactGroupLC();
       
   703     TContactItemId groupId = newGroup->Id();
       
   704     CleanupStack::PopAndDestroy(); // newGroup
       
   705 
       
   706     CContactItem* group = iContactDb->OpenContactLX(groupId);
       
   707     CleanupStack::PushL(group);
       
   708     CContact* result = CContact::NewL(*this, group);
       
   709     CleanupStack::Pop(2); // group, lock
       
   710     CleanupStack::PushL(result);
       
   711 
       
   712     return result;
       
   713     }
       
   714 
       
   715 // --------------------------------------------------------------------------
       
   716 // CContactStore::CreateViewLC
       
   717 // --------------------------------------------------------------------------
       
   718 //
       
   719 MVPbkContactView* CContactStore::CreateViewLC(
       
   720         const CVPbkContactViewDefinition& aViewDefinition,
       
   721         MVPbkContactViewObserver& aObserver,
       
   722         const MVPbkFieldTypeList& aSortOrder )
       
   723     {
       
   724     VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   725         ("CContactStore::CreateViewLC(0x%x)"), &aSortOrder);
       
   726 
       
   727     CViewBase* result = NULL;
       
   728     if (aViewDefinition.SortPolicy() == EVPbkUnsortedContactView)
       
   729         {
       
   730         // Contact model doesn't have a view that is not sorted.
       
   731         User::Leave( KErrArgument );
       
   732         }
       
   733     else if (aViewDefinition.Type() == EVPbkContactsView)
       
   734         {
       
   735         if ( !aViewDefinition.FieldTypeFilter() && !aViewDefinition.ContactSelector() )
       
   736             {
       
   737             // View without filtering
       
   738             result = CContactView::NewLC( aViewDefinition, aObserver,
       
   739                     *this, aSortOrder );
       
   740             }
       
   741         else
       
   742             {
       
   743             // A filtered view
       
   744             result = CFilteredContactView::NewLC( aViewDefinition,
       
   745                     aObserver, *this, aSortOrder, iStoreDomain.FsSession() );
       
   746             }
       
   747         }
       
   748     else // aViewDefinition.Type() == EVPbkGroupsView
       
   749         {
       
   750         if ( !aViewDefinition.FieldTypeFilter() &&
       
   751         		!aViewDefinition.FlagIsOn( EVPbkExcludeEmptyGroups ) )
       
   752             {
       
   753             // View without filtering
       
   754             result = CGroupView::NewLC( aViewDefinition, aObserver, *this,
       
   755                 aSortOrder );
       
   756             }
       
   757         else
       
   758             {
       
   759             // A filtered view
       
   760             result = CFilteredGroupView::NewLC( aViewDefinition,
       
   761                     aObserver, *this, aSortOrder, iStoreDomain.FsSession() );
       
   762             }
       
   763         }
       
   764 
       
   765     return result;
       
   766     }
       
   767 
       
   768 // --------------------------------------------------------------------------
       
   769 // CContactStore::ContactGroupsLC
       
   770 // --------------------------------------------------------------------------
       
   771 //
       
   772 MVPbkContactLinkArray* CContactStore::ContactGroupsLC() const
       
   773     {
       
   774     // Check that store has been opened
       
   775     __ASSERT_DEBUG( iContactDb,
       
   776         ContactStorePanic( EPreCond_ContactGroupsLC ) );
       
   777 
       
   778     CVPbkContactLinkArray* result = CVPbkContactLinkArray::NewLC();
       
   779 
       
   780     CContactIdArray* groups = iContactDb->GetGroupIdListL();
       
   781     if (groups)
       
   782         {
       
   783         CleanupStack::PushL(groups);
       
   784         const TInt count = groups->Count();
       
   785         for (TInt i = 0; i < count; ++i)
       
   786             {
       
   787             MVPbkContactLink* link = CreateLinkLC((*groups)[i]);
       
   788             result->AppendL(link);
       
   789             CleanupStack::Pop(); // link
       
   790             }
       
   791         CleanupStack::PopAndDestroy(); // groups
       
   792         }
       
   793 
       
   794     return result;
       
   795     }
       
   796 
       
   797 // --------------------------------------------------------------------------
       
   798 // CContactStore::StoreInfo
       
   799 // --------------------------------------------------------------------------
       
   800 //
       
   801 const MVPbkContactStoreInfo& CContactStore::StoreInfo() const
       
   802     {
       
   803     return *iStoreInfo;
       
   804     }
       
   805 
       
   806 // --------------------------------------------------------------------------
       
   807 // CContactStore::CreateLinkFromInternalsLC
       
   808 // --------------------------------------------------------------------------
       
   809 //
       
   810 MVPbkContactLink* CContactStore::CreateLinkFromInternalsLC(
       
   811         RReadStream& aStream) const
       
   812     {
       
   813     // Contact store constness casted away, no reason to be const
       
   814     return CContactLink::NewLC(const_cast<CContactStore&>(*this), aStream);
       
   815     }
       
   816 
       
   817 
       
   818 // --------------------------------------------------------------------------
       
   819 // CContactStore::ContactStoreExtension
       
   820 // --------------------------------------------------------------------------
       
   821 //
       
   822 TAny* CContactStore::ContactStoreExtension( TUid aExtensionUid )
       
   823     {
       
   824     if( aExtensionUid == KMVPbkContactStoreExtension2Uid )
       
   825         {
       
   826         return static_cast<MVPbkContactStore2*>( this );
       
   827         }
       
   828 
       
   829     return NULL;
       
   830     }
       
   831 
       
   832 
       
   833 // --------------------------------------------------------------------------
       
   834 // CContactStore::OwnContactLinkL
       
   835 // --------------------------------------------------------------------------
       
   836 //
       
   837 MVPbkContactOperationBase* CContactStore::OwnContactLinkL(
       
   838 		   MVPbkSingleContactLinkOperationObserver& aObserver) const
       
   839 	{
       
   840     __ASSERT_DEBUG( iContactDb,
       
   841         ContactStorePanic( EPreCond_OwnContactLinkL ) );
       
   842 
       
   843 	MVPbkContactLink* ownContactLink = NULL;
       
   844 	TContactItemId ownCardId = iContactDb->OwnCardId();
       
   845 
       
   846 	if ( ownCardId != KNullContactId )
       
   847 		{
       
   848 		ownContactLink = CContactLink::NewLC(
       
   849 				const_cast<CContactStore&>(*this),
       
   850 				ownCardId );
       
   851 		}
       
   852 
       
   853     // if ownCard is KNullContactId, than return ownContactLink with NULL, async
       
   854 	MVPbkContactOperationBase* result = new (ELeave) COwnContactLinkOperation(
       
   855 			ownContactLink,
       
   856 			aObserver );
       
   857 
       
   858 	if ( ownCardId != KNullContactId )
       
   859 		{
       
   860 		CleanupStack::Pop(); //contact link
       
   861 		}
       
   862 
       
   863 	return result;
       
   864 	}
       
   865 
       
   866 // --------------------------------------------------------------------------
       
   867 // CContactStore::SetOwnContactL
       
   868 // --------------------------------------------------------------------------
       
   869 //
       
   870 void CContactStore::SetAsOwnL(
       
   871         const CContact& aContactItem,
       
   872         MVPbkContactObserver& aObserver )
       
   873 	{
       
   874     iAsyncContactOperation->PrepareL
       
   875         (MVPbkContactObserver::EContactSetOwn, aContactItem, aObserver);
       
   876     iAsyncContactOperation->Execute();
       
   877 	}
       
   878 
       
   879 // --------------------------------------------------------------------------
       
   880 // CContactStore::CreateContactRetrieverL
       
   881 // --------------------------------------------------------------------------
       
   882 //
       
   883 MVPbkContactOperation* CContactStore::CreateContactRetrieverL(
       
   884         const MVPbkContactLink& aLink,
       
   885         MVPbkSingleContactOperationObserver& aObserver)
       
   886     {
       
   887     // test if aLink is in fact a instance of this class
       
   888     CContactRetriever* operation = NULL;
       
   889     if (CContactLink::Matches(StoreProperties().Uri(), aLink))
       
   890         {
       
   891         if ( IsOpened() )
       
   892             {
       
   893             operation = CContactRetriever::NewLC(aLink, *this, aObserver);
       
   894             CleanupStack::Pop();
       
   895             }
       
   896         else
       
   897             {
       
   898             VPBK_DEBUG_PRINT( VPBK_DEBUG_STRING(
       
   899                 "VPbkCntModel: ContactStore not opened" ) );
       
   900             User::Leave( KErrArgument );
       
   901             }
       
   902         }
       
   903 
       
   904     return operation;
       
   905     }
       
   906 
       
   907 // --------------------------------------------------------------------------
       
   908 // CContactStore::CreateDeleteContactsOperationL
       
   909 // --------------------------------------------------------------------------
       
   910 //
       
   911 MVPbkContactOperation* CContactStore::CreateDeleteContactsOperationL(
       
   912                 const MVPbkContactLinkArray& aContactLinks,
       
   913                 MVPbkBatchOperationObserver& aObserver)
       
   914     {
       
   915     CVPbkContactLinkArray* links = CVPbkContactLinkArray::NewLC();
       
   916 
       
   917     const TInt linkCount = aContactLinks.Count();
       
   918     for (TInt i = 0; i < linkCount; ++i)
       
   919         {
       
   920         const MVPbkContactLink& link = aContactLinks.At(i);
       
   921         if (CContactLink::Matches(StoreProperties().Uri(), link))
       
   922             {
       
   923             MVPbkContactLink* newLink = link.CloneLC();
       
   924             links->AppendL(newLink);
       
   925             CleanupStack::Pop(); // newLink
       
   926             }
       
   927         }
       
   928 
       
   929     MVPbkContactOperation* operation = NULL;
       
   930     if (links->Count() > 0)
       
   931         {
       
   932         __ASSERT_DEBUG( IsOpened(),
       
   933             VPbkError::Panic( VPbkError::EAccessOfUnopenedStore ) );
       
   934         if ( IsOpened() )
       
   935             {
       
   936             operation = CDeleteContactsOperation::NewL(*this, *links, aObserver,
       
   937                                                        iStoreDomain.SharedDataClient(),
       
   938                                                        *iDiskSpaceCheck );
       
   939             }
       
   940         }
       
   941     CleanupStack::PopAndDestroy(); // links
       
   942 
       
   943     return operation;
       
   944     }
       
   945 
       
   946 // --------------------------------------------------------------------------
       
   947 // CContactStore::CreateCommitContactsOperationL
       
   948 // --------------------------------------------------------------------------
       
   949 //
       
   950 MVPbkContactOperation* CContactStore::CreateCommitContactsOperationL(
       
   951         const TArray<MVPbkStoreContact*>& aContacts,
       
   952         MVPbkBatchOperationObserver& aObserver)
       
   953     {
       
   954     CArrayPtrFlat<CContact>* contacts =
       
   955         new(ELeave) CArrayPtrFlat<CContact>(KDefaultArrayGranularity);
       
   956     CleanupStack::PushL(contacts);
       
   957 
       
   958     const TInt contactCount = aContacts.Count();
       
   959     for (TInt i = 0; i < contactCount; ++i)
       
   960         {
       
   961         MVPbkStoreContact* contact = aContacts[i];
       
   962         if (&contact->ParentStore() == this)
       
   963             {
       
   964             contacts->AppendL(static_cast<CContact*>(contact));
       
   965 
       
   966             // Validate syncronization field content
       
   967             VPbkUtils::VerifySyncronizationFieldL(
       
   968                 iStoreDomain.FsSession(),
       
   969                 StoreProperties().SupportedFields(),
       
   970                 *(aContacts[i]));
       
   971             }
       
   972         }
       
   973 
       
   974     MVPbkContactOperation* operation = NULL;
       
   975     if (contacts->Count() > 0)
       
   976         {
       
   977         __ASSERT_DEBUG( IsOpened(),
       
   978             VPbkError::Panic( VPbkError::EAccessOfUnopenedStore ) );
       
   979         if ( IsOpened() )
       
   980             {
       
   981             operation = CCommitContactsOperation::NewL(*this, contacts->Array(), aObserver);
       
   982             }
       
   983         }
       
   984     CleanupStack::PopAndDestroy(); // contacts
       
   985 
       
   986     return operation;
       
   987     }
       
   988 
       
   989 // --------------------------------------------------------------------------
       
   990 // CContactStore::CreateMatchPhoneNumberOperationL
       
   991 // --------------------------------------------------------------------------
       
   992 //
       
   993 MVPbkContactOperation* CContactStore::CreateMatchPhoneNumberOperationL(
       
   994         const TDesC& aPhoneNumber,
       
   995         TInt aMaxMatchDigits,
       
   996         MVPbkContactFindObserver& aObserver)
       
   997     {
       
   998     MVPbkContactOperation* operation = NULL;
       
   999     if ( IsOpened() )
       
  1000         {
       
  1001         operation = CMatchPhoneNumberOperation::NewL(
       
  1002             *this, aPhoneNumber, aMaxMatchDigits, aObserver);
       
  1003         }
       
  1004     return operation;
       
  1005     }
       
  1006 
       
  1007 // --------------------------------------------------------------------------
       
  1008 // CContactStore::CreateFindOperationL
       
  1009 // --------------------------------------------------------------------------
       
  1010 //
       
  1011 MVPbkContactOperation* CContactStore::CreateFindOperationL(
       
  1012         const TDesC& aSearchString,
       
  1013         const MVPbkFieldTypeList& aFieldTypes,
       
  1014         MVPbkContactFindObserver& aObserver)
       
  1015     {
       
  1016     MVPbkContactOperation* operation = NULL;
       
  1017     if ( IsOpened() )
       
  1018         {
       
  1019         operation = CFindOperation::NewL(
       
  1020             *this, aSearchString, aFieldTypes, aObserver);
       
  1021         }
       
  1022     return operation;
       
  1023     }
       
  1024 
       
  1025 // --------------------------------------------------------------------------
       
  1026 // CContactStore::CreateFindOperationL
       
  1027 // --------------------------------------------------------------------------
       
  1028 //
       
  1029 MVPbkContactOperation* CContactStore::CreateFindOperationL(
       
  1030         const MDesC16Array& aSearchStrings,
       
  1031         const MVPbkFieldTypeList& aFieldTypes,
       
  1032         MVPbkContactFindFromStoresObserver& aObserver,
       
  1033         const TCallBack& aWordParserCallBack )
       
  1034     {
       
  1035     MVPbkContactOperation* operation = NULL;
       
  1036     if ( IsOpened() )
       
  1037         {
       
  1038         operation = CFindInTextDefOperation::NewL( *this, aSearchStrings,
       
  1039             aFieldTypes, aObserver, aWordParserCallBack );
       
  1040         }
       
  1041     return operation;
       
  1042     }
       
  1043 
       
  1044 // --------------------------------------------------------------------------
       
  1045 // CContactStore::CreateCompressStoresOperationL
       
  1046 // --------------------------------------------------------------------------
       
  1047 //
       
  1048 MVPbkContactOperation* CContactStore::CreateCompressStoresOperationL(
       
  1049 	MVPbkBatchOperationObserver& /*aObserver*/)
       
  1050 	{
       
  1051 	// Contacts model handles compress by itself nowadays
       
  1052 	return NULL;
       
  1053 	}
       
  1054 
       
  1055 // --------------------------------------------------------------------------
       
  1056 // CContactStore::AddObserverL
       
  1057 // --------------------------------------------------------------------------
       
  1058 //
       
  1059 void CContactStore::AddObserverL(MVPbkContactStoreObserver& aObserver)
       
  1060     {
       
  1061     // adds aObserver to list of observers if it isnt there already, thus
       
  1062     // avoids clients registering multiple times
       
  1063     if (iObservers.Find(&aObserver) == KErrNotFound)
       
  1064         {
       
  1065         iObservers.AppendL( &aObserver );
       
  1066         }
       
  1067     }
       
  1068 
       
  1069 // --------------------------------------------------------------------------
       
  1070 // CContactStore::RemoveObserver
       
  1071 // --------------------------------------------------------------------------
       
  1072 //
       
  1073 void CContactStore::RemoveObserver(MVPbkContactStoreObserver& aObserver)
       
  1074     {
       
  1075     const TInt pos = iObservers.Find(&aObserver);
       
  1076     if (pos != KErrNotFound)
       
  1077         {
       
  1078         iObservers.Remove(pos);
       
  1079         }
       
  1080     }
       
  1081 
       
  1082 // --------------------------------------------------------------------------
       
  1083 // CContactStore::IsOpened
       
  1084 // --------------------------------------------------------------------------
       
  1085 //
       
  1086 TBool CContactStore::IsOpened() const
       
  1087     {
       
  1088     if ( iContactDb )
       
  1089         {
       
  1090         return ETrue;
       
  1091         }
       
  1092     else
       
  1093         {
       
  1094         return EFalse;
       
  1095         }
       
  1096     }
       
  1097 
       
  1098 // --------------------------------------------------------------------------
       
  1099 // CContactStore::HandleDatabaseEventL
       
  1100 // --------------------------------------------------------------------------
       
  1101 //
       
  1102 void CContactStore::HandleDatabaseEventL(TContactDbObserverEvent aEvent)
       
  1103     {
       
  1104     // Note: prints Symbian event and contact id
       
  1105     VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
  1106     ("VPbkCntModel:CContactStore(0x%x)::HandleDatabaseEventL %d, cntId=%d"),
       
  1107     this, aEvent.iType, aEvent.iContactId );
       
  1108 
       
  1109     TVPbkContactStoreEvent mappedEvent = MapDbEventToStoreEvent(aEvent);
       
  1110 
       
  1111     if (aEvent.iContactId != KNullContactId)
       
  1112         {
       
  1113         mappedEvent.iContactLink = CreateLinkLC(aEvent.iContactId);
       
  1114         }
       
  1115 
       
  1116     if (mappedEvent.iEventType != TVPbkContactStoreEvent::ENullEvent)
       
  1117         {
       
  1118         SendEventL(iObservers, &MVPbkContactStoreObserver::HandleStoreEventL,
       
  1119             *this, mappedEvent);
       
  1120         }
       
  1121 
       
  1122     // Backup handling. Send unavailable event when backup/restore begins
       
  1123     // and ready event when it completes.
       
  1124     switch( mappedEvent.iEventType )
       
  1125         {
       
  1126         case TVPbkContactStoreEvent::EStoreRestoreBeginning: // FALLTHROUGH
       
  1127         case TVPbkContactStoreEvent::EStoreBackupBeginning:
       
  1128             {
       
  1129             SendErrorEvent( iObservers,
       
  1130                 &MVPbkContactStoreObserver::StoreUnavailable, *this,
       
  1131                 KErrAccessDenied );
       
  1132             break;
       
  1133             }
       
  1134         case TVPbkContactStoreEvent::EStoreBackupRestoreCompleted:
       
  1135             {
       
  1136             SendEventL( iObservers, &MVPbkContactStoreObserver::StoreReady,
       
  1137                 *this );
       
  1138             break;
       
  1139             }
       
  1140         default:
       
  1141             {
       
  1142             // Do nothing
       
  1143             break;
       
  1144             }
       
  1145         }
       
  1146 
       
  1147     if ( mappedEvent.iContactLink )
       
  1148         {
       
  1149         CleanupStack::PopAndDestroy(); // mappedEvent.iContactLink;
       
  1150         }
       
  1151     }
       
  1152 
       
  1153 // --------------------------------------------------------------------------
       
  1154 // CContactStore::DoOpenL
       
  1155 // --------------------------------------------------------------------------
       
  1156 //
       
  1157 void CContactStore::DoOpenL(MVPbkContactStoreObserver& aObserver, TBool aReplace)
       
  1158     {
       
  1159     VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
  1160         ("CContactStore::DoOpenL(0x%x)"), &aObserver);
       
  1161 
       
  1162     if (!iContactDb)
       
  1163         {
       
  1164         CContactDatabase* db = NULL;
       
  1165         if (aReplace)
       
  1166             {
       
  1167             db = CContactDatabase::ReplaceL(StoreProperties().Name().UriDes());
       
  1168             }
       
  1169         else
       
  1170             {
       
  1171             db = OpenInternalL();
       
  1172             }
       
  1173         CleanupStack::PushL(db);
       
  1174 
       
  1175         // opens the Symbian Contacts model golden template
       
  1176         TBool updated = EFalse;
       
  1177         iSysTemplate = db->OpenContactL(db->TemplateId());
       
  1178         // set contact model template label texts according to localisation
       
  1179         // must be done in order for contact field labels to be correct after language change
       
  1180         if (UpdateSystemTemplateFieldsL(*iSysTemplate, *iFieldsInfo))
       
  1181             {
       
  1182             db->CommitContactL(*iSysTemplate);
       
  1183             updated = ETrue;
       
  1184             }
       
  1185         CloseSystemTemplate(db);
       
  1186 
       
  1187         // reopen the contact database if the golden template has been changed
       
  1188         if(updated)
       
  1189             {
       
  1190             CleanupStack::PopAndDestroy(db);
       
  1191             db = NULL;
       
  1192             // db already exists so we just reopen it
       
  1193             db = OpenInternalL();
       
  1194             CleanupStack::PushL(db);
       
  1195             }
       
  1196         // read the system template and create the field factory accordingly
       
  1197         iSysTemplate = db->ReadContactL(db->TemplateId());
       
  1198         iFieldFactory = CFieldFactory::NewL(iStoreDomain.FieldTypeMap(),
       
  1199             iSysTemplate, MasterFieldTypeList(), iStoreDomain.FsSession() );
       
  1200         iSysTemplate = NULL;
       
  1201 
       
  1202         // set supported fields for this store
       
  1203         iProperties->SetSupportedFields(*iFieldFactory);
       
  1204         SetStaticPropertiesL();
       
  1205 
       
  1206         iDbNotifier = CContactChangeNotifier::NewL(*db, this);
       
  1207         CleanupStack::Pop(db);
       
  1208         iContactDb = db;
       
  1209 
       
  1210         // Activate remote views so that contacts server will build
       
  1211         // the view as soon as possible when system boots.
       
  1212         // This is trapped because it's not wanted to block
       
  1213         // the store opening if the view building failed.
       
  1214         TRAP_IGNORE( DoActivateRemoteViewsL() );
       
  1215 
       
  1216         // Send event to all observers. This means that multiple pending open requests
       
  1217         // are all signalled as complete here and we can cancel all other open operations.
       
  1218         SendEventL(iObservers, &MVPbkContactStoreObserver::StoreReady, *this);
       
  1219         iAsyncOpenOp->Purge();
       
  1220         }
       
  1221     else
       
  1222         {
       
  1223         // In case the contact database is already open, we come here
       
  1224         SendEventL(&aObserver, &MVPbkContactStoreObserver::StoreReady, *this);
       
  1225         }
       
  1226     }
       
  1227 
       
  1228 // --------------------------------------------------------------------------
       
  1229 // CContactStore::OpenError
       
  1230 // --------------------------------------------------------------------------
       
  1231 //
       
  1232 void CContactStore::OpenError(MVPbkContactStoreObserver& aObserver,
       
  1233         TInt aError)
       
  1234     {
       
  1235     VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
  1236         ("VPbkCntModel: CContactStore::OpenError(%d,0x%x)"), aError, &aObserver);
       
  1237 
       
  1238     SendErrorEvent(iObservers, &MVPbkContactStoreObserver::StoreUnavailable,
       
  1239         *this, aError);
       
  1240     }
       
  1241 
       
  1242 // --------------------------------------------------------------------------
       
  1243 // CContactStore::SetStaticPropertiesL
       
  1244 // --------------------------------------------------------------------------
       
  1245 //
       
  1246 inline void CContactStore::SetStaticPropertiesL()
       
  1247     {
       
  1248     iProperties->SetBooleanProperty
       
  1249         (CVPbkContactStoreProperties::EPropertyFieldLabelSupported, ETrue);
       
  1250     iProperties->SetBooleanProperty
       
  1251         (CVPbkContactStoreProperties::EPropertyDefaultsSupported, ETrue);
       
  1252     iProperties->SetBooleanProperty
       
  1253         (CVPbkContactStoreProperties::EPropertyVoiceTagsSupported,
       
  1254          VoiceTagSupported() );
       
  1255     iProperties->SetBooleanProperty
       
  1256         (CVPbkContactStoreProperties::EPropertySpeedDialsSupported, ETrue);
       
  1257     iProperties->SetBooleanProperty
       
  1258         (CVPbkContactStoreProperties::EPropertyContactGroupsSupported, ETrue);
       
  1259     iProperties->SetBooleanProperty
       
  1260         (CVPbkContactStoreProperties::EPropertyOwnContactSupported, ETrue);
       
  1261     // Contacts Model store is never remote store but always in device memory
       
  1262     // or memory card.
       
  1263     iProperties->SetBooleanProperty(
       
  1264         CVPbkContactStoreProperties::EPropertyLocal, ETrue );
       
  1265     // The store is always persistent because contacts are saved in data base.
       
  1266     iProperties->SetBooleanProperty(
       
  1267         CVPbkContactStoreProperties::EPropertyPersistent, ETrue );
       
  1268 
       
  1269     // For setting removable property we need the drive letter from the URI
       
  1270     TDriveUnit driveUnit( iStoreURI->Uri().Component(
       
  1271         TVPbkContactStoreUriPtr::EContactStoreUriStoreDrive ) );
       
  1272     // Then the removable information can be received from TDriveInfo
       
  1273     TVolumeInfo volInfo;
       
  1274     User::LeaveIfError( iStoreDomain.FsSession().Volume(
       
  1275         volInfo, driveUnit ) );
       
  1276     if ( volInfo.iDrive.iDriveAtt & KDriveAttRemovable )
       
  1277         {
       
  1278         iProperties->SetBooleanProperty(
       
  1279             CVPbkContactStoreProperties::EPropertyRemovable, ETrue );
       
  1280         }
       
  1281     }
       
  1282 
       
  1283 // --------------------------------------------------------------------------
       
  1284 // CContactStore::DoAddFieldTypesL
       
  1285 // --------------------------------------------------------------------------
       
  1286 //
       
  1287 void CContactStore::DoAddFieldTypesL()
       
  1288     {
       
  1289     CVPbkLocalVariationManager* localVariation =
       
  1290         CVPbkLocalVariationManager::NewL();
       
  1291     CleanupStack::PushL(localVariation);
       
  1292 
       
  1293     // open the golden template extension resource file
       
  1294     VPbkEngUtils::RLocalizedResourceFile resFile;
       
  1295     resFile.OpenLC( iStoreDomain.FsSession(),
       
  1296         KVPbkRomFileDrive, KDC_RESOURCE_FILES_DIR, KCntExtResFile );
       
  1297 
       
  1298     // Nick name field
       
  1299     if ( localVariation->LocallyVariatedFeatureEnabled(
       
  1300             EVPbkLVAddNickNameField ) )
       
  1301         {
       
  1302         TResourceReader reader;
       
  1303         reader.SetBuffer(
       
  1304             resFile.AllocReadLC( R_CNTUI_ADD_NICK_NAME_FIELD_DEFNS) );
       
  1305         iFieldsInfo->AppendFieldsL( reader );
       
  1306         // R_CNTUI_ADD_NICK_NAME_FIELD_DEFNS buffer
       
  1307         CleanupStack::PopAndDestroy();
       
  1308         }
       
  1309 
       
  1310     // Video telephony fields
       
  1311     if ( localVariation->LocallyVariatedFeatureEnabled(
       
  1312             EVPbkLVAddVideoTelephonyFields) )
       
  1313         {
       
  1314         TResourceReader reader;
       
  1315         reader.SetBuffer(
       
  1316             resFile.AllocReadLC( R_CNTUI_ADD_VIDEO_TELEPHONY_FIELD_DEFNS) );
       
  1317         iFieldsInfo->AppendFieldsL( reader );
       
  1318         // R_CNTUI_ADD_VIDEO_TELEPHONY_FIELD_DEFNS buffer
       
  1319         CleanupStack::PopAndDestroy();
       
  1320         }
       
  1321 
       
  1322     // VOIP fields
       
  1323     if ( localVariation->LocallyVariatedFeatureEnabled( EVPbkLVVOIP ) )
       
  1324         {
       
  1325         TResourceReader reader;
       
  1326         reader.SetBuffer( resFile.AllocReadLC( R_CNTUI_ADD_VOIP_FIELD_DEFNS) );
       
  1327         iFieldsInfo->AppendFieldsL( reader );
       
  1328         CleanupStack::PopAndDestroy(); // R_CNTUI_ADD_VOIP_FIELD_DEFNS buffer
       
  1329         }
       
  1330 
       
  1331     // PTT/POC field
       
  1332     if ( localVariation->LocallyVariatedFeatureEnabled( EVPbkLVPOC ) )
       
  1333         {
       
  1334         TResourceReader reader;
       
  1335         reader.SetBuffer( resFile.AllocReadLC( R_CNTUI_ADD_POC_FIELD_DEF ) );
       
  1336         iFieldsInfo->AppendFieldsL( reader );
       
  1337         CleanupStack::PopAndDestroy(); // R_CNTUI_ADD_POC_FIELD_DEF buffer
       
  1338         }
       
  1339 
       
  1340     // Share View field
       
  1341     if ( localVariation->LocallyVariatedFeatureEnabled( EVPbkLVShareView ) )
       
  1342         {
       
  1343         TResourceReader reader;
       
  1344         reader.SetBuffer(
       
  1345             resFile.AllocReadLC( R_CNTUI_ADD_SHARE_VIEW_FIELD_DEF ) );
       
  1346         iFieldsInfo->AppendFieldsL( reader );
       
  1347         // R_CNTUI_ADD_SHARE_VIEW_FIELD_DEF buffer
       
  1348         CleanupStack::PopAndDestroy();
       
  1349         }
       
  1350 
       
  1351 
       
  1352     // OLD VOIP fields for compatibility
       
  1353     if ( localVariation->LocallyVariatedFeatureEnabled( EVPbkLVVOIP ) )
       
  1354         {
       
  1355         TResourceReader reader;
       
  1356         reader.SetBuffer( resFile.AllocReadLC(
       
  1357             R_CNTUI_ADD_OLD_VOIP_FIELD_DEFNS ) );
       
  1358         iFieldsInfo->AppendFieldsL( reader );
       
  1359         // R_CNTUI_ADD_OLD_VOIP_FIELD_DEFNS buffer
       
  1360         CleanupStack::PopAndDestroy();
       
  1361         }
       
  1362 
       
  1363 
       
  1364     // OLD PTT/POC field for compatibility
       
  1365     if ( localVariation->LocallyVariatedFeatureEnabled( EVPbkLVPOC ) )
       
  1366         {
       
  1367         TResourceReader reader;
       
  1368         reader.SetBuffer(
       
  1369             resFile.AllocReadLC( R_CNTUI_ADD_OLD_POC_FIELD_DEF ) );
       
  1370         iFieldsInfo->AppendFieldsL( reader );
       
  1371         CleanupStack::PopAndDestroy(); // R_CNTUI_ADD_OLD_POC_FIELD_DEF buffer
       
  1372         }
       
  1373 
       
  1374 
       
  1375     // OLD Share View field for compatibility
       
  1376     if ( localVariation->LocallyVariatedFeatureEnabled( EVPbkLVShareView ) )
       
  1377         {
       
  1378         TResourceReader reader;
       
  1379         reader.SetBuffer(
       
  1380             resFile.AllocReadLC( R_CNTUI_ADD_OLD_SHARE_VIEW_FIELD_DEF ) );
       
  1381         iFieldsInfo->AppendFieldsL( reader );
       
  1382         // R_CNTUI_ADD_OLD_SHARE_VIEW_FIELD_DEF buffer
       
  1383         CleanupStack::PopAndDestroy();
       
  1384         }
       
  1385 
       
  1386     // Generic SIP field
       
  1387     if ( localVariation->LocallyVariatedFeatureEnabled( EVPbkLVAddSIPFields ) )
       
  1388         {
       
  1389         TResourceReader reader;
       
  1390         reader.SetBuffer( resFile.AllocReadLC( R_CNTUI_ADD_SIP_FIELD_DEF ) );
       
  1391         iFieldsInfo->AppendFieldsL( reader );
       
  1392         CleanupStack::PopAndDestroy(); // R_CNTUI_ADD_SIP_FIELD_DEF buffer
       
  1393         }
       
  1394 
       
  1395     // COD fields
       
  1396     if ( FeatureManager::FeatureSupported( KFeatureIdCallImagetext ) )
       
  1397         {
       
  1398         TResourceReader reader;
       
  1399         reader.SetBuffer( resFile.AllocReadLC( R_CNTUI_ADD_COD_FIELD_DEFNS ) );
       
  1400         iFieldsInfo->AppendFieldsL( reader );
       
  1401         CleanupStack::PopAndDestroy(); // R_CNTUI_ADD_COD_FIELD_DEFNS buffer
       
  1402 	    }
       
  1403 
       
  1404     // MDO fields
       
  1405     if ( localVariation->LocallyVariatedFeatureEnabled( EVPbkLVAddMDOFields ) )
       
  1406         {
       
  1407         TResourceReader reader;
       
  1408         reader.SetBuffer(
       
  1409             resFile.AllocReadLC( R_CNTUI_ADD_PREFIX_SUFFIX_FIELD_DEFNS ) );
       
  1410         iFieldsInfo->AppendFieldsL( reader );
       
  1411         // R_CNTUI_ADD_PREFIX_SUFFIX_FIELD_DEFNS buffer
       
  1412         CleanupStack::PopAndDestroy();
       
  1413         }
       
  1414 
       
  1415      // MegaOperator fields
       
  1416     if ( localVariation->LocallyVariatedFeatureEnabled(
       
  1417             EVPbkLVMegaOperatorFields ) )
       
  1418         {
       
  1419         TResourceReader reader;
       
  1420         reader.SetBuffer(
       
  1421             resFile.AllocReadLC( R_CNTUI_ADD_MEGAOP_FIELD_DEFNS ) );
       
  1422         iFieldsInfo->AppendFieldsL( reader );
       
  1423         CleanupStack::PopAndDestroy(); // R_CNTUI_ADD_MEGAOP_FIELD_DEFNS buffer
       
  1424         }
       
  1425 
       
  1426     CleanupStack::PopAndDestroy(2); // resFile, localVariation
       
  1427     }
       
  1428 
       
  1429 // --------------------------------------------------------------------------
       
  1430 // CContactStore::CloseSystemTemplate
       
  1431 // --------------------------------------------------------------------------
       
  1432 //
       
  1433 void CContactStore::CloseSystemTemplate(CContactDatabase* aContactDb)
       
  1434     {
       
  1435     if(iSysTemplate && aContactDb)
       
  1436         {
       
  1437         // according to contacts model documentation closecontactL
       
  1438         // cannot leave, so this is safe.
       
  1439         aContactDb->CloseContactL(iSysTemplate->Id());
       
  1440         delete iSysTemplate;
       
  1441         iSysTemplate = NULL;
       
  1442         }
       
  1443     }
       
  1444 
       
  1445 // --------------------------------------------------------------------------
       
  1446 // CContactStore::OpenL
       
  1447 // --------------------------------------------------------------------------
       
  1448 //
       
  1449 CContactDatabase* CContactStore::OpenInternalL()
       
  1450     {
       
  1451     TBool creating = EFalse;
       
  1452 
       
  1453     CContactDatabase* db = NULL;
       
  1454 
       
  1455     TPtrC dbName( StoreProperties().Name().UriDes() );
       
  1456     TRAPD( err, db = CContactDatabase::OpenL(dbName) );
       
  1457 
       
  1458     if ( KErrNotFound == err )
       
  1459         {
       
  1460         // Database not found --> Creating it
       
  1461         creating = ETrue;
       
  1462         TRAP( err, db = CContactDatabase::CreateL(dbName) );
       
  1463         }
       
  1464 
       
  1465     RSharedDataClient* sharedDataClient = iStoreDomain.SharedDataClient();
       
  1466     if ( KErrDiskFull == err && sharedDataClient )
       
  1467         {
       
  1468         // Try to release space for contact db opening
       
  1469         sharedDataClient->RequestFreeDiskSpaceLC(KDiskSpaceForDbOpening);
       
  1470         if (creating)
       
  1471             {
       
  1472             // Databse was not found --> Creating it
       
  1473             db = CContactDatabase::CreateL(dbName);
       
  1474             }
       
  1475         else
       
  1476             {
       
  1477             // Opening database
       
  1478             db = CContactDatabase::OpenL(dbName);
       
  1479             }
       
  1480         CleanupStack::PopAndDestroy();  // RequestFreeDiskSpaceLC
       
  1481         }
       
  1482     else
       
  1483         {
       
  1484         User::LeaveIfError(err);
       
  1485         }
       
  1486     return db;
       
  1487     }
       
  1488 
       
  1489 // --------------------------------------------------------------------------
       
  1490 // CContactStore::DoActivateRemoteViewsL
       
  1491 // --------------------------------------------------------------------------
       
  1492 //
       
  1493 void CContactStore::DoActivateRemoteViewsL()
       
  1494     {
       
  1495     // create the parameter object
       
  1496     CVPbkSortOrderAcquirer::TSortOrderAcquirerParam param(
       
  1497             MasterFieldTypeList() );
       
  1498     // load ecom plugins to acquire the sort orders from the presentation
       
  1499     // layer
       
  1500     CSortOrderAcquirerList* ecomList = CSortOrderAcquirerList::NewLC(param);
       
  1501 
       
  1502     const TInt count = ecomList->Count();
       
  1503     for ( TInt i = 0; i < count; ++i )
       
  1504         {
       
  1505         CVPbkSortOrderAcquirer& acquirer = ecomList->At( i );
       
  1506         if ( acquirer.ApplySortOrderToStoreL( iStoreURI->Uri() ) )
       
  1507             {
       
  1508             RContactViewSortOrder cntSortOrder = CreateSortOrderL(
       
  1509                 acquirer.SortOrder() );
       
  1510             CleanupClosePushL(cntSortOrder);
       
  1511             // Info is always found because acquirer is from same
       
  1512             // CSortOrderAcquirerList instance.
       
  1513             const CImplementationInformation* info =
       
  1514                     ecomList->FindInfo(acquirer);
       
  1515             TContactViewPreferences viewPrefs = ConvertViewPrefsL(
       
  1516                     info->OpaqueData());
       
  1517 
       
  1518             CNamedRemoteViewHandle* handle = CNamedRemoteViewHandle::NewLC();
       
  1519             // create remote view
       
  1520             handle->CreateRemoteViewL( info->DisplayName(), *iContactDb,
       
  1521                     cntSortOrder, viewPrefs );
       
  1522             // append handle to container
       
  1523             iNamedViewContainer.AppendL( handle );
       
  1524             CleanupStack::Pop( handle );
       
  1525             CleanupStack::PopAndDestroy(); // cntSortOrder
       
  1526             }
       
  1527         }
       
  1528     CleanupStack::PopAndDestroy( ecomList );
       
  1529     }
       
  1530 
       
  1531 // --------------------------------------------------------------------------
       
  1532 // CContactStore::CreateSortOrderL
       
  1533 // --------------------------------------------------------------------------
       
  1534 //
       
  1535 RContactViewSortOrder CContactStore::CreateSortOrderL(
       
  1536         const MVPbkFieldTypeList& aSortOrder) const
       
  1537     {
       
  1538     RContactViewSortOrder sortOrder;
       
  1539     CleanupClosePushL(sortOrder);
       
  1540 
       
  1541     const TInt count = aSortOrder.FieldTypeCount();
       
  1542     for ( TInt i = 0; i < count; ++i )
       
  1543         {
       
  1544         const MVPbkFieldType& fieldType = aSortOrder.FieldTypeAt(i);
       
  1545         // Ignores all field types that are not supported by this store
       
  1546         const CContactItemField* field = iFieldFactory->FindField(
       
  1547             fieldType);
       
  1548         if (field)
       
  1549             {
       
  1550             sortOrder.AppendL(field->ContentType().FieldType(0));
       
  1551             }
       
  1552         }
       
  1553     CleanupStack::Pop(); // sortOrder
       
  1554     return sortOrder;
       
  1555     }
       
  1556 
       
  1557 // --------------------------------------------------------------------------
       
  1558 // CContactStore::ConvertViewPrefsL
       
  1559 // --------------------------------------------------------------------------
       
  1560 //
       
  1561 TContactViewPreferences CContactStore::ConvertViewPrefsL(const TDesC8& aData)
       
  1562     {
       
  1563     // convert character to TContactViewPreferences
       
  1564     TLex8 lexer(aData);
       
  1565     TUint32 output;
       
  1566     User::LeaveIfError(lexer.Val(output, EDecimal));
       
  1567 
       
  1568     TContactViewPreferences prefs = static_cast<TContactViewPreferences>(
       
  1569             output);
       
  1570     return prefs;
       
  1571     }
       
  1572 
       
  1573 // --------------------------------------------------------------------------
       
  1574 // CContactStore::ContactStoreDomainFsSession
       
  1575 // --------------------------------------------------------------------------
       
  1576 //
       
  1577 RFs& CContactStore::ContactStoreDomainFsSession()
       
  1578     {
       
  1579     return iStoreDomain.FsSession();
       
  1580     }
       
  1581 
       
  1582 } /// namespace VPbkCntModel
       
  1583 
       
  1584 // End of File