|
1 /* |
|
2 * Copyright (c) 2006,2007 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: CUniEditorVCardOperationn, operation for adding VCard into the message |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // ========== INCLUDE FILES ================================ |
|
21 |
|
22 #include <MsgMediaInfo.h> |
|
23 #include <contactmatcher.h> |
|
24 #include <msgtextutils.h> |
|
25 #include <MsgMediaResolver.h> |
|
26 #include <MPbk2ContactNameFormatter.h> |
|
27 |
|
28 #include "UniEditorLogging.h" |
|
29 #include "UniEditorVCardOperation.h" |
|
30 #include "UniEditorEnum.h" |
|
31 |
|
32 _LIT8( KVCardMiMeType, "text/X-vCard" ); |
|
33 _LIT( KTempVCardFileName, "vCard.vcf" ); |
|
34 _LIT( KTempVCardFileSuffix, ".vcf"); |
|
35 |
|
36 _LIT(KInvalidFileNameChars, "?*<>/\"|\\:"); |
|
37 _LIT(KReplaceChar, "_"); |
|
38 |
|
39 // --------------------------------------------------------- |
|
40 // CUniEditorVCardOperation::NewL |
|
41 // |
|
42 // Factory method. |
|
43 // --------------------------------------------------------- |
|
44 // |
|
45 CUniEditorVCardOperation* CUniEditorVCardOperation::NewL( |
|
46 MUniEditorOperationObserver& aObserver, |
|
47 CUniEditorDocument& aDocument, |
|
48 RFs& aFs ) |
|
49 { |
|
50 CUniEditorVCardOperation* self = new ( ELeave ) CUniEditorVCardOperation( |
|
51 aObserver, |
|
52 aDocument, |
|
53 aFs ); |
|
54 CleanupStack::PushL( self ); |
|
55 self->ConstructL(); |
|
56 CleanupStack::Pop( self ); |
|
57 return self; |
|
58 } |
|
59 |
|
60 // --------------------------------------------------------- |
|
61 // CUniEditorVCardOperation::CUniEditorVCardOperation |
|
62 // |
|
63 // Constructor. |
|
64 // --------------------------------------------------------- |
|
65 // |
|
66 CUniEditorVCardOperation::CUniEditorVCardOperation( |
|
67 MUniEditorOperationObserver& aObserver, |
|
68 CUniEditorDocument& aDocument, |
|
69 RFs& aFs ) : |
|
70 CUniEditorOperation( aObserver, aDocument, aFs, EUniEditorOperationVCard ), |
|
71 iNewVCardAttaId( KMsvNullIndexEntryId ), |
|
72 iAddedVCardCount( 0 ), |
|
73 iCurrentContactIndex( -1 ) |
|
74 { |
|
75 } |
|
76 |
|
77 // --------------------------------------------------------- |
|
78 // CUniEditorVCardOperation::CUniEditorVCardOperation |
|
79 // |
|
80 // Destructor. iContact, iContacts and iCheckNames must be deleted |
|
81 // in this order! |
|
82 // --------------------------------------------------------- |
|
83 // |
|
84 CUniEditorVCardOperation::~CUniEditorVCardOperation() |
|
85 { |
|
86 Cancel(); |
|
87 |
|
88 delete iContact; |
|
89 delete iContacts; |
|
90 delete iCheckNames; |
|
91 delete iStoreContact; |
|
92 delete iVCardEng; |
|
93 delete iVCardExportOp; |
|
94 delete iEditStore; |
|
95 |
|
96 iVCardStream.Close(); |
|
97 } |
|
98 |
|
99 // --------------------------------------------------------- |
|
100 // CUniEditorVCardOperation::ConstructL |
|
101 // |
|
102 // 2nd phase constructor. |
|
103 // --------------------------------------------------------- |
|
104 // |
|
105 void CUniEditorVCardOperation::ConstructL() |
|
106 { |
|
107 BaseConstructL(); |
|
108 |
|
109 iCheckNames = CMsgCheckNames::NewL(); |
|
110 |
|
111 iVCardEng = CVPbkVCardEng::NewL( iCheckNames->ContactMatcher().GetContactManager() ); |
|
112 } |
|
113 |
|
114 // --------------------------------------------------------- |
|
115 // CUniEditorVCardOperation::Start |
|
116 // |
|
117 // --------------------------------------------------------- |
|
118 // |
|
119 void CUniEditorVCardOperation::Start() |
|
120 { |
|
121 iOperationState = EUniProcessVCardStart; |
|
122 CompleteSelf( KErrNone ); |
|
123 } |
|
124 |
|
125 // --------------------------------------------------------- |
|
126 // CUniEditorVCardOperation::GetContactsL |
|
127 // |
|
128 // --------------------------------------------------------- |
|
129 // |
|
130 void CUniEditorVCardOperation::GetContactsL() |
|
131 { |
|
132 ResetAll(); |
|
133 |
|
134 // Create a new empty array |
|
135 iContacts = CVPbkContactLinkArray::NewL(); |
|
136 |
|
137 iCheckNames->FetchRecipientsL( *iContacts, CMsgCheckNames::EMsgTypeAll ); |
|
138 |
|
139 if ( iContacts->Count() > 0 ) |
|
140 { |
|
141 iOperationState = EUniProcessVCardExportNext; |
|
142 CompleteSelf( KErrNone ); |
|
143 } |
|
144 else |
|
145 { |
|
146 iOperationState = EUniProcessVCardComplete; |
|
147 CompleteSelf( KErrNone ); |
|
148 } |
|
149 } |
|
150 |
|
151 // --------------------------------------------------------- |
|
152 // CUniEditorVCardOperation::ExportVCardAndAddAttachmentL |
|
153 // |
|
154 // --------------------------------------------------------- |
|
155 // |
|
156 void CUniEditorVCardOperation::ExportVCardAndAddAttachmentL() |
|
157 { |
|
158 Reset(); |
|
159 |
|
160 // Initial value is -1, so we start to handle the contact in index 0. |
|
161 iCurrentContactIndex++; |
|
162 |
|
163 if ( iCurrentContactIndex < iContacts->Count() ) |
|
164 { |
|
165 // Handle next contact. |
|
166 iContact = const_cast<MVPbkContactLink *>( |
|
167 &iContacts->At( iCurrentContactIndex ) )->CloneLC(); |
|
168 CleanupStack::Pop(); // Cloned link. |
|
169 |
|
170 iOperationState = EUniProcessVCardCreatingEmptyVCardAttachment; |
|
171 CompleteSelf( KErrNone ); |
|
172 } |
|
173 else |
|
174 { |
|
175 // No more contacts, so we can clean up and complete. |
|
176 // Clean up is done, in order to get iContact deleted, before |
|
177 // its contact manager is deleted. Bad design in virtual phonebook. |
|
178 iOperationState = EUniProcessVCardComplete; |
|
179 CompleteSelf( KErrNone ); |
|
180 } |
|
181 } |
|
182 |
|
183 // --------------------------------------------------------- |
|
184 // CUniEditorVCardOperation::AddedVCardCount |
|
185 // |
|
186 // --------------------------------------------------------- |
|
187 // |
|
188 TInt CUniEditorVCardOperation::AddedVCardCount() |
|
189 { |
|
190 return iAddedVCardCount; |
|
191 } |
|
192 |
|
193 // --------------------------------------------------------- |
|
194 // CUniEditorVCardOperation::CreateEmptyVCardAttachmentL |
|
195 // |
|
196 // --------------------------------------------------------- |
|
197 // |
|
198 void CUniEditorVCardOperation::CreateEmptyVCardAttachmentL() |
|
199 { |
|
200 iCheckNames->ContactMatcher().GetStoreContactL( *iContact, &iStoreContact ); |
|
201 |
|
202 // If this store contact is a group, then we don't add it to object list. |
|
203 if ( !iStoreContact->Group() ) |
|
204 { |
|
205 MVPbkStoreContactFieldCollection& fieldCollection = iStoreContact->Fields(); |
|
206 |
|
207 HBufC* contactName = iCheckNames->ContactMatcher().ContactNameFormatterL().GetContactTitleL( fieldCollection, 0 ); |
|
208 |
|
209 // Form a name for the attachment. If contactName is NULL, then |
|
210 // attachment is name vCard.vcf. |
|
211 if ( contactName ) |
|
212 { |
|
213 // Reserve more space for filename to include .vcf |
|
214 contactName = contactName->ReAllocL( |
|
215 contactName->Length() + KTempVCardFileSuffix().Length() ); // ReAllocL deletes original |
|
216 CleanupStack::PushL( contactName ); |
|
217 |
|
218 // Modify contact's name to be a file name. |
|
219 TPtr contactFilePtr = contactName->Des(); |
|
220 contactFilePtr.Append( KTempVCardFileSuffix ); |
|
221 } |
|
222 else |
|
223 { |
|
224 // Use hard coded filename vCard.vcf. |
|
225 contactName = KTempVCardFileName().AllocLC(); |
|
226 } |
|
227 |
|
228 // Remove illegal characters from file name. Phonebook allows characters |
|
229 // to be inserted to contact's name, which are not allowed by Symbian file |
|
230 // system. |
|
231 TPtr contactNamePtr = contactName->Des(); // May contain illegal characters |
|
232 HBufC* validName = HBufC::NewLC( contactName->Length() ); |
|
233 TPtr validNamePtr = validName->Des(); // Does not contain illegal characters |
|
234 |
|
235 // Loop throuh characters and replace illegal characters with underscore. |
|
236 for ( TInt i = 0; i < contactName->Length(); ++i ) |
|
237 { |
|
238 TChar ch = contactNamePtr[i]; |
|
239 if ( KInvalidFileNameChars().Locate( ch ) == KErrNotFound ) |
|
240 { |
|
241 validNamePtr.Append( ch ); |
|
242 } |
|
243 else |
|
244 { |
|
245 validNamePtr.Append( KReplaceChar ); |
|
246 } |
|
247 } |
|
248 validNamePtr.TrimAll(); |
|
249 |
|
250 // Create empty stored attachment to store. |
|
251 RFile newVCardFile; |
|
252 iEditStore = iDocument.Mtm().Entry().EditStoreL(); |
|
253 MMsvAttachmentManagerSync& managerSync = iEditStore->AttachmentManagerExtensionsL(); |
|
254 CMsvAttachment* attachment = CMsvAttachment::NewL( CMsvAttachment::EMsvFile ); |
|
255 CleanupStack::PushL( attachment ); |
|
256 managerSync.CreateAttachmentL( validNamePtr, newVCardFile, attachment ); |
|
257 CleanupStack::Pop( attachment); // ownership transferred |
|
258 CleanupStack::PopAndDestroy( 2, contactName ); // validName, contactName |
|
259 |
|
260 // Store the id, it is used when attachment created above is saved to |
|
261 // object list. |
|
262 iNewVCardAttaId = attachment->Id(); |
|
263 iVCardStream.Attach( newVCardFile ); |
|
264 |
|
265 // Call vCard engine to export a contact to a stored attachment. |
|
266 // Engine will call VPbkSingleContactOperationComplete or |
|
267 // VPbkSingleContactOperationFailed |
|
268 iVCardExportOp = iVCardEng->ExportVCardL( iVCardStream, |
|
269 *iContact, |
|
270 *this); |
|
271 SetPending(); |
|
272 } |
|
273 else |
|
274 { |
|
275 // Don't add group name as a vCard, results are not nice. |
|
276 iOperationState = EUniProcessVCardExportNext; |
|
277 CompleteSelf( KErrNone ); |
|
278 } |
|
279 } |
|
280 |
|
281 // --------------------------------------------------------- |
|
282 // CUniEditorVCardOperation::DoCancelCleanup |
|
283 // |
|
284 // --------------------------------------------------------- |
|
285 // |
|
286 void CUniEditorVCardOperation::DoCancelCleanup() |
|
287 { |
|
288 Reset(); |
|
289 } |
|
290 |
|
291 // --------------------------------------------------------- |
|
292 // CUniEditorVCardOperation::RunL |
|
293 // |
|
294 // --------------------------------------------------------- |
|
295 // |
|
296 void CUniEditorVCardOperation::RunL() |
|
297 { |
|
298 PrintOperationAndState(); |
|
299 if ( iStatus.Int() != KErrNone ) |
|
300 { |
|
301 SetError( iStatus.Int() ); |
|
302 iOperationState = EUniProcessVCardError; |
|
303 } |
|
304 |
|
305 switch( iOperationState ) |
|
306 { |
|
307 case EUniProcessVCardStart: |
|
308 { |
|
309 // Get contacts to export |
|
310 GetContactsL(); |
|
311 break; |
|
312 } |
|
313 case EUniProcessVCardExportNext: |
|
314 { |
|
315 // Start handling of single contact. |
|
316 ExportVCardAndAddAttachmentL(); |
|
317 break; |
|
318 } |
|
319 case EUniProcessVCardCreatingEmptyVCardAttachment: |
|
320 { |
|
321 // Create an empty attachment to message store. |
|
322 CreateEmptyVCardAttachmentL(); |
|
323 break; |
|
324 } |
|
325 case EUniProcessVCardComplete: |
|
326 { |
|
327 // All contacts handled, tell appUi that we are complete. |
|
328 ReportEvent( EUniEditorOperationComplete ); |
|
329 break; |
|
330 } |
|
331 case EUniProcessVCardCancel: |
|
332 { |
|
333 // Somebody cancelled us, tell appUi that we were cancelled. |
|
334 ReportEvent( EUniEditorOperationCancel ); |
|
335 break; |
|
336 } |
|
337 case EUniProcessVCardError: |
|
338 { |
|
339 Reset(); |
|
340 iObserver.EditorOperationEvent( EUniEditorOperationVCard, |
|
341 EUniEditorOperationError ); |
|
342 break; |
|
343 } |
|
344 default: |
|
345 { |
|
346 // Huh, this can also be possible. |
|
347 iObserver.EditorOperationEvent( EUniEditorOperationVCard, |
|
348 EUniEditorOperationError ); |
|
349 break; |
|
350 } |
|
351 } |
|
352 } |
|
353 |
|
354 // --------------------------------------------------------- |
|
355 // CUniEditorVCardOperation::VPbkSingleContactOperationComplete |
|
356 // |
|
357 // --------------------------------------------------------- |
|
358 // |
|
359 void CUniEditorVCardOperation::VPbkSingleContactOperationComplete( MVPbkContactOperationBase& aOperation, |
|
360 MVPbkStoreContact* /*aContact*/ ) |
|
361 { |
|
362 iLastError = KErrNone; |
|
363 |
|
364 if ( &aOperation == iVCardExportOp ) |
|
365 { |
|
366 TDataType type( KVCardMiMeType ); |
|
367 |
|
368 // Release and close stream. |
|
369 TRAP_IGNORE( iVCardStream.CommitL() ); |
|
370 iVCardStream.Close(); |
|
371 |
|
372 // Get attachment handle again, since iVCardStream.Attach() function |
|
373 // call makes the original handle invalid. |
|
374 MMsvAttachmentManager* manager = NULL; |
|
375 TRAP_IGNORE( manager = &iEditStore->AttachmentManagerL() ); |
|
376 |
|
377 RFile storedVCard; |
|
378 TRAPD( err, storedVCard = manager->GetAttachmentFileL( iNewVCardAttaId ) ); |
|
379 |
|
380 if ( err == KErrNone ) |
|
381 { |
|
382 // Add stored attachment to object list. |
|
383 CMsgMediaInfo* media = NULL; |
|
384 |
|
385 TRAP_IGNORE( media = CMsgMediaInfo::NewL( storedVCard, |
|
386 type, |
|
387 EMsgMediaUnknown ) ); |
|
388 |
|
389 // Count the size of the message after current vCard is inserted. |
|
390 TInt vCardSize = media->FileSize(); |
|
391 TInt sizeAfterInsert = iDocument.MessageSize() + vCardSize; |
|
392 |
|
393 if ( sizeAfterInsert <= iDocument.MaxMessageSize() ) |
|
394 { |
|
395 // Must be committed and deleted since only one client can access |
|
396 // entry in edit mode and AddStoredAttachmentL function want's to |
|
397 // edit it too. |
|
398 TRAP_IGNORE( iEditStore->CommitL() ); |
|
399 |
|
400 delete iEditStore; |
|
401 iEditStore = NULL; |
|
402 |
|
403 TRAP_IGNORE( iDocument.DataModel()->AddStoredAttachmentL( iNewVCardAttaId, |
|
404 media ) ); |
|
405 media = NULL; // Not owned anymore |
|
406 |
|
407 // Increase success counter, used to show correct note |
|
408 // when all contacts are handled. |
|
409 iAddedVCardCount++; |
|
410 |
|
411 // Object is now saved to unieditor's object list. |
|
412 } |
|
413 else |
|
414 { |
|
415 // Delete created media info |
|
416 delete media; |
|
417 media = NULL; |
|
418 |
|
419 TRAP_IGNORE( |
|
420 { |
|
421 MMsvAttachmentManagerSync& managerSync = iEditStore->AttachmentManagerExtensionsL(); |
|
422 managerSync.RemoveAttachmentL( CUniDataUtils::IndexPositionOfAttachmentL( *manager, |
|
423 iNewVCardAttaId ) ); |
|
424 iEditStore->CommitL(); |
|
425 iNewVCardAttaId = KMsvNullIndexEntryId; |
|
426 }); |
|
427 |
|
428 SetError( EUniInsertTooBig ); |
|
429 |
|
430 // Try whether next vCard fits to max message size. |
|
431 } |
|
432 |
|
433 // Current contact handled, start next one. Whether there still |
|
434 // exist unhandled contacts, it is decided elsewhere. |
|
435 iOperationState = EUniProcessVCardExportNext; |
|
436 CompleteOperation( KErrNone ); |
|
437 |
|
438 // Close temporary attachment handle. |
|
439 storedVCard.Close(); |
|
440 } |
|
441 else |
|
442 { |
|
443 // Couldn't get a handle to a stored attachment, |
|
444 // let's give up. |
|
445 iOperationState = EUniProcessVCardError; |
|
446 CompleteOperation( err ); |
|
447 } |
|
448 } |
|
449 } |
|
450 |
|
451 // --------------------------------------------------------- |
|
452 // CUniEditorVCardOperation::VPbkSingleContactOperationFailed |
|
453 // |
|
454 // --------------------------------------------------------- |
|
455 // |
|
456 void CUniEditorVCardOperation::VPbkSingleContactOperationFailed( |
|
457 MVPbkContactOperationBase& /*aOperation*/, TInt aError ) |
|
458 { |
|
459 iLastError = aError; |
|
460 |
|
461 SetError( iLastError ); |
|
462 |
|
463 Reset(); |
|
464 |
|
465 iOperationState = EUniProcessVCardError; |
|
466 CompleteOperation( iLastError ); |
|
467 } |
|
468 |
|
469 // --------------------------------------------------------- |
|
470 // CUniEditorVCardOperation::Reset |
|
471 // |
|
472 // --------------------------------------------------------- |
|
473 void CUniEditorVCardOperation::Reset() |
|
474 { |
|
475 delete iContact; |
|
476 iContact = NULL; |
|
477 |
|
478 delete iStoreContact; |
|
479 iStoreContact = NULL; |
|
480 |
|
481 delete iVCardExportOp; |
|
482 iVCardExportOp = NULL; |
|
483 |
|
484 delete iEditStore; |
|
485 iEditStore = NULL; |
|
486 |
|
487 iNewVCardAttaId = KMsvNullIndexEntryId; |
|
488 iVCardStream.Close(); |
|
489 } |
|
490 |
|
491 // --------------------------------------------------------- |
|
492 // CUniEditorVCardOperation::ResetAll |
|
493 // |
|
494 // --------------------------------------------------------- |
|
495 // |
|
496 void CUniEditorVCardOperation::ResetAll() |
|
497 { |
|
498 // First reset counters. |
|
499 iCurrentContactIndex = -1; |
|
500 iAddedVCardCount = 0; |
|
501 |
|
502 if ( iContacts ) |
|
503 { |
|
504 delete iContacts; |
|
505 iContacts = NULL; |
|
506 } |
|
507 |
|
508 Reset(); |
|
509 |
|
510 // Reset any previous errors, since we are started again. |
|
511 ResetErrors(); |
|
512 } |
|
513 |
|
514 // --------------------------------------------------------- |
|
515 // CUniEditorVCardOperation::ReportEvent |
|
516 // |
|
517 // --------------------------------------------------------- |
|
518 // |
|
519 void CUniEditorVCardOperation::ReportEvent( TUniEditorOperationEvent aEvent ) |
|
520 { |
|
521 iObserver.EditorOperationEvent( EUniEditorOperationVCard, aEvent ); |
|
522 } |
|
523 |
|
524 // EOF |