diff -r 000000000000 -r e686773b3f54 phonebookengines/VirtualPhonebook/VPbkEng/src/CVPbkxSPContactsOperation.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines/VirtualPhonebook/VPbkEng/src/CVPbkxSPContactsOperation.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,392 @@ +/* +* Copyright (c) 2005-2007 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: xSP Contact operation + * +*/ + + +// INCLUDES +#include "CVPbkxSPContactsOperation.h" + + +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "VPbkDebug.h" + +#include +#include +#include +namespace + { + +#ifdef _DEBUG + enum TxSPErrors + { + ExSPErrorWrongLogic1, + ExSPErrorWrongState, + EInvalidOperation, + ExSPErrorWrongStateRun + }; + + _LIT( KPanicStrxSPManagement, "VPbk_xSPManag"); + + void Panic(TxSPErrors aReason) + { + User::Panic(KPanicStrxSPManagement, aReason); + } +#endif + } + +/////////////////////////////////////////////////////////////////////////////// + +CVPbkxSPContactsOperation* CVPbkxSPContactsOperation::NewLC( + const MVPbkStoreContact& aContact, + CVPbkContactManager& aContactManager, + MVPbkOperationErrorObserver& aErrorObserver, TxSPOperation aOperation) + { + CVPbkxSPContactsOperation* self = new (ELeave) CVPbkxSPContactsOperation( + aContact, + aContactManager, + aErrorObserver, + aOperation ); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +void CVPbkxSPContactsOperation::ConstructL() + { + iContactLink = iContact.CreateLinkLC(); + CleanupStack::Pop(); //iContactLink + iContactLinks = CVPbkContactLinkArray::NewL(); + CompleteOurself(); //start execution right away + } + +CVPbkxSPContactsOperation::CVPbkxSPContactsOperation( + const MVPbkStoreContact& aContact, + CVPbkContactManager& aContactManager, + MVPbkOperationErrorObserver& aErrorObserver, + TxSPOperation /*aOperation*/) : + CActive(EPriorityStandard), + iNextState(EStateNone), iContact(aContact), + iContactManager(aContactManager), iErrorObserver(&aErrorObserver) + { + CActiveScheduler::Add(this); + } + +CVPbkxSPContactsOperation::~CVPbkxSPContactsOperation() + { + Cancel(); + delete iContactOperation; + + if(iContactLinks) + { + iContactLinks->ResetAndDestroy(); + } + + delete iContactLinks; + delete iContactLink; + delete iFieldTypeRefList; + delete iXspIdArray; + } + +MVPbkContactOperationBase* CVPbkxSPContactsOperation::NewGetxSPLinksOperationL( + const MVPbkStoreContact& aContact, + CVPbkContactManager& aContactManager, + MVPbkOperationResultObserver& aObserver, + MVPbkOperationErrorObserver& aErrorObserver, TxSPOperation aOperation) + { + __ASSERT_DEBUG( aOperation == EGetxSPContactLinks, + Panic(EInvalidOperation) ); + + CVPbkxSPContactsOperation* self = NewLC(aContact, aContactManager, + aErrorObserver, aOperation); + self->iLinksObserver = &aObserver; + self->iNextState = EStateFind; + + CleanupStack::Pop(self); + return self; + } + +void CVPbkxSPContactsOperation::DoCancel() + { + delete iContactOperation; + iContactOperation = NULL; + } + +void CVPbkxSPContactsOperation::RunL() + { + switch(iNextState) + { + case EStateFind: + { + GetIMPPDataL(); + } + break; + + case EStateAbortWithError: + { + NotifyError(iAbortError); + } + break; + + default: + { + __ASSERT_DEBUG( EFalse,Panic( ExSPErrorWrongStateRun ) ); + } + } + } + +TInt CVPbkxSPContactsOperation::RunError(TInt aError) + { + NotifyError(aError); + return KErrNone; + } + +//--------------------------------------------------------------- +// These are from MVPbkContactStoreObserver + +void CVPbkxSPContactsOperation::FindFromStoreSucceededL( + MVPbkContactStore& /*aStore*/, + MVPbkContactLinkArray* aResultsFromStore) + { + ProcessContactLinksL(aResultsFromStore); + delete aResultsFromStore; + } + +void CVPbkxSPContactsOperation::FindFromStoreFailed( + MVPbkContactStore& /*aStore*/, TInt /*aError*/) + { + //do nothing + } + +void CVPbkxSPContactsOperation::FindFromStoresOperationComplete() + { + TRAP_IGNORE(SubsearchCompleteL()); + } + +// ---------------------------------------------------------- +// CVPbkxSPContactsOperation::GetIMPPDataL +// +// ---------------------------------------------------------- +// +void CVPbkxSPContactsOperation::GetIMPPDataL() + { + //Check is contact valid. + __ASSERT_ALWAYS ( NULL != &iContact, User::Leave(KErrArgument)); + + TBool imppFound = EFalse; + iXspIdArray = new ( ELeave ) CDesCArrayFlat( 5 ); + const MVPbkFieldType* type = + iContactManager.FieldTypes().Find( R_VPBK_FIELD_TYPE_IMPP); + CVPbkBaseContactFieldTypeIterator* itr = + CVPbkBaseContactFieldTypeIterator::NewLC( *type, + iContact.Fields() ); + if (itr->HasNext() ) + { + imppFound = ETrue; + while (itr->HasNext() ) + { + const MVPbkBaseContactField* field = itr->Next(); + const MVPbkContactFieldUriData& uri = + MVPbkContactFieldUriData::Cast(field->FieldData() ); + HBufC* data = uri.Uri().AllocL(); + CleanupStack::PushL(data); + iXspIdArray->AppendL(data->Des() ); + CleanupStack::PopAndDestroy(data); + } + + iFieldTypeRefList = CVPbkFieldTypeRefsList::NewL(); + iFieldTypeRefList->AppendL( + *iContactManager.FieldTypes().Find( R_VPBK_FIELD_TYPE_IMPP) ); + FindUsingIdL(); + } + + CleanupStack::PopAndDestroy(itr); + + //If there isn't any impp fields, notify empty contact link array. + if (!imppFound) + { + NotifyResult(); + } + } + +// --------------------------------------------------------------------------- +// CVPbkxSPContactsOperation::FindUsingIdL +// --------------------------------------------------------------------------- +// +TBool CVPbkxSPContactsOperation::FindUsingIdL() + { + TBool started(EFalse); + + if( iXspIdArray->MdcaCount() > iNextXspId ) + { + if ( iContactOperation != NULL ) + { + delete iContactOperation; + iContactOperation = NULL; + } + + started = ETrue; + CDesCArrayFlat* idArray = new ( ELeave ) CDesCArrayFlat( 1 ); + CleanupStack::PushL(idArray); + idArray->AppendL( iXspIdArray->MdcaPoint(iNextXspId) ); + iNextXspId++; + TCallBack parser(CVPbkxSPContactsOperation::WordParserL, this); + CDesC16ArrayFlat* aXUriArray = new ( ELeave ) CDesCArrayFlat( 52 ); + CleanupStack::PushL(aXUriArray); + RIdArray ids; + CleanupClosePushL( ids ); + CSPSettings* settings = CSPSettings::NewL(); + CleanupStack::PushL( settings ); + TInt error = settings->FindServiceIdsL( ids ); + const TInt count = ids.Count(); + TVPbkContactStoreUriPtr defaultUri = VPbkContactStoreUris::DefaultCntDbUri(); + + for( TInt i = 0; i < count; i++ ) + { + CSPProperty* property = CSPProperty::NewLC(); + error = settings->FindPropertyL( ids[i], EPropertyContactStoreId, + *property ); + if( KErrNone == error ) + { + RBuf uri; + uri.Create( KSPMaxDesLength ); + CleanupClosePushL( uri ); + property->GetValue( uri ); + + // Append the uri which is not equal to default store uri + if ( defaultUri.UriDes().CompareF(uri) != KErrNone ) + { + aXUriArray->AppendL( uri ); + } + CleanupStack::PopAndDestroy(); //uri + } + CleanupStack::PopAndDestroy(); //property + } + CleanupStack::PopAndDestroy( 2 ); // settings, ids + + iContactOperation = iContactManager.FindL( *idArray, *iFieldTypeRefList, + *this, parser,*aXUriArray); + + CleanupStack::PopAndDestroy( 2 ); + } + + return started; + } + +// ---------------------------------------------------------- +// CVPbkxSPContactsOperation::WordParserL +// +// ---------------------------------------------------------- +// +TInt CVPbkxSPContactsOperation::WordParserL(TAny* aWordParserParam) + { + //Get all data, no need to parse anything.. + TVPbkWordParserCallbackParam* param = + static_cast(aWordParserParam ); + TPtrC data(param->iStringToParse->Ptr() ); + param->iWordArray->AppendL(data); + return 0; + } + +void CVPbkxSPContactsOperation::ProcessContactLinksL( + MVPbkContactLinkArray* aResultsFromStore) + { + TInt count = aResultsFromStore->Count(); + + for (TInt a = 0; a < count; a++) + { + const MVPbkContactLink& link = aResultsFromStore->At(a); + + //If not from original storage, add to array. + if (!link.RefersTo(iContact)) + { + if(iContactLinks->Find(link) == KErrNotFound) + { + iContactLinks->AppendL(link.CloneLC()); + CleanupStack::Pop(); //Clone + } + } + } + } + +// -------------------------------------------------------------------------- +// Completes this active object. +// -------------------------------------------------------------------------- +void CVPbkxSPContactsOperation::CompleteOurself() + { + if ( !IsActive() ) + { + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrNone); + SetActive(); + } + else + { + __ASSERT_DEBUG( EFalse, Panic(ExSPErrorWrongLogic1) ); + } + } + +// -------------------------------------------------------------------------- +// Search completed +// -------------------------------------------------------------------------- +void CVPbkxSPContactsOperation::SubsearchCompleteL() + { + if(!FindUsingIdL()) + { + NotifyResult(); + } + } + +// -------------------------------------------------------------------------- +// Notifies operation observer of results +// -------------------------------------------------------------------------- +void CVPbkxSPContactsOperation::NotifyResult() + { + iLinksObserver->VPbkOperationResultCompleted( this, iContactLinks); + } + +// -------------------------------------------------------------------------- +// Sends error notification to the error observer +// -------------------------------------------------------------------------- +inline void CVPbkxSPContactsOperation::NotifyError(TInt aErr) + { + iErrorObserver->VPbkOperationFailed( this, aErr); + } + +// -------------------------------------------------------------------------- +// Notify error async +// -------------------------------------------------------------------------- +void CVPbkxSPContactsOperation::AbortWithError(TInt aErr) + { + iAbortError = aErr; + iNextState = EStateAbortWithError; + CompleteOurself(); + } + +// end of file