diff -r 000000000000 -r 72b543305e3a messagingappbase/smartmessaging/bva/src/BvaContainer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/messagingappbase/smartmessaging/bva/src/BvaContainer.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,575 @@ +/* +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* Container control class that will contain a Bio Control. +* %version : % +* +*/ + + + +// INCLUDE FILES +#include +#include +#include +#include // resouce identifiers +#include "BvaAppUi.h" +#include "BvaContainer.h" +#include "bvalog.h" + +#include +#include +#include // Feature manager + +#include // AknLayoutUtils +#include // LAF +#include + + +// LOCAL CONSTANTS AND MACROS + +_LIT8(KBeginVCard, "BEGIN:VCARD"); +_LIT8(KBeginVCalendar, "BEGIN:VCALENDAR"); +_LIT8(KICalVersion, "VERSION:2.0"); + +_LIT(KBvaContainer,"CBvaContainer"); + +const TInt KNumberOfControls = 1; + +// This is an estimate based on observed userid lengths in iCal messages +const TInt KICalLengthNeeded = 255; + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// Symbian OS two phased constructor +// --------------------------------------------------------- +// +void CBvaContainer::ConstructL(const TRect& aRect) + { + LOG("CBvaContainer::ConstructL begin"); + FeatureManager::InitializeLibL(); + + CreateWindowL(); + iBgContext = CAknsBasicBackgroundControlContext::NewL( + KAknsIIDQsnBgAreaMainMessage, aRect, ETrue); + + SetSizeWithoutNotification(aRect.Size()); + SetBlank(); + CreateScrollBarL(); + iLineHeight = MsgEditorCommons::MsgBaseLineDelta(); + iBaseLineOffset = MsgEditorCommons::MsgBaseLineOffset(); + LOG("CBvaContainer::ConstructL end"); + } + +void CBvaContainer::LoadBioControlL( const RFile& aFile ) + { + LOG("CBvaContainer::LoadBioControlL begin"); + SetRect(iEikonEnv->EikAppUi()->ClientRect()); + ActivateL(); + delete iFactory; + iFactory = NULL; + iFactory = CMsgBioControlFactory::NewL(); + + delete iBioControl; + iBioControl = NULL; + + TUid bioUid = BioUidL( aFile ); + + TRAPD(ret,iBioControl = iFactory->CreateControlL( + *static_cast(iEikonEnv->EikAppUi()), + bioUid, + EMsgBioViewerMode, + aFile )); + + if(ret == KErrNotFound && bioUid == KMsgBioUidICalendar) + { + iBioControl = iFactory->CreateControlL( + *static_cast(iEikonEnv->EikAppUi()), + KMsgBioUidVCalendar, + EMsgBioViewerMode, + aFile ); + } + else if(ret != KErrNone) + { + User::Leave(ret); + } + + + iBioControl->SetContainerWindowL(*this); + iBioControl->ActivateL(); + UpdateScrollBarL(); + TSize size = Size(); + TInt scrollBarWidth = iScrollBar->ScrollBarBreadth(CEikScrollBar::EVertical); + size.iWidth -= scrollBarWidth; + iBioControl->SetAndGetSizeL(size); + iBioControl->SetExtent(TPoint(0,0),iBioControl->Size()); + + UpdateScrollBarL(); + DrawNow(); + LOG("CBvaContainer::LoadBioControlL end"); + } + +// Destructor +CBvaContainer::~CBvaContainer() + { + FeatureManager::UnInitializeLib(); + delete iBioControl; + delete iFactory; + delete iScrollBar; + delete iBgContext; + } + +void CBvaContainer::SizeChanged() + { + if ( iBgContext ) + { + iBgContext->SetRect( Rect() ); + iBgContext->SetParentPos( PositionRelativeToScreen() ); + } + if( iBioControl ) + { + //the scrollbar width is deducted from the viewer width + //this ensures that the scrollbar is not blocked by it + TSize size = iEikonEnv->EikAppUi()->ClientRect().Size(); + TInt scrollBarWidth = iScrollBar->ScrollBarBreadth(CEikScrollBar::EVertical); + size.iWidth -= scrollBarWidth; + TRAP_IGNORE(iBioControl->SetAndGetSizeL(size)); + iBioControl->SetExtent(TPoint(0,0), iBioControl->Size()); + TRAP_IGNORE( UpdateScrollBarL() ); + } + } + +TInt CBvaContainer::CountComponentControls() const + { + TInt countScrollBarComponents( 0 ); + if ( iScrollBar ) + { + countScrollBarComponents = iScrollBar->CountComponentControls(); + } + if (!iBioControl) + { + return countScrollBarComponents; + } + return countScrollBarComponents + KNumberOfControls ; + } + +CCoeControl* CBvaContainer::ComponentControl(TInt aIndex) const + { + TInt countScrollBarComponents( 0 ); + if ( iScrollBar ) + { + countScrollBarComponents = iScrollBar->CountComponentControls(); + } + + switch ( aIndex ) + { + case 0: + { + if( iBioControl ) + { + return iBioControl; + } + else + { + return iScrollBar->ComponentControl( aIndex ); + } + } + default: + if ( iScrollBar + && aIndex >= KNumberOfControls + && aIndex < countScrollBarComponents + KNumberOfControls ) + { + return iScrollBar->ComponentControl( aIndex - KNumberOfControls ); + } + else + { + } + return NULL; + } + } + +TTypeUid::Ptr CBvaContainer::MopSupplyObject(TTypeUid aId) + { + if (aId.iUid == MAknsControlContext::ETypeId) + { + return MAknsControlContext::SupplyMopObject( aId, iBgContext ); + } + return CCoeControl::MopSupplyObject(aId); + } + +TKeyResponse CBvaContainer::OfferKeyEventL( + const TKeyEvent& aKeyEvent, + TEventCode aType) + { + TKeyResponse keyResp( EKeyWasNotConsumed ); + if (!iBioControl) + { + return EKeyWasNotConsumed; + } + if(aKeyEvent.iCode == EKeyEnter ) + { + iEikonEnv->EikAppUi()->HandleCommandL(EAknSoftkeyContextOptions); + return EKeyWasConsumed; + } + keyResp = iBioControl->OfferKeyEventL(aKeyEvent, aType); + UpdateScrollBarL(); + return keyResp; + } + +CMsgBioControl& CBvaContainer::BioControl() + { + __ASSERT_DEBUG(iBioControl, Panic(EBioControlNotExist)); + return *iBioControl; + } + +TUid CBvaContainer::BioUidL(const TFileName& aFileName, RFs& aFs ) + { + RFile file; + + User::LeaveIfError(file.Open(aFs,aFileName,EFileRead)); + CleanupClosePushL(file); // file on CS + return BioUidL( file ); + } + + + TUid CBvaContainer::BioUidL( const RFile& aFile ) + { + LOG("CBvaContainer::BioUidL begin"); + TInt size; + User::LeaveIfError(aFile.Size(size)); + if (!size) + { + // File reading failed. + User::Leave(KErrNotFound); + } + + HBufC8* dataBuf = HBufC8::NewLC(KICalLengthNeeded); // dataBuf on CS + TPtr8 data(dataBuf->Des()); + User::LeaveIfError(aFile.Read(data, KICalLengthNeeded)); + TInt lengthNeeded = KBeginVCalendar().Length(); + + // Compare file length to text string + TInt length = dataBuf->Length(); + if (length < lengthNeeded) + { + User::Leave(KErrCorrupt); + } + + // Compare beginning of read buffer with text strings. + if ( dataBuf->Left( KBeginVCard().Length() ).CompareF(KBeginVCard) == 0) + { + CleanupStack::PopAndDestroy(dataBuf); // dataBuf + return KMsgBioUidVCard; + } + else if ( + dataBuf->FindF(KICalVersion) != KErrNotFound && + dataBuf->FindF(KBeginVCalendar) != KErrNotFound + ) + { + CleanupStack::PopAndDestroy(dataBuf); // dataBuf + + if ( FeatureManager::FeatureSupported( KFeatureIdMeetingRequestSupport ) ) + { + return KMsgBioUidICalendar; // we use ICalBC to launch the Meeting Request Viewers + } + else + { + return KMsgBioUidVCalendar; // VCalBC is used to open iCal message + } + } + else if ( + dataBuf->FindF(KICalVersion) == KErrNotFound && + dataBuf->FindF(KBeginVCalendar) != KErrNotFound + ) + { + CleanupStack::PopAndDestroy(dataBuf); // dataBuf + return KMsgBioUidVCalendar; + } + CleanupStack::PopAndDestroy(dataBuf); // dataBuf + LOG("CBvaContainer::BioUidL end"); + User::Leave(KErrNotSupported); + // Never reached. A compilation warning is avoided if null TUid returned. + return TUid::Null(); + } + +void CBvaContainer::Panic(TInt aCode) const + { + User::Panic(KBvaContainer, aCode); + } + +void CBvaContainer::Draw(const TRect& aRect) const + { + CWindowGc& gc = SystemGc(); + + MAknsSkinInstance* skin = AknsUtils::SkinInstance(); + MAknsControlContext* cc = AknsDrawUtils::ControlContext( this ); + + if( !AknsDrawUtils::Background( skin, cc, this, gc, aRect ) ) + { + // Same as CCoeControl draw for blank controls + CGraphicsContext& gcBlank = SystemGc(); + gcBlank.SetPenStyle( CGraphicsContext::ENullPen ); + gcBlank.SetBrushStyle( CGraphicsContext::ESolidBrush ); + gcBlank.DrawRect( aRect ); + } + } + +void CBvaContainer::HandleResourceChange( TInt aType ) + { + CCoeControl::HandleResourceChange( aType ); + + switch( aType ) + { + case KEikDynamicLayoutVariantSwitch: + { + iLineHeight = MsgEditorCommons::MsgBaseLineDelta(); + iBaseLineOffset = MsgEditorCommons::MsgBaseLineOffset(); + + SetRect(iEikonEnv->EikAppUi()->ClientRect()); + + AknLayoutUtils::LayoutVerticalScrollBar( + iScrollBar, + TRect( TPoint( 0, 0 ), iEikonEnv->EikAppUi()->ClientRect().Size() ), + AknLayoutScalable_Apps::scroll_pane_cp017().LayoutLine() ); + SizeChanged(); + break; + } + default: + // fall through + break; + } + } + +TBool CBvaContainer::IsBioControl() + { + if(iBioControl) + return ETrue; + else + return EFalse; + } + +void CBvaContainer::CreateScrollBarL() + { + iScrollBar = new ( ELeave ) CEikScrollBarFrame( + this, // CCoeControl* aParentWindow + this, // MEikScrollBarObserver* aObserver + ETrue // TBool aPreAlloc=EFalse + ); + + // Check which type of scrollbar is to be shown + CAknAppUiBase* appUi = static_cast( iEikonEnv->EikAppUi() ); + + if ( AknLayoutUtils::DefaultScrollBarType( appUi ) == + CEikScrollBarFrame::EDoubleSpan ) + { + // For EDoubleSpan type scrollbar + // non-window owning scrollbar + iScrollBar->CreateDoubleSpanScrollBarsL( EFalse, EFalse, ETrue, EFalse ); + iScrollBar->SetTypeOfVScrollBar( CEikScrollBarFrame::EDoubleSpan ); + AknLayoutUtils::LayoutVerticalScrollBar( + iScrollBar, + TRect( TPoint( 0, 0 ), iEikonEnv->EikAppUi()->ClientRect().Size() ), + AknLayoutScalable_Apps::scroll_pane_cp017().LayoutLine() ); + } + else + { + // For EArrowHead type scrollbar + iScrollBar->SetTypeOfVScrollBar( CEikScrollBarFrame::EArrowHead ); + } + + iScrollBar->SetScrollBarVisibilityL( + CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto ); + } + +void CBvaContainer::UpdateScrollBarL() + { + TEikScrollBarModel horzModel; + TEikScrollBarModel vertModel; + TInt height; + TInt pos; + + GetVirtualFormHeightAndPos( height, pos ); + +#ifdef _DEBUG + // CAknScrollIndicator::SetPosition has an __ASSERT_DEBUG + // for range check even if the control handles out-of-range + // values properly. + if ( pos > height ) pos = height; + if ( pos < -1 ) pos = -1; +#endif + + vertModel.iScrollSpan = height; + vertModel.iThumbSpan = iEikonEnv->EikAppUi()->ClientRect().Height(); + + if ( height > iEikonEnv->EikAppUi()->ClientRect().Height() ) + { + vertModel.iThumbPosition = pos; + } + else + { + vertModel.iThumbPosition = 0; + } + + TEikScrollBarFrameLayout layout; + + if ( iScrollBar && iScrollBar->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan ) + { + // For EDoubleSpan type scrollbar + if ( vertModel.iScrollSpan == vertModel.iThumbPosition ) + { + vertModel.iThumbPosition--; + } + + TAknDoubleSpanScrollBarModel hDsSbarModel( horzModel ); + TAknDoubleSpanScrollBarModel vDsSbarModel( vertModel ); + layout.iTilingMode = TEikScrollBarFrameLayout::EInclusiveRectConstant; + + // It seems to be important that we have separate + // variable for "inclusiveRect" and "clientRect" + TRect inclusiveRect( Rect() ); + TRect clientRect( Rect() ); + + iScrollBar->TileL( &hDsSbarModel, &vDsSbarModel, clientRect, inclusiveRect, layout ); + iScrollBar->SetVFocusPosToThumbPos( vDsSbarModel.FocusPosition() ); + } + else + { + TRect rect( Rect() ); + iScrollBar->TileL( &horzModel, &vertModel, rect, rect, layout ); + iScrollBar->SetVFocusPosToThumbPos( vertModel.iThumbPosition ); + } + } + +void CBvaContainer::GetVirtualFormHeightAndPos( TInt& aHeight, TInt& aPos ) + { + aHeight = iBioControl->VirtualHeight(); + aPos = iBioControl->VirtualVisibleTop(); + } + +#ifdef RD_SCALABLE_UI_V2 +void CBvaContainer::HandleScrollEventL(CEikScrollBar* aScrollBar, TEikScrollEvent aEventType) + { + switch ( aEventType ) + { + case EEikScrollUp: + { + //ensure that we scroll 2 lines + ScrollViewL(iLineHeight*2 , EMsgScrollUp, ETrue ); + break; + } + case EEikScrollDown: + { + //ensure that we scroll 2 lines + ScrollViewL( iLineHeight*2, EMsgScrollDown, ETrue ); + break; + } + case EEikScrollTop: + { + // Not supported yet. + break; + } + case EEikScrollBottom: + { + // Not supported yet. + break; + } + case EEikScrollThumbReleaseVert: + { + // Not implemented yet + break; + } + case EEikScrollPageUp: + case EEikScrollPageDown: + case EEikScrollThumbDragVert: + { + TInt scrolledPixels(iBioControl->VirtualVisibleTop() - aScrollBar->ThumbPosition()); + + //the scrolled amount have to be manipulated to be atleast + //one line height of pixels + if(aScrollBar->ThumbPosition() + iBioControl->VirtualVisibleTop() <= + iBioControl->VirtualHeight() - iLineHeight) + { + if(Abs(scrolledPixels) >= iLineHeight) + { + scrolledPixels += ( scrolledPixels % (iLineHeight)); + } + else + { + scrolledPixels -= iLineHeight; + } + } + else + { + scrolledPixels -= (iLineHeight); + } + + if ( scrolledPixels != 0 ) + { + ScrollViewL( Abs( scrolledPixels ), + scrolledPixels > 0 ? EMsgScrollUp : + EMsgScrollDown, + EFalse ); + UpdateScrollBarL(); + } + break; + } + default: + { + break; + } + } + } +#else +void CBvaContainer::HandleScrollEventL( CEikScrollBar* /*aScrollBar*/, + TEikScrollEvent /*aEventType*/) + { + } +#endif //RD_SCALABLE_UI_V2 + +const TAknDoubleSpanScrollBarModel* CBvaContainer::AknScrollBarModel() const + { + return static_cast( iScrollBar->VerticalScrollBar()->Model() ); + } + +#ifdef RD_SCALABLE_UI_V2 +void CBvaContainer::ScrollViewL( TInt aPixelsToScroll, + TMsgScrollDirection aDirection, + TBool aMoveThumb ) + { + if ( aMoveThumb ) + { + const TAknDoubleSpanScrollBarModel* model = AknScrollBarModel(); + + TInt directionMultiplier( -1 ); + if ( aDirection == EMsgScrollDown ) + { + directionMultiplier = 1; + } + // Scroll bar thumb is moved only if caller requests it. + iScrollBar->SetVFocusPosToThumbPos( model->FocusPosition() - 1 + + directionMultiplier * aPixelsToScroll ); + } + + iBioControl->ScrollL( aPixelsToScroll, aDirection ); + } +#else +void CBvaContainer::ScrollViewL( TInt /*aPixelsToScroll*/, + TMsgScrollDirection /*aDirection*/, + TBool /*aMoveThumb*/ ) + { + } +#endif //RD_SCALABLE_UI_V2 + +// End of File