|
1 /* |
|
2 * Copyright (c) 2002-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: Bio control for Business Cards. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include "VCardBioControl.h" // for CVCardBioControl |
|
22 #include "vcardvpbutil.h" |
|
23 #include "VCardLog.h" // Logging functionality |
|
24 |
|
25 #include <eikon.hrh> // for EikEdwin defines |
|
26 #include <eiklabel.h> // for CEikLabel |
|
27 #include <eikenv.h> // for eikenv |
|
28 #include <eikbtgpc.h> // for CEikButtonGroupContainer |
|
29 #include <e32base.h> |
|
30 #include <eikmenup.h> |
|
31 #include <eikmenub.h> |
|
32 #include <avkon.hrh> |
|
33 #include <aknnotedialog.h> // for CAknNoteDialog |
|
34 #include <gulicon.h> // for CGulIcon |
|
35 #include <eikclbd.h> |
|
36 #include <bioscmds.h> |
|
37 #include <msvapi.h> // for CMsvSession |
|
38 #include <s32file.h> // for RFileReadStream |
|
39 #include <msgbiocontrolObserver.h> // for MMsgBioControlObserver |
|
40 #include <StringLoader.h> // StringLoader |
|
41 #include <vcardbc.rsg> // resouce identifiers |
|
42 #include <CRichBio.h> // CRichBio |
|
43 #include <CPbkFieldInfo.h> |
|
44 #include <MsgBioUtils.h> |
|
45 #include <MsgSmsViewer.hrh> // ESmsViewerCreateCCNew, ESmsViewerCreateCCExisting |
|
46 #include <sysutil.h> |
|
47 #include <featmgr.h> |
|
48 #include <bldvariant.hrh> |
|
49 #include <csxhelp/smart.hlp.hrh> |
|
50 #include <mmsvattachmentmanager.h> |
|
51 #include <AknDef.h> |
|
52 #include <AknUtils.h> |
|
53 #include <PbkView.rsg> |
|
54 #include <akninputblock.h> |
|
55 |
|
56 //Phonebook 2 API |
|
57 #include <CPbk2StoreConfiguration.h> |
|
58 #include <VPbkContactStoreUris.h> |
|
59 #include <CVPbkContactStoreUriArray.h> |
|
60 #include <CVPbkContactManager.h> |
|
61 #include <TVPbkContactStoreUriPtr.h> |
|
62 #include <CVPbkVCardEng.h> |
|
63 #include <MVPbkContactStoreList.h> |
|
64 #include <MVPbkContactStore.h> |
|
65 #include <MVPbkStoreContactFieldCollection.h> |
|
66 #include <MVPbkStoreContact.h> |
|
67 #include <MVPbkContactFieldData.h> |
|
68 #include <MVPbkContactFieldTextData.h> |
|
69 #include <VPbkContactStoreUris.h> |
|
70 |
|
71 // LOCAL CONSTANTS AND MACROS |
|
72 |
|
73 _LIT(KResourceFile, "vcardbc.rsc"); |
|
74 _LIT(KPbk2CommonUi,"Pbk2CommonUi.rsc"); |
|
75 _LIT(KPbk2UIControls,"Pbk2UIControls.rsc"); |
|
76 _LIT(KClassName, "CVCardBioControl"); |
|
77 |
|
78 const TInt KMenuPos = 1; //The inserting position of menu item. |
|
79 |
|
80 // Compact Business Card Bio UID |
|
81 const TUid KUidBioBusinessCard = {0x10005531}; |
|
82 |
|
83 const TInt KVcdBcHeightReductionBva = 9; |
|
84 |
|
85 // CLASS-SPECIFIC PANIC CODES |
|
86 enum TPanicCode |
|
87 { |
|
88 ENullObject1, |
|
89 ENullObject2, |
|
90 ENullObject3, |
|
91 ENullObject4, |
|
92 ENullObject5, |
|
93 ENullObject6, |
|
94 ENullObject7, |
|
95 EUndefinedEnum, |
|
96 EInvalidIndex, |
|
97 EPanicPostCond_ReallocBufferL |
|
98 }; |
|
99 |
|
100 // MEMBER FUNCTIONS |
|
101 |
|
102 // Two-phased constructor. |
|
103 EXPORT_C CMsgBioControl* CVCardBioControl::NewL( |
|
104 MMsgBioControlObserver& aObserver, |
|
105 CMsvSession* aSession, |
|
106 TMsvId aId, |
|
107 TMsgBioMode aEditorOrViewerMode, |
|
108 const RFile* aFile) |
|
109 { |
|
110 LOG("CVCardBioControl::NewL begin"); |
|
111 CVCardBioControl* self = new(ELeave) CVCardBioControl( |
|
112 aObserver, |
|
113 aSession, |
|
114 aId, |
|
115 aEditorOrViewerMode, |
|
116 aFile); |
|
117 CleanupStack::PushL(self); |
|
118 self->ConstructL(); |
|
119 CleanupStack::Pop(self); |
|
120 LOG("CVCardBioControl::NewL end"); |
|
121 return self; |
|
122 } |
|
123 |
|
124 CVCardBioControl::~CVCardBioControl() |
|
125 { |
|
126 FeatureManager::UnInitializeLib(); |
|
127 delete iViewer; |
|
128 delete iVpbUtil; |
|
129 } |
|
130 |
|
131 void CVCardBioControl::SetAndGetSizeL(TSize& aSize) |
|
132 { |
|
133 LOG("CVCardBioControl::SetAndGetSizeL begin"); |
|
134 __ASSERT_DEBUG(iViewer, Panic(ENullObject1)); |
|
135 |
|
136 if(iIsFileBased) |
|
137 { |
|
138 SetPosition(TPoint(0,KVcdBcHeightReductionBva)); |
|
139 aSize.iHeight -= KVcdBcHeightReductionBva; |
|
140 iViewer->SetAndGetSizeL(aSize); |
|
141 SetSizeWithoutNotification(aSize); |
|
142 } |
|
143 else |
|
144 { |
|
145 iViewer->SetAndGetSizeL(aSize); |
|
146 |
|
147 //the following compares the window size against the |
|
148 //"virtual" height of the viewer. This way there is no |
|
149 //scrolling if virtualHeight is less than window size |
|
150 if(iViewer->VirtualHeight() <= Window().Size().iHeight) |
|
151 { |
|
152 aSize.iHeight = iViewer->VirtualHeight(); |
|
153 SetSizeWithoutNotification(aSize); |
|
154 } |
|
155 else |
|
156 { |
|
157 SetSizeWithoutNotification(aSize); |
|
158 } |
|
159 } |
|
160 |
|
161 LOG("CVCardBioControl::SetAndGetSizeL end"); |
|
162 } |
|
163 |
|
164 void CVCardBioControl::SetMenuCommandSetL(CEikMenuPane& aMenuPane) |
|
165 { |
|
166 LOG("CVCardBioControl::SetMenuCommandSetL begin"); |
|
167 if (!IsEditor()) |
|
168 { |
|
169 if (iIsFileBased) |
|
170 { |
|
171 FileBasedAddMenuItemL(aMenuPane, R_QTN_SM_ADD_PHONEBOOK, |
|
172 EAddToPhonebook); |
|
173 } |
|
174 else |
|
175 { |
|
176 AddMenuItemL(aMenuPane, R_QTN_SM_ADD_PHONEBOOK, |
|
177 EAddToPhonebook, KMenuPos); |
|
178 } |
|
179 } |
|
180 LOG("CVCardBioControl::SetMenuCommandSetL end"); |
|
181 } |
|
182 |
|
183 TBool CVCardBioControl::HandleBioCommandL(TInt aCommand) |
|
184 { |
|
185 if (aCommand == iBioControlObserver.FirstFreeCommand() |
|
186 + EAddToPhonebook) |
|
187 { |
|
188 CAknInputBlock* blocker = CAknInputBlock::NewLC(); |
|
189 AddToPhoneBookL(); |
|
190 CleanupStack::PopAndDestroy( blocker ); |
|
191 return ETrue; |
|
192 } |
|
193 return EFalse; |
|
194 } |
|
195 |
|
196 TRect CVCardBioControl::CurrentLineRect() const |
|
197 { |
|
198 return iViewer->CurrentLineRect(); |
|
199 } |
|
200 |
|
201 TBool CVCardBioControl::IsFocusChangePossible( |
|
202 TMsgFocusDirection aDirection) const |
|
203 { |
|
204 if (aDirection == EMsgFocusUp) |
|
205 { |
|
206 return iViewer->IsCursorLocation(EMsgTop); |
|
207 } |
|
208 return EFalse; |
|
209 } |
|
210 |
|
211 HBufC* CVCardBioControl::HeaderTextL() const |
|
212 { |
|
213 return StringLoader::LoadL(R_QTN_SM_TITLE_BUSINESS_CARD, iCoeEnv); |
|
214 } |
|
215 |
|
216 TInt CVCardBioControl::VirtualHeight() |
|
217 { |
|
218 __ASSERT_DEBUG(iViewer, Panic(ENullObject2)); |
|
219 return iViewer->VirtualHeight(); |
|
220 } |
|
221 |
|
222 TInt CVCardBioControl::VirtualVisibleTop() |
|
223 { |
|
224 __ASSERT_DEBUG(iViewer, Panic(ENullObject3)); |
|
225 return iViewer->VirtualVisibleTop(); |
|
226 } |
|
227 |
|
228 TBool CVCardBioControl::IsCursorLocation(TMsgCursorLocation aLocation) const |
|
229 { |
|
230 return iViewer->IsCursorLocation(aLocation); |
|
231 } |
|
232 |
|
233 TKeyResponse CVCardBioControl::OfferKeyEventL( |
|
234 const TKeyEvent& aKeyEvent, |
|
235 TEventCode aType) |
|
236 { |
|
237 __ASSERT_DEBUG(iViewer, Panic(ENullObject4)); |
|
238 return iViewer->OfferKeyEventL(aKeyEvent, aType); |
|
239 } |
|
240 |
|
241 void CVCardBioControl::GetHelpContext(TCoeHelpContext& aHelpContext) const |
|
242 { |
|
243 LOG("CVCardBioControl::GetHelpContext begin"); |
|
244 const TUid KUidSmart = {0x101F4CDA}; |
|
245 if (!iIsFileBased) |
|
246 { |
|
247 aHelpContext.iContext=IsEditor()? |
|
248 KSMART_HLP_BUSINESSEDITOR():KSMART_HLP_BUSINESSVIEWER() ; |
|
249 aHelpContext.iMajor=KUidSmart; |
|
250 } |
|
251 else |
|
252 { |
|
253 if ( !IsEditor() ) |
|
254 { |
|
255 aHelpContext.iContext=KSMART_HLP_BUSPULLMESVIEWER; |
|
256 aHelpContext.iMajor=KUidSmart; |
|
257 } |
|
258 } |
|
259 LOG("CVCardBioControl::GetHelpContext end"); |
|
260 } |
|
261 |
|
262 void CVCardBioControl::SetDimmed(TBool aDimmed) |
|
263 { |
|
264 LOG("CVCardBioControl::SetDimmed begin"); |
|
265 CCoeControl::SetDimmed(aDimmed); |
|
266 LOG("CVCardBioControl::SetDimmed end"); |
|
267 } |
|
268 |
|
269 TInt CVCardBioControl::CountComponentControls() const |
|
270 { |
|
271 return 1; // just the iViewer |
|
272 } |
|
273 |
|
274 CCoeControl* CVCardBioControl::ComponentControl(TInt aIndex) const |
|
275 { |
|
276 if (aIndex == 0) |
|
277 { |
|
278 return iViewer; |
|
279 } |
|
280 return NULL; |
|
281 } |
|
282 |
|
283 void CVCardBioControl::SizeChanged() |
|
284 { |
|
285 LOG("CVCardBioControl::SizeChanged begin"); |
|
286 __ASSERT_DEBUG(iViewer, Panic(ENullObject5)); |
|
287 iViewer->SetExtent(Position(), iViewer->Size()); |
|
288 LOG("CVCardBioControl::SizeChanged end"); |
|
289 } |
|
290 |
|
291 void CVCardBioControl::FocusChanged(TDrawNow /*aDrawNow*/) |
|
292 { |
|
293 LOG("CVCardBioControl::FocusChanged begin"); |
|
294 __ASSERT_DEBUG(iViewer, Panic(ENullObject6)); |
|
295 iViewer->SetFocus(IsFocused()); |
|
296 LOG("CVCardBioControl::FocusChanged end"); |
|
297 } |
|
298 |
|
299 void CVCardBioControl::SetContainerWindowL(const CCoeControl& aContainer) |
|
300 { |
|
301 LOG("CVCardBioControl::SetContainerWindowL begin"); |
|
302 CCoeControl::SetContainerWindowL(aContainer); |
|
303 |
|
304 // The reason for creating the viewer control here is that the |
|
305 // construction requires a parent with a window. So it cannot be done in |
|
306 // ConstructL(). |
|
307 |
|
308 iViewer = CRichBio::NewL(this, ERichBioModeEditorBase); |
|
309 AddVPbkFieldsToViewerL(*iVpbContact); |
|
310 LOG("CVCardBioControl::SetContainerWindowL end"); |
|
311 } |
|
312 |
|
313 CVCardBioControl::CVCardBioControl( |
|
314 MMsgBioControlObserver& aObserver, |
|
315 CMsvSession* aSession, |
|
316 TMsvId aId, |
|
317 TMsgBioMode aEditorOrViewerMode, |
|
318 const RFile* aFile |
|
319 ): |
|
320 CMsgBioControl(aObserver, |
|
321 aSession, |
|
322 aId, |
|
323 aEditorOrViewerMode, |
|
324 aFile) |
|
325 { |
|
326 } |
|
327 |
|
328 // Symbian OS default constructor can leave. |
|
329 void CVCardBioControl::ConstructL() |
|
330 { |
|
331 LOG("CVCardBioControl::ConstructL begin"); |
|
332 |
|
333 SetExtension( this ); |
|
334 iIsFileBased = IsFileBased(); |
|
335 |
|
336 LoadResourceL(KResourceFile); |
|
337 LoadResourceL(KPbk2CommonUi); |
|
338 LoadResourceL(KPbk2UIControls); |
|
339 LoadStandardBioResourceL(); |
|
340 |
|
341 TVCardBCBusinessCardType type; |
|
342 |
|
343 // file handle to the vcard attachment in msv store |
|
344 RFile fileHandle; |
|
345 ResolveFileHandleAndTypeL( fileHandle, type ); |
|
346 CleanupClosePushL( fileHandle ); |
|
347 |
|
348 iVpbUtil = CVCardVpbUtil::NewL(); |
|
349 |
|
350 FeatureManager::InitializeLibL(); |
|
351 |
|
352 // Now do the importing |
|
353 // |
|
354 if (type == EVCard ) |
|
355 { |
|
356 CleanupStack::Pop( &fileHandle ); |
|
357 //after this call the fileHandle will no longer be valid |
|
358 TRAPD(err,iVpbUtil->ImportVCardL(EVCard,fileHandle)); |
|
359 if (err != KErrNone) |
|
360 { |
|
361 User::Leave(KErrMsgBioMessageNotValid); |
|
362 } |
|
363 |
|
364 if (iVpbUtil->IsContactItemEmpty()) |
|
365 { |
|
366 User::Leave(KErrMsgBioMessageNotValid); |
|
367 } |
|
368 |
|
369 iVpbContact = iVpbUtil->ContactData(); |
|
370 } |
|
371 else if(type == ECompactBusinessCard) |
|
372 { |
|
373 CleanupStack::Pop( &fileHandle ); |
|
374 //after this call the fileHandle will no longer be valid |
|
375 TRAPD(err,iVpbUtil->ImportVCardL(ECompactBusinessCard,fileHandle)); |
|
376 if(err != KErrNone) |
|
377 { |
|
378 User::Leave(KErrMsgBioMessageNotValid); |
|
379 } |
|
380 |
|
381 iVpbContact = iVpbUtil->ContactData(); |
|
382 |
|
383 if (iVpbUtil->IsContactItemEmpty()) |
|
384 { |
|
385 User::Leave(KErrMsgBioMessageNotValid); |
|
386 } |
|
387 } |
|
388 else |
|
389 { |
|
390 __ASSERT_DEBUG(EFalse, Panic(EUndefinedEnum)); |
|
391 } |
|
392 LOG("CVCardBioControl::ConstructL end"); |
|
393 } |
|
394 |
|
395 void CVCardBioControl::AddToPhoneBookL() |
|
396 { |
|
397 LOG("CVCardBioControl::AddToPhoneBookL begin"); |
|
398 RFs fs; |
|
399 TInt connVal = fs.Connect(); |
|
400 User::LeaveIfError(connVal); |
|
401 CleanupClosePushL( fs ); |
|
402 |
|
403 // Check whether there's free space in flash mem to save the contact |
|
404 if ( SysUtil::FFSSpaceBelowCriticalLevelL( &fs )) |
|
405 { |
|
406 User::Leave( KErrDiskFull ); |
|
407 } |
|
408 CleanupStack::PopAndDestroy(); // fs |
|
409 |
|
410 TBool vcardStored(EFalse); |
|
411 vcardStored = iVpbUtil->CommitVCardToStoreL(); |
|
412 |
|
413 if( vcardStored ) |
|
414 { |
|
415 MsgBioUtils::ConfirmationNoteL( R_QTN_BCARD_SAVED_TO_PB_AS_NEW ); |
|
416 } |
|
417 LOG("CVCardBioControl::AddToPhoneBookL end"); |
|
418 } |
|
419 |
|
420 void CVCardBioControl::ResolveFileHandleAndTypeL( |
|
421 RFile& aFile, |
|
422 TVCardBCBusinessCardType& aBCType ) |
|
423 { |
|
424 LOG("CVCardBioControl::ResolveFileHandleAndTypeL begin"); |
|
425 if (iIsFileBased) |
|
426 { |
|
427 // Note that file based Compact Business Cards are not supported. |
|
428 // (The stand alone Bio Viewer Application will not be registered to |
|
429 // handle CBC mime types) |
|
430 aBCType = EVCard; |
|
431 aFile.Duplicate(FileHandle()); |
|
432 } |
|
433 else |
|
434 { |
|
435 CMsvEntry* entry = MsvSession().GetEntryL( iId ); |
|
436 if (entry->Entry().iBioType == KUidBioBusinessCard.iUid) |
|
437 { |
|
438 aBCType = ECompactBusinessCard; //Bio type of COMPACT Business card |
|
439 } |
|
440 else |
|
441 { |
|
442 aBCType = EVCard; // It is a vCard |
|
443 } |
|
444 |
|
445 CleanupStack::PushL( entry ); |
|
446 CMsvStore* store = entry->ReadStoreL(); |
|
447 CleanupStack::PushL(store); |
|
448 MMsvAttachmentManager& attachMan = store->AttachmentManagerL(); |
|
449 aFile = attachMan.GetAttachmentFileL( 0 ); //card is the firstattachment |
|
450 CleanupStack::PopAndDestroy( 2 ); // store, entry |
|
451 } |
|
452 LOG("CVCardBioControl::ResolveFileHandleAndTypeL end"); |
|
453 } |
|
454 |
|
455 void CVCardBioControl::AddVPbkFieldsToViewerL(const MVPbkStoreContact& aContact) |
|
456 { |
|
457 LOG("CVCardBioControl::AddPbkFieldsToViewerL begin"); |
|
458 |
|
459 const MVPbkStoreContactFieldCollection& fields = aContact.Fields(); |
|
460 TInt count = fields.FieldCount(); |
|
461 |
|
462 for (TInt n(0); n < count; n++) |
|
463 { |
|
464 const MVPbkStoreContactField& field = fields.FieldAt(n); |
|
465 if (FieldToBeShown(field)) |
|
466 { |
|
467 TPtrC text(iVpbUtil->FormatFieldContentL(field)); |
|
468 if (text.Length() && field.FieldLabel().Length()) |
|
469 { |
|
470 iViewer->AddItemL(field.FieldLabel(), text); |
|
471 } |
|
472 } |
|
473 } |
|
474 LOG("CVCardBioControl::AddPbkFieldsToViewerL end"); |
|
475 } |
|
476 |
|
477 TBool CVCardBioControl::FieldToBeShown(const MVPbkStoreContactField& aField) |
|
478 { |
|
479 LOG("CVCardBioControl::FieldToBeShown begin"); |
|
480 if (aField.FieldData().DataType() == EVPbkFieldStorageTypeBinary || |
|
481 aField.FieldData().DataType() == EVPbkFieldStorageTypeNull) |
|
482 { |
|
483 return EFalse; |
|
484 } |
|
485 LOG("CVCardBioControl::FieldToBeShown end"); |
|
486 return ETrue; |
|
487 } |
|
488 |
|
489 void CVCardBioControl::FileBasedAddMenuItemL(CEikMenuPane& aMenuPane, |
|
490 TInt aStringRes, TInt aCommandOffset) |
|
491 { |
|
492 LOG("CVCardBioControl::FileBasedAddMenuItemL begin"); |
|
493 CEikMenuPaneItem::SData menuItem; |
|
494 menuItem.iCascadeId = NULL; |
|
495 menuItem.iFlags = NULL; |
|
496 HBufC* menuItemText(StringLoader::LoadLC(aStringRes, iCoeEnv)); |
|
497 TPtr textPtr = menuItemText->Des(); |
|
498 if(textPtr.Length() > menuItem.iText.MaxLength()) |
|
499 { |
|
500 menuItem.iText.Format(textPtr.MidTPtr(0,menuItem.iText.MaxLength()) ); |
|
501 } |
|
502 else |
|
503 { |
|
504 menuItem.iText.Format(textPtr); |
|
505 } |
|
506 CleanupStack::PopAndDestroy(menuItemText); |
|
507 menuItem.iCommandId = iBioControlObserver.FirstFreeCommand() |
|
508 + aCommandOffset; |
|
509 aMenuPane.InsertMenuItemL(menuItem, 0); |
|
510 LOG("CVCardBioControl::FileBasedAddMenuItemL end"); |
|
511 } |
|
512 |
|
513 void CVCardBioControl::OpenStreamLC(RFileReadStream& aStream, |
|
514 TFileName& aFileName) |
|
515 { |
|
516 LOG("CVCardBioControl::OpenStreamLC begin"); |
|
517 User::LeaveIfError( aStream.Open( |
|
518 CCoeEnv::Static()->FsSession(), |
|
519 aFileName, |
|
520 EFileStream )); |
|
521 aStream.PushL(); |
|
522 LOG("CVCardBioControl::OpenStreamLC end"); |
|
523 } |
|
524 |
|
525 void CVCardBioControl::HandleResourceChange( TInt aType ) |
|
526 { |
|
527 LOG("CVCardBioControl::HandleResourceChange begin"); |
|
528 CMsgBioControl::HandleResourceChange( aType ); |
|
529 |
|
530 if ( aType == KEikDynamicLayoutVariantSwitch ) |
|
531 { |
|
532 iViewer->Reset(); |
|
533 } |
|
534 LOG("CVCardBioControl::HandleResourceChange end"); |
|
535 } |
|
536 |
|
537 TAny* CVCardBioControl::BioControlExtension(TInt aExtensionId) |
|
538 { |
|
539 if ( aExtensionId == KMsgBioControlScrollExtension ) |
|
540 { |
|
541 return static_cast<MMsgBioControlScrollExtension*> (this); |
|
542 } |
|
543 else |
|
544 { |
|
545 return NULL; |
|
546 } |
|
547 } |
|
548 |
|
549 TInt CVCardBioControl::ExtScrollL( TInt aPixelsToScroll, |
|
550 TMsgScrollDirection aDirection ) |
|
551 { |
|
552 return iViewer->ScrollL(aPixelsToScroll, aDirection); |
|
553 } |
|
554 |
|
555 void CVCardBioControl::ExtNotifyViewEvent( TMsgViewEvent aEvent, TInt aParam ) |
|
556 { |
|
557 iViewer->NotifyViewEvent( aEvent, aParam ); |
|
558 } |
|
559 |
|
560 void CVCardBioControl::Panic(TInt aReason) |
|
561 { |
|
562 User::Panic(KClassName, aReason); |
|
563 } |
|
564 // End of File |