diff -r 000000000000 -r 72b543305e3a mobilemessaging/postcard/postcardsrc/PostcardOperationSave.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mobilemessaging/postcard/postcardsrc/PostcardOperationSave.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,1003 @@ +/* +* Copyright (c) 2005 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: +* CPostcardOperationSave +* +*/ + + + +// ========== INCLUDE FILES ================================ + +#include +#include +#include +#include // TDataType +#include // AttachmentManager +#include // AttachmentManager +#include // MimeHeaders + +#include // For StringLoader + +#include +#include +#include + +#include + +#include // VCardPropertyValue +#include +#include +#include // CContactTextField + +#include +#include "PostcardOperationSave.h" +#include "PostcardUtils.h" +#include "Postcard.hrh" +#include "PostcardAddressForm.h" +#include "PostcardPrivateCRKeys.h" // cenrep keys +#include "PostcardCenRep.h" + +// ========== EXTERNAL DATA STRUCTURES ===================== + +// ========== EXTERNAL FUNCTION PROTOTYPES ================= + +// ========== CONSTANTS ==================================== + +// ========== MACROS ======================================= + +// ========== LOCAL CONSTANTS AND MACROS =================== + +_LIT8( KReplaceChar8, "_" ); +_LIT8( KPostcardVCardName, "N"); // This was "FN" in 3.0-3.1 but OMA says it should be "N" +_LIT8( KPostcardVCardAddr, "ADR"); +_LIT8( KPostcardGreetingXParameter, "X-MMS-GREETING-TEXT" ); + +// ========== MODULE DATA STRUCTURES ======================= + +// ========== LOCAL FUNCTION PROTOTYPES ==================== + +// ========== LOCAL FUNCTIONS ============================== + +// ========== MEMBER FUNCTIONS ============================= + +// --------------------------------------------------------- +// NewL +// --------------------------------------------------------- +CPostcardOperationSave* CPostcardOperationSave::NewL( + MPostcardOperationObserver& aObserver, + CPostcardDocument& aDocument, + CPostcardAppUi& aAppUi, + RFs& aFs, + CContactCard& aContact, + CPlainText& aPlainText ) + { + CPostcardOperationSave* self = + new ( ELeave ) CPostcardOperationSave( aObserver, aDocument, aAppUi, aFs, aContact, aPlainText ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------- +// CPostcardOperationSave +// --------------------------------------------------------- +CPostcardOperationSave::CPostcardOperationSave( + MPostcardOperationObserver& aObserver, + CPostcardDocument& aDocument, + CPostcardAppUi& aAppUi, + RFs& aFs, + CContactCard& aContact, + CPlainText& aPlainText ) : + CPostcardOperation( aObserver, aDocument, aAppUi, aFs ), + iContact( aContact ), + iPlainText( aPlainText ) + { + } + +// --------------------------------------------------------- +// CPostcardOperationSave +// --------------------------------------------------------- +CPostcardOperationSave::~CPostcardOperationSave( ) + { + Cancel( ); + if( iTempFile ) + { + iTempFile->Close( ); + delete iTempFile; + } + delete iSendOperation; + delete iCharConv; + delete iRecipientName; + } + +// --------------------------------------------------------- +// Start +// --------------------------------------------------------- +void CPostcardOperationSave::Start( TInt aArgument ) + { + if( aArgument ) + { + iFlags |= EPostcardSaveSend; + } + if( iAppUi.CenRep().GetString( KPocaKeyServiceSpecialFormat ).Length() > 0 && + ( iFlags & EPostcardSaveSend ) ) + { // if special send format is defined and we are sending -> take it into use + iFlags |= EPostcardSaveSpecialFormat; + } + iLaunchState = EPostcardSaveInitializing; + CompleteSelf( KErrNone ); + } + +// --------------------------------------------------------- +// DoLaunchStepL +// --------------------------------------------------------- +void CPostcardOperationSave::DoLaunchStepL( ) + { + iFlags &= ~EPostcardSaveRequestActive; + switch ( iLaunchState ) + { + case EPostcardSaveInitializing: + { + InitL( ); + iLaunchState = EPostcardSaveCheckAttas; + CompleteSelf( KErrNone ); + break; + } + case EPostcardSaveCheckAttas: + { + if( !CheckAttasL( ) ) + { // If there was an error, this has been completed already + iLaunchState = EPostcardSaveRemoveOldAttas; + CompleteSelf( KErrNone ); + } + break; + } + case EPostcardSaveRemoveOldAttas: + { + RemoveOldAttasL( ); + // Let's see the next phase.. + if( iPlainText.DocumentLength( ) > 0 && iDocument.Changed( EPostcardText ) ) + { // We have text and it has changed -> so save it.. + iLaunchState = EPostcardSaveCreateTextAtta; + } + else if ( ( iFlags & EPostcardSaveSend ) && + ( iFlags & EPostcardSaveSpecialFormat ) ) + { // Text has not changed, but we have special format on -> so create text atta anyway + iLaunchState = EPostcardSaveCreateTextAtta; + } + else if ( iDocument.Changed( EPostcardRecipient ) ) + { // We are not sending special format, but the recipient has changed + iLaunchState = EPostcardSaveCreateRecipientAtta; + } + else if( !iSmil && + ( iFlags & EPostcardSaveSend ) && + !( iFlags & EPostcardSaveSpecialFormat ) ) + { // Text and recipient have not changed, but we are sending OMA Postcard and there's no SMIL yet + iLaunchState = EPostcardSaveCreateSmilAtta; + } + else + { + iLaunchState = EPostcardSaveUninit; + } + CompleteSelf( KErrNone ); + break; + } + case EPostcardSaveCreateTextAtta: + { + CreateNewTextAttaL( ); + iLaunchState = EPostcardSaveSaveTextAtta; + SetActive(); + break; + } + case EPostcardSaveSaveTextAtta: + { + HandleTextL( ); + iLaunchState = EPostcardSaveFinalizeTextAtta; + CompleteSelf( KErrNone ); + break; + } + case EPostcardSaveFinalizeTextAtta: + { + FinalizeTextL( ); + if ( iDocument.Changed( EPostcardRecipient ) && + ( iFlags & EPostcardSaveHasContact ) ) + { // We are not sending special format, but the recipient has changed + iLaunchState = EPostcardSaveCreateRecipientAtta; + } + else if( !iSmil && + ( iFlags & EPostcardSaveSend ) && + !( iFlags & EPostcardSaveSpecialFormat ) ) + { // Recipient has not changed, but we are sending OMA Postcard and there's no SMIL yet + iLaunchState = EPostcardSaveCreateSmilAtta; + } + else + { + iLaunchState = EPostcardSaveUninit; + } + CompleteSelf( KErrNone ); + break; + } + case EPostcardSaveCreateRecipientAtta: + { + CreateNewRecipientAttaL( ); + iLaunchState = EPostcardSaveSaveRecipientAtta; + SetActive( ); + break; + } + case EPostcardSaveSaveRecipientAtta: + { + HandleRecipientL( ); + iLaunchState = EPostcardSaveFinalizeRecipientAtta; + CompleteSelf( KErrNone ); + break; + } + case EPostcardSaveFinalizeRecipientAtta: + { + FinalizeRecipientL( ); + if( !iSmil && + ( iFlags & EPostcardSaveSend ) && + !( iFlags & EPostcardSaveSpecialFormat ) ) + { // Smil is created only to confront OMA Postcard spec + iLaunchState = EPostcardSaveCreateSmilAtta; + } + else + { + // Smil seems to exists already or we are not sending + iLaunchState = EPostcardSaveUninit; + } + CompleteSelf( KErrNone ); + break; + } + case EPostcardSaveCreateSmilAtta: + { + CreateNewSmilAttaL( ); + iLaunchState = EPostcardSaveSaveSmilAtta; + SetActive( ); + break; + } + case EPostcardSaveSaveSmilAtta: + { + HandleSmilL( ); + iLaunchState = EPostcardFinalizeSmilAtta; + CompleteSelf( KErrNone ); + break; + } + case EPostcardFinalizeSmilAtta: + { + FinalizeSmilL( ); + iLaunchState = EPostcardSaveUninit; + CompleteSelf( KErrNone ); + break; + } + case EPostcardSaveUninit: + { + UnInitL( ); + iLaunchState = EPostcardSaveFinalizeMessage; + CompleteSelf( KErrNone ); + break; + } + case EPostcardSaveFinalizeMessage: + { + FinalizeMessageL( ); + if( iFlags & EPostcardSaveSend ) + { + iLaunchState = EPostcardSaveStartSend; + } + else + { + iLaunchState = EPostcardSaveFinished; + } + CompleteSelf( KErrNone ); + break; + } + case EPostcardSaveStartSend: + { + StartSendingL( ); + iLaunchState = EPostcardSaveFinished; + SetActive(); + break; + } + case EPostcardSaveFinished: + { + iObserver.PostcardOperationEvent( + EPostcardOperationSave, + EPostcardOperationComplete ); + break; + } + default: + iObserver.PostcardOperationEvent( + EPostcardOperationSave, + EPostcardOperationError ); + break; + } + } + +// --------------------------------------------------------- +// RemoveOldAttasL +// --------------------------------------------------------- +void CPostcardOperationSave::RemoveOldAttasL( ) + { + if( iDocument.Changed( EPostcardText ) || + ( ( iFlags & EPostcardSaveSend ) && ( iFlags & EPostcardSaveSpecialFormat ) ) ) + { + if( iText ) + { // Remove old + TInt old = TMsvIdToIndexL( iText ); + if( old != KErrNotFound ) + { + // If there is an old text atta and a no new text atta, we need to + // ask commit here, otherwise old atta would be left with the message. + iCommit = ETrue; + iStore->AttachmentManagerExtensionsL( ).RemoveAttachmentL( old ); + } + } + } + if( iDocument.Changed( EPostcardRecipient ) || + ( ( iFlags & EPostcardSaveSend ) && ( iFlags & EPostcardSaveSpecialFormat ) ) ) + { + if( iRecipient ) + { // Remove old + TInt old = TMsvIdToIndexL( iRecipient ); + if( old != KErrNotFound ) + { + iStore->AttachmentManagerExtensionsL( ).RemoveAttachmentL( old ); + } + } + } + } + +// --------------------------------------------------------- +// CreateNewTextAttaL +// --------------------------------------------------------- +void CPostcardOperationSave::CreateNewTextAttaL( ) + { + // Now lets create a new attachment + TFileName file( _L("greeting.txt") ); + StartCreatingEmptyAttachmentL( file ); + } + +// --------------------------------------------------------- +// HandleTextL +// --------------------------------------------------------- +void CPostcardOperationSave::HandleTextL( ) + { + if( !iCharConv ) + { + iCharConv = CCnvCharacterSetConverter::NewL( ); + } + + if ( iCharConv->PrepareToConvertToOrFromL( KCharacterSetIdentifierUtf8, iFs ) + != CCnvCharacterSetConverter::EAvailable ) + { + User::Leave( KErrNotSupported ); + } + + // Delete possible old headers + delete iHeaders; + iHeaders = NULL; + iHeaders = CMsvMimeHeaders::NewL( ); + + if( ( iFlags & EPostcardSaveSend ) && !( iFlags & EPostcardSaveSpecialFormat ) ) + { + iHeaders->XTypeParams().AppendL( KPostcardGreetingXParameter ); + iHeaders->XTypeParams().AppendL( TPtrC8() ); + } + + _LIT(KFileName, "text.txt"); + iHeaders->SetContentLocationL( KFileName ); + iHeaders->SetMimeCharset( KMmsUtf8 ); + + TInt slash = KMsgMimeTextPlain().Locate( '/' ); + iHeaders->SetContentTypeL( KMsgMimeTextPlain().Left( slash ) ); + iHeaders->SetContentSubTypeL( KMsgMimeTextPlain().Mid( slash + 1 ) ); + + iTempAtta->SetMimeTypeL( KMsgMimeTextPlain ); + + iText = iTempAtta->Id( ); + RFileWriteStream writer( *iTempFile ); + writer.PushL( ); + delete iTempFile; // not close as write does it.. + iTempFile = NULL; + + TPtrC16 remainderOfUnicodeText; + TInt numCleanupItems = 0; + + if( (iFlags & EPostcardSaveSend) && (iFlags & EPostcardSaveSpecialFormat ) ) + { + // If we are here -> we are sending so we must have iContact OK + HBufC* wholeText = MakeSpecialFormatTextL(); + CleanupStack::PushL( wholeText ); + numCleanupItems++; + + remainderOfUnicodeText.Set( wholeText->Des( ) ); + + // Now we remove the HasContact flag so that the recipient is not stored separately + iFlags &= ~EPostcardSaveHasContact; + } + else + { + remainderOfUnicodeText.Set( + iPlainText.Read( 0, iPlainText.DocumentLength() ) ); + } + + // Now remainOfUnicodeText has the stuff needed to store into the greeting text + TBuf8<128> outputBuffer; + TInt returnValue; + do + { + returnValue = iCharConv->ConvertFromUnicode( + outputBuffer, remainderOfUnicodeText ); + if ( returnValue < 0 ) + { + User::Leave( + returnValue == CCnvCharacterSetConverter::EErrorIllFormedInput ? + KErrCorrupt:KErrGeneral ); + } + writer.WriteL( outputBuffer ); + remainderOfUnicodeText.Set( remainderOfUnicodeText.Right( + returnValue ) ); + } + while( returnValue ); + + CleanupStack::PopAndDestroy( numCleanupItems ); + writer.Pop( ); + writer.Close( ); + } + +// --------------------------------------------------------- +// MakeSpecialFormatTextL +// --------------------------------------------------------- +HBufC* CPostcardOperationSave::MakeSpecialFormatTextL() + { + CContactItemFieldSet& set = iContact.CardFields( ); + // Organise the address into an array + CDesCArrayFlat* desarr = AddressArrayLC( set ); + + const TDesC& replacement = + iAppUi.CenRep().GetString( KPocaKeyServiceReplaceString ); + const TDesC& separator = + iAppUi.CenRep().GetString( KPocaKeyServiceSeparator ); + + // Add the greeting text. + + TInt len = iPlainText.DocumentLength(); + HBufC* buf = HBufC::NewLC( len ); + *buf = iPlainText.Read( 0, len ); + + // Replace illegal chars + TPtr des = buf->Des(); + ReplaceWith( des, separator, replacement ); + // And add this to the desarr + desarr->InsertL( 0, *buf ); + + // Read the format string from cenrep + const TDesC& specialFormat = + iAppUi.CenRep().GetString( KPocaKeyServiceSpecialFormat ); + + // Construct the text to be sent. Room for each tag, strings between + // tags and prefix and postfix. + const TInt KMaxItems = TPostcardUtils::ENumSpecFormatTags * 2 + 1; + TPtrC textItems[KMaxItems]; + + TPtrC format(specialFormat); + TInt position = 0; + TInt numItems = 0; + while(numItems < KMaxItems - 1 && position != KErrNotFound) + { + TInt tag; + position = TPostcardUtils::NextTag(format, tag); + if ( position != KErrNotFound ) + { + textItems[numItems++].Set( format.Left( position ) ); + textItems[numItems++].Set( desarr->MdcaPoint( tag ) ); + format.Set( format.Right( format.Length() - position - 3 ) ); + } + else + { + textItems[numItems++].Set( format ); + } + } + + // Calculate buffer length needed to fit the whole text + TInt buffSize = 0; + for( TInt i = 0; i < numItems; i++ ) + { + buffSize += textItems[i].Length(); + } + + // Copy text into buffer + HBufC* dstBuf = HBufC::NewL( buffSize ); + TPtr dst = dstBuf->Des(); + for( TInt i = 0; i < numItems; i++ ) + { + dst.Append( textItems[i] ); + } + + CleanupStack::PopAndDestroy( 2 ); // buff, desarr + + return dstBuf; + } + +// --------------------------------------------------------- +// FinalizeTextL +// --------------------------------------------------------- +void CPostcardOperationSave::FinalizeTextL( ) + { + iHeaders->StoreL( *iTempAtta ); + } + +// --------------------------------------------------------- +// CreateNewRecipientAttaL +// --------------------------------------------------------- +void CPostcardOperationSave::CreateNewRecipientAttaL( ) + { + // Now lets create a new attachment + TFileName file( _L("recipient.vcf") ); + StartCreatingEmptyAttachmentL( file ); + } + +// --------------------------------------------------------- +// HandleRecipientL +// --------------------------------------------------------- +void CPostcardOperationSave::HandleRecipientL( ) + { + if( !iCharConv ) + { + iCharConv = CCnvCharacterSetConverter::NewL( ); + } + if ( iCharConv->PrepareToConvertToOrFromL( KCharacterSetIdentifierAscii, iFs ) != + CCnvCharacterSetConverter::EAvailable ) + { + User::Leave( KErrNotSupported ); + } + + // Delete possible old headers + delete iHeaders; + iHeaders = NULL; + iHeaders = CMsvMimeHeaders::NewL( ); + iHeaders->SetContentLocationL( _L("recipient.vcf") ); + + TInt slash = KMsgMimeVCard().Locate( '/' ); + iHeaders->SetContentTypeL( KMsgMimeVCard().Left( slash ) ); + iHeaders->SetContentSubTypeL( KMsgMimeVCard().Mid( slash + 1 ) ); + + iTempAtta->SetMimeTypeL( KMsgMimeVCard ); + + iRecipient = iTempAtta->Id( ); + + CParserVCard* parser = CParserVCard::NewL(); + CleanupStack::PushL(parser); + + RFileWriteStream vCardStream( *iTempFile ); + vCardStream.PushL( ); + delete iTempFile; // not close as VCardStream does it.. + iTempFile = NULL; + + iCharConv->SetReplacementForUnconvertibleUnicodeCharactersL( KReplaceChar8 ); + + CContactItemFieldSet& set = iContact.CardFields( ); + + const CContactItemField* field = TPostcardUtils::FieldOrNull( set, + TPostcardUtils::ContactItemNameFromId( EPostcardAddressName ) ); + + if( field ) + { + CParserPropertyValueHBufC* val = + CParserPropertyValueHBufC::NewL( field->TextStorage()->Text() ); + CleanupStack::PushL( val ); + CArrayPtrFlat* array = new(ELeave)CArrayPtrFlat(1); + CleanupStack::PushL( array ); + CParserProperty* property = CParserProperty::NewL( *val, KPostcardVCardName, array); + CleanupStack::PushL( property ); + parser->AddPropertyL( property ); + CleanupStack::Pop( 3, val ); + } + + CDesCArrayFlat* desarr = VCardAddressArrayL( set ); // Organise the address into an array + CleanupStack::PushL( desarr ); + // AddressArrayL does not add empty "PO Box" descriptor into the desarr + desarr->InsertL( 0, KNullDesC ); + + CParserPropertyValue* val = new (ELeave)CParserPropertyValueCDesCArray(desarr); + CleanupStack::Pop(desarr); + CleanupStack::PushL( val ); + CArrayPtrFlat* array = new(ELeave)CArrayPtrFlat(1); + CleanupStack::PushL( array ); + + CParserProperty* property = CParserProperty::NewL( *val, KPostcardVCardAddr, array); + CleanupStack::PushL( property ); + parser->AddPropertyL( property ); + CleanupStack::Pop( 3, val ); + + parser->ExternalizeL(vCardStream); + + vCardStream.Pop( ); + vCardStream.Close( ); + + CleanupStack::PopAndDestroy(parser); + } + +// --------------------------------------------------------- +// FinalizeRecipientL +// --------------------------------------------------------- +void CPostcardOperationSave::FinalizeRecipientL( ) + { + iHeaders->StoreL( *iTempAtta ); + } + +// --------------------------------------------------------- +// CreateNewSmilAttaL +// --------------------------------------------------------- +void CPostcardOperationSave::CreateNewSmilAttaL( ) + { + // Now lets create a new attachment + TFileName file( _L("postcard.smil") ); + StartCreatingEmptyAttachmentL( file ); + } + +// --------------------------------------------------------- +// HandleSmilL +// --------------------------------------------------------- +void CPostcardOperationSave::HandleSmilL( ) + { + // Delete possible old headers + delete iHeaders; + iHeaders = NULL; + + iHeaders = CMsvMimeHeaders::NewL( ); + iHeaders->SetContentLocationL( _L("pres.smil") ); + + TInt slash = KMsgMimeSmil().Locate( '/' ); + iHeaders->SetContentTypeL( KMsgMimeSmil().Left( slash ) ); + iHeaders->SetContentSubTypeL( KMsgMimeSmil().Mid( slash + 1 ) ); + + iTempAtta->SetMimeTypeL( KMsgMimeSmil ); + + iSmil = iTempAtta->Id( ); + + // Get the name of the image file to be inserted into the SMIL file + HBufC* fileName = GetImageFileNameL( ); + CleanupStack::PushL( fileName ); + TInt resId = R_POSTCARD_OMA_SMIL; + HBufC* smil = StringLoader::LoadL( resId, *fileName ); + CleanupStack::PopAndDestroy( fileName ); + CleanupStack::PushL( smil ); + + // convert the smil to 8-bit + HBufC8* smil8 = HBufC8::NewLC( smil->Des( ).Length( ) ); + smil8->Des().Copy( smil->Des( ) ); + + RFileWriteStream smilStream( *iTempFile ); + smilStream.PushL( ); + + delete iTempFile; // not close as smilStream does it + iTempFile = NULL; + + smilStream.WriteL( *smil8 ); + + smilStream.Close( ); + smilStream.Pop( ); + CleanupStack::PopAndDestroy( 2, smil ); // smil, smil8 + } + +// --------------------------------------------------------- +// FinalizeSmilL +// --------------------------------------------------------- +void CPostcardOperationSave::FinalizeSmilL( ) + { + iHeaders->StoreL( *iTempAtta ); + } + +// --------------------------------------------------------- +// FinalizeMessageL +// --------------------------------------------------------- +void CPostcardOperationSave::FinalizeMessageL( ) + { + + const CMsvRecipientList& addresses = iDocument.Mtm( ).AddresseeList(); + + if( addresses.Count( ) < 1 ) + { + iDocument.Mtm().AddAddresseeL( + iAppUi.CenRep().GetString( KPocaKeyServiceProvider ) ); + } + + // Disable delivery reports for postcards + iDocument.Mtm().SetDeliveryReport( EMmsNo ); + + iDocument.Mtm().SaveMessageL(); + + TMmsMsvEntry tEntry = static_cast( iDocument.Entry() ); + + // Update timestamp + tEntry.iDate.UniversalTime(); + + if ( !tEntry.Visible() ) + { + // Save from close or exit save. + // Message should be visible after save + tEntry.SetVisible( ETrue ); + tEntry.SetInPreparation( EFalse ); + } + + if ( !tEntry.EditorOriented() ) + { + tEntry.SetEditorOriented( ETrue ); + } + + tEntry.iDetails.Set( iRecipientName->Des( ) ) ; + tEntry.iDescription.Set( + iPlainText.Read( 0, Min( iPlainText.DocumentLength(), 20 ) ) ); + + tEntry.iBioType = KUidMsgSubTypeMmsPostcard.iUid; + + iDocument.CurrentEntry().ChangeL( tEntry ); + } + +// --------------------------------------------------------- +// CPostcardOperationSave::StartSendingL +// --------------------------------------------------------- +void CPostcardOperationSave::StartSendingL( ) + { + iSendOperation = iDocument.Mtm().SendL( iStatus ); + } + +// --------------------------------------------------------- +// CPostcardOperationSave::ConstructL +// --------------------------------------------------------- +void CPostcardOperationSave::ConstructL( ) + { + if( HasContact() ) + { + iFlags |= EPostcardSaveHasContact; + CContactItemFieldSet& fieldSet = iContact.CardFields(); + const CContactItemField* field = TPostcardUtils::FieldOrNull( fieldSet, + TPostcardUtils::ContactItemNameFromId( EPostcardAddressName ) ); + if( field ) + { + iRecipientName = field->TextStorage()->Text().AllocL(); + } + } + if( !iRecipientName ) + { + iRecipientName = HBufC::NewL( 0 ); + } + } + +// --------------------------------------------------------- +// CPostcardOperationSave::DoCancel +// --------------------------------------------------------- +void CPostcardOperationSave::DoCancel( ) + { + if( iManager ) + { + if( iFlags & EPostcardSaveRequestActive ) + { // Attachment Manager request going on -> cancel + iManager->CancelRequest(); + } + } + } + +// --------------------------------------------------------- +// RunL +// --------------------------------------------------------- +void CPostcardOperationSave::RunL( ) + { + DoLaunchStepL( ); + } + +// --------------------------------------------------------- +// RunError +// --------------------------------------------------------- +TInt CPostcardOperationSave::RunError( TInt aError ) + { + iLaunchState = -1; + SetError( aError ); + iObserver.PostcardOperationEvent( + EPostcardOperationSave, + EPostcardOperationError ); + return KErrNone; + } + +// --------------------------------------------------------- +// StartCreatingEmptyAttachmentL +// --------------------------------------------------------- +void CPostcardOperationSave::StartCreatingEmptyAttachmentL( const TFileName& aFileName ) + { + CMsvAttachment* attachment = CMsvAttachment::NewL( CMsvAttachment::EMsvFile ); + CleanupStack::PushL( attachment ); + iTempFile = new ( ELeave ) RFile; + iManager->CreateAttachmentL( aFileName, *iTempFile, attachment, iStatus ); + iFlags |= EPostcardSaveRequestActive; + CleanupStack::Pop( attachment ); + iTempAtta = attachment; + iCommit = ETrue; + } + +// --------------------------------------------------------- +// HasContact +// --------------------------------------------------------- +TBool CPostcardOperationSave::HasContact( ) + { + CContactItemFieldSet& set = iContact.CardFields( ); + for( TInt i = 0; iText( ).Length( ) > 0 ) + { + return ETrue; + } + } + return EFalse; + } + +// --------------------------------------------------------- +// AddressArrayLC +// --------------------------------------------------------- +CDesCArrayFlat* CPostcardOperationSave::AddressArrayLC( CContactItemFieldSet& aSet ) + { + // Get contact fields into an array. No ownership. + const CContactItemField* fields[ CPostcardAddressForm::ENumAddrFields ]; + + const TInt first = EPostcardAddressName; + const TInt last = EPostcardAddressCountry; + for( TInt i = first; i <= last; i++) + { + fields[i - first] = TPostcardUtils::FieldOrNull( + aSet, TPostcardUtils::ContactItemNameFromId( i ) ); + } + + CDesCArrayFlat* desarr = + new( ELeave ) CDesCArrayFlat( CPostcardAddressForm::ENumAddrFields ); + CleanupStack::PushL(desarr); + + for( TInt i = 0; i < CPostcardAddressForm::ENumAddrFields; i++ ) + { + if( fields[i] ) + { + if( ( iFlags & EPostcardSaveSend) && + (iFlags & EPostcardSaveSpecialFormat ) ) + { // We are sending & have the special format on + // so lets replace possible user added separator strings + TPtr string = fields[i]->TextStorage()->Text().AllocLC()->Des(); + // Trim leading and trailing white space so it doesn't affect + // parsing of special format string when opened from sent + // folder. + string.Trim(); + ReplaceWith( string, + iAppUi.CenRep().GetString( KPocaKeyServiceSeparator ), + iAppUi.CenRep().GetString( KPocaKeyServiceReplaceString ) + ); + desarr->AppendL( string ); + CleanupStack::PopAndDestroy(); // string + } + else + { // Otherwise just add the data field + desarr->AppendL( fields[i]->TextStorage()->Text() ); + } + } + else + { + desarr->AppendL( KNullDesC ); + } + } + return desarr; + } + +// --------------------------------------------------------- +// VCardAddressArrayL +// --------------------------------------------------------- +CDesCArrayFlat* CPostcardOperationSave::VCardAddressArrayL( CContactItemFieldSet& aSet ) + { + // Exclude name + const TInt KPocaVCardAddrFields = CPostcardAddressForm::ENumAddrFields - 1; + + // Get contact fields into an array. No ownership. + const CContactItemField* fields[ KPocaVCardAddrFields ]; + + // Order of contact fields in array + static const TInt ids[KPocaVCardAddrFields] = + { + EPostcardAddressInfo, EPostcardAddressStreet, EPostcardAddressCity, + EPostcardAddressState, EPostcardAddressZip, EPostcardAddressCountry + }; + + for( TInt i = 0; i < KPocaVCardAddrFields; i++) + { + fields[i] = TPostcardUtils::FieldOrNull( + aSet, TPostcardUtils::ContactItemNameFromId( ids[i] ) ); + } + + CDesCArrayFlat* desarr = new(ELeave) CDesCArrayFlat( KPocaVCardAddrFields ); + CleanupStack::PushL( desarr ); + + for( TInt i = 0; i < KPocaVCardAddrFields; i++ ) + { + desarr->AppendL( + fields[i] ? fields[i]->TextStorage()->Text() : KNullDesC() ); + } + + CleanupStack::Pop( desarr ); + return desarr; + } + +// --------------------------------------------------------- +// ReplaceWith +// --------------------------------------------------------- +void CPostcardOperationSave::ReplaceWith( TDes& aOrig, const TDesC& aWhat, + const TDesC& aWith ) + { + TInt pos = 0; + TInt foundPos = 0; + TBool found = ETrue; + + while( found ) + { + found = EFalse; + if( pos >= aOrig.Length( ) ) + { + continue; // as found is false -> while is not true anymore + } + + foundPos = aOrig.Mid( pos, aOrig.Length()-pos ).Find( aWhat ); + + if( foundPos == KErrNotFound ) + { // Not found anymore, so the rest is ok + continue; // as found is false -> while is not true anymore + } + + found = ETrue; + // As foundPos is related to previous sepa char, we need to add the beginning, too + foundPos += pos; + aOrig.Replace( foundPos, aWhat.Length( ), aWith ); + pos = foundPos + aWhat.Length( ) + ( aWith.Length( ) - aWhat.Length( ) ); + } + } + +// --------------------------------------------------------- +// GetImageFileName +// --------------------------------------------------------- +HBufC* CPostcardOperationSave::GetImageFileNameL( ) + { + // Goes thru the attas and check how many images, text and recipients there are + TInt count = iManager->AttachmentCount( ); + CMsvAttachment* atta = NULL; + + HBufC* nameString = NULL; + for(TInt a = 0; aGetAttachmentInfoL( a ); + CleanupStack::PushL( atta ); + + switch( RecogniseFileType( atta->MimeType( ) ) ) + { + case EPostcardFileImage: + { + CMsvMimeHeaders* msvMime = CMsvMimeHeaders::NewLC(); + msvMime->RestoreL( *atta ); + nameString = msvMime->ContentLocation().AllocL(); + CleanupStack::PopAndDestroy( msvMime ); // msvMime, atta + break; + } + default: + break; + } + CleanupStack::PopAndDestroy( atta ); + } + return nameString ? nameString : HBufC::NewL( 0 ); + } + +// EOF