|
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 * CPostcardOperationOpen |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 |
|
21 // ========== INCLUDE FILES ================================ |
|
22 |
|
23 #include <AknsConstants.h> |
|
24 #include <data_caging_path_literals.hrh> |
|
25 #include <apmstd.h> // TDataType |
|
26 #include <gulicon.h> // CGulIcon |
|
27 #include <txtetext.h> // For TDocumentStorage |
|
28 |
|
29 #include <MsgMediaInfo.h> |
|
30 #include <MsgMedia.hrh> |
|
31 #include <MsgImageInfo.h> |
|
32 #include <MsgMediaResolver.h> // for CMmsMediaResolver |
|
33 #include <MsgTextInfo.h> |
|
34 #include <msgtextutils.h> |
|
35 #include <MsgMimeTypes.h> |
|
36 |
|
37 #include <IHLImageFactory.h> |
|
38 #include <IHLViewerFactory.h> |
|
39 #include <MIHLFileImage.h> |
|
40 #include <MIHLBitmap.h> |
|
41 #include <MIHLImageViewer.h> |
|
42 |
|
43 #include <mmsvattachmentmanager.h> // AttachmentManager |
|
44 #include <mmsvattachmentmanagersync.h> // AttachmentManagerSync |
|
45 #include <cmsvmimeheaders.h> // MimeHeaders |
|
46 #include <mmsclient.h> |
|
47 |
|
48 #include <vprop.h> // VCardPropertyValue |
|
49 #include <cntitem.h> |
|
50 #include <vcard.h> |
|
51 #include <cntfldst.h> // CContactTextField |
|
52 |
|
53 #include <StringLoader.h> // for StringLoader |
|
54 |
|
55 #include <Postcard.rsg> // for Postcard resources |
|
56 #include "PostcardLaf.h" |
|
57 #include "PostcardUtils.h" |
|
58 #include "Postcard.hrh" |
|
59 #include "PostcardOperationOpen.h" |
|
60 #include "PostcardRecipientWrapper.h" |
|
61 #include "PostcardContact.h" |
|
62 #include "PostcardPrivateCRKeys.h" // cenrep keys |
|
63 #include "PostcardCenRep.h" |
|
64 |
|
65 // ========== EXTERNAL DATA STRUCTURES ===================== |
|
66 |
|
67 // ========== EXTERNAL FUNCTION PROTOTYPES ================= |
|
68 |
|
69 // ========== CONSTANTS ==================================== |
|
70 |
|
71 // ========== MACROS ======================================= |
|
72 |
|
73 // ========== LOCAL CONSTANTS AND MACROS =================== |
|
74 |
|
75 // This was "FN" in 3.0-3.1 but OMA says it should be "N". Accept |
|
76 // both when opening and be compatible with both. |
|
77 _LIT8(KPostcardVCardName, "N"); |
|
78 _LIT8(KPostcardVCardNameFN, "FN"); |
|
79 _LIT8(KPostcardVCardAddr, "ADR"); |
|
80 |
|
81 // ========== MODULE DATA STRUCTURES ======================= |
|
82 |
|
83 // ========== LOCAL FUNCTION PROTOTYPES ==================== |
|
84 |
|
85 // ========== LOCAL FUNCTIONS ============================== |
|
86 |
|
87 // ========== MEMBER FUNCTIONS ============================= |
|
88 |
|
89 // --------------------------------------------------------- |
|
90 // CPostcardOperationOpen::NewL |
|
91 // --------------------------------------------------------- |
|
92 CPostcardOperationOpen* CPostcardOperationOpen::NewL( |
|
93 MPostcardOperationObserver& aObserver, |
|
94 CPostcardDocument& aDocument, |
|
95 CPostcardAppUi& aAppUi, |
|
96 RFs& aFs ) |
|
97 { |
|
98 CPostcardOperationOpen* self = |
|
99 new ( ELeave ) CPostcardOperationOpen( aObserver, aDocument, aAppUi, aFs ); |
|
100 CleanupStack::PushL( self ); |
|
101 self->ConstructL( ); |
|
102 CleanupStack::Pop( self ); |
|
103 return self; |
|
104 } |
|
105 |
|
106 // --------------------------------------------------------- |
|
107 // CPostcardOperationOpen::CPostcardOperationOpen |
|
108 // --------------------------------------------------------- |
|
109 CPostcardOperationOpen::CPostcardOperationOpen( |
|
110 MPostcardOperationObserver& aObserver, |
|
111 CPostcardDocument& aDocument, |
|
112 CPostcardAppUi& aAppUi, |
|
113 RFs& aFs ) : |
|
114 CPostcardOperation( aObserver, aDocument, aAppUi, aFs ), |
|
115 iSpecialFormat( aAppUi.CenRep().GetString( KPocaKeyServiceSpecialFormat ) ), |
|
116 iSeparatorChar( aAppUi.CenRep().GetString( KPocaKeyServiceSeparator ) ) |
|
117 { |
|
118 } |
|
119 |
|
120 // --------------------------------------------------------- |
|
121 // CPostcardOperationOpen::CPostcardOperationOpen |
|
122 // --------------------------------------------------------- |
|
123 CPostcardOperationOpen::~CPostcardOperationOpen( ) |
|
124 { |
|
125 if( iEditFile ) |
|
126 { |
|
127 iEditFile->Close(); |
|
128 delete iEditFile; |
|
129 } |
|
130 delete iImageInfo; |
|
131 delete iImageProcessor; |
|
132 } |
|
133 |
|
134 // --------------------------------------------------------- |
|
135 // CPostcardOperationOpen::Start |
|
136 // --------------------------------------------------------- |
|
137 void CPostcardOperationOpen::Start( TInt /*aArgument*/ ) |
|
138 { |
|
139 ToState( EPostcardOpenInitializing ); |
|
140 } |
|
141 |
|
142 // --------------------------------------------------------- |
|
143 // CPostcardOperationOpen::Launch |
|
144 // --------------------------------------------------------- |
|
145 void CPostcardOperationOpen::DoLaunchStepL() |
|
146 { |
|
147 iFlags &= ~EPostcardOpenRequestActive; |
|
148 switch ( iLaunchState ) |
|
149 { |
|
150 case EPostcardOpenInitializing: |
|
151 { |
|
152 InitL( ); |
|
153 iDocument.InitializeL( iFs ); |
|
154 ToState( EPostcardOpenCheckAttas ); |
|
155 break; |
|
156 } |
|
157 case EPostcardOpenCheckAttas: |
|
158 { |
|
159 if( !CheckAttasL( ) ) |
|
160 { // If there was error, this has been completed already |
|
161 ToState( EPostcardOpenHandleImage ); |
|
162 } |
|
163 else |
|
164 { |
|
165 iLaunchState = EPostcardOpenError; |
|
166 } |
|
167 break; |
|
168 } |
|
169 case EPostcardOpenHandleImage: |
|
170 { |
|
171 DoHandleImageL( ); |
|
172 break; |
|
173 } |
|
174 case EPostcardOpenProcessImage: |
|
175 { |
|
176 DoStartProcessImageL( ); |
|
177 break; |
|
178 } |
|
179 case EPostcardOpenHandleText: |
|
180 { |
|
181 DoHandleTextL( ); |
|
182 break; |
|
183 } |
|
184 case EPostcardOpenHandleRecipient: |
|
185 { |
|
186 DoHandleRecipientL( ); |
|
187 ToState( EPostcardOpenFinished ); |
|
188 break; |
|
189 } |
|
190 case EPostcardOpenFinished: |
|
191 { |
|
192 UnInitL( ); |
|
193 iObserver.PostcardOperationEvent( |
|
194 EPostcardOperationOpen, |
|
195 EPostcardOperationComplete ); |
|
196 break; |
|
197 } |
|
198 default: |
|
199 UnInitL( ); |
|
200 iObserver.PostcardOperationEvent( |
|
201 EPostcardOperationOpen, |
|
202 EPostcardOperationError ); |
|
203 break; |
|
204 } |
|
205 } |
|
206 |
|
207 // --------------------------------------------------------- |
|
208 // DoHandleL |
|
209 // --------------------------------------------------------- |
|
210 void CPostcardOperationOpen::DoHandleImageL( ) |
|
211 { |
|
212 if ( iImage != 0 ) |
|
213 { |
|
214 if( iDocument.MessageType( ) == EPostcardSendAs ) |
|
215 { // SendAs -> Lets see what's inside |
|
216 RFile imageFile = iManager->GetAttachmentFileL( iImage ); |
|
217 CleanupClosePushL( imageFile ); |
|
218 iImageInfo = iDocument.MediaResolver()->CreateMediaInfoL( imageFile ); |
|
219 iDocument.MediaResolver()->ParseInfoDetailsL( iImageInfo, imageFile ); |
|
220 |
|
221 // Lets first check if the file seems to be ok for inserting |
|
222 if( iImageInfo->Protection( ) ) |
|
223 { |
|
224 CleanupStack::PopAndDestroy( &imageFile ); // imageFile |
|
225 ToErrorState( R_POSTCARD_CANNOT_SEND_PROTECTED ); |
|
226 return; |
|
227 } |
|
228 if( iImageInfo->Corrupt( ) ) |
|
229 { |
|
230 // Corrupt is set to only supported media types |
|
231 CleanupStack::PopAndDestroy( &imageFile ); // imageFile |
|
232 ToErrorState( R_POSTCARD_OBJECT_CORRUPTED ); |
|
233 return; |
|
234 } |
|
235 else if ( !iDocument.IsImage( iImageInfo->MimeType( ) ) ) |
|
236 { |
|
237 CleanupStack::PopAndDestroy( &imageFile ); // imageFile |
|
238 ToErrorState( R_POSTCARD_FORMAT_NOT_SUPPORTED ); |
|
239 return; |
|
240 } |
|
241 else if ( iImageInfo->MediaType() != EMsgMediaImage ) |
|
242 { |
|
243 CleanupStack::PopAndDestroy( &imageFile ); // imageFile |
|
244 ToErrorState( R_POSTCARD_FORMAT_NOT_SUPPORTED ); |
|
245 return; |
|
246 } |
|
247 else if ( static_cast<CMsgImageInfo*>(iImageInfo)->IsAnimation( ) ) |
|
248 { |
|
249 CleanupStack::PopAndDestroy( &imageFile ); // imageFile |
|
250 ToErrorState( R_POSTCARD_FORMAT_NOT_SUPPORTED ); |
|
251 return; |
|
252 } |
|
253 |
|
254 TSize dimensions = static_cast<CMsgImageInfo*>(iImageInfo)->Dimensions( ); |
|
255 TInt imageWidth = dimensions.iWidth>dimensions.iHeight?dimensions.iWidth:dimensions.iHeight; |
|
256 TInt imageHeight = dimensions.iWidth>dimensions.iHeight?dimensions.iHeight:dimensions.iWidth; |
|
257 |
|
258 TSize maxSize = iDocument.MaxImageDimensions( ); |
|
259 |
|
260 // OK, it seems to be pretty ok, now lets see what we can do |
|
261 if( ( iImageInfo->MimeType( ).CompareF( KMsgMimeImagePng ) == 0 ) |
|
262 || ( ( imageWidth > maxSize.iWidth || imageHeight > maxSize.iHeight ) |
|
263 && iImageInfo->FileSize( ) > iDocument.MaxImageSize( ) ) ) |
|
264 { // This is PNG or it's a too wide JPEG file |
|
265 iEditFile = new ( ELeave ) RFile; |
|
266 CMsvAttachment* attachment = CMsvAttachment::NewL( CMsvAttachment::EMsvFile ); |
|
267 CleanupStack::PushL( attachment ); |
|
268 attachment->SetAttachmentNameL( KPostcardFilenameScaled ); |
|
269 iManager->CreateAttachmentL( KPostcardFilenameScaled, *iEditFile, attachment, iStatus ); |
|
270 iFlags |= EPostcardOpenRequestActive; |
|
271 CleanupStack::Pop( attachment ); // attachment |
|
272 iEditAtta = attachment; |
|
273 iLaunchState = EPostcardOpenProcessImage; |
|
274 SetActive(); |
|
275 CleanupStack::PopAndDestroy( &imageFile ); // imagefile |
|
276 return; |
|
277 } |
|
278 else if( iImageInfo->FileSize( ) > iDocument.MaxImageSize( ) ) |
|
279 { // Image is too big, but not too wide -> create empty attachment for now |
|
280 iEditFile = new ( ELeave ) RFile; |
|
281 CMsvAttachment* attachment = CMsvAttachment::NewL( CMsvAttachment::EMsvFile ); |
|
282 CleanupStack::PushL( attachment ); |
|
283 attachment->SetAttachmentNameL( KPostcardFilenameCompressed ); |
|
284 iManager->CreateAttachmentL( KPostcardFilenameCompressed, *iEditFile, attachment, iStatus ); |
|
285 iFlags |= EPostcardOpenRequestActive; |
|
286 CleanupStack::Pop( attachment ); // attachment |
|
287 iEditAtta = attachment; |
|
288 iLaunchState = EPostcardOpenProcessImage; |
|
289 SetActive(); |
|
290 CleanupStack::PopAndDestroy( &imageFile ); // imagefile |
|
291 return; |
|
292 } |
|
293 else |
|
294 { // OK, the file is ok, we just need to update the MsvHeaders |
|
295 DoUpdateSendasAttachmentL( iImageInfo->MimeType( ) ); |
|
296 } |
|
297 CleanupStack::PopAndDestroy( ); // imagefile |
|
298 } |
|
299 // Either this is not sendas or the image did not need conversion or compression |
|
300 RFile imageFile = iManager->GetAttachmentFileL( iImage ); |
|
301 CleanupClosePushL( imageFile ); |
|
302 |
|
303 // Scale image to bitmap to be drawn on the screen |
|
304 iSourceImage = IHLImageFactory::OpenFileImageL( imageFile ); |
|
305 iDestinationBitmap = IHLBitmap::CreateL(); |
|
306 iImageHandler = IHLViewerFactory::CreateImageViewerL( PostcardLaf::Image( ).Size( ), |
|
307 *iSourceImage, |
|
308 *iDestinationBitmap, |
|
309 *this, |
|
310 TUint32( 0 ) ); |
|
311 User::LeaveIfError( iImageHandler->SetSourceRectPosition( TPoint( 0, 0 ) ) ); |
|
312 |
|
313 CleanupStack::PopAndDestroy( &imageFile ); // imageFile |
|
314 } |
|
315 else |
|
316 { |
|
317 ToState( EPostcardOpenHandleText ); |
|
318 } |
|
319 } |
|
320 |
|
321 // --------------------------------------------------------- |
|
322 // DoStartProcessImageL |
|
323 // --------------------------------------------------------- |
|
324 void CPostcardOperationOpen::DoStartProcessImageL( ) |
|
325 { |
|
326 RFile sourceFile = iManager->GetAttachmentFileL( iImage ); |
|
327 CleanupClosePushL( sourceFile ); |
|
328 if( !iImageProcessor ) |
|
329 { |
|
330 iImageProcessor = new (ELeave) CUniImageProcessor( this ); |
|
331 } |
|
332 TSize maxDimensions = iDocument.MaxImageDimensions( ); |
|
333 |
|
334 TSize origDimensions = static_cast<CMsgImageInfo*>(iImageInfo)->Dimensions( ); |
|
335 |
|
336 if( origDimensions.iWidth < origDimensions.iHeight ) |
|
337 { // It's portrait so swap max dimensions |
|
338 origDimensions = maxDimensions; |
|
339 maxDimensions.iWidth = origDimensions.iHeight; |
|
340 maxDimensions.iHeight = origDimensions.iWidth; |
|
341 } |
|
342 |
|
343 iImageProcessor->ProcessImageL( sourceFile, |
|
344 *iEditFile, |
|
345 maxDimensions, |
|
346 KMsgMimeImageJpeg, |
|
347 ETrue, |
|
348 iDocument.MaxImageSize( ) ); |
|
349 CleanupStack::PopAndDestroy(); // sourceFile |
|
350 } |
|
351 |
|
352 // --------------------------------------------------------- |
|
353 // DoUpdateSendasAttachmentL |
|
354 // --------------------------------------------------------- |
|
355 void CPostcardOperationOpen::DoUpdateSendasAttachmentL( const TDataType& aMimeType ) |
|
356 { |
|
357 CMsvMimeHeaders* headers = CMsvMimeHeaders::NewLC( ); |
|
358 if( aMimeType.Des8( ).CompareF( KMsgMimeImageGif ) == 0 ) |
|
359 { // Image is gif |
|
360 headers->SetContentLocationL( KPostcardFilenameNoOpGif); |
|
361 } |
|
362 else |
|
363 { |
|
364 headers->SetContentLocationL( KPostcardFilenameNoOp ); |
|
365 } |
|
366 headers->SetContentTypeL( aMimeType.Des8( ) ); |
|
367 |
|
368 // As this function is called only when in SendAs |
|
369 // there's certainly just one attachment so we index it directly |
|
370 CMsvAttachment* attachment = iManager->GetAttachmentInfoL( 0 ); |
|
371 CleanupStack::PushL( attachment ); |
|
372 headers->StoreL( *attachment ); |
|
373 attachment->SetMimeTypeL( aMimeType.Des8( ) ); |
|
374 iStore->AttachmentManagerExtensionsL( ).ModifyAttachmentInfoL( attachment ); |
|
375 CleanupStack::Pop( attachment ); |
|
376 |
|
377 CleanupStack::PopAndDestroy( headers ); |
|
378 |
|
379 iStore->Commit( ); |
|
380 // Lets check again (to get right AttachmentIds) |
|
381 CheckAttasL( ); |
|
382 } |
|
383 |
|
384 // --------------------------------------------------------- |
|
385 // ImageProcessingReady |
|
386 // --------------------------------------------------------- |
|
387 void CPostcardOperationOpen::ImageProcessingReady( TSize aBitmapSize, TInt aFileSize, TBool /*aCompressed*/ ) |
|
388 { |
|
389 if( iEditFile ) |
|
390 { |
|
391 iEditFile->Close(); |
|
392 delete iEditFile; |
|
393 iEditFile = NULL; |
|
394 } |
|
395 |
|
396 TBool imageFits = EFalse; |
|
397 TSize maxDimensions = iDocument.MaxImageDimensions( ); |
|
398 if( aBitmapSize.iWidth <= maxDimensions.iWidth && |
|
399 aBitmapSize.iHeight <= maxDimensions.iHeight ) |
|
400 { |
|
401 imageFits = ETrue; |
|
402 } |
|
403 else if( aBitmapSize.iWidth <= maxDimensions.iHeight && |
|
404 aBitmapSize.iHeight <= maxDimensions.iWidth ) |
|
405 { |
|
406 imageFits = ETrue; |
|
407 } |
|
408 |
|
409 if( !imageFits || aFileSize > iDocument.MaxImageSize( ) ) |
|
410 { // The process was not successful |
|
411 ToErrorState( R_POSTCARD_PROCESS_NOT_SUCCESSFUL ); |
|
412 return; |
|
413 } |
|
414 |
|
415 // Call this to start scaling to screen (deletes the previous image etc..) |
|
416 TRAPD( err, StartScalingToScreenL( ) ); |
|
417 if( err ) |
|
418 { |
|
419 ToErrorState( R_POSTCARD_FORMAT_NOT_SUPPORTED ); |
|
420 } |
|
421 } |
|
422 |
|
423 // --------------------------------------------------------- |
|
424 // StartScalingToScreenL |
|
425 // --------------------------------------------------------- |
|
426 void CPostcardOperationOpen::StartScalingToScreenL( ) |
|
427 { |
|
428 TInt oldImage = TMsvIdToIndexL( iImage ); |
|
429 iStore->AttachmentManagerExtensionsL( ).RemoveAttachmentL( oldImage ); |
|
430 iStore->Commit( ); |
|
431 |
|
432 DoUpdateSendasAttachmentL( iImageInfo->MimeType( ) ); |
|
433 |
|
434 // Lets add headers |
|
435 RFile imageFile = iManager->GetAttachmentFileL( iImage ); |
|
436 CleanupClosePushL( imageFile ); |
|
437 |
|
438 iSourceImage = IHLImageFactory::OpenFileImageL( imageFile ); |
|
439 iDestinationBitmap = IHLBitmap::CreateL(); |
|
440 |
|
441 iImageHandler = IHLViewerFactory::CreateImageViewerL( PostcardLaf::Image( ).Size( ), |
|
442 *iSourceImage, |
|
443 *iDestinationBitmap, |
|
444 *this, |
|
445 TUint32( 0 ) ); |
|
446 User::LeaveIfError( iImageHandler->SetSourceRectPosition( TPoint( 0, 0 ) ) ); |
|
447 |
|
448 CleanupStack::PopAndDestroy( &imageFile ); // imageFile |
|
449 } |
|
450 |
|
451 // --------------------------------------------------------- |
|
452 // ViewerBitmapChangedL |
|
453 // --------------------------------------------------------- |
|
454 void CPostcardOperationOpen::ViewerBitmapChangedL() |
|
455 { |
|
456 CFbsBitmap* bitmap = new (ELeave) CFbsBitmap; |
|
457 CFbsBitmap* mask = NULL; |
|
458 bitmap->Duplicate( iDestinationBitmap->Bitmap().Handle( ) ); |
|
459 |
|
460 if ( iDestinationBitmap->HasMask() ) |
|
461 { |
|
462 mask = new (ELeave) CFbsBitmap; |
|
463 mask->Duplicate( iDestinationBitmap->Mask().Handle( ) ); |
|
464 } |
|
465 |
|
466 delete iDestinationBitmap; |
|
467 iDestinationBitmap = NULL; |
|
468 |
|
469 delete iSourceImage; |
|
470 iSourceImage = NULL; |
|
471 |
|
472 delete iImageHandler; |
|
473 iImageHandler = NULL; |
|
474 |
|
475 iLaunchState = EPostcardOpenHandleText; |
|
476 |
|
477 CGulIcon* icon = NULL; |
|
478 TRAPD( err, icon = CGulIcon::NewL( bitmap, mask ) ); |
|
479 |
|
480 if( err ) |
|
481 { // Lets nullify it if there was an error |
|
482 icon = NULL; |
|
483 } |
|
484 |
|
485 iAppUi.SetImage( icon ); |
|
486 |
|
487 CompleteSelf( KErrNone ); |
|
488 |
|
489 } |
|
490 |
|
491 // --------------------------------------------------------- |
|
492 // ViewerError |
|
493 // --------------------------------------------------------- |
|
494 void CPostcardOperationOpen::ViewerError( TInt /*aError*/ ) |
|
495 { |
|
496 ToErrorState( R_POSTCARD_FORMAT_NOT_SUPPORTED ); |
|
497 } |
|
498 |
|
499 // --------------------------------------------------------- |
|
500 // DoHandleTextL |
|
501 // --------------------------------------------------------- |
|
502 void CPostcardOperationOpen::DoHandleTextL( ) |
|
503 { |
|
504 /* if ( iText != 0 ) |
|
505 { // Lets externalize the text itself |
|
506 RFile file = iManager->GetAttachmentFileL( iText ); |
|
507 |
|
508 CMmsTextInfo* info = static_cast<CMmsTextInfo*>(iDocument.MediaResolver()->ResolveFileTransferInfoL( file )); |
|
509 CleanupStack::PushL( info ); |
|
510 TUint attaCharset = info->CharacterSet(); |
|
511 CleanupStack::PopAndDestroy( info ); |
|
512 RFileReadStream input_stream( file ); |
|
513 |
|
514 CPlainText::TImportExportParam param; |
|
515 param.iForeignEncoding = attaCharset; //charconvCharsetID; |
|
516 param.iOrganisation = CPlainText::EOrganiseByParagraph; |
|
517 CPlainText::TImportExportResult result; |
|
518 TRAPD( error, text->ImportTextL( 0, input_stream, param, result) ); |
|
519 input_stream.Close( ); |
|
520 file.Close( ); |
|
521 } |
|
522 */ |
|
523 |
|
524 TPostcardMsgType type = iDocument.MessageType( ); |
|
525 if( iText > 0 && type == EPostcardSendAs ) |
|
526 { // If type is SendAs and file is from Phonebook -> Handle this case first |
|
527 CMsvAttachment* atta = iManager->GetAttachmentInfoL( iText ); |
|
528 CleanupStack::PushL( atta ); |
|
529 if( atta->AttachmentName( ).Find( _L("X-Nokia-PhonebookId_") ) != -1 ) |
|
530 { |
|
531 // All right, it was from Phonebook |
|
532 RFile file = iManager->GetAttachmentFileL( iText ); |
|
533 CleanupClosePushL( file ); |
|
534 |
|
535 CPostcardContact* contact = CPostcardContact::NewL( iFs ); |
|
536 CleanupStack::PushL( contact ); |
|
537 contact->FetchContactL( file ); |
|
538 DoHandlePhonebookSendAsL( *contact ); |
|
539 CleanupStack::PopAndDestroy( 3, atta ); // contact, file, atta |
|
540 |
|
541 ToState( EPostcardOpenFinished ); |
|
542 return; |
|
543 } |
|
544 // Ok, it was not from Phonebook, so lets continue normally.. |
|
545 CleanupStack::PopAndDestroy( atta ); |
|
546 } |
|
547 |
|
548 CPlainText* text = CPlainText::NewL( CEditableText::ESegmentedStorage, KPostcardDefaultGreetingSegment ); |
|
549 CleanupStack::PushL( text ); |
|
550 |
|
551 if ( iText > 0 ) |
|
552 { // Lets externalize the text itself |
|
553 RFile file = iManager->GetAttachmentFileL( iText ); |
|
554 CleanupClosePushL( file ); |
|
555 |
|
556 CMsvAttachment* atta = iManager->GetAttachmentInfoL( iText ); |
|
557 CleanupStack::PushL( atta ); |
|
558 |
|
559 CMsvMimeHeaders* msvMime = CMsvMimeHeaders::NewLC(); |
|
560 msvMime->RestoreL( *atta ); |
|
561 |
|
562 TUint attaCharset = msvMime->MimeCharset( ); // only charset needed |
|
563 |
|
564 CleanupStack::PopAndDestroy( 2, atta ); // mime, atta |
|
565 |
|
566 if( attaCharset == 0 ) |
|
567 { |
|
568 //assume US-ASCII - mandated by RFC 2046 |
|
569 attaCharset = KMmsUsAscii; |
|
570 } |
|
571 |
|
572 TUint finalCharset = iDocument.TextUtils()->MibIdToCharconvIdL( attaCharset ); |
|
573 |
|
574 RFileReadStream input_stream( file ); |
|
575 |
|
576 CPlainText::TImportExportParam param; |
|
577 param.iForeignEncoding = finalCharset; |
|
578 param.iOrganisation = CPlainText::EOrganiseByParagraph; |
|
579 CPlainText::TImportExportResult result; |
|
580 TRAP_IGNORE( text->ImportTextL( 0, input_stream, param, result) ); |
|
581 input_stream.Close( ); |
|
582 CleanupStack::PopAndDestroy( &file ); // file |
|
583 } |
|
584 |
|
585 if( type == EPostcardSendAs ) |
|
586 { |
|
587 // Otherwise there's no text or text is just text |
|
588 CleanupStack::Pop( text ); |
|
589 iAppUi.SetTextL( *text ); // AppUI takes the ownership |
|
590 ToState( EPostcardOpenHandleRecipient ); |
|
591 return; |
|
592 } |
|
593 else if( type == EPostcardForward || |
|
594 type == EPostcardEdit || |
|
595 type == EPostcardSent || |
|
596 type == EPostcardDraft ) |
|
597 { |
|
598 // The recipient might be added into the greeting text only when the entry |
|
599 // is opened from Sent folder or is forwarded or edited |
|
600 if( iSpecialFormat.Length( ) > 0 && text->DocumentLength( ) > 0 && iRecipient == 0 ) |
|
601 { // if special send format is defined and there's no separate recipient attachment |
|
602 TPtrC16 textBuf ( text->Read( 0 ) ); |
|
603 if( textBuf.Find( iSeparatorChar ) != KErrNotFound ) |
|
604 { // There are separators -> this msg has been sent |
|
605 // lets dig the recipient info from the text |
|
606 DoHandleSpecialFormatOpenL( *text ); |
|
607 CleanupStack::PopAndDestroy( text ); |
|
608 ToState( EPostcardOpenFinished ); |
|
609 return; |
|
610 } |
|
611 else |
|
612 { |
|
613 // There are no separators -> we can normally continue |
|
614 // and use "text" as the real greeting text |
|
615 } |
|
616 } |
|
617 } |
|
618 CleanupStack::Pop( text ); |
|
619 iAppUi.SetTextL( *text ); // AppUI takes the ownership |
|
620 ToState( EPostcardOpenHandleRecipient ); |
|
621 } |
|
622 |
|
623 // --------------------------------------------------------- |
|
624 // DoHandleRecipientL |
|
625 // --------------------------------------------------------- |
|
626 void CPostcardOperationOpen::DoHandleRecipientL( ) |
|
627 { |
|
628 CContactCard* card = CContactCard::NewLC(); |
|
629 |
|
630 if( iRecipient != 0 ) |
|
631 { |
|
632 TPostcardMsgType type = iDocument.MessageType( ); |
|
633 |
|
634 if( type == EPostcardForward ) |
|
635 { // We are opening a forward entry -> delete VCard |
|
636 TInt oldImage = TMsvIdToIndexL( iRecipient ); |
|
637 iStore->AttachmentManagerExtensionsL( ).RemoveAttachmentL( oldImage ); |
|
638 iCommit = ETrue; |
|
639 } |
|
640 else |
|
641 { |
|
642 ParseRecipientL( *card ); |
|
643 } |
|
644 } |
|
645 CleanupStack::Pop( card ); |
|
646 iAppUi.SetRecipientL( *card ); //ownership moves.. the function does not leave before card is set as a member |
|
647 } |
|
648 |
|
649 // --------------------------------------------------------- |
|
650 // CPostcardOperationOpen::ParseRecipientL |
|
651 // --------------------------------------------------------- |
|
652 void CPostcardOperationOpen::ParseRecipientL( CContactCard& aContactCard ) |
|
653 { |
|
654 RFile file = iManager->GetAttachmentFileL( iRecipient ); |
|
655 CleanupClosePushL( file ); |
|
656 |
|
657 CParserVCard* parser = CParserVCard::NewL(); |
|
658 CleanupStack::PushL(parser); |
|
659 |
|
660 RFileReadStream vCardStream( file ); |
|
661 vCardStream.PushL(); |
|
662 MStreamBuf* buf = vCardStream.Source(); |
|
663 if( !buf ) |
|
664 { |
|
665 User::Leave( KErrGeneral ); |
|
666 } |
|
667 |
|
668 parser->InternalizeL(vCardStream); |
|
669 |
|
670 vCardStream.Close(); |
|
671 vCardStream.Pop(); |
|
672 |
|
673 // Does not take ownership |
|
674 CArrayPtr<CParserProperty>* arr = parser->ArrayOfProperties(EFalse); |
|
675 for( TInt a = 0; a < arr->Count( ); a++ ) |
|
676 { |
|
677 CParserProperty* prop = arr->At( a ); |
|
678 TPtrC8 propName = prop->Name(); |
|
679 CParserPropertyValue *propValue = prop->Value(); |
|
680 if( propValue ) |
|
681 { |
|
682 if( propValue->Uid().iUid == KVersitPropertyCDesCArrayUid ) |
|
683 { |
|
684 CParserPropertyValueCDesCArray* arrayProperty = |
|
685 reinterpret_cast<CParserPropertyValueCDesCArray*>( propValue ); |
|
686 CDesCArray* values = arrayProperty->Value(); |
|
687 if( propName.Compare( KPostcardVCardName ) == 0 ) |
|
688 { |
|
689 TPostcardUtils::AddContactFieldL( aContactCard, |
|
690 TPostcardUtils::ContactItemNameFromId( EPostcardAddressName ), |
|
691 values->MdcaPoint( 0 ) ); |
|
692 } |
|
693 else if( propName.Compare( KPostcardVCardAddr ) == 0 ) |
|
694 { |
|
695 // This is the order items are read from the VCard store |
|
696 static const TInt indexToId[] = |
|
697 { |
|
698 0, // PO Box in the array will be ignored |
|
699 EPostcardAddressInfo, EPostcardAddressStreet, |
|
700 EPostcardAddressCity, EPostcardAddressState, |
|
701 EPostcardAddressZip, EPostcardAddressCountry |
|
702 }; |
|
703 const TInt KNumIds = |
|
704 sizeof( indexToId ) / sizeof( indexToId[0] ); |
|
705 TPostcardMsgType type = iDocument.MessageType(); |
|
706 // Skip PO Box at beginning of the array |
|
707 for (TInt i = 1; i < values->Count() && i < KNumIds; i++) |
|
708 { |
|
709 TPtrC value = values->MdcaPoint(i); |
|
710 // If viewing a sent postcard, all available fields are |
|
711 // initialized. Otherwise the field is initialized if |
|
712 // it's visible in address dialog (max. length is not zero). |
|
713 if( value.Length() && |
|
714 ( type == EPostcardSent || iAppUi.MaxTextLength( indexToId[i] ) ) ) |
|
715 { |
|
716 TPostcardUtils::AddContactFieldL( aContactCard, |
|
717 TPostcardUtils::ContactItemNameFromId( indexToId[i] ), |
|
718 value ); |
|
719 } |
|
720 } |
|
721 } |
|
722 } |
|
723 else if( propValue->Uid().iUid == KVersitPropertyHBufCUid ) |
|
724 { |
|
725 // Postcard before S60 3.2 release used FN (full name) property. |
|
726 // Since 3.2, N property is used |
|
727 if( propName.Compare( KPostcardVCardNameFN ) == 0 ) |
|
728 { |
|
729 TPostcardUtils::AddContactFieldL( aContactCard, |
|
730 TPostcardUtils::ContactItemNameFromId( EPostcardAddressName ), |
|
731 static_cast<CParserPropertyValueHBufC*>( propValue )->Value() ); |
|
732 } |
|
733 } |
|
734 } |
|
735 } |
|
736 CleanupStack::PopAndDestroy( 2, &file ); // file, parser |
|
737 } |
|
738 |
|
739 // --------------------------------------------------------- |
|
740 // CPostcardOperationOpen::ConstructL |
|
741 // --------------------------------------------------------- |
|
742 void CPostcardOperationOpen::ConstructL( ) |
|
743 { |
|
744 } |
|
745 |
|
746 // --------------------------------------------------------- |
|
747 // CPostcardOperationOpen::DoCancel |
|
748 // --------------------------------------------------------- |
|
749 void CPostcardOperationOpen::DoCancel( ) |
|
750 { |
|
751 if( iManager ) |
|
752 { |
|
753 if( iFlags & EPostcardOpenRequestActive ) |
|
754 { |
|
755 iManager->CancelRequest(); |
|
756 } |
|
757 } |
|
758 } |
|
759 |
|
760 // --------------------------------------------------------- |
|
761 // CPostcardOperationOpen::RunL |
|
762 // --------------------------------------------------------- |
|
763 void CPostcardOperationOpen::RunL( ) |
|
764 { |
|
765 DoLaunchStepL( ); |
|
766 } |
|
767 |
|
768 // --------------------------------------------------------- |
|
769 // RunError |
|
770 // --------------------------------------------------------- |
|
771 TInt CPostcardOperationOpen::RunError( TInt aError ) |
|
772 { |
|
773 iLaunchState = -1; |
|
774 SetError( aError ); |
|
775 iObserver.PostcardOperationEvent( |
|
776 EPostcardOperationOpen, |
|
777 EPostcardOperationError ); |
|
778 return KErrNone; |
|
779 } |
|
780 |
|
781 // --------------------------------------------------------- |
|
782 // CPostcardOperationOpen::DoHandlePhonebookSendAsL |
|
783 // --------------------------------------------------------- |
|
784 void CPostcardOperationOpen::DoHandlePhonebookSendAsL( CPostcardContact& aContact ) |
|
785 { |
|
786 CPostcardRecipientWrapper* recWrapper = |
|
787 CPostcardRecipientWrapper::NewL( iDocument, iAppUi, aContact ); |
|
788 CleanupStack::PushL( recWrapper ); |
|
789 |
|
790 // First remove wait note so that the dialog can be shown |
|
791 iAppUi.RemoveWaitNote( ); |
|
792 |
|
793 // Location asking is done in recipientWrapper |
|
794 CPostcardContact::TLocation location; |
|
795 TBool hasLocation = recWrapper->AskLocationL( location ); |
|
796 CleanupStack::PopAndDestroy( recWrapper ); |
|
797 |
|
798 iAppUi.ShowWaitNoteL( R_POSTCARD_WAIT_OPENING, EFalse ); |
|
799 |
|
800 if ( !hasLocation ) |
|
801 { |
|
802 // Contact not found or cancel selected.. |
|
803 CContactCard* card = CContactCard::NewL(); |
|
804 // Ownership moves.. |
|
805 // The function does not leave before card is set as a member |
|
806 iAppUi.SetRecipientL( *card ); |
|
807 CPlainText* emptyText = CPlainText::NewL( |
|
808 CEditableText::ESegmentedStorage, KPostcardDefaultGreetingSegment ); |
|
809 // Ownership moves.. |
|
810 // The function does not leave before card is set as a member |
|
811 iAppUi.SetTextL( *emptyText ); |
|
812 } |
|
813 else |
|
814 { |
|
815 // Otherwise location now tells the chosen location |
|
816 |
|
817 CContactCard* card = CContactCard::NewLC(); |
|
818 UpdateContactCardL( *card, aContact, location ); |
|
819 |
|
820 CleanupStack::Pop( card ); // card |
|
821 // Ownership moves.. |
|
822 // The function does not leave before card is set as a member |
|
823 iAppUi.SetRecipientL( *card ); |
|
824 iDocument.SetChanged( EPostcardRecipient ); |
|
825 iCommit = ETrue; // Remove the original atta way as it's just a phonebook atta |
|
826 MMsvAttachmentManagerSync& managerSync = iStore->AttachmentManagerExtensionsL(); |
|
827 TInt textIndex = TMsvIdToIndexL( iText ); |
|
828 managerSync.RemoveAttachmentL( textIndex ); |
|
829 iText = 0; |
|
830 CPlainText* emptyText = CPlainText::NewL( |
|
831 CEditableText::ESegmentedStorage, KPostcardDefaultGreetingSegment ); |
|
832 // Ownership moves.. |
|
833 // The function does not leave before card is set as a member |
|
834 iAppUi.SetTextL( *emptyText ); |
|
835 } |
|
836 } |
|
837 |
|
838 // --------------------------------------------------------- |
|
839 // CPostcardOperationOpen::UpdateContactCardL |
|
840 // --------------------------------------------------------- |
|
841 void CPostcardOperationOpen::UpdateContactCardL( CContactCard& aCard, |
|
842 CPostcardContact& aContact, CPostcardContact::TLocation aLocation ) |
|
843 { |
|
844 |
|
845 // Get contact name, combined last and first name |
|
846 HBufC* contactName = aContact.GetNameLC(); |
|
847 if ( contactName->Length() ) |
|
848 { |
|
849 // Create a new CContactCard field |
|
850 AddContactCardFieldL( aCard, *contactName, EPostcardAddressName ); |
|
851 } |
|
852 CleanupStack::PopAndDestroy( contactName ); // contactName |
|
853 |
|
854 // Handle rest of the address fields |
|
855 for( TInt i = EPostcardAddressInfo; i <= EPostcardAddressCountry; i++) |
|
856 { |
|
857 // Initialize address field only if it's visible to user |
|
858 // (max. length is not zero) |
|
859 if ( iAppUi.MaxTextLength( i ) ) |
|
860 { |
|
861 HBufC* fieldText = aContact.GetAddressFieldLC( aLocation, |
|
862 CPostcardContact::ControlIdToAddrField( i ) ); |
|
863 if ( fieldText->Length() ) |
|
864 { |
|
865 // Create a new CContactCard field |
|
866 AddContactCardFieldL( aCard, *fieldText, i ); |
|
867 } |
|
868 CleanupStack::PopAndDestroy( fieldText ); // fieldText |
|
869 } |
|
870 } |
|
871 } |
|
872 |
|
873 // --------------------------------------------------------- |
|
874 // CPostcardOperationOpen::AddContactCardFieldL |
|
875 // --------------------------------------------------------- |
|
876 void CPostcardOperationOpen::AddContactCardFieldL( CContactCard& aCard, |
|
877 const TPtrC& aText, TInt aFieldSelect ) |
|
878 { |
|
879 TPostcardUtils::AddContactFieldL(aCard, |
|
880 TPostcardUtils::ContactItemNameFromId( aFieldSelect ), |
|
881 aText); |
|
882 } |
|
883 |
|
884 // --------------------------------------------------------- |
|
885 // CPostcardOperationOpen::ParseSpecialFormatTextL |
|
886 // --------------------------------------------------------- |
|
887 void CPostcardOperationOpen::ParseSpecialFormatTextL( CPlainText& aText, |
|
888 CContactCard& aCard, CPlainText& aGreeting ) |
|
889 { |
|
890 TPtrC format( iSpecialFormat ); |
|
891 TPtrC srcText( aText.Read( 0 , aText.DocumentLength() ) ); |
|
892 |
|
893 const TInt KTagLen = 3; |
|
894 |
|
895 // Find tags from format and parse source text accordingly |
|
896 TInt tag; |
|
897 TInt position = TPostcardUtils::NextTag( format, tag ); |
|
898 // Eat prefix and tag from format. Assume the format has at least one tag. |
|
899 format.Set( format.Right( format.Length() - position - KTagLen ) ); |
|
900 // Eat prefix from source text |
|
901 srcText.Set( srcText.Right( srcText.Length() - position ) ); |
|
902 while( position != KErrNotFound ) |
|
903 { |
|
904 TInt newTag; |
|
905 position = TPostcardUtils::NextTag( format, newTag ); |
|
906 TPtrC text; |
|
907 if ( position != KErrNotFound ) |
|
908 { |
|
909 // Separator string from previous tag to this one. This cannot |
|
910 // be empty, otherwise text fields cannot be separated from each other. |
|
911 TPtrC separator( format.Left( position ) ); |
|
912 TInt separatorPos = srcText.Find( separator ); |
|
913 TInt srcLen = srcText.Length() - position - separatorPos; |
|
914 if ( separatorPos == KErrNotFound || srcLen < 0 ) |
|
915 { |
|
916 // Unexpected. Cannot parse. |
|
917 return; |
|
918 } |
|
919 text.Set( srcText.Left( separatorPos ) ); |
|
920 // Eat separator and tag from format |
|
921 format.Set( format.Right( format.Length() - position - KTagLen ) ); |
|
922 // Eat text and separator from source |
|
923 srcText.Set( srcText.Right( srcLen ) ); |
|
924 } |
|
925 else |
|
926 { |
|
927 // No new tags. Text is source string minus postfix |
|
928 text.Set( srcText.Left( srcText.Length() - format.Length() ) ); |
|
929 } |
|
930 if ( text.Length() ) |
|
931 { |
|
932 if ( tag == 0 ) |
|
933 { |
|
934 aGreeting.InsertL( 0, text ); |
|
935 } |
|
936 else |
|
937 { |
|
938 if ( iDocument.MessageType() != EPostcardForward ) |
|
939 { // Add the fields only when not in Forward mode |
|
940 TPostcardUtils::AddContactFieldL(aCard, |
|
941 TPostcardUtils::ContactItemNameFromTag( tag ), |
|
942 text); |
|
943 } |
|
944 } |
|
945 } |
|
946 tag = newTag; |
|
947 } |
|
948 } |
|
949 |
|
950 // --------------------------------------------------------- |
|
951 // CPostcardOperationOpen::DoHandleSpecialFormatOpenL |
|
952 // --------------------------------------------------------- |
|
953 void CPostcardOperationOpen::DoHandleSpecialFormatOpenL( CPlainText& aText ) |
|
954 { |
|
955 CContactCard* newCard = CContactCard::NewLC(); // New ContactCard |
|
956 CPlainText* newText = CPlainText::NewL( CEditableText::ESegmentedStorage, KPostcardDefaultGreetingSegment ); // New PlainText for greeting text |
|
957 CleanupStack::PushL( newText ); |
|
958 |
|
959 ParseSpecialFormatTextL( aText, *newCard, *newText ); |
|
960 |
|
961 CleanupStack::Pop(); // newText |
|
962 iAppUi.SetTextL( *newText ); // AppUI takes the ownership |
|
963 CleanupStack::Pop(); // newCard |
|
964 iAppUi.SetRecipientL( *newCard ); |
|
965 } |
|
966 |
|
967 // --------------------------------------------------------- |
|
968 // CPostcardOperationOpen::ToState |
|
969 // --------------------------------------------------------- |
|
970 void CPostcardOperationOpen::ToState( TPostcardOpenState aState ) |
|
971 { |
|
972 iLaunchState = aState; |
|
973 CompleteSelf( KErrNone ); |
|
974 } |
|
975 |
|
976 // --------------------------------------------------------- |
|
977 // CPostcardOperationOpen::ToErrorState |
|
978 // --------------------------------------------------------- |
|
979 void CPostcardOperationOpen::ToErrorState( TInt aResourceId ) |
|
980 { |
|
981 SetError( aResourceId ); |
|
982 iLaunchState = EPostcardOpenError; |
|
983 CompleteSelf( KErrCancel ); |
|
984 } |
|
985 |
|
986 // EOF |