messagingappbase/smartmessaging/bva/src/BvaContainer.cpp
changeset 0 72b543305e3a
child 2 0bf1d54f37d9
--- /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 <msgbiocontrol.h>
+#include <MsgBioUids.h>
+#include <msgbiocontrolfactory.h>
+#include <bva.rsg>                  // resouce identifiers
+#include "BvaAppUi.h"
+#include "BvaContainer.h"
+#include "bvalog.h"
+
+#include <AknsBasicBackgroundControlContext.h>
+#include <AknsDrawUtils.h>
+#include <featmgr.h>				// Feature manager
+
+#include <AknUtils.h>                   // AknLayoutUtils
+#include <aknlayoutscalable_apps.cdl.h> // LAF
+#include <MsgEditorCommon.h>
+
+
+//  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<CBvaAppUi*>(iEikonEnv->EikAppUi()),
+        bioUid,
+        EMsgBioViewerMode,
+        aFile ));
+
+    if(ret == KErrNotFound && bioUid == KMsgBioUidICalendar)
+        {
+        iBioControl = iFactory->CreateControlL(
+        *static_cast<CBvaAppUi*>(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<CAknAppUiBase*>( 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<const TAknDoubleSpanScrollBarModel*>( 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