extras/about/src/AboutContainer.cpp
branchRCL_3
changeset 21 10c6e6d6e4d9
child 22 bec11adf88f9
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extras/about/src/AboutContainer.cpp	Wed Sep 01 12:29:54 2010 +0100
@@ -0,0 +1,808 @@
+/*
+* 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: application container control.  
+*
+*/
+
+
+// INCLUDE FILES
+
+#include "AboutContainer.h"
+#include "AboutImage.h"
+#include "about.hrh"
+#include "about_test.hrh"
+#include <layoutmetadata.cdl.h>
+#include <about.rsg>
+#include <eiksbfrm.h>
+#include <eikscrlb.h>
+#include <eikrted.h>
+#include <txtrich.h>
+#include <barsread.h>
+#include <eikenv.h>
+#include <aknenv.h>
+#include <AknUtils.h>
+#include <aknconsts.h>
+#include <txtfrmat.h>
+#include <AknBidiTextUtils.h>
+#include <data_caging_path_literals.hrh>
+#include <f32file.h>
+#include <aknlayoutscalable_apps.cdl.h>
+#include <aknappui.h>
+#include <AknsDrawUtils.h> 
+#include    <AknsBasicBackgroundControlContext.h>
+#include    <AknsConstants.h>
+#include <AknDef.h>
+#include <about.mbg>
+#include <StringLoader.h> 
+
+// CONSTANTS
+
+_LIT( KAboutPanicCategory, "About" );
+
+enum TAboutPanic
+    {
+    EAboutNotSupported = 0
+    };
+
+/**
+* SCROLLING:
+*
+* Scrolling is implemented according to the following rules
+* when scrolling down:
+*
+* (same screens are shown again when scrolling up)
+*
+* - If the last line in previous screen was a text line,
+*   next screen is started with that line, ie. the last
+*   line is shown again in the next screen.
+*
+* - If previous screen ended with an image that did not
+*   fully fit, next screen is started with that image so
+*   that it can be seen as a whole.
+*
+* - If previous screen ended with an image that fit there fully,
+*   next screen is started with next text line or image.
+*/
+
+// constructors
+
+CAboutContainer::CAboutContainer():iNumItem( 0 )
+    {
+    }
+
+void CAboutContainer::ConstructL( const TRect& aRect )
+    {
+    CreateWindowL();
+
+    iScrollBarDragged = EFalse;
+    iBreakFlag = EFalse;
+    iIsSvg = EFalse;
+	iSkinContext = NULL;
+	iText = NULL;
+	iImages = NULL;
+	iScreenStarts = NULL;
+	iSBFrame = NULL;
+    CalculateL(aRect); 
+    ActivateL();
+    }
+
+// destructor
+
+CAboutContainer::~CAboutContainer()
+    {
+	delete iSkinContext;
+    delete iSBFrame;
+    delete iScreenStarts;
+    delete iIcon;
+
+    if ( iText )
+        {
+        iText->ResetAndDestroy();
+        delete iText;
+        }
+
+    if ( iImages )
+        {
+        iImages->ResetAndDestroy();
+        delete iImages;
+        }
+    }
+
+void CAboutContainer::SizeChanged()
+    {
+    TRect parentRect(Rect());
+	if (iSkinContext)
+        {
+        iSkinContext->SetRect(parentRect);
+        }
+	}
+// -----------------------------------------------------------------------------
+// CAboutContainer::Draw()
+// -----------------------------------------------------------------------------
+
+void CAboutContainer::Draw( const TRect& aRect ) const
+    {
+    CWindowGc& gc = SystemGc();
+	MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+	if (iSkinContext)
+		{//Draw the skin background
+		AknsDrawUtils::Background(
+			skin, iSkinContext, this, gc, aRect);
+		}
+	else
+		{//  clear the area
+		gc.SetBrushColor( iEikonEnv->ControlColor( EColorWindowBackground, *this ) );
+		gc.SetBrushStyle( CGraphicsContext::ESolidBrush );
+		gc.Clear( aRect );
+		}
+
+    // draw text
+    gc.UseFont( iFont );
+    // index of the first line on the screen in the text array
+    TInt firstLine = 0 ;
+
+    // The value of firstLine can not be the same.
+    if ( !iScrollBarDragged )
+        {
+        if ( ( iScreenStarts ) && (iScreenStarts->Count() >= iCurrentScreen ) )
+            {
+    	    firstLine = ( ( *iScreenStarts )[ iCurrentScreen ] ); 	
+            }        
+        }
+    else
+        {                    
+        if ( iCurrentScreen <= ( ( *iScreenStarts )[ iScreenStarts->Count() - 1 ] ) )
+            {
+            firstLine = iCurrentScreen ;
+            }
+        }
+    // index of the last line on the screen in the text array
+    TInt lastLine( firstLine + iLinesPerScreen - 1 );
+
+    gc.SetBrushStyle( CGraphicsContext::ENullBrush );
+    TPoint position( iTopBaseLineX, iTopBaseLineY );
+    TPoint topLeft;
+    TSize rectSize( iLineWidth, iBaseLineDelta +iFont->DescentInPixels() );
+
+    for ( TInt index = firstLine ;
+          index < iText->Count() && index <= lastLine ;
+          index++, position.iY += iBaseLineDelta )
+        {
+        HBufC* text = (*iText)[ index ];
+
+        if ( text )
+            {
+            topLeft = TPoint( position.iX, position.iY-iBaseLineDelta );
+			TRgb color;			
+			TInt error = AknsUtils::GetCachedColor( skin, 
+							color, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG6 );
+			
+			if(error == KErrNone)
+				{
+				gc.SetPenColor(color);
+				}		
+            gc.DrawText( *text,
+                         TRect( topLeft, rectSize ),
+                         iBaseLineDelta,
+                         iTextAlign );
+            }
+        }
+
+    gc.DiscardFont();
+
+    // draw images
+
+    for ( TInt i = 0 ; i < iImages->Count() ; i++ )
+        {
+        CAboutImage* image = (*iImages)[ i ];
+
+        // If part of the image resides in visible lines, draw it.
+        if ( image->StartLine() <= lastLine && image->EndLine() >= firstLine )
+            {
+            position.SetXY( iTopBaseLineX, iTopBaseLineY );
+            position.iY += ( image->StartLine() - firstLine ) * iBaseLineDelta;
+
+            position.iY -= iBaseLineDelta - iFont->DescentInPixels();
+            // Now iY is the top line of rectangle where the picture is
+            // centered in.
+            position.iY += ( (image->Lines()+1) * iBaseLineDelta -
+                             iFont->HeightInPixels() -
+                             image->HeightInPixels() ) / 2;
+
+            // If text is right-aligned, also align images to the right.
+
+            if ( iTextAlign == CGraphicsContext::ERight )
+                {
+                position.iX += ( iLineWidth - image->WidthInPixels() );
+                }
+
+            gc.BitBlt( position, image->Bitmap(), aRect );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAboutContainer::ActivateL()
+// -----------------------------------------------------------------------------
+
+void CAboutContainer::ActivateL()
+    {
+    CCoeControl::ActivateL();
+    UpdateScrollIndicatorL();
+    }
+
+// -----------------------------------------------------------------------------
+// CAboutContainer::SetTextL()
+// -----------------------------------------------------------------------------
+
+void CAboutContainer::SetTextL( const TDesC& aText , const TInt aItem )
+    {
+    CArrayFix<TPtrC>* wrappedArray =
+        new( ELeave ) CArrayFixFlat<TPtrC>( 10 );
+
+    CleanupStack::PushL( wrappedArray );
+
+    HBufC* dataToDestroy =
+        AknBidiTextUtils::ConvertToVisualAndWrapToArrayL(
+            aText, iLineWidth, *iFont, *wrappedArray
+        );
+
+    TInt numLines( wrappedArray->Count() );
+    for ( TInt i = 0 ; i < numLines ; i++ )
+        {
+        HBufC* line = (*wrappedArray)[i].AllocLC();
+
+		switch( aItem )
+			{
+			// The fourteen string's setting
+			case 14:
+				{
+				iBreakFlag = ETrue;
+				break;
+				}
+			default:
+				break;
+			}
+        if(!line->Length())
+            {
+            iText->AppendL( NULL );
+			
+            CleanupStack::PopAndDestroy(line);  // line
+            }
+        else
+            {
+            if( iBreakFlag && ( numLines - 1 ) == i )
+            	{
+                iText->AppendL( line );
+                // Get the text's lines' count for set break
+                TInt textCount = iText->Count();
+                TInt count = iLinesPerScreen - ( textCount % ( iLinesPerScreen - 1 ) ) - 1;
+                if( iLinesPerScreen == count + 1 )
+                	{
+                	// When the last line has content, we should set count zero 
+                	count = 0;
+                	}
+                for( TInt j = 0; j < count; j++ )
+                	{
+                	iText->AppendL( NULL );
+                	}
+                CleanupStack::Pop( line );  // line
+                iBreakFlag = EFalse;
+            	}
+            else
+            	{
+                iText->AppendL( line );
+                CleanupStack::Pop( line );  // line
+            	}
+            }
+        }
+	iText->AppendL( NULL );
+
+    // If the last char was newline, add one extra, since
+    // wrapping automatically removes it.
+    if ( aText[ aText.Length() - 1 ] == '\n' )
+        {
+        iText->AppendL( NULL );
+		}
+
+    CleanupStack::PopAndDestroy(wrappedArray); // wrappedArray
+    delete dataToDestroy;
+
+    // update screen scrolling info array
+
+    TInt lastLine( iText->Count() - 1 );
+    TInt screenStart( (*iScreenStarts)[ iScreenStarts->Count() - 1 ] );
+
+    TBool firstNewScreenHandled( EFalse );
+
+    while ( lastLine >= screenStart + iLinesPerScreen )
+        {
+        if ( !firstNewScreenHandled && iDoNotShowLastLineAgain )
+            {
+            screenStart++;
+            firstNewScreenHandled = ETrue;
+            }
+
+        screenStart += iLinesPerScreen - 1;
+        iScreenStarts->AppendL( screenStart );
+        if ( ( lastLine == screenStart + 1 ) && ( aItem == iNumItem - 1 ) )
+        	{
+        	iScreenStarts->Delete( iScreenStarts->Count() - 1 );
+        	}
+        }
+
+    // if text, last line is shown again in next screen
+    iDoNotShowLastLineAgain = EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CAboutContainer::SetImageL()
+// -----------------------------------------------------------------------------
+
+void CAboutContainer::SetImageL( const TDesC& aFileName, TInt aBitmapId )
+    {
+    TInt firstLineOfImage( iText->Count() );
+
+    // If flag is ETrue, the file type is bmp 
+    CAboutImage* image =
+    CAboutImage::NewLC( aFileName, aBitmapId, firstLineOfImage, iBaseLineDelta, ETrue );
+
+    // new lines to make room for the picture
+
+    for ( TInt i = 0 ; i < image->Lines() ; i++ )
+        {
+        iText->AppendL( NULL );
+        }
+
+    iImages->AppendL( image );
+    CleanupStack::Pop(image); // image
+
+    // update screen scrolling info array
+
+    TInt lastLineOfImage( iText->Count() - 1 );
+    TInt screenStart( (*iScreenStarts)[ iScreenStarts->Count() - 1 ] );
+
+    TBool firstNewScreenHandled( EFalse );
+
+    // If the image was not fully shown in the first screen,
+    // start the next screen with the image.
+
+    if ( firstLineOfImage < screenStart + iLinesPerScreen &&
+         lastLineOfImage >= screenStart + iLinesPerScreen )
+        {
+        screenStart = firstLineOfImage;
+        iScreenStarts->AppendL( screenStart );
+        firstNewScreenHandled = ETrue;
+        }
+
+    while ( lastLineOfImage >= screenStart + iLinesPerScreen )
+        {
+        if ( !firstNewScreenHandled && iDoNotShowLastLineAgain )
+            {
+            screenStart++;
+            firstNewScreenHandled = ETrue;
+            }
+
+        screenStart += iLinesPerScreen - 1;
+        iScreenStarts->AppendL( screenStart );
+        }
+
+    if ( lastLineOfImage == screenStart + iLinesPerScreen - 1 )
+        {
+        iDoNotShowLastLineAgain = ETrue;
+        }
+    else
+        {
+        iDoNotShowLastLineAgain = EFalse;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CAboutContainer::OfferKeyEventL()
+// -----------------------------------------------------------------------------
+
+TKeyResponse CAboutContainer::OfferKeyEventL( const TKeyEvent& aKeyEvent,
+                                              TEventCode aType )
+    {
+    // Operation is different in dragging and thumbing.
+    if ( ( iScrollBarDragged ) && ( aType == EEventKey ) )
+        {
+        for( TInt i=0; i<iScreenStarts->Count(); i++ )
+            {
+            if ( iCurrentScreen <= ( ( *iScreenStarts )[i] ) ) 
+                {
+                // if last state is dragging, value of iCurrentScreen should be adjusted.
+                switch ( aKeyEvent.iCode )
+                    {
+                    case EKeyUpArrow:
+                        {
+                        iScrollBarDragged = EFalse;
+                        // Do nothing if the scroll bar is on the top, when pressing arrow up.
+                        if ( i != 0 )
+                            {
+                            iCurrentScreen =  ( i - 1 );
+                            }
+                        DrawNow();
+                        UpdateScrollIndicatorL();
+                        break;
+                        }
+                    case EKeyDownArrow:
+                        {
+                        iScrollBarDragged = EFalse;
+                        if ( ( iCurrentScreen == ( *iScreenStarts )[i] )
+                            // Do nothing if the scroll bar is on the bottom, when pressing arrow down.
+                            && ( i != ( iScreenStarts->Count() - 1 ) ) )
+                            {
+                            iCurrentScreen = ( i + 1 );
+                            }
+                       	else
+                            {
+                            iCurrentScreen = i;
+                            }
+                        DrawNow();
+                        UpdateScrollIndicatorL();
+                        break;
+                        }
+                    default:
+                        break;
+                    }
+                return EKeyWasConsumed;
+                }
+            } 
+        }
+        
+    if ( aType == EEventKey && iScreenStarts->Count() > 1 )
+        {
+        switch ( aKeyEvent.iCode )
+            {
+            case EKeyUpArrow:
+                {
+                if ( iCurrentScreen > 0 )
+                    {
+                    iCurrentScreen--;
+                    DrawNow();
+                    UpdateScrollIndicatorL();
+                    }
+                }
+                break;
+
+            case EKeyDownArrow:
+                {
+                if ( iCurrentScreen < iScreenStarts->Count() - 1 )
+                    {
+                    iCurrentScreen++;
+                    DrawNow();
+                    UpdateScrollIndicatorL();
+                    }
+                }
+                break;
+
+            default:
+                break;
+            }
+        return EKeyWasConsumed;
+        }
+
+    // When pressing the Send Key and the event's type is not EEvenKey return EKeyWasNotConsumed
+    return EKeyWasNotConsumed;
+    }
+
+// -----------------------------------------------------------------------------
+// CAboutContainer::UpdateScrollIndicatorL()
+// -----------------------------------------------------------------------------
+
+void CAboutContainer::UpdateScrollIndicatorL()
+ {
+    if ( iScreenStarts->Count() <= 1 )
+    {
+        return;
+    }
+
+    if ( !iSBFrame )
+    {
+        iSBFrame = new( ELeave ) CEikScrollBarFrame( this,this, ETrue );
+        
+		// Decide which type of scrollbar is to be shown
+        CAknAppUi* appUi = iAvkonAppUi;
+		if (AknLayoutUtils::DefaultScrollBarType(appUi) == CEikScrollBarFrame::EDoubleSpan)
+		{
+			// For EDoubleSpan type scrollbar
+			iSBFrame->CreateDoubleSpanScrollBarsL(ETrue, EFalse); // non-window owning scrollbar            
+			iSBFrame->SetTypeOfVScrollBar(CEikScrollBarFrame::EDoubleSpan);
+		}
+		else
+		{
+			// For EArrowHead type scrollbar
+			iSBFrame->SetTypeOfVScrollBar(CEikScrollBarFrame::EArrowHead);
+		}  
+		iSBFrame->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff,CEikScrollBarFrame::EAuto);
+    }
+
+	TEikScrollBarModel hSbarModel;
+    TEikScrollBarModel vSbarModel;
+
+    // The member of vSbarModel shoul be changed because the state when dragging scroll bar shoul be considered.
+    TInt spanAdjust = iLinesPerScreen - ( iText->Count() - ( *iScreenStarts )[ iScreenStarts->Count() - 1 ] + 1 );
+    if ( iScrollBarDragged )
+    {
+    vSbarModel.iThumbPosition = iCurrentScreen;
+    }
+    else
+    {
+        vSbarModel.iThumbPosition = iCurrentScreen * ( iLinesPerScreen - 1 );
+    }
+    vSbarModel.iScrollSpan = iText->Count() + spanAdjust;
+    vSbarModel.iThumbSpan = ( iLinesPerScreen - 1 );
+	
+	TRect rect(Rect());  
+    TEikScrollBarFrameLayout layout;
+	layout.iTilingMode = TEikScrollBarFrameLayout::EInclusiveRectConstant;
+
+    if (iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan)
+    {    
+        // For EDoubleSpan type scrollbar
+        if (vSbarModel.iThumbPosition + vSbarModel.iThumbSpan > vSbarModel.iScrollSpan)
+        {
+            // Not let scrollbar values overflow
+            vSbarModel.iThumbPosition = vSbarModel.iScrollSpan - vSbarModel.iThumbSpan;
+        }
+		
+        TAknDoubleSpanScrollBarModel hDsSbarModel(hSbarModel);
+        TAknDoubleSpanScrollBarModel vDsSbarModel(vSbarModel);
+       
+        // When resolution is changed, changing the drawing area of layout for the text.
+        TRect currentRect( iAvkonAppUi->ClientRect() );
+        iSBFrame->TileL(&hDsSbarModel, &vDsSbarModel, currentRect, rect, layout);        
+        iSBFrame->SetVFocusPosToThumbPos(vDsSbarModel.FocusPosition());
+	}  
+	else
+	{
+		iSBFrame->TileL( &hSbarModel, &vSbarModel, rect, rect, layout );
+		iSBFrame->SetVFocusPosToThumbPos( vSbarModel.iThumbPosition );
+	}
+}
+
+
+// End of File
+
+void CAboutContainer::CalculateL(const TRect& aRect)
+    {
+    TRect rect( 0, 0, 0, 0 );
+    iCurrentScreen = 0;
+	
+    if ( iSkinContext )
+        {
+        delete iSkinContext;
+        iSkinContext = NULL;
+        }  
+	
+    // Temporary rect is passed. Correct rect is set in SizeChanged.
+    iSkinContext = CAknsBasicBackgroundControlContext::NewL(
+    KAknsIIDQsnBgAreaMain , rect, EFalse );
+
+    iFont = AknLayoutUtils::FontFromId( EAknLogicalFontSecondaryFont );
+
+    // Calculate various text positioning parameters
+    iBaseLineDelta = iFont->HeightInPixels() * 4 / 3;
+
+    TInt mainPaneWidth( aRect.iBr.iX - aRect.iTl.iX );
+    TInt mainPaneHeight( aRect.iBr.iY - aRect.iTl.iY );
+    // Line width is 87% of client rect, horizontal margins 13%
+    iLineWidth = mainPaneWidth * 87 / 100;
+    iTopBaseLineX = ( mainPaneWidth - iLineWidth ) / 2;
+
+    // top margin is 6.5% of the client rect
+    TInt topMargin = mainPaneHeight * 65 / 1000;    
+    iTopBaseLineY = topMargin + iFont->AscentInPixels();
+
+    // minimum bottom margin is 3% of the client rect
+    TInt bottomMargin = mainPaneHeight * 3 / 100;
+    iLinesPerScreen =
+        ( mainPaneHeight - topMargin - bottomMargin ) / iBaseLineDelta;
+    
+    TInt uiLanguage = User::Language();
+    
+    if( uiLanguage == ELangArabic || uiLanguage == ELangFarsi || 
+        uiLanguage == ELangHebrew || uiLanguage == ELangUrdu )
+    	{
+        iTextAlign = CGraphicsContext::ERight;
+    	}
+    else
+    	{
+        iTextAlign = CGraphicsContext::ELeft;
+    	}
+
+   
+    if ( iText )
+        {
+        iText->ResetAndDestroy();
+        delete iText;
+        iText = NULL;
+        }
+
+    // Every text line on screen is one entry in this array
+    iText = new( ELeave ) CArrayPtrFlat<HBufC>( 20 );
+
+    if ( iImages )
+        {
+        iImages->ResetAndDestroy();
+        delete iImages;
+        iImages = NULL;
+        }
+
+    // Every image on screen is one entry in this array
+    iImages = new( ELeave ) CArrayPtrFlat<CAboutImage>( 1 );
+
+    if ( iScreenStarts )
+        {
+        delete iScreenStarts;
+        iScreenStarts = NULL;
+        }
+    // This array contains indices for lines that start the subsequent
+    // screens, for custom scrolling
+    iScreenStarts = new( ELeave ) CArrayFixFlat<TInt>( 5 );
+    // Initialisation: first screen starts at line 0.
+    iScreenStarts->AppendL( 0 );
+
+    // Read text and image items to be shown on the screen from a resource file.
+#ifdef __ABOUT_USE_TEST_RESOURCE__
+    #include <about_test.rsg>
+    // test resource
+    _LIT(KDirAndFile, "Z:about_test.rsc");
+    TParse* fp = new(ELeave) TParse ();
+    fp->Set (KDirAndFile, &KDC_APP_RESOURCE_DIR, NULL);
+    TBuf<254> KAboutTestResourceFileName;
+    KAboutTestResourceFileName.Copy(fp ->FullName());
+    delete fp;
+    fp=NULL;
+
+    TFileName fileName( KAboutTestResourceFileName );
+    BaflUtils::NearestLanguageFile( iEikEnv->FsSession(), filename );
+    TInt testResourceFileOffset = iCoeEnv->AddResourceFileL( fileName );
+    TResourceReader reader;
+    iEikonEnv->CreateResourceReaderLC( reader, R_ABOUT_TEST_MAIN_TEXT );
+#else
+    // real resource
+    TResourceReader reader;
+    iEikonEnv->CreateResourceReaderLC( reader, R_ABOUT_MAIN_TEXT );
+#endif
+ 
+    TInt NumItem( reader.ReadInt16() );
+    iNumItem = NumItem;
+
+    for ( TInt i = 0 ; i < iNumItem ; i++ )
+        {
+        TInt type = reader.ReadInt8();
+        if ( type == EAboutTextItem )    
+            { 
+            HBufC* text;  
+            if ( reader.ReadInt8() == EAboutUpdateTime )
+                {  
+                TTime time;
+                time.UniversalTime();
+                TDateTime currentTime = time.DateTime();
+                text = StringLoader::LoadLC( reader.ReadInt32(), 
+                                            currentTime.Year(), CEikonEnv::Static() );
+                }
+            else
+                {
+                text = iEikonEnv->AllocReadResourceLC( reader.ReadInt32() );
+                }
+			SetTextL( *text , i );
+			CleanupStack::PopAndDestroy( text );
+            }
+        else if ( type == EAboutImageItem )
+            {
+            TPtrC bitmapFile = reader.ReadTPtrC();
+            TInt bitmapId = reader.ReadInt16();
+            if( iIsSvg )
+            	{
+            	TFileName svgPath;
+            	_LIT( KSvgFileName, "Z:about.mif" );
+            	TParse* fpSvg = new( ELeave ) TParse ();
+            	fpSvg->Set( KSvgFileName, &KDC_APP_BITMAP_DIR, NULL );
+            	svgPath.Copy( fpSvg ->FullName() );
+            	delete fpSvg;
+            	fpSvg = NULL;    
+            	SetImageL( svgPath, EMbmAboutQgn_graf_java_logo );
+            	}
+            else
+            	{
+            	SetImageL( bitmapFile, bitmapId );
+            	}
+            }
+        else
+            {
+            User::Panic( KAboutPanicCategory, EAboutNotSupported );
+            }
+        }
+
+    CleanupStack::PopAndDestroy(); // reader
+
+#ifdef __ABOUT_USE_TEST_RESOURCE__
+    if ( testResourceFileOffset )
+        {
+        iCoeEnv->DeleteResourceFile( testResourceFileOffset );
+        }
+#endif
+
+    SetRect( aRect );  
+    UpdateScrollIndicatorL();
+    }
+
+
+ void CAboutContainer::HandleResourceChange(TInt aType)
+ {
+
+switch ( aType )
+  {
+  case KEikDynamicLayoutVariantSwitch :
+       {
+       TRAP_IGNORE(CalculateL(iAvkonAppUi->ClientRect()));   
+       DrawNow();
+       }
+       break;
+  case KEikMessageUnfadeWindows :
+  case KAknsMessageSkinChange :
+       {
+       TRAP_IGNORE(iSBFrame->CreateDoubleSpanScrollBarsL(ETrue, EFalse)); // window owning scrollbar            
+       iSBFrame->SetTypeOfVScrollBar(CEikScrollBarFrame::EDoubleSpan);
+ 	   TRAP_IGNORE(iSBFrame->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff,CEikScrollBarFrame::EOn));
+	   TRAP_IGNORE(UpdateScrollIndicatorL());
+       }
+        
+  default:
+       {
+       CCoeControl::HandleResourceChange(aType);
+       }
+	   break;
+  }
+}  
+// ---------------------------------------------------------
+// CAboutContainer::MopSupplyObject()
+// Pass skin information if need.
+// ---------------------------------------------------------
+
+TTypeUid::Ptr CAboutContainer::MopSupplyObject(TTypeUid aId)
+    {
+    if (aId.iUid == MAknsControlContext::ETypeId && iSkinContext)
+        {
+        return MAknsControlContext::SupplyMopObject(aId, iSkinContext);
+        }
+
+    return CCoeControl::MopSupplyObject(aId);
+    }
+
+// ---------------------------------------------------------
+// CAboutContainer::HandleScrollEventL()
+// Capture Touch Events on the Scroll Bar
+// ---------------------------------------------------------
+void CAboutContainer::HandleScrollEventL(CEikScrollBar* aScrollBar,TEikScrollEvent aEventType)
+{
+    //Only on page up/down,scroll up/down and drag events
+    if((aEventType == EEikScrollPageDown) || (aEventType == EEikScrollPageUp) || 
+       (aEventType == EEikScrollThumbDragVert) || (aEventType == EEikScrollUp) ||
+       (aEventType == EEikScrollDown))
+    {
+        //Get the current position from the scroll bar
+        iCurrentScreen = aScrollBar->ThumbPosition();
+        
+        // Reset flag when dragging scroll bar
+        iScrollBarDragged = ETrue;
+        //Refresh now
+        DrawNow();
+        UpdateScrollIndicatorL();
+    }
+    
+}