--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/CommandsExtension/src/CPbk2SendContactCmd.cpp Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,1262 @@
+/*
+* 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 send contact command.
+*
+*/
+
+
+#include "CPbk2SendContactCmd.h"
+
+// Phonebook 2
+#include "Pbk2SendCmdUtils.h"
+#include "CPbk2vCardConverter.h"
+#include <MPbk2CommandObserver.h>
+#include <Pbk2Commands.rsg>
+#include <Pbk2CmdExtRes.rsg>
+#include <Pbk2ProcessDecoratorFactory.h>
+#include <MPbk2ProcessDecorator.h>
+#include <MPbk2ContactLinkIterator.h>
+#include <CPbk2AttachmentFile.h>
+#include <CPbk2DriveSpaceCheck.h>
+#include <CPbk2AppUiBase.h>
+#include <CPbk2ApplicationServices.h>
+
+// Virtual Phonebook
+#include <CVPbkContactManager.h>
+#include <CVPbkContactLinkArray.h>
+#include <CVPbkVCardEng.h>
+#include <MVPbkContactOperationBase.h>
+#include <MPbk2ContactUiControl.h>
+#include <MVPbkStoreContactFieldCollection.h>
+#include <MVPbkStoreContact.h>
+#include <MVPbkFieldType.h>
+#include <TVPbkFieldTypeMapping.h>
+#include <VPbkEng.rsg>
+
+// System includes
+#include <txtrich.h>
+#include <barsread.h>
+#include <AknWaitDialog.h>
+#include <sendui.h>
+#include <TSendingCapabilities.h>
+#include <MsgBioUids.h>
+#include <SendUiConsts.h>
+#include <eikenv.h>
+#include <CMessageData.h>
+#include <eikclb.h>
+#include <aknPopup.h>
+#include <featmgr.h>
+
+// Debugging headers
+#include <Pbk2Debug.h>
+
+/// Unnamed namespace for local definitions
+namespace {
+
+const TUint KNoMenu = 0;
+const TInt KGranularity( 4 );
+
+struct TPbk2SelectionMapping
+ {
+ /// Maps to first selection
+ TPbk2SendvCardChoiceItemEnumerations iStSelection;
+ /// Maps to second selection
+ TPbk2SendvCardChoiceItemEnumerations iNdSelection;
+ /// Maps to third selection
+ TPbk2SendvCardChoiceItemEnumerations iRdSelection;
+ //// Resource id
+ TInt iResId;
+ };
+
+enum TSelection
+ {
+ ESelectionLast = -1
+ };
+
+/// Maps listbox index selections to 'sending selected detail'
+/// menu selections If command not supported selection is ECancel.
+static const TPbk2SelectionMapping SelectionMapping[] =
+ {
+ {ESendCurrentItem, ESendAllData, ECancel,
+ R_PBK2_CONTACTINFO_SEND_OPTIONS},
+ {ESendCurrentItem, ESendAllDataWithoutPicture, ESendAllData,
+ R_PBK2_CONTACTINFO_SEND_OPTIONS_SMS_THUMBNAIL},
+ {ESendAllDataWithoutPicture, ESendAllData, ECancel,
+ R_PBK2_CONTACTINFO_SEND_OPTIONS_SMS_THUMBNAIL_NO_FIELD},
+ {ESendAllDataWithoutPicture, ESendAllData, ECancel,
+ R_PHONEBOOK2_SEND_OPTIONS},
+ {ECancel, ECancel, ECancel, ESelectionLast}
+ };
+
+
+/// Represents the different listbox index selections.
+enum TPbk2ListBoxSelections
+ {
+ EFirstSelection = 0,
+ ESecondSelection,
+ EThirdSelection
+ };
+
+#if 0 // Not used in ECE
+/**
+ Function checks if the focused field is one of these fields.
+
+ - Prefix
+ - Suffix
+ - Firstname
+ JAPANESE.PRONOUNCIATION{
+ - FirstnameReading
+ }JAPANESE.PRONOUNCIATION
+ - Middle name
+ - Lastname
+ JAPANESE.PRONOUNCIATION{
+ - Last name Reading
+ }JAPANESE.PRONOUNCIATION
+ - Ringing tone
+ CALL.OBJECT.DISPLAY{
+ - Image
+ }CALL.OBJECT.DISPLAY
+ CALL.OBJECT.DISPLAY{
+ - Text for call
+ }CALL.OBJECT.DISPLAY
+ - Synchronization
+*/
+TBool IsNameOrPropertyField( const MVPbkBaseContactField& aField )
+ {
+ TBool res ( EFalse );
+ const MVPbkFieldType* fieldType = aField.BestMatchingFieldType();
+ if ( fieldType )
+ {
+ TInt resId( fieldType->FieldTypeResId() );
+ if ( resId == R_VPBK_FIELD_TYPE_PREFIX ||
+ resId == R_VPBK_FIELD_TYPE_SUFFIX ||
+ resId == R_VPBK_FIELD_TYPE_FIRSTNAME ||
+ resId == R_VPBK_FIELD_TYPE_FIRSTNAMEREADING ||
+ resId == R_VPBK_FIELD_TYPE_MIDDLENAME ||
+ resId == R_VPBK_FIELD_TYPE_LASTNAME ||
+ resId == R_VPBK_FIELD_TYPE_LASTNAMEREADING ||
+ resId == R_VPBK_FIELD_TYPE_RINGTONE ||
+ resId == R_VPBK_FIELD_TYPE_CALLEROBJIMG ||
+ resId == R_VPBK_FIELD_TYPE_CALLEROBJTEXT ||
+ resId == R_VPBK_FIELD_TYPE_SYNCCLASS )
+ {
+ res = ETrue;
+ }
+ }
+ return res;
+ }
+#endif // 0
+
+#ifdef _DEBUG
+
+enum TPanicCode
+ {
+ EPanicPreCond_SendvCardsL = 1,
+ EPanicLogic_CmdSendContactDataL,
+ EPanicLogic_MapSelection,
+ EPanicLogic_ConversionDone,
+ EPanicLogic_ReadFileTypeL,
+ ERunL_OOB,
+ EPanicPreCond_ErrArgument,
+ EResetFindResult
+ };
+
+void Panic(TPanicCode aReason)
+ {
+ _LIT(KPanicText, "CPbk2SendContactCmd");
+ User::Panic(KPanicText,aReason);
+ }
+
+#endif // _DEBUG
+
+
+/**
+ * Helper class for sending the vCard(s) in async callback.
+ */
+NONSHARABLE_CLASS(CVCardSender) : public CIdle
+ {
+ public: // Constructor
+
+ /**
+ * Creates a new instance of this object.
+ *
+ * @param aPriority Desired priority.
+ */
+ static CVCardSender* NewL(
+ TInt aPriority );
+
+ private: // From CIdle
+ void RunL();
+ TInt RunError(
+ TInt aError );
+
+ private: // Implementation
+ CVCardSender(
+ TInt aPriority );
+ };
+
+// --------------------------------------------------------------------------
+// CVCardSender::CVCardSender
+// --------------------------------------------------------------------------
+//
+inline CVCardSender::CVCardSender( TInt aPriority ):
+ CIdle( aPriority )
+ {
+ CActiveScheduler::Add( this );
+ }
+
+// --------------------------------------------------------------------------
+// CVCardSender::NewL
+// --------------------------------------------------------------------------
+//
+CVCardSender* CVCardSender::NewL( TInt aPriority )
+ {
+ return new ( ELeave ) CVCardSender( aPriority );
+ }
+
+// --------------------------------------------------------------------------
+// CVCardSender::RunL
+// --------------------------------------------------------------------------
+//
+void CVCardSender::RunL()
+ {
+ CIdle::RunL();
+ // Destroy self.
+ // If RunL (the callback) leaves RunError will handle the deletion.
+ delete this;
+ }
+
+// --------------------------------------------------------------------------
+// CVCardSender::RunError
+// --------------------------------------------------------------------------
+//
+TInt CVCardSender::RunError( TInt aError)
+ {
+ delete this;
+ // Forward all errors to the active scheduler
+ return aError;
+ }
+
+/**
+ * Creates a rich text object and packages contents of a file to it.
+ * The file's data is not converted in any way except that characters
+ * are widened to 16 bits.
+ *
+ * @param aEikEnv EIKON environment.
+ * @param aFileName Name of the file to convert.
+ * @return A new rich text object with file's contents.
+ * The returned object is also left on top of the cleanup stack.
+ */
+CRichText* CreateRichTextFromFileLC
+ (CEikonEnv& aEikEnv, const TDesC& aFileName)
+ {
+ PBK2_DEBUG_PRINT
+ (PBK2_DEBUG_STRING("CreateRichTextFromFileLC (%S)"), &aFileName);
+ // Common allocation granularity and buffer size for rich text and
+ // file reading
+ const TInt KBufSize = CEditableText::EDefaultTextGranularity;
+
+ // Create a rich text object with default formatting
+ CRichText* richText = CRichText::NewL(
+ aEikEnv.SystemParaFormatLayerL(),
+ aEikEnv.SystemCharFormatLayerL(),
+ CEditableText::ESegmentedStorage,
+ KBufSize // Allocation granularity
+ );
+ CleanupStack::PushL(richText);
+
+ // Open the file for reading
+ RFile file;
+ User::LeaveIfError(file.Open
+ (aEikEnv.FsSession(), aFileName,
+ EFileRead|EFileStream|EFileShareReadersOnly));
+ CleanupClosePushL(file);
+
+ // Create two buffers: 8-bit for reading from file and 16-bit for
+ // converting to 16-bit format
+ HBufC8* buf8 = HBufC8::NewLC(KBufSize);
+ TPtr8 ptr8 = buf8->Des();
+ HBufC16* buf16 = HBufC16::NewLC(ptr8.MaxLength());
+ TPtr16 ptr16 = buf16->Des();
+
+ // Read, convert and append to rich text until the file ends
+ for (TInt err = file.Read(ptr8);
+ ptr8.Length() > 0;
+ err = file.Read(ptr8))
+ {
+ User::LeaveIfError(err);
+ ptr16.Copy(ptr8);
+ richText->InsertL(richText->DocumentLength(), ptr16);
+ }
+
+ // Cleanup and return
+ CleanupStack::PopAndDestroy(3); // buf16, buf8, file
+ PBK2_DEBUG_PRINT
+ (PBK2_DEBUG_STRING("CreateRichTextFromFileLC, end"));
+ return richText;
+ }
+
+} /// namespace
+
+/**
+ * Sending parameters.
+ */
+class TPbk2SendingParams
+ {
+ public: // Construction and destruction
+
+ /**
+ * Constructor.
+ *
+ * @param aMtmFilter MTM filter
+ * @param aCapabilities Sending capabilities.
+ */
+ TPbk2SendingParams(
+ CArrayFixFlat<TUid>* aMtmFilter,
+ TSendingCapabilities aCapabilities );
+
+ public: // Data
+ /// Ref: MTM filter
+ CArrayFixFlat<TUid>* iMtmFilter;
+ /// Own: Sending capabilities
+ TSendingCapabilities iCapabilities;
+ };
+
+// --------------------------------------------------------------------------
+// TPbk2SendingParams::TPbk2SendingParams
+// --------------------------------------------------------------------------
+//
+inline TPbk2SendingParams::TPbk2SendingParams
+ ( CArrayFixFlat<TUid>* aMtmFilter,
+ TSendingCapabilities aCapabilities ) :
+ iMtmFilter( aMtmFilter ), iCapabilities( aCapabilities )
+ {
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::CPbk2SendContactCmd
+// --------------------------------------------------------------------------
+//
+inline CPbk2SendContactCmd::CPbk2SendContactCmd(
+ MPbk2ContactUiControl& aUiControl ) :
+ CActive(EPriorityIdle),
+ iUiControl(&aUiControl)
+ {
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::~CPbk2SendContactCmd
+// --------------------------------------------------------------------------
+//
+CPbk2SendContactCmd::~CPbk2SendContactCmd()
+ {
+ PBK2_DEBUG_PRINT
+ (PBK2_DEBUG_STRING("CPbk2SendContactCmd, destructor (0x%x)"), this);
+ Cancel();
+ if( iUiControl )
+ {
+ iUiControl->RegisterCommand( NULL );
+ }
+
+ delete iSelectedContacts;
+ delete iConverter;
+ delete iVCardSender;
+ delete iVCardEngine;
+ iStoreContacts.ResetAndDestroy();
+ iStoreContacts.Close();
+ delete iRetrieveOperation;
+ delete iDecorator;
+ delete iCntIterator;
+ delete iSendUi;
+ Release( iAppServices );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::NewL
+// --------------------------------------------------------------------------
+//
+CPbk2SendContactCmd* CPbk2SendContactCmd::NewL
+ (MPbk2ContactUiControl& aUiControl)
+ {
+ CPbk2SendContactCmd* self = new (ELeave)CPbk2SendContactCmd(aUiControl);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::ConstructL
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::ConstructL()
+ {
+ PBK2_DEBUG_PRINT
+ (PBK2_DEBUG_STRING("CPbk2SendContactCmd::ConstructL(0x%x)"), this);
+ CActiveScheduler::Add(this);
+ CPbk2DriveSpaceCheck* driveSpaceCheck = CPbk2DriveSpaceCheck::NewL
+ ( CCoeEnv::Static()->FsSession() );
+ CleanupStack::PushL( driveSpaceCheck );
+ // check FFS situation
+ driveSpaceCheck->DriveSpaceCheckL();
+ CleanupStack::PopAndDestroy( driveSpaceCheck );
+ iEikEnv = CEikonEnv::Static();
+ iAppServices = CPbk2ApplicationServices::InstanceL();
+ iVCardEngine = CVPbkVCardEng::NewL( iAppServices->ContactManager() );
+ iConverter = CPbk2vCardConverter::NewL(
+ iEikEnv->FsSession(),
+ iAppServices->ContactManager(),
+ *iVCardEngine,
+ iAppServices->NameFormatter() );
+ iVCardSender = CVCardSender::NewL(CActive::EPriorityIdle);
+ iSendUi = CSendUi::NewL();
+
+ if( iUiControl )
+ {
+ // Use iterator to make sure that OOM situation does not occur
+ // if multiple contacts selected.
+ iCntIterator = iUiControl->SelectedContactsIteratorL();
+ if ( !iCntIterator )
+ {
+ // If no iterator, there is no selected contacts.
+ // Only one contact is returned.
+ iSelectedContacts = iUiControl->SelectedContactsOrFocusedContactL();
+ }
+ iFocusedField = iUiControl->FocusedField();
+ iUiControl->RegisterCommand( this );
+ }
+ PBK2_DEBUG_PRINT
+ (PBK2_DEBUG_STRING("CPbk2SendContactCmd::ConstructL, end"));
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::ExecuteLD
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::ExecuteLD()
+ {
+ PBK2_DEBUG_PRINT
+ (PBK2_DEBUG_STRING("CPbk2SendContactCmd::ExecuteLD(0x%x)"), this);
+
+ CleanupStack::PushL(this);
+
+ iCurrentContactLinkIndex = 0;
+ iState = EShowingSendQuery;
+ IssueRequest();
+
+ CleanupStack::Pop(this);
+ PBK2_DEBUG_PRINT
+ (PBK2_DEBUG_STRING("CPbk2SendContactCmd::ExecuteLD, end"), this);
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::AddObserver
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::AddObserver(MPbk2CommandObserver& aObserver)
+ {
+ iCommandObserver = &aObserver;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::ResetUiControl
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::ResetUiControl(
+ MPbk2ContactUiControl& aUiControl)
+ {
+ if (iUiControl == & aUiControl)
+ {
+ iUiControl = NULL;
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::RunL
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::RunL()
+ {
+ switch (iState)
+ {
+ case EShowingSendQuery:
+ {
+ iMtmUid = ShowSendQueryL();
+ if (iMtmUid == KNullUid)
+ {
+ iState = ECancelling;
+ }
+ else
+ {
+ iState = ERetrievingContact;
+ }
+ IssueRequest();
+ break;
+ }
+
+ case ERetrievingContact:
+ {
+ if ( iSelectedContacts )
+ {
+ __ASSERT_DEBUG( iSelectedContacts->Count() >
+ iCurrentContactLinkIndex, Panic( ERunL_OOB ) );
+ RetrieveContactL(iSelectedContacts->At
+ (iCurrentContactLinkIndex));
+ }
+ else
+ {
+ iState = ESelectingSentData;
+ IssueRequest();
+ }
+ break;
+ }
+
+ case ESelectingSentData:
+ {
+ TInt selection(ESendAllData);
+ if ( iSelectedContacts )
+ {
+ // If there is only one contact or launched in info view
+ // do the data selection
+ selection = SelectSentDataL();
+ }
+ ConvertContactL(selection);
+ break;
+ }
+
+ case EStopping:
+ {
+ ProcessDone(KErrNone);
+ break;
+ }
+
+ case ECancelling:
+ {
+ ProcessDone( KErrCancel );
+ break;
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::RunError
+// --------------------------------------------------------------------------
+//
+TInt CPbk2SendContactCmd::RunError(TInt aError)
+ {
+ return FilterErrors(aError);
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::DoCancel
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::DoCancel()
+ {
+ delete iRetrieveOperation;
+ iRetrieveOperation = NULL;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::ConversionDone
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::ConversionDone( TInt PBK2_DEBUG_ONLY( aCount ) )
+ {
+ PBK2_DEBUG_PRINT
+ ( PBK2_DEBUG_STRING( "CPbk2SendContactCmd::ConversionDone(0x%x)" ),
+ this );
+
+ __ASSERT_DEBUG( iStoreContacts.Count() == aCount,
+ Panic( EPanicLogic_ConversionDone ) );
+
+ // Decorator will call processdismissed which will continue
+ // contact send
+ iDecorator->ProcessStopped();
+
+ PBK2_DEBUG_PRINT( PBK2_DEBUG_STRING
+ ( "CPbk2SendContactCmd::ConversionDone(0x%x), end" ), this );
+
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::ConversionError
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::ConversionError(TInt aError)
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2SendContactCmd::ConversionError(%d)"), aError);
+
+ // Report the failure to the user
+ CCoeEnv::Static()->HandleError( aError );
+
+ // iDecorator calls processdismissed
+ iDecorator->ProcessStopped();
+ iState = EStopping;
+
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2SendContactCmd::ConversionError(0x%x), end"), this);
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::VPbkSingleContactOperationComplete
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::VPbkSingleContactOperationComplete(
+ MVPbkContactOperationBase& aOperation, MVPbkStoreContact* aContact)
+ {
+ if (&aOperation == iRetrieveOperation)
+ {
+ delete iRetrieveOperation;
+ iRetrieveOperation = NULL;
+
+ // We now have a store contact
+ TInt error = iStoreContacts.Append(aContact);
+ if ( error == KErrNone )
+ {
+ ++iCurrentContactLinkIndex;
+ if (iSelectedContacts->Count() == iCurrentContactLinkIndex)
+ {
+ iCurrentContactLinkIndex = 0;
+ iState = ESelectingSentData;
+ }
+ else
+ {
+ iState = ERetrievingContact;
+ }
+
+ IssueRequest();
+ }
+ else
+ {
+ ProcessDone( error );
+ }
+ }
+ else
+ {
+ IssueStopRequest();
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::VPbkSingleContactOperationFailed
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::VPbkSingleContactOperationFailed(
+ MVPbkContactOperationBase& aOperation, TInt aError)
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2SendContactCmd::VPbkSingleContactOperationFailed (%d)"), aError);
+ if (&aOperation == iRetrieveOperation)
+ {
+ delete iRetrieveOperation;
+ iRetrieveOperation = NULL;
+
+ // We cannot get the contact, so we have to
+ // fail. We cannot continue, since this operation
+ // was executed only in case of one contact.
+ ProcessDone(aError);
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::SendvCardsLD
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::SendvCardsLD()
+ {
+ PBK2_DEBUG_PRINT
+ (PBK2_DEBUG_STRING("CPbk2SendContactCmd::SendvCardsLD(0x%x)"), this);
+ // Relinquish ownership, iVCardSender takes care of it self
+ iVCardSender = NULL;
+
+ CMessageData* messageData = CMessageData::NewL();
+ CleanupStack::PushL( messageData );
+
+ if (iConverter->FileNames().MdcaCount() > 0 &&
+ !iUnderDestruction)
+ {
+ TSendingCapabilities caps;
+ User::LeaveIfError(
+ iSendUi->ServiceCapabilitiesL( iMtmUid, caps ) );
+ if (caps.iFlags & TSendingCapabilities::ESupportsAttachments)
+ {
+ // Not sending through SMS, just pass the attachments
+ __ASSERT_DEBUG(iConverter->FileNames().MdcaCount()>=1,
+ Panic(EPanicPreCond_SendvCardsL));
+
+ //Fill message data
+ const TInt count( iConverter->FileNames().MdcaCount());
+ for( TInt i( 0 ); i < count; ++i )
+ {
+ messageData->AppendAttachmentHandleL(
+ iConverter->AttachmentFileArray().FileHandleAt( i ) );
+ }
+ SendMsgUsingSendUI(messageData);
+ }
+ else if (caps.iFlags & TSendingCapabilities::ESupportsBodyText)
+ {
+ PBK2_DEBUG_PRINT
+ (PBK2_DEBUG_STRING("SendvCardsLD, KSenduiMtmSmsUid"));
+ // Sending through SMS -> there should be only one vCard
+ // attachment. Package the attachment to a rich text object and
+ // send it as the message body.
+ __ASSERT_DEBUG(iConverter->FileNames().MdcaCount()==1,
+ Panic(EPanicPreCond_SendvCardsL));
+
+ // Copy the one and only attachment into a rich text object
+ CRichText* msgBody = CreateRichTextFromFileLC
+ (*iEikEnv, iConverter->FileNames().MdcaPoint(0));
+
+ messageData->SetBodyTextL( msgBody );
+ SendMsgUsingSendUI(messageData);
+
+ CleanupStack::PopAndDestroy(msgBody);
+ }
+ else
+ {
+ User::Leave( KErrNotSupported );
+ }
+ }
+
+ CleanupStack::PopAndDestroy(); //messageData
+
+ ProcessDone(KErrNone);
+ PBK2_DEBUG_PRINT
+ (PBK2_DEBUG_STRING("CPbk2SendContactCmd::SendvCardsLD, end"), this);
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::SendvCardsLD
+// --------------------------------------------------------------------------
+//
+TInt CPbk2SendContactCmd::SendvCardsLD(TAny* aThis)
+ {
+ __ASSERT_DEBUG( aThis, Panic(EPanicPreCond_ErrArgument) );
+
+ CPbk2SendContactCmd* self = static_cast<CPbk2SendContactCmd*>(aThis);
+ self->SendvCardsLD();
+
+ return EFalse;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::AnyThumbnailsL
+// --------------------------------------------------------------------------
+//
+TBool CPbk2SendContactCmd::AnyThumbnailsL() const
+ {
+ TInt cntCount(iStoreContacts.Count());
+
+ for (TInt i=0; i < cntCount; ++i)
+ {
+ MVPbkStoreContact* contact = (iStoreContacts)[i];
+ const MVPbkBaseContactField* field =
+ Pbk2SendCmdUtils::FindFieldL(
+ *contact,
+ R_THUMBNAIL_FIELD_TYPE,
+ iAppServices->ContactManager().FieldTypes());
+
+ if (field)
+ {
+ // We can exit the loop as soon as a thumbnail
+ // is found
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+#if 0
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::SelectionListL
+// --------------------------------------------------------------------------
+//
+TInt CPbk2SendContactCmd::SelectionListL() const
+ {
+ TInt ret( KNoMenu );
+ TBool supportsFieldType( ETrue );
+ TBool nameOrPropertyField( EFalse );
+
+ // Check is the sending media SMS and does the contact
+ // have a thumbnail
+ TBool smsAndThumbnail( EFalse );
+ if ( ( iMtmUid == KSenduiMtmSmsUid ) && AnyThumbnailsL() )
+ {
+ smsAndThumbnail = ETrue;
+ }
+
+ // If focused field is supplied, the command object was
+ // launched from contact info view and that requires
+ // we have to check is the field supported by vCard spec
+ if ( iFocusedField )
+ {
+ if ( iAppServices && ( !iVCardEngine->SupportsFieldType(
+ *Pbk2SendCmdUtils::FieldType(
+ *iFocusedField,
+ iAppServices->ContactManager().FieldTypes() ) ) ) )
+ {
+ supportsFieldType = EFalse;
+ }
+ }
+
+ // Now check the cases when the menu needs to be shown
+ // There are two main branches depending on which view
+ // this command object was launched from
+ if ( iFocusedField )
+ {
+ // Command object was launched from contact info view.
+
+ if ( !smsAndThumbnail )
+ {
+ // When there is no thumbnail involved the selection
+ // menu is shown only if we are over vCard supported
+ // field and the focus is not in the name or property field.
+ nameOrPropertyField = IsNameOrPropertyField( *iFocusedField );
+ if ( supportsFieldType && !nameOrPropertyField )
+ {
+ ret = R_PBK2_CONTACTINFO_SEND_OPTIONS;
+ }
+ }
+ else
+ {
+ // Thumbnail is involved, the selection menu depends
+ // on whether we are over vCard supported field or not
+ if ( supportsFieldType )
+ {
+ ret = R_PBK2_CONTACTINFO_SEND_OPTIONS_SMS_THUMBNAIL;
+ }
+ else
+ {
+ ret = R_PBK2_CONTACTINFO_SEND_OPTIONS_SMS_THUMBNAIL_NO_FIELD;
+ }
+ }
+ }
+ else
+ {
+ // Command object was launched from contact list view,
+ // the menu is shown only in case there is thumbnail
+ // involded and the sending media is SMS
+ if ( smsAndThumbnail )
+ {
+ ret = R_PHONEBOOK2_SEND_OPTIONS;
+ }
+ }
+
+ return ret;
+ }
+#endif
+
+#if 1
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::SelectionListL
+// --------------------------------------------------------------------------
+//
+TInt CPbk2SendContactCmd::SelectionListL() const
+ {
+ TInt ret( KNoMenu );
+
+ // Show the query if contact has a thumbnail.
+ if ( AnyThumbnailsL() )
+ {
+ ret = R_PHONEBOOK2_SEND_OPTIONS;
+ }
+
+ return ret;
+ }
+#endif
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::MapSelection
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::MapSelection(TInt& aSelection, TInt aShownMenu)
+ {
+ for (TInt i = 0; SelectionMapping[i].iResId != ESelectionLast; ++i)
+ {
+ if (SelectionMapping[i].iResId == aShownMenu)
+ {
+ TInt selection(KErrNotFound);
+ switch(aSelection)
+ {
+ case 0:
+ {
+ selection = SelectionMapping[i].iStSelection;
+ break;
+ }
+ case 1:
+ {
+ selection = SelectionMapping[i].iNdSelection;
+ break;
+ }
+ case 2:
+ {
+ selection = SelectionMapping[i].iRdSelection;
+ break;
+ }
+ default:
+ {
+ __ASSERT_DEBUG(EFalse, Panic(EPanicLogic_MapSelection));
+ }
+ }
+
+ if (selection == ECancel)
+ {
+ __ASSERT_DEBUG(EFalse, Panic(EPanicLogic_MapSelection));
+ }
+
+ aSelection = selection;
+ return;
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::SelectSentDataL
+// --------------------------------------------------------------------------
+//
+TInt CPbk2SendContactCmd::SelectSentDataL()
+ {
+ TInt selectionIndex(ESendAllData);
+
+ // Get the resource id of the menu to be shown
+ TInt resourceId = SelectionListL();
+
+ if (resourceId)
+ {
+ // Create a list box
+ CEikColumnListBox* listBox = static_cast<CEikColumnListBox*>
+ (EikControlFactory::CreateByTypeL
+ (EAknCtSinglePopupMenuListBox).iControl);
+ CleanupStack::PushL(listBox);
+
+ // Create a popup list
+ CAknPopupList* popupList = CAknPopupList::NewL
+ (listBox, R_AVKON_SOFTKEYS_OK_CANCEL__OK,
+ AknPopupLayouts::EMenuGraphicWindow);
+ CleanupStack::PushL(popupList);
+
+ HBufC* headingText= CCoeEnv::Static()->AllocReadResourceLC
+ (R_PBK2_BUSINESSCARD_SEND_HEADING);
+ popupList->SetTitleL(*headingText);
+ CleanupStack::PopAndDestroy(); // headingText
+
+ // Init list box
+ listBox->SetContainerWindowL(*popupList);
+
+ TResourceReader resReader;
+ CCoeEnv::Static()->CreateResourceReaderLC(resReader, resourceId);
+ listBox->ConstructFromResourceL(resReader);
+ CleanupStack::PopAndDestroy(); // resReader
+
+ listBox->CreateScrollBarFrameL(ETrue);
+ listBox->ScrollBarFrame()->SetScrollBarVisibilityL
+ (CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto);
+
+ CleanupStack::Pop(); // popupList
+
+ // Show popuplist dialog
+ TInt res = popupList->ExecuteLD();
+ if (res)
+ {
+ selectionIndex = listBox->CurrentItemIndex();
+
+ // We have to remap the selection index since
+ // several different listbox configurations
+ MapSelection(selectionIndex, resourceId);
+ }
+ else
+ {
+ selectionIndex = ECancel;
+ }
+ CleanupStack::PopAndDestroy(); // listBox
+ }
+
+ return selectionIndex;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::ShowSendQueryL
+// --------------------------------------------------------------------------
+//
+TUid CPbk2SendContactCmd::ShowSendQueryL()
+ {
+ /// Sending params
+ TPbk2SendingParams params = CreateParamsLC();
+
+ TUid uid = iSendUi->ShowSendQueryL( NULL, params.iCapabilities, params.iMtmFilter );
+
+ CleanupStack::PopAndDestroy(); // mtmfilter
+ return uid;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::ProcessDone
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::ProcessDone(TInt aCancelCode)
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2SendContactCmd::ProcessDone (%d)"), aCancelCode);
+ if ( aCancelCode != KErrCancel && iUiControl )
+ {
+ // Ignore possible errors in clearing find box contents in release
+ // builds; just assert in debug builds. Showing an error here might
+ // signal to the user that there was some problem in the send contact
+ // command completion.
+ TInt err( KErrNone );
+ TRAP( err, iUiControl->ResetFindL() );
+ __ASSERT_DEBUG( err == KErrNone, Panic( EResetFindResult ) );
+
+ iUiControl->UpdateAfterCommandExecution();
+ }
+
+ if ( iCommandObserver )
+ {
+ // Notify command owner that the command has finished
+ iCommandObserver->CommandFinished(*this);
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::ProcessDismissed
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::ProcessDismissed( TInt aCancelCode )
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2SendContactCmd::ProcessDismissed (%d)"), aCancelCode);
+ if (aCancelCode == EAknSoftkeyCancel)
+ {
+ ProcessDone( KErrCancel );
+ }
+ else if ( iState == EStopping )
+ {
+ IssueStopRequest();
+ }
+ else
+ {
+ // Cancel first any outstanding requests
+ iVCardSender->Cancel();
+ iVCardSender->Start( TCallBack( &CPbk2SendContactCmd::SendvCardsLD,
+ this ) );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::CreateParamsLC
+// --------------------------------------------------------------------------
+//
+TPbk2SendingParams CPbk2SendContactCmd::CreateParamsLC()
+ {
+ // Construct the MTM filter
+ CArrayFixFlat<TUid>* mtmFilter =
+ new(ELeave) CArrayFixFlat<TUid>(KGranularity);
+ CleanupStack::PushL(mtmFilter);
+
+ mtmFilter->AppendL(KSenduiMtmPostcardUid); // hide postcard
+ mtmFilter->AppendL( KSenduiMtmAudioMessageUid ); // hide audio message
+ mtmFilter->AppendL( KMmsDirectUpload ); // hide upload
+
+ // Check must we disable SMS menuitem
+ if ( iSendUi->CanSendBioMessage( KMsgBioUidVCard ) )
+ {
+ mtmFilter->AppendL(KSenduiMtmSmsUid); // hide SMS
+ }
+
+ // If there are items more than one, hide items
+ if ( IsMoreThanOneContact() )
+ {
+ mtmFilter->AppendL(KSenduiMtmSmsUid); // hide SMS
+ }
+ else if (!FeatureManager::FeatureSupported(KFeatureIdMMS))
+ {
+ // Hide MMS if not supported
+ mtmFilter->AppendL(KSenduiMtmMmsUid);
+ }
+
+ // Hide Email if not supported
+ if (!FeatureManager::FeatureSupported(KFeatureIdEmailUi))
+ {
+ mtmFilter->AppendL(KSenduiMtmSmtpUid);
+ mtmFilter->AppendL(KSenduiMtmImap4Uid);
+ mtmFilter->AppendL(KSenduiMtmPop3Uid);
+ mtmFilter->AppendL(KSenduiMtmSyncMLEmailUid);
+ }
+
+ TSendingCapabilities capabilities = TSendingCapabilities();
+ capabilities.iFlags = TSendingCapabilities::ESupportsBioSending;
+ capabilities.iFlags |= TSendingCapabilities::ESupportsAttachments;
+ return TPbk2SendingParams( mtmFilter, capabilities );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::ConvertContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::ConvertContactL(TInt aSelectionIndex)
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2SendContactCmd::ConvertContactL(0x%x)"), this);
+
+ delete iDecorator;
+ iDecorator = NULL;
+
+ if (aSelectionIndex != ECancel)
+ {
+ // Start wait note if user continues. If it cancels then don't
+ // create decorator because it causes a panic in CActive destructor
+ // of this instance.
+ iDecorator = Pbk2ProcessDecoratorFactory::CreateWaitNoteDecoratorL(
+ R_QTN_SM_WAIT_BUSINESS_CARD, ETrue );
+ iDecorator->SetObserver( *this );
+ // wait note doesn't care about amount
+ iDecorator->ProcessStartedL( 0 );
+
+ if ( iFocusedField )
+ {
+ iConverter->ConvertContactL(
+ iStoreContacts.Array(), iFocusedField,
+ aSelectionIndex, *this);
+ }
+ else if ( iCntIterator )
+ {
+ iConverter->ConvertContactsL(
+ *iCntIterator, aSelectionIndex, *this );
+ }
+ else
+ {
+ // iContacts validity is checked in function entry
+ iConverter->ConvertContactsL(
+ iStoreContacts.Array(), aSelectionIndex, *this);
+ }
+ }
+ else
+ {
+ IssueStopRequest();
+ }
+
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2SendContactCmd::ConvertContactL(0x%x), end"), this);
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::RetrieveContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::RetrieveContactL(const MVPbkContactLink& aLink)
+ {
+ iRetrieveOperation = iAppServices->ContactManager().
+ RetrieveContactL(aLink, *this);
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::FilterErrors
+// --------------------------------------------------------------------------
+//
+TInt CPbk2SendContactCmd::FilterErrors(TInt aErrorCode)
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2SendContactCmd::FilterErrors(%d) start"), aErrorCode);
+
+ TInt result = aErrorCode;
+ switch (aErrorCode)
+ {
+ case KErrNotFound: // FALLTHROUGH
+ case KErrInUse: // FALLTHROUGH
+ {
+ // Ignore these errors
+ // KErrNotFound means that somebody got the contact first
+ // KErrInUse means that the contact is open
+ result = KErrNone;
+ break;
+ }
+
+ default: // Something more serious happened -> give up
+ {
+ Cancel();
+ ProcessDone(aErrorCode);
+ break;
+ }
+ }
+
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2SendContactCmd::FilterErrors(%d) end"), result);
+
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::IssueRequest
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::IssueRequest()
+ {
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ SetActive();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::IssueStopRequest
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::IssueStopRequest()
+ {
+ iState = EStopping;
+ if (!IsActive())
+ {
+ IssueRequest();
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::SendMsgUsingSendUI
+// --------------------------------------------------------------------------
+//
+void CPbk2SendContactCmd::SendMsgUsingSendUI(CMessageData* aMsgData)
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2SendContactCmd::SendMsgUsingSendUI(0x%x), start"), this);
+
+ // Send the message using Send Ui
+ TRAPD(error, iSendUi->CreateAndSendMessageL( iMtmUid, aMsgData, KMsgBioUidVCard));
+
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2SendContactCmd::SendMsgUsingSendUI(%d), error"), error);
+
+ if (error != KErrNone)
+ {
+ FilterErrors(error);
+ }
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2SendContactCmd::SendMsgUsingSendUI(0x%x), end"), this);
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2SendContactCmd::IsMoreThanOneContact
+// --------------------------------------------------------------------------
+//
+TBool CPbk2SendContactCmd::IsMoreThanOneContact()
+ {
+ TBool result = EFalse;
+ if ( iCntIterator )
+ {
+ result = ETrue;
+ }
+ return result;
+ }
+
+// End of File