|
1 /* |
|
2 * Copyright (c) 2002 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 * Container control class that will contain a Bio Control. |
|
16 * %version : % |
|
17 * |
|
18 */ |
|
19 |
|
20 |
|
21 |
|
22 // INCLUDE FILES |
|
23 #include <msgbiocontrol.h> |
|
24 #include <MsgBioUids.h> |
|
25 #include <msgbiocontrolfactory.h> |
|
26 #include <bva.rsg> // resouce identifiers |
|
27 #include "BvaAppUi.h" |
|
28 #include "BvaContainer.h" |
|
29 #include "bvalog.h" |
|
30 |
|
31 #include <AknsBasicBackgroundControlContext.h> |
|
32 #include <AknsDrawUtils.h> |
|
33 #include <featmgr.h> // Feature manager |
|
34 |
|
35 #include <AknUtils.h> // AknLayoutUtils |
|
36 #include <aknlayoutscalable_apps.cdl.h> // LAF |
|
37 #include <MsgEditorCommon.h> |
|
38 |
|
39 |
|
40 // LOCAL CONSTANTS AND MACROS |
|
41 |
|
42 _LIT8(KBeginVCard, "BEGIN:VCARD"); |
|
43 _LIT8(KBeginVCalendar, "BEGIN:VCALENDAR"); |
|
44 _LIT8(KICalVersion, "VERSION:2.0"); |
|
45 |
|
46 _LIT(KBvaContainer,"CBvaContainer"); |
|
47 |
|
48 const TInt KNumberOfControls = 1; |
|
49 |
|
50 // This is an estimate based on observed userid lengths in iCal messages |
|
51 const TInt KICalLengthNeeded = 255; |
|
52 |
|
53 // ================= MEMBER FUNCTIONS ======================= |
|
54 |
|
55 // --------------------------------------------------------- |
|
56 // Symbian OS two phased constructor |
|
57 // --------------------------------------------------------- |
|
58 // |
|
59 void CBvaContainer::ConstructL(const TRect& aRect) |
|
60 { |
|
61 LOG("CBvaContainer::ConstructL begin"); |
|
62 FeatureManager::InitializeLibL(); |
|
63 |
|
64 CreateWindowL(); |
|
65 iBgContext = CAknsBasicBackgroundControlContext::NewL( |
|
66 KAknsIIDQsnBgAreaMainMessage, aRect, ETrue); |
|
67 |
|
68 SetSizeWithoutNotification(aRect.Size()); |
|
69 SetBlank(); |
|
70 CreateScrollBarL(); |
|
71 iLineHeight = MsgEditorCommons::MsgBaseLineDelta(); |
|
72 iBaseLineOffset = MsgEditorCommons::MsgBaseLineOffset(); |
|
73 LOG("CBvaContainer::ConstructL end"); |
|
74 } |
|
75 |
|
76 void CBvaContainer::LoadBioControlL( const RFile& aFile ) |
|
77 { |
|
78 LOG("CBvaContainer::LoadBioControlL begin"); |
|
79 SetRect(iEikonEnv->EikAppUi()->ClientRect()); |
|
80 ActivateL(); |
|
81 delete iFactory; |
|
82 iFactory = NULL; |
|
83 iFactory = CMsgBioControlFactory::NewL(); |
|
84 |
|
85 delete iBioControl; |
|
86 iBioControl = NULL; |
|
87 |
|
88 TUid bioUid = BioUidL( aFile ); |
|
89 |
|
90 TRAPD(ret,iBioControl = iFactory->CreateControlL( |
|
91 *static_cast<CBvaAppUi*>(iEikonEnv->EikAppUi()), |
|
92 bioUid, |
|
93 EMsgBioViewerMode, |
|
94 aFile )); |
|
95 |
|
96 if(ret == KErrNotFound && bioUid == KMsgBioUidICalendar) |
|
97 { |
|
98 iBioControl = iFactory->CreateControlL( |
|
99 *static_cast<CBvaAppUi*>(iEikonEnv->EikAppUi()), |
|
100 KMsgBioUidVCalendar, |
|
101 EMsgBioViewerMode, |
|
102 aFile ); |
|
103 } |
|
104 else if(ret != KErrNone) |
|
105 { |
|
106 User::Leave(ret); |
|
107 } |
|
108 |
|
109 |
|
110 iBioControl->SetContainerWindowL(*this); |
|
111 iBioControl->ActivateL(); |
|
112 UpdateScrollBarL(); |
|
113 TSize size = Size(); |
|
114 TInt scrollBarWidth = iScrollBar->ScrollBarBreadth(CEikScrollBar::EVertical); |
|
115 size.iWidth -= scrollBarWidth; |
|
116 iBioControl->SetAndGetSizeL(size); |
|
117 iBioControl->SetExtent(TPoint(0,0),iBioControl->Size()); |
|
118 |
|
119 UpdateScrollBarL(); |
|
120 DrawNow(); |
|
121 LOG("CBvaContainer::LoadBioControlL end"); |
|
122 } |
|
123 |
|
124 // Destructor |
|
125 CBvaContainer::~CBvaContainer() |
|
126 { |
|
127 FeatureManager::UnInitializeLib(); |
|
128 delete iBioControl; |
|
129 delete iFactory; |
|
130 delete iScrollBar; |
|
131 delete iBgContext; |
|
132 } |
|
133 |
|
134 void CBvaContainer::SizeChanged() |
|
135 { |
|
136 if ( iBgContext ) |
|
137 { |
|
138 iBgContext->SetRect( Rect() ); |
|
139 iBgContext->SetParentPos( PositionRelativeToScreen() ); |
|
140 } |
|
141 if( iBioControl ) |
|
142 { |
|
143 //the scrollbar width is deducted from the viewer width |
|
144 //this ensures that the scrollbar is not blocked by it |
|
145 TSize size = iEikonEnv->EikAppUi()->ClientRect().Size(); |
|
146 TInt scrollBarWidth = iScrollBar->ScrollBarBreadth(CEikScrollBar::EVertical); |
|
147 size.iWidth -= scrollBarWidth; |
|
148 TRAP_IGNORE(iBioControl->SetAndGetSizeL(size)); |
|
149 iBioControl->SetExtent(TPoint(0,0), iBioControl->Size()); |
|
150 TRAP_IGNORE( UpdateScrollBarL() ); |
|
151 } |
|
152 } |
|
153 |
|
154 TInt CBvaContainer::CountComponentControls() const |
|
155 { |
|
156 TInt countScrollBarComponents( 0 ); |
|
157 if ( iScrollBar ) |
|
158 { |
|
159 countScrollBarComponents = iScrollBar->CountComponentControls(); |
|
160 } |
|
161 if (!iBioControl) |
|
162 { |
|
163 return countScrollBarComponents; |
|
164 } |
|
165 return countScrollBarComponents + KNumberOfControls ; |
|
166 } |
|
167 |
|
168 CCoeControl* CBvaContainer::ComponentControl(TInt aIndex) const |
|
169 { |
|
170 TInt countScrollBarComponents( 0 ); |
|
171 if ( iScrollBar ) |
|
172 { |
|
173 countScrollBarComponents = iScrollBar->CountComponentControls(); |
|
174 } |
|
175 |
|
176 switch ( aIndex ) |
|
177 { |
|
178 case 0: |
|
179 { |
|
180 if( iBioControl ) |
|
181 { |
|
182 return iBioControl; |
|
183 } |
|
184 else if( iScrollBar ) |
|
185 { |
|
186 return iScrollBar->ComponentControl( aIndex ); |
|
187 } |
|
188 } |
|
189 default: |
|
190 if ( iScrollBar |
|
191 && aIndex >= KNumberOfControls |
|
192 && aIndex < countScrollBarComponents + KNumberOfControls ) |
|
193 { |
|
194 return iScrollBar->ComponentControl( aIndex - KNumberOfControls ); |
|
195 } |
|
196 else |
|
197 { |
|
198 } |
|
199 return NULL; |
|
200 } |
|
201 } |
|
202 |
|
203 TTypeUid::Ptr CBvaContainer::MopSupplyObject(TTypeUid aId) |
|
204 { |
|
205 if (aId.iUid == MAknsControlContext::ETypeId) |
|
206 { |
|
207 return MAknsControlContext::SupplyMopObject( aId, iBgContext ); |
|
208 } |
|
209 return CCoeControl::MopSupplyObject(aId); |
|
210 } |
|
211 |
|
212 TKeyResponse CBvaContainer::OfferKeyEventL( |
|
213 const TKeyEvent& aKeyEvent, |
|
214 TEventCode aType) |
|
215 { |
|
216 TKeyResponse keyResp( EKeyWasNotConsumed ); |
|
217 if (!iBioControl) |
|
218 { |
|
219 return EKeyWasNotConsumed; |
|
220 } |
|
221 if(aKeyEvent.iCode == EKeyEnter ) |
|
222 { |
|
223 iEikonEnv->EikAppUi()->HandleCommandL(EAknSoftkeyContextOptions); |
|
224 return EKeyWasConsumed; |
|
225 } |
|
226 keyResp = iBioControl->OfferKeyEventL(aKeyEvent, aType); |
|
227 UpdateScrollBarL(); |
|
228 return keyResp; |
|
229 } |
|
230 |
|
231 CMsgBioControl& CBvaContainer::BioControl() |
|
232 { |
|
233 __ASSERT_DEBUG(iBioControl, Panic(EBioControlNotExist)); |
|
234 return *iBioControl; |
|
235 } |
|
236 |
|
237 TUid CBvaContainer::BioUidL(const TFileName& aFileName, RFs& aFs ) |
|
238 { |
|
239 RFile file; |
|
240 |
|
241 User::LeaveIfError(file.Open(aFs,aFileName,EFileRead)); |
|
242 CleanupClosePushL(file); // file on CS |
|
243 return BioUidL( file ); |
|
244 } |
|
245 |
|
246 |
|
247 TUid CBvaContainer::BioUidL( const RFile& aFile ) |
|
248 { |
|
249 LOG("CBvaContainer::BioUidL begin"); |
|
250 TInt size; |
|
251 User::LeaveIfError(aFile.Size(size)); |
|
252 if (!size) |
|
253 { |
|
254 // File reading failed. |
|
255 User::Leave(KErrNotFound); |
|
256 } |
|
257 |
|
258 HBufC8* dataBuf = HBufC8::NewLC(KICalLengthNeeded); // dataBuf on CS |
|
259 TPtr8 data(dataBuf->Des()); |
|
260 User::LeaveIfError(aFile.Read(data, KICalLengthNeeded)); |
|
261 TInt lengthNeeded = KBeginVCalendar().Length(); |
|
262 |
|
263 // Compare file length to text string |
|
264 TInt length = dataBuf->Length(); |
|
265 if (length < lengthNeeded) |
|
266 { |
|
267 User::Leave(KErrCorrupt); |
|
268 } |
|
269 |
|
270 // Compare beginning of read buffer with text strings. |
|
271 if ( dataBuf->Left( KBeginVCard().Length() ).CompareF(KBeginVCard) == 0) |
|
272 { |
|
273 CleanupStack::PopAndDestroy(dataBuf); // dataBuf |
|
274 return KMsgBioUidVCard; |
|
275 } |
|
276 else if ( |
|
277 dataBuf->FindF(KICalVersion) != KErrNotFound && |
|
278 dataBuf->FindF(KBeginVCalendar) != KErrNotFound |
|
279 ) |
|
280 { |
|
281 CleanupStack::PopAndDestroy(dataBuf); // dataBuf |
|
282 |
|
283 if ( FeatureManager::FeatureSupported( KFeatureIdMeetingRequestSupport ) ) |
|
284 { |
|
285 return KMsgBioUidICalendar; // we use ICalBC to launch the Meeting Request Viewers |
|
286 } |
|
287 else |
|
288 { |
|
289 return KMsgBioUidVCalendar; // VCalBC is used to open iCal message |
|
290 } |
|
291 } |
|
292 else if ( |
|
293 dataBuf->FindF(KICalVersion) == KErrNotFound && |
|
294 dataBuf->FindF(KBeginVCalendar) != KErrNotFound |
|
295 ) |
|
296 { |
|
297 CleanupStack::PopAndDestroy(dataBuf); // dataBuf |
|
298 return KMsgBioUidVCalendar; |
|
299 } |
|
300 CleanupStack::PopAndDestroy(dataBuf); // dataBuf |
|
301 LOG("CBvaContainer::BioUidL end"); |
|
302 User::Leave(KErrNotSupported); |
|
303 // Never reached. A compilation warning is avoided if null TUid returned. |
|
304 return TUid::Null(); |
|
305 } |
|
306 |
|
307 void CBvaContainer::Panic(TInt aCode) const |
|
308 { |
|
309 User::Panic(KBvaContainer, aCode); |
|
310 } |
|
311 |
|
312 void CBvaContainer::Draw(const TRect& aRect) const |
|
313 { |
|
314 CWindowGc& gc = SystemGc(); |
|
315 |
|
316 MAknsSkinInstance* skin = AknsUtils::SkinInstance(); |
|
317 MAknsControlContext* cc = AknsDrawUtils::ControlContext( this ); |
|
318 |
|
319 if( !AknsDrawUtils::Background( skin, cc, this, gc, aRect ) ) |
|
320 { |
|
321 // Same as CCoeControl draw for blank controls |
|
322 CGraphicsContext& gcBlank = SystemGc(); |
|
323 gcBlank.SetPenStyle( CGraphicsContext::ENullPen ); |
|
324 gcBlank.SetBrushStyle( CGraphicsContext::ESolidBrush ); |
|
325 gcBlank.DrawRect( aRect ); |
|
326 } |
|
327 } |
|
328 |
|
329 void CBvaContainer::HandleResourceChange( TInt aType ) |
|
330 { |
|
331 CCoeControl::HandleResourceChange( aType ); |
|
332 |
|
333 switch( aType ) |
|
334 { |
|
335 case KEikDynamicLayoutVariantSwitch: |
|
336 { |
|
337 iLineHeight = MsgEditorCommons::MsgBaseLineDelta(); |
|
338 iBaseLineOffset = MsgEditorCommons::MsgBaseLineOffset(); |
|
339 |
|
340 SetRect(iEikonEnv->EikAppUi()->ClientRect()); |
|
341 |
|
342 AknLayoutUtils::LayoutVerticalScrollBar( |
|
343 iScrollBar, |
|
344 TRect( TPoint( 0, 0 ), iEikonEnv->EikAppUi()->ClientRect().Size() ), |
|
345 AknLayoutScalable_Apps::scroll_pane_cp017().LayoutLine() ); |
|
346 SizeChanged(); |
|
347 break; |
|
348 } |
|
349 default: |
|
350 // fall through |
|
351 break; |
|
352 } |
|
353 } |
|
354 |
|
355 TBool CBvaContainer::IsBioControl() |
|
356 { |
|
357 if(iBioControl) |
|
358 return ETrue; |
|
359 else |
|
360 return EFalse; |
|
361 } |
|
362 |
|
363 void CBvaContainer::CreateScrollBarL() |
|
364 { |
|
365 iScrollBar = new ( ELeave ) CEikScrollBarFrame( |
|
366 this, // CCoeControl* aParentWindow |
|
367 this, // MEikScrollBarObserver* aObserver |
|
368 ETrue // TBool aPreAlloc=EFalse |
|
369 ); |
|
370 |
|
371 // Check which type of scrollbar is to be shown |
|
372 CAknAppUiBase* appUi = static_cast<CAknAppUiBase*>( iEikonEnv->EikAppUi() ); |
|
373 |
|
374 if ( AknLayoutUtils::DefaultScrollBarType( appUi ) == |
|
375 CEikScrollBarFrame::EDoubleSpan ) |
|
376 { |
|
377 // For EDoubleSpan type scrollbar |
|
378 // non-window owning scrollbar |
|
379 iScrollBar->CreateDoubleSpanScrollBarsL( EFalse, EFalse, ETrue, EFalse ); |
|
380 iScrollBar->SetTypeOfVScrollBar( CEikScrollBarFrame::EDoubleSpan ); |
|
381 AknLayoutUtils::LayoutVerticalScrollBar( |
|
382 iScrollBar, |
|
383 TRect( TPoint( 0, 0 ), iEikonEnv->EikAppUi()->ClientRect().Size() ), |
|
384 AknLayoutScalable_Apps::scroll_pane_cp017().LayoutLine() ); |
|
385 } |
|
386 else |
|
387 { |
|
388 // For EArrowHead type scrollbar |
|
389 iScrollBar->SetTypeOfVScrollBar( CEikScrollBarFrame::EArrowHead ); |
|
390 } |
|
391 |
|
392 iScrollBar->SetScrollBarVisibilityL( |
|
393 CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto ); |
|
394 } |
|
395 |
|
396 void CBvaContainer::UpdateScrollBarL() |
|
397 { |
|
398 TEikScrollBarModel horzModel; |
|
399 TEikScrollBarModel vertModel; |
|
400 TInt height; |
|
401 TInt pos; |
|
402 |
|
403 GetVirtualFormHeightAndPos( height, pos ); |
|
404 |
|
405 #ifdef _DEBUG |
|
406 // CAknScrollIndicator::SetPosition has an __ASSERT_DEBUG |
|
407 // for range check even if the control handles out-of-range |
|
408 // values properly. |
|
409 if ( pos > height ) pos = height; |
|
410 if ( pos < -1 ) pos = -1; |
|
411 #endif |
|
412 |
|
413 vertModel.iScrollSpan = height; |
|
414 vertModel.iThumbSpan = iEikonEnv->EikAppUi()->ClientRect().Height(); |
|
415 |
|
416 if ( height > iEikonEnv->EikAppUi()->ClientRect().Height() ) |
|
417 { |
|
418 vertModel.iThumbPosition = pos; |
|
419 } |
|
420 else |
|
421 { |
|
422 vertModel.iThumbPosition = 0; |
|
423 } |
|
424 |
|
425 TEikScrollBarFrameLayout layout; |
|
426 |
|
427 if ( iScrollBar && iScrollBar->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan ) |
|
428 { |
|
429 // For EDoubleSpan type scrollbar |
|
430 if ( vertModel.iScrollSpan == vertModel.iThumbPosition ) |
|
431 { |
|
432 vertModel.iThumbPosition--; |
|
433 } |
|
434 |
|
435 TAknDoubleSpanScrollBarModel hDsSbarModel( horzModel ); |
|
436 TAknDoubleSpanScrollBarModel vDsSbarModel( vertModel ); |
|
437 layout.iTilingMode = TEikScrollBarFrameLayout::EInclusiveRectConstant; |
|
438 |
|
439 // It seems to be important that we have separate |
|
440 // variable for "inclusiveRect" and "clientRect" |
|
441 TRect inclusiveRect( Rect() ); |
|
442 TRect clientRect( Rect() ); |
|
443 |
|
444 iScrollBar->TileL( &hDsSbarModel, &vDsSbarModel, clientRect, inclusiveRect, layout ); |
|
445 iScrollBar->SetVFocusPosToThumbPos( vDsSbarModel.FocusPosition() ); |
|
446 } |
|
447 else |
|
448 { |
|
449 TRect rect( Rect() ); |
|
450 iScrollBar->TileL( &horzModel, &vertModel, rect, rect, layout ); |
|
451 iScrollBar->SetVFocusPosToThumbPos( vertModel.iThumbPosition ); |
|
452 } |
|
453 } |
|
454 |
|
455 void CBvaContainer::GetVirtualFormHeightAndPos( TInt& aHeight, TInt& aPos ) |
|
456 { |
|
457 aHeight = iBioControl->VirtualHeight(); |
|
458 aPos = iBioControl->VirtualVisibleTop(); |
|
459 } |
|
460 |
|
461 #ifdef RD_SCALABLE_UI_V2 |
|
462 void CBvaContainer::HandleScrollEventL(CEikScrollBar* aScrollBar, TEikScrollEvent aEventType) |
|
463 { |
|
464 switch ( aEventType ) |
|
465 { |
|
466 case EEikScrollUp: |
|
467 { |
|
468 //ensure that we scroll 2 lines |
|
469 ScrollViewL(iLineHeight*2 , EMsgScrollUp, ETrue ); |
|
470 break; |
|
471 } |
|
472 case EEikScrollDown: |
|
473 { |
|
474 //ensure that we scroll 2 lines |
|
475 ScrollViewL( iLineHeight*2, EMsgScrollDown, ETrue ); |
|
476 break; |
|
477 } |
|
478 case EEikScrollTop: |
|
479 { |
|
480 // Not supported yet. |
|
481 break; |
|
482 } |
|
483 case EEikScrollBottom: |
|
484 { |
|
485 // Not supported yet. |
|
486 break; |
|
487 } |
|
488 case EEikScrollThumbReleaseVert: |
|
489 { |
|
490 // Not implemented yet |
|
491 break; |
|
492 } |
|
493 case EEikScrollPageUp: |
|
494 case EEikScrollPageDown: |
|
495 case EEikScrollThumbDragVert: |
|
496 { |
|
497 TInt scrolledPixels(iBioControl->VirtualVisibleTop() - aScrollBar->ThumbPosition()); |
|
498 |
|
499 //the scrolled amount have to be manipulated to be atleast |
|
500 //one line height of pixels |
|
501 if(aScrollBar->ThumbPosition() + iBioControl->VirtualVisibleTop() <= |
|
502 iBioControl->VirtualHeight() - iLineHeight) |
|
503 { |
|
504 if(Abs(scrolledPixels) >= iLineHeight) |
|
505 { |
|
506 scrolledPixels += ( scrolledPixels % (iLineHeight)); |
|
507 } |
|
508 else |
|
509 { |
|
510 scrolledPixels -= iLineHeight; |
|
511 } |
|
512 } |
|
513 else |
|
514 { |
|
515 scrolledPixels -= (iLineHeight); |
|
516 } |
|
517 |
|
518 if ( scrolledPixels != 0 ) |
|
519 { |
|
520 ScrollViewL( Abs( scrolledPixels ), |
|
521 scrolledPixels > 0 ? EMsgScrollUp : |
|
522 EMsgScrollDown, |
|
523 EFalse ); |
|
524 UpdateScrollBarL(); |
|
525 } |
|
526 break; |
|
527 } |
|
528 default: |
|
529 { |
|
530 break; |
|
531 } |
|
532 } |
|
533 } |
|
534 #else |
|
535 void CBvaContainer::HandleScrollEventL( CEikScrollBar* /*aScrollBar*/, |
|
536 TEikScrollEvent /*aEventType*/) |
|
537 { |
|
538 } |
|
539 #endif //RD_SCALABLE_UI_V2 |
|
540 |
|
541 const TAknDoubleSpanScrollBarModel* CBvaContainer::AknScrollBarModel() const |
|
542 { |
|
543 return static_cast<const TAknDoubleSpanScrollBarModel*>( iScrollBar->VerticalScrollBar()->Model() ); |
|
544 } |
|
545 |
|
546 #ifdef RD_SCALABLE_UI_V2 |
|
547 void CBvaContainer::ScrollViewL( TInt aPixelsToScroll, |
|
548 TMsgScrollDirection aDirection, |
|
549 TBool aMoveThumb ) |
|
550 { |
|
551 if ( aMoveThumb ) |
|
552 { |
|
553 const TAknDoubleSpanScrollBarModel* model = AknScrollBarModel(); |
|
554 |
|
555 TInt directionMultiplier( -1 ); |
|
556 if ( aDirection == EMsgScrollDown ) |
|
557 { |
|
558 directionMultiplier = 1; |
|
559 } |
|
560 // Scroll bar thumb is moved only if caller requests it. |
|
561 iScrollBar->SetVFocusPosToThumbPos( model->FocusPosition() - 1 + |
|
562 directionMultiplier * aPixelsToScroll ); |
|
563 } |
|
564 |
|
565 iBioControl->ScrollL( aPixelsToScroll, aDirection ); |
|
566 } |
|
567 #else |
|
568 void CBvaContainer::ScrollViewL( TInt /*aPixelsToScroll*/, |
|
569 TMsgScrollDirection /*aDirection*/, |
|
570 TBool /*aMoveThumb*/ ) |
|
571 { |
|
572 } |
|
573 #endif //RD_SCALABLE_UI_V2 |
|
574 |
|
575 // End of File |