--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/UIServices/src/CPbk2AiwAssignProvider.cpp Wed Sep 01 12:29:52 2010 +0100
@@ -0,0 +1,1309 @@
+/*
+* 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: Phonebook 2 Assign UI service AIW provider.
+*
+*/
+
+
+#include "CPbk2AiwAssignProvider.h"
+
+// Phonebook 2
+#include "CPbk2ServerAppConnection.h"
+#include "Pbk2UIServices.hrh"
+#include <Pbk2IPCPackage.h>
+#include <Pbk2UiServicesRes.rsg>
+#include <Pbk2UIControls.rsg>
+#include <Pbk2DataCaging.hrh>
+#include <Pbk2MimeTypeHandler.h>
+#include <Pbk2InternalUID.h>
+
+// Virtual Phonebook
+#include <VPbkPublicUid.h>
+
+// System includes
+#include <AiwMenu.h>
+#include <AiwContactAssignDataTypes.h>
+#include <s32mem.h>
+#include <eikspane.h>
+#include <akntitle.h>
+#include <avkon.hrh>
+#include <featmgr.h>
+#include <aknViewAppUi.h>
+
+using namespace AiwContactAssign;
+
+/// Unnamed namespace for local definitions
+namespace {
+
+_LIT(KPbk2UiServicesDllResFileName, "Pbk2UiServicesRes.rsc");
+_LIT(KPbk2UiControlsDllResFileName, "Pbk2UiControls.rsc");
+
+#ifdef _DEBUG
+
+enum TPanicCode
+ {
+ ENullPointer,
+ EInvalidArgument,
+ EDataTypeNotSupported
+ };
+
+void Panic(TPanicCode aReason)
+ {
+ _LIT( KPanicText, "CPbk2AiwAssignProvider" );
+ User::Panic( KPanicText, aReason );
+ }
+
+#endif // _DEBUG
+
+
+/**
+ * Verifies whether the given command id is handled here.
+ * This should be done by AIW.
+ *
+ * @param aCmdId The command id to check.
+ * @return ETrue if command is handled by this provider
+ */
+inline TBool IsCorrectAiwCmd( const TInt aCmdId )
+ {
+ TBool ret = EFalse;
+ switch ( aCmdId )
+ {
+ case KAiwCmdAssign: // FALLTHROUGH
+ case EPbk2AiwCmdAssign: // FALLTHROUGH
+ case EPbk2AiwCmdDataSaveCreateNew: // FALLTHROUGH
+ case EPbk2AiwCmdDataSaveAddToExisting:
+ {
+ ret = ETrue;
+ break;
+ }
+
+ default:
+ {
+ // Do nothing
+ break;
+ }
+ }
+ return ret;
+ }
+
+/**
+ * Finds a AIW semantic id from the AIW in param list.
+ *
+ * @param aInParamList AIW in param list.
+ * @param aSemanticId The semantic id to look for.
+ * @return ETrue if found, EFalse otherwise.
+ */
+inline TBool FindSemanticId
+ ( const CAiwGenericParamList& aInParamList,
+ const TGenericParamId aSemanticId )
+ {
+ TBool ret = EFalse;
+
+ TInt index = 0;
+ if ( aInParamList.FindFirst( index, aSemanticId ) )
+ {
+ ret = ETrue;
+ }
+
+ return ret;
+ }
+
+/**
+ * Validates that param's data is valid
+ *
+ * @param aInParamList The data passed by the consumer.
+ * @param aSemanticId The param which data to be validate.
+ * @return ETrue if data is valid, EFalse otherwise
+ */
+inline TBool ValidateData
+ ( const CAiwGenericParamList& aInParamList,
+ TGenericParamId aSemanticId )
+ {
+ TBool result = ETrue;
+
+ // EGenericParamMIMEType param data validation
+ if ( EGenericParamMIMEType == aSemanticId )
+ {
+ TInt index = 0;
+
+ const TAiwGenericParam* mimeTypeParam =
+ aInParamList.FindFirst( index, EGenericParamMIMEType,
+ EVariantTypeDesC );
+
+ TInt error = KErrNone;
+ TInt mimeType = Pbk2MimeTypeHandler::EMimeTypeNotSupported;
+ if ( mimeTypeParam )
+ {
+ TRAP( error,
+ {
+ if ( mimeTypeParam->Value().AsData().Ptr() )
+ {
+ // 8-bit
+ mimeType = Pbk2MimeTypeHandler::MapMimeTypeL
+ ( mimeTypeParam->Value().AsData() );
+ }
+ else if ( mimeTypeParam->Value().AsDes().Ptr() )
+ {
+ // 16-bit
+ mimeType = Pbk2MimeTypeHandler::MapMimeTypeL
+ ( mimeTypeParam->Value().AsDes() );
+ }
+ } ); // TRAP
+ }
+
+ // No MIME type found if leaves with KErrNotFound.
+ // Not supported type if mimeType is not found.
+ if ( error == KErrNotFound ||
+ Pbk2MimeTypeHandler::EMimeTypeNotSupported == mimeType )
+ {
+ result = EFalse;
+ }
+ }
+
+ return result;
+ }
+
+/**
+ * Validates that consumer passed all required data.
+ * Checks also if required param EGenericParamMIMEType data is valid.
+ * If invalid data is given leave KErrArgument will occur.
+ *
+ * @param aInParamList The data passed by the consumer.
+ * @return EGenericParamUnspecified if no valid data is found,
+ * AIW semantic id of found data otherwise.
+ */
+inline TGenericParamId ValidateParams
+ ( const CAiwGenericParamList& aInParamList )
+ {
+ TGenericParamId ret = EGenericParamUnspecified;
+
+ if ( FindSemanticId( aInParamList, EGenericParamPhoneNumber ) )
+ {
+ ret = EGenericParamPhoneNumber;
+ }
+ else if ( FindSemanticId( aInParamList, EGenericParamEmailAddress ) )
+ {
+ ret = EGenericParamEmailAddress;
+ }
+ else if ( FindSemanticId( aInParamList, EGenericParamSIPAddress ) )
+ {
+ ret = EGenericParamSIPAddress;
+ }
+ else if ( FindSemanticId( aInParamList, EGenericParamURL ) )
+ {
+ ret = EGenericParamURL;
+ }
+ else if ( FindSemanticId( aInParamList, EGenericParamWVID ) )
+ {
+ ret = EGenericParamWVID;
+ }
+ else if ( FindSemanticId( aInParamList, EGenericParamSpeedDialIndex ) )
+ {
+ ret = EGenericParamSpeedDialIndex;
+ }
+ else if ( FindSemanticId( aInParamList, EGenericParamXSpId ) )
+ {
+ ret = EGenericParamXSpId;
+ }
+ else if ( FindSemanticId( aInParamList, EGenericParamContactItem ) )
+ {
+ ret = EGenericParamContactItem;
+ }
+ if ( ret == EGenericParamUnspecified )
+ {
+ // The in param list must have a MIME type with the data and file name
+ if ( FindSemanticId( aInParamList, EGenericParamMIMEType ) &&
+ ValidateData( aInParamList, EGenericParamMIMEType ) )
+ {
+ if ( FindSemanticId( aInParamList, EGenericParamFile ) )
+ {
+ // In this case, return EGenericParamFile
+ ret = EGenericParamFile;
+ }
+ }
+ }
+
+ return ret;
+ }
+
+/**
+ * Selects correct address select selector matching the passed parameters.
+ *
+ * @param aInParamList Parameter list.
+ * @return Selector resource id.
+ */
+TInt SelectSelectorResourceIdFromParams
+ ( const CAiwGenericParamList& aInParamList )
+ {
+ TInt resourceId = KErrNotFound;
+
+ if ( FindSemanticId( aInParamList, EGenericParamPhoneNumber ) )
+ {
+ if( FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) )
+ {
+ resourceId = R_PBK2_AIW_PHONENUMBER_SELECTOR_VOIP;
+ }
+ else
+ {
+ resourceId = R_PBK2_AIW_PHONENUMBER_SELECTOR;
+ }
+ }
+ else if ( FindSemanticId( aInParamList, EGenericParamEmailAddress ) )
+ {
+ if( FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) )
+ {
+ resourceId = R_PBK2_AIW_EMAIL_SELECTOR_VOIP;
+ }
+ else
+ {
+ resourceId = R_PBK2_AIW_EMAIL_SELECTOR;
+ }
+ }
+ else if ( FindSemanticId( aInParamList, EGenericParamSIPAddress ) )
+ {
+ if( FeatureManager::FeatureSupported( KFeatureIdCommonVoip ) )
+ {
+ resourceId = R_PBK2_AIW_SIP_SELECTOR_VOIP;
+ }
+ else
+ {
+ resourceId = R_PBK2_AIW_SIP_SELECTOR;
+ }
+ }
+ else if ( FindSemanticId( aInParamList, EGenericParamURL ) )
+ {
+ resourceId = R_PBK2_AIW_URL_SELECTOR;
+ }
+ else if ( FindSemanticId( aInParamList, EGenericParamWVID ) )
+ {
+ // Not supported yet
+ }
+ else if ( FindSemanticId( aInParamList, EGenericParamDateTime ) )
+ {
+ // Not supported yet
+ }
+ else if ( FindSemanticId( aInParamList, EGenericParamXSpId ) )
+ {
+ resourceId = R_PBK2_AIW_IMPP_SELECTOR;
+ }
+ else
+ {
+ TInt index = 0;
+
+ // Lets then try MIME type param
+ const TAiwGenericParam* mimeTypeParam =
+ aInParamList.FindFirst( index, EGenericParamMIMEType,
+ EVariantTypeDesC );
+
+ if ( mimeTypeParam )
+ {
+ // If MIME type is specified, then the selector resource
+ // depends on the type of MIME
+ TInt mimeType( 0 );
+ if ( mimeTypeParam->Value().AsData().Ptr() )
+ {
+ // 8-bit
+ mimeType = Pbk2MimeTypeHandler::MapMimeTypeL
+ ( mimeTypeParam->Value().AsData() );
+ }
+ else if ( mimeTypeParam->Value().AsDes().Ptr() )
+ {
+ // 16-bit
+ mimeType = Pbk2MimeTypeHandler::MapMimeTypeL
+ ( mimeTypeParam->Value().AsDes() );
+ }
+
+ switch ( mimeType )
+ {
+ case Pbk2MimeTypeHandler::EMimeTypeImage:
+ {
+ resourceId = R_PBK2_AIW_THUMBNAIL_SELECTOR;
+ break;
+ }
+ case Pbk2MimeTypeHandler::EMimeTypeAudio: // FALLTHROUGH
+ case Pbk2MimeTypeHandler::EMimeTypeVideo:
+ {
+ resourceId = R_PBK2_AIW_RINGTONE_SELECTOR;
+ break;
+ }
+ default:
+ {
+ // Do nothing
+ break;
+ }
+ }
+ }
+ }
+
+ return resourceId;
+ }
+
+/**
+ * Selects correct contact view filter selector matching
+ * the passed parameters.
+ *
+ * @param aInParamList Parameter list.
+ * @return Selector resource id.
+ */
+TInt SelectFilterResourceIdFromParams
+ ( const CAiwGenericParamList& aInParamList )
+ {
+ TInt resourceId = KErrNotFound;
+
+ if ( FindSemanticId( aInParamList, EGenericParamSpeedDialIndex ) )
+ {
+ resourceId = R_PHONEBOOK2_PHONENUMBER_SELECTOR;
+ }
+
+ return resourceId;
+ }
+
+} /// namespace
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::CPbk2AiwAssignProvider
+// --------------------------------------------------------------------------
+//
+CPbk2AiwAssignProvider::CPbk2AiwAssignProvider()
+ : iUiServicesResourceFile( *CCoeEnv::Static() )
+ {
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::~CPbk2AiwAssignProvider
+// --------------------------------------------------------------------------
+//
+CPbk2AiwAssignProvider::~CPbk2AiwAssignProvider()
+ {
+ delete iConnection;
+ delete iEventParamList;
+ delete iDataPackage;
+ delete iConfigurationPackage;
+ delete iInstructionsPackage;
+ iUiServicesResourceFile.Close();
+ FeatureManager::UnInitializeLib();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::NewL
+// --------------------------------------------------------------------------
+//
+CPbk2AiwAssignProvider* CPbk2AiwAssignProvider::NewL()
+ {
+ CPbk2AiwAssignProvider* self = new ( ELeave) CPbk2AiwAssignProvider;
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::ConstructL
+// --------------------------------------------------------------------------
+//
+void CPbk2AiwAssignProvider::ConstructL()
+ {
+ iUiServicesResourceFile.OpenL(KPbk2RomFileDrive,
+ KDC_RESOURCE_FILES_DIR, KPbk2UiServicesDllResFileName);
+ FeatureManager::InitializeLibL();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::InitializeMenuPaneL
+// --------------------------------------------------------------------------
+//
+void CPbk2AiwAssignProvider::InitializeMenuPaneL
+ ( CAiwMenuPane& aMenuPane, TInt aIndex,
+ TInt /*aCascadeId*/, const CAiwGenericParamList& aInParamList)
+ {
+ TAiwGenericParam param = ValidateParams(aInParamList);
+ if (param != EGenericParamUnspecified)
+ {
+ // Initialize with the default menu
+ TInt menuResourceId = R_PBK2_AIW_ASSIGN;
+
+ CreateInstructionPackageL( aInParamList );
+
+ if (iInstructionsPackage)
+ {
+ TInt version = TAiwContactAssignDataBase::
+ AssignDataTypeFromBuffer( *iInstructionsPackage );
+ if (version == EAiwMultipleContactAssignV1)
+ {
+ // Multi assign has always just one menu option,
+ // and it has already been set
+ }
+ else if (version == EAiwSingleContactAssignV1)
+ {
+ // Single assign defaults to R_PBK2_AIW_ADD_TO_CONTACTS,
+ // but if there is a raised EUseSimpleMenu flag
+ // then we show the R_PBK2_AIW_ASSIGN menu
+ TAiwSingleContactAssignDataV1Pckg data;
+ data.Copy( *iInstructionsPackage );
+ TUint assignFlags = data().Flags();
+ if ( !( assignFlags & EUseSimpleMenu ) )
+ {
+ if (param == EGenericParamXSpId)
+ {
+ menuResourceId = R_PBK2_AIW_ADD_TO_CONTACTS_XSP;
+ }
+ else
+ {
+ menuResourceId = R_PBK2_AIW_ADD_TO_CONTACTS;
+ }
+ }
+ }
+ else
+ {
+ User::Leave( KErrArgument );
+ }
+ }
+
+ // Show the menu
+ TResourceReader reader;
+ CCoeEnv::Static()->CreateResourceReaderLC
+ (reader, menuResourceId);
+ aMenuPane.AddMenuItemsL(reader, KAiwCmdAssign, aIndex);
+ CleanupStack::PopAndDestroy(); // reader
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::HandleMenuCmdL
+// --------------------------------------------------------------------------
+//
+void CPbk2AiwAssignProvider::HandleMenuCmdL
+ ( TInt aMenuCmdId, const CAiwGenericParamList& aInParamList,
+ CAiwGenericParamList& aOutParamList,
+ TUint aCmdOptions, const MAiwNotifyCallback* aCallback )
+ {
+ // Route to HandleServiceCmdL
+ HandleServiceCmdL( aMenuCmdId, aInParamList,
+ aOutParamList, aCmdOptions, aCallback );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::InitialiseL
+// --------------------------------------------------------------------------
+//
+void CPbk2AiwAssignProvider::InitialiseL
+ ( MAiwNotifyCallback& /*aFrameworkCallback*/,
+ const RCriteriaArray& /*aInterest*/ )
+ {
+ // Nothing needs to be done
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::HandleServiceCmdL
+// --------------------------------------------------------------------------
+//
+void CPbk2AiwAssignProvider::HandleServiceCmdL
+ ( const TInt& aCmdId, const CAiwGenericParamList& aInParamList,
+ CAiwGenericParamList& /*aOutParamList*/,
+ TUint aCmdOptions, const MAiwNotifyCallback* aCallback )
+ {
+ if ( IsCorrectAiwCmd( aCmdId ) )
+ {
+ if ( !iConnection )
+ {
+ iConnection = CPbk2ServerAppConnection::NewL( *this );
+ }
+ else if( iConnection->IsActive() )
+ {
+ if ( aCmdOptions & KAiwOptCancel )
+ {
+ // Client wants to cancel existing service
+ iConnection->CancelAssign();
+ }
+
+ // Request is already active for the same client, do nothing
+ // as Phonebook supports only one request per client at a time.
+ return;
+ }
+
+ if ( !iEventParamList )
+ {
+ iEventParamList = CAiwGenericParamList::NewL();
+ }
+
+ TGenericParamId semanticId = ValidateParams( aInParamList );
+ iCallback = aCallback;
+
+ // Create IPC packages
+ CreateInstructionPackageL( aInParamList );
+ ValidateInstructionPackageL();
+ ValidateMenuServiceL( aCmdId );
+ CreateConfigurationPackageL( aInParamList );
+
+ if ( semanticId == EGenericParamSpeedDialIndex )
+ {
+ LaunchAttributeAssignL( aInParamList, semanticId );
+ }
+ else
+ {
+ LaunchDataAssignL( aInParamList, semanticId );
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::OperationCompleteL
+// --------------------------------------------------------------------------
+//
+void CPbk2AiwAssignProvider::OperationCompleteL
+ ( const TDesC8& aContactLinks, TInt aExtraResultData,
+ const TDesC& /*aField*/ )
+ {
+ iEventParamList->Reset();
+ iEventParamList->AppendL(
+ TAiwGenericParam( EGenericParamContactLinkArray,
+ TAiwVariant( aContactLinks ) ) );
+
+ // aExtraResultData contains index of focused field from editor
+ // this is used in cca details view.
+ // todo: would it be better to add a new aiw semantic id instead of EGenericParamContactItem?
+ iEventParamList->AppendL(
+ TAiwGenericParam( EGenericParamContactItem,
+ TAiwVariant( aExtraResultData )));
+
+ if (iCallback)
+ {
+ // Must cast this because of AIW design error
+ const_cast<MAiwNotifyCallback*>(iCallback)->HandleNotifyL
+ ( KAiwCmdAssign, KAiwEventCompleted, *iEventParamList,
+ *iInParamList );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::OperationCanceledL
+// --------------------------------------------------------------------------
+//
+void CPbk2AiwAssignProvider::OperationCanceledL()
+ {
+ iEventParamList->Reset();
+ if (iCallback)
+ {
+ // Must cast this because of AIW design error
+ const_cast<MAiwNotifyCallback*>(iCallback)->HandleNotifyL
+ ( KAiwCmdAssign, KAiwEventCanceled, *iEventParamList,
+ *iInParamList );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::OperationErrorL
+// --------------------------------------------------------------------------
+//
+void CPbk2AiwAssignProvider::OperationErrorL( TInt aError )
+ {
+ iEventParamList->Reset();
+ iEventParamList->AppendL(
+ TAiwGenericParam( EGenericParamError,
+ TAiwVariant( aError ) ) );
+
+ if ( iCallback )
+ {
+ // Must cast this because of AIW design error
+ const_cast<MAiwNotifyCallback*>( iCallback )->HandleNotifyL
+ ( KAiwCmdAssign, KAiwEventError, *iEventParamList,
+ *iInParamList );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::OkToExitL
+// --------------------------------------------------------------------------
+//
+TBool CPbk2AiwAssignProvider::OkToExitL
+ ( TInt /*aCommandId*/, TPbk2ExitCommandParams aExitParameter )
+ {
+ TBool okToExit = ETrue;
+
+ if ( iCallback )
+ {
+ iEventParamList->Reset();
+ iEventParamList->AppendL(
+ TAiwGenericParam( EGenericParamApplication,
+ TAiwVariant( aExitParameter ) ) );
+
+ // Must cast this because of AIW design error
+ okToExit = const_cast<MAiwNotifyCallback*>( iCallback )
+ ->HandleNotifyL( KAiwCmdAssign, KAiwEventQueryExit,
+ *iEventParamList, *iInParamList );
+ }
+
+ return okToExit;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::AcceptSelectionL
+// --------------------------------------------------------------------------
+//
+TBool CPbk2AiwAssignProvider::AcceptSelectionL
+ ( TInt /*aNumberOfSelectedContacts*/, HBufC8& /*aContactLink*/ )
+ {
+ // Assign service does not contain support
+ // for verification of the selection
+ return ETrue;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::PackParameterToBufferL
+// --------------------------------------------------------------------------
+//
+HBufC8* CPbk2AiwAssignProvider::PackParameterToBufferL
+ ( TGenericParamId aParamId,
+ const CAiwGenericParamList& aInParamList) const
+ {
+ HBufC8* result = NULL;
+
+ TInt paramIndex = 0;
+ const TAiwGenericParam* paramData =
+ aInParamList.FindFirst( paramIndex, aParamId );
+
+ if ( paramData && paramData->Value().AsData().Ptr() )
+ {
+ result = paramData->Value().AsData().AllocL();
+ }
+ else if ( paramData && paramData->Value().AsDes().Ptr() )
+ {
+ // Data was given as 16-bit, transform it into 8-bit
+ const TInt size( paramData->Value().AsDes().Size() );
+ result = HBufC8::NewL( size );
+ result->Des().Copy( paramData->Value().AsDes() );
+ }
+
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::PackParameterToBuffer16L
+// --------------------------------------------------------------------------
+//
+HBufC16* CPbk2AiwAssignProvider::PackParameterToBuffer16L
+ ( TGenericParamId aParamId,
+ const CAiwGenericParamList& aInParamList ) const
+ {
+ HBufC16* result = NULL;
+
+ TInt paramIndex = 0;
+ const TAiwGenericParam* paramData =
+ aInParamList.FindFirst(paramIndex, aParamId);
+
+ if ( paramData && paramData->Value().AsData().Ptr() )
+ {
+ // Data was given as 8-bit, transform it into 16-bit
+ const TInt size( paramData->Value().AsData().Size() );
+ result = HBufC::NewL( size );
+ result->Des().Copy( paramData->Value().AsData() );
+ }
+ else if ( paramData && paramData->Value().AsDes().Ptr() )
+ {
+ result = paramData->Value().AsDes().AllocL();
+ }
+
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::PackSelectorToBufferL
+// --------------------------------------------------------------------------
+//
+HBufC8* CPbk2AiwAssignProvider::PackSelectorToBufferL
+ ( const CAiwGenericParamList& aInParamList ) const
+ {
+ HBufC8* result = NULL;
+
+ TInt resourceId = SelectSelectorResourceIdFromParams( aInParamList );
+ if ( resourceId != KErrNotFound )
+ {
+ // Construct a resource buffer pointed to
+ // VPBK_FIELD_TYPE_SELECTOR resource, which will
+ // contain the suitable fields for the passed data
+ RFs fs;
+ User::LeaveIfError( fs.Connect() );
+ CleanupClosePushL( fs );
+
+ RPbk2LocalizedResourceFile resFile =
+ RPbk2LocalizedResourceFile( &fs );
+ resFile.OpenLC( KPbk2RomFileDrive,
+ KDC_RESOURCE_FILES_DIR, KPbk2UiServicesDllResFileName );
+ result = resFile.AllocReadLC( resourceId );
+ CleanupStack::Pop(); // result
+ CleanupStack::PopAndDestroy(2); // resFile, fs
+ }
+
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::PackFilterToBufferL
+// --------------------------------------------------------------------------
+//
+HBufC8* CPbk2AiwAssignProvider::PackFilterToBufferL
+ ( const CAiwGenericParamList& aInParamList ) const
+ {
+ HBufC8* result = NULL;
+
+ TInt resourceId = SelectFilterResourceIdFromParams( aInParamList );
+ if ( resourceId != KErrNotFound )
+ {
+ // Construct a resource buffer pointed to
+ // VPBK_FIELD_TYPE_SELECTOR resource, which will
+ // contain the suitable fields for the passed data
+ RFs fs;
+ User::LeaveIfError( fs.Connect() );
+ CleanupClosePushL( fs );
+
+ RPbk2LocalizedResourceFile resFile =
+ RPbk2LocalizedResourceFile( &fs );
+ resFile.OpenLC( KPbk2RomFileDrive,
+ KDC_RESOURCE_FILES_DIR, KPbk2UiControlsDllResFileName );
+ result = resFile.AllocReadLC( resourceId );
+ CleanupStack::Pop(); // result
+ CleanupStack::PopAndDestroy(2); // resFile, fs
+ }
+
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::CreateDataPackageL
+// --------------------------------------------------------------------------
+//
+void CPbk2AiwAssignProvider::CreateDataPackageL
+ ( const CAiwGenericParamList& aInParamList,
+ const TGenericParamId aSemanticId )
+ {
+ // MIME type
+ HBufC8* mimeTypeBuffer = PackParameterToBufferL
+ ( EGenericParamMIMEType, aInParamList );
+ CleanupStack::PushL( mimeTypeBuffer );
+
+ // The data to assign, if any
+ HBufC16* dataBuffer = NULL;
+ HBufC16* indexBuffer = NULL;
+ if ( aSemanticId == EGenericParamXSpId)
+ {
+ dataBuffer = PackImppParametersToBufferL(aInParamList);
+ }
+ else if ( aSemanticId == EGenericParamContactItem )
+ {
+ // TODO: get index from aInParamList AsTInt32()
+ indexBuffer = PackParameterToBuffer16L( aSemanticId, aInParamList );
+ }
+ else if ( aSemanticId != EGenericParamUnspecified )
+ {
+ dataBuffer = PackParameterToBuffer16L( aSemanticId, aInParamList );
+ }
+ CleanupStack::PushL( dataBuffer );
+ CleanupStack::PushL( indexBuffer );
+
+ TInt length = Pbk2IPCPackage::CountPackageSize( mimeTypeBuffer );
+ length += Pbk2IPCPackage::CountPackageSize( dataBuffer );
+ length += Pbk2IPCPackage::CountPackageSize( indexBuffer );
+
+ delete iDataPackage;
+ iDataPackage = NULL;
+ iDataPackage = HBufC8::NewL( length );
+ TPtr8 bufferPtr( iDataPackage->Des() );
+
+ RDesWriteStream writeStream( bufferPtr );
+ writeStream.PushL();
+ Pbk2IPCPackage::ExternalizeL( mimeTypeBuffer, writeStream );
+ Pbk2IPCPackage::ExternalizeL( dataBuffer, writeStream );
+ Pbk2IPCPackage::ExternalizeL( indexBuffer, writeStream );
+ writeStream.CommitL();
+
+ CleanupStack::PopAndDestroy( &writeStream );
+ CleanupStack::PopAndDestroy( 3 ); // dataBuffer, mimeTypeBuffer, indexbuffer
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::CreateAttributePackageL
+// --------------------------------------------------------------------------
+//
+TPbk2AttributeAssignData CPbk2AiwAssignProvider::CreateAttributePackageL
+ ( const CAiwGenericParamList& aInParamList,
+ const TGenericParamId aSemanticId )
+ {
+ TPbk2AttributeAssignData ret;
+ ret.iAttributeUid = TUid::Uid( KEPOCNullUID );
+ ret.iAttributeValue = KErrNotFound;
+
+ switch ( aSemanticId )
+ {
+ case EGenericParamSpeedDialIndex:
+ {
+ TInt speedDialIndex = KErrNotFound;
+ TInt paramIndex = 0;
+
+ const TAiwGenericParam* paramData =
+ aInParamList.FindFirst( paramIndex, aSemanticId );
+
+ if ( paramData )
+ {
+ speedDialIndex = paramData->Value().AsTInt32();
+ }
+
+ ret.iAttributeUid =
+ TUid::Uid( KVPbkSpeedDialAttributeImplementationUID );
+ ret.iAttributeValue = speedDialIndex;
+ break;
+ }
+
+ default:
+ {
+ __ASSERT_DEBUG( EFalse, Panic( EInvalidArgument ) );
+ break;
+ }
+ };
+
+ return ret;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::CreateConfigurationPackageL
+// --------------------------------------------------------------------------
+//
+void CPbk2AiwAssignProvider::CreateConfigurationPackageL
+ ( const CAiwGenericParamList& aInParamList )
+ {
+ // Store URIs
+ HBufC8* storeUriBuffer = PackParameterToBufferL
+ ( EGenericParamContactStoreUriArray, aInParamList );
+ CleanupStack::PushL( storeUriBuffer );
+
+ // Contact links
+ HBufC8* linkBuffer = PackParameterToBufferL
+ ( EGenericParamContactLinkArray, aInParamList );
+ CleanupStack::PushL( linkBuffer );
+
+ // Field type selector
+ HBufC8* selectorBuffer = PackSelectorToBufferL( aInParamList );
+ CleanupStack::PushL( selectorBuffer );
+
+ // Contact view filter
+ HBufC8* viewFilterBuffer = PackFilterToBufferL( aInParamList );
+ CleanupStack::PushL( viewFilterBuffer );
+
+ // Title pane
+ HBufC* titlePaneText = ClientTitlePaneL();
+ CleanupStack::PushL( titlePaneText );
+
+ HBufC* orientationType = ClientOrientation();
+ CleanupStack::PushL( orientationType );
+ TInt length = Pbk2IPCPackage::CountPackageSize( storeUriBuffer );
+ length += Pbk2IPCPackage::CountPackageSize( linkBuffer );
+ length += Pbk2IPCPackage::CountPackageSize( selectorBuffer );
+ length += Pbk2IPCPackage::CountPackageSize( viewFilterBuffer );
+ length += Pbk2IPCPackage::CountPackageSize( titlePaneText );
+ length += Pbk2IPCPackage::CountPackageSize( orientationType );
+
+ delete iConfigurationPackage;
+ iConfigurationPackage = NULL;
+ iConfigurationPackage = HBufC8::NewL( length );
+ TPtr8 bufferPtr( iConfigurationPackage->Des() );
+
+ RDesWriteStream writeStream( bufferPtr );
+ writeStream.PushL();
+ Pbk2IPCPackage::ExternalizeL( storeUriBuffer, writeStream );
+ Pbk2IPCPackage::ExternalizeL( linkBuffer, writeStream );
+ Pbk2IPCPackage::ExternalizeL( selectorBuffer, writeStream );
+ Pbk2IPCPackage::ExternalizeL( viewFilterBuffer, writeStream );
+ Pbk2IPCPackage::ExternalizeL( titlePaneText, writeStream );
+ Pbk2IPCPackage::ExternalizeL( orientationType, writeStream );
+ writeStream.CommitL();
+
+ CleanupStack::PopAndDestroy( &writeStream );
+ CleanupStack::PopAndDestroy( 6 ); // orientationType, titlePaneText,
+ // viewFilterBuffer, selectorBuffer,
+ // linkBuffer, storeUriBuffer
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::CreateInstructionPackageL
+// --------------------------------------------------------------------------
+//
+void CPbk2AiwAssignProvider::CreateInstructionPackageL
+ ( const CAiwGenericParamList& aInParamList )
+ {
+ delete iInstructionsPackage;
+ iInstructionsPackage = NULL;
+ iInstructionsPackage = PackParameterToBufferL
+ ( EGenericParamContactAssignData, aInParamList );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::ValidateInstructionPackageL
+// --------------------------------------------------------------------------
+//
+void CPbk2AiwAssignProvider::ValidateInstructionPackageL()
+ {
+ if ( iInstructionsPackage )
+ {
+ // Version check
+ TInt version = TAiwContactAssignDataBase::
+ AssignDataTypeFromBuffer( *iInstructionsPackage );
+ if ( version == EAiwContactAssignDataTypeNotDefined )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ switch( version )
+ {
+ case EAiwSingleContactAssignV1:
+ {
+ // Nothing to validate since for example editor can be
+ // on/off and similarly with new contact creation both
+ // choises on/off are supported
+ break;
+ }
+
+ case EAiwMultipleContactAssignV1:
+ {
+ TAiwMultipleContactAssignDataV1Pckg dataPckg;
+
+ // Reconstruct the instructions
+ dataPckg.Copy( iInstructionsPackage->Ptr(),
+ sizeof( TAiwMultipleContactAssignDataV1 ) );
+
+ // Multi assign does not support new contact
+ // creation nor does it support contact editor,
+ // so disable those
+ TUint flags = dataPckg().Flags();
+ flags &= ~ECreateNewContact;
+ flags |= EDoNotOpenEditor;
+ dataPckg().SetFlags( flags );
+
+ delete iInstructionsPackage;
+ iInstructionsPackage = NULL;
+ iInstructionsPackage = dataPckg.AllocL();
+ break;
+ }
+
+ case EAiwContactAttributeAssignV1:
+ {
+ TAiwContactAttributeAssignDataV1Pckg dataPckg;
+
+ // Reconstruct the instructions
+ dataPckg.Copy( iInstructionsPackage->Ptr(),
+ sizeof( TAiwContactAttributeAssignDataV1 ) );
+
+ // Attribute assign does not support new contact
+ // creation nor does it support contact editor,
+ // so disable those
+ TUint flags = dataPckg().Flags();
+ flags &= ~ECreateNewContact;
+ flags |= EDoNotOpenEditor;
+ dataPckg().SetFlags( flags );
+
+ delete iInstructionsPackage;
+ iInstructionsPackage = NULL;
+ iInstructionsPackage = dataPckg.AllocL();
+ break;
+ }
+
+ default:
+ {
+ __ASSERT_DEBUG( EFalse, Panic( EDataTypeNotSupported ) );
+ break;
+ }
+ }
+
+ }
+
+ // If client does not give instructions then default
+ // to multiple contact assign
+ if ( !iInstructionsPackage )
+ {
+ TAiwMultipleContactAssignDataV1Pckg dataPckg;
+ iInstructionsPackage = dataPckg.AllocL();
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::ValidateMenuServiceL
+// --------------------------------------------------------------------------
+//
+void CPbk2AiwAssignProvider::ValidateMenuServiceL( const TInt& aCmdId )
+ {
+ // Version check
+ TInt version = TAiwContactAssignDataBase::
+ AssignDataTypeFromBuffer( *iInstructionsPackage );
+ if ( version == EAiwContactAssignDataTypeNotDefined )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ switch ( aCmdId )
+ {
+ case EPbk2AiwCmdAssign:
+ {
+ // Nothing to validate
+ break;
+ }
+
+ case EPbk2AiwCmdDataSaveCreateNew:
+ {
+ // Create new supports only single contact assign
+ if ( version != EAiwSingleContactAssignV1 )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ TAiwSingleContactAssignDataV1Pckg dataPckg;
+ // Reconstruct the instructions
+ dataPckg.Copy( iInstructionsPackage->Ptr(),
+ sizeof( TAiwSingleContactAssignDataV1 ) );
+ TUint flags = dataPckg().Flags();
+ // Make sure the Create New Contact flag is up
+ flags |= ECreateNewContact;
+ dataPckg().SetFlags( flags );
+
+ delete iInstructionsPackage;
+ iInstructionsPackage = NULL;
+ iInstructionsPackage = dataPckg.AllocL();
+ break;
+ }
+
+ case EPbk2AiwCmdDataSaveAddToExisting:
+ {
+ // Update existing can be done to multiple contacts
+ // or to a single contact. We must take care that
+ // create new contact flag is down.
+ switch ( version )
+ {
+ case EAiwMultipleContactAssignV1:
+ {
+ TAiwMultipleContactAssignDataV1Pckg dataPckg;
+ // Reconstruct the instructions
+ dataPckg.Copy( iInstructionsPackage->Ptr(),
+ sizeof( TAiwMultipleContactAssignDataV1 ) );
+ TUint flags = dataPckg().Flags();
+ // Make sure the Create New Contact flag is down
+ flags &= ~ECreateNewContact;
+ dataPckg().SetFlags( flags );
+
+ delete iInstructionsPackage;
+ iInstructionsPackage = NULL;
+ iInstructionsPackage = dataPckg.AllocL();
+ break;
+ }
+ case EAiwSingleContactAssignV1:
+ {
+ TAiwSingleContactAssignDataV1Pckg dataPckg;
+ // Reconstruct the instructions
+ dataPckg.Copy( iInstructionsPackage->Ptr(),
+ sizeof( TAiwSingleContactAssignDataV1 ) );
+ TUint flags = dataPckg().Flags();
+ // Make sure the Create New Contact flag is down
+ flags &= ~ECreateNewContact;
+ dataPckg().SetFlags(flags);
+
+ delete iInstructionsPackage;
+ iInstructionsPackage = NULL;
+ iInstructionsPackage = dataPckg.AllocL();
+ break;
+ }
+ default:
+ {
+ __ASSERT_DEBUG( EFalse, Panic( EDataTypeNotSupported ) );
+ break;
+ }
+ };
+
+ break;
+ }
+
+ default:
+ {
+ // Service was used from client applications own menu
+ // or as a base service. Nothing to do.
+ break;
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::ClientTitlePaneL
+// --------------------------------------------------------------------------
+//
+HBufC* CPbk2AiwAssignProvider::ClientTitlePaneL()
+ {
+ HBufC* result = NULL;
+
+ CEikStatusPane* statusPane =
+ CEikonEnv::Static()->AppUiFactory()->StatusPane();
+
+ if ( statusPane &&
+ statusPane->PaneCapabilities(
+ TUid::Uid( EEikStatusPaneUidTitle ) ).IsPresent() )
+ {
+ CAknTitlePane* titlePane = static_cast<CAknTitlePane*>( statusPane->
+ ControlL( TUid::Uid( EEikStatusPaneUidTitle ) ) );
+
+ if ( titlePane->Text() )
+ {
+ result = titlePane->Text()->AllocL();
+ }
+ }
+
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::ClientOrientation
+// --------------------------------------------------------------------------
+//
+HBufC* CPbk2AiwAssignProvider::ClientOrientation() const
+ {
+ HBufC* result = NULL;
+
+ CAknViewAppUi* appUi = static_cast<CAknViewAppUi*> ( CEikonEnv::Static()->EikAppUi() );
+
+ if( appUi )
+ {
+ TInt orientationType = appUi->Orientation();
+ result = HBufC::New( sizeof(orientationType) );
+ TPtr resultPtr = result->Des();
+ resultPtr.Num( orientationType );
+ }
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::LaunchAttributeAssignL
+// --------------------------------------------------------------------------
+//
+inline void CPbk2AiwAssignProvider::LaunchAttributeAssignL
+ ( const CAiwGenericParamList& aInParamList,
+ const TGenericParamId aSemanticId )
+ {
+ iAttributeData =
+ CreateAttributePackageL( aInParamList, aSemanticId );
+
+ // Check does the client want to assign attribute,
+ // or does it want to unassign instead
+ TAiwContactAttributeAssignDataV1Pckg data;
+ data.Copy( *iInstructionsPackage );
+ TBool unassign = data().RemoveAttribute();
+
+ if ( !unassign )
+ {
+ // Launch assign
+ iConnection->LaunchAttributeAssignL
+ ( iConfigurationPackage, iAttributeData, iInstructionsPackage );
+ }
+ else
+ {
+ // Unassign service requires that contact links are also being sent
+ // to the server
+ if ( !FindSemanticId
+ ( aInParamList, EGenericParamContactLinkArray ) )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ // Launch unassign
+ iConnection->LaunchAttributeUnassignL
+ ( iConfigurationPackage, iAttributeData, iInstructionsPackage );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::LaunchDataAssignL
+// --------------------------------------------------------------------------
+//
+inline void CPbk2AiwAssignProvider::LaunchDataAssignL
+ ( const CAiwGenericParamList& aInParamList,
+ const TGenericParamId aSemanticId )
+ {
+ CreateDataPackageL( aInParamList, aSemanticId );
+
+ // Launch
+ iConnection->LaunchAssignL
+ ( iConfigurationPackage, iDataPackage, iInstructionsPackage );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2AiwAssignProvider::PackImppParametersToBuffer
+// --------------------------------------------------------------------------
+//
+HBufC* CPbk2AiwAssignProvider::PackImppParametersToBufferL(
+ const CAiwGenericParamList& aInParamList)
+ {
+ _LIT(KSeparator, "\n");
+ const TInt KParamsCount = 4;
+ TGenericParamId paramId[KParamsCount] = {EGenericParamXSpId,
+ EGenericParamFirstName, EGenericParamLastName,
+ EGenericParamNickname};
+ TPtrC params[KParamsCount] = {TPtrC(), TPtrC(), TPtrC(), TPtrC()};
+ HBufC* paramsBuf[KParamsCount] = {NULL, NULL, NULL, NULL};
+
+ TInt i = 0;
+ TInt separators = 0;
+ TInt length = 0;
+ // read all parameters
+ for (; i < KParamsCount; i++)
+ {
+ TInt paramIndex = 0;
+ const TAiwGenericParam* paramData =
+ aInParamList.FindFirst(paramIndex, paramId[i]);
+ if (paramData && paramData->Value().AsData().Ptr())
+ {
+ // Data was given as 8-bit, transform it into 16-bit
+ TPtrC8 ptr = paramData->Value().AsData();
+ paramsBuf[i] = HBufC::NewLC(ptr.Size());
+ paramsBuf[i]->Des().Copy(ptr);
+ params[i].Set(*paramsBuf[i]);
+ separators = i;
+ }
+ else if ( paramData && paramData->Value().AsDes().Ptr() )
+ {
+ params[i].Set(paramData->Value().AsDes());
+ separators = i;
+ }
+ length += params[i].Length();
+ }
+
+ HBufC* result = HBufC::NewL(length+separators);
+ TPtr ptr = result->Des();
+ // now separators will be used to count fields
+ // but fields is one more than separators
+ separators++;
+ // create parameter string for server
+ for (i = 0; i < separators; i++)
+ {
+ if (i)
+ {
+ ptr.Append(KSeparator);
+ }
+ ptr.Append(params[i]);
+ }
+
+ // clean cleanup stack
+ for (i = KParamsCount-1; i >= 0; i--)
+ {
+ if (paramsBuf[i])
+ {
+ CleanupStack::PopAndDestroy(paramsBuf[i]);
+ }
+ }
+
+ return result;
+ }
+
+// End of File