uifw/EikStd/coctlsrc/EIKSBFRM.CPP
changeset 0 2f259fa3e83a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uifw/EikStd/coctlsrc/EIKSBFRM.CPP	Tue Feb 02 01:00:49 2010 +0200
@@ -0,0 +1,1451 @@
+/*
+* Copyright (c) 1997-1999 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:
+*
+*/
+
+
+#include <eiksbfrm.h>
+#include <eikpanic.h>
+#include <eikbtgpc.h>
+#include <eikcba.h>
+#include <eikenv.h>
+#include <eikappui.h>
+
+#include <aknenv.h>
+#include <aknappui.h>
+#include <AknLayout.lag>
+#include <AknUtils.h>
+
+#include "EIKSBEXT.H"
+
+// const TInt KCbaScrollBarWidth=9;
+
+//
+// TEikScrollBarFrameLayout
+//
+
+EXPORT_C TEikScrollBarFrameLayout::TEikScrollBarFrameLayout()
+	//
+	// default constructor
+	//
+	{
+    iInclusiveMargin.iTop = 0;
+    iInclusiveMargin.iBottom = 0;
+    iInclusiveMargin.iLeft = 0;
+    iInclusiveMargin.iRight = 0;
+    
+    iClientMargin.iTop = 0;
+    iClientMargin.iBottom = 0;
+    iClientMargin.iLeft = 0;
+    iClientMargin.iRight = 0;
+    
+    iClientAreaGranularity = TSize(0,0);
+    
+    iTilingMode = EClientRectConstant;
+	}
+
+EXPORT_C void TEikScrollBarFrameLayout::SetInclusiveMargin(TInt aMargin)
+	//
+	// sets all inclusive margins to aMargin
+	//
+	{
+    iInclusiveMargin.iTop = aMargin;
+    iInclusiveMargin.iBottom = aMargin;
+    iInclusiveMargin.iLeft = aMargin;
+    iInclusiveMargin.iRight = aMargin;
+	}
+
+EXPORT_C void TEikScrollBarFrameLayout::SetClientMargin(TInt aMargin)
+	//
+	// sets all client margins to aMargin
+	//
+	{
+    iClientMargin.iTop = aMargin;
+    iClientMargin.iBottom = aMargin;
+    iClientMargin.iLeft = aMargin;
+    iClientMargin.iRight = aMargin;
+	}
+
+
+CEikScrollBarFrameExtension::CEikScrollBarFrameExtension()
+    {
+
+    }
+
+CEikScrollBarFrameExtension::~CEikScrollBarFrameExtension()
+    {
+
+    }
+
+//
+// CEikScrollBarFrame
+//
+
+enum TEikScrollBarFramePanic
+	{
+	ENoScrollBarFrame	=0x01,
+	EFailedToRemoveExternalScrollBar,
+	EUnexpectedExternalScrollBarDisconnectRequest
+	};
+
+GLDEF_C void SbfPanic(TEikScrollBarFramePanic aPanic)
+    {
+	_LIT(KPanicCategory, "UIKON - Scrollbar Frame");
+    User::Panic(KPanicCategory, aPanic);
+    }
+
+// const TInt KTypeOfScrollBarMask=0x0300;
+// const TInt KSideOfScrollBarMask=0x0c00;
+
+
+enum // private flags
+	{
+	EDisplayHScrollBar			=0x01,
+	EDisplayVScrollBar			=0x02,
+	EDoNotAdjustHorizontalModel	=0x04,
+	EDoNotAdjustVerticalModel	=0x08,
+	EPreAllocScrollBars			=0x10
+	};
+
+EXPORT_C CEikScrollBarFrame::~CEikScrollBarFrame()
+	{
+    DeleteScrollBars();
+    delete iExtension;
+	}
+
+EXPORT_C CEikScrollBarFrame::CEikScrollBarFrame(CCoeControl* aParentWindow, MEikScrollBarObserver* aObserver, TBool /*aPreAlloc*/)
+	{
+    InitExtension(aParentWindow,aObserver);
+	GetScrollBars(EFalse);	
+	}
+
+CEikScrollBarFrame::CEikScrollBarFrame(CCoeControl* aParentWindow, MEikScrollBarObserver* aObserver, TBool /*aPreAlloc*/, TBool aDoubleSpan)
+	{
+    InitExtension(aParentWindow,aObserver);
+	GetScrollBars(aDoubleSpan);
+	}
+
+void CEikScrollBarFrame::InitExtension(CCoeControl* aParentWindow, MEikScrollBarObserver* aObserver)
+    {
+    iExtension = new CEikScrollBarFrameExtension();
+    if (iExtension)
+        {
+        iExtension->iParentWindow = aParentWindow;
+        iExtension->iH.iModel = TAknDoubleSpanScrollBarModel();
+        iExtension->iH.iBar = NULL;
+        iExtension->iH.iExternalScrollBarAttached = EFalse;
+        iExtension->iH.iVisibility = EOff; 
+        if(AknLayoutUtils::PenEnabled())
+            {
+            iExtension->iScrollBarObserver = aObserver;
+            }
+        }
+    }
+
+void CEikScrollBarFrame::DisconnectExternalScrollBar(CEikScrollBar* aScrollBar)
+	{
+	if (iV.iExternalScrollBarAttached && iV.iBar == aScrollBar)
+        {
+        iV.iExternalScrollBarAttached = EFalse;
+	    iV.iBar = NULL;
+        }
+
+    if (iExtension && iExtension->iH.iExternalScrollBarAttached && iExtension->iH.iBar == aScrollBar) 
+        {
+    	iExtension->iH.iExternalScrollBarAttached = EFalse;
+	    iExtension->iH.iBar = NULL;
+        }
+    }
+
+void CEikScrollBarFrame::GetScrollBars(TBool aDoubleSpan)
+	{
+	if (!iV.iBar)
+		{
+		CEikCba* cba=GetCurrentCba();
+		if (cba)
+			{
+			// If aDoubleSpan is true, we will optimize and do not create arrow heads at all.
+			// There will come CreateDoubleSpanScrollBarsL call, and arrow heads are not needed.
+			if ( !(aDoubleSpan && (AknLayoutUtils::DefaultScrollBarType(iAvkonAppUi) == CEikScrollBarFrame::EDoubleSpan)) )
+			    {
+			    TRAP_IGNORE(cba->CreateArrowHeadScrollBarL());  
+			    }
+			// returns the vertical scroll bar from the top scroll bar host
+			iV.iBar=cba->VScrollBarAsControl();
+			iV.iExternalScrollBarAttached=ETrue;
+			TRAPD(err, iV.iBar->AddExternalFrameL(this));
+			if (err)
+				{
+				iV.iExternalScrollBarAttached = EFalse;
+				iV.iBar = NULL;
+				}
+			}
+		}
+	}
+
+EXPORT_C void CEikScrollBarFrame::DrawScrollBarsNow() const
+// Force a redraw of any scrollbars
+	{	
+	if (iV.iBar && iExtension && iExtension->iParentWindow->IsVisible())
+		iV.iBar->DrawNow();
+
+	if (iExtension && iExtension->iH.iBar && iExtension->iParentWindow->IsVisible())
+		iExtension->iH.iBar->DrawNow();
+
+	}
+
+void CEikScrollBarFrame::DrawScrollBarsDeferred() const
+    {
+    if (iV.iBar && iExtension && iExtension->iParentWindow->IsVisible())
+	    {	   
+	    iV.iBar->DrawDeferred();	    
+	    }		
+
+	if (iExtension && iExtension->iH.iBar && iExtension->iParentWindow->IsVisible())
+	    {
+	    iExtension->iH.iBar->DrawDeferred();	    
+	    }    
+    }
+
+const TInt KLongEnoughToCauseComponentsToBeCreated=200;
+
+
+EXPORT_C void CEikScrollBarFrame::SetScrollBarVisibilityL(TScrollBarVisibility aHVisibility, TScrollBarVisibility aVVisibility)
+// Set the visibility state for both scrollbars to be used when tiling
+	{
+	__ASSERT_DEBUG(this, SbfPanic(ENoScrollBarFrame));
+
+    // Vertical scrollbar
+	iV.iVisibility=aVVisibility;
+    if (iV.iBar && TypeOfVScrollBar() == EDoubleSpan && aVVisibility==EOff)
+        {
+       	iScrollBarFrameFlags&=(~EDisplayVScrollBar);
+        MakeSBarVisible(iV, EFalse);
+        }
+
+    // Horizontal scrollbar
+    if (iExtension)
+        {
+    	iExtension->iH.iVisibility=aHVisibility;
+        if (iExtension->iH.iBar && TypeOfHScrollBar() == EDoubleSpan && aHVisibility==EOff)
+            {
+       	    iScrollBarFrameFlags&=(~EDisplayHScrollBar);
+            MakeSBarVisible(iExtension->iH, EFalse);
+            }
+        }
+	}
+
+EXPORT_C TBool CEikScrollBarFrame::Tile(TEikScrollBarModel* aVModel)
+	//
+	// The main function which provides the necessary scrollbars according to visibilities and size considerations
+	// returns ETrue if the "output rect" was changed
+	//
+	{
+	GetScrollBars(EFalse);
+	CalcTheoreticalScrollBarVisibility(aVModel);
+	if (iV.iVisibility!=EOff)
+		iV.iModel = *aVModel;
+	MakeSBarVisible(iV, iScrollBarFrameFlags&EDisplayVScrollBar);
+	return EFalse;
+	}
+
+EXPORT_C TBool CEikScrollBarFrame::TileL(TEikScrollBarModel* aHModel, TEikScrollBarModel* aVModel,
+			  TRect& aClientRect, TRect& aInclusiveRect, const TEikScrollBarFrameLayout& aLayout)
+	{
+	TRect tempRect(aClientRect);
+	if(aClientRect.Height() < 0 )
+	    {
+	    aClientRect.iTl.iY = aClientRect.iBr.iY;
+	    aClientRect.iBr.iY = tempRect.iTl.iY;
+	    }
+	if(aClientRect.Width() < 0 )
+        {
+        aClientRect.iTl.iX = aClientRect.iBr.iX;
+        aClientRect.iBr.iX = tempRect.iTl.iX;
+        }
+	tempRect = aInclusiveRect;
+	if(aInclusiveRect.Height() < 0 )
+        {
+        aInclusiveRect.iTl.iY = aInclusiveRect.iBr.iY;
+        aInclusiveRect.iBr.iY = tempRect.iTl.iY;
+        }
+    if(aInclusiveRect.Width() < 0 )
+        {
+        aInclusiveRect.iTl.iX = aInclusiveRect.iBr.iX;
+        aInclusiveRect.iBr.iX = tempRect.iTl.iX;
+        }
+    if (iExtension && iExtension->iH.iVisibility!=EOff)
+        {
+        if(aClientRect.Height() < ScrollBarBreadth( CEikScrollBar::EHorizontal) )
+            {
+            aClientRect.SetHeight( ScrollBarBreadth(CEikScrollBar::EHorizontal) );
+            }
+        if(aInclusiveRect.Height() < ScrollBarBreadth( CEikScrollBar::EHorizontal) )
+            {
+            aInclusiveRect.SetHeight( ScrollBarBreadth(CEikScrollBar::EHorizontal) );
+            }
+        }
+    TBool sizeChanged = EFalse;
+    
+	GetScrollBars(EFalse);
+	CalcTheoreticalScrollBarVisibility(aVModel,aHModel);
+
+	if (iV.iVisibility!=EOff)
+		iV.iModel = *aVModel;
+	
+	MakeSBarVisible(iV, iScrollBarFrameFlags&EDisplayVScrollBar);
+
+    if (iExtension && iExtension->iH.iBar)
+        {
+        if (iExtension->iH.iVisibility!=EOff)
+	        iExtension->iH.iModel = *aHModel;   
+        
+        MakeSBarVisible(iExtension->iH, iScrollBarFrameFlags&EDisplayHScrollBar);
+        }
+
+    // Vertical Double span scollbar
+    if (iV.iBar && TypeOfVScrollBar() == EDoubleSpan && iV.iExternalScrollBarAttached==EFalse )
+        {        
+        TInt scrollBarWidth = ScrollBarBreadth(CEikScrollBar::EVertical); // is 0 if SB not visible !
+        TInt horizontalScrollBarWidth = 0;
+        if (iExtension && iExtension->iH.iVisibility!=EOff)
+            {
+            horizontalScrollBarWidth = ScrollBarBreadth(CEikScrollBar::EHorizontal);
+            }
+        CAknDoubleSpanScrollBar* scrollbar = static_cast <CAknDoubleSpanScrollBar*> (iV.iBar);
+        if (scrollbar->FixedLayoutRect().Size() == TSize(0,0))
+            {
+            TMargins checkedClientMargin(aLayout.iClientMargin);
+            TMargins checkedInclusiveMargin(aLayout.iInclusiveMargin);
+            checkedClientMargin.iTop = Max(0,checkedClientMargin.iTop);
+            checkedClientMargin.iBottom = Max(0,checkedClientMargin.iBottom);
+            checkedClientMargin.iRight = Max(0,checkedClientMargin.iRight);
+            checkedClientMargin.iLeft = Max(0,checkedClientMargin.iLeft);
+
+            checkedInclusiveMargin.iTop = Max(0,checkedInclusiveMargin.iTop);
+            checkedInclusiveMargin.iBottom = Max(0,checkedInclusiveMargin.iBottom);
+            checkedInclusiveMargin.iRight = Max(0,checkedInclusiveMargin.iRight);
+            checkedInclusiveMargin.iLeft = Max(0,checkedInclusiveMargin.iLeft);
+
+            TInt width  = 0;                
+            TInt xPos   = 0;
+            TInt yPos   = 0;
+            TInt height = 0;
+            
+            if (!AknLayoutUtils::LayoutMirrored())
+                {
+                if (aLayout.iTilingMode == TEikScrollBarFrameLayout::EInclusiveRectConstant)
+                    {
+                    width = scrollBarWidth + checkedInclusiveMargin.iRight;                
+                    xPos = aInclusiveRect.iBr.iX - width;
+                    yPos = aInclusiveRect.iTl.iY + checkedInclusiveMargin.iTop;
+                    height = aInclusiveRect.Size().iHeight - (checkedInclusiveMargin.iTop + checkedInclusiveMargin.iBottom) - horizontalScrollBarWidth;
+                
+                    if ((aClientRect.iBr.iX + width > aInclusiveRect.iBr.iX) || (aInclusiveRect.iBr.iX - width > aClientRect.iBr.iX))
+                        {
+                        aClientRect.iBr.iX = aInclusiveRect.iBr.iX - width;
+                        sizeChanged = ETrue;
+                        }
+                    }
+                else
+                    {
+                    width = scrollBarWidth + checkedClientMargin.iRight;                
+                    xPos = aClientRect.iBr.iX + checkedClientMargin.iRight;
+                    yPos = aInclusiveRect.iTl.iY + checkedInclusiveMargin.iTop;
+                    height = aInclusiveRect.Size().iHeight - (checkedInclusiveMargin.iTop + checkedInclusiveMargin.iBottom) - horizontalScrollBarWidth;
+
+                    if ((aClientRect.iBr.iX + width + checkedInclusiveMargin.iRight > aInclusiveRect.iBr.iX) || 
+                        (aInclusiveRect.iBr.iX - (width + checkedInclusiveMargin.iRight) > aClientRect.iBr.iX))
+                        {
+                        aInclusiveRect.iBr.iX = aClientRect.iBr.iX + width + checkedInclusiveMargin.iRight;
+                        sizeChanged = ETrue;
+                        }
+                    }
+                }
+            else
+                {
+                // Mirrored Left & Right
+                if (aLayout.iTilingMode == TEikScrollBarFrameLayout::EInclusiveRectConstant)
+                    {
+                    width = scrollBarWidth + checkedInclusiveMargin.iRight;                
+                    xPos = aInclusiveRect.iTl.iX + checkedInclusiveMargin.iRight;
+                    yPos = aInclusiveRect.iTl.iY + checkedInclusiveMargin.iTop;
+                    height = aInclusiveRect.Size().iHeight - (checkedInclusiveMargin.iTop + checkedInclusiveMargin.iBottom) - horizontalScrollBarWidth;
+                
+                    if ((aClientRect.iTl.iX - width < aInclusiveRect.iTl.iX) || (aInclusiveRect.iTl.iX + width > aClientRect.iTl.iX))
+                        {
+                        aClientRect.iTl.iX = aInclusiveRect.iTl.iX + width;
+                        xPos = aInclusiveRect.iTl.iX + checkedInclusiveMargin.iRight;
+                        sizeChanged = ETrue;
+                        }
+                    }
+                else
+                    {
+                    width = scrollBarWidth + checkedClientMargin.iRight;                
+                    xPos = aClientRect.iTl.iX - checkedClientMargin.iRight;
+                    yPos = aInclusiveRect.iTl.iY + checkedInclusiveMargin.iTop;
+                    height = aInclusiveRect.Size().iHeight - (checkedInclusiveMargin.iTop + checkedInclusiveMargin.iBottom) - horizontalScrollBarWidth;
+
+                    if ((aClientRect.iTl.iX - width - checkedInclusiveMargin.iRight > aInclusiveRect.iTl.iX) || 
+                        (aInclusiveRect.iTl.iX - (width + checkedInclusiveMargin.iRight) < aClientRect.iTl.iX))
+                        {
+                        aInclusiveRect.iTl.iX = aClientRect.iTl.iX - width - checkedInclusiveMargin.iRight;
+                        xPos = aInclusiveRect.iTl.iX + checkedInclusiveMargin.iRight;
+                        sizeChanged = ETrue;
+                        }
+                    }
+
+                }
+    
+            TRect newRect = TRect(TPoint(xPos, yPos), TSize(width, height ));
+            if (iV.iBar->IsVisible() && (newRect != TRect(iV.iBar->Position(), iV.iBar->Size())))
+                {
+                iV.iBar->SetRect(newRect);                     
+                }
+
+            }
+        }
+
+    // Horizontal Double span scollbar
+    if (iExtension && 
+        iExtension->iH.iBar && 
+        TypeOfHScrollBar() == EDoubleSpan && 
+        iExtension->iH.iExternalScrollBarAttached==EFalse )
+        {                
+        TInt scrollBarWidth = ScrollBarBreadth(CEikScrollBar::EHorizontal); // is 0 if SB not visible !
+        TInt verticalScrollBarWidth = 0;
+        if (iV.iVisibility!=EOff)
+            {
+            verticalScrollBarWidth = ScrollBarBreadth(CEikScrollBar::EVertical);
+            }
+        CAknDoubleSpanScrollBar* scrollbar = static_cast <CAknDoubleSpanScrollBar*> (iExtension->iH.iBar);
+        if (scrollbar->FixedLayoutRect().Size() == TSize(0,0))
+            {
+            TMargins checkedClientMargin(aLayout.iClientMargin);
+            TMargins checkedInclusiveMargin(aLayout.iInclusiveMargin);
+            checkedClientMargin.iTop = Max(0,checkedClientMargin.iTop);
+            checkedClientMargin.iBottom = Max(0,checkedClientMargin.iBottom);
+            checkedClientMargin.iRight = Max(0,checkedClientMargin.iRight);
+            checkedClientMargin.iLeft = Max(0,checkedClientMargin.iLeft);
+
+            checkedInclusiveMargin.iTop = Max(0,checkedInclusiveMargin.iTop);
+            checkedInclusiveMargin.iBottom = Max(0,checkedInclusiveMargin.iBottom);
+            checkedInclusiveMargin.iRight = Max(0,checkedInclusiveMargin.iRight);
+            checkedInclusiveMargin.iLeft = Max(0,checkedInclusiveMargin.iLeft);
+
+            TInt width  = 0;                
+            TInt xPos   = 0;
+            TInt yPos   = 0;
+            TInt height = 0;
+            
+            if (aLayout.iTilingMode == TEikScrollBarFrameLayout::EInclusiveRectConstant)
+                {
+                width = scrollBarWidth + checkedInclusiveMargin.iBottom; // width as vertical direction (height).               
+                xPos = aInclusiveRect.iTl.iX + checkedInclusiveMargin.iLeft;
+                if (AknLayoutUtils::LayoutMirrored())
+                    {
+                    xPos += verticalScrollBarWidth;
+                    }
+                yPos = aInclusiveRect.iBr.iY - checkedInclusiveMargin.iBottom - width;
+                height = aInclusiveRect.Size().iWidth - (checkedInclusiveMargin.iLeft + checkedInclusiveMargin.iRight) - verticalScrollBarWidth; // height as horizontal (width).
+                
+                if ((aClientRect.iBr.iY + width > aInclusiveRect.iBr.iY) || (aInclusiveRect.iBr.iY - width > aClientRect.iBr.iY))
+                    {
+                    aClientRect.iBr.iY = aInclusiveRect.iBr.iY - width;
+                    sizeChanged = ETrue;
+                    }
+                }
+            else
+                {
+                width = scrollBarWidth + checkedClientMargin.iBottom; // width as vertical direction (height).               
+                xPos = aInclusiveRect.iTl.iX + checkedInclusiveMargin.iLeft;
+                if (AknLayoutUtils::LayoutMirrored())
+                    {
+                    xPos += verticalScrollBarWidth;
+                    }
+                yPos = aClientRect.iBr.iY + checkedClientMargin.iBottom;
+                height = aInclusiveRect.Size().iWidth - (checkedInclusiveMargin.iLeft + checkedInclusiveMargin.iRight) - verticalScrollBarWidth; // height as horizontal (width).
+                
+                if ((aClientRect.iBr.iY + width + checkedClientMargin.iBottom > aInclusiveRect.iBr.iY) || 
+                    (aInclusiveRect.iBr.iY - (width + checkedInclusiveMargin.iBottom) > aClientRect.iBr.iY))
+                    {
+                    aInclusiveRect.iBr.iY = aClientRect.iBr.iY + width + checkedInclusiveMargin.iBottom;
+                    sizeChanged = ETrue;
+                    }
+                }
+
+            TRect newRect = TRect(TPoint(xPos, yPos), TSize(height, width ));  // height & width swapped 
+            if (iExtension->iH.iBar->IsVisible() && (newRect != TRect(iV.iBar->Position(), iV.iBar->Size())))
+                {
+                iExtension->iH.iBar->SetRect(newRect);                   
+                }
+            }
+        
+        }
+
+    return sizeChanged;
+	}
+
+EXPORT_C void CEikScrollBarFrame::MoveThumbsBy(TInt aDeltaX, TInt aDeltaY)
+	//
+ 	// Used to update any scrollbar(s) after an external scroll
+	// values in terms of the model, presumed not to have changed spans.
+	//
+	{
+    // Vertical scrollbar
+    if (aDeltaY && iV.iBar)
+        {
+        if (TypeOfVScrollBar() == TScrollBarType(EArrowHead))
+            {
+		    iV.iModel.iThumbPosition += aDeltaY;
+            }
+        else
+            {
+            // EDoubleSpan has different model.
+            if (iV.iModel.ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
+                {
+                TAknDoubleSpanScrollBarModel* model = static_cast <TAknDoubleSpanScrollBarModel*> (&iV.iModel);
+                // Note that for a large scroll span and small delta this may not actually change focusposition
+                // because of the 15 bit accuracy of TAknDoubleSpanScrollBarModel values.
+                model->SetFocusPosition(model->FocusPosition() + aDeltaY);    
+                }
+            else
+                {
+                // Error. User of the API is perhaps assigning values directly to TEikScrollBarModel
+                // member variables which is not allowed with EAknDoubleSpanScrollBarModel.
+                // #ifdef _DEBUG
+                // RDebug::Print(_L("CEikScrollBarFrame: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel"));
+                // #endif
+                // In most cases we can work with the TEikScrollBarModel model.
+    		    iV.iModel.iThumbPosition += aDeltaY;
+                }
+            }
+	    ApplyModel(iV);
+        }
+
+
+    // Horizontal scrollbar
+    if (aDeltaX && iExtension && iExtension->iH.iBar && TypeOfHScrollBar() == TScrollBarType(EDoubleSpan))
+        {
+        if (iExtension->iH.iModel.ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
+            {
+            TAknDoubleSpanScrollBarModel* model = static_cast <TAknDoubleSpanScrollBarModel*> (&(iExtension->iH.iModel));
+            // Note that for a large scroll span and small delta this may not actually change focusposition
+            // because of the 15 bit accuracy of TAknDoubleSpanScrollBarModel values.
+            model->SetFocusPosition(model->FocusPosition() + aDeltaX);    
+            }
+        else
+            {
+            // Error. User of the API is perhaps assigning values directly to TEikScrollBarModel
+            // member variables which is not allowed with EAknDoubleSpanScrollBarModel.
+            // #ifdef _DEBUG
+            // RDebug::Print(_L("CEikScrollBarFrame: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel"));
+            // #endif
+            // In most cases we can work with the TEikScrollBarModel model.
+            iExtension->iH.iModel.iThumbPosition += aDeltaX;
+            }
+        ApplyModel(iExtension->iH);
+        }
+
+	}
+
+EXPORT_C void CEikScrollBarFrame::MoveVertThumbTo(TInt aVertThumbPos)
+	{
+	if (iV.iBar)
+		{
+        if (TypeOfVScrollBar() == TScrollBarType(EArrowHead))
+            {
+    		iV.iModel.iThumbPosition = aVertThumbPos;
+            }
+        else
+            {
+            // EDoubleSpan has different model.
+            if (iV.iModel.ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
+                {
+                TAknDoubleSpanScrollBarModel* model = static_cast <TAknDoubleSpanScrollBarModel*> (&iV.iModel);
+                model->SetFocusPosition(aVertThumbPos);    
+                }
+            else
+                {
+                // Error. User of the API is perhaps assigning values directly to TEikScrollBarModel
+                // member variables which is not allowed with EAknDoubleSpanScrollBarModel.
+                // #ifdef _DEBUG
+                // RDebug::Print(_L("CEikScrollBarFrame: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel"));
+                // #endif
+                // In most cases we can work with the TEikScrollBarModel model.
+        		iV.iModel.iThumbPosition = aVertThumbPos;
+                }
+            }
+		ApplyModel(iV);
+		}
+	}
+
+EXPORT_C void CEikScrollBarFrame::SetVFocusPosToThumbPos(TInt aFocusPosition)
+	{
+	MoveVertThumbTo(aFocusPosition);
+	}
+
+EXPORT_C TInt CEikScrollBarFrame::ScrollBarBreadth(CEikScrollBar::TOrientation aOrientation) const
+	//
+	// return the appropriate scrollbar's breadth or zero if none exists
+	//
+	{
+	CAknScrollBar* sBar=(CAknScrollBar*)GetScrollBarHandle(aOrientation);
+	if (!sBar) 
+		return 0;
+	return sBar->ScrollBarBreadth(); 
+	}
+
+EXPORT_C TBool CEikScrollBarFrame::ScrollBarExists(CEikScrollBar::TOrientation aOrientation) const
+	//
+	// returns ETrue if the specified scrollbar exists
+	//
+	{
+	if (GetScrollBarHandle(aOrientation))
+		return ETrue;
+	return EFalse;
+	}
+
+EXPORT_C TInt CEikScrollBarFrame::CountComponentControls() const
+    {
+    TInt numberOfComponents = 0;
+	
+    if (iV.iBar)
+		numberOfComponents++;
+	
+    if (iExtension && iExtension->iH.iBar)
+		numberOfComponents++;
+
+    return numberOfComponents;
+    }
+
+EXPORT_C CCoeControl* CEikScrollBarFrame::ComponentControl(TInt aIndex) const
+    {
+    if (aIndex == 0)
+        {
+        if (iV.iBar)
+            return iV.iBar;
+        else
+            {
+            if (iExtension && iExtension->iH.iBar)
+                return iExtension->iH.iBar;
+            }
+        }
+
+    if (aIndex == 1)
+        {
+        if (iExtension && iExtension->iH.iBar)
+            return iExtension->iH.iBar;
+        else
+            {
+            if (iV.iBar)
+                return iV.iBar;
+            }
+        }
+
+	return NULL;
+    }
+
+EXPORT_C CEikScrollBar* CEikScrollBarFrame::GetScrollBarHandle(CEikScrollBar::TOrientation aOrientation) const
+	//
+	// returns the pointer to the appropriate scrollbar
+	//
+	{
+	if (aOrientation==CEikScrollBar::EVertical)
+		{
+		if (iScrollBarFrameFlags&EDisplayVScrollBar)
+			return(iV.iBar);
+		}
+
+	if (aOrientation==CEikScrollBar::EHorizontal)
+		{
+		if (iScrollBarFrameFlags&EDisplayHScrollBar && iExtension)
+			return(iExtension->iH.iBar);
+		}
+
+	return(NULL);
+	}
+
+EXPORT_C CEikScrollBar* CEikScrollBarFrame::VerticalScrollBar() const
+	//
+	// returns the vertical scroll bar
+	//
+	{
+	return iV.iBar;
+	}
+
+void CEikScrollBarFrame::CalcTheoreticalScrollBarVisibility(const TEikScrollBarModel* aVModel)
+	//
+	// Determines which scrollbars are necessary before size considerations are taken into account
+	//
+	{
+	// assume no scrollbars to start with
+	iScrollBarFrameFlags&=(~EDisplayVScrollBar);
+    
+    TBool scrollBarUseful = EFalse;
+
+    switch(TypeOfVScrollBar())
+        {
+        case EDoubleSpan:
+            {
+            if (aVModel->ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
+                {
+                //const TAknDoubleSpanScrollBarModel* model = static_cast <const TAknDoubleSpanScrollBarModel*> (aVModel);
+                //scrollBarUseful = (model->FocusPosition() < model->ScrollSpan()) && (model->WindowSize() < model->ScrollSpan());    
+                scrollBarUseful = ETrue; // S60 style says double span scrollbar is always shown if visibility is EAuto
+                }
+            else
+                {
+                // Error. User of the API is perhaps assigning values directly to TEikScrollBarModel
+                // member variables which is not allowed with EAknDoubleSpanScrollBarModel.
+                //#ifdef _DEBUG
+                //RDebug::Print(_L("CEikScrollBarFrame: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel"));
+                //#endif
+                // In most cases we can work with the TEikScrollBarModel model.
+                //scrollBarUseful = (aVModel->iThumbPosition < aVModel->iScrollSpan) && (aVModel->iThumbSpan < aVModel->iScrollSpan);    
+                scrollBarUseful = ETrue; // S60 style says double span scrollbar is always shown if visibility is EAuto
+                }
+            break;
+            }
+
+        case EArrowHead: // fallthrough
+        default:
+            {
+            scrollBarUseful = aVModel->ScrollBarUseful();
+            break;
+            }
+        }
+
+    if ( (iV.iVisibility==EOn) || ( (iV.iVisibility==EAuto)&&(scrollBarUseful) ) )
+        {
+        iScrollBarFrameFlags|=EDisplayVScrollBar;
+        }
+
+	}
+
+CEikCba* CEikScrollBarFrame::GetCurrentCba()
+	{
+	CEikCba* mopCba = NULL;
+    if (iExtension && iExtension->iParentWindow)
+        mopCba=iExtension->iParentWindow->MopGetObject(mopCba);
+	return mopCba;
+	}
+
+void CEikScrollBarFrame::ApplyModel(SBarData& aSBar)
+	{
+	if (iExtension && iExtension->iParentWindow && iExtension->iParentWindow->IsVisible() 
+	        && aSBar.iBar && aSBar.iBar->IsVisible())
+		{
+		aSBar.iBar->SetModel(&aSBar.iModel);
+		}		
+	}
+
+void CEikScrollBarFrame::MakeSBarVisible(SBarData& aSBar, TBool aVisible)
+	{
+	if (iExtension && iExtension->iParentWindow->IsVisible() && aSBar.iBar)
+		{
+		if (aVisible && iExtension->iParentWindow->IsVisible())
+		    {
+		    aSBar.iBar->SetModel(&aSBar.iModel);
+		    aSBar.iBar->MakeVisible(ETrue);
+		    }
+		else if(!aVisible)
+		    {
+		    aSBar.iBar->MakeVisible(EFalse);
+		    }
+		}
+    else if (TypeOfVScrollBar() == TScrollBarType(EDoubleSpan) && aSBar.iBar)
+        aSBar.iBar->SetModel(&aSBar.iModel);
+	}
+
+void CEikScrollBarFrame::SetParentWindow(CCoeControl* aParentWindow)
+	{
+	if (iExtension)
+        {
+        iExtension->iParentWindow=aParentWindow;
+        }
+    else
+        {
+        iExtension = new CEikScrollBarFrameExtension();
+        if (iExtension)
+            {
+            iExtension->iParentWindow = aParentWindow;
+            iExtension->iH.iModel = TAknDoubleSpanScrollBarModel();
+            iExtension->iH.iBar = NULL;
+            iExtension->iH.iExternalScrollBarAttached = EFalse;
+            iExtension->iH.iVisibility = EOff; 
+            }
+        }
+	}
+
+CCoeControl* CEikScrollBarFrame::ParentWindow() const
+	{
+    if (iExtension)
+        {
+        return iExtension->iParentWindow;
+        }
+    else
+        {
+        return NULL;
+        }
+	}
+
+
+
+EXPORT_C void CEikScrollBarFrame::SetScrollBarFrameObserver(MEikScrollBarObserver* aObserver)
+	{
+    if( !AknLayoutUtils::PenEnabled() )
+        {
+        return;
+        }
+    
+    iExtension->iScrollBarObserver = aObserver;
+    
+    if(iV.iBar)
+        {
+        iV.iBar->SetScrollBarObserver(aObserver);
+        }
+    if(iExtension && iExtension->iH.iBar)
+        {
+        iExtension->iH.iBar->SetScrollBarObserver(aObserver);
+        }
+	}
+
+MEikScrollBarObserver* CEikScrollBarFrame::ScrollBarFrameObserver()
+	{
+	if(AknLayoutUtils::PenEnabled())
+        return iExtension->iScrollBarObserver;
+	else
+	    return NULL;
+	}
+
+// Functions which don't do anything useful in the avkon UI
+EXPORT_C void CEikScrollBarFrame::SetAdjustsHorizontalModel(TBool /*aAdjusts*/)
+	{
+	}
+
+EXPORT_C void CEikScrollBarFrame::SetAdjustsVerticalModel(TBool /*aAdjusts*/)
+	{
+	}
+
+EXPORT_C void CEikScrollBarFrame::MoveHorizThumbTo(TInt aHorizThumbPos)
+	{
+	if (iExtension && iExtension->iH.iBar)
+		{
+        if (TypeOfVScrollBar() == TScrollBarType(EDoubleSpan))
+            {
+            // EDoubleSpan has different model.
+            if (iV.iModel.ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
+                {
+                TAknDoubleSpanScrollBarModel* model = static_cast <TAknDoubleSpanScrollBarModel*> (&(iExtension->iH.iModel));
+                model->SetFocusPosition(aHorizThumbPos);    
+                }
+            else
+                {
+                // Error. User of the API is perhaps assigning values directly to TEikScrollBarModel
+                // member variables which is not allowed with EAknDoubleSpanScrollBarModel.
+                // #ifdef _DEBUG
+                // RDebug::Print(_L("CEikScrollBarFrame: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel"));
+                // #endif
+                // In most cases we can work with the TEikScrollBarModel model.
+        		iExtension->iH.iModel.iThumbPosition = aHorizThumbPos;
+                }
+            }
+		ApplyModel(iExtension->iH);
+		}
+	}
+
+EXPORT_C void CEikScrollBarFrame::SetTypeOfHScrollBar(TScrollBarType aType)
+	{
+    if (iExtension && iExtension->iH.iBar)
+        {
+        if (TypeOfHScrollBar() == aType)
+            return; // already set to requested type
+
+        if (aType == CEikScrollBarFrame::TScrollBarType(EDoubleSpan))
+            {
+            TRAP_IGNORE(CreateDoubleSpanScrollBarsL(ETrue,EFalse)); // by default a window owning                
+            return;    
+            }
+
+        if (aType == CEikScrollBarFrame::TScrollBarType(EArrowHead))
+            {
+            return; // not supported   
+            }
+        }
+	}
+
+EXPORT_C void CEikScrollBarFrame::SetTypeOfVScrollBar(TScrollBarType aType)
+	{
+    if (iV.iBar)
+        {
+        if (TypeOfVScrollBar() == aType)
+            return; // already set to requested type
+
+
+        if (aType == CEikScrollBarFrame::TScrollBarType(EDoubleSpan))
+            {
+            TRAP_IGNORE(CreateDoubleSpanScrollBarsL(ETrue,EFalse)); // by default a window owning                
+            return;    
+            }
+
+        if (aType == CEikScrollBarFrame::TScrollBarType(EArrowHead))
+            {
+            TRAP_IGNORE(CreateArrowHeadScrollBarsL());
+            return;    
+            }
+        }
+	}
+
+EXPORT_C CEikScrollBarFrame::TScrollBarType CEikScrollBarFrame::TypeOfHScrollBar() const
+	{
+    if (iExtension && iExtension->iH.iBar && 
+       (iExtension->iH.iBar->ScrollBarType() == CEikScrollBar::TScrollBarType(EDoubleSpan)))
+        {
+        return EDoubleSpan;
+        }
+    else
+        {
+	    return EArrowHead;
+        }
+	}
+
+EXPORT_C CEikScrollBarFrame::TScrollBarType CEikScrollBarFrame::TypeOfVScrollBar() const
+	{
+    if (iV.iBar && (iV.iBar->ScrollBarType() == CEikScrollBar::TScrollBarType(EDoubleSpan)))
+        {
+        return EDoubleSpan;
+        }
+    else
+        {
+	    return EArrowHead;
+        }
+	}
+
+EXPORT_C TBool CEikScrollBarFrame::IsArrowHeadScrollBar(TInt /*aFlag*/) const
+	{
+    if (TypeOfVScrollBar() == TScrollBarType(EArrowHead))
+        {
+        return ETrue;
+        }
+    else
+        {
+        return EFalse;
+        }
+	}
+
+EXPORT_C void CEikScrollBarFrame::CreateDoubleSpanScrollBarsL(TBool aWindowOwning, TBool aRemote)
+    {
+    CreateDoubleSpanScrollBarsL(aWindowOwning, aRemote, ETrue, ETrue);
+    }
+
+EXPORT_C void CEikScrollBarFrame::CreateDoubleSpanScrollBarsL(TBool aWindowOwning, TBool aRemote, TBool aVertical, TBool aHorizontal)
+    {
+    if (!TAknDoubleSpanScrollBarModel::ModelIsSupported())
+        {
+        return;
+        }
+
+    // This method should not delete the old scrollbars before it is sure that new 
+    // one has been succesfully created. Create a temp variable here.
+    SBarData newVerticalScrollBar;
+    newVerticalScrollBar.iBar = NULL;
+    newVerticalScrollBar.iExternalScrollBarAttached = EFalse;
+    newVerticalScrollBar.iVisibility = iV.iVisibility;
+
+    SBarData newHorizontalScrollBar;
+    newHorizontalScrollBar.iBar = NULL;
+    newHorizontalScrollBar.iExternalScrollBarAttached = EFalse;
+    if (iExtension)
+        newHorizontalScrollBar.iVisibility = iExtension->iH.iVisibility;
+
+    if (aRemote && iExtension && iExtension->iParentWindow)
+        {
+        // try getting scrollbarframe from parent using mop supply mechanism
+        CEikScrollBarFrame* sbf = iExtension->iParentWindow->MopGetObject(sbf);
+        if (sbf)
+            {
+            newVerticalScrollBar.iBar = sbf->VerticalScrollBar();
+            newVerticalScrollBar.iExternalScrollBarAttached = ETrue;
+            
+            newHorizontalScrollBar.iBar = sbf->HorizontalScrollBar();
+            newHorizontalScrollBar.iExternalScrollBarAttached = ETrue;
+            
+            TInt err1 = KErrNone;
+            TInt err2 = KErrNone;
+            if (newVerticalScrollBar.iBar)
+                {
+                TRAP(err1, newVerticalScrollBar.iBar->AddExternalFrameL(this));
+                }
+
+            if (newHorizontalScrollBar.iBar)
+                {
+                TRAP(err2, newHorizontalScrollBar.iBar->AddExternalFrameL(this));
+                }
+            
+            if (err1 || err2)
+	            {
+	            newVerticalScrollBar.iExternalScrollBarAttached = EFalse;
+	            newVerticalScrollBar.iBar = NULL;
+	            newHorizontalScrollBar.iExternalScrollBarAttached = EFalse;
+	            newHorizontalScrollBar.iBar = NULL;
+	            }
+
+            User::LeaveIfError(err1);
+            User::LeaveIfError(err2);
+
+            if (TypeOfVScrollBar() == EDoubleSpan)
+                {
+                if( AknLayoutUtils::PenEnabled() )
+                    {
+	    			// Correction. Giving null reference as parameter screws up the model values
+                    newVerticalScrollBar.iModel = TAknDoubleSpanScrollBarModel();
+                    }
+                else
+                    {
+                    newVerticalScrollBar.iModel = TAknDoubleSpanScrollBarModel(0);
+                    }
+                }
+
+            if (TypeOfHScrollBar() == EDoubleSpan)
+                {
+                if( AknLayoutUtils::PenEnabled() )
+                    {
+                    // Correction. Giving null reference as parameter screws up the model values
+                    newHorizontalScrollBar.iModel = TAknDoubleSpanScrollBarModel();
+                    }
+                else
+                    {
+                    newHorizontalScrollBar.iModel = TAknDoubleSpanScrollBarModel(0);
+                    }
+                }
+
+            }
+        else
+            {
+            User::Leave(KErrNotFound);
+            }
+        }
+    else
+        {
+        // Create new vertical AknDoubleSpanScrollBar
+        newVerticalScrollBar.iBar = 0;
+        newVerticalScrollBar.iExternalScrollBarAttached=EFalse;
+        
+        CAknDoubleSpanScrollBar* verticalScrollBar = NULL;
+
+        MEikScrollBarObserver* observer = NULL;
+
+        if(AknLayoutUtils::PenEnabled())
+            {
+            if(iExtension)
+                {
+                observer = iExtension->iScrollBarObserver;
+                }
+            }
+
+        TInt scrollBarFlags = 
+            ( ( iScrollBarFrameFlags & EEnableNudgeButtons ) ? 
+                CEikScrollBar::EEnableNudgeButtons : 0 ) |
+            ( ( iScrollBarFrameFlags & EDisableExpandedTouchArea ) ? 
+                CEikScrollBar::EDisableExpandedTouchArea : 0 );
+                
+        if (aVertical)
+            {
+            verticalScrollBar = new(ELeave) CAknDoubleSpanScrollBar(ParentWindow());            
+            CleanupStack::PushL(verticalScrollBar);
+            verticalScrollBar->ConstructL(
+                aWindowOwning, observer ,ParentWindow(),
+                CAknScrollBar::EVertical,
+                KLongEnoughToCauseComponentsToBeCreated,
+                scrollBarFlags );
+            CleanupStack::Pop(); // verticalScrollBar
+            }
+        newVerticalScrollBar.iBar = verticalScrollBar;
+        if( AknLayoutUtils::PenEnabled() )
+            {
+            // Correction. Giving null reference as parameter screws up the model values
+            newVerticalScrollBar.iModel = TAknDoubleSpanScrollBarModel();
+            }
+        else
+            {
+            newVerticalScrollBar.iModel = TAknDoubleSpanScrollBarModel(0);
+            }
+
+        // Create new horizontal AknDoubleSpanScrollBar
+        newHorizontalScrollBar.iBar = 0;
+        newHorizontalScrollBar.iExternalScrollBarAttached=EFalse;
+        CAknDoubleSpanScrollBar* horizontalScrollBar = NULL;
+       
+        if (aHorizontal)
+            {
+            horizontalScrollBar = new(ELeave) CAknDoubleSpanScrollBar(ParentWindow());
+            CleanupStack::PushL(horizontalScrollBar);
+            horizontalScrollBar->ConstructL(
+                aWindowOwning, observer ,ParentWindow(),
+                CAknScrollBar::EHorizontal,
+                KLongEnoughToCauseComponentsToBeCreated,
+                scrollBarFlags );
+            CleanupStack::Pop(); // horizontalScrollBar
+            }
+        newHorizontalScrollBar.iBar = horizontalScrollBar;        
+        if( AknLayoutUtils::PenEnabled() )
+            {
+            // Correction. Giving null reference as parameter screws up the model values
+            newHorizontalScrollBar.iModel = TAknDoubleSpanScrollBarModel();
+            }
+        else
+            {
+            newHorizontalScrollBar.iModel = TAknDoubleSpanScrollBarModel(0);
+            }
+        }
+
+    TBool oldVerticalScrollbarExists = EFalse;
+    TBool oldHorizontalScrollbarExists = EFalse;
+
+    if (iV.iBar)
+        oldVerticalScrollbarExists = ETrue;
+
+    if (iExtension && iExtension->iH.iBar)
+        oldHorizontalScrollbarExists = ETrue;
+
+    
+    if (oldVerticalScrollbarExists || oldHorizontalScrollbarExists)
+        {
+        // Remove old scroll bar
+        DeleteScrollBars();
+        }
+    
+    iV = newVerticalScrollBar;
+    
+    if (iExtension)
+        iExtension->iH = newHorizontalScrollBar;
+
+    }
+
+
+EXPORT_C void CEikScrollBarFrame::Tile(TEikScrollBarModel* aVModel, TRect& aVScrollBarRect)
+    {
+	Tile(aVModel);
+	TRect tempRect(aVScrollBarRect);
+    if(aVScrollBarRect.Height() < 0 )
+        {
+        aVScrollBarRect.iTl.iY = aVScrollBarRect.iBr.iY;
+        aVScrollBarRect.iBr.iY = tempRect.iTl.iY;
+        }
+    if(aVScrollBarRect.Width() < 0 )
+        {
+        aVScrollBarRect.iTl.iX = aVScrollBarRect.iBr.iX;
+        aVScrollBarRect.iBr.iX = tempRect.iTl.iX;
+        }
+    if (iV.iBar && TypeOfVScrollBar() == EDoubleSpan && iV.iExternalScrollBarAttached==EFalse )
+        {
+        CAknDoubleSpanScrollBar* scrollbar = static_cast <CAknDoubleSpanScrollBar*> (iV.iBar);
+        // check if fixed layout has been set
+        if (scrollbar->FixedLayoutRect().Size() == TSize(0,0))
+            {
+            if (aVScrollBarRect != TRect(iV.iBar->Position(), iV.iBar->Size()))
+                {
+                iV.iBar->SetRect(aVScrollBarRect);
+                }
+            }
+        }
+    }
+
+
+void CEikScrollBarFrame::DeleteScrollBars()
+    {
+    //
+    // Delete vertical scollbar
+    //
+    if(!iV.iExternalScrollBarAttached)
+        delete(iV.iBar);
+    else if (iV.iBar)
+	    {
+	    if (iExtension && iExtension->iParentWindow && iExtension->iParentWindow->IsVisible())
+		    {
+		    // This test will be false if the app is being destroyed, making it unsafe to resize the CBA.
+		    if (CCoeEnv::Static()->NormalFont())
+			    iV.iBar->MakeVisible(EFalse);
+		    }
+	    iV.iBar->RemoveExternalFrame(this);		// calls back to DisconnectExternalScrollBar to null iV.iBar
+	    __ASSERT_DEBUG(iV.iBar == NULL, SbfPanic(EFailedToRemoveExternalScrollBar));
+	    }
+
+    //
+    // Delete horizontal scrollbar
+    //
+    if(iExtension && iExtension->iH.iBar)
+        {
+        if(!(iExtension->iH.iExternalScrollBarAttached))
+            {
+            delete(iExtension->iH.iBar);
+            iExtension->iH.iBar = NULL;
+            }
+        else if (iExtension->iH.iBar)
+	        {
+	        if (iExtension && iExtension->iParentWindow && iExtension->iParentWindow->IsVisible())
+		        {
+		        // This test will be false if the app is being destroyed, making it unsafe to resize the CBA.
+		        if (CCoeEnv::Static()->NormalFont())
+			        iExtension->iH.iBar->MakeVisible(EFalse);
+		        }
+	        iExtension->iH.iBar->RemoveExternalFrame(this);		// calls back to DisconnectExternalScrollBar to null iV.iBar
+	        __ASSERT_DEBUG(iExtension->iH.iBar == NULL, SbfPanic(EFailedToRemoveExternalScrollBar));
+	        }    
+        }
+    }
+
+
+void CEikScrollBarFrame::CreateArrowHeadScrollBarsL()
+    {
+    CEikCba* cba=GetCurrentCba();
+    if (cba)
+        {
+        // create arrow heads
+        TRAPD(err, cba->CreateArrowHeadScrollBarL()); 
+        if (err)
+            {
+		    iV.iExternalScrollBarAttached = EFalse;
+		    iV.iBar = NULL;
+	        return;
+            }
+        // delete old scroll bars
+        DeleteScrollBars();
+        // returns the vertical scroll bar from the top scroll bar host
+		iV.iBar=cba->VScrollBarAsControl();
+		iV.iExternalScrollBarAttached=ETrue;
+		TRAPD(err2, iV.iBar->AddExternalFrameL(this));
+		if (err2)
+		    {
+			iV.iExternalScrollBarAttached = EFalse;
+			iV.iBar = NULL;
+			}
+		}
+    }
+
+void CEikScrollBarFrame::CalcTheoreticalScrollBarVisibility(const TEikScrollBarModel* aVModel, const TEikScrollBarModel* aHModel)
+    {
+	// assume no scrollbars to start with
+    iScrollBarFrameFlags&=(~EDisplayVScrollBar);
+	iScrollBarFrameFlags&=(~EDisplayHScrollBar);
+    
+    TBool verticalScrollBarUseful = EFalse;
+    TBool horizontalScrollBarUseful = EFalse;
+
+    if (aVModel)
+        {
+        switch(TypeOfVScrollBar())
+            {
+            case EDoubleSpan:
+                {
+                if (aVModel->ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
+                    {
+                    //const TAknDoubleSpanScrollBarModel* model = static_cast <const TAknDoubleSpanScrollBarModel*> (aVModel);
+                    //verticalScrollBarUseful = (model->FocusPosition() < model->ScrollSpan()) && (model->WindowSize() <= model->ScrollSpan());    
+                    verticalScrollBarUseful = ETrue; // S60 style says double span scrollbar is always shown if visibility is EAuto
+                    }
+                else
+                    {
+                    // Error. User of the API is perhaps assigning values directly to TEikScrollBarModel
+                    // member variables which is not allowed with EAknDoubleSpanScrollBarModel.
+                    //#ifdef _DEBUG
+                    //RDebug::Print(_L("CEikScrollBarFrame: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel"));
+                    //#endif
+                    // In most cases we can work with the TEikScrollBarModel model.
+                    //verticalScrollBarUseful = (aVModel->iThumbPosition < aVModel->iScrollSpan) && (aVModel->iThumbSpan <= aVModel->iScrollSpan);    
+                    verticalScrollBarUseful = ETrue; // S60 style says double span scrollbar is always shown if visibility is EAuto
+                    }
+                break;
+                }
+
+            case EArrowHead: // fallthrough
+            default:
+                {
+                verticalScrollBarUseful = aVModel->ScrollBarUseful();
+                break;
+                }
+            }
+        }
+
+    if (aHModel)
+        {
+        switch(TypeOfHScrollBar())
+            {
+            case EDoubleSpan: // by default only double span is supported as horizontal scrollbar
+            default:
+                {
+                if (aHModel->ScrollBarModelType() == TEikScrollBarModel::EAknDoubleSpanScrollBarModel)
+                    {
+                    //const TAknDoubleSpanScrollBarModel* model = static_cast <const TAknDoubleSpanScrollBarModel*> (aHModel);
+                    //horizontalScrollBarUseful = (model->FocusPosition() < model->ScrollSpan()) && (model->WindowSize() <= model->ScrollSpan());    
+                    horizontalScrollBarUseful = ETrue; // S60 style says double span scrollbar is always shown if visibility is EAuto
+                    }
+                else
+                    {
+                    // Error. User of the API is perhaps assigning values directly to TEikScrollBarModel
+                    // member variables which is not allowed with EAknDoubleSpanScrollBarModel.
+                    //#ifdef _DEBUG
+                    //RDebug::Print(_L("CEikScrollBarFrame: Please, use TAknDoubleSpanScrollBarModel instead of TEikScrollBarModel"));
+                    //#endif
+                    // In most cases we can work with the TEikScrollBarModel model.
+                    //horizontalScrollBarUseful = (aHModel->iThumbPosition < aHModel->iScrollSpan) && (aHModel->iThumbSpan <= aVModel->iScrollSpan);    
+                    horizontalScrollBarUseful = ETrue; // S60 style says double span scrollbar is always shown if visibility is EAuto
+                    }
+                break;
+                }
+            }
+        }
+
+
+    // Decide visibility for vertical scrollbar
+    if ( (iV.iVisibility==EOn) || ( (iV.iVisibility==EAuto)&&(verticalScrollBarUseful) ) )
+        {
+        iScrollBarFrameFlags|=EDisplayVScrollBar;
+        }
+
+    // Decide visibility for horizontal scrollbar
+    if (iExtension && (iExtension->iH.iVisibility==EOn || (iExtension->iH.iVisibility==EAuto && horizontalScrollBarUseful)))
+        {
+        iScrollBarFrameFlags|=EDisplayHScrollBar;
+        }
+    }
+
+EXPORT_C CEikScrollBarFrame::TScrollBarVisibility CEikScrollBarFrame::ScrollBarVisibility(CEikScrollBar::TOrientation aOrientation) const
+    {
+    if (aOrientation == CEikScrollBar::EVertical)
+        {
+        return iV.iVisibility;
+        }
+    else
+        {
+        if (iExtension)
+            {
+            return iExtension->iH.iVisibility;
+            }
+        else
+            {
+            return EOff;
+            }
+
+        }
+    }
+
+EXPORT_C void CEikScrollBarFrame::Tile(TEikScrollBarModel* aHModel, TEikScrollBarModel* aVModel)
+    {
+	GetScrollBars(EFalse);
+	CalcTheoreticalScrollBarVisibility(aVModel,aHModel);
+	
+	if (iV.iVisibility!=EOff)
+		iV.iModel = *aVModel;
+    
+    MakeSBarVisible(iV, iScrollBarFrameFlags&EDisplayVScrollBar);
+	
+    if (iExtension && iExtension->iH.iBar)
+        {
+   	    if (iExtension->iH.iVisibility!=EOff)
+	        iExtension->iH.iModel = *aHModel;
+   	    
+   	    MakeSBarVisible(iExtension->iH, iScrollBarFrameFlags&EDisplayHScrollBar);
+        }
+
+    }
+
+EXPORT_C TInt CEikScrollBarFrame::DrawBackground(TBool aDrawHorizontal, TBool aDrawVertical)
+	{
+	// The double span scrollbar only supports backgroun drawing flag
+	if(TypeOfHScrollBar() != EDoubleSpan && TypeOfVScrollBar() != EDoubleSpan)
+		{
+		return KErrNotSupported;
+		}
+	
+	if(iV.iBar && (TypeOfVScrollBar() == EDoubleSpan))
+		{
+		CAknDoubleSpanScrollBar* scrollbar = static_cast <CAknDoubleSpanScrollBar*> (iV.iBar);
+		scrollbar->DrawBackground(aDrawVertical);
+		}
+	
+	if(iExtension && iExtension->iH.iBar && (TypeOfHScrollBar() == EDoubleSpan))
+		{
+		CAknDoubleSpanScrollBar* scrollbar = static_cast <CAknDoubleSpanScrollBar*> (iExtension->iH.iBar);
+		scrollbar->DrawBackground(aDrawHorizontal);
+		}
+	
+	return KErrNone;				
+	}
+	
+EXPORT_C TInt CEikScrollBarFrame::DrawBackgroundState(TBool& aDrawHorizontal, TBool& aDrawVertical)
+	{
+	// The double span scrollbar only supports backgroun drawing flag
+		
+	if(iV.iBar && (TypeOfVScrollBar() == EDoubleSpan))
+		{
+		CAknDoubleSpanScrollBar* scrollbar = static_cast <CAknDoubleSpanScrollBar*> (iV.iBar);		
+		aDrawVertical = scrollbar->DrawBackgroundState();
+		}
+	
+	if(iExtension && iExtension->iH.iBar && (TypeOfHScrollBar() == EDoubleSpan))
+		{
+		CAknDoubleSpanScrollBar* scrollbar = static_cast <CAknDoubleSpanScrollBar*> (iExtension->iH.iBar);
+		aDrawHorizontal = scrollbar->DrawBackgroundState();
+		}
+	
+	if(TypeOfHScrollBar() != EDoubleSpan && TypeOfVScrollBar() != EDoubleSpan)
+		{
+		return KErrNotSupported;
+		}
+	
+	return KErrNone;
+	}
+
+CEikScrollBar* CEikScrollBarFrame::HorizontalScrollBar() const
+    {
+    if (iExtension)
+        return iExtension->iH.iBar;
+    else
+        return NULL;
+    }
+
+
+
+// For Cba Scrollbar frame
+
+CEikCbaScrollBarFrame::CEikCbaScrollBarFrame(CCoeControl* aParentWindow, MEikScrollBarObserver* /*aObserver*/, TBool /*aPreAlloc*/)
+	{
+	SetParentWindow(aParentWindow);
+	}
+
+void CEikCbaScrollBarFrame::ConstructL()
+	{
+    iV.iBar = 0;
+    iV.iExternalScrollBarAttached=EFalse;
+    
+    // We construct CEikScrollBar instance here, because it doesn't create bitmaps -> faster 
+    // and save RAM. If CBAs are really needed, then we replace CEikScrollBar with  
+    // CAknArrowHeadScrollBar instance at SwitchArrowHeadScrollBarL method.
+    iV.iBar = new(ELeave) CEikScrollBar();
+    iV.iBar->ConstructL(NULL,ParentWindow(),CAknScrollBar::EVertical,KLongEnoughToCauseComponentsToBeCreated,0);
+	}
+	
+// Delete CEikScrollBar instance and replace it with actual arrow head scroll bar
+void CEikCbaScrollBarFrame::SwitchToArrowHeadScrollBarL()
+	{
+	delete(iV.iBar);
+	iV.iBar = 0;
+	iV.iExternalScrollBarAttached=EFalse;
+	iV.iBar = new(ELeave) CAknArrowHeadScrollBar(ParentWindow());
+	iV.iBar->ConstructL(NULL,ParentWindow(),CAknScrollBar::EVertical,KLongEnoughToCauseComponentsToBeCreated,0);
+	}
+