phonebookengines/VirtualPhonebook/VPbkCntModel/src/CDeleteContactsOperation.cpp
branchRCL_3
changeset 63 f4a778e096c2
child 64 c1e8ba0c2b16
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:  An operation object to delete contacts from contacts database
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "CDeleteContactsOperation.h"
       
    20 
       
    21 // VPbkCntModel
       
    22 #include "CContactLink.h"
       
    23 #include "CContactStore.h"
       
    24 #include "CVPbkDiskSpaceCheck.h"
       
    25 #include "CContact.h"
       
    26 
       
    27 // Virtual Phonebook engine
       
    28 #include <MVPbkBatchOperationObserver.h>
       
    29 #include <MVPbkContactStoreInfo.h>
       
    30 
       
    31 // Contact Model
       
    32 #include <cntdef.h>
       
    33 #include <cntdb.h>
       
    34 #include <cntitem.h>
       
    35 
       
    36 
       
    37 namespace VPbkCntModel {
       
    38 
       
    39 // Definition for delete array size
       
    40 const TInt KDeleteArraySize = 3;
       
    41 
       
    42 // Definition for FreeDiskSpaceRequest towards DOSSERVER
       
    43 const TInt KFreeSpaceRequiredInKB = 140 * 1024; // 140 kB
       
    44 
       
    45 // -----------------------------------------------------------------------------
       
    46 // CDeleteContactsOperation::CDeleteContactsOperation
       
    47 // -----------------------------------------------------------------------------
       
    48 //
       
    49 CDeleteContactsOperation::CDeleteContactsOperation(
       
    50         CContactStore& aContactStore,
       
    51         MVPbkBatchOperationObserver& aObserver,
       
    52         RSharedDataClient* aSharedDataClient,
       
    53         VPbkEngUtils::CVPbkDiskSpaceCheck& aDiskSpaceChecker ) :
       
    54     CActive( CActive::EPriorityIdle ),
       
    55     iContactStore( aContactStore ),
       
    56     iObserver( aObserver ),
       
    57     iState( EDelete ),
       
    58     iSharedDataClient( aSharedDataClient ),
       
    59     iDiskSpaceChecker( aDiskSpaceChecker )
       
    60     {
       
    61     CActiveScheduler::Add(this);
       
    62     }
       
    63 
       
    64 // -----------------------------------------------------------------------------
       
    65 // CDeleteContactsOperation::~CDeleteContactsOperation
       
    66 // -----------------------------------------------------------------------------
       
    67 //
       
    68 CDeleteContactsOperation::~CDeleteContactsOperation()
       
    69     {
       
    70     Cancel();
       
    71     delete iRemainingContactIds;
       
    72     delete iCurrentContactIds;
       
    73     }
       
    74 
       
    75 // -----------------------------------------------------------------------------
       
    76 // CDeleteContactsOperation::NewL
       
    77 // -----------------------------------------------------------------------------
       
    78 //
       
    79 CDeleteContactsOperation* CDeleteContactsOperation::NewL(
       
    80         CContactStore& aContactStore,
       
    81         const MVPbkContactLinkArray& aLinks,
       
    82         MVPbkBatchOperationObserver& aObserver,
       
    83         RSharedDataClient* aSharedDataClient,
       
    84         VPbkEngUtils::CVPbkDiskSpaceCheck& aDiskSpaceChecker )
       
    85     {
       
    86     CDeleteContactsOperation* self =
       
    87         new( ELeave ) CDeleteContactsOperation( aContactStore, aObserver,
       
    88                                                 aSharedDataClient, aDiskSpaceChecker );
       
    89     CleanupStack::PushL( self );
       
    90     self->ConstructL( aLinks );
       
    91     CleanupStack::Pop( self );
       
    92     return self;
       
    93     }
       
    94 
       
    95 // -----------------------------------------------------------------------------
       
    96 // CDeleteContactsOperation::ConstructL
       
    97 // -----------------------------------------------------------------------------
       
    98 //
       
    99 inline void CDeleteContactsOperation::ConstructL
       
   100         (const MVPbkContactLinkArray& aLinks)
       
   101     {
       
   102     iRemainingContactIds = CContactIdArray::NewL();
       
   103     iCurrentContactIds = CContactIdArray::NewL();
       
   104     
       
   105     iGroupCount = iContactStore.StoreInfo().NumberOfGroupsL();
       
   106     
       
   107     const TInt count = aLinks.Count();
       
   108     for ( TInt i=0 ; i < count; ++i )
       
   109         {
       
   110         const CContactLink& link =
       
   111             static_cast<const CContactLink&>( aLinks.At( i ) );
       
   112         iRemainingContactIds->AddL( link.ContactId() );
       
   113         }
       
   114     PrepareNextDelete();
       
   115     }
       
   116 
       
   117 // -----------------------------------------------------------------------------
       
   118 // CDeleteContactsOperation::DoCancel
       
   119 // -----------------------------------------------------------------------------
       
   120 //
       
   121 void CDeleteContactsOperation::DoCancel()
       
   122     {
       
   123     // Do nothing
       
   124     }
       
   125 
       
   126 // -----------------------------------------------------------------------------
       
   127 // CDeleteContactsOperation::RunL
       
   128 // -----------------------------------------------------------------------------
       
   129 //
       
   130 void CDeleteContactsOperation::RunL()
       
   131     {
       
   132     switch ( iState )
       
   133         {
       
   134         case EDelete:
       
   135             {
       
   136             RunDeleteL();
       
   137             IssueRequest();
       
   138             break;
       
   139             }
       
   140         case EComplete:
       
   141             {
       
   142             iObserver.OperationComplete( *this );
       
   143             break;
       
   144             }
       
   145         }
       
   146     }
       
   147 
       
   148 // -----------------------------------------------------------------------------
       
   149 // CDeleteContactsOperation::RunError
       
   150 // -----------------------------------------------------------------------------
       
   151 //
       
   152 TInt CDeleteContactsOperation::RunError(TInt aError)
       
   153     {    
       
   154     if ( iFreeDiskSpaceRequired )
       
   155         {
       
   156         // Notify shared data that we do not need free space anymore
       
   157         DoCancelFreeDiskSpaceRequest();
       
   158         iFreeDiskSpaceRequired = EFalse;
       
   159         }
       
   160 
       
   161     // if iCurrentContactIndex is valid, than it's delete error
       
   162     // otherwise, RunDeleteL leaved outside the delete loop
       
   163     TBool deleteError = iCurrentContactIndex >= 0 &&
       
   164     					iCurrentContactIndex < iCurrentContactIds->Count();
       
   165 
       
   166     // if error outside the delete loop, than skip all current contacts,
       
   167     // otherwise, remove failed contact and try again
       
   168     TInt stepSize = iCurrentContactIds->Count();
       
   169     if ( deleteError )
       
   170     	{
       
   171     	stepSize = 1;
       
   172     	}
       
   173     
       
   174     if ( iObserver.StepFailed( *this, stepSize, aError ) )
       
   175         {
       
   176         if ( iCurrentContactIds->Count() > 1 && deleteError )
       
   177         	{
       
   178         	//remove failed contact and try without it again
       
   179         	iCurrentContactIds->Remove( iCurrentContactIndex );
       
   180         	iState = EDelete;
       
   181         	}
       
   182         else
       
   183         	{
       
   184         	//skip iCurrentContactIds, try remaining
       
   185         	PrepareNextDelete();
       
   186         	}
       
   187         IssueRequest();
       
   188         }
       
   189  
       
   190     return KErrNone;
       
   191     }
       
   192 
       
   193 // -----------------------------------------------------------------------------
       
   194 // CDeleteContactsOperation::StartL
       
   195 // -----------------------------------------------------------------------------
       
   196 //
       
   197 void CDeleteContactsOperation::StartL()
       
   198     {   
       
   199     IssueRequest();
       
   200     }
       
   201 
       
   202 // -----------------------------------------------------------------------------
       
   203 // CDeleteContactsOperation::Cancel
       
   204 // -----------------------------------------------------------------------------
       
   205 //
       
   206 void CDeleteContactsOperation::Cancel()
       
   207     {
       
   208     CActive::Cancel();
       
   209     }
       
   210 
       
   211 // -----------------------------------------------------------------------------
       
   212 // CDeleteContactsOperation::IssueRequest
       
   213 // -----------------------------------------------------------------------------
       
   214 //
       
   215 void CDeleteContactsOperation::IssueRequest()
       
   216     {
       
   217     TRequestStatus* status = &iStatus;
       
   218     User::RequestComplete( status, KErrNone );
       
   219     SetActive();
       
   220     }
       
   221 
       
   222 // -----------------------------------------------------------------------------
       
   223 // CDeleteContactsOperation::UpdateTimeStampOfAllContactsInGroupL
       
   224 // -----------------------------------------------------------------------------
       
   225 //
       
   226 void CDeleteContactsOperation::UpdateTimeStampOfAllContactsInGroupL()
       
   227     {
       
   228     CContactItem* groupItem = iContactStore.NativeDatabase().
       
   229                                 ReadContactLC( ( *iCurrentContactIds )[iCurrentContactIndex] );
       
   230     
       
   231     CContact* group = CContact::NewL( iContactStore, groupItem );
       
   232     CleanupStack::Pop(groupItem);
       
   233     CleanupStack::PushL( group );
       
   234    
       
   235     group->UpdateTimeStampOfAllContactsInGroupL();
       
   236     
       
   237     CleanupStack::PopAndDestroy( group ); 
       
   238     }
       
   239 
       
   240 // -----------------------------------------------------------------------------
       
   241 // CDeleteContactsOperation::CurrentItemIsGroupL
       
   242 // -----------------------------------------------------------------------------
       
   243 //
       
   244 TBool CDeleteContactsOperation::CurrentItemIsGroupL()
       
   245     {
       
   246     TBool isGroup = EFalse;
       
   247     
       
   248     // If groups exists, we need to read a minimal contact to get it's type
       
   249     if (iGroupCount > 0)
       
   250         {
       
   251         CContactItem* item = iContactStore.NativeDatabase().
       
   252             ReadMinimalContactLC( ( *iCurrentContactIds )[iCurrentContactIndex] );
       
   253                    
       
   254         if (item->Type() == KUidContactGroup)
       
   255             {
       
   256             isGroup = ETrue;
       
   257             }
       
   258         
       
   259         CleanupStack::PopAndDestroy(item); 
       
   260         }
       
   261     
       
   262     return isGroup;
       
   263     }
       
   264 
       
   265 // -----------------------------------------------------------------------------
       
   266 // CDeleteContactsOperation::RunDeleteL
       
   267 // -----------------------------------------------------------------------------
       
   268 //
       
   269 inline void CDeleteContactsOperation::RunDeleteL()
       
   270     {
       
   271     StartTransactionLC();
       
   272 
       
   273     TInt stepSize = iCurrentContactIds->Count();
       
   274     for ( iCurrentContactIndex = 0;
       
   275     	  iCurrentContactIndex < stepSize;
       
   276       	  ++iCurrentContactIndex )
       
   277         {
       
   278         DoRequestFreeDiskSpaceLC();        
       
   279         
       
   280         // If contact item is a group, we need to update the timestamps 
       
   281         // of the contacts in the group before deleting the group.
       
   282         // This is needed for sync services.
       
   283         if ( CurrentItemIsGroupL() )
       
   284             {
       
   285             UpdateTimeStampOfAllContactsInGroupL();
       
   286             }
       
   287       
       
   288         // Cannot use DeleteContactsL here, since it does not
       
   289         // send contact removed events
       
   290         iContactStore.NativeDatabase().
       
   291             DeleteContactL( ( *iCurrentContactIds )[iCurrentContactIndex] );
       
   292         
       
   293         CleanupStack::PopAndDestroy();  // RequestFreeDiskSpaceLC            
       
   294 
       
   295         RunCompressL(EFalse);
       
   296         }
       
   297     
       
   298     // Commit database transaction
       
   299     CommitTransactionLP();
       
   300     
       
   301     iObserver.StepComplete( *this, stepSize );
       
   302     RunCompressL(ETrue);
       
   303     PrepareNextDelete();
       
   304     }
       
   305 
       
   306 void CDeleteContactsOperation::PrepareNextDelete()
       
   307 	{
       
   308     iCurrentContactIds->Reset();
       
   309     for ( TInt i = Min(iRemainingContactIds->Count(), KDeleteArraySize) - 1;
       
   310     	  i >= 0;
       
   311     	  --i )
       
   312         {
       
   313         iCurrentContactIds->AddL( ( *iRemainingContactIds )[i] );
       
   314         iRemainingContactIds->Remove( i );
       
   315         }
       
   316     
       
   317     iState = EDelete;
       
   318     iCurrentContactIndex = -1; //make index invalid, it's checked in RunError
       
   319     						   //to detect StartTransactionLC leave
       
   320     if ( iCurrentContactIds->Count() == 0 )
       
   321         {
       
   322         // No more contacts to delete
       
   323         iState = EComplete;
       
   324         }
       
   325 	}
       
   326 
       
   327 // -----------------------------------------------------------------------------
       
   328 // CDeleteContactsOperation::RunCompressL
       
   329 // -----------------------------------------------------------------------------
       
   330 //
       
   331 inline void CDeleteContactsOperation::RunCompressL(TBool aForce)
       
   332     {
       
   333     if ( aForce || iContactStore.NativeDatabase().CompressRequired() )
       
   334         {
       
   335         DoRequestFreeDiskSpaceLC();        
       
   336         // Compress database
       
   337         iContactStore.NativeDatabase().CompactL();
       
   338         CleanupStack::PopAndDestroy();  // RequestFreeDiskSpaceLC        
       
   339         }    
       
   340     }
       
   341 
       
   342 // -----------------------------------------------------------------------------
       
   343 // CDeleteContactsOperation::StartTransactionLC
       
   344 // -----------------------------------------------------------------------------
       
   345 //
       
   346 inline void CDeleteContactsOperation::StartTransactionLC()
       
   347     {
       
   348     // If database transaction starting leaves --> 
       
   349     // Reserved disk space if freed in CDeleteContactsOperation::RunError
       
   350     DoRequestFreeDiskSpace();
       
   351     iFreeDiskSpaceRequired = ETrue;
       
   352     
       
   353     iContactStore.NativeDatabase().DatabaseBeginLC( EFalse );
       
   354     
       
   355     DoCancelFreeDiskSpaceRequest();
       
   356     iFreeDiskSpaceRequired = EFalse;
       
   357     }
       
   358     
       
   359 // -----------------------------------------------------------------------------
       
   360 // CDeleteContactsOperation::CommitTransactionLC
       
   361 // -----------------------------------------------------------------------------
       
   362 //
       
   363 inline void CDeleteContactsOperation::CommitTransactionLP()
       
   364     {
       
   365     // If database commit leaves --> Reserved disk space if freeed in
       
   366     // CDeleteContactsOperation::RunError
       
   367     DoRequestFreeDiskSpace();
       
   368     iFreeDiskSpaceRequired = ETrue;
       
   369     
       
   370     iContactStore.NativeDatabase().DatabaseCommitLP( EFalse );
       
   371     
       
   372     DoCancelFreeDiskSpaceRequest();
       
   373     iFreeDiskSpaceRequired = EFalse;  
       
   374     }
       
   375 
       
   376 // -----------------------------------------------------------------------------
       
   377 // CDeleteContactsOperation::DoRequestFreeDiskSpace
       
   378 // -----------------------------------------------------------------------------
       
   379 //
       
   380 void CDeleteContactsOperation::DoRequestFreeDiskSpace()
       
   381     {
       
   382     if ( iSharedDataClient )
       
   383         {
       
   384         iSharedDataClient->RequestFreeDiskSpace(KFreeSpaceRequiredInKB);
       
   385         }
       
   386     }
       
   387 
       
   388 // -----------------------------------------------------------------------------
       
   389 // CDeleteContactsOperation::DoRequestFreeDiskSpaceLC
       
   390 // -----------------------------------------------------------------------------
       
   391 //
       
   392 void CDeleteContactsOperation::DoRequestFreeDiskSpaceLC()
       
   393     {
       
   394     if ( iSharedDataClient )
       
   395         {
       
   396         iSharedDataClient->RequestFreeDiskSpaceLC(KFreeSpaceRequiredInKB);        
       
   397         }
       
   398     else
       
   399         {
       
   400         // place token in cleanup stack
       
   401         TAny* const nop = NULL;
       
   402         CleanupStack::PushL(nop);
       
   403         }
       
   404     }
       
   405 
       
   406 // -----------------------------------------------------------------------------
       
   407 // CDeleteContactsOperation::CancelFreeDiskSpaceRequest
       
   408 // -----------------------------------------------------------------------------
       
   409 //
       
   410 void CDeleteContactsOperation::DoCancelFreeDiskSpaceRequest()
       
   411     {
       
   412     if ( iSharedDataClient )
       
   413         {
       
   414         iSharedDataClient->CancelFreeDiskSpaceRequest();
       
   415         }
       
   416     }
       
   417 
       
   418 } // namespace VPbkCntModel
       
   419 
       
   420 // End of File