phonebookui/Phonebook2/CommonUI/src/CPbk2ContactRelocator.cpp
changeset 0 e686773b3f54
child 14 81f8547efd4f
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 relocator.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include <CPbk2ContactRelocator.h>
       
    22 
       
    23 // Phonebook 2
       
    24 #include <CPbk2StoreConfiguration.h>
       
    25 #include <MPbk2ApplicationServices.h>
       
    26 #include <Phonebook2PrivateCRKeys.h>
       
    27 #include <MPbk2ContactRelocatorObserver.h>
       
    28 #include <Pbk2CommonUi.rsg>
       
    29 #include <CPbk2StoreProperty.h>
       
    30 #include <CPbk2StorePropertyArray.h>
       
    31 #include <MPbk2ContactNameFormatter.h>
       
    32 #include <TPbk2DestructionIndicator.h>
       
    33 
       
    34 // Virtual Phonebook
       
    35 #include <MVPbkStoreContact.h>
       
    36 #include <MVPbkContactStore.h>
       
    37 #include <MVPbkContactStoreList.h>
       
    38 #include <MVPbkContactStoreProperties.h>
       
    39 #include <VPbkContactStoreUris.h>
       
    40 #include <CVPbkContactStoreUriArray.h>
       
    41 #include <CVPbkContactManager.h>
       
    42 #include <MVPbkContactOperationBase.h>
       
    43 #include <MVPbkContactLink.h>
       
    44 #include <TVPbkContactStoreUriPtr.h>
       
    45 #include <CVPbkContactLinkArray.h>
       
    46 #include <CPbk2ApplicationServices.h>
       
    47 #include <MVPbkContactCopyPolicy.h>
       
    48 #include <CVPbkContactCopyPolicyManager.h>
       
    49 
       
    50 // System includes
       
    51 #include <centralrepository.h>
       
    52 #include <StringLoader.h>
       
    53 #include <AknQueryDialog.h>
       
    54 
       
    55 /// Unnamed namespace for local definitions
       
    56 namespace {
       
    57 
       
    58 // LOCAL CONSTANTS AND MACROS
       
    59 
       
    60 const TInt KFirstElement = 0;
       
    61 const TInt KOneContact = 1;
       
    62 const TInt KDefaultTitleFormat = MPbk2ContactNameFormatter::EUseSeparator;
       
    63 
       
    64 #ifdef _DEBUG
       
    65 
       
    66 // Definition for many contacts relocation
       
    67 const TInt KLinkArrayRelocationMinCount = 2;
       
    68 
       
    69 enum TPanicCode
       
    70     {
       
    71     EPanicPreCond_ContactsSaved,
       
    72     EPanicLogic_AskConfirmationL,
       
    73     EPanicPreCond_RelocateContactL,
       
    74     EPanicPreCond_RelocateContactsL,
       
    75     EPanicPreCond_RelocateAndLockContactL,
       
    76     EPanicPreCond_PrepareToRelocateContactL,
       
    77     EPanicPreCond_DeleteSourceContact,
       
    78     EPanicPreCond_VerifyRelocationQueryType
       
    79     };
       
    80 
       
    81 void Panic( TInt aReason )
       
    82     {
       
    83     _LIT( KPanicText, "CPbk2ContactRelocator" );
       
    84     User::Panic( KPanicText, aReason );
       
    85     }
       
    86 
       
    87 #endif // _DEBUG
       
    88 
       
    89 /**
       
    90  * Fetches contact's store name, which can be use in relocation queries.
       
    91  * If store name cannot be fetched from global store properties, then
       
    92  * contact's store property is returned.
       
    93  *
       
    94  * @param aContact Reference to contact.
       
    95  * @param aStoreProperties Reference to store properties.
       
    96  * @return Pointer to store name. Ownership is not transferred
       
    97  */
       
    98 const TDesC* StoreName(
       
    99         const MVPbkStoreContact* aContact,
       
   100         CPbk2StorePropertyArray& aStoreProperties )
       
   101     {
       
   102     const TDesC* storeName = NULL;
       
   103     if ( aContact )
       
   104         {
       
   105         // Fetch store name
       
   106         TVPbkContactStoreUriPtr uri =
       
   107             aContact->ParentStore().StoreProperties().Uri();
       
   108         const CPbk2StoreProperty* storeProperty =
       
   109             aStoreProperties.FindProperty( uri );
       
   110 
       
   111         if (storeProperty)
       
   112             {
       
   113             storeName = &storeProperty->StoreName();
       
   114             }
       
   115         else
       
   116             {
       
   117             storeName = &uri.UriDes();
       
   118             }        
       
   119         }
       
   120     return storeName;
       
   121     }
       
   122 
       
   123 } // namespace
       
   124 
       
   125 
       
   126 // --------------------------------------------------------------------------
       
   127 // CPbk2ContactRelocator::CPbk2ContactRelocator
       
   128 // --------------------------------------------------------------------------
       
   129 //
       
   130 CPbk2ContactRelocator::CPbk2ContactRelocator() :
       
   131         CActive( CActive::EPriorityStandard )
       
   132     {
       
   133     CActiveScheduler::Add( this );
       
   134     }
       
   135 
       
   136 // --------------------------------------------------------------------------
       
   137 // CPbk2ContactRelocator::~CPbk2ContactRelocator
       
   138 // --------------------------------------------------------------------------
       
   139 //
       
   140 CPbk2ContactRelocator::~CPbk2ContactRelocator()
       
   141     {
       
   142     Cancel();
       
   143     delete iSourceContact;
       
   144     delete iSourceContacts;
       
   145     delete iRelocatedContact;
       
   146     delete iContactRetriever;
       
   147     delete iSavedContactsRetriever;
       
   148     delete iContactCopier;
       
   149     delete iCopyPolicyManager;
       
   150     delete iQueryDialog;
       
   151 
       
   152     if ( iTargetStore )
       
   153         {
       
   154         iTargetStore->Close( *this );
       
   155         }
       
   156 
       
   157     if ( iDestroyedPtr )
       
   158         {
       
   159         *iDestroyedPtr = ETrue;
       
   160         }
       
   161     Release( iAppServices ); 
       
   162     }
       
   163 
       
   164 // --------------------------------------------------------------------------
       
   165 // CPbk2ContactRelocator::NewL
       
   166 // --------------------------------------------------------------------------
       
   167 //
       
   168 EXPORT_C CPbk2ContactRelocator* CPbk2ContactRelocator::NewL()
       
   169     {
       
   170     CPbk2ContactRelocator* self =
       
   171         new ( ELeave ) CPbk2ContactRelocator();
       
   172     CleanupStack::PushL( self );
       
   173     self->ConstructL();
       
   174     CleanupStack::Pop( self );
       
   175     return self;
       
   176     }
       
   177 
       
   178 // --------------------------------------------------------------------------
       
   179 // CPbk2ContactRelocator::ConstructL
       
   180 // --------------------------------------------------------------------------
       
   181 //
       
   182 inline void CPbk2ContactRelocator::ConstructL()
       
   183     {
       
   184     iAppServices = CPbk2ApplicationServices::InstanceL();
       
   185     iRelocationPolicy = ReadRelocationPolicyL();
       
   186     }
       
   187 
       
   188 // --------------------------------------------------------------------------
       
   189 // CPbk2ContactRelocator::RelocateContactL
       
   190 // --------------------------------------------------------------------------
       
   191 //
       
   192 EXPORT_C TBool CPbk2ContactRelocator::RelocateContactL(
       
   193         MVPbkStoreContact* aContact,
       
   194         MPbk2ContactRelocatorObserver& aObserver,
       
   195         Pbk2ContactRelocator::TPbk2ContactRelocationQueryPolicy aQueryPolicy,
       
   196         TUint32 aFlags )
       
   197     {
       
   198     __ASSERT_DEBUG( aContact, Panic( EPanicPreCond_RelocateContactL ) );
       
   199 
       
   200     // Adjust policy
       
   201     if ( iRelocationPolicy == Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemoryAndLock )
       
   202         {
       
   203         iRelocationPolicy = Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemory;
       
   204         }
       
   205     else if ( iRelocationPolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock )
       
   206         {
       
   207         iRelocationPolicy = Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemory;
       
   208         }
       
   209 
       
   210     return PrepareToRelocateContactL( aContact, NULL, aObserver,
       
   211         aQueryPolicy, aFlags );
       
   212     }
       
   213 
       
   214 // --------------------------------------------------------------------------
       
   215 // CPbk2ContactRelocator::RelocateAndLockContactL
       
   216 // --------------------------------------------------------------------------
       
   217 //
       
   218 EXPORT_C TBool CPbk2ContactRelocator::RelocateAndLockContactL(
       
   219         MVPbkStoreContact* aContact,
       
   220         MPbk2ContactRelocatorObserver& aObserver,
       
   221         Pbk2ContactRelocator::TPbk2ContactRelocationQueryPolicy aQueryPolicy,
       
   222         TUint32 aFlags )
       
   223     {
       
   224     __ASSERT_DEBUG( aContact, Panic( EPanicPreCond_RelocateAndLockContactL ) );
       
   225 
       
   226     // Adjust policy
       
   227     if ( iRelocationPolicy == Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemory )
       
   228         {
       
   229         iRelocationPolicy = Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemoryAndLock;
       
   230         }
       
   231     else if ( iRelocationPolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemory )
       
   232         {
       
   233         iRelocationPolicy = Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock;
       
   234         }
       
   235 
       
   236     return PrepareToRelocateContactL( aContact, NULL, aObserver,
       
   237         aQueryPolicy, aFlags );
       
   238     }
       
   239 
       
   240 // --------------------------------------------------------------------------
       
   241 // CPbk2ContactRelocator::RelocateContactsL
       
   242 // --------------------------------------------------------------------------
       
   243 //
       
   244 EXPORT_C TBool CPbk2ContactRelocator::RelocateContactsL(
       
   245         CVPbkContactLinkArray* aContacts,
       
   246         MPbk2ContactRelocatorObserver& aObserver,
       
   247         Pbk2ContactRelocator::TPbk2ContactRelocationQueryPolicy aQueryPolicy )
       
   248     {
       
   249     __ASSERT_DEBUG( aContacts, Panic(EPanicPreCond_RelocateContactsL ) );
       
   250 
       
   251     return PrepareToRelocateContactL( NULL, aContacts, aObserver,
       
   252         aQueryPolicy, EPbk2RelocatorExistingContact );
       
   253     }
       
   254 
       
   255 // --------------------------------------------------------------------------
       
   256 // CPbk2ContactRelocator::IsPhoneMemoryContact
       
   257 // --------------------------------------------------------------------------
       
   258 //
       
   259 EXPORT_C TBool CPbk2ContactRelocator::IsPhoneMemoryContact(
       
   260         const MVPbkStoreContact& aContact) const
       
   261     {
       
   262     TBool ret = EFalse;
       
   263 
       
   264     TVPbkContactStoreUriPtr uri =
       
   265         aContact.ParentStore().StoreProperties().Uri();
       
   266 
       
   267     TVPbkContactStoreUriPtr phoneMemoryUri
       
   268         ( VPbkContactStoreUris::DefaultCntDbUri() );
       
   269 
       
   270     if (uri.Compare( phoneMemoryUri,
       
   271         TVPbkContactStoreUriPtr::EContactStoreUriStoreType ) == 0)
       
   272         {
       
   273         ret = ETrue;
       
   274         }
       
   275 
       
   276     return ret;
       
   277     }
       
   278 
       
   279 // --------------------------------------------------------------------------
       
   280 // CPbk2ContactRelocator::IsPhoneMemoryInConfigurationL
       
   281 // --------------------------------------------------------------------------
       
   282 //
       
   283 EXPORT_C TBool CPbk2ContactRelocator::IsPhoneMemoryInConfigurationL() const
       
   284     {
       
   285     TBool ret = EFalse;
       
   286 
       
   287     // Get current configuration
       
   288     CPbk2StoreConfiguration& storeConfig = iAppServices->StoreConfiguration();
       
   289 
       
   290     CVPbkContactStoreUriArray* uriArray = storeConfig.CurrentConfigurationL();
       
   291 
       
   292     // Check is phone memory included
       
   293     ret = uriArray->IsIncluded( VPbkContactStoreUris::DefaultCntDbUri() );
       
   294     delete uriArray;
       
   295 
       
   296     return ret;
       
   297     }
       
   298 
       
   299 // --------------------------------------------------------------------------
       
   300 // CPbk2ContactRelocator::RunL
       
   301 // --------------------------------------------------------------------------
       
   302 //
       
   303 void CPbk2ContactRelocator::RunL()
       
   304     {
       
   305     // This methods gets called only when the relocation was cancelled or
       
   306     // otherwise stopped at the very beginning. The observer is needed to
       
   307     // be called back asynchronously, so the active object is set running.
       
   308     if ( iSourceContact )
       
   309         {
       
   310         MVPbkStoreContact* sourceContact = iSourceContact;
       
   311         iSourceContact = NULL;
       
   312         iObserver->ContactRelocationFailed( iErrorCode, sourceContact );
       
   313         }
       
   314     else if ( iSourceContacts )
       
   315         {
       
   316         CVPbkContactLinkArray* sourceContacts = iSourceContacts;
       
   317         iSourceContacts = NULL;
       
   318         iObserver->ContactsRelocationFailed( iErrorCode, sourceContacts );
       
   319         }
       
   320     }
       
   321 
       
   322 // --------------------------------------------------------------------------
       
   323 // CPbk2ContactRelocator::DoCancel
       
   324 // --------------------------------------------------------------------------
       
   325 //
       
   326 void CPbk2ContactRelocator::DoCancel()
       
   327     {
       
   328     // Do nothing
       
   329     }
       
   330 
       
   331 // --------------------------------------------------------------------------
       
   332 // CPbk2ContactRelocator::RunError
       
   333 // --------------------------------------------------------------------------
       
   334 //
       
   335 TInt CPbk2ContactRelocator::RunError( TInt /*aError*/ )
       
   336     {
       
   337     // No leaving code in RunL
       
   338     return KErrNone;
       
   339     }
       
   340 
       
   341 // --------------------------------------------------------------------------
       
   342 // CPbk2ContactRelocator::StoreReady
       
   343 // Phone memory store was succesfully opened.
       
   344 // --------------------------------------------------------------------------
       
   345 //
       
   346 void CPbk2ContactRelocator::StoreReady
       
   347         ( MVPbkContactStore& /*aContactStore*/ )
       
   348     {
       
   349     iTargetStoreOpen = ETrue;
       
   350     // Safe to ignore error
       
   351     TRAP_IGNORE( DoRelocateContactL() );
       
   352     }
       
   353 
       
   354 // --------------------------------------------------------------------------
       
   355 // CPbk2ContactRelocator::StoreUnavailable
       
   356 // --------------------------------------------------------------------------
       
   357 //
       
   358 void CPbk2ContactRelocator::StoreUnavailable
       
   359         ( MVPbkContactStore& /*aContactStore*/, TInt aReason )
       
   360     {
       
   361     // Problem in opening phone memory store
       
   362     iObserver->ContactRelocationFailed( aReason, iSourceContact );
       
   363     iSourceContact = NULL; // ownership was given away
       
   364     }
       
   365 
       
   366 // --------------------------------------------------------------------------
       
   367 // CPbk2ContactRelocator::HandleStoreEventL
       
   368 // --------------------------------------------------------------------------
       
   369 //
       
   370 void CPbk2ContactRelocator::HandleStoreEventL
       
   371         ( MVPbkContactStore& /*aContactStore*/,
       
   372         TVPbkContactStoreEvent /*aStoreEvent*/ )
       
   373     {
       
   374     // Do nothing
       
   375     }
       
   376 
       
   377 // --------------------------------------------------------------------------
       
   378 // CPbk2ContactRelocator::FieldAddedToContact
       
   379 // --------------------------------------------------------------------------
       
   380 //
       
   381 void CPbk2ContactRelocator::FieldAddedToContact
       
   382         ( MVPbkContactOperationBase& /*aOperation*/ )
       
   383     {
       
   384     // Do nothing
       
   385     }
       
   386 
       
   387 // --------------------------------------------------------------------------
       
   388 // CPbk2ContactRelocator::FieldAddingFailed
       
   389 // --------------------------------------------------------------------------
       
   390 //
       
   391 void CPbk2ContactRelocator::FieldAddingFailed
       
   392         ( MVPbkContactOperationBase& /*aOperation*/, TInt /*aError*/ )
       
   393     {
       
   394     // Do nothing
       
   395     }
       
   396 
       
   397 // --------------------------------------------------------------------------
       
   398 // CPbk2ContactRelocator::ContactsSaved
       
   399 // Contact was succesfully saved to phone memory
       
   400 // --------------------------------------------------------------------------
       
   401 //
       
   402 void CPbk2ContactRelocator::ContactsSaved
       
   403         ( MVPbkContactOperationBase& /*aOperation*/,
       
   404         MVPbkContactLinkArray* aResults )
       
   405     {
       
   406     // There should be only one link in the results array
       
   407     __ASSERT_DEBUG( aResults && aResults->Count() == KOneContact,
       
   408         Panic( EPanicPreCond_ContactsSaved ) );
       
   409 
       
   410     TRAPD( err,
       
   411         {
       
   412         CleanupDeletePushL( aResults );
       
   413 
       
   414         // Next, retrieve the saved contact
       
   415         RetrieveSavedContactL( aResults->At( KFirstElement ) );
       
   416         CleanupStack::PopAndDestroy(); // aResults
       
   417         });
       
   418 
       
   419     if ( err != KErrNone )
       
   420         {
       
   421         iObserver->ContactRelocationFailed( err, iSourceContact );
       
   422         iSourceContact = NULL; // ownership was given away
       
   423         }
       
   424 
       
   425     }
       
   426 
       
   427 // --------------------------------------------------------------------------
       
   428 // CPbk2ContactRelocator::ContactsSavingFailed
       
   429 // --------------------------------------------------------------------------
       
   430 //
       
   431 void CPbk2ContactRelocator::ContactsSavingFailed
       
   432         ( MVPbkContactOperationBase& /*aOperation*/, TInt aError )
       
   433     {
       
   434     // Contact was not succesfully saved to phone memory
       
   435     iObserver->ContactRelocationFailed( aError, iSourceContact );
       
   436     iSourceContact = NULL; // ownership was given away
       
   437 
       
   438     // Move to next request, if any. Safe to ignore error.
       
   439     TRAP_IGNORE( DoRelocateContactL() );
       
   440     }
       
   441 
       
   442 // --------------------------------------------------------------------------
       
   443 // CPbk2ContactRelocator::VPbkSingleContactOperationComplete
       
   444 // Contact was succesfully retrieved from a link.
       
   445 // --------------------------------------------------------------------------
       
   446 //
       
   447 void CPbk2ContactRelocator::VPbkSingleContactOperationComplete
       
   448         ( MVPbkContactOperationBase& aOperation,
       
   449         MVPbkStoreContact* aContact )
       
   450     {
       
   451     if ( &aOperation == iSavedContactsRetriever )
       
   452         {
       
   453         // Destroy the last relocated contact
       
   454         delete iRelocatedContact;
       
   455         iRelocatedContact = NULL;
       
   456         // Assign a new relocated contact
       
   457         iRelocatedContact = aContact;
       
   458         if ( ( iActivePolicy == Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemoryAndLock ) ||
       
   459             ( iActivePolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock ) )
       
   460             {
       
   461             // Lock the contact
       
   462             TRAPD( err, iRelocatedContact->LockL( *this ) );
       
   463             if ( err != KErrNone )
       
   464                 {
       
   465                 iObserver->ContactRelocationFailed( err, iSourceContact );
       
   466                 iSourceContact = NULL; // ownership was given away
       
   467 
       
   468                 // Move to next request, if any. Safe to ignore error.
       
   469                 TRAP_IGNORE( DoRelocateContactL() );
       
   470                 }
       
   471             }
       
   472         else if ( iActivePolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemory )
       
   473             {
       
   474             DeleteSourceContact();
       
   475             }
       
   476         else // EPbk2CopyContactToPhoneMemory
       
   477             {
       
   478             DoHandleContactRelocated();
       
   479             TRAP_IGNORE( DoRelocateContactL() );
       
   480             FinalizeIfReady();
       
   481             }
       
   482         }
       
   483     else if ( &aOperation == iContactRetriever )
       
   484         {
       
   485         // One contact from given link array was retrieved, now it has
       
   486         // to be stored and then relocated
       
   487         iSourceContact = aContact;
       
   488         TRAP_IGNORE( DoRelocateContactL() );
       
   489         }
       
   490     }
       
   491 
       
   492 // --------------------------------------------------------------------------
       
   493 // CPbk2ContactRelocator::VPbkSingleContactOperationFailed
       
   494 // Contact was not succesfully retrieved from a link.
       
   495 // --------------------------------------------------------------------------
       
   496 //
       
   497 void CPbk2ContactRelocator::VPbkSingleContactOperationFailed
       
   498         ( MVPbkContactOperationBase& /*aOperation*/, TInt aError )
       
   499     {
       
   500     iObserver->ContactRelocationFailed( aError, iSourceContact );
       
   501     iSourceContact = NULL; // ownership was given away
       
   502 
       
   503     // Move to next request, if any
       
   504     TRAP_IGNORE( DoRelocateContactL() );
       
   505     }
       
   506 
       
   507 // --------------------------------------------------------------------------
       
   508 // CPbk2ContactRelocator::ContactOperationCompleted
       
   509 // --------------------------------------------------------------------------
       
   510 //
       
   511 void CPbk2ContactRelocator::ContactOperationCompleted
       
   512         ( TContactOpResult aResult )
       
   513     {
       
   514     if ( aResult.iOpCode == MVPbkContactObserver::EContactLock )
       
   515         {
       
   516         if ( iActivePolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock )
       
   517             {
       
   518             // One step to -> delete the original contact
       
   519             DeleteSourceContact();
       
   520             }
       
   521         else
       
   522             {
       
   523             // Relocation is done with current contact
       
   524             DoHandleContactRelocated();
       
   525             // Continue if there are still contacts to relocate
       
   526             TRAP_IGNORE( DoRelocateContactL() );
       
   527             FinalizeIfReady();
       
   528             }
       
   529         }
       
   530     else if ( aResult.iOpCode == MVPbkContactObserver::EContactDelete )
       
   531         {
       
   532         // The original contact was succesfully deleted.
       
   533         // Notify has already been called, so move to next request, if any.
       
   534         // In practise:
       
   535         DoHandleContactRelocated();
       
   536         TRAP_IGNORE( DoRelocateContactL() );
       
   537         FinalizeIfReady();
       
   538         }
       
   539     }
       
   540 
       
   541 // --------------------------------------------------------------------------
       
   542 // CPbk2ContactRelocator::ContactOperationFailed
       
   543 // --------------------------------------------------------------------------
       
   544 //
       
   545 void CPbk2ContactRelocator::ContactOperationFailed
       
   546         ( TContactOp /*aOpCode*/, TInt aErrorCode,
       
   547         TBool /*aErrorNotified*/ )
       
   548     {
       
   549     // Request of the deletion of the original contact
       
   550     // was not succesfully completed
       
   551     // Give ownership of the failed contact to the observer
       
   552     iObserver->ContactRelocationFailed( aErrorCode, iSourceContact );
       
   553     iSourceContact = NULL;
       
   554 
       
   555     // Move to next request, if any
       
   556     TRAP_IGNORE( DoRelocateContactL() );
       
   557     }
       
   558 
       
   559 // --------------------------------------------------------------------------
       
   560 // CPbk2ContactRelocator::ReadRelocationPolicyL
       
   561 // --------------------------------------------------------------------------
       
   562 //
       
   563 Pbk2ContactRelocator::TPbk2ContactRelocationPolicy
       
   564         CPbk2ContactRelocator::ReadRelocationPolicyL()
       
   565     {
       
   566     // Default to copy option
       
   567     Pbk2ContactRelocator::TPbk2ContactRelocationPolicy ret = Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemory;
       
   568     TInt result = 0;
       
   569 
       
   570     // Get real setting from central repository
       
   571     CRepository* repository = CRepository::NewL
       
   572         ( TUid::Uid( KCRUidPhonebookInternalConfig ) );
       
   573     CleanupStack::PushL( repository );
       
   574     TInt err = repository->Get( KPhonebookContactRelocationPolicy, result );
       
   575     if ( err == KErrNone )
       
   576         {
       
   577         ret  = Pbk2ContactRelocator::TPbk2ContactRelocationPolicy( result );
       
   578         }
       
   579 
       
   580     CleanupStack::PopAndDestroy( repository );
       
   581     return ret;
       
   582     }
       
   583 
       
   584 // --------------------------------------------------------------------------
       
   585 // CPbk2ContactRelocator::OpenTargetStoreL
       
   586 // --------------------------------------------------------------------------
       
   587 //
       
   588 void CPbk2ContactRelocator::OpenTargetStoreL()
       
   589     {
       
   590     if ( !iTargetStore )
       
   591         {
       
   592         const TVPbkContactStoreUriPtr phoneMemoryUri =
       
   593             VPbkContactStoreUris::DefaultCntDbUri();
       
   594         CVPbkContactManager& contactManager =
       
   595             iAppServices->ContactManager();
       
   596         contactManager.LoadContactStoreL( phoneMemoryUri );
       
   597 
       
   598         MVPbkContactStoreList& storeList = contactManager.ContactStoresL();
       
   599 
       
   600         iTargetStore = storeList.Find( phoneMemoryUri );
       
   601         User::LeaveIfNull( iTargetStore );
       
   602         iTargetStore->OpenL( *this );
       
   603         }
       
   604     }
       
   605 
       
   606 // --------------------------------------------------------------------------
       
   607 // CPbk2ContactRelocator::DoRelocateContactL
       
   608 // --------------------------------------------------------------------------
       
   609 //
       
   610 void CPbk2ContactRelocator::DoRelocateContactL()
       
   611     {
       
   612     // No previous multirelocate request exists,
       
   613     // cleanup the previous request
       
   614     if ( iSourceContacts && iSourceContacts->Count() < KOneContact )
       
   615         {
       
   616         // All contacts were sent to relocation, its important
       
   617         // to clean the array and set it NULL
       
   618         delete iSourceContacts;
       
   619         iSourceContacts = NULL;
       
   620         }
       
   621 
       
   622     if ( iSourceContact )
       
   623         {
       
   624         // Start the copy operation
       
   625         CopyContactL( *iSourceContact );
       
   626         }
       
   627     else if ( iSourceContacts )
       
   628         {
       
   629         // Since we can not use batch copy operation (it does not give
       
   630         // copied contact links back) we have to retrieve all the contacts
       
   631         // and relocate them one by one
       
   632         if ( iSourceContacts->Count() >= KOneContact )
       
   633             {
       
   634             // Take the first contact link of the array
       
   635             MVPbkContactLink* contactLink =
       
   636                 iSourceContacts->At( KFirstElement ).CloneLC();
       
   637             // Then remove it from the array
       
   638             iSourceContacts->Delete( KFirstElement );
       
   639 
       
   640             // Then retrieve it
       
   641             delete iContactRetriever;
       
   642             iContactRetriever = NULL;
       
   643             iContactRetriever =
       
   644                 iAppServices->ContactManager().
       
   645                     RetrieveContactL( *contactLink, *this );
       
   646             CleanupStack::PopAndDestroy(); // contactLink
       
   647             }
       
   648         }
       
   649     }
       
   650 
       
   651 // --------------------------------------------------------------------------
       
   652 // CPbk2ContactRelocator::InitCopyPolicyL
       
   653 // --------------------------------------------------------------------------
       
   654 //
       
   655 inline void CPbk2ContactRelocator::InitCopyPolicyL()
       
   656     {
       
   657     if (!iCopyPolicy)
       
   658         {
       
   659         // There is no copy policy manager if we are in this method
       
   660         // so creating a new one is always ok
       
   661         delete iCopyPolicyManager;
       
   662         iCopyPolicyManager = NULL;
       
   663         iCopyPolicyManager = CVPbkContactCopyPolicyManager::NewL();
       
   664         iCopyPolicy = iCopyPolicyManager->GetPolicyL
       
   665             ( iAppServices->ContactManager(),
       
   666             VPbkContactStoreUris::DefaultCntDbUri());
       
   667         }
       
   668     }
       
   669 
       
   670 // --------------------------------------------------------------------------
       
   671 // CPbk2ContactRelocator::DoHandleContactRelocated
       
   672 // --------------------------------------------------------------------------
       
   673 //
       
   674 void CPbk2ContactRelocator::DoHandleContactRelocated()
       
   675     {
       
   676     if ( iRelocatedContact )
       
   677         {
       
   678         MVPbkStoreContact* relocatedContact = iRelocatedContact;
       
   679         iRelocatedContact = NULL;
       
   680         // Give ownership of the relocated contact to client.
       
   681         TRAPD( res, iObserver->ContactRelocatedL( relocatedContact ) );
       
   682         if ( res != KErrNone )
       
   683             {
       
   684             MVPbkStoreContact* sourceContact = iSourceContact;
       
   685             iSourceContact = NULL;
       
   686             // Give source contact as documented in observer. Client
       
   687             // takes the ownership
       
   688             iObserver->ContactRelocationFailed( res, sourceContact );
       
   689             }
       
   690 
       
   691         delete iSourceContact;
       
   692         iSourceContact = NULL;
       
   693         }
       
   694     }
       
   695 
       
   696 // --------------------------------------------------------------------------
       
   697 // CPbk2ContactRelocator::DeleteSourceContact
       
   698 // --------------------------------------------------------------------------
       
   699 //
       
   700 void CPbk2ContactRelocator::DeleteSourceContact()
       
   701     {
       
   702     // Source contact is deleted only if policy is MOVE
       
   703     __ASSERT_DEBUG( iActivePolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemory ||
       
   704         iActivePolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock,
       
   705         Panic( EPanicPreCond_DeleteSourceContact ) );
       
   706 
       
   707     // Delete original contact
       
   708     if ( iSourceContact )
       
   709         {
       
   710         TRAPD( err, iSourceContact->DeleteL( *this ) );
       
   711         if ( err != KErrNone )
       
   712             {
       
   713             MVPbkStoreContact* sourceContact = iSourceContact;
       
   714             iSourceContact = NULL;
       
   715             // Give source contact as documented in observer. Client
       
   716             // takes the ownership
       
   717             iObserver->ContactRelocationFailed( err, sourceContact );
       
   718             if ( !iSourceContacts )
       
   719                 {
       
   720                 // If no more contacts to relocate then complete the relocation
       
   721                 iObserver->RelocationProcessComplete();
       
   722                 }
       
   723             }
       
   724         }
       
   725     }
       
   726 
       
   727 // --------------------------------------------------------------------------
       
   728 // CPbk2ContactRelocator::AskConfirmationL
       
   729 // --------------------------------------------------------------------------
       
   730 //
       
   731 TBool CPbk2ContactRelocator::AskConfirmationL(
       
   732         MVPbkStoreContact* aContact,
       
   733         CVPbkContactLinkArray* aContacts,
       
   734         TPbk2RelocationQueryType aRelocationQueryType )
       
   735     {
       
   736     TBool ret = ETrue;
       
   737 
       
   738     HBufC* prompt = NULL;
       
   739     HBufC* nameBuffer = NULL;
       
   740     const TDesC* storeName = 
       
   741         StoreName( aContact,
       
   742             iAppServices->StoreProperties() );
       
   743 
       
   744     if ( aContact )
       
   745         {
       
   746         nameBuffer = 
       
   747                 iAppServices->NameFormatter().
       
   748                     GetContactTitleL( aContact->Fields(), KDefaultTitleFormat );
       
   749 
       
   750         CleanupStack::PushL( nameBuffer );    
       
   751         }   
       
   752                     
       
   753     switch( aRelocationQueryType )
       
   754         {
       
   755         case EPbk2NoRelocationQuery:
       
   756         //don't show the following queries anymore
       
   757         case EPbk2CopyOneToStoreQuery:
       
   758         case EPbk2MoveOneToStoreQuery:
       
   759         case EPbk2CopyOneToPhoneQuery:
       
   760         case EPbk2MoveOneToPhoneQuery:
       
   761         case EPbk2CopyManyToStoreQuery:
       
   762         case EPbk2MoveManyToStoreQuery:
       
   763             {
       
   764             // Do nothing
       
   765             }
       
   766             break;
       
   767         default:
       
   768             {
       
   769             __ASSERT_DEBUG( EFalse,
       
   770                 Panic( EPanicLogic_AskConfirmationL ) );
       
   771             break;
       
   772             }            
       
   773         }
       
   774     
       
   775     if ( prompt )
       
   776         {
       
   777         CleanupStack::PushL( prompt );
       
   778         delete iQueryDialog;
       
   779         iQueryDialog = NULL;
       
   780         iQueryDialog = CAknQueryDialog::NewL();
       
   781         iQueryDialog->SetPromptL( *prompt );
       
   782 
       
   783         CleanupStack::PopAndDestroy( prompt );
       
   784 
       
   785         ret = iQueryDialog->ExecuteLD( R_PBK2_COMMONUI_CONFIRMATION_QUERY );
       
   786         iQueryDialog = NULL;
       
   787         }
       
   788 
       
   789     if ( aContact )
       
   790         {
       
   791         CleanupStack::PopAndDestroy(); // nameBuffer    
       
   792         }
       
   793     return ret;    
       
   794     }
       
   795 
       
   796 // --------------------------------------------------------------------------
       
   797 // CPbk2ContactRelocator::RetrieveSavedContactL
       
   798 // --------------------------------------------------------------------------
       
   799 //
       
   800 void CPbk2ContactRelocator::RetrieveSavedContactL
       
   801         ( const MVPbkContactLink& aLink )
       
   802     {
       
   803     delete iSavedContactsRetriever;
       
   804     iSavedContactsRetriever = NULL;
       
   805     iSavedContactsRetriever =
       
   806         iAppServices->ContactManager().
       
   807             RetrieveContactL( aLink, *this );
       
   808     }
       
   809 
       
   810 // --------------------------------------------------------------------------
       
   811 // CPbk2ContactRelocator::VerifyPolicy
       
   812 // --------------------------------------------------------------------------
       
   813 //
       
   814 inline void CPbk2ContactRelocator::VerifyPolicy(
       
   815         MVPbkStoreContact* aContact, TUint32 aFlags )
       
   816     {
       
   817     // Reset policy
       
   818     iActivePolicy = iRelocationPolicy;
       
   819 
       
   820     // Read-only contacts can not be moved so
       
   821     // adjust active policy if necessary. New contacts are also not moved.
       
   822     if ( iRelocationPolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemory ||
       
   823          iRelocationPolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock )
       
   824         {
       
   825         if ( aContact )
       
   826             {
       
   827             if (aContact->ParentStore().StoreProperties().ReadOnly() ||
       
   828                 aFlags & EPbk2RelocatorNewContact )
       
   829                 {
       
   830                 iActivePolicy = Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemory;
       
   831                 if ( iRelocationPolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock )
       
   832                     {
       
   833                     iActivePolicy = Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemoryAndLock;
       
   834                     }
       
   835                 }            
       
   836             }
       
   837         }
       
   838     }
       
   839 
       
   840 // --------------------------------------------------------------------------
       
   841 // CPbk2ContactRelocator::PrepareToRelocateContactL
       
   842 // --------------------------------------------------------------------------
       
   843 //
       
   844 TBool CPbk2ContactRelocator::PrepareToRelocateContactL(
       
   845         MVPbkStoreContact* aContact,
       
   846         CVPbkContactLinkArray* aContacts,
       
   847         MPbk2ContactRelocatorObserver& aObserver,
       
   848         Pbk2ContactRelocator::TPbk2ContactRelocationQueryPolicy aQueryPolicy,
       
   849         TUint32 aFlags )
       
   850     {
       
   851     __ASSERT_DEBUG( !iSourceContact && !iSourceContacts,
       
   852         Panic( EPanicPreCond_PrepareToRelocateContactL ) );
       
   853 
       
   854     iObserver = &aObserver;
       
   855 
       
   856     TBool result = EFalse;
       
   857 
       
   858     // If this is deleted when confirmation note returns do not access
       
   859     // any member data.
       
   860     TBool thisDestroyed = EFalse;
       
   861     iDestroyedPtr = &thisDestroyed;
       
   862     TPbk2DestructionIndicator indicator
       
   863         ( &thisDestroyed, iDestroyedPtr );
       
   864 
       
   865     
       
   866     if ( aContact || aContacts )
       
   867         {
       
   868         VerifyPolicy( aContact, aFlags );
       
   869         TPbk2RelocationQueryType relocationQueryType =
       
   870             SelectRelocationQueryType( aContact, aContacts, aQueryPolicy );        
       
   871             
       
   872         // Take ownership
       
   873         iSourceContact = aContact;
       
   874         iSourceContacts = aContacts;
       
   875         
       
   876         result = AskConfirmationL( aContact, aContacts, relocationQueryType );
       
   877         }
       
   878     else
       
   879         {
       
   880         iErrorCode  = KErrArgument;
       
   881         }
       
   882             
       
   883     if ( !thisDestroyed )
       
   884         {
       
   885         if ( !result )
       
   886             {
       
   887             iErrorCode = KErrCancel;
       
   888             }
       
   889 
       
   890         if ( iErrorCode != KErrNone )
       
   891             {
       
   892             // Inform failure asynchronously
       
   893             TRequestStatus* status = &iStatus;
       
   894             User::RequestComplete( status, KErrNone );
       
   895             SetActive();
       
   896             }
       
   897         else
       
   898             {
       
   899             if ( !iTargetStoreOpen )
       
   900                 {
       
   901                 OpenTargetStoreL();
       
   902                 }
       
   903             else
       
   904                 {
       
   905                 DoRelocateContactL();
       
   906                 }
       
   907             }
       
   908         }
       
   909 
       
   910     return result;
       
   911     }
       
   912 
       
   913 // --------------------------------------------------------------------------
       
   914 // CPbk2ContactRelocator::CopyContactL
       
   915 // --------------------------------------------------------------------------
       
   916 //
       
   917 void CPbk2ContactRelocator::CopyContactL( MVPbkStoreContact& aContact )
       
   918     {
       
   919     // Init copy policy
       
   920     InitCopyPolicyL();
       
   921 
       
   922     delete iContactCopier;
       
   923     iContactCopier = NULL;
       
   924     iContactCopier = iCopyPolicy->CopyContactL
       
   925         ( aContact, *iTargetStore, *this );
       
   926     }
       
   927 
       
   928 // --------------------------------------------------------------------------
       
   929 // CPbk2ContactRelocator::FinalizeIfReady
       
   930 // --------------------------------------------------------------------------
       
   931 //
       
   932 void CPbk2ContactRelocator::FinalizeIfReady()
       
   933     {
       
   934     // If there are no more contacts waiting to be relocated in this
       
   935     // request, signal process complete
       
   936     if ( !iSourceContacts )
       
   937         {
       
   938         iObserver->RelocationProcessComplete();
       
   939         }
       
   940     }
       
   941 
       
   942 // --------------------------------------------------------------------------
       
   943 // CPbk2ContactRelocator::SelectRelocationQueryType
       
   944 // --------------------------------------------------------------------------
       
   945 //
       
   946 CPbk2ContactRelocator::TPbk2RelocationQueryType 
       
   947     CPbk2ContactRelocator::SelectRelocationQueryType(
       
   948         MVPbkStoreContact* aContact,
       
   949         CVPbkContactLinkArray* aContacts,
       
   950         Pbk2ContactRelocator::TPbk2ContactRelocationQueryPolicy
       
   951         aQueryPolicy )
       
   952     {    
       
   953     TPbk2RelocationQueryType relocationQueryType(EPbk2NoRelocationQuery);
       
   954     TBool moveRelocation(EFalse);
       
   955     
       
   956     if ( Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemory == iActivePolicy || 
       
   957          Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock == iActivePolicy )
       
   958         {
       
   959         moveRelocation = ETrue;
       
   960         }
       
   961 
       
   962     switch (aQueryPolicy)
       
   963         {
       
   964         case Pbk2ContactRelocator::EPbk2DisplayNoQueries:
       
   965             {
       
   966             relocationQueryType = EPbk2NoRelocationQuery;
       
   967             }
       
   968             break;
       
   969         
       
   970         case Pbk2ContactRelocator::EPbk2DisplayBasicQuery:
       
   971             {
       
   972             relocationQueryType = EPbk2CopyOneToStoreQuery;
       
   973             if ( moveRelocation )
       
   974                 {
       
   975                 relocationQueryType = EPbk2MoveOneToStoreQuery;
       
   976                 }
       
   977             }
       
   978             break;
       
   979     
       
   980         case Pbk2ContactRelocator::EPbk2DisplayStoreDoesNotSupportQuery:
       
   981             {
       
   982             relocationQueryType = EPbk2CopyOneToPhoneQuery;
       
   983             if ( moveRelocation )
       
   984                 {
       
   985                 relocationQueryType = EPbk2MoveOneToPhoneQuery;
       
   986                 }
       
   987             }
       
   988             break;
       
   989 
       
   990         default:
       
   991             {
       
   992             __ASSERT_DEBUG( EFalse,
       
   993                 Panic( EPanicPreCond_VerifyRelocationQueryType ) );
       
   994             break;
       
   995             }
       
   996         }
       
   997         
       
   998     if ( !aContact && aContacts && 
       
   999          aQueryPolicy != Pbk2ContactRelocator::EPbk2DisplayNoQueries )
       
  1000         {
       
  1001         // Relocation is going to be done for many contacts
       
  1002         // and query policy is defined.
       
  1003         __ASSERT_DEBUG( aContacts->Count() >= KLinkArrayRelocationMinCount, 
       
  1004                         Panic( EPanicPreCond_VerifyRelocationQueryType ) );
       
  1005         
       
  1006         relocationQueryType = EPbk2CopyManyToStoreQuery;
       
  1007         if ( moveRelocation )
       
  1008             {
       
  1009             relocationQueryType = EPbk2MoveManyToStoreQuery;
       
  1010             }        
       
  1011         }
       
  1012     return relocationQueryType;        
       
  1013     }
       
  1014 
       
  1015 // End of File