/*
* 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