phonebookui/Phonebook2/CommonUI/src/CPbk2ContactRelocator.cpp
branchRCL_3
changeset 63 f4a778e096c2
child 64 c1e8ba0c2b16
child 68 9da50d567e3c
equal deleted inserted replaced
62:5b6f26637ad3 63:f4a778e096c2
       
     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     TRAPD( err, DoRelocateContactL() );
       
   352     if ( err == KErrDiskFull )
       
   353         {
       
   354         IssueRequest();
       
   355         }
       
   356     }
       
   357 
       
   358 // --------------------------------------------------------------------------
       
   359 // CPbk2ContactRelocator::IssueRequest
       
   360 // Inform failure asynchronously
       
   361 // --------------------------------------------------------------------------
       
   362 //
       
   363 void CPbk2ContactRelocator::IssueRequest()
       
   364     {
       
   365     TRequestStatus* status = &iStatus;
       
   366     User::RequestComplete( status, KErrNone );
       
   367     SetActive();
       
   368     }
       
   369 
       
   370 // --------------------------------------------------------------------------
       
   371 // CPbk2ContactRelocator::StoreUnavailable
       
   372 // --------------------------------------------------------------------------
       
   373 //
       
   374 void CPbk2ContactRelocator::StoreUnavailable
       
   375         ( MVPbkContactStore& /*aContactStore*/, TInt aReason )
       
   376     {
       
   377     // Problem in opening phone memory store
       
   378     iObserver->ContactRelocationFailed( aReason, iSourceContact );
       
   379     iSourceContact = NULL; // ownership was given away
       
   380     }
       
   381 
       
   382 // --------------------------------------------------------------------------
       
   383 // CPbk2ContactRelocator::HandleStoreEventL
       
   384 // --------------------------------------------------------------------------
       
   385 //
       
   386 void CPbk2ContactRelocator::HandleStoreEventL
       
   387         ( MVPbkContactStore& /*aContactStore*/,
       
   388         TVPbkContactStoreEvent /*aStoreEvent*/ )
       
   389     {
       
   390     // Do nothing
       
   391     }
       
   392 
       
   393 // --------------------------------------------------------------------------
       
   394 // CPbk2ContactRelocator::FieldAddedToContact
       
   395 // --------------------------------------------------------------------------
       
   396 //
       
   397 void CPbk2ContactRelocator::FieldAddedToContact
       
   398         ( MVPbkContactOperationBase& /*aOperation*/ )
       
   399     {
       
   400     // Do nothing
       
   401     }
       
   402 
       
   403 // --------------------------------------------------------------------------
       
   404 // CPbk2ContactRelocator::FieldAddingFailed
       
   405 // --------------------------------------------------------------------------
       
   406 //
       
   407 void CPbk2ContactRelocator::FieldAddingFailed
       
   408         ( MVPbkContactOperationBase& /*aOperation*/, TInt /*aError*/ )
       
   409     {
       
   410     // Do nothing
       
   411     }
       
   412 
       
   413 // --------------------------------------------------------------------------
       
   414 // CPbk2ContactRelocator::ContactsSaved
       
   415 // Contact was succesfully saved to phone memory
       
   416 // --------------------------------------------------------------------------
       
   417 //
       
   418 void CPbk2ContactRelocator::ContactsSaved
       
   419         ( MVPbkContactOperationBase& /*aOperation*/,
       
   420         MVPbkContactLinkArray* aResults )
       
   421     {
       
   422     // There should be only one link in the results array
       
   423     __ASSERT_DEBUG( aResults && aResults->Count() == KOneContact,
       
   424         Panic( EPanicPreCond_ContactsSaved ) );
       
   425 
       
   426     TRAPD( err,
       
   427         {
       
   428         CleanupDeletePushL( aResults );
       
   429 
       
   430         // Next, retrieve the saved contact
       
   431         RetrieveSavedContactL( aResults->At( KFirstElement ) );
       
   432         CleanupStack::PopAndDestroy(); // aResults
       
   433         });
       
   434 
       
   435     if ( err != KErrNone )
       
   436         {
       
   437         iObserver->ContactRelocationFailed( err, iSourceContact );
       
   438         iSourceContact = NULL; // ownership was given away
       
   439         }
       
   440 
       
   441     }
       
   442 
       
   443 // --------------------------------------------------------------------------
       
   444 // CPbk2ContactRelocator::ContactsSavingFailed
       
   445 // --------------------------------------------------------------------------
       
   446 //
       
   447 void CPbk2ContactRelocator::ContactsSavingFailed
       
   448         ( MVPbkContactOperationBase& /*aOperation*/, TInt aError )
       
   449     {
       
   450     // Contact was not succesfully saved to phone memory
       
   451     iObserver->ContactRelocationFailed( aError, iSourceContact );
       
   452     iSourceContact = NULL; // ownership was given away
       
   453 
       
   454     // Move to next request, if any. Safe to ignore error.
       
   455     TRAP_IGNORE( DoRelocateContactL() );
       
   456     }
       
   457 
       
   458 // --------------------------------------------------------------------------
       
   459 // CPbk2ContactRelocator::VPbkSingleContactOperationComplete
       
   460 // Contact was succesfully retrieved from a link.
       
   461 // --------------------------------------------------------------------------
       
   462 //
       
   463 void CPbk2ContactRelocator::VPbkSingleContactOperationComplete
       
   464         ( MVPbkContactOperationBase& aOperation,
       
   465         MVPbkStoreContact* aContact )
       
   466     {
       
   467     if ( &aOperation == iSavedContactsRetriever )
       
   468         {
       
   469         // Destroy the last relocated contact
       
   470         delete iRelocatedContact;
       
   471         iRelocatedContact = NULL;
       
   472         // Assign a new relocated contact
       
   473         iRelocatedContact = aContact;
       
   474         if ( ( iActivePolicy == Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemoryAndLock ) ||
       
   475             ( iActivePolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock ) )
       
   476             {
       
   477             // Lock the contact
       
   478             TRAPD( err, iRelocatedContact->LockL( *this ) );
       
   479             if ( err != KErrNone )
       
   480                 {
       
   481                 iObserver->ContactRelocationFailed( err, iSourceContact );
       
   482                 iSourceContact = NULL; // ownership was given away
       
   483 
       
   484                 // Move to next request, if any. Safe to ignore error.
       
   485                 TRAP_IGNORE( DoRelocateContactL() );
       
   486                 }
       
   487             }
       
   488         else if ( iActivePolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemory )
       
   489             {
       
   490             DeleteSourceContact();
       
   491             }
       
   492         else // EPbk2CopyContactToPhoneMemory
       
   493             {
       
   494             DoHandleContactRelocated();
       
   495             TRAP_IGNORE( DoRelocateContactL() );
       
   496             FinalizeIfReady();
       
   497             }
       
   498         }
       
   499     else if ( &aOperation == iContactRetriever )
       
   500         {
       
   501         // One contact from given link array was retrieved, now it has
       
   502         // to be stored and then relocated
       
   503         iSourceContact = aContact;
       
   504         DoRelocateContactL();
       
   505         }
       
   506     }
       
   507 
       
   508 // --------------------------------------------------------------------------
       
   509 // CPbk2ContactRelocator::VPbkSingleContactOperationFailed
       
   510 // Contact was not succesfully retrieved from a link.
       
   511 // --------------------------------------------------------------------------
       
   512 //
       
   513 void CPbk2ContactRelocator::VPbkSingleContactOperationFailed
       
   514         ( MVPbkContactOperationBase& /*aOperation*/, TInt aError )
       
   515     {
       
   516     if ( aError != KErrDiskFull )
       
   517         {
       
   518         iObserver->ContactRelocationFailed( aError, iSourceContact );
       
   519         iSourceContact = NULL; // ownership was given away
       
   520 
       
   521         // Move to next request, if any
       
   522         TRAP_IGNORE( DoRelocateContactL() );
       
   523         }
       
   524     else
       
   525         {
       
   526         IssueRequest();
       
   527         }
       
   528     }
       
   529 
       
   530 // --------------------------------------------------------------------------
       
   531 // CPbk2ContactRelocator::ContactOperationCompleted
       
   532 // --------------------------------------------------------------------------
       
   533 //
       
   534 void CPbk2ContactRelocator::ContactOperationCompleted
       
   535         ( TContactOpResult aResult )
       
   536     {
       
   537     if ( aResult.iOpCode == MVPbkContactObserver::EContactLock )
       
   538         {
       
   539         if ( iActivePolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock )
       
   540             {
       
   541             // One step to -> delete the original contact
       
   542             DeleteSourceContact();
       
   543             }
       
   544         else
       
   545             {
       
   546             // Relocation is done with current contact
       
   547             DoHandleContactRelocated();
       
   548             // Continue if there are still contacts to relocate
       
   549             TRAP_IGNORE( DoRelocateContactL() );
       
   550             FinalizeIfReady();
       
   551             }
       
   552         }
       
   553     else if ( aResult.iOpCode == MVPbkContactObserver::EContactDelete )
       
   554         {
       
   555         // The original contact was succesfully deleted.
       
   556         // Notify has already been called, so move to next request, if any.
       
   557         // In practise:
       
   558         DoHandleContactRelocated();
       
   559         TRAP_IGNORE( DoRelocateContactL() );
       
   560         FinalizeIfReady();
       
   561         }
       
   562     }
       
   563 
       
   564 // --------------------------------------------------------------------------
       
   565 // CPbk2ContactRelocator::ContactOperationFailed
       
   566 // --------------------------------------------------------------------------
       
   567 //
       
   568 void CPbk2ContactRelocator::ContactOperationFailed
       
   569         ( TContactOp /*aOpCode*/, TInt aErrorCode,
       
   570         TBool /*aErrorNotified*/ )
       
   571     {
       
   572     // Request of the deletion of the original contact
       
   573     // was not succesfully completed
       
   574     // Give ownership of the failed contact to the observer
       
   575     iObserver->ContactRelocationFailed( aErrorCode, iSourceContact );
       
   576     iSourceContact = NULL;
       
   577 
       
   578     // Move to next request, if any
       
   579     TRAP_IGNORE( DoRelocateContactL() );
       
   580     }
       
   581 
       
   582 // --------------------------------------------------------------------------
       
   583 // CPbk2ContactRelocator::ReadRelocationPolicyL
       
   584 // --------------------------------------------------------------------------
       
   585 //
       
   586 Pbk2ContactRelocator::TPbk2ContactRelocationPolicy
       
   587         CPbk2ContactRelocator::ReadRelocationPolicyL()
       
   588     {
       
   589     // Default to copy option
       
   590     Pbk2ContactRelocator::TPbk2ContactRelocationPolicy ret = Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemory;
       
   591     TInt result = 0;
       
   592 
       
   593     // Get real setting from central repository
       
   594     CRepository* repository = CRepository::NewL
       
   595         ( TUid::Uid( KCRUidPhonebookInternalConfig ) );
       
   596     CleanupStack::PushL( repository );
       
   597     TInt err = repository->Get( KPhonebookContactRelocationPolicy, result );
       
   598     if ( err == KErrNone )
       
   599         {
       
   600         ret  = Pbk2ContactRelocator::TPbk2ContactRelocationPolicy( result );
       
   601         }
       
   602 
       
   603     CleanupStack::PopAndDestroy( repository );
       
   604     return ret;
       
   605     }
       
   606 
       
   607 // --------------------------------------------------------------------------
       
   608 // CPbk2ContactRelocator::OpenTargetStoreL
       
   609 // --------------------------------------------------------------------------
       
   610 //
       
   611 void CPbk2ContactRelocator::OpenTargetStoreL()
       
   612     {
       
   613     if ( !iTargetStore )
       
   614         {
       
   615         const TVPbkContactStoreUriPtr phoneMemoryUri =
       
   616             VPbkContactStoreUris::DefaultCntDbUri();
       
   617         CVPbkContactManager& contactManager =
       
   618             iAppServices->ContactManager();
       
   619         contactManager.LoadContactStoreL( phoneMemoryUri );
       
   620 
       
   621         MVPbkContactStoreList& storeList = contactManager.ContactStoresL();
       
   622 
       
   623         iTargetStore = storeList.Find( phoneMemoryUri );
       
   624         User::LeaveIfNull( iTargetStore );
       
   625         iTargetStore->OpenL( *this );
       
   626         }
       
   627     }
       
   628 
       
   629 // --------------------------------------------------------------------------
       
   630 // CPbk2ContactRelocator::DoRelocateContactL
       
   631 // --------------------------------------------------------------------------
       
   632 //
       
   633 void CPbk2ContactRelocator::DoRelocateContactL()
       
   634     {
       
   635     // No previous multirelocate request exists,
       
   636     // cleanup the previous request
       
   637     if ( iSourceContacts && iSourceContacts->Count() < KOneContact )
       
   638         {
       
   639         // All contacts were sent to relocation, its important
       
   640         // to clean the array and set it NULL
       
   641         delete iSourceContacts;
       
   642         iSourceContacts = NULL;
       
   643         }
       
   644 
       
   645     if ( iSourceContact )
       
   646         {
       
   647         // Start the copy operation
       
   648         CopyContactL( *iSourceContact );
       
   649         }
       
   650     else if ( iSourceContacts )
       
   651         {
       
   652         // Since we can not use batch copy operation (it does not give
       
   653         // copied contact links back) we have to retrieve all the contacts
       
   654         // and relocate them one by one
       
   655         if ( iSourceContacts->Count() >= KOneContact )
       
   656             {
       
   657             // Take the first contact link of the array
       
   658             MVPbkContactLink* contactLink =
       
   659                 iSourceContacts->At( KFirstElement ).CloneLC();
       
   660             // Then remove it from the array
       
   661             iSourceContacts->Delete( KFirstElement );
       
   662 
       
   663             // Then retrieve it
       
   664             delete iContactRetriever;
       
   665             iContactRetriever = NULL;
       
   666             iContactRetriever =
       
   667                 iAppServices->ContactManager().
       
   668                     RetrieveContactL( *contactLink, *this );
       
   669             CleanupStack::PopAndDestroy(); // contactLink
       
   670             }
       
   671         }
       
   672     }
       
   673 
       
   674 // --------------------------------------------------------------------------
       
   675 // CPbk2ContactRelocator::InitCopyPolicyL
       
   676 // --------------------------------------------------------------------------
       
   677 //
       
   678 inline void CPbk2ContactRelocator::InitCopyPolicyL()
       
   679     {
       
   680     if (!iCopyPolicy)
       
   681         {
       
   682         // There is no copy policy manager if we are in this method
       
   683         // so creating a new one is always ok
       
   684         delete iCopyPolicyManager;
       
   685         iCopyPolicyManager = NULL;
       
   686         iCopyPolicyManager = CVPbkContactCopyPolicyManager::NewL();
       
   687         iCopyPolicy = iCopyPolicyManager->GetPolicyL
       
   688             ( iAppServices->ContactManager(),
       
   689             VPbkContactStoreUris::DefaultCntDbUri());
       
   690         }
       
   691     }
       
   692 
       
   693 // --------------------------------------------------------------------------
       
   694 // CPbk2ContactRelocator::DoHandleContactRelocated
       
   695 // --------------------------------------------------------------------------
       
   696 //
       
   697 void CPbk2ContactRelocator::DoHandleContactRelocated()
       
   698     {
       
   699     if ( iRelocatedContact )
       
   700         {
       
   701         MVPbkStoreContact* relocatedContact = iRelocatedContact;
       
   702         iRelocatedContact = NULL;
       
   703         // Give ownership of the relocated contact to client.
       
   704         TRAPD( res, iObserver->ContactRelocatedL( relocatedContact ) );
       
   705         if ( res != KErrNone )
       
   706             {
       
   707             MVPbkStoreContact* sourceContact = iSourceContact;
       
   708             iSourceContact = NULL;
       
   709             // Give source contact as documented in observer. Client
       
   710             // takes the ownership
       
   711             iObserver->ContactRelocationFailed( res, sourceContact );
       
   712             }
       
   713 
       
   714         delete iSourceContact;
       
   715         iSourceContact = NULL;
       
   716         }
       
   717     }
       
   718 
       
   719 // --------------------------------------------------------------------------
       
   720 // CPbk2ContactRelocator::DeleteSourceContact
       
   721 // --------------------------------------------------------------------------
       
   722 //
       
   723 void CPbk2ContactRelocator::DeleteSourceContact()
       
   724     {
       
   725     // Source contact is deleted only if policy is MOVE
       
   726     __ASSERT_DEBUG( iActivePolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemory ||
       
   727         iActivePolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock,
       
   728         Panic( EPanicPreCond_DeleteSourceContact ) );
       
   729 
       
   730     // Delete original contact
       
   731     if ( iSourceContact )
       
   732         {
       
   733         TRAPD( err, iSourceContact->DeleteL( *this ) );
       
   734         if ( err != KErrNone )
       
   735             {
       
   736             MVPbkStoreContact* sourceContact = iSourceContact;
       
   737             iSourceContact = NULL;
       
   738             // Give source contact as documented in observer. Client
       
   739             // takes the ownership
       
   740             iObserver->ContactRelocationFailed( err, sourceContact );
       
   741             if ( !iSourceContacts )
       
   742                 {
       
   743                 // If no more contacts to relocate then complete the relocation
       
   744                 iObserver->RelocationProcessComplete();
       
   745                 }
       
   746             }
       
   747         }
       
   748     }
       
   749 
       
   750 // --------------------------------------------------------------------------
       
   751 // CPbk2ContactRelocator::AskConfirmationL
       
   752 // --------------------------------------------------------------------------
       
   753 //
       
   754 TBool CPbk2ContactRelocator::AskConfirmationL(
       
   755         MVPbkStoreContact* aContact,
       
   756         CVPbkContactLinkArray* aContacts,
       
   757         TPbk2RelocationQueryType aRelocationQueryType )
       
   758     {
       
   759     TBool ret = ETrue;
       
   760 
       
   761     HBufC* prompt = NULL;
       
   762     HBufC* nameBuffer = NULL;
       
   763     const TDesC* storeName = 
       
   764         StoreName( aContact,
       
   765             iAppServices->StoreProperties() );
       
   766 
       
   767     if ( aContact )
       
   768         {
       
   769         nameBuffer = 
       
   770                 iAppServices->NameFormatter().
       
   771                     GetContactTitleL( aContact->Fields(), KDefaultTitleFormat );
       
   772 
       
   773         CleanupStack::PushL( nameBuffer );    
       
   774         }   
       
   775                     
       
   776     switch( aRelocationQueryType )
       
   777         {
       
   778         case EPbk2NoRelocationQuery:
       
   779         //don't show the following queries anymore
       
   780         case EPbk2CopyOneToStoreQuery:
       
   781         case EPbk2MoveOneToStoreQuery:
       
   782         case EPbk2CopyOneToPhoneQuery:
       
   783         case EPbk2MoveOneToPhoneQuery:
       
   784         case EPbk2CopyManyToStoreQuery:
       
   785         case EPbk2MoveManyToStoreQuery:
       
   786             {
       
   787             // Do nothing
       
   788             }
       
   789             break;
       
   790         default:
       
   791             {
       
   792             __ASSERT_DEBUG( EFalse,
       
   793                 Panic( EPanicLogic_AskConfirmationL ) );
       
   794             break;
       
   795             }            
       
   796         }
       
   797     
       
   798     if ( prompt )
       
   799         {
       
   800         CleanupStack::PushL( prompt );
       
   801         delete iQueryDialog;
       
   802         iQueryDialog = NULL;
       
   803         iQueryDialog = CAknQueryDialog::NewL();
       
   804         iQueryDialog->SetPromptL( *prompt );
       
   805 
       
   806         CleanupStack::PopAndDestroy( prompt );
       
   807 
       
   808         ret = iQueryDialog->ExecuteLD( R_PBK2_COMMONUI_CONFIRMATION_QUERY );
       
   809         iQueryDialog = NULL;
       
   810         }
       
   811 
       
   812     if ( aContact )
       
   813         {
       
   814         CleanupStack::PopAndDestroy(); // nameBuffer    
       
   815         }
       
   816     return ret;    
       
   817     }
       
   818 
       
   819 // --------------------------------------------------------------------------
       
   820 // CPbk2ContactRelocator::RetrieveSavedContactL
       
   821 // --------------------------------------------------------------------------
       
   822 //
       
   823 void CPbk2ContactRelocator::RetrieveSavedContactL
       
   824         ( const MVPbkContactLink& aLink )
       
   825     {
       
   826     delete iSavedContactsRetriever;
       
   827     iSavedContactsRetriever = NULL;
       
   828     iSavedContactsRetriever =
       
   829         iAppServices->ContactManager().
       
   830             RetrieveContactL( aLink, *this );
       
   831     }
       
   832 
       
   833 // --------------------------------------------------------------------------
       
   834 // CPbk2ContactRelocator::VerifyPolicy
       
   835 // --------------------------------------------------------------------------
       
   836 //
       
   837 inline void CPbk2ContactRelocator::VerifyPolicy(
       
   838         MVPbkStoreContact* aContact, TUint32 aFlags )
       
   839     {
       
   840     // Reset policy
       
   841     iActivePolicy = iRelocationPolicy;
       
   842 
       
   843     // Read-only contacts can not be moved so
       
   844     // adjust active policy if necessary. New contacts are also not moved.
       
   845     if ( iRelocationPolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemory ||
       
   846          iRelocationPolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock )
       
   847         {
       
   848         if ( aContact )
       
   849             {
       
   850             if (aContact->ParentStore().StoreProperties().ReadOnly() ||
       
   851                 aFlags & EPbk2RelocatorNewContact )
       
   852                 {
       
   853                 iActivePolicy = Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemory;
       
   854                 if ( iRelocationPolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock )
       
   855                     {
       
   856                     iActivePolicy = Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemoryAndLock;
       
   857                     }
       
   858                 }            
       
   859             }
       
   860         }
       
   861     }
       
   862 
       
   863 // --------------------------------------------------------------------------
       
   864 // CPbk2ContactRelocator::PrepareToRelocateContactL
       
   865 // --------------------------------------------------------------------------
       
   866 //
       
   867 TBool CPbk2ContactRelocator::PrepareToRelocateContactL(
       
   868         MVPbkStoreContact* aContact,
       
   869         CVPbkContactLinkArray* aContacts,
       
   870         MPbk2ContactRelocatorObserver& aObserver,
       
   871         Pbk2ContactRelocator::TPbk2ContactRelocationQueryPolicy aQueryPolicy,
       
   872         TUint32 aFlags )
       
   873     {
       
   874     __ASSERT_DEBUG( !iSourceContact && !iSourceContacts,
       
   875         Panic( EPanicPreCond_PrepareToRelocateContactL ) );
       
   876 
       
   877     iObserver = &aObserver;
       
   878 
       
   879     TBool result = EFalse;
       
   880 
       
   881     // If this is deleted when confirmation note returns do not access
       
   882     // any member data.
       
   883     TBool thisDestroyed = EFalse;
       
   884     iDestroyedPtr = &thisDestroyed;
       
   885     TPbk2DestructionIndicator indicator
       
   886         ( &thisDestroyed, iDestroyedPtr );
       
   887 
       
   888     
       
   889     if ( aContact || aContacts )
       
   890         {
       
   891         VerifyPolicy( aContact, aFlags );
       
   892         TPbk2RelocationQueryType relocationQueryType =
       
   893             SelectRelocationQueryType( aContact, aContacts, aQueryPolicy );        
       
   894             
       
   895         // Take ownership
       
   896         iSourceContact = aContact;
       
   897         iSourceContacts = aContacts;
       
   898         
       
   899         result = AskConfirmationL( aContact, aContacts, relocationQueryType );
       
   900         }
       
   901     else
       
   902         {
       
   903         iErrorCode  = KErrArgument;
       
   904         }
       
   905             
       
   906     if ( !thisDestroyed )
       
   907         {
       
   908         if ( !result )
       
   909             {
       
   910             iErrorCode = KErrCancel;
       
   911             }
       
   912 
       
   913         if ( iErrorCode != KErrNone )
       
   914             {
       
   915             IssueRequest();
       
   916             }
       
   917         else
       
   918             {
       
   919             if ( !iTargetStoreOpen )
       
   920                 {
       
   921                 OpenTargetStoreL();
       
   922                 }
       
   923             else
       
   924                 {
       
   925                 DoRelocateContactL();
       
   926                 }
       
   927             }
       
   928         }
       
   929 
       
   930     return result;
       
   931     }
       
   932 
       
   933 // --------------------------------------------------------------------------
       
   934 // CPbk2ContactRelocator::CopyContactL
       
   935 // --------------------------------------------------------------------------
       
   936 //
       
   937 void CPbk2ContactRelocator::CopyContactL( MVPbkStoreContact& aContact )
       
   938     {
       
   939     // Init copy policy
       
   940     InitCopyPolicyL();
       
   941 
       
   942     delete iContactCopier;
       
   943     iContactCopier = NULL;
       
   944     iContactCopier = iCopyPolicy->CopyContactL
       
   945         ( aContact, *iTargetStore, *this );
       
   946     }
       
   947 
       
   948 // --------------------------------------------------------------------------
       
   949 // CPbk2ContactRelocator::FinalizeIfReady
       
   950 // --------------------------------------------------------------------------
       
   951 //
       
   952 void CPbk2ContactRelocator::FinalizeIfReady()
       
   953     {
       
   954     // If there are no more contacts waiting to be relocated in this
       
   955     // request, signal process complete
       
   956     if ( !iSourceContacts )
       
   957         {
       
   958         iObserver->RelocationProcessComplete();
       
   959         }
       
   960     }
       
   961 
       
   962 // --------------------------------------------------------------------------
       
   963 // CPbk2ContactRelocator::SelectRelocationQueryType
       
   964 // --------------------------------------------------------------------------
       
   965 //
       
   966 CPbk2ContactRelocator::TPbk2RelocationQueryType 
       
   967     CPbk2ContactRelocator::SelectRelocationQueryType(
       
   968         MVPbkStoreContact* aContact,
       
   969         CVPbkContactLinkArray* aContacts,
       
   970         Pbk2ContactRelocator::TPbk2ContactRelocationQueryPolicy
       
   971         aQueryPolicy )
       
   972     {    
       
   973     TPbk2RelocationQueryType relocationQueryType(EPbk2NoRelocationQuery);
       
   974     TBool moveRelocation(EFalse);
       
   975     
       
   976     if ( Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemory == iActivePolicy || 
       
   977          Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock == iActivePolicy )
       
   978         {
       
   979         moveRelocation = ETrue;
       
   980         }
       
   981 
       
   982     switch (aQueryPolicy)
       
   983         {
       
   984         case Pbk2ContactRelocator::EPbk2DisplayNoQueries:
       
   985             {
       
   986             relocationQueryType = EPbk2NoRelocationQuery;
       
   987             }
       
   988             break;
       
   989         
       
   990         case Pbk2ContactRelocator::EPbk2DisplayBasicQuery:
       
   991             {
       
   992             relocationQueryType = EPbk2CopyOneToStoreQuery;
       
   993             if ( moveRelocation )
       
   994                 {
       
   995                 relocationQueryType = EPbk2MoveOneToStoreQuery;
       
   996                 }
       
   997             }
       
   998             break;
       
   999     
       
  1000         case Pbk2ContactRelocator::EPbk2DisplayStoreDoesNotSupportQuery:
       
  1001             {
       
  1002             relocationQueryType = EPbk2CopyOneToPhoneQuery;
       
  1003             if ( moveRelocation )
       
  1004                 {
       
  1005                 relocationQueryType = EPbk2MoveOneToPhoneQuery;
       
  1006                 }
       
  1007             }
       
  1008             break;
       
  1009 
       
  1010         default:
       
  1011             {
       
  1012             __ASSERT_DEBUG( EFalse,
       
  1013                 Panic( EPanicPreCond_VerifyRelocationQueryType ) );
       
  1014             break;
       
  1015             }
       
  1016         }
       
  1017         
       
  1018     if ( !aContact && aContacts && 
       
  1019          aQueryPolicy != Pbk2ContactRelocator::EPbk2DisplayNoQueries )
       
  1020         {
       
  1021         // Relocation is going to be done for many contacts
       
  1022         // and query policy is defined.
       
  1023         __ASSERT_DEBUG( aContacts->Count() >= KLinkArrayRelocationMinCount, 
       
  1024                         Panic( EPanicPreCond_VerifyRelocationQueryType ) );
       
  1025         
       
  1026         relocationQueryType = EPbk2CopyManyToStoreQuery;
       
  1027         if ( moveRelocation )
       
  1028             {
       
  1029             relocationQueryType = EPbk2MoveManyToStoreQuery;
       
  1030             }        
       
  1031         }
       
  1032     return relocationQueryType;        
       
  1033     }
       
  1034 
       
  1035 // End of File