mobilemessaging/postcard/postcardsrc/PostcardOperationSave.cpp
changeset 0 72b543305e3a
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     1 /*
       
     2 * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 *       CPostcardOperationSave
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 // ========== INCLUDE FILES ================================
       
    22 
       
    23 #include <badesca.h>
       
    24 #include <AknsConstants.h>
       
    25 #include <data_caging_path_literals.hrh> 
       
    26 #include <apmstd.h>  // TDataType
       
    27 #include <mmsvattachmentmanager.h>	// AttachmentManager
       
    28 #include <mmsvattachmentmanagersync.h>	// AttachmentManager
       
    29 #include <cmsvmimeheaders.h>		// MimeHeaders
       
    30 
       
    31 #include <StringLoader.h>			// For StringLoader
       
    32 
       
    33 #include <mmsclient.h>
       
    34 #include <mmsconst.h>
       
    35 #include <mmsmsventry.h>
       
    36 
       
    37 #include <MsgMimeTypes.h>
       
    38 
       
    39 #include <vprop.h>	// VCardPropertyValue
       
    40 #include <cntitem.h>
       
    41 #include <vcard.h>
       
    42 #include <cntfldst.h> // CContactTextField
       
    43 
       
    44 #include <Postcard.rsg>
       
    45 #include "PostcardOperationSave.h"
       
    46 #include "PostcardUtils.h"
       
    47 #include "Postcard.hrh"
       
    48 #include "PostcardAddressForm.h"
       
    49 #include "PostcardPrivateCRKeys.h"  // cenrep keys
       
    50 #include "PostcardCenRep.h"
       
    51 
       
    52 // ========== EXTERNAL DATA STRUCTURES =====================
       
    53 
       
    54 // ========== EXTERNAL FUNCTION PROTOTYPES =================
       
    55 
       
    56 // ========== CONSTANTS ====================================
       
    57 
       
    58 // ========== MACROS =======================================
       
    59 
       
    60 // ========== LOCAL CONSTANTS AND MACROS ===================
       
    61 
       
    62 _LIT8( KReplaceChar8, "_" );
       
    63 _LIT8( KPostcardVCardName, "N"); // This was "FN" in 3.0-3.1 but OMA says it should be "N"
       
    64 _LIT8( KPostcardVCardAddr, "ADR");
       
    65 _LIT8( KPostcardGreetingXParameter, "X-MMS-GREETING-TEXT" );
       
    66 
       
    67 // ========== MODULE DATA STRUCTURES =======================
       
    68 
       
    69 // ========== LOCAL FUNCTION PROTOTYPES ====================
       
    70 
       
    71 // ========== LOCAL FUNCTIONS ==============================
       
    72 
       
    73 // ========== MEMBER FUNCTIONS =============================
       
    74 
       
    75 // ---------------------------------------------------------
       
    76 // NewL
       
    77 // ---------------------------------------------------------
       
    78 CPostcardOperationSave* CPostcardOperationSave::NewL(
       
    79             MPostcardOperationObserver& aObserver,
       
    80             CPostcardDocument& aDocument,
       
    81             CPostcardAppUi& aAppUi,
       
    82             RFs& aFs,
       
    83             CContactCard& aContact,
       
    84             CPlainText& aPlainText )
       
    85     {
       
    86     CPostcardOperationSave* self = 
       
    87         new ( ELeave ) CPostcardOperationSave( aObserver, aDocument, aAppUi, aFs, aContact, aPlainText );
       
    88     CleanupStack::PushL( self );
       
    89     self->ConstructL();
       
    90     CleanupStack::Pop( self );
       
    91     return self;
       
    92     }
       
    93 
       
    94 // ---------------------------------------------------------
       
    95 // CPostcardOperationSave
       
    96 // ---------------------------------------------------------
       
    97 CPostcardOperationSave::CPostcardOperationSave(
       
    98             MPostcardOperationObserver& aObserver,
       
    99             CPostcardDocument& aDocument,
       
   100             CPostcardAppUi& aAppUi,
       
   101             RFs& aFs,
       
   102 			CContactCard& aContact,
       
   103 			CPlainText& aPlainText ) :
       
   104     CPostcardOperation( aObserver, aDocument, aAppUi, aFs ),
       
   105     iContact( aContact ),
       
   106     iPlainText( aPlainText )
       
   107     {
       
   108     }
       
   109 
       
   110 // ---------------------------------------------------------
       
   111 // CPostcardOperationSave
       
   112 // ---------------------------------------------------------
       
   113 CPostcardOperationSave::~CPostcardOperationSave( )
       
   114     {
       
   115     Cancel( );
       
   116     if( iTempFile )
       
   117         {
       
   118         iTempFile->Close( );
       
   119         delete iTempFile;
       
   120         }
       
   121     delete iSendOperation;
       
   122     delete iCharConv;
       
   123     delete iRecipientName;
       
   124     }
       
   125 
       
   126 // ---------------------------------------------------------
       
   127 // Start
       
   128 // ---------------------------------------------------------
       
   129 void CPostcardOperationSave::Start( TInt aArgument )
       
   130     {
       
   131     if( aArgument )
       
   132     	{
       
   133     	iFlags |= EPostcardSaveSend;
       
   134     	}
       
   135     if( iAppUi.CenRep().GetString( KPocaKeyServiceSpecialFormat ).Length() > 0 &&
       
   136         ( iFlags & EPostcardSaveSend ) )
       
   137         { // if special send format is defined and we are sending -> take it into use
       
   138         iFlags |= EPostcardSaveSpecialFormat;
       
   139         }
       
   140     iLaunchState = EPostcardSaveInitializing;
       
   141     CompleteSelf( KErrNone );
       
   142     }
       
   143 
       
   144 // ---------------------------------------------------------
       
   145 // DoLaunchStepL
       
   146 // ---------------------------------------------------------
       
   147 void CPostcardOperationSave::DoLaunchStepL( )
       
   148     {
       
   149     iFlags &= ~EPostcardSaveRequestActive;
       
   150     switch ( iLaunchState )
       
   151         {        
       
   152     	case EPostcardSaveInitializing:
       
   153     		{
       
   154     		InitL( );			
       
   155             iLaunchState = EPostcardSaveCheckAttas;
       
   156             CompleteSelf( KErrNone );
       
   157             break;    			
       
   158     		}
       
   159         case EPostcardSaveCheckAttas:
       
   160             {
       
   161             if( !CheckAttasL( ) )
       
   162             	{ // If there was an error, this has been completed already
       
   163 	            iLaunchState = EPostcardSaveRemoveOldAttas; 
       
   164 	            CompleteSelf( KErrNone );            		
       
   165             	}
       
   166             break;
       
   167             }
       
   168         case EPostcardSaveRemoveOldAttas:
       
   169             {
       
   170             RemoveOldAttasL( );
       
   171             // Let's see the next phase..
       
   172             if( iPlainText.DocumentLength( ) > 0 && iDocument.Changed( EPostcardText ) )
       
   173                 { // We have text and it has changed -> so save it..
       
   174                 iLaunchState = EPostcardSaveCreateTextAtta;
       
   175                 }
       
   176             else if ( ( iFlags & EPostcardSaveSend ) &&
       
   177                       ( iFlags & EPostcardSaveSpecialFormat ) )
       
   178                 { // Text has not changed, but we have special format on -> so create text atta anyway
       
   179                 iLaunchState = EPostcardSaveCreateTextAtta;                
       
   180                 }
       
   181             else if ( iDocument.Changed( EPostcardRecipient ) )
       
   182                 { // We are not sending special format, but the recipient has changed
       
   183                 iLaunchState = EPostcardSaveCreateRecipientAtta;
       
   184                 }
       
   185             else if(   !iSmil && 
       
   186                     (  iFlags & EPostcardSaveSend ) &&
       
   187                     !( iFlags & EPostcardSaveSpecialFormat ) )
       
   188                 { // Text and recipient have not changed, but we are sending OMA Postcard and there's no SMIL yet
       
   189                 iLaunchState = EPostcardSaveCreateSmilAtta;
       
   190                 }
       
   191             else
       
   192                 {
       
   193                 iLaunchState = EPostcardSaveUninit;
       
   194                 }
       
   195             CompleteSelf( KErrNone );
       
   196             break;
       
   197             }
       
   198         case EPostcardSaveCreateTextAtta:
       
   199             {
       
   200             CreateNewTextAttaL( );
       
   201             iLaunchState = EPostcardSaveSaveTextAtta;
       
   202 		    SetActive();    
       
   203             break;
       
   204             }
       
   205         case EPostcardSaveSaveTextAtta:
       
   206             {
       
   207             HandleTextL( );
       
   208             iLaunchState = EPostcardSaveFinalizeTextAtta;
       
   209             CompleteSelf( KErrNone );
       
   210             break;
       
   211             }
       
   212         case EPostcardSaveFinalizeTextAtta:
       
   213             {
       
   214             FinalizeTextL( );
       
   215             if ( iDocument.Changed( EPostcardRecipient ) &&
       
   216                 ( iFlags & EPostcardSaveHasContact ) )
       
   217                 { // We are not sending special format, but the recipient has changed
       
   218                 iLaunchState = EPostcardSaveCreateRecipientAtta;
       
   219                 }
       
   220             else if(   !iSmil && 
       
   221                     (  iFlags & EPostcardSaveSend ) &&
       
   222                     !( iFlags & EPostcardSaveSpecialFormat ) )
       
   223                 { // Recipient has not changed, but we are sending OMA Postcard and there's no SMIL yet
       
   224                 iLaunchState = EPostcardSaveCreateSmilAtta;
       
   225                 }
       
   226             else
       
   227                 {
       
   228                 iLaunchState = EPostcardSaveUninit;
       
   229                 }
       
   230             CompleteSelf( KErrNone );
       
   231             break;
       
   232             }
       
   233         case EPostcardSaveCreateRecipientAtta:
       
   234             {
       
   235             CreateNewRecipientAttaL( );
       
   236             iLaunchState = EPostcardSaveSaveRecipientAtta;
       
   237 		    SetActive( );        	
       
   238             break;
       
   239             }
       
   240         case EPostcardSaveSaveRecipientAtta:
       
   241             {
       
   242             HandleRecipientL( );
       
   243             iLaunchState = EPostcardSaveFinalizeRecipientAtta;
       
   244             CompleteSelf( KErrNone );
       
   245             break;
       
   246             }
       
   247         case EPostcardSaveFinalizeRecipientAtta:
       
   248             {
       
   249             FinalizeRecipientL( );
       
   250             if( !iSmil && 
       
   251                  ( iFlags & EPostcardSaveSend ) &&
       
   252                 !( iFlags & EPostcardSaveSpecialFormat ) )
       
   253                 { // Smil is created only to confront OMA Postcard spec
       
   254                 iLaunchState = EPostcardSaveCreateSmilAtta;
       
   255                 }
       
   256             else
       
   257                 {
       
   258                 // Smil seems to exists already or we are not sending
       
   259                 iLaunchState = EPostcardSaveUninit;                
       
   260                 }
       
   261             CompleteSelf( KErrNone );
       
   262             break;
       
   263             }
       
   264         case EPostcardSaveCreateSmilAtta:
       
   265             {
       
   266             CreateNewSmilAttaL( );
       
   267             iLaunchState = EPostcardSaveSaveSmilAtta;
       
   268 		    SetActive( );        	
       
   269             break;
       
   270             }
       
   271         case EPostcardSaveSaveSmilAtta:
       
   272             {
       
   273             HandleSmilL( );
       
   274             iLaunchState = EPostcardFinalizeSmilAtta;
       
   275             CompleteSelf( KErrNone );
       
   276             break;
       
   277             }
       
   278         case EPostcardFinalizeSmilAtta:
       
   279             {
       
   280             FinalizeSmilL( );
       
   281             iLaunchState = EPostcardSaveUninit;            
       
   282             CompleteSelf( KErrNone );
       
   283             break;
       
   284             }
       
   285         case EPostcardSaveUninit:
       
   286             {
       
   287             UnInitL( );
       
   288             iLaunchState = EPostcardSaveFinalizeMessage;
       
   289             CompleteSelf( KErrNone );
       
   290             break;
       
   291             }
       
   292         case EPostcardSaveFinalizeMessage:
       
   293             {
       
   294             FinalizeMessageL( );
       
   295             if( iFlags & EPostcardSaveSend )
       
   296             	{
       
   297 	            iLaunchState = EPostcardSaveStartSend;        	            		
       
   298             	}
       
   299             else
       
   300             	{
       
   301 	            iLaunchState = EPostcardSaveFinished;        	
       
   302             	}
       
   303             CompleteSelf( KErrNone );
       
   304             break;
       
   305             }
       
   306         case EPostcardSaveStartSend:
       
   307             {
       
   308             StartSendingL( );
       
   309             iLaunchState = EPostcardSaveFinished;        	
       
   310 		    SetActive();    
       
   311             break;
       
   312             }
       
   313         case EPostcardSaveFinished:
       
   314             {
       
   315             iObserver.PostcardOperationEvent(
       
   316                 EPostcardOperationSave,
       
   317                 EPostcardOperationComplete ); 
       
   318             break;
       
   319             }
       
   320         default:
       
   321             iObserver.PostcardOperationEvent(
       
   322                 EPostcardOperationSave,
       
   323                 EPostcardOperationError ); 
       
   324             break;
       
   325         }
       
   326     }
       
   327 
       
   328 // ---------------------------------------------------------
       
   329 // RemoveOldAttasL
       
   330 // ---------------------------------------------------------
       
   331 void CPostcardOperationSave::RemoveOldAttasL( )
       
   332 	{
       
   333 	if( 	iDocument.Changed( EPostcardText ) || 
       
   334 		( ( iFlags & EPostcardSaveSend ) && ( iFlags & EPostcardSaveSpecialFormat ) ) )
       
   335 		{
       
   336 		if( iText )
       
   337 			{ // Remove old
       
   338 			TInt old = TMsvIdToIndexL( iText );
       
   339 			if( old != KErrNotFound )
       
   340 			    {
       
   341 			    // If there is an old text atta and a no new text atta, we need to
       
   342 			    // ask commit here, otherwise old atta would be left with the message.
       
   343 			    iCommit = ETrue;
       
   344     			iStore->AttachmentManagerExtensionsL( ).RemoveAttachmentL( old );			    
       
   345 			    }
       
   346 			}		
       
   347 		}
       
   348 	if( 	iDocument.Changed( EPostcardRecipient ) || 
       
   349 		( ( iFlags & EPostcardSaveSend ) && ( iFlags & EPostcardSaveSpecialFormat ) ) )
       
   350 		{
       
   351 		if( iRecipient )
       
   352 			{ // Remove old
       
   353 			TInt old = TMsvIdToIndexL( iRecipient );
       
   354 			if( old != KErrNotFound )
       
   355 			    {
       
   356     			iStore->AttachmentManagerExtensionsL( ).RemoveAttachmentL( old );
       
   357 			    }
       
   358 			}		
       
   359 		}	
       
   360 	}
       
   361 	
       
   362 // ---------------------------------------------------------
       
   363 // CreateNewTextAttaL
       
   364 // ---------------------------------------------------------
       
   365 void CPostcardOperationSave::CreateNewTextAttaL( )
       
   366 	{
       
   367     // Now lets create a new attachment
       
   368     TFileName file( _L("greeting.txt") );
       
   369     StartCreatingEmptyAttachmentL( file );
       
   370 	}
       
   371 	
       
   372 // ---------------------------------------------------------
       
   373 // HandleTextL
       
   374 // ---------------------------------------------------------
       
   375 void CPostcardOperationSave::HandleTextL( )
       
   376 	{
       
   377     if( !iCharConv )
       
   378         {
       
   379         iCharConv = CCnvCharacterSetConverter::NewL( );
       
   380         }
       
   381 		
       
   382     if ( iCharConv->PrepareToConvertToOrFromL( KCharacterSetIdentifierUtf8, iFs )
       
   383         != CCnvCharacterSetConverter::EAvailable )
       
   384         {
       
   385         User::Leave( KErrNotSupported );
       
   386         }
       
   387 	
       
   388     // Delete possible old headers
       
   389     delete iHeaders;
       
   390     iHeaders = NULL;
       
   391     iHeaders = CMsvMimeHeaders::NewL( );
       
   392 
       
   393     if( ( iFlags & EPostcardSaveSend ) && !( iFlags & EPostcardSaveSpecialFormat ) )
       
   394         {
       
   395         iHeaders->XTypeParams().AppendL( KPostcardGreetingXParameter );
       
   396         iHeaders->XTypeParams().AppendL( TPtrC8() );	    
       
   397         }
       
   398 
       
   399     _LIT(KFileName, "text.txt");
       
   400     iHeaders->SetContentLocationL( KFileName );
       
   401     iHeaders->SetMimeCharset( KMmsUtf8 );
       
   402 
       
   403     TInt slash = KMsgMimeTextPlain().Locate( '/' );
       
   404     iHeaders->SetContentTypeL( KMsgMimeTextPlain().Left( slash ) );
       
   405     iHeaders->SetContentSubTypeL( KMsgMimeTextPlain().Mid( slash + 1 ) );
       
   406 
       
   407     iTempAtta->SetMimeTypeL( KMsgMimeTextPlain );
       
   408 
       
   409     iText = iTempAtta->Id( );
       
   410     RFileWriteStream writer( *iTempFile );
       
   411     writer.PushL( );
       
   412     delete iTempFile; // not close as write does it..
       
   413     iTempFile = NULL;
       
   414     
       
   415     TPtrC16 remainderOfUnicodeText;
       
   416     TInt numCleanupItems = 0;
       
   417     
       
   418     if( (iFlags & EPostcardSaveSend) && (iFlags & EPostcardSaveSpecialFormat ) )
       
   419         {
       
   420         // If we are here -> we are sending so we must have iContact OK
       
   421         HBufC* wholeText = MakeSpecialFormatTextL();
       
   422         CleanupStack::PushL( wholeText );
       
   423         numCleanupItems++;
       
   424 
       
   425         remainderOfUnicodeText.Set( wholeText->Des( ) );	
       
   426         
       
   427         // Now we remove the HasContact flag so that the recipient is not stored separately
       
   428 		iFlags &=  ~EPostcardSaveHasContact;
       
   429 		}
       
   430     else
       
   431         {
       
   432         remainderOfUnicodeText.Set(
       
   433             iPlainText.Read( 0, iPlainText.DocumentLength() ) );
       
   434         }
       
   435 
       
   436     // Now remainOfUnicodeText has the stuff needed to store into the greeting text
       
   437     TBuf8<128> outputBuffer;
       
   438     TInt returnValue;
       
   439     do
       
   440         {
       
   441         returnValue = iCharConv->ConvertFromUnicode(
       
   442             outputBuffer, remainderOfUnicodeText );
       
   443         if ( returnValue < 0 )
       
   444             {
       
   445             User::Leave(
       
   446                 returnValue == CCnvCharacterSetConverter::EErrorIllFormedInput ?
       
   447                 KErrCorrupt:KErrGeneral );
       
   448             }
       
   449         writer.WriteL( outputBuffer );
       
   450         remainderOfUnicodeText.Set( remainderOfUnicodeText.Right(
       
   451             returnValue ) );
       
   452         }
       
   453     while( returnValue );
       
   454 
       
   455     CleanupStack::PopAndDestroy( numCleanupItems );
       
   456     writer.Pop( );
       
   457     writer.Close( );	
       
   458 	}
       
   459 
       
   460 // ---------------------------------------------------------
       
   461 // MakeSpecialFormatTextL
       
   462 // ---------------------------------------------------------
       
   463 HBufC* CPostcardOperationSave::MakeSpecialFormatTextL()
       
   464     {
       
   465     CContactItemFieldSet& set = iContact.CardFields( );
       
   466     // Organise the address into an array
       
   467     CDesCArrayFlat* desarr = AddressArrayLC( set );
       
   468 
       
   469     const TDesC& replacement =
       
   470         iAppUi.CenRep().GetString( KPocaKeyServiceReplaceString );
       
   471     const TDesC& separator =
       
   472         iAppUi.CenRep().GetString( KPocaKeyServiceSeparator );
       
   473 
       
   474     // Add the greeting text.
       
   475     
       
   476     TInt len = iPlainText.DocumentLength();
       
   477     HBufC* buf = HBufC::NewLC( len );
       
   478     *buf = iPlainText.Read( 0, len );
       
   479 
       
   480     // Replace illegal chars
       
   481     TPtr des = buf->Des();
       
   482     ReplaceWith( des, separator, replacement );
       
   483     // And add this to the desarr
       
   484     desarr->InsertL( 0, *buf );
       
   485 
       
   486     // Read the format string from cenrep
       
   487     const TDesC& specialFormat =
       
   488         iAppUi.CenRep().GetString( KPocaKeyServiceSpecialFormat );
       
   489 
       
   490     // Construct the text to be sent. Room for each tag, strings between
       
   491     // tags and prefix and postfix.
       
   492     const TInt KMaxItems = TPostcardUtils::ENumSpecFormatTags * 2 + 1;
       
   493     TPtrC textItems[KMaxItems];
       
   494 
       
   495     TPtrC format(specialFormat);
       
   496     TInt position = 0;
       
   497     TInt numItems = 0;
       
   498     while(numItems < KMaxItems - 1 && position != KErrNotFound)
       
   499         {
       
   500         TInt tag;
       
   501         position = TPostcardUtils::NextTag(format, tag);
       
   502         if ( position != KErrNotFound )
       
   503             {
       
   504             textItems[numItems++].Set( format.Left( position ) );
       
   505             textItems[numItems++].Set( desarr->MdcaPoint( tag ) );
       
   506             format.Set( format.Right( format.Length() - position - 3 ) );
       
   507             }
       
   508         else
       
   509             {
       
   510             textItems[numItems++].Set( format );
       
   511             }
       
   512         }
       
   513         
       
   514     // Calculate buffer length needed to fit the whole text
       
   515     TInt buffSize = 0;
       
   516     for( TInt i = 0; i < numItems; i++ )
       
   517         {
       
   518         buffSize += textItems[i].Length();
       
   519         }
       
   520 
       
   521     // Copy text into buffer
       
   522     HBufC* dstBuf = HBufC::NewL( buffSize );
       
   523     TPtr dst = dstBuf->Des();
       
   524     for( TInt i = 0; i < numItems; i++ )
       
   525         {
       
   526         dst.Append( textItems[i] );
       
   527         }
       
   528 
       
   529     CleanupStack::PopAndDestroy( 2 ); // buff, desarr
       
   530 
       
   531     return dstBuf;
       
   532     }
       
   533 
       
   534 // ---------------------------------------------------------
       
   535 // FinalizeTextL
       
   536 // ---------------------------------------------------------
       
   537 void CPostcardOperationSave::FinalizeTextL( )
       
   538 	{
       
   539 	iHeaders->StoreL( *iTempAtta );
       
   540 	}
       
   541 	
       
   542 // ---------------------------------------------------------
       
   543 // CreateNewRecipientAttaL
       
   544 // ---------------------------------------------------------
       
   545 void CPostcardOperationSave::CreateNewRecipientAttaL( )
       
   546 	{
       
   547     // Now lets create a new attachment
       
   548     TFileName file( _L("recipient.vcf") );
       
   549     StartCreatingEmptyAttachmentL( file );
       
   550 	}
       
   551 	
       
   552 // ---------------------------------------------------------
       
   553 // HandleRecipientL
       
   554 // ---------------------------------------------------------
       
   555 void CPostcardOperationSave::HandleRecipientL( )
       
   556 	{
       
   557 	if( !iCharConv )
       
   558 		{
       
   559 	    iCharConv = CCnvCharacterSetConverter::NewL( );
       
   560 		}
       
   561     if ( iCharConv->PrepareToConvertToOrFromL( KCharacterSetIdentifierAscii, iFs ) !=
       
   562         CCnvCharacterSetConverter::EAvailable )
       
   563         {
       
   564         User::Leave( KErrNotSupported );
       
   565         }
       
   566 
       
   567 	// Delete possible old headers
       
   568 	delete iHeaders;
       
   569 	iHeaders = NULL;
       
   570 	iHeaders = CMsvMimeHeaders::NewL( );
       
   571    	iHeaders->SetContentLocationL( _L("recipient.vcf") );
       
   572 	
       
   573 	TInt slash = KMsgMimeVCard().Locate( '/' );
       
   574     iHeaders->SetContentTypeL( KMsgMimeVCard().Left( slash ) );
       
   575     iHeaders->SetContentSubTypeL( KMsgMimeVCard().Mid( slash + 1 ) );
       
   576 	
       
   577 	iTempAtta->SetMimeTypeL( KMsgMimeVCard );
       
   578 
       
   579     iRecipient = iTempAtta->Id( );    
       
   580         
       
   581     CParserVCard* parser = CParserVCard::NewL();
       
   582     CleanupStack::PushL(parser);
       
   583 
       
   584     RFileWriteStream vCardStream( *iTempFile );
       
   585     vCardStream.PushL( );    
       
   586     delete iTempFile; // not close as VCardStream does it..
       
   587     iTempFile = NULL;
       
   588 
       
   589 	iCharConv->SetReplacementForUnconvertibleUnicodeCharactersL( KReplaceChar8 );
       
   590 	
       
   591 	CContactItemFieldSet& set = iContact.CardFields( );
       
   592 
       
   593     const CContactItemField* field = TPostcardUtils::FieldOrNull( set,
       
   594         TPostcardUtils::ContactItemNameFromId( EPostcardAddressName ) );
       
   595 
       
   596     if( field )
       
   597         {
       
   598 		CParserPropertyValueHBufC* val =
       
   599 		    CParserPropertyValueHBufC::NewL( field->TextStorage()->Text() );
       
   600 		CleanupStack::PushL( val );
       
   601 		CArrayPtrFlat<CParserParam>* array = new(ELeave)CArrayPtrFlat<CParserParam>(1);
       
   602 		CleanupStack::PushL( array );
       
   603 		CParserProperty* property = CParserProperty::NewL( *val, KPostcardVCardName, array);
       
   604 		CleanupStack::PushL( property );
       
   605 		parser->AddPropertyL( property );
       
   606 		CleanupStack::Pop( 3, val );				
       
   607 		}
       
   608 
       
   609 	CDesCArrayFlat* desarr = VCardAddressArrayL( set ); // Organise the address into an array
       
   610 	CleanupStack::PushL( desarr );
       
   611 	// AddressArrayL does not add empty "PO Box" descriptor into the desarr
       
   612 	desarr->InsertL( 0, KNullDesC );
       
   613 
       
   614     CParserPropertyValue* val = new (ELeave)CParserPropertyValueCDesCArray(desarr);
       
   615     CleanupStack::Pop(desarr);
       
   616 	CleanupStack::PushL( val );
       
   617 	CArrayPtrFlat<CParserParam>* array = new(ELeave)CArrayPtrFlat<CParserParam>(1);
       
   618 	CleanupStack::PushL( array );
       
   619 
       
   620 	CParserProperty* property = CParserProperty::NewL( *val, KPostcardVCardAddr, array);
       
   621 	CleanupStack::PushL( property );
       
   622 	parser->AddPropertyL( property );
       
   623 	CleanupStack::Pop( 3, val );				
       
   624         
       
   625     parser->ExternalizeL(vCardStream);
       
   626 
       
   627     vCardStream.Pop( );
       
   628     vCardStream.Close( );
       
   629 
       
   630     CleanupStack::PopAndDestroy(parser);
       
   631 	}
       
   632 	
       
   633 // ---------------------------------------------------------
       
   634 // FinalizeRecipientL
       
   635 // ---------------------------------------------------------
       
   636 void CPostcardOperationSave::FinalizeRecipientL( )
       
   637 	{
       
   638 	iHeaders->StoreL( *iTempAtta );	
       
   639 	}
       
   640 
       
   641 // ---------------------------------------------------------
       
   642 // CreateNewSmilAttaL
       
   643 // ---------------------------------------------------------
       
   644 void CPostcardOperationSave::CreateNewSmilAttaL( )
       
   645     {
       
   646     // Now lets create a new attachment
       
   647     TFileName file( _L("postcard.smil") );
       
   648     StartCreatingEmptyAttachmentL( file );
       
   649     }
       
   650     
       
   651 // ---------------------------------------------------------
       
   652 // HandleSmilL
       
   653 // ---------------------------------------------------------
       
   654 void CPostcardOperationSave::HandleSmilL( )
       
   655     {
       
   656 	// Delete possible old headers
       
   657 	delete iHeaders;
       
   658 	iHeaders = NULL;
       
   659 	
       
   660 	iHeaders = CMsvMimeHeaders::NewL( );
       
   661    	iHeaders->SetContentLocationL( _L("pres.smil") );
       
   662 	
       
   663 	TInt slash = KMsgMimeSmil().Locate( '/' );
       
   664     iHeaders->SetContentTypeL( KMsgMimeSmil().Left( slash ) );
       
   665     iHeaders->SetContentSubTypeL( KMsgMimeSmil().Mid( slash + 1 ) );
       
   666     
       
   667 	iTempAtta->SetMimeTypeL( KMsgMimeSmil );
       
   668 
       
   669     iSmil = iTempAtta->Id( );
       
   670     
       
   671     // Get the name of the image file to be inserted into the SMIL file
       
   672     HBufC* fileName = GetImageFileNameL( );
       
   673     CleanupStack::PushL( fileName );
       
   674 	TInt resId = R_POSTCARD_OMA_SMIL;
       
   675 	HBufC* smil = StringLoader::LoadL( resId, *fileName );
       
   676     CleanupStack::PopAndDestroy( fileName );
       
   677     CleanupStack::PushL( smil );
       
   678 
       
   679     // convert the smil to 8-bit
       
   680     HBufC8* smil8 = HBufC8::NewLC( smil->Des( ).Length( ) );
       
   681     smil8->Des().Copy( smil->Des( ) );
       
   682 
       
   683     RFileWriteStream smilStream( *iTempFile );
       
   684     smilStream.PushL( );    
       
   685     
       
   686     delete iTempFile; // not close as smilStream does it
       
   687     iTempFile = NULL;
       
   688 
       
   689     smilStream.WriteL( *smil8 );
       
   690 
       
   691     smilStream.Close( );
       
   692     smilStream.Pop( );
       
   693     CleanupStack::PopAndDestroy( 2, smil ); // smil, smil8
       
   694     }
       
   695 
       
   696 // ---------------------------------------------------------
       
   697 // FinalizeSmilL
       
   698 // ---------------------------------------------------------
       
   699 void CPostcardOperationSave::FinalizeSmilL( )
       
   700     {
       
   701 	iHeaders->StoreL( *iTempAtta );
       
   702     }
       
   703 	
       
   704 // ---------------------------------------------------------
       
   705 // FinalizeMessageL
       
   706 // ---------------------------------------------------------
       
   707 void CPostcardOperationSave::FinalizeMessageL( )
       
   708 	{
       
   709 	
       
   710     const CMsvRecipientList& addresses = iDocument.Mtm( ).AddresseeList();
       
   711     
       
   712     if( addresses.Count( ) < 1 )
       
   713     	{
       
   714         iDocument.Mtm().AddAddresseeL(
       
   715             iAppUi.CenRep().GetString( KPocaKeyServiceProvider ) );
       
   716     	}
       
   717 	
       
   718 	// Disable delivery reports for postcards
       
   719 	iDocument.Mtm().SetDeliveryReport( EMmsNo );
       
   720 	
       
   721     iDocument.Mtm().SaveMessageL();
       
   722 
       
   723     TMmsMsvEntry tEntry = static_cast<TMmsMsvEntry>( iDocument.Entry() );
       
   724 	
       
   725     // Update timestamp  
       
   726     tEntry.iDate.UniversalTime();
       
   727 
       
   728     if ( !tEntry.Visible() )
       
   729         {
       
   730         // Save from close or exit save.
       
   731         // Message should be visible after save
       
   732         tEntry.SetVisible( ETrue );
       
   733         tEntry.SetInPreparation( EFalse );
       
   734         }
       
   735 
       
   736     if ( !tEntry.EditorOriented() )
       
   737         {
       
   738         tEntry.SetEditorOriented( ETrue );
       
   739         }
       
   740 
       
   741 	tEntry.iDetails.Set( iRecipientName->Des( ) ) ;
       
   742     tEntry.iDescription.Set(
       
   743         iPlainText.Read( 0, Min( iPlainText.DocumentLength(), 20 ) ) );
       
   744     
       
   745 	tEntry.iBioType = KUidMsgSubTypeMmsPostcard.iUid;
       
   746     
       
   747     iDocument.CurrentEntry().ChangeL( tEntry );
       
   748 	}
       
   749 
       
   750 // ---------------------------------------------------------
       
   751 // CPostcardOperationSave::StartSendingL
       
   752 // ---------------------------------------------------------
       
   753 void CPostcardOperationSave::StartSendingL( )
       
   754 	{
       
   755     iSendOperation = iDocument.Mtm().SendL( iStatus );
       
   756 	}
       
   757 
       
   758 // ---------------------------------------------------------
       
   759 // CPostcardOperationSave::ConstructL
       
   760 // ---------------------------------------------------------
       
   761 void CPostcardOperationSave::ConstructL( )
       
   762     {
       
   763     if( HasContact() )
       
   764         {
       
   765         iFlags |=  EPostcardSaveHasContact;
       
   766         CContactItemFieldSet& fieldSet =  iContact.CardFields();
       
   767         const CContactItemField* field = TPostcardUtils::FieldOrNull( fieldSet,
       
   768             TPostcardUtils::ContactItemNameFromId( EPostcardAddressName ) );
       
   769         if( field )
       
   770             {
       
   771             iRecipientName = field->TextStorage()->Text().AllocL();
       
   772             }
       
   773         }
       
   774     if( !iRecipientName )
       
   775         {
       
   776         iRecipientName = HBufC::NewL( 0 );
       
   777         }
       
   778     }
       
   779 
       
   780 // ---------------------------------------------------------
       
   781 // CPostcardOperationSave::DoCancel
       
   782 // ---------------------------------------------------------
       
   783 void CPostcardOperationSave::DoCancel( )
       
   784     {
       
   785     if( iManager )
       
   786         {
       
   787         if( iFlags & EPostcardSaveRequestActive )
       
   788             { // Attachment Manager request going on -> cancel
       
   789             iManager->CancelRequest();        
       
   790             }
       
   791         }
       
   792     }
       
   793 
       
   794 // ---------------------------------------------------------
       
   795 // RunL
       
   796 // ---------------------------------------------------------
       
   797 void CPostcardOperationSave::RunL( )
       
   798     {
       
   799     DoLaunchStepL( );
       
   800     }
       
   801 
       
   802 // ---------------------------------------------------------
       
   803 // RunError
       
   804 // ---------------------------------------------------------
       
   805 TInt CPostcardOperationSave::RunError( TInt aError )
       
   806     {
       
   807     iLaunchState = -1;
       
   808     SetError( aError );
       
   809     iObserver.PostcardOperationEvent(
       
   810         EPostcardOperationSave,
       
   811         EPostcardOperationError );     
       
   812     return KErrNone;
       
   813     }
       
   814 
       
   815 // ---------------------------------------------------------
       
   816 // StartCreatingEmptyAttachmentL
       
   817 // ---------------------------------------------------------
       
   818 void CPostcardOperationSave::StartCreatingEmptyAttachmentL( const TFileName& aFileName )
       
   819     {
       
   820     CMsvAttachment* attachment = CMsvAttachment::NewL( CMsvAttachment::EMsvFile );
       
   821     CleanupStack::PushL( attachment );
       
   822     iTempFile = new ( ELeave ) RFile;
       
   823     iManager->CreateAttachmentL( aFileName, *iTempFile, attachment, iStatus );
       
   824     iFlags |= EPostcardSaveRequestActive;
       
   825     CleanupStack::Pop( attachment );
       
   826     iTempAtta = attachment;
       
   827     iCommit = ETrue;
       
   828     }
       
   829     
       
   830 // ---------------------------------------------------------
       
   831 // HasContact
       
   832 // ---------------------------------------------------------
       
   833 TBool CPostcardOperationSave::HasContact( )
       
   834 	{
       
   835 	CContactItemFieldSet& set = iContact.CardFields( );
       
   836 	for( TInt i = 0; i<set.Count( ); i++ )
       
   837 		{
       
   838 		CContactItemField& field = set[i];
       
   839 		if( field.TextStorage( )->Text( ).Length( ) > 0 )
       
   840 			{
       
   841 			return ETrue;
       
   842 			}
       
   843 		}
       
   844 	return EFalse;	
       
   845 	}
       
   846     
       
   847 // ---------------------------------------------------------
       
   848 // AddressArrayLC
       
   849 // ---------------------------------------------------------
       
   850 CDesCArrayFlat* CPostcardOperationSave::AddressArrayLC( CContactItemFieldSet& aSet )
       
   851 	{
       
   852     // Get contact fields into an array. No ownership.
       
   853     const CContactItemField* fields[ CPostcardAddressForm::ENumAddrFields ];
       
   854 
       
   855     const TInt first = EPostcardAddressName;
       
   856     const TInt last = EPostcardAddressCountry;
       
   857     for( TInt i = first; i <= last; i++)
       
   858         {
       
   859         fields[i - first] = TPostcardUtils::FieldOrNull(
       
   860             aSet, TPostcardUtils::ContactItemNameFromId( i ) );
       
   861         }
       
   862 
       
   863     CDesCArrayFlat* desarr =
       
   864         new( ELeave ) CDesCArrayFlat( CPostcardAddressForm::ENumAddrFields );
       
   865     CleanupStack::PushL(desarr);
       
   866 
       
   867     for( TInt i = 0; i < CPostcardAddressForm::ENumAddrFields; i++ )
       
   868         {
       
   869         if( fields[i] )
       
   870             {
       
   871             if( ( iFlags & EPostcardSaveSend) &&
       
   872                 (iFlags & EPostcardSaveSpecialFormat ) )
       
   873                 { // We are sending & have the special format on
       
   874                 // so lets replace possible user added separator strings
       
   875                 TPtr string = fields[i]->TextStorage()->Text().AllocLC()->Des();
       
   876                 // Trim leading and trailing white space so it doesn't affect
       
   877                 // parsing of special format string when opened from sent
       
   878                 // folder.
       
   879                 string.Trim();
       
   880                 ReplaceWith( string,
       
   881                     iAppUi.CenRep().GetString( KPocaKeyServiceSeparator ),
       
   882                     iAppUi.CenRep().GetString( KPocaKeyServiceReplaceString )
       
   883                     );
       
   884                 desarr->AppendL( string );
       
   885                 CleanupStack::PopAndDestroy(); // string
       
   886                 }
       
   887             else
       
   888                 { // Otherwise just add the data field
       
   889                 desarr->AppendL( fields[i]->TextStorage()->Text() );
       
   890                 }
       
   891             }
       
   892         else
       
   893             {
       
   894             desarr->AppendL( KNullDesC );
       
   895             }
       
   896         }
       
   897     return desarr;
       
   898     }
       
   899 
       
   900 // ---------------------------------------------------------
       
   901 // VCardAddressArrayL
       
   902 // ---------------------------------------------------------
       
   903 CDesCArrayFlat* CPostcardOperationSave::VCardAddressArrayL( CContactItemFieldSet& aSet )
       
   904     {
       
   905     // Exclude name
       
   906     const TInt KPocaVCardAddrFields = CPostcardAddressForm::ENumAddrFields - 1;
       
   907 
       
   908     // Get contact fields into an array. No ownership.
       
   909     const CContactItemField* fields[ KPocaVCardAddrFields ];
       
   910 
       
   911     // Order of contact fields in array
       
   912     static const TInt ids[KPocaVCardAddrFields] =
       
   913         {
       
   914         EPostcardAddressInfo, EPostcardAddressStreet, EPostcardAddressCity,
       
   915         EPostcardAddressState, EPostcardAddressZip, EPostcardAddressCountry
       
   916         };
       
   917     
       
   918     for( TInt i = 0; i < KPocaVCardAddrFields; i++)
       
   919         {
       
   920         fields[i] = TPostcardUtils::FieldOrNull(
       
   921             aSet, TPostcardUtils::ContactItemNameFromId( ids[i] ) );
       
   922         }
       
   923 
       
   924     CDesCArrayFlat* desarr = new(ELeave) CDesCArrayFlat( KPocaVCardAddrFields );
       
   925     CleanupStack::PushL( desarr );
       
   926 
       
   927     for( TInt i = 0; i < KPocaVCardAddrFields; i++ )
       
   928         {
       
   929         desarr->AppendL(
       
   930             fields[i] ? fields[i]->TextStorage()->Text() : KNullDesC() );
       
   931         }
       
   932 
       
   933 	CleanupStack::Pop( desarr );
       
   934 	return desarr;
       
   935     }
       
   936 
       
   937 // ---------------------------------------------------------
       
   938 // ReplaceWith
       
   939 // ---------------------------------------------------------
       
   940 void CPostcardOperationSave::ReplaceWith( TDes& aOrig, const TDesC& aWhat,
       
   941     const TDesC& aWith )
       
   942     {    
       
   943 	TInt pos = 0;
       
   944 	TInt foundPos = 0;
       
   945 	TBool found = ETrue;
       
   946 
       
   947 	while( found )
       
   948 	    {
       
   949 	    found = EFalse;
       
   950 		if( pos >= aOrig.Length( ) )
       
   951 			{
       
   952 			continue; // as found is false -> while is not true anymore
       
   953 			}	
       
   954 				
       
   955     	foundPos =  aOrig.Mid( pos, aOrig.Length()-pos ).Find( aWhat );
       
   956     	
       
   957 		if( foundPos == KErrNotFound )
       
   958 			{ // Not found anymore, so the rest is ok
       
   959 			continue; // as found is false -> while is not true anymore
       
   960 			}
       
   961 			
       
   962         found = ETrue;
       
   963 		// As foundPos is related to previous sepa char, we need to add the beginning, too
       
   964 		foundPos += pos;
       
   965 		aOrig.Replace( foundPos, aWhat.Length( ), aWith );
       
   966 	    pos = foundPos + aWhat.Length( ) + ( aWith.Length( ) - aWhat.Length( ) );
       
   967 	    }    
       
   968     }
       
   969 
       
   970 // ---------------------------------------------------------
       
   971 // GetImageFileName
       
   972 // ---------------------------------------------------------
       
   973 HBufC* CPostcardOperationSave::GetImageFileNameL( )
       
   974     {
       
   975     // Goes thru the attas and check how many images, text and recipients there are
       
   976     TInt count = iManager->AttachmentCount( );
       
   977     CMsvAttachment* atta = NULL;
       
   978 
       
   979     HBufC* nameString = NULL;
       
   980     for(TInt a = 0; a<count && !nameString; a++)
       
   981         {
       
   982         atta = iManager->GetAttachmentInfoL( a );
       
   983         CleanupStack::PushL( atta );
       
   984 
       
   985         switch( RecogniseFileType( atta->MimeType( ) ) )
       
   986             {
       
   987             case EPostcardFileImage:
       
   988                 {
       
   989                 CMsvMimeHeaders* msvMime = CMsvMimeHeaders::NewLC();
       
   990                 msvMime->RestoreL( *atta );
       
   991                 nameString = msvMime->ContentLocation().AllocL();
       
   992                 CleanupStack::PopAndDestroy( msvMime ); // msvMime, atta
       
   993                 break;
       
   994                 }
       
   995             default:
       
   996                 break;
       
   997             }
       
   998         CleanupStack::PopAndDestroy( atta );
       
   999         }
       
  1000     return nameString ? nameString : HBufC::NewL( 0 );
       
  1001     }
       
  1002     
       
  1003 // EOF