phonebookengines/VirtualPhonebook/VPbkVCardEng/src/CVPbkGroupCardHandler.cpp
branchRCL_3
changeset 63 f4a778e096c2
child 64 c1e8ba0c2b16
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/VirtualPhonebook/VPbkVCardEng/src/CVPbkGroupCardHandler.cpp	Wed Sep 01 12:29:52 2010 +0100
@@ -0,0 +1,523 @@
+/*
+* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Handler to manage groupcard property during import and export
+ *
+*/
+
+
+#include "CVPbkGroupCardHandler.h"
+
+#include <MVPbkContactStore.h>
+#include <MVPbkContactGroup.h>
+#include <MVPbkContactStore2.h>
+#include <MVPbkContactStoreProperties.h>
+#include <MVPbkContactStoreProperties2.h>
+#include <MVPbkContactOperationBase.h>
+#include <CVPbkContactManager.h>
+#include <CVPbkContactIdConverter.h>
+#include <MVPbkStoreContact2.h>
+
+_LIT8(KGroup,"X-CATEGORIES");
+_LIT16(KSemiColon,";");    
+_LIT16(KVersitTokencrlf,"\r\n");
+
+// ----------------------------------------------------------------------------
+// CVPbkGroupCardHandler::CVPbkGroupCardHandler
+// ----------------------------------------------------------------------------
+CVPbkGroupCardHandler::CVPbkGroupCardHandler(CVPbkVCardData& aData):iData(aData)
+            {
+            }
+
+// ----------------------------------------------------------------------------
+// CVPbkGroupCardHandler::NewL
+// ----------------------------------------------------------------------------
+CVPbkGroupCardHandler* CVPbkGroupCardHandler::NewL(CVPbkVCardData& aData)
+    {
+    CVPbkGroupCardHandler* self = new (ELeave) CVPbkGroupCardHandler(aData);
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ----------------------------------------------------------------------------
+// CVPbkGroupCardHandler::ConstructL
+// ----------------------------------------------------------------------------
+void CVPbkGroupCardHandler::ConstructL()
+    {
+    iWait = new( ELeave )CActiveSchedulerWait();
+    iContactsGroupsMap = NULL;
+    iTargetStore = NULL;
+    iStore = NULL;
+    }
+
+// ----------------------------------------------------------------------------
+// CVPbkGroupCardHandler::~CVPbkGroupCardHandler
+// ----------------------------------------------------------------------------
+CVPbkGroupCardHandler::~CVPbkGroupCardHandler()
+    {
+    // The code that started iWait must know if this instance has been deleted.
+    if ( iDestroyed )
+        {
+        *iDestroyed = ETrue;
+        }
+    
+    if ( iSelfPtr )
+        {
+        *iSelfPtr = NULL;
+        }
+    
+    delete iRetrieveOp;
+    
+    if ( iWait )
+        {
+        if( iWait->IsStarted() )
+            iWait->AsyncStop();
+        delete iWait;
+        iWait = NULL;
+        }
+
+    if(iStore)
+        {
+        delete iStore;
+        iStore = NULL;
+        }
+
+    if (iContactsGroupsMap)
+        {   
+        iContactsGroupsMap->ResetAndDestroy();
+        iContactsGroupsMap->Close();
+        delete iContactsGroupsMap;
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CVPbkGroupCardHandler::CreateXSelfPropertyL
+// ----------------------------------------------------------------------------
+CParserProperty* CVPbkGroupCardHandler::CreateXGroupPropertyL(const MVPbkStoreContact* aStore)
+    {
+    TPtrC8 text( KGroup);
+    CParserProperty* property = NULL;
+    CVPbkVCardParserParamArray* params = NULL;
+    
+    if ( aStore == NULL)
+        return property;
+
+    MVPbkContactLinkArray* groupIdArray = aStore->GroupsJoinedLC(); //Get Groupid list of contact.
+
+    if ( groupIdArray == NULL)
+        return property;
+
+    TInt totalGroupsInContact = 0;
+    totalGroupsInContact = groupIdArray->Count();
+
+    if (totalGroupsInContact == 0)
+        {
+        //if contact has no groups,Append X-CATEGORIES field with NULL field Value. 
+        CParserPropertyValueHBufC* tempValue = CParserPropertyValueHBufC::NewL( KNullDesC() );
+        CParserPropertyValue* value = static_cast<CParserPropertyValue*>(tempValue);
+        property = CParserProperty::NewL( *value,text, params);
+        CleanupStack::PopAndDestroy();  //For GoupIdArray
+        return property;
+        }
+
+    CDesCArrayFlat* desArray=new (ELeave)CDesCArrayFlat(totalGroupsInContact);
+    CleanupStack::PushL(desArray);
+
+    //Append all the Group Names of contact to X-CATEGORIES field value.
+    TBool thisDestroyed = EFalse;
+    for ( TInt m = 0 ; m < totalGroupsInContact && !thisDestroyed ; m++ )
+        {                  
+        const  MVPbkContactLink& groupLink = (*groupIdArray)[m];
+        thisDestroyed = RetrieveContactL( groupLink, *this );
+        if (!thisDestroyed && iTargetStore)
+            {
+            MVPbkContactGroup* contactGrp = iTargetStore->Group();
+            if(contactGrp)
+                {
+                CParserPropertyValueHBufC* tempValue = CParserPropertyValueHBufC::NewL( contactGrp->GroupLabel() );
+                CleanupStack::PushL(tempValue);
+                desArray->AppendL(tempValue->Value());
+                CleanupStack::PopAndDestroy(tempValue);
+                }
+            delete iTargetStore;
+            iTargetStore = NULL;
+            }
+        }
+
+    CParserPropertyValue* value = new (ELeave) CParserPropertyValueCDesCArray(desArray);
+    CleanupStack::PushL(value);
+
+    property = CParserProperty::NewL( *value, text, params); //Create the Property with field and Value
+
+    CleanupStack::Pop(value);
+    CleanupStack::Pop(desArray);
+    CleanupStack::PopAndDestroy();  //For GoupIdArray
+
+    return property;
+    }
+
+// ----------------------------------------------------------------------------
+// CVPbkGroupCardHandler::DeleteContactFromGroupsL
+// ----------------------------------------------------------------------------
+void CVPbkGroupCardHandler::DeleteContactFromGroupsL()
+    {
+    if(iStore == NULL)
+        return;
+    //Get Groupid list a contact belongs
+    MVPbkContactLinkArray* groupIds = iStore->GroupsJoinedLC(); 
+
+    if(groupIds == NULL)
+        return; 
+
+    TInt groupIdsCount = 0;
+    groupIdsCount = groupIds->Count();    
+    const MVPbkContactLink* contactLink = iStore->CreateLinkLC();
+
+    //Remove the contact from all the Groups it belongs.
+    TBool thisDestroyed = EFalse;
+    for(TInt i = 0;i < groupIdsCount && !thisDestroyed;i++)
+        {
+        const MVPbkContactLink& groupLink = (*groupIds)[i];
+        thisDestroyed = RetrieveContactL( groupLink, *this );
+        if (!thisDestroyed && iTargetStore)
+            { 
+            MVPbkContactGroup* contactGrp = iTargetStore->Group();
+            if(contactGrp)
+                {   
+                iTargetStore->LockL(*this); //Lock the contact before editing the contact.
+                //wait for LockL operation to complete
+                if( ! (iWait->IsStarted()) )
+                    {
+                    iWait->Start();
+                    }
+
+                contactGrp->RemoveContactL(*contactLink); //Removes a contact from a Group
+
+                iTargetStore->CommitL(*this);  //save the Changes to VPBK.
+                //wait for CommitL operation to complete
+                if( ! (iWait->IsStarted()) )
+                    {
+                    iWait->Start();
+                    }
+                }  
+
+            delete iTargetStore;
+            iTargetStore = NULL;
+            }
+        }
+
+    CleanupStack::PopAndDestroy();  // for contactLink
+    CleanupStack::PopAndDestroy(); // for groupIds
+    }
+
+// ----------------------------------------------------------------------------
+// CVPbkGroupCardHandler::CreateNewGroupFromContactL
+// ----------------------------------------------------------------------------
+void CVPbkGroupCardHandler::CreateNewGroupFromContactL(TPtr16& aGroupLabel)
+    {
+    if(iStore == NULL)
+        return;
+    //Creates New Group 
+    MVPbkContactGroup* groupItem = iStore->ParentStore().CreateNewContactGroupLC(); 
+
+    if(groupItem)
+        {                    
+        groupItem->SetGroupLabelL(aGroupLabel); // set the group name.
+        
+        //Retrieve group store
+        const MVPbkContactLink* grpContactLink = groupItem->CreateLinkLC();
+        TBool thisDestroyed = RetrieveContactL( *grpContactLink, *this );
+        CleanupStack::PopAndDestroy();// to clean grpContactLink
+
+        if (!thisDestroyed && iTargetStore)
+            {
+            const MVPbkContactLink* contactLink = iStore->CreateLinkLC();
+            groupItem->AddContactL(*contactLink);
+            CleanupStack::PopAndDestroy(); //For aContactLink
+            groupItem->CommitL(*this); 
+            if( ! (iWait->IsStarted()) )
+                {
+                iWait->Start();
+                }//Commit to VPBK for new grp changes.
+
+            //Add the New Group to Hash Table
+            TPtrC16 contactGroupName;
+            contactGroupName.Set( aGroupLabel );
+            HBufC16* grpName = contactGroupName.AllocLC();
+
+            if(iContactsGroupsMap == NULL)
+                {
+                iContactsGroupsMap = new(ELeave) RPtrHashMap<TDesC16, MVPbkStoreContact>();
+                }
+            // iContactsGroupsMap takes the ownership of iTargetStore
+            TInt res = iContactsGroupsMap->Insert(grpName, iTargetStore);
+            if ( res != KErrNone )
+                {
+                delete iTargetStore;
+                }
+            iTargetStore = NULL;
+            CleanupStack::Pop(); // To pop up grpName
+            }
+        }   
+
+    CleanupStack::PopAndDestroy(); // To pop up and destroy groupItem  
+    }
+
+// ----------------------------------------------------------------------------
+// CVPbkGroupCardHandler::DecodeContactGroupInVCardL
+// ----------------------------------------------------------------------------
+void CVPbkGroupCardHandler::DecodeContactGroupInVCardL(TPtr16 aValue,
+        CVPbkGroupCardHandler** aSelfPointer )
+    {        
+    if(iStore == NULL)
+        return;
+    iSelfPtr = aSelfPointer;
+    const MVPbkContactLink* contactLink = iStore->CreateLinkLC();
+
+    TInt newLinePos = aValue.Find(KVersitTokencrlf());
+
+    if (newLinePos != KErrNotFound)
+        aValue = aValue.Left(newLinePos); //remove CRLF from aValue
+
+    TInt semiColonPos = 0;
+    TBool endGrpValue = EFalse;    
+
+    DeleteContactFromGroupsL(); //Delete the contact from the Groups it belongs
+
+    TBool destroyed = EFalse;
+    while(!endGrpValue && !destroyed)
+        {        
+        semiColonPos = aValue.Find( KSemiColon() );
+        if(semiColonPos == KErrNotFound)
+            {
+            semiColonPos = aValue.Length();
+            endGrpValue = ETrue;  // all the Group card values are parsed
+            }
+
+        if(semiColonPos > 0)
+            {          
+            //Get each group card value to save OR add to Groups
+            TPtrC16 desGrpValue = aValue.Left(semiColonPos); 
+            HBufC16* unicodeGrpValue = desGrpValue.Alloc();
+            CleanupStack::PushL( unicodeGrpValue );
+            TPtr16 desGrpValueHash = unicodeGrpValue->Des();
+
+            MVPbkContactGroup* groupContactItemId = NULL;
+            MVPbkStoreContact* storeContact = NULL;
+            if(iContactsGroupsMap)
+                {
+                // Find whether Group already present in VPBK, to get group store
+                storeContact = iContactsGroupsMap->Find(desGrpValueHash);
+                if (storeContact)
+                    groupContactItemId = storeContact->Group();
+                }
+
+            // if group already present add the contact to existing group otherwise 
+            // add the contact to new group 
+            if(groupContactItemId != NULL)
+                { 
+                storeContact->LockL(*this);
+                iDestroyed = &destroyed;
+                //wait for Lock operation to complete
+                if( ! (iWait->IsStarted()) )
+                    {
+                    iWait->Start();
+                    }
+                if ( !destroyed )
+                    {
+                    iDestroyed = NULL;
+                    groupContactItemId->AddContactL(*contactLink);
+                    storeContact->CommitL(*this);  // save Group modifications.
+                    iDestroyed = &destroyed;
+                    if( ! (iWait->IsStarted()) )
+                        {
+                        iWait->Start();
+                        }
+                    if ( !destroyed )
+                        {
+                        iDestroyed = NULL;
+                        }
+                    }
+                }
+            else
+                {                                
+                CreateNewGroupFromContactL(desGrpValueHash);
+                }// End of if(err = KErrNone)
+
+            CleanupStack::PopAndDestroy(unicodeGrpValue);
+            }// End of if(semiColonPos > 0)
+
+        //Get Next Group card Value
+        if(!endGrpValue)
+            aValue = aValue.Right( aValue.Length() - semiColonPos - KSemiColon().Length());
+        } //End Of While loop
+
+    CleanupStack::PopAndDestroy(); // For contactLink 
+
+    if(!destroyed)
+        {
+        iSelfPtr = NULL;
+        delete iStore;
+        iStore = NULL;
+        }
+
+    }
+// ----------------------------------------------------------------------------
+// CVPbkGroupCardHandler::BuildContactGroupsHashMapL
+// ----------------------------------------------------------------------------
+void CVPbkGroupCardHandler::BuildContactGroupsHashMapL(
+        MVPbkContactStore& aTargetContactStore, 
+        CVPbkGroupCardHandler** aSelfPointer)
+    {
+    //Get all the Group Links in current VPBK
+    MVPbkContactLinkArray* groupLinks = aTargetContactStore.ContactGroupsLC();
+
+    if( (groupLinks == NULL || iContactsGroupsMap != NULL))
+        return;
+
+    iSelfPtr = aSelfPointer;
+    
+    iContactsGroupsMap = new(ELeave) RPtrHashMap<TDesC16, MVPbkStoreContact>();
+
+    TInt groupCount = 0;
+    groupCount = groupLinks->Count();
+
+    // Get Group Name and Group store, store these values into Hash Table.
+    TBool thisDestroyed = EFalse;
+    for(TInt i = 0;i < groupCount && !thisDestroyed;i++)
+        {
+        const MVPbkContactLink& groupLink = (*groupLinks)[i];
+        thisDestroyed = RetrieveContactL( groupLink, *this );
+        if (!thisDestroyed && iTargetStore)
+            {
+            MVPbkContactGroup* contactGrp = iTargetStore->Group();
+            if(contactGrp)
+                {   
+                TPtrC16 contactGroupName;
+                contactGroupName.Set( contactGrp->GroupLabel());
+                HBufC16* grpName = contactGroupName.AllocLC();
+                // iContactsGroupsMap takes the ownership of iTargetStore
+                TInt res = iContactsGroupsMap->Insert(grpName, iTargetStore);
+                if ( res != KErrNone )
+                    {
+                    delete iTargetStore;
+                    }
+                iTargetStore = NULL;
+                CleanupStack::Pop();  //grpName
+                }       
+            }    
+        }// End of for loop
+
+    CleanupStack::PopAndDestroy(); //for groupLinks
+    
+    if ( !thisDestroyed )
+        {
+        iSelfPtr = NULL;
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CVPbkGroupCardHandler::RetrieveContactL
+// ----------------------------------------------------------------------------
+TBool CVPbkGroupCardHandler::RetrieveContactL( const MVPbkContactLink& aLink,
+            MVPbkSingleContactOperationObserver& aObserver)
+    {
+    delete iTargetStore;
+    iTargetStore = NULL;
+    iRetrieveOp = iData.GetContactManager().RetrieveContactL( aLink, aObserver );
+    
+    TBool destroyed = EFalse;
+    // Set iDestroyed to point to stack variable that is accessed from
+    // destructor.
+    iDestroyed = &destroyed; 
+    //wait for GetContactGroupStoreL operation to complete,to get storecontact
+    if( ! (iWait->IsStarted()) )
+        {
+        iWait->Start();
+        }
+    
+    if ( !destroyed )
+        {
+        // Reset pointer to stack variable.
+        iDestroyed = NULL;
+        delete iRetrieveOp;
+        iRetrieveOp = NULL;
+        }
+    return destroyed; 
+    }
+
+// ----------------------------------------------------------------------------
+// CVPbkGroupCardHandler::VPbkSingleContactOperationComplete
+// ----------------------------------------------------------------------------
+void CVPbkGroupCardHandler::VPbkSingleContactOperationComplete(
+        MVPbkContactOperationBase& /*aOperation*/,
+        MVPbkStoreContact* aContact)
+    {
+    iTargetStore = aContact;
+
+    if( iWait->IsStarted() )
+        iWait->AsyncStop();
+
+    }
+
+// ----------------------------------------------------------------------------
+// CVPbkGroupCardHandler::VPbkSingleContactOperationFailed
+// ----------------------------------------------------------------------------
+void CVPbkGroupCardHandler::VPbkSingleContactOperationFailed
+(MVPbkContactOperationBase& /*aOperation*/, TInt /*aError*/)
+    {
+    if( iWait->IsStarted() )
+        iWait->AsyncStop();
+    }
+
+// ----------------------------------------------------------------------------
+// CVPbkGroupCardHandler::GetContactGroupStoreL
+// Retrieve the contact store of group contact
+// ----------------------------------------------------------------------------
+void CVPbkGroupCardHandler::GetContactGroupStoreL(
+        const MVPbkContactLink& aContactLink, 
+        CVPbkGroupCardHandler** aSelfPointer)
+    {
+    iSelfPtr = aSelfPointer;
+    delete iStore;
+    iStore = NULL;
+    if ( !RetrieveContactL( aContactLink, *this ) )
+        {
+        iSelfPtr = NULL;
+        // iStore takes the ownership.
+        iStore = iTargetStore;
+        iTargetStore = NULL;
+        }        
+    }
+
+// ----------------------------------------------------------------------------
+// CVPbkGroupCardHandler::ContactOperationCompleted
+// ----------------------------------------------------------------------------
+void CVPbkGroupCardHandler::ContactOperationCompleted(TContactOpResult aResult)
+    {
+    delete aResult.iStoreContact;
+    if( iWait->IsStarted() )
+        iWait->AsyncStop();
+    }
+
+// ----------------------------------------------------------------------------
+// CVPbkGroupCardHandler::ContactOperationFailed
+// ----------------------------------------------------------------------------
+void CVPbkGroupCardHandler::ContactOperationFailed
+(TContactOp /*aOpCode*/, TInt /*aErrorCode*/, TBool /*aErrorNotified*/)
+    {
+    if( iWait->IsStarted() )
+        iWait->AsyncStop();
+    }