uifw/EikStd/dlgsrc/EIKDPAGE.CPP
changeset 0 2f259fa3e83a
child 4 8ca85d2f0db7
child 14 3320e4e6e8bb
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <barsread.h>
       
    20 #include <coemain.h>
       
    21 #include <eikenv.h>
       
    22 #include <eikcapc.h>
       
    23 #ifndef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    24 #include <eikfctry.h>
       
    25 #else
       
    26 #include <eikfctry.h>
       
    27 #include <uikon/eikctrlstatus.h>
       
    28 #endif
       
    29 #include <eikcapca.h>
       
    30 #include <eikedwin.h>
       
    31 #include <eikappui.h>
       
    32 #include <eikdpage.h>
       
    33 #include <eikdpsel.h>
       
    34 #include <eikdialg.pan>
       
    35 #include <eikform.pan>
       
    36 #include <eikon.hrh>
       
    37 #include <eikdialogext.h>
       
    38 #include <eikseced.h>
       
    39 #include <eikmfne.h>
       
    40 #include <eikfpne.h> 
       
    41 #include <avkon.hrh>
       
    42 #include <avkon.rsg>
       
    43 #include <AknUtils.h> 
       
    44 #include <eikscrlb.h>
       
    45 #include <AknsDrawUtils.h>
       
    46 #include <AknsUtils.h>
       
    47 #include <skinlayout.cdl.h>
       
    48 #include <aknlayoutscalable_avkon.cdl.h>
       
    49 #include "EIKFANIM.H"
       
    50 
       
    51 #include <touchfeedback.h>
       
    52 
       
    53 #include <AknTasHook.h> // for testability hooks
       
    54 #include "aknformphysics.h"
       
    55 #include "aknrecordinggc.h"
       
    56 #include <aknphysics.h>
       
    57 #include <aknappui.h>
       
    58 #include <aknPriv.hrh>
       
    59 
       
    60 //
       
    61 // Global constants.
       
    62 //
       
    63 
       
    64 const TInt KSpaceFromTitle=0 ; 
       
    65 const TInt KSpaceFromBottom=0 ;
       
    66 const TInt KPageArrayGranularity=4;
       
    67 const TInt KLineArrayGranularity=4;
       
    68 
       
    69 /*
       
    70  *  The following set of static functions return value which have been hard coded from the Series 60 Skins LAF v2.0
       
    71  *  If a layout DLL becomes available the hard-coded values may be replaced with equivalent Macros.
       
    72  *  NOTE THAT THESE ARE COPIES OF FUNCTIONS IN EIKCAPC.CPP
       
    73  */
       
    74 
       
    75 LOCAL_D TRect EditFrameTopLeftRect( const TRect& aParentRect )
       
    76     {// Skins LAF table 5.24 Line 2
       
    77     TAknLayoutRect topLeft ;
       
    78     topLeft.LayoutRect( aParentRect, SkinLayout::Input_field_skin_placing__general__Line_2() ); 
       
    79     return topLeft.Rect() ;
       
    80     }
       
    81 
       
    82 LOCAL_D TRect EditFrameBottomRightRect( const TRect& aParentRect )
       
    83     {// Skins LAF table 5.24 Line 5
       
    84     TAknWindowLineLayout l( SkinLayout::Input_field_skin_placing__general__Line_5() );
       
    85     TAknLayoutRect layoutRect;
       
    86     layoutRect.LayoutRect( aParentRect, l );
       
    87     TRect rectInputField( layoutRect.Rect() );
       
    88 
       
    89     return rectInputField;
       
    90     }
       
    91 
       
    92 NONSHARABLE_CLASS(CDialogPageExtension) : public CBase
       
    93     {
       
    94 public:
       
    95     enum TFlags
       
    96         {
       
    97         ELineHandlerCalled
       
    98         };
       
    99     static CDialogPageExtension* NewL();
       
   100     ~CDialogPageExtension();
       
   101 
       
   102     void Feedback( CEikDialogPage* aControl, TTouchLogicalFeedback aFeedback ) const;
       
   103     /**
       
   104      * Produces vibra-only feedback. Event filtering by pointer event is used..
       
   105      */
       
   106     void SilentFeedback( CEikDialogPage* aDPage, 
       
   107                          TTouchLogicalFeedback aFeedback, 
       
   108                          const TPointerEvent& aPointerEvent ) const;
       
   109     
       
   110     void HandleFormFeedback( CEikDialogPage* aControl, const TPointerEvent& aPointerEvent, TInt aTouchedLineIndex, TInt aCurrentLine );
       
   111 
       
   112 protected:  
       
   113     void ConstructL();
       
   114     
       
   115 private:
       
   116     CDialogPageExtension();
       
   117     CDialogPageExtension(const CDialogPageExtension& aExtension);
       
   118     
       
   119 public: 
       
   120     TInt iPopFieldEvents;    
       
   121     TBool iExternalScrollbar;
       
   122     TBool iIsDoubleQuery;
       
   123     TBool iFocusedClicked;
       
   124     TInt iPreviousThumbPosition;
       
   125     TBool iPreviousThumbDirection;
       
   126     MTouchFeedback* iFeedback;
       
   127     TBitFlags iFlags;
       
   128     /**
       
   129     * @c iDestroyedPtr is used for the object destruction check.
       
   130     * If it has non-null value, the destruction check is turned on, and
       
   131     * the value points to a local boolean variable that keeps the destroyed state.
       
   132     */
       
   133     TBool* iDestroyedPtr;
       
   134     
       
   135     TPoint iDragStartPosition;
       
   136     TPoint iLastPointerPos;
       
   137     TTime iStartTime;
       
   138     CAknRecordingGc* iRecordingGc;
       
   139     TBool iHandlingScrollEvent;
       
   140     CPeriodic* iHighlightTimer;
       
   141     TInt iLastTouchedLine;
       
   142     TPoint iSynchronizedPosition;
       
   143     TBool iScrolling;
       
   144     TBool iScrolled;
       
   145     TBool iInitialLayoutDone;
       
   146     TBool iSetInitialFocusDone;
       
   147     TBool iHandlingResourceChange;
       
   148     TInt iCapturingItem;
       
   149     // record the center point Y value of current view when touch down an item
       
   150     TInt iOldCenterY;
       
   151     // top item in current view, -1 if item's Y is negative
       
   152     TInt iTopItem;
       
   153     // bottom item in current view, fields count when Y is larger than
       
   154     // the last item's Y
       
   155     TInt iBottomItem; 
       
   156 
       
   157     /**
       
   158      * Boolean used to check if application is single touch compatible.
       
   159      */
       
   160     TBool iUsesSingleClick;
       
   161     // It is used to distinguish if the focus item has changed.
       
   162     TBool iFocusItemChanged;
       
   163     };
       
   164 
       
   165 CDialogPageExtension::CDialogPageExtension()
       
   166     {
       
   167     }
       
   168 
       
   169 CDialogPageExtension* CDialogPageExtension::NewL()
       
   170     {
       
   171     CDialogPageExtension* extension = new (ELeave) CDialogPageExtension();
       
   172     CleanupStack::PushL(extension);
       
   173     extension->ConstructL();
       
   174     CleanupStack::Pop(extension); //extension
       
   175     
       
   176     return extension;
       
   177     }
       
   178 
       
   179 CDialogPageExtension::~CDialogPageExtension()
       
   180     {
       
   181     delete iHighlightTimer;
       
   182     delete iRecordingGc;
       
   183     
       
   184     if( iDestroyedPtr )
       
   185         {
       
   186         // Mark the object as destroyed.
       
   187         *iDestroyedPtr = ETrue;
       
   188         iDestroyedPtr = NULL;
       
   189         }
       
   190     }
       
   191     
       
   192 CDialogPageExtension::CDialogPageExtension(const CDialogPageExtension& /*aExtension*/)
       
   193     {
       
   194     }
       
   195 
       
   196 void CDialogPageExtension::ConstructL()
       
   197     {
       
   198     iFeedback = MTouchFeedback::Instance();
       
   199     iHighlightTimer = CPeriodic::NewL( CActive::EPriorityStandard );
       
   200     iCapturingItem = KErrNotFound;
       
   201     }
       
   202 
       
   203 void CDialogPageExtension::HandleFormFeedback(
       
   204     CEikDialogPage* aDPage,
       
   205     const TPointerEvent& aPointerEvent,
       
   206     TInt aTouchedLineIndex,
       
   207     TInt aCurrentLine )
       
   208     {
       
   209     // note, that iFormControl is checked in Feedback()
       
   210     if ( aPointerEvent.iType == TPointerEvent::EButton1Down &&
       
   211         aCurrentLine != aTouchedLineIndex && aDPage->LineOnPageOrNull( 0 ) ) 
       
   212         {
       
   213         // feedback for edit/view mode form, when non-focused line is clicked
       
   214         // feedback for focused item is responsibility of the item
       
   215         // no feedback with focus change when single click is enabled
       
   216         if ( !iUsesSingleClick )
       
   217             {
       
   218             Feedback( aDPage, ETouchFeedbackSensitiveList );
       
   219             }
       
   220         iFocusItemChanged = ETrue;
       
   221         }
       
   222 
       
   223     else if ( aPointerEvent.iType == TPointerEvent::EButton1Down &&
       
   224         aTouchedLineIndex == aCurrentLine && aDPage->LineOnPageOrNull( 0 ) )
       
   225         {
       
   226         // Feedback for view mode form, when focused item is
       
   227         // clicked. Basically same case as for msk simulation later on
       
   228         // the function, but on pointer
       
   229         // down. iExtension->iFocusedClicked is not valid here, since
       
   230         // it can't be known in this phase whether user drags pointer
       
   231         // away.
       
   232         Feedback( aDPage, ETouchFeedbackList );
       
   233         iFocusItemChanged = EFalse;
       
   234         }
       
   235 
       
   236     else if ( aPointerEvent.iType == TPointerEvent::EButton1Up &&
       
   237             aDPage->LineOnPageOrNull( 0 ) )
       
   238         {// when focus changed, it should not send feedback on up event.
       
   239         //when up event comes, aTouchedLineIndex always equal to aCurrentLine
       
   240         if ( !iFocusItemChanged )
       
   241             {
       
   242             SilentFeedback( aDPage, ETouchFeedbackList, aPointerEvent );
       
   243             }
       
   244         }
       
   245     }
       
   246 
       
   247 void CDialogPageExtension::Feedback( CEikDialogPage* aDPage, 
       
   248                                      TTouchLogicalFeedback aFeedback ) const
       
   249     {
       
   250     if ( aDPage
       
   251         && aDPage->IsForm()
       
   252         && iFeedback
       
   253         && !aDPage->IsDimmed()
       
   254         && aDPage->IsVisible() )
       
   255         {
       
   256         iFeedback->InstantFeedback( aFeedback );
       
   257         }
       
   258     }
       
   259 
       
   260 void CDialogPageExtension::SilentFeedback( CEikDialogPage* aDPage, 
       
   261                                            TTouchLogicalFeedback aFeedback, 
       
   262                                            const TPointerEvent& aPointerEvent ) const
       
   263     {
       
   264     if ( aDPage
       
   265         && aDPage->IsForm()
       
   266         && iFeedback
       
   267         && !aDPage->IsDimmed()
       
   268         && aDPage->IsVisible() )
       
   269         {
       
   270         iFeedback->InstantFeedback( aDPage, aFeedback, ETouchFeedbackVibra, aPointerEvent );
       
   271         }
       
   272     }
       
   273 
       
   274 class CAknPaneScroll : public CBase
       
   275 {
       
   276 public:
       
   277     enum TScrollChangeType
       
   278         {
       
   279         ENoChange = 0,
       
   280         ETopChanged = 1,
       
   281         EBottomChanged = 2,
       
   282         ESizeChanged = 4,
       
   283         EFocusChanged = 8
       
   284         };
       
   285     CAknPaneScroll(CCoeControl* /*ctrl*/) : iTop(0), iMiddle(-1), iBottom(-1) { }
       
   286     void SetLines(CEikCapCArray *aLines) { iLines = aLines; }
       
   287     void SetOutsideRect(TRect aRect); // this is list_form_gen_pane
       
   288     TScrollChangeType ExposeLine(TInt aLine, TBool aShowWholeLine=ETrue);
       
   289     TInt Top() const {return iTop; }
       
   290     TInt Middle() const {return iMiddle; }
       
   291     TInt Bottom() const {return iBottom; }
       
   292 private:
       
   293     TRect iOutsideRect;
       
   294     CEikCapCArray *iLines;
       
   295     TInt iTop, iMiddle, iBottom;
       
   296     TInt iOldTop, iOldMiddle, iOldBottom;
       
   297     TInt iOldFocus;
       
   298 };
       
   299 
       
   300 CAknPaneScroll::TScrollChangeType CAknPaneScroll::ExposeLine(TInt aLine, TBool /*aShowWholeLine*/)
       
   301 {
       
   302     if (aLine < 0 || aLine >= iLines->Count()) return ENoChange;
       
   303     
       
   304     TInt top = iTop;
       
   305     TInt middle = iMiddle;
       
   306     TInt bottom = iBottom;
       
   307     
       
   308     TBool switchDir = iLines->CalcItemIndexes(top, middle, bottom, iOutsideRect.Size());
       
   309 
       
   310     if (switchDir && iTop == -1) { iTop = top; iMiddle = -1; iBottom = -1; }
       
   311     if (switchDir && iBottom == -1) { iTop = -1; iMiddle = -1; iBottom = bottom; }
       
   312     if (aLine < top) { iTop = aLine; iMiddle = -1; iBottom=-1; }
       
   313     else if (aLine >= iLines->Count() - bottom) { iBottom = iLines->Count() - 1 - aLine; iMiddle = -1; iTop=-1; }
       
   314 
       
   315     TScrollChangeType change = ENoChange;
       
   316     if (iOldTop != top) { change = TScrollChangeType(change | ETopChanged); }
       
   317     if (iOldBottom != bottom) { change = TScrollChangeType(change | EBottomChanged); }
       
   318     if (iOldMiddle != middle) { change = TScrollChangeType(change | ESizeChanged); }
       
   319     if (iOldFocus != aLine) {change = TScrollChangeType(change | EFocusChanged); }
       
   320 
       
   321     iOldTop = top;
       
   322     iOldMiddle = middle;
       
   323     iOldBottom = bottom;
       
   324     iOldFocus = aLine;
       
   325     return change;
       
   326 }
       
   327 
       
   328 void CAknPaneScroll::SetOutsideRect(TRect aRect) { iOutsideRect = aRect; }
       
   329 
       
   330 //
       
   331 // CEikDialogPage.
       
   332 //
       
   333 
       
   334 CEikDialogPage::~CEikDialogPage()
       
   335     {
       
   336     AKNTASHOOK_REMOVE();
       
   337     // Page observer needs to be nulled or an already deleted instance is
       
   338     // called when pointer up event is handled. This is valid only for dialogs
       
   339     // that have embedded virtual inputs.
       
   340     iPageObserver = NULL;
       
   341     delete iPhysics;
       
   342     delete iLines;
       
   343     delete iScroll;    
       
   344     delete iExtension;
       
   345     }
       
   346 
       
   347 CEikDialogPage* CEikDialogPage::NewL(TInt aPageId,RWindow& aViewWin,CEikScrollBarFrame& aSBFrame,const CEikDialogPageContainer& aParent,MEikDialogPageObserver* aPageObserver)
       
   348     {
       
   349     CEikDialogPage* self=CEikDialogPage::NewLC(aPageId,aViewWin,aSBFrame,aParent,aPageObserver);
       
   350     CleanupStack::Pop();
       
   351     return self;
       
   352     }
       
   353 
       
   354 void CEikDialogPage::CommonConstructCodeBetweenNewL(CEikDialogPage& aDialogPage, const CEikDialogPageContainer& aParent)
       
   355     {
       
   356 /* 
       
   357 Added the next line as normal window heirarchy does not hold for dialogs, so the 
       
   358 container window mechanism cannot be used to find the menu / CBA, which is used
       
   359 in the MOP system for scrollers.
       
   360 */
       
   361     aDialogPage.SetPageContainer(&aParent);
       
   362     aDialogPage.ConstructL();
       
   363     aDialogPage.CopyControlContextFrom(&aParent);
       
   364     };
       
   365 
       
   366 CEikDialogPage* CEikDialogPage::NewLC(TInt aPageId,RWindow& aViewWin,CEikScrollBarFrame& aSBFrame,const CEikDialogPageContainer& aParent,MEikDialogPageObserver* aPageObserver)
       
   367     {
       
   368     CEikDialogPage* self=new(ELeave) CEikDialogPage(aPageId,aViewWin,aSBFrame,aPageObserver);
       
   369     CleanupStack::PushL(self);
       
   370     CommonConstructCodeBetweenNewL(*self,aParent); 
       
   371     AKNTASHOOK_ADDL( self, "CEikDialogPage" );
       
   372     return self;
       
   373     }
       
   374 
       
   375 CEikDialogPage* CEikDialogPage::NewL(TInt aPageId,RWindow& aViewWin,CEikScrollBarFrame& aSBFrame,const CEikDialogPageContainer& aParent,MEikDialogPageObserver* aPageObserver,TResourceReader& aReader)
       
   376     {
       
   377     CEikDialogPage* self=CEikDialogPage::NewLC(aPageId,aViewWin,aSBFrame,aParent,aPageObserver,aReader);
       
   378     CleanupStack::Pop();
       
   379     return self;
       
   380     }
       
   381 
       
   382 CEikDialogPage* CEikDialogPage::NewLC(TInt aPageId,RWindow& aViewWin,CEikScrollBarFrame& aSBFrame,const CEikDialogPageContainer& aParent,MEikDialogPageObserver* aPageObserver,TResourceReader& aReader)
       
   383     {
       
   384     CEikDialogPage* self=new(ELeave) CEikDialogPage(aPageId,aViewWin,aSBFrame,aPageObserver);
       
   385     CleanupStack::PushL(self);
       
   386     CommonConstructCodeBetweenNewL(*self,aParent);
       
   387     self->ConstructFromResourceL(aReader);
       
   388     AKNTASHOOK_ADDL( self, "CEikDialogPage" );
       
   389     return self;
       
   390     }
       
   391 
       
   392 CEikDialogPage::CEikDialogPage(TInt aPageId,RWindow& /*aViewWin*/,
       
   393     CEikScrollBarFrame& /*aSBFrame*/,MEikDialogPageObserver* aPageObserver)
       
   394     : iPageObserver(aPageObserver),
       
   395         iPageId(aPageId),iCurrentLine(-1)
       
   396     {
       
   397     SetBlank();
       
   398     SetComponentsToInheritVisibility();
       
   399     }
       
   400 
       
   401 void CEikDialogPage::ConstructL()
       
   402     {
       
   403     iLines=new(ELeave)CEikCapCArray(KLineArrayGranularity);
       
   404     SetContainerWindowL( *iPageContainer );
       
   405     Window().SetPointerGrab(ETrue); 
       
   406     Window().SetShadowDisabled(ETrue);
       
   407     Window().SetBackgroundColor(iEikonEnv->ControlColor(EColorDialogBackground,*this));
       
   408     iScroll = new(ELeave)CAknPaneScroll(this);
       
   409     iScroll->SetLines(iLines);
       
   410     iExtension = CDialogPageExtension::NewL();
       
   411     }
       
   412 
       
   413 void CEikDialogPage::ConstructFromResourceL(TResourceReader& aReader, TBool aFormControl )
       
   414     {
       
   415     iFormControl = aFormControl ;
       
   416 
       
   417     if ( IsForm() )
       
   418         {
       
   419         if ( iAvkonAppUi )
       
   420             {
       
   421             iExtension->iUsesSingleClick = 
       
   422                 iAvkonAppUi->IsSingleClickCompatible();
       
   423             }
       
   424         
       
   425         iPhysics = CAknFormPhysics::NewL( *this, *iExtension->iRecordingGc );
       
   426         iExtension->iRecordingGc = new ( ELeave ) CAknRecordingGc( &SystemGc() );
       
   427         }
       
   428         
       
   429     const TInt lineCount=aReader.ReadInt16();
       
   430     if (lineCount==EEikDlgMainPageIndirect)
       
   431         {
       
   432         TInt indirectRid=aReader.ReadInt32();
       
   433         if (!indirectRid)
       
   434             return;
       
   435         TResourceReader indirectReader;
       
   436         iCoeEnv->CreateResourceReaderLC(indirectReader,indirectRid);
       
   437         ConstructFromResourceL(indirectReader);
       
   438         CleanupStack::PopAndDestroy();
       
   439         return;
       
   440         }
       
   441 
       
   442     // This section modified to handle FORM structure (which contains DIALOG_LINE structs )
       
   443     // There might be lines on the page already
       
   444     for (TInt ii=0;ii<lineCount;ii++)
       
   445         {
       
   446         CEikCaptionedControl* thisLine=ConstructLineL(aReader); 
       
   447 /* 
       
   448 Second argument used to be used to set previous line.  This has been moved into a 
       
   449 AfterAddingNewLinesL, in an attempt to group code which has to be executed together
       
   450 */
       
   451         CleanupStack::PushL(thisLine);
       
   452 
       
   453         iLines->AppendL(thisLine);
       
   454         CleanupStack::Pop(); // thisLine
       
   455         thisLine->iIsFormControl = aFormControl ;
       
   456         if ( aFormControl )
       
   457             {
       
   458             thisLine->GetAknLayoutValuesL() ;   // should cause the control to have size.
       
   459             if ( iFormFlags )
       
   460             thisLine->SetFormFlags( iFormFlags ) ;
       
   461             }       
       
   462 // allow the caption to know the one above itself
       
   463         AfterAddingNewLinesL(iLines->LineIndexFromId(thisLine->iId));
       
   464         }
       
   465 
       
   466     SetDensePacking( !iFormControl ) ;
       
   467     if (!iScroll)
       
   468         {
       
   469         iScroll = new(ELeave)CAknPaneScroll(this);
       
   470         }
       
   471     iScroll->SetLines(iLines);
       
   472     }
       
   473 
       
   474 void CEikDialogPage::ConstructFormFromResourceL( TResourceReader& aReader ) 
       
   475     {
       
   476     iFormFlags = TInt16(aReader.ReadInt16()) ;
       
   477     iFormLayout = (iFormFlags&EEikFormUseDoubleSpacedFormat) ? EDouble : ESingle;
       
   478     ConstructFromResourceL( aReader, ETrue ) ;
       
   479     }
       
   480 
       
   481 CCoeControl* CEikDialogPage::CreateLineByTypeL(const TDesC& aCaption,TInt aLineId,TInt aControlType,TAny* aReturnValue)
       
   482     {
       
   483     ShowFocus( EFalse, EFalse ) ;  // Turn the focus off the current line.  
       
   484     CEikCaptionedControl* line=new(ELeave) CEikCaptionedControl;
       
   485     CleanupStack::PushL(line);
       
   486     line->SetComponentsToInheritVisibility();
       
   487     // Try to insert line above the currently selected line.  If no line is currently selected then append (TimW 22/5/00)
       
   488     // INSERTION SHOULD BE BELOW!
       
   489 
       
   490     TInt oldLine = iCurrentLine;
       
   491     
       
   492     if ( (iCurrentLine != -1) && (iCurrentLine < iLines->Count()) )
       
   493         {
       
   494         iLines->InsertL( iCurrentLine+1, line ) ;
       
   495         ++iCurrentLine;
       
   496         }
       
   497     else
       
   498         {
       
   499         iLines->AppendL( line ) ;
       
   500         iCurrentLine = iLines->Count() - 1 ;
       
   501         }
       
   502 // used to update CaptionedControlAfter field upon adding new lines.
       
   503     CleanupStack::Pop(); // "line" is now owned by iLines.
       
   504     ConstructByTypeL(aControlType,line,this); // line owns control, dialog owns line - no need for cleanup stack.
       
   505     line->SetCaptionL(aCaption);
       
   506 
       
   507     line->iId=aLineId;
       
   508     __ASSERT_DEBUG(line->IsNonFocusing() || aLineId!=0, Panic(EEikDialogPanicFocusableLineWithIdZero));
       
   509     line->iReturnValue=aReturnValue;
       
   510     AfterAddingNewLinesL(iCurrentLine); 
       
   511     TInt targetLine = iCurrentLine;
       
   512     iCurrentLine = oldLine;
       
   513 
       
   514     ChangeFocusTo( targetLine );
       
   515 
       
   516     // physics engine needs to be updated when lines are added after the initial layout
       
   517     UpdatePhysics();
       
   518 
       
   519     return line->iControl;
       
   520     }
       
   521 
       
   522 CEikCaptionedControl* CEikDialogPage::ConstructLineL(TInt aResourceId)
       
   523     {
       
   524     TResourceReader resourceReader;
       
   525     iCoeEnv->CreateResourceReaderLC(resourceReader,aResourceId);
       
   526     CEikCaptionedControl* line=ConstructLineL(resourceReader);
       
   527     CleanupStack::PopAndDestroy(); // resourceReader
       
   528     return line;
       
   529     }
       
   530 
       
   531 CEikCaptionedControl* CEikDialogPage::ConstructLineL(TResourceReader& aReader)
       
   532     {
       
   533     CEikCaptionedControl* line=new(ELeave) CEikCaptionedControl;
       
   534     CleanupStack::PushL(line);
       
   535     line->iIsFormControl=iFormControl; 
       
   536     line->SetComponentsToInheritVisibility();
       
   537     TInt controlType=aReader.ReadInt16();
       
   538     TResourceReader* reader=(&aReader);
       
   539     TInt indirectRid=0;
       
   540     if (controlType==EEikDlgItemIndirect)
       
   541         {
       
   542         indirectRid=aReader.ReadInt32();
       
   543         TResourceReader indirectReader;
       
   544         iCoeEnv->CreateResourceReaderLC(indirectReader,indirectRid);
       
   545         controlType=indirectReader.ReadInt16();
       
   546         reader=(&indirectReader);
       
   547         }
       
   548 
       
   549     ConstructByTypeL(controlType,line,this);
       
   550     line->ConstructFromResourceL(*reader);
       
   551     if (indirectRid)
       
   552         CleanupStack::PopAndDestroy();
       
   553     CleanupStack::Pop(); // line
       
   554     return line;
       
   555     }
       
   556 
       
   557 void CEikDialogPage::ConstructByTypeL(TInt aType,CEikCaptionedControl* aLine,CCoeControl* aContainer)
       
   558     {
       
   559     SEikControlInfo controlInfo=EikControlFactory::CreateByTypeL(aType);
       
   560     if (!controlInfo.iControl)
       
   561         controlInfo=CreateCustomControlL(aType);
       
   562     aLine->iIsFormControl=iFormControl; 
       
   563     aLine->iControl=controlInfo.iControl;
       
   564     aLine->iControlType=aType;
       
   565     aLine->SetContainerWindowL(*aContainer);
       
   566     aLine->CopyControlContextFrom(aContainer);
       
   567     aLine->SetObserver(this);
       
   568     controlInfo.iControl->SetContainerWindowL(*aContainer);
       
   569     controlInfo.iControl->SetObserver(this);
       
   570 
       
   571     // Skins requires the routine of object provider through the captioned control
       
   572     if (iFormControl)
       
   573         controlInfo.iControl->SetMopParent(aLine);
       
   574 
       
   575     controlInfo.iControl->CopyControlContextFrom(aContainer);
       
   576 
       
   577     if (controlInfo.iFlags&EEikControlHasEars)
       
   578         aLine->SetUsesEars();
       
   579     if (controlInfo.iFlags&EEikControlIsNonFocusing)
       
   580         {
       
   581         aLine->SetNonFocusing();
       
   582         controlInfo.iControl->SetNonFocusing();
       
   583         }
       
   584     if (controlInfo.iFlags&EEikControlHasExtraAscent)
       
   585         aLine->SetExtraAscent();
       
   586     if (controlInfo.iTrailerTextId)
       
   587         {
       
   588         HBufC* tmp=iCoeEnv->AllocReadResourceLC(controlInfo.iTrailerTextId);
       
   589         aLine->SetTrailerL(tmp->Des());
       
   590         CleanupStack::PopAndDestroy(); // tmp
       
   591         }
       
   592     }
       
   593 
       
   594 SEikControlInfo CEikDialogPage::CreateCustomControlL(TInt aControlType)
       
   595     {
       
   596     ASSERT(iPageObserver);
       
   597     return iPageObserver->CreateCustomControlL(aControlType);
       
   598     }
       
   599 
       
   600 void CEikDialogPage::SetActiveL()
       
   601     {
       
   602     ActivateL();
       
   603     MakeVisible(ETrue);        
       
   604     
       
   605     if(AknLayoutUtils::PenEnabled())
       
   606     {
       
   607     if (iFormControl && iPageContainer->ScrollBar())
       
   608         {        
       
   609         iPageContainer->ScrollBar()->SetScrollBarFrameObserver(this);
       
   610         }
       
   611     }
       
   612 
       
   613     UpdateScrollBarL();
       
   614     MakeEdwinScrollbarsVisibleL(ETrue);
       
   615 
       
   616     const TInt numLines=iLines->Count();
       
   617     for (TInt ii=0;ii<numLines;ii++)
       
   618         {
       
   619         CEikCaptionedControl* line=(*iLines)[ii];
       
   620         if (line->IsLatent())
       
   621             line->MakeVisible(EFalse);
       
   622 
       
   623         else if ( IsForm() )
       
   624             line->ActivateL() ;
       
   625         }
       
   626     AknsUtils::RegisterControlPosition( this ) ;
       
   627     TInt count = iLines->Count();
       
   628     for (TInt i = 0; i<count; i++)
       
   629         {
       
   630         CEikCaptionedControl *capCtrl = (*iLines)[i];
       
   631         AknsUtils::RegisterControlPosition(capCtrl);
       
   632         AknsUtils::RegisterControlPosition(capCtrl->iCaption);
       
   633         AknsUtils::RegisterControlPosition(capCtrl->iControl);
       
   634         AknsUtils::RegisterControlPosition(capCtrl->iTrailer);
       
   635         AknsUtils::RegisterControlPosition(capCtrl->iBitmap);
       
   636 
       
   637     if ( capCtrl->iIsFormControl && iCurrentLine != i)
       
   638         {
       
   639 
       
   640         if (capCtrl->ControlIsAnEdwin(capCtrl->iControlType))
       
   641             {
       
   642             CEikEdwin *edwin = (CEikEdwin*)capCtrl->iControl;
       
   643             TRAP_IGNORE(edwin->TextView()->SetDocPosL(0)
       
   644                 );
       
   645             }
       
   646        }
       
   647 
       
   648         }
       
   649     }
       
   650 
       
   651 void CEikDialogPage::SetActiveAndFocusL()
       
   652     {
       
   653     SetActiveL();
       
   654     SetEditableL(iIsEditable, ETrue);
       
   655     //When active a page, need to show the focus in that page.
       
   656     ShowFocus( ETrue, EFalse ) ;
       
   657     // Display the focus on the current line 
       
   658     if ( iCurrentLine == -1 || IsForm() )
       
   659         {
       
   660         SetInitialFocus() ;
       
   661         }
       
   662     
       
   663     ExposeLine( iCurrentLine, EFalse );
       
   664     UpdateScrollBarL();
       
   665     }
       
   666 
       
   667 void CEikDialogPage::SetInactiveL()
       
   668     {
       
   669     MakeEdwinScrollbarsVisibleL(EFalse);
       
   670     MakeVisible(EFalse);
       
   671     }
       
   672 
       
   673 void CEikDialogPage::MakeEdwinScrollbarsVisibleL(TBool aVisible)
       
   674     {
       
   675     const TInt numLines=iLines->Count();
       
   676     for (TInt ii=0;ii<numLines;ii++)
       
   677         {
       
   678         CEikCaptionedControl* thisLine=(*iLines)[ii];
       
   679         const TInt controlType(thisLine->iControlType);
       
   680         if (thisLine->ControlIsAnEdwin(controlType))
       
   681             {
       
   682             CEikEdwin* edwin=(CEikEdwin*)thisLine->iControl;
       
   683             if(edwin->Text())
       
   684                 edwin->ForceScrollBarUpdateL();
       
   685             CEikScrollBarFrame* frame=edwin->ScrollBarFrame();
       
   686             if (frame)
       
   687                 {
       
   688                 TInt count=frame->CountComponentControls();
       
   689                 for (TInt jj=0;jj<count;jj++)
       
   690                     frame->ComponentControl(jj)->MakeVisible(aVisible);
       
   691                 }
       
   692             }
       
   693         }
       
   694     }
       
   695 
       
   696 TInt CEikDialogPage::PageId() const
       
   697     {
       
   698     return iPageId;
       
   699     }
       
   700 
       
   701 TInt CEikDialogPage::LineId(const CCoeControl& aControl) const
       
   702     {
       
   703     TInt lineIndex=iLines->FindLineIndex(&aControl);
       
   704     if (lineIndex>=0)
       
   705         return (*iLines)[lineIndex]->iId;
       
   706 
       
   707     return KErrNotFound;
       
   708     }
       
   709 
       
   710 TBool CEikDialogPage::SetInitialFocus()
       
   711     {
       
   712     TBool focusSet=EFalse;
       
   713 
       
   714     const TInt numLines=iLines->Count();
       
   715     for (TInt ii=0;ii<numLines;ii++)
       
   716         {
       
   717         CEikCaptionedControl* line=(*iLines)[ii];
       
   718         if (line->IsNonFocusing() || line->IsDimmed() || !(line->IsVisible()))
       
   719             continue;
       
   720         ChangeFocusTo(ii);
       
   721         focusSet=ETrue;
       
   722         
       
   723         if ( IsForm() )
       
   724             {
       
   725             // move line with initial focus to the screen
       
   726     		iLines->MoveLineToScreen( ii, iPhysics->ViewTopY(), ETrue );
       
   727             }
       
   728         break;
       
   729         }
       
   730     iExtension->iSetInitialFocusDone = ETrue;
       
   731     return focusSet;
       
   732     }
       
   733 
       
   734 TKeyResponse CEikDialogPage::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
       
   735     {
       
   736     TKeyResponse response=EKeyWasNotConsumed;
       
   737 
       
   738     if (!(PageContainer()->PageSelector()->Dialg()->DialogFlags() & EEikDialogFlagDontEatUpDownEvents))
       
   739         {
       
   740         if (aType != EEventKey)
       
   741         return response;
       
   742         }
       
   743 
       
   744     const TInt numLines=iLines->Count();
       
   745     if ((iCurrentLine>-1)&&(iCurrentLine<numLines))
       
   746         {
       
   747         // If the control changes size as a result of offering it the key event then it will be
       
   748         // necessary to reformat the page
       
   749         if ((aKeyEvent.iCode != EKeyTab && aKeyEvent.iCode != EKeyPrevious && aKeyEvent.iCode != EKeyNext) || (*iLines)[iCurrentLine]->ControlIsAPopfield((*iLines)[iCurrentLine]->iControlType) ) // tab keys are not offered to child controls
       
   750             {
       
   751             response=(*iLines)[iCurrentLine]->OfferKeyEventL(aKeyEvent,aType);
       
   752             }
       
   753         iExtension->iFocusedClicked = EFalse;
       
   754         }
       
   755     if (aType == EEventKey && response==EKeyWasConsumed)
       
   756         ReportEventL(MCoeControlObserver::EEventStateChanged);
       
   757     else if (aType == EEventKey && (
       
   758             aKeyEvent.iCode==EKeyUpArrow 
       
   759             || aKeyEvent.iCode==EKeyDownArrow 
       
   760             || aKeyEvent.iCode==EKeyTab
       
   761             || aKeyEvent.iCode==EKeyNext
       
   762             || aKeyEvent.iCode==EKeyPrevious
       
   763             ))
       
   764         response=OfferUpDownKeyEventL(aKeyEvent,aType,ENonCyclic);
       
   765     return response;
       
   766     }
       
   767 
       
   768 TKeyResponse CEikDialogPage::OfferUpDownKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType,TFocusNavigationMode aFocusNavigationMode)
       
   769     {
       
   770     TKeyResponse response=EKeyWasNotConsumed;
       
   771     if (aType==EEventKey)
       
   772         {
       
   773         const TInt numLines=iLines->Count();
       
   774         if ((iCurrentLine>-1)&&(iCurrentLine<numLines))
       
   775             { 
       
   776             if (!iFormControl || (*iLines)[iCurrentLine]->iIsEditable  ) // non form controls should not have editable concept
       
   777                 {
       
   778                 // 1. Tab events are never forwarded.
       
   779                 // 2. If it's a non-form dialog, then it is forwarded.
       
   780                 // 3. If it's a form dialog, then it is forwarded if it's not 
       
   781                 //    next/previous nor line is a popup field.
       
   782                 if ( aKeyEvent.iCode != EKeyTab && 
       
   783                      ( !iFormControl ||
       
   784                        ( aKeyEvent.iCode != EKeyPrevious && aKeyEvent.iCode != EKeyNext ) || 
       
   785                        ( *iLines)[iCurrentLine]->ControlIsAPopfield((*iLines)[iCurrentLine]->iControlType ) ) )
       
   786                     {
       
   787                     response=(*iLines)[iCurrentLine]->OfferKeyEventL(aKeyEvent,aType);
       
   788                     }
       
   789                 }
       
   790             else
       
   791                 response=EKeyWasNotConsumed ;
       
   792             }
       
   793         if (response!=EKeyWasConsumed && 
       
   794             (aKeyEvent.iCode==EKeyUpArrow 
       
   795             || aKeyEvent.iCode==EKeyDownArrow 
       
   796             || aKeyEvent.iCode==EKeyTab
       
   797             || aKeyEvent.iCode==EKeyNext
       
   798             || aKeyEvent.iCode==EKeyPrevious
       
   799             ))
       
   800             {
       
   801             iExtension->iFocusedClicked = ETrue;
       
   802             
       
   803             switch (aFocusNavigationMode)
       
   804                 {
       
   805                 case ECyclic:
       
   806                     iExtension->iScrolled = ETrue;                    
       
   807                     response=HandleCyclicFocusNavigationKeyL(aKeyEvent);
       
   808                     break;
       
   809                     
       
   810                 case ENonCyclic:
       
   811                     iExtension->iScrolled = ETrue;                    
       
   812                     response=HandleNonCyclicFocusNavigationKeyL(aKeyEvent);
       
   813                     break;
       
   814                     
       
   815                 default:
       
   816                     break;
       
   817                 };
       
   818 
       
   819             if (response==EKeyWasConsumed)
       
   820                 ReportEventL(MCoeControlObserver::EEventStateChanged);
       
   821             }
       
   822         }
       
   823 
       
   824     if (response==EKeyWasConsumed)
       
   825         UpdateScrollBarThumb();
       
   826 
       
   827     return response;
       
   828     }
       
   829 
       
   830 TKeyResponse CEikDialogPage::HandleNonCyclicFocusNavigationKeyL(const TKeyEvent& aKeyEvent)
       
   831     {
       
   832     TKeyResponse response=EKeyWasNotConsumed;
       
   833     TBool up = EFalse;
       
   834     TBool down = EFalse;
       
   835     TBool tab = EFalse;
       
   836     TInt naviCount = 1;
       
   837     switch (aKeyEvent.iCode)
       
   838         {
       
   839         case EKeyPrevious:
       
   840             naviCount = aKeyEvent.iRepeats + 1;
       
   841         case EKeyUpArrow:
       
   842             up = ETrue;
       
   843             break;
       
   844         case EKeyNext:
       
   845             naviCount = aKeyEvent.iRepeats + 1;
       
   846         case EKeyDownArrow:
       
   847             down = ETrue;
       
   848             break;
       
   849         case EKeyTab:
       
   850             tab = ETrue;
       
   851             if (aKeyEvent.iModifiers & EModifierShift)
       
   852                 {
       
   853                 up = ETrue;
       
   854                 }
       
   855             else
       
   856                 {
       
   857                 down = ETrue;
       
   858                 }
       
   859             break;
       
   860         default:
       
   861             ASSERT(EFalse);
       
   862         };
       
   863     
       
   864     if (up)
       
   865         {
       
   866         if (iCurrentLine!=TopFocusableLine()||(iExtension->iIsDoubleQuery&&tab))
       
   867            {
       
   868            if (RotateFocusByL(-1*naviCount))
       
   869                response=EKeyWasConsumed;
       
   870            }
       
   871         }
       
   872     if (down)
       
   873         {
       
   874         if (iCurrentLine!=BottomFocusableLine()||(iExtension->iIsDoubleQuery&&tab))
       
   875             {
       
   876             if (RotateFocusByL(+1*naviCount))
       
   877                 response=EKeyWasConsumed;
       
   878             }
       
   879         else if (aKeyEvent.iRepeats>0)
       
   880             {
       
   881             response=EKeyWasConsumed;
       
   882             }
       
   883 
       
   884         }
       
   885 
       
   886     return response;
       
   887     }
       
   888 
       
   889 TKeyResponse CEikDialogPage::HandleCyclicFocusNavigationKeyL(const TKeyEvent& aKeyEvent)
       
   890     {
       
   891     TKeyResponse response=EKeyWasNotConsumed;
       
   892 
       
   893     switch (aKeyEvent.iCode)
       
   894         {
       
   895         case EKeyUpArrow:
       
   896             if (!(iCurrentLine==TopFocusableLine() && aKeyEvent.iRepeats>0)) // Check not reached top from a repeated key event.
       
   897                 {
       
   898                 if (RotateFocusByL(-1))
       
   899                     response=EKeyWasConsumed;
       
   900                 }
       
   901             break;
       
   902         case EKeyDownArrow:
       
   903             if (!(iCurrentLine==BottomFocusableLine() && aKeyEvent.iRepeats>0)) // Check not reached bottom from a repeated key event.
       
   904                 {
       
   905                 if (RotateFocusByL(+1))
       
   906                     response=EKeyWasConsumed;
       
   907                 }
       
   908             break;
       
   909         default:
       
   910             ASSERT(EFalse);
       
   911         }
       
   912 
       
   913     return response;
       
   914     }
       
   915 
       
   916 TBool CEikDialogPage::OwnsLine(TInt aLineId) const
       
   917     {
       
   918     TBool ownsLine=EFalse;
       
   919 
       
   920     const TInt numLines=iLines->Count();
       
   921     for (TInt ii=0;ii<numLines;ii++)
       
   922         {
       
   923         if ((*iLines)[ii]->iId==aLineId)
       
   924             {
       
   925             ownsLine=ETrue;
       
   926             break;
       
   927             }
       
   928         }
       
   929 
       
   930     return ownsLine;
       
   931     }
       
   932 
       
   933 void CEikDialogPage::SetDimmed(TBool aDimmed)
       
   934     {
       
   935     CCoeControl::SetDimmed(aDimmed);
       
   936 
       
   937     const TInt numLines=iLines->Count();
       
   938     for (TInt ii=0;ii<numLines;ii++)
       
   939         {
       
   940         CEikCaptionedControl* thisLine=(*iLines)[ii];
       
   941         thisLine->iControl->SetDimmed(aDimmed);
       
   942         thisLine->CheckDimmedDisplayState();
       
   943         }
       
   944     }
       
   945 
       
   946 TBool CEikDialogPage::RotateFocusByL(TInt aDelta)
       
   947     {
       
   948     TInt numLines=iLines->Count();
       
   949     if (numLines == 0)
       
   950         return(EFalse);
       
   951     
       
   952     // If form is in view mode and highlight is hidden then the first
       
   953     // navigation key press just displays the highlight.
       
   954     if ( IsForm() && !IsEditable() && !HighlightVisible() )
       
   955         {
       
   956         HighlightVisible( ETrue );
       
   957         
       
   958         TInt lineIndex = iLines->FocusableLine( iCurrentLine,
       
   959                 iPhysics->ViewTopY() );
       
   960         
       
   961         if ( lineIndex != KErrNotFound )
       
   962             {
       
   963             if ( lineIndex == iCurrentLine )
       
   964                 {
       
   965                 CEikCaptionedControl* line = (*iLines)[iCurrentLine];
       
   966                 ShowFocus( ETrue, ETrue );
       
   967                 }
       
   968             else
       
   969                 {
       
   970                 iExtension->iLastTouchedLine = lineIndex;
       
   971                 HandleHighlightTimer();
       
   972                 }
       
   973             }
       
   974         
       
   975         return ETrue;
       
   976         }
       
   977     
       
   978     TInt max=numLines-1;
       
   979     TInt currentLine=iCurrentLine;
       
   980     while (numLines--)
       
   981         {
       
   982         currentLine+=aDelta;
       
   983 
       
   984 
       
   985         if (currentLine<0)
       
   986             currentLine=0;
       
   987         else if (currentLine>max)
       
   988             currentLine=max;
       
   989 
       
   990         (*iLines)[currentLine]->ActivateL() ;  // ensure that the current line is activated.
       
   991 
       
   992         if (!(LineIsFocusable(currentLine)))
       
   993             continue;
       
   994 
       
   995         PrepareForFocusTransitionL();
       
   996 
       
   997         if (!(LineIsFocusable(currentLine)))
       
   998             continue;
       
   999 
       
  1000         ChangeFocusToAndExposeL(currentLine);
       
  1001         LineChangedL((*iLines)[currentLine]->iId);
       
  1002         iExtension->iFocusedClicked = ETrue;
       
  1003         return(ETrue);
       
  1004         }
       
  1005         
       
  1006     return EFalse;
       
  1007     }
       
  1008 
       
  1009 void CEikDialogPage::ChangeFocusToAndExposeL( TInt aLine, TBool /*aShowWholeControl*/ )
       
  1010     {
       
  1011     if ( aLine < 0 || aLine == iCurrentLine )
       
  1012         return;
       
  1013     
       
  1014     TInt oldLine = iCurrentLine;
       
  1015     
       
  1016     if( aLine != iCurrentLine )
       
  1017         (*iLines)[iCurrentLine]->ScrollBackEditor();
       
  1018     
       
  1019     ChangeFocusTo( aLine );
       
  1020     ExposeLine( iCurrentLine, EFalse );
       
  1021 
       
  1022     if ( oldLine != iCurrentLine )
       
  1023         {
       
  1024         
       
  1025         // If secret editor, cursor position should be update again to reflect
       
  1026         // screen scroll caused by ExposeLine(...)
       
  1027         CEikCaptionedControl* currentLine=(*iLines)[iCurrentLine];
       
  1028         if( IsForm() && currentLine->ControlIsASecretEditor(currentLine->iControlType) )
       
  1029             {
       
  1030             ShowFocus(ETrue, EFalse);
       
  1031             }
       
  1032         
       
  1033         DrawDeferred();
       
  1034         }
       
  1035     }
       
  1036 
       
  1037 TInt CEikDialogPage::TopFocusableLine() const
       
  1038     {
       
  1039     const TInt numLines=iLines->Count();
       
  1040     for (TInt i=0;i<numLines;i++)
       
  1041         {
       
  1042         if (LineIsFocusable(i))
       
  1043             return i;
       
  1044         }
       
  1045 
       
  1046     return KErrNotFound;
       
  1047     }
       
  1048 
       
  1049 TInt CEikDialogPage::BottomFocusableLine() const
       
  1050     {
       
  1051     const TInt numLines=iLines->Count();
       
  1052     for (TInt i=numLines-1;i>=0;i--)
       
  1053         {
       
  1054         if (LineIsFocusable(i))
       
  1055             return i;
       
  1056         }
       
  1057 
       
  1058     return KErrNotFound;
       
  1059     }
       
  1060 
       
  1061 TBool CEikDialogPage::LineIsFocusable(TInt aLine) const
       
  1062     {
       
  1063     TBool focusable(ETrue);
       
  1064     CEikCaptionedControl* line=(*iLines)[aLine];
       
  1065 
       
  1066     if (line->IsNonFocusing() || line->IsDimmed() || !(line->IsVisible()))
       
  1067         focusable=EFalse;
       
  1068 
       
  1069     return focusable;
       
  1070     }
       
  1071 
       
  1072 void CEikDialogPage::SetDensePacking(TBool aDensePacking)
       
  1073     {
       
  1074     iLines->SetDensePacking(aDensePacking);
       
  1075     }
       
  1076 
       
  1077 void CEikDialogPage::InsertLineL(TInt aPosition,TInt aResourceId)
       
  1078     {
       
  1079     // alteration is bloated but should not provide any side-effects.
       
  1080     if (!iFormControl)
       
  1081         {
       
  1082         CEikCaptionedControl* line=ConstructLineL(aResourceId);
       
  1083         CleanupStack::PushL(line);
       
  1084         iLines->InsertL(aPosition,line);
       
  1085         CleanupStack::Pop(); // line
       
  1086         line->RegisterPageWithCaptionControl(this);
       
  1087         return;
       
  1088         }
       
  1089     ShowFocus( EFalse,EFalse ) ; 
       
  1090     CEikCaptionedControl* line=ConstructLineL(aResourceId);
       
  1091     CleanupStack::PushL(line);
       
  1092     line->SetComponentsToInheritVisibility(); 
       
  1093     iLines->InsertL(aPosition,line);
       
  1094     CleanupStack::Pop(); // line now owned by iLines.
       
  1095     AfterAddingNewLinesL(aPosition); 
       
  1096 /* 
       
  1097 iCurrentLine should be increased as it is relative to the lines in that page
       
  1098 and we have just added a new line before it in the page.
       
  1099 */
       
  1100     if (iCurrentLine>=aPosition) 
       
  1101         iCurrentLine++;
       
  1102     }
       
  1103 
       
  1104 void CEikDialogPage::DeleteLine(TInt aLineId, TBool aRedraw)
       
  1105     {
       
  1106     TInt index( LineIndex( aLineId ) ) ;
       
  1107     if ( index == iCurrentLine ) // we're deleting the current line
       
  1108         {
       
  1109 // If this is the last line then move the focus to the line above.  (becomes -1 if last line)
       
  1110         if( iCurrentLine == iLines->Count() - 1 )
       
  1111             iCurrentLine-- ;
       
  1112 /* 
       
  1113 LastExposedLine is needed for when to remember control positions in forms.
       
  1114 If we've deleted that line, forget it.
       
  1115 */      iLastExposedLine=-1; 
       
  1116         }
       
  1117     else
       
  1118         {
       
  1119 /* Since iCurrentLine is relative to the positions in the form, if we've deleted a line which
       
  1120 comes before it in the list, we should reduce iCurrentLine by 1.
       
  1121 Same is true for LastExposedLine.
       
  1122 */
       
  1123         if (index<iCurrentLine)
       
  1124             {
       
  1125             iCurrentLine--;
       
  1126             iLastExposedLine--;
       
  1127             }
       
  1128         }
       
  1129 // Actually delete the line.
       
  1130     TInt lineIndex = LineIndex( aLineId );
       
  1131 
       
  1132     // delete line's cached draw commands
       
  1133     if ( IsForm() )
       
  1134         {
       
  1135         iExtension->iRecordingGc->DeleteLine( lineIndex );
       
  1136         }
       
  1137 
       
  1138     iLines->DeleteLine( lineIndex ); 
       
  1139     
       
  1140     ReconsiderPageSize();
       
  1141 
       
  1142     if (aRedraw)
       
  1143         {
       
  1144         if (iCurrentLine!=-1)
       
  1145             {
       
  1146             TInt targetLine = iCurrentLine ;
       
  1147             iCurrentLine = -1 ;
       
  1148             ChangeFocusTo( targetLine ) ;
       
  1149             ExposeLine( targetLine, ETrue ) ;
       
  1150             ShowFocus( ETrue, EFalse ) ;
       
  1151             }
       
  1152 
       
  1153         DrawNow();
       
  1154         TRAP_IGNORE(UpdateScrollBarL()); // if OOM, scrollbar will not be updated - No great loss.
       
  1155         }
       
  1156     }
       
  1157 
       
  1158 void CEikDialogPage::AdjustAllIds(TInt aControlIdDelta)
       
  1159     {
       
  1160     iLines->AdjustAllIds(aControlIdDelta);
       
  1161     }
       
  1162 
       
  1163 TInt CEikDialogPage::FocusLineL(TInt aLineId)
       
  1164     {
       
  1165     TInt lineIndex=LineIndex(aLineId);
       
  1166 
       
  1167     if (lineIndex==KErrNotFound)
       
  1168         return KErrNotFound;
       
  1169 
       
  1170     PrepareForFocusTransitionL();
       
  1171 // Show whole line, not scroll into line.
       
  1172     ChangeFocusToAndExposeL(lineIndex, ETrue); 
       
  1173     LineChangedL(aLineId);
       
  1174     return KErrNone;
       
  1175     }
       
  1176 
       
  1177 TInt CEikDialogPage::FocusedLineId() const
       
  1178     {
       
  1179     if (iCurrentLine>=0)
       
  1180         return (*iLines)[iCurrentLine]->iId;
       
  1181     return 0;
       
  1182     }
       
  1183 
       
  1184 void CEikDialogPage::GetAutoValues()
       
  1185     {
       
  1186     const TInt numLines=iLines->Count();
       
  1187     for (TInt ii=0;ii<numLines;ii++)
       
  1188         {
       
  1189         CEikCaptionedControl* line=(*iLines)[ii];
       
  1190         TAny* returnValue=line->iReturnValue;
       
  1191         if (!returnValue)
       
  1192             continue;
       
  1193         CCoeControl* control=line->iControl;
       
  1194         switch (line->iControlType)
       
  1195             {
       
  1196         case EEikCtEdwin:
       
  1197             ((CEikEdwin*)control)->GetText(*(TDes*)returnValue);
       
  1198             break;
       
  1199         case EEikCtSecretEd:
       
  1200             ((CEikSecretEditor*)control)->GetText(*(TDes*)returnValue);
       
  1201             break;
       
  1202 
       
  1203         case EEikCtFlPtEd:
       
  1204             (*(TReal*)returnValue)=((CEikFloatingPointEditor*)control)->Value();
       
  1205             break;
       
  1206         case EEikCtFxPtEd:
       
  1207             (*(TInt*)returnValue)=((CEikFixedPointEditor*)control)->Value();
       
  1208             break;
       
  1209 
       
  1210         case EEikCtNumberEditor:
       
  1211             (*(TInt*)returnValue)=((CEikNumberEditor*)control)->Number();
       
  1212             break;
       
  1213         case EEikCtRangeEditor:
       
  1214             (*(SEikRange*)returnValue)=((CEikRangeEditor*)control)->Range();
       
  1215             break;
       
  1216         case EEikCtTimeEditor:
       
  1217             (*(TTime*)returnValue)=((CEikTimeEditor*)control)->Time();
       
  1218             break;
       
  1219         case EEikCtDateEditor:
       
  1220             (*(TTime*)returnValue)=((CEikDateEditor*)control)->Date();
       
  1221             break;
       
  1222         case EEikCtTimeAndDateEditor:
       
  1223             (*(TTime*)returnValue)=((CEikTimeAndDateEditor*)control)->TimeAndDate();
       
  1224             break;
       
  1225         case EEikCtDurationEditor:
       
  1226             (*(TTimeIntervalSeconds*)returnValue)=((CEikDurationEditor*)control)->Duration();
       
  1227             break;
       
  1228         case EEikCtTimeOffsetEditor:
       
  1229             (*(TTimeIntervalSeconds*)returnValue)=((CEikTimeOffsetEditor*)control)->TimeOffset();
       
  1230             break;
       
  1231 
       
  1232         default:
       
  1233             ASSERT(iPageObserver);
       
  1234             iPageObserver->GetCustomAutoValue(returnValue,line->iControlType,control);
       
  1235             break;
       
  1236             }
       
  1237         }
       
  1238     }
       
  1239 
       
  1240 TInt CEikDialogPage::LineIndex(TInt aLineId)
       
  1241     {
       
  1242     const TInt numLines=iLines->Count();
       
  1243     for (TInt ii=0;ii<numLines;ii++)
       
  1244         {
       
  1245         if ((*iLines)[ii]->iId==aLineId)
       
  1246             return ii;
       
  1247         }
       
  1248 
       
  1249     return KErrNotFound;
       
  1250     }
       
  1251 
       
  1252 TInt CEikDialogPage::YPosToLine2(TInt aYPos) const
       
  1253     {
       
  1254     return iLines->YPosToLine( Rect(), iScroll->Top(), iScroll->Middle(), iScroll->Bottom(), aYPos );
       
  1255     }
       
  1256 
       
  1257 TInt CEikDialogPage::LineToYPos(TInt& aLine) const
       
  1258 //
       
  1259 // Calcs YPos of line relative to the ViewWin and adjusts aLine if its out of bounds
       
  1260     {
       
  1261     ASSERT(iLines);
       
  1262     const TInt numLines=iLines->Count();
       
  1263     ASSERT(numLines>0);
       
  1264     if (aLine<0)
       
  1265         aLine=0;
       
  1266     else if (aLine>=numLines)
       
  1267         aLine=numLines-1;
       
  1268     return (*iLines)[aLine]->Position().iY; // TPREMOVAL +iDataWinPos.iY;
       
  1269     }
       
  1270 
       
  1271 void CEikDialogPage::ExposeLine(TInt aLine, TBool aForceResize, TBool aShowWholeLine) 
       
  1272 //
       
  1273 /* Exposes the given line so that its fully visible in the ViewWin
       
  1274 */  {
       
  1275     if ( iSize.iHeight == 0 || aLine == -1 )
       
  1276         {
       
  1277         return;
       
  1278         }
       
  1279 
       
  1280     CAknPaneScroll::TScrollChangeType change = iScroll->ExposeLine( aLine, aShowWholeLine );
       
  1281     
       
  1282     if ( change == CAknPaneScroll::ENoChange && !aForceResize )
       
  1283         {
       
  1284         return;
       
  1285         }
       
  1286 
       
  1287     CEikCaptionedControl* capCtrl = (*iLines)[aLine];
       
  1288     capCtrl->MinimumSize();
       
  1289     TInt controlHeight (ControlHeight( aLine ));
       
  1290     TInt focusedControlsPositionInDataWin (capCtrl->Position().iY);
       
  1291 
       
  1292     if ( IsForm() )
       
  1293         {
       
  1294         focusedControlsPositionInDataWin = iLines->LineIndexToYPosition( aLine, 0 );
       
  1295         }
       
  1296     
       
  1297     TInt topYPosOfControlWhichMustBeViewable = focusedControlsPositionInDataWin;
       
  1298     TInt bottomYPosOfControlWhichMustBeViewable = focusedControlsPositionInDataWin+controlHeight;
       
  1299     TInt controlType = capCtrl->iControlType;
       
  1300 
       
  1301     // make the default value for where we'd like the datawinpos offset to be the current value
       
  1302     TInt idealDataWindowPosition = 0;
       
  1303     /* 
       
  1304     If it's not a form, the values set above should be fine
       
  1305     */
       
  1306     if ( iFormControl && !aShowWholeLine )
       
  1307         {
       
  1308         if ( aLine == iLastExposedLine && !capCtrl->ControlIsAnEdwin( controlType ) && iFormControl ) 
       
  1309             {
       
  1310             /*
       
  1311             We want to position this control as near to the place it was before as possible
       
  1312             Important for growing and shrinking of popupfields.
       
  1313             Hence set the datawin as the remembered position
       
  1314             (the position is stored relative to the view win, hence the calculation)
       
  1315             */
       
  1316             idealDataWindowPosition = (-1*topYPosOfControlWhichMustBeViewable)+iLastExposedLineViewWinYPosition;
       
  1317 
       
  1318             topYPosOfControlWhichMustBeViewable = iLastExposedLineViewWinYPosition;
       
  1319             bottomYPosOfControlWhichMustBeViewable = topYPosOfControlWhichMustBeViewable + controlHeight;
       
  1320             }
       
  1321         }
       
  1322 
       
  1323     SetDataPosition( topYPosOfControlWhichMustBeViewable, bottomYPosOfControlWhichMustBeViewable, aForceResize ); 
       
  1324   
       
  1325     if ( aLine != iLastExposedLine )
       
  1326         {
       
  1327         iLastExposedLine = aLine;
       
  1328         iLastExposedLineViewWinYPosition = topYPosOfControlWhichMustBeViewable + idealDataWindowPosition;
       
  1329         }
       
  1330     }
       
  1331 
       
  1332 void CEikDialogPage::SetDataPosition( TInt aTopY, TInt aBottomY, TBool aForceResize )
       
  1333     {
       
  1334     // update rect only if the currently focused control doesn't fit
       
  1335     if ( iFormControl )
       
  1336         {
       
  1337         TInt topY = iPhysics->ViewTopY();
       
  1338         TInt maxBottomY = topY + iSize.iHeight;
       
  1339 
       
  1340         if ( aForceResize || aTopY < topY || aBottomY > maxBottomY )
       
  1341             {
       
  1342             TInt totalHeight = 0;
       
  1343             TInt count = iLines->Count();
       
  1344             TPoint viewCenter( iPhysics->ViewCenter() );
       
  1345             
       
  1346             for ( TInt i = 0; i < count; ++i )
       
  1347                 {
       
  1348                 totalHeight += (*iLines)[i]->Rect().Height();
       
  1349                 }
       
  1350             
       
  1351             if ( totalHeight > iSize.iHeight )
       
  1352                 {
       
  1353                 if( aTopY < topY )
       
  1354                     {
       
  1355                     viewCenter.iY = iPhysics->ViewCenter().iY - topY + aTopY;
       
  1356                     }                       
       
  1357                 else if( aBottomY > maxBottomY )
       
  1358                     {
       
  1359                     viewCenter.iY = iPhysics->ViewCenter().iY + aBottomY - maxBottomY;
       
  1360                     }                       
       
  1361                 else if( totalHeight < ( iPhysics->ViewCenter().iY + iPhysics->ViewCenterDistance() ) )
       
  1362                     {
       
  1363                     viewCenter.iY = totalHeight - iPhysics->ViewCenterDistance();
       
  1364                     }
       
  1365                 else 
       
  1366                     {
       
  1367                     viewCenter.iY = iPhysics->ViewCenter().iY;
       
  1368                     }                        
       
  1369                 }
       
  1370             else
       
  1371                 {
       
  1372                 viewCenter.iY = iPhysics->ViewCenterDistance();
       
  1373                 }
       
  1374 
       
  1375             iPhysics->SetViewCenter( viewCenter );
       
  1376             iLines->MoveLineToScreen( iCurrentLine, iPhysics->ViewTopY(), ETrue );
       
  1377             }
       
  1378         }
       
  1379     }
       
  1380                     
       
  1381 /*
       
  1382 class CDummy: public CCoeControl
       
  1383     {
       
  1384     public:
       
  1385         TBool IsReadyToDraw() const
       
  1386             {
       
  1387             return CCoeControl::IsReadyToDraw();
       
  1388             }
       
  1389     };
       
  1390     
       
  1391     if ( iPhysics )
       
  1392         {
       
  1393         // Awful hack below is used to prevent some unwanted drawing that would
       
  1394         // otherwise occur during form's initialization.
       
  1395         //
       
  1396         // Unfortunately CCoeControl::IsActivated is protected so we need to
       
  1397         // work around that somehow...
       
  1398         CCoeControl* parent = WindowOwningParent();
       
  1399         
       
  1400         if ( parent )
       
  1401             {
       
  1402             CDummy* fakeParent = reinterpret_cast<CDummy*>( parent );
       
  1403             TBool isReadyToDraw = fakeParent->IsReadyToDraw();
       
  1404             
       
  1405             if ( isReadyToDraw )
       
  1406                 {
       
  1407                 DrawNow();
       
  1408                 }
       
  1409             }
       
  1410         }
       
  1411 */                    
       
  1412 
       
  1413 TInt CEikDialogPage::ControlHeight(TInt aLineIndex) const
       
  1414     {
       
  1415     return (*iLines)[aLineIndex]->Size().iHeight;
       
  1416     }
       
  1417 
       
  1418 void CEikDialogPage::SizeChanged()
       
  1419     {
       
  1420     // update form area's size to scroll control
       
  1421     iScroll->SetOutsideRect( Rect() );
       
  1422     iLines->SetRect( Rect(), iScroll->Top(), iScroll->Middle(), iScroll->Bottom() );
       
  1423 
       
  1424     if ( (iLines->Count() > 0 ) && ( iCurrentLine >= 0 ) )
       
  1425         {
       
  1426         ExposeLine( iCurrentLine, EFalse );
       
  1427         }
       
  1428 
       
  1429     TRAP_IGNORE( UpdateScrollBarL() ); // ignore any errors.
       
  1430     AknsUtils::RegisterControlPosition( this ); 
       
  1431 
       
  1432     UpdatePhysics();
       
  1433     iExtension->iInitialLayoutDone = ETrue;
       
  1434     }
       
  1435 
       
  1436 TSize CEikDialogPage::MinimumSize()
       
  1437     {
       
  1438     return TSize( iLines->MinimumSize().iWidth, 0 );   // Can be zero height
       
  1439     }
       
  1440 
       
  1441 void CEikDialogPage::PrepareForFocusLossL()
       
  1442     {
       
  1443     PrepareForFocusTransitionL();
       
  1444     }
       
  1445 
       
  1446 /**
       
  1447  * Writes the internal state of the control and its components to aStream.
       
  1448  * Does nothing in release mode.
       
  1449  * Designed to be overidden and base called by subclasses.
       
  1450  *
       
  1451  * @internal
       
  1452  * @since App-Framework_6.1
       
  1453  */
       
  1454 #ifndef _DEBUG
       
  1455 void  CEikDialogPage::WriteInternalStateL(RWriteStream&) const
       
  1456     {}
       
  1457 #else
       
  1458 void  CEikDialogPage::WriteInternalStateL(RWriteStream& aWriteStream) const
       
  1459     {
       
  1460     CCoeControl::WriteInternalStateL(aWriteStream);
       
  1461     }
       
  1462 #endif
       
  1463 
       
  1464 TSize CEikDialogPage::PreferredSize() const
       
  1465     {
       
  1466     return CONST_CAST(CEikDialogPage*,this)->iLines->MinimumSize();
       
  1467     }
       
  1468 
       
  1469 TBool CEikDialogPage::HandleEdwinSizeEventL(CEikEdwin* aEdwin, TEdwinSizeEvent aEventType, TSize aDesirableEdwinSize)
       
  1470     {
       
  1471     switch (aEventType)
       
  1472         {
       
  1473     case EEventSizeChanging:
       
  1474 
       
  1475         if ( iFormFlags & EFormResizeOptimisationFlag ) // Flag indicates that resizing is not necessary now (it will be done later)
       
  1476             return EFalse ;
       
  1477         if (iCurrentLine>=0&& iIgnoreFurtherEdwinResizeEvents!=aEdwin)
       
  1478             return ResizeEdwinToFitTextL(aEdwin, EDrawNow, aDesirableEdwinSize);
       
  1479         break;
       
  1480     default:
       
  1481         break;
       
  1482         }
       
  1483     return EFalse;
       
  1484     }
       
  1485 
       
  1486 /** 
       
  1487  * From MEikEdwinObserver. Look for navigation and editor text update events, as scrolling
       
  1488  might be required to keep cursor visible.
       
  1489  */
       
  1490 void CEikDialogPage::HandleEdwinEventL(CEikEdwin* aEdwin,TEdwinEvent aEventType)
       
  1491     {
       
  1492     if ( IsForm() && ( aEventType == EEventTextUpdate
       
  1493             || aEventType == EEventTextUpdateAPI ) )
       
  1494         {
       
  1495         CEikCaptionedControl* line = NULL;
       
  1496         TInt controlType = -1;
       
  1497         
       
  1498         for ( TInt i = 0; i < iLines->Count(); ++i )
       
  1499             {
       
  1500             line = (*iLines)[i];
       
  1501             controlType = line->ControlType();
       
  1502             
       
  1503             if ( line->ControlIsAnEdwin( controlType ) )
       
  1504                 {
       
  1505                 if ( line->iControl == aEdwin )
       
  1506                     {
       
  1507                     RecordLineL( i );
       
  1508                     
       
  1509                     if ( i != iCurrentLine )
       
  1510                         {
       
  1511                         DrawNow();
       
  1512                         }
       
  1513                         
       
  1514                     break;
       
  1515                     }
       
  1516                 }
       
  1517             }
       
  1518         }
       
  1519     
       
  1520     if( iCurrentLine == iLastExposedLine || iCurrentLine == -1 )
       
  1521         return;
       
  1522     if( aEventType == EEventNavigation || aEventType == EEventTextUpdate )
       
  1523         {
       
  1524         ExposeLine( iCurrentLine, EFalse );
       
  1525             
       
  1526         UpdateScrollBarL();
       
  1527         }
       
  1528     }
       
  1529 
       
  1530 /**
       
  1531  * Handle events caused by popup field controls, and resize if necessary
       
  1532  */
       
  1533 void CEikDialogPage::HandlePopupFieldEventL(CAknPopupField* aPopupField, TAknPopupFieldEvent aEventType, TInt /*aHint*/)
       
  1534     {
       
  1535     switch (aEventType)
       
  1536         {
       
  1537     case EAknPopupFieldEventValueChange:
       
  1538         {
       
  1539         CEikCaptionedControl* line = NULL;
       
  1540         for ( TInt i = 0; i < iLines->Count(); ++i )
       
  1541             {
       
  1542             line = (*iLines)[i];
       
  1543             if ( line->iControl == aPopupField )
       
  1544                 {
       
  1545                 if ( IsForm() )
       
  1546                     {
       
  1547                     RecordLineL( i );
       
  1548                     }
       
  1549                 DrawNow();
       
  1550                 break;
       
  1551                 }
       
  1552             }
       
  1553         break;  
       
  1554         }
       
  1555     case EAknPopupFieldEventModeChange:
       
  1556         {
       
  1557         TInt index = iCurrentLine;
       
  1558         
       
  1559         if(iIsEditable && (iExtension->iPopFieldEvents != 0))
       
  1560             {           
       
  1561             iExtension->iPopFieldEvents = 0;
       
  1562             SetScbState(EFalse);
       
  1563             }
       
  1564         else
       
  1565             {
       
  1566             iExtension->iPopFieldEvents = 1;
       
  1567             }     
       
  1568                 
       
  1569         ReconsiderPageSize();
       
  1570         ExposeLine( index, ETrue );
       
  1571         DrawNow();
       
  1572 
       
  1573         UpdateScrollBarL();
       
  1574         PrepareToDrawVerticalLine();
       
  1575         break;
       
  1576         }
       
  1577     default:
       
  1578         break;
       
  1579         }
       
  1580     }
       
  1581 
       
  1582 void CEikDialogPage::PrepareToDrawVerticalLine() const
       
  1583     { // to avoid flushes, we resize skin frame bitmaps before actual draw.
       
  1584       // NOTE, this should be possiblie to call from SizeChanged() or OfferKeyEventL() method :-) (the GC?)
       
  1585 
       
  1586     if (AknsUtils::AvkonSkinEnabled())
       
  1587         {
       
  1588         MAknsSkinInstance* skin = AknsUtils::SkinInstance() ;
       
  1589         MAknsControlContext* cc = AknsDrawUtils::ControlContext( this ) ;
       
  1590         if ( CurrentLine() )
       
  1591             {                 
       
  1592             TRect rectNotToDrawOuter( CurrentLine()->Rect() ) ;
       
  1593             TRect rectNotToDrawInner ;
       
  1594 
       
  1595             if ( iIsEditable )
       
  1596                 {
       
  1597                 rectNotToDrawInner.iTl = EditFrameTopLeftRect( rectNotToDrawOuter ).iBr ;
       
  1598                 rectNotToDrawInner.iBr = EditFrameBottomRightRect( rectNotToDrawOuter ).iTl ;
       
  1599                 AknsDrawUtils::PrepareFrame( skin,
       
  1600                                              rectNotToDrawOuter,
       
  1601                                              rectNotToDrawInner,
       
  1602                                              KAknsIIDQsnFrInput,
       
  1603                                              KAknsIIDDefault ) ;
       
  1604                 }
       
  1605 
       
  1606             }       
       
  1607         
       
  1608         }
       
  1609     
       
  1610     }
       
  1611 
       
  1612 void CEikDialogPage::DrawVerticalLine() const
       
  1613     {       
       
  1614     }
       
  1615 
       
  1616 void CEikDialogPage::HandleControlEventL(CCoeControl* aControl,TCoeEvent aEventType)
       
  1617     {
       
  1618     switch (aEventType)
       
  1619         {
       
  1620     case EEventPrepareFocusTransition:
       
  1621         PrepareForFocusTransitionL();
       
  1622         break;
       
  1623     case EEventRequestFocus:
       
  1624         ChangeFocusTo(FindLineIndex(aControl));
       
  1625         break;
       
  1626     case EEventStateChanged:
       
  1627 /*
       
  1628 if current line is at the top/bottom of the visible page
       
  1629 AND the page is in edit mode,
       
  1630 redraw the line in the captionedcontrol.
       
  1631 */
       
  1632         if (iCurrentLine!=-1)
       
  1633             {
       
  1634             CEikCaptionedControl* line = (*iLines)[iCurrentLine];
       
  1635             if (line->ControlIsAnEdwin(line->iControlType))
       
  1636                 {
       
  1637                 if  (
       
  1638                     (IsAtOrOffBottomOfPage(STATIC_CAST(CEikEdwin*,line->iControl))) || 
       
  1639                     (IsAtOrOffTopOfPage(STATIC_CAST(CEikEdwin*,line->iControl)))
       
  1640                     )
       
  1641                     {
       
  1642                     line->DrawClosingLine();
       
  1643                     }
       
  1644                 }
       
  1645             }
       
  1646             
       
  1647         if ( IsForm() )
       
  1648             {
       
  1649             CEikCaptionedControl* line = NULL;
       
  1650             for ( TInt i = 0; i < iLines->Count(); ++i )
       
  1651                 {
       
  1652                 line = (*iLines)[i];
       
  1653                 if ( line->iControl == aControl )
       
  1654                     {
       
  1655                     RecordLineL( i );
       
  1656                     break;
       
  1657                     }
       
  1658                 }
       
  1659             }
       
  1660 
       
  1661         PassOnEventL(aControl,aEventType);
       
  1662         break;
       
  1663     case EEventRequestExit:
       
  1664     case EEventRequestCancel:
       
  1665     case EEventInteractionRefused:
       
  1666     default:
       
  1667         break;
       
  1668         }
       
  1669     }
       
  1670 
       
  1671 void CEikDialogPage::PassOnEventL(CCoeControl* aControl,MCoeControlObserver::TCoeEvent aEvent)
       
  1672     {
       
  1673     MCoeControlObserver* observer=Observer();
       
  1674     if (observer)
       
  1675         observer->HandleControlEventL(aControl,aEvent);
       
  1676     }
       
  1677 
       
  1678 TBool CEikDialogPage::ResizeEdwinToFitTextL(CEikEdwin* aEdwin, TDrawNow /*aDrawNow*/, TSize aDesirableEdwinSize)
       
  1679 //
       
  1680     {
       
  1681     TInt edwinYPosBefore = aEdwin->Position().iY;
       
  1682     TInt edwinHeightBefore = aEdwin->Size().iHeight;
       
  1683 
       
  1684     const TInt maxHeight=iSize.iHeight-(KSpaceFromTitle+KSpaceFromBottom);
       
  1685     TInt height = aDesirableEdwinSize.iHeight;
       
  1686     if (height > maxHeight)
       
  1687         height = maxHeight;
       
  1688 
       
  1689     TSize size = aEdwin->Size();
       
  1690     TInt maximumEdwinHeight = aEdwin->MaximumHeight();
       
  1691 // ensure maxheight as dynamic construction may be done whilst form is of zero height.
       
  1692     if ((maximumEdwinHeight > maxHeight) && maxHeight) 
       
  1693         aEdwin->SetMaximumHeight(maxHeight);    // Can't be bigger than form itself
       
  1694     else if ((maximumEdwinHeight == 0) && (size.iHeight == height))
       
  1695         return EFalse;
       
  1696    
       
  1697     if ( (maximumEdwinHeight > 0) && (height > maximumEdwinHeight))
       
  1698         height=maximumEdwinHeight;  // Can't be bigger than edwin itself
       
  1699     size.iHeight = height;
       
  1700 
       
  1701     // Must force a size change on current captioned contrl even if control doesn't change size (so that edwin is resized by aknutils)
       
  1702     aEdwin->SetSize(size);  
       
  1703     ReconsiderPageSize();
       
  1704     ExposeLine(iCurrentLine, ETrue);
       
  1705     PrepareToDrawVerticalLine(); // do flushes here.
       
  1706 
       
  1707 /* improved redraw code
       
  1708 Due to some unpleasantness about dialogs, forms and requirements, to get caption controls
       
  1709 to draw properly requires a call to draw now.  A system initiated draw does not work correctly
       
  1710 
       
  1711 Therefore the drawing code has been tailored to minimise redraws and improve behaviour, whilst
       
  1712 cleaning up the marks left behind from shrinking edwins, etc.
       
  1713 */
       
  1714     TInt edwinYPosAfter = aEdwin->Position().iY;
       
  1715     TInt edwinHeightAfter =  aEdwin->Size().iHeight;
       
  1716 
       
  1717 /*
       
  1718 if the control is at the bottom of the page it could have initiated scrolling
       
  1719 which requires a full redraw.
       
  1720 */
       
  1721     DrawDeferred();
       
  1722     if (edwinHeightBefore!=edwinHeightAfter)
       
  1723         {
       
  1724 /* 
       
  1725 The scrollbar is updated here rather than in the more generic SizeChanged
       
  1726 as SizeChanged occurs multiple times on creation of multiline forms.
       
  1727 */
       
  1728         TRAP_IGNORE(UpdateScrollBarL()); // ignore any errors 
       
  1729         }
       
  1730     return ETrue;
       
  1731     }
       
  1732 
       
  1733 
       
  1734 static TInt CountNumberOfLines_Edwin(CEikEdwin *aEdwin, TRect aRect, TInt numOfLines)
       
  1735     {
       
  1736     TInt edwinLines = numOfLines;
       
  1737     TInt count = 0;
       
  1738     for(TInt i=0;i<edwinLines;i++)
       
  1739         {
       
  1740         TInt scrolledLines = aEdwin->TextLayout()->FirstLineInBand();
       
  1741         TInt docPos = aEdwin->TextLayout()->FirstCharOnLine(scrolledLines + i+1);
       
  1742         TPoint point;
       
  1743         aEdwin->TextLayout()->PosInBand(docPos, point);
       
  1744         TInt yPos = point.iY;
       
  1745         TRect lineRect;
       
  1746         aEdwin->TextLayout()->GetLineRect(yPos, lineRect);
       
  1747         lineRect.iTl += aEdwin->Position();
       
  1748         lineRect.iBr += aEdwin->Position();
       
  1749         if (aRect.Contains(lineRect.iTl) && aRect.Contains(lineRect.iBr))
       
  1750             count++;
       
  1751         }   
       
  1752     return count;
       
  1753     }
       
  1754 static TInt CountNumberOfLines_Ctrl(CCoeControl *aControl, TRect aRect)
       
  1755     {
       
  1756     TRect rect = TRect(aControl->Position(), aControl->Size());
       
  1757     TInt count = 0;
       
  1758     if (aRect.Contains(rect.iTl) && aRect.Contains(rect.iBr))
       
  1759         count ++;
       
  1760     return count;
       
  1761     }
       
  1762 
       
  1763 static TInt CountNumberOfVisibleLines(CEikCaptionedControl *aControl, TRect aClipRect)
       
  1764     {
       
  1765     TInt count = 0;
       
  1766     if (aControl->ControlIsAnEdwin(aControl->iControlType))
       
  1767         count += CountNumberOfLines_Edwin((CEikEdwin*)aControl->iControl, aClipRect, aControl->NumberOfLines());
       
  1768     else
       
  1769         count += CountNumberOfLines_Ctrl(aControl->iControl, aClipRect);
       
  1770     count += CountNumberOfLines_Ctrl(aControl->iCaption, aClipRect);
       
  1771     return count;
       
  1772     }
       
  1773 
       
  1774 static TInt NumberOfTextLinesVisible(CEikCapCArray *aLines, TInt aItem, TRect aClipRect)
       
  1775     {
       
  1776     if (aItem < 0) return 0;
       
  1777     CEikCaptionedControl *control = (*aLines)[aItem];
       
  1778     return CountNumberOfVisibleLines(control, aClipRect);   
       
  1779     }
       
  1780 
       
  1781 
       
  1782 void CEikDialogPage::HandleScrollEventL(CEikScrollBar* aScrollBar,TEikScrollEvent aEventType)
       
  1783     {
       
  1784     iExtension->iHandlingScrollEvent = ETrue;
       
  1785 
       
  1786     switch (aEventType)
       
  1787         {
       
  1788         case EEikScrollPageUp:
       
  1789         case EEikScrollPageDown:
       
  1790         case EEikScrollThumbDragVert:
       
  1791             iExtension->iScrolled = ETrue;
       
  1792             iExtension->iScrolling = ETrue;
       
  1793             iLines->MoveLineToScreen( iCurrentLine, 0, EFalse );
       
  1794             break;
       
  1795 
       
  1796         default:
       
  1797             break;
       
  1798         }
       
  1799 
       
  1800     iPhysics->ViewPositionChanged( TPoint( iPhysics->ViewCenter().iX, 
       
  1801             aScrollBar->ThumbPosition() + iPhysics->ViewCenterDistance() ), ETrue );
       
  1802 
       
  1803     switch (aEventType)
       
  1804         {
       
  1805         case EEikScrollPageUp:
       
  1806         case EEikScrollPageDown:
       
  1807         case EEikScrollThumbReleaseVert:
       
  1808             iExtension->iScrolling = EFalse;
       
  1809             iLines->MoveLineToScreen( iCurrentLine, iPhysics->ViewTopY(), ETrue );
       
  1810             break;
       
  1811 
       
  1812         default:
       
  1813             break;
       
  1814         }
       
  1815     
       
  1816     iExtension->iHandlingScrollEvent = EFalse;
       
  1817     }
       
  1818 
       
  1819 TBool CEikDialogPage::LineHandlerCalled() const
       
  1820     {
       
  1821     return iExtension->iFlags.IsSet( CDialogPageExtension::ELineHandlerCalled );
       
  1822     }    
       
  1823     
       
  1824 TRect MainPane()
       
  1825     {
       
  1826     TRect mainPaneRect;
       
  1827     AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPaneRect );
       
  1828     return mainPaneRect;
       
  1829     }
       
  1830 
       
  1831 void CEikDialogPage::UpdateScrollBarL()
       
  1832     {
       
  1833     // Only forms in S60 need dialog's scrollbar.
       
  1834     if ( !iFormControl || !iPageContainer->ScrollBar() || iSize.iHeight == 0 || iSize.iWidth == 0 || iExtension->iHandlingScrollEvent )
       
  1835         {
       
  1836         return;
       
  1837         }
       
  1838 
       
  1839     CAknScrollBar* scrollBar = STATIC_CAST(CAknScrollBar*, iPageContainer->ScrollBar()->VerticalScrollBar());
       
  1840 
       
  1841     if (scrollBar)
       
  1842         {
       
  1843         TInt top = iScroll->Top();
       
  1844         TInt middle = iScroll->Middle();
       
  1845         TInt bottom = iScroll->Bottom();
       
  1846         TRect parent( Rect() );
       
  1847         TBool topmostPartial = top == -1;
       
  1848         iLines->CalcItemIndexes(top, middle, bottom, parent.Size());
       
  1849         TInt extraLines = topmostPartial ? NumberOfTextLinesVisible(iLines, top-1, parent) : 0;
       
  1850         iExtension->iPreviousThumbPosition = iLines->NumberOfTextLinesBeforeLine( top - extraLines );
       
  1851 
       
  1852         // Using form layout, since this is used by AknForm only
       
  1853         TAknWindowComponentLayout layout = TAknWindowComponentLayout::Compose( 
       
  1854             AknLayoutScalable_Avkon::listscroll_form_pane(),  
       
  1855             AknLayoutScalable_Avkon::scroll_pane_cp8());
       
  1856             
       
  1857         TRect scrollBarParent( MainPane().Size()/*mainPaneRect.Size()*/ );
       
  1858     
       
  1859         AknLayoutUtils::LayoutVerticalScrollBar(iPageContainer->ScrollBar(), scrollBarParent, layout.LayoutLine());
       
  1860         if(!ScbState() &&  iCurrentLine!=-1 && iCurrentLine < iLines->Count() )
       
  1861         	{
       
  1862     		CEikCaptionedControl *ctrl = (*iLines)[iCurrentLine];
       
  1863         	if(ctrl->ControlIsAPopfield(ctrl->iControlType))
       
  1864 				{
       
  1865 	            CAknPopupField::EAknPopupFieldSelectionMode mode = ((CAknPopupField*)ctrl->iControl)->SelectionMode();
       
  1866 	            if (mode == CAknPopupField::EAknPopupFieldSelectionListMode)
       
  1867 	                {
       
  1868 	                return;
       
  1869 	                }
       
  1870 				}        		
       
  1871         	UpdateScrollBarThumb();
       
  1872         	}
       
  1873         }
       
  1874     }
       
  1875     
       
  1876 
       
  1877 void CEikDialogPage::UpdateScrollBarThumb()
       
  1878     {
       
  1879     if ( !iFormControl || !iPageContainer->ScrollBar() || ScbState() )
       
  1880         {
       
  1881         return;
       
  1882         }
       
  1883 
       
  1884     CAknScrollBar* scrollBar = STATIC_CAST(CAknScrollBar*, iPageContainer->ScrollBar()->VerticalScrollBar());
       
  1885     
       
  1886     if ( scrollBar )
       
  1887         {
       
  1888         TEikScrollBarModel vertModel;
       
  1889 
       
  1890         // scrollbar's accuracy is one pixel
       
  1891         // TODO: replace iLines->MinimumSize with world size, presumably saved in CAknFormPhysics
       
  1892         vertModel.iScrollSpan = iLines->MinimumSize().iHeight;
       
  1893         vertModel.iThumbSpan = iSize.iHeight - iSize.iHeight % 2;
       
  1894         vertModel.iThumbPosition = Max( iPhysics->ViewTopY(), 0 );
       
  1895 
       
  1896         iExtension->iPreviousThumbPosition = vertModel.iThumbPosition;
       
  1897         TRAP_IGNORE(scrollBar->SetModelL(&vertModel)); // won't leave now, but can't guarantee forever        
       
  1898         iPageContainer->ScrollBar()->Tile(&vertModel);
       
  1899         iPageContainer->ScrollBar()->SetVFocusPosToThumbPos(vertModel.iThumbPosition);
       
  1900         }
       
  1901     }
       
  1902 
       
  1903 CCoeControl* CEikDialogPage::ComponentControl(TInt aIndex) const
       
  1904     {
       
  1905     if ( IsForm() && !iExtension->iHandlingResourceChange)
       
  1906         {
       
  1907         if ( iCurrentLine != -1 && !iExtension->iScrolling )
       
  1908             {
       
  1909             return (*iLines)[iCurrentLine];
       
  1910             }
       
  1911             
       
  1912         return NULL;
       
  1913         }
       
  1914         
       
  1915     // Ensure that the current line is the last control returned
       
  1916     if ( iCurrentLine != -1 )
       
  1917         {
       
  1918         if ( aIndex == CountComponentControls() -1 )
       
  1919             return ((*iLines)[iCurrentLine]);
       
  1920         else if ( aIndex < iCurrentLine )
       
  1921             return ((*iLines)[aIndex]);
       
  1922         else
       
  1923             return ((*iLines)[aIndex+1]);
       
  1924         }
       
  1925     else
       
  1926         return((*iLines)[aIndex]);
       
  1927     }
       
  1928 
       
  1929 TInt CEikDialogPage::CountComponentControls() const
       
  1930     {
       
  1931     if ( IsForm() && !iExtension->iHandlingResourceChange)
       
  1932         {
       
  1933         if ( iCurrentLine != -1 && !iExtension->iScrolling )
       
  1934             {
       
  1935             return 1;
       
  1936             }
       
  1937             
       
  1938         return 0;
       
  1939         }
       
  1940         
       
  1941     return iLines->Count();
       
  1942     }
       
  1943 
       
  1944 void CEikDialogPage::PrepareForFocusTransitionL()
       
  1945     {
       
  1946     if (iPageObserver)
       
  1947         iPageObserver->PrepareForFocusTransitionL();
       
  1948     }
       
  1949 
       
  1950 void CEikDialogPage::ReportPageChangedL()
       
  1951     {
       
  1952     if (iPageObserver)
       
  1953         iPageObserver->PageChangedL(PageId());
       
  1954     }
       
  1955 
       
  1956 void CEikDialogPage::LineChangedL(TInt aControlId)
       
  1957     {
       
  1958     if (iPageObserver)
       
  1959         iPageObserver->LineChangedL(aControlId);
       
  1960 // update scrollbar
       
  1961     UpdateScrollBarL();
       
  1962     PrepareToDrawVerticalLine();
       
  1963     }
       
  1964 
       
  1965 void CEikDialogPage::ShowFocus(TBool aFocus, TBool aRedraw)
       
  1966     {
       
  1967     if (iCurrentLine>=0)
       
  1968         {
       
  1969         if ( iExtension && iExtension->iUsesSingleClick && aFocus )
       
  1970             {
       
  1971             aFocus = HighlightVisible();
       
  1972             }
       
  1973         
       
  1974         (*iLines)[iCurrentLine]->SetCurrent(aFocus, aRedraw);
       
  1975 
       
  1976         if (aRedraw)
       
  1977             (*iLines)[iCurrentLine]->DrawNow();
       
  1978         else 
       
  1979             (*iLines)[iCurrentLine]->DrawDeferred(); 
       
  1980         }
       
  1981     }
       
  1982 
       
  1983 void CEikDialogPage::ChangeFocusTo(TInt aLineIndex)
       
  1984     {
       
  1985     TInt oldLine = iCurrentLine;
       
  1986     
       
  1987     if (aLineIndex==iCurrentLine)
       
  1988         return;
       
  1989     ShowFocus( EFalse, EFalse );
       
  1990     iCurrentLine=aLineIndex;
       
  1991     ShowFocus(ETrue, EFalse );
       
  1992 
       
  1993     if ( ( oldLine != iCurrentLine && IsForm() ) && 
       
  1994             iExtension->iInitialLayoutDone )
       
  1995         {
       
  1996         if ( oldLine != -1 )
       
  1997             {
       
  1998             iLines->MoveLineToScreen( oldLine, 0, EFalse );
       
  1999             RecordLineL( oldLine );
       
  2000             }
       
  2001 
       
  2002 		RecordLineL( iCurrentLine );
       
  2003 		iLines->MoveLineToScreen( iCurrentLine, iPhysics->ViewTopY(), ETrue );
       
  2004 		}
       
  2005     }
       
  2006 
       
  2007 TInt CEikDialogPage::FindLineIndex(const CCoeControl* aControl) const
       
  2008     {
       
  2009     return(iLines->FindLineIndex(aControl));
       
  2010     }
       
  2011 
       
  2012 /**
       
  2013  * Gets the list of logical colors employed in the drawing of the control,
       
  2014  * paired with an explanation of how they are used. Appends the list into aColorUseList.
       
  2015  */
       
  2016 void CEikDialogPage::GetColorUseListL(CArrayFix<TCoeColorUse>& aColorUseList) const
       
  2017     {
       
  2018     TCoeColorUse colorUse;
       
  2019     colorUse.SetLogicalColor(EColorDialogBackground);
       
  2020     colorUse.SetUse(TCoeColorUse::EBack|TCoeColorUse::ESurrounds|TCoeColorUse::EActive|TCoeColorUse::ENormal|TCoeColorUse::ENeutral);
       
  2021     aColorUseList.AppendL(colorUse);
       
  2022     }
       
  2023 
       
  2024 /**
       
  2025  * Handles a change to the control's resources of type aType
       
  2026  * which are shared across the environment, e.g. colors or fonts.
       
  2027  */
       
  2028 void CEikDialogPage::HandleResourceChange(TInt aType)
       
  2029     {
       
  2030     if ( aType==KEikDynamicLayoutVariantSwitch )
       
  2031         {
       
  2032         const TInt numLines=iLines->Count();
       
  2033         for ( TInt i=0; i < numLines; i++ )
       
  2034             {
       
  2035             CEikCaptionedControl* thisLine=(*iLines)[i];
       
  2036             thisLine->iControl->HandleResourceChange(aType);
       
  2037             }
       
  2038         }
       
  2039 
       
  2040     if ( aType != KEikDynamicLayoutVariantSwitch || !IsForm() )
       
  2041         {
       
  2042         iExtension->iHandlingResourceChange = ETrue;
       
  2043         CCoeControl::HandleResourceChange(aType);
       
  2044         iExtension->iHandlingResourceChange = EFalse;
       
  2045         }
       
  2046     
       
  2047 // Removed, because disables transparency
       
  2048     if (!CAknEnv::Static()->TransparencyEnabled() || 
       
  2049         (PageContainer()->PageSelector()->Dialg()->DialogFlags() & EEikDialogFlagFillAppClientRect ||
       
  2050         PageContainer()->PageSelector()->Dialg()->DialogFlags() & EEikDialogFlagFillScreen) )
       
  2051         {
       
  2052         Window().SetBackgroundColor(iEikonEnv->ControlColor(EColorDialogBackground,*this));
       
  2053         }
       
  2054 
       
  2055     if ( IsForm() )
       
  2056         {
       
  2057         switch ( aType )
       
  2058             {
       
  2059             case KEikDynamicLayoutVariantSwitch:
       
  2060                 for ( TInt i = 0; i  < iLines->Count(); ++i ) 
       
  2061                     {
       
  2062                     (*iLines)[i]->HandleResourceChange( KEikDynamicLayoutVariantSwitch );
       
  2063                     }
       
  2064                 
       
  2065                 ReconsiderPageSize();
       
  2066 
       
  2067                 if ( iCurrentLine != KErrNotFound )
       
  2068                     {
       
  2069                     if( iLastExposedLine != -1 )
       
  2070                         {
       
  2071                         iLastExposedLineViewWinYPosition = iLines->LineIndexToYPosition( iLastExposedLine, 0 );
       
  2072                         }
       
  2073 
       
  2074                     iExtension->iScrolling = EFalse;
       
  2075                     ExposeLine( iCurrentLine, ETrue );
       
  2076                     (*iLines)[iCurrentLine]->DrawNow();
       
  2077                     }
       
  2078                 
       
  2079                 DrawDeferred();
       
  2080                 break;
       
  2081 
       
  2082             case KAknsMessageSkinChange:
       
  2083                 ReconsiderPageSize();
       
  2084 
       
  2085                 if ( iCurrentLine != KErrNotFound )
       
  2086                     {
       
  2087                     ExposeLine( iCurrentLine, ETrue );
       
  2088                     }
       
  2089                 break;
       
  2090                 
       
  2091             case KAknMessageFocusLost:
       
  2092                 if ( !IsEditable() && iExtension && 
       
  2093                     iExtension->iUsesSingleClick && HighlightVisible() )
       
  2094                     {
       
  2095                     HighlightVisible( EFalse );
       
  2096                     
       
  2097                     CEikCaptionedControl* line = (*iLines)[iCurrentLine];
       
  2098             
       
  2099                     if ( line )
       
  2100                         {
       
  2101                         ShowFocus( EFalse, ETrue );
       
  2102                         }
       
  2103                     }
       
  2104                 break;
       
  2105 
       
  2106             default:
       
  2107                 break;
       
  2108             }
       
  2109         }
       
  2110     }
       
  2111 
       
  2112 CCoeControl* CEikDialogPage::Control(TInt aLineId) const
       
  2113     {
       
  2114     return(Line(aLineId)->iControl);
       
  2115     }
       
  2116 
       
  2117 CCoeControl* CEikDialogPage::ControlOrNull(TInt aLineId) const
       
  2118     {
       
  2119     TInt index=iLines->LineIndexFromId(aLineId);
       
  2120     if (index<0)
       
  2121         return(NULL);
       
  2122     return((*iLines)[index]->iControl);
       
  2123     }
       
  2124 
       
  2125 CEikCaptionedControl* CEikDialogPage::Line(TInt aLineId) const
       
  2126     {
       
  2127     CEikCaptionedControl* line=LineOrNull(aLineId);
       
  2128     if (line)
       
  2129         return line;
       
  2130 
       
  2131     ASSERT(EFalse); // Not found.
       
  2132     return NULL;
       
  2133     }
       
  2134 
       
  2135 CEikCaptionedControl* CEikDialogPage::LineOrNull(TInt aLineId) const
       
  2136     {
       
  2137     TInt index=iLines->LineIndexFromId(aLineId);
       
  2138     if (index<0)
       
  2139         return NULL;    // Not found.
       
  2140     return((*iLines)[index]);
       
  2141     }
       
  2142 
       
  2143 CEikCaptionedControl* CEikDialogPage::CurrentLine() const
       
  2144     {
       
  2145     if (iCurrentLine>=0)
       
  2146         return (*iLines)[iCurrentLine];
       
  2147 
       
  2148     return NULL;
       
  2149     }
       
  2150 
       
  2151 void CEikDialogPage::FocusChanged(TDrawNow /*aDrawNow*/)
       
  2152     {
       
  2153     if (iCurrentLine>=0 && !IsFocused())
       
  2154         {
       
  2155         CEikCaptionedControl* currentLine=(*iLines)[iCurrentLine];
       
  2156         currentLine->SetCurrent(EFalse);
       
  2157         }
       
  2158     }
       
  2159 
       
  2160 void CEikDialogPage::ResetLineMinimumSizes()
       
  2161     {
       
  2162     iLines->ResetMinimumSizes();
       
  2163     }
       
  2164 
       
  2165 TKeyResponse CEikDialogPage::OfferHotKeysKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
       
  2166     {
       
  2167 /* 
       
  2168 Changed from offering the hot key to every control on the page in order of appearance, until 
       
  2169 someone accepts the hotkey, to only offering the hot key to the current line and then, only if 
       
  2170 it accepts hotkeys.
       
  2171 
       
  2172   Added Enter key as a special case... 
       
  2173 */
       
  2174     if ( (iCurrentLine!=-1) && (iCurrentLine < iLines->Count()) )
       
  2175         if ( (*iLines)[iCurrentLine]->OfferHotKeys() ||
       
  2176             (*iLines)[iCurrentLine]->TakesEnterKey() && (aKeyEvent.iCode==EKeyEnter)
       
  2177             )
       
  2178             if (!IsForm()|| iIsEditable)
       
  2179                 return (*iLines)[iCurrentLine]->iControl->OfferKeyEventL(aKeyEvent,aType);
       
  2180     return EKeyWasNotConsumed;
       
  2181     }
       
  2182 
       
  2183 TBool CEikDialogPage::TakesEnterKey()
       
  2184     {
       
  2185     if (iCurrentLine<0)
       
  2186         return EFalse;
       
  2187     return (*iLines)[iCurrentLine]->TakesEnterKey();
       
  2188     }
       
  2189 
       
  2190 void CEikDialogPage::SetEditableL( TBool aEditable, TBool /*aActivePage*/ ) 
       
  2191     {
       
  2192     // Tell each of the controls on the page (which are part of a form) of their editable state.  
       
  2193 
       
  2194     iIsEditable = aEditable;
       
  2195 
       
  2196     HighlightVisible( aEditable );
       
  2197     
       
  2198     if ( iExtension->iUsesSingleClick && iExtension->iSetInitialFocusDone )
       
  2199         {
       
  2200         ShowFocus( EFalse );
       
  2201         }
       
  2202     
       
  2203     const TInt numLines=iLines->Count() ;
       
  2204 /* if a form, no currently selected line, in edit mode,  and there is a line 
       
  2205 available (we know this as iLines->Count()>0), then select the first line.
       
  2206 */
       
  2207     if ((iFormControl) && (iCurrentLine==-1) && 
       
  2208         (aEditable) && (iLines->Count()>0))
       
  2209         iCurrentLine=0;
       
  2210     for ( TInt ii = 0 ; ii < numLines ; ii++ )
       
  2211         {
       
  2212         if ( (*iLines)[ii]->iIsFormControl  )
       
  2213             {
       
  2214             (*iLines)[ii]->SetEditableL( aEditable,  !( iFormFlags & EEikFormHideEmptyFields ) ) ;
       
  2215             CEikCaptionedControl* theLine =  (*iLines)[ii];
       
  2216             if (theLine->ControlIsAnEdwin(theLine->iControlType))
       
  2217                 { 
       
  2218 /* 
       
  2219 Set the edwin out to have the correct width, but
       
  2220   @ Make the line invisible, to prevent redraws.
       
  2221   @ stop any edwin resize events being acted on (done by iIgnoreFurtherEdwinResizeEvents)
       
  2222 */
       
  2223                 iIgnoreFurtherEdwinResizeEvents=STATIC_CAST(CEikEdwin*,theLine->iControl);
       
  2224                 theLine->MakeVisible(EFalse);
       
  2225                 theLine->PositionFormComponents();
       
  2226                 theLine->MakeVisible(ETrue);
       
  2227                 iIgnoreFurtherEdwinResizeEvents=0;
       
  2228                 if (aEditable)
       
  2229                     {
       
  2230 /* 
       
  2231 Set the cursor position correctly for each edwin
       
  2232 @ if it's before the current line, set it to the end of the edwin
       
  2233 @ if it is or is after the current line, set it to the start of the edwin
       
  2234 */
       
  2235                     CEikEdwin* edwinPtr = STATIC_CAST(CEikEdwin*,theLine->iControl);
       
  2236                     //filter enterkay.
       
  2237                     //edwinPtr->AddFlagToUserFlags(CEikEdwin::ENoLineOrParaBreaks);
       
  2238                     if (ii<=iCurrentLine)
       
  2239                         edwinPtr->SetCursorPosL(edwinPtr->TextLength(),EFalse);
       
  2240                     else
       
  2241                         edwinPtr->SetCursorPosL(0,EFalse);
       
  2242                     }
       
  2243                 }           
       
  2244             }
       
  2245         }
       
  2246 /* 
       
  2247 if changing to view mode, 
       
  2248 and the currentline is now non-focussing (invisible)
       
  2249 Then set iCurrentLine to the top focusable control
       
  2250 */
       
  2251     if ((iFormControl)&&(!aEditable)&&(iCurrentLine!=-1))
       
  2252         {
       
  2253         CEikCaptionedControl* line = (*iLines)[iCurrentLine];
       
  2254         if (line->IsNonFocusing())
       
  2255             {
       
  2256 // break the news to the old focussed line.
       
  2257             ShowFocus(EFalse, EFalse);
       
  2258 // now set the new currentline value.
       
  2259             iCurrentLine=TopFocusableLine();
       
  2260             }
       
  2261         }
       
  2262 
       
  2263     if ( ( iCurrentLine >= 0 ) && ( (*iLines)[iCurrentLine]->iIsFormControl ) )
       
  2264         (*iLines)[iCurrentLine]->SetCurrent( ETrue ) ;
       
  2265     
       
  2266     ReconsiderPageSize();
       
  2267 
       
  2268     if ((iLines->Count()>0) && (iCurrentLine >= 0))
       
  2269         {
       
  2270         ExposeLine(iCurrentLine,ETrue); 
       
  2271         }
       
  2272   }
       
  2273 
       
  2274 TBool CEikDialogPage::AnythingToDisplay() const
       
  2275     {
       
  2276     // assume Form control... shouldnt be called otherwise (Panic?)
       
  2277     for (TInt i=0;i<iLines->Count();i++)
       
  2278         {
       
  2279         if ((*iLines)[i]->IsDisplayable())
       
  2280             {
       
  2281             return ETrue;
       
  2282             };
       
  2283         }
       
  2284 
       
  2285     return EFalse;
       
  2286     }
       
  2287 
       
  2288 // <SKIN> New function (Averell 2) to permit skinning the No Data screen.  New AknDrawWithSkins() utility requires 'this'
       
  2289 void CEikDialogPage::DrawEmptyListL( CWindowGc& aGc ) 
       
  2290     {
       
  2291      HBufC* dataBuffer=0;
       
  2292     dataBuffer=iEikonEnv->AllocReadResourceLC(R_AVKON_NO_DATA );
       
  2293     AknDrawWithSkins::DrawEmptyList(TRect(TPoint(1,7),TPoint(177,135)),aGc,*dataBuffer, this );
       
  2294     CleanupStack::PopAndDestroy(); // finished with current val of dataBuffer 
       
  2295     }
       
  2296 
       
  2297 void CEikDialogPage::Draw(const TRect& /*aRect*/) const
       
  2298     {
       
  2299     if ( iFormControl )
       
  2300         {
       
  2301         // added this to see if anything on the page is visible.
       
  2302         // if not, this is used to display the No data found screen.
       
  2303         TBool anythingToShow= AnythingToDisplay();
       
  2304     
       
  2305         CWindowGc& windowGcRef = SystemGc(); // needed for DrawEmptyList
       
  2306 
       
  2307         if (!anythingToShow)
       
  2308             {
       
  2309             // Have to call non const leaving function...  Ignore the TRAP as result is cosmetic only.
       
  2310             TRAP_IGNORE( const_cast<CEikDialogPage*>(this)->DrawEmptyListL( windowGcRef ) ) ;
       
  2311             }
       
  2312         else
       
  2313             DrawVerticalLine();
       
  2314         
       
  2315         
       
  2316         if ( IsForm() )
       
  2317             {
       
  2318             TInt delta = iPhysics->ViewCenter().iY;
       
  2319             delta -= iPhysics->ViewCenterDistance();
       
  2320             TInt topY = delta;
       
  2321             delta *= -1;
       
  2322             
       
  2323             TAknLayoutRect formtLayoutRect;
       
  2324             formtLayoutRect.LayoutRect(Rect(), AknLayoutScalable_Avkon::listscroll_form_pane().LayoutLine());
       
  2325             formtLayoutRect.LayoutRect(formtLayoutRect.Rect(), AknLayoutScalable_Avkon::list_form_gen_pane().LayoutLine());
       
  2326 
       
  2327 
       
  2328             TRect targetRect( formtLayoutRect.Rect() );
       
  2329             targetRect.iBr.iY = topY + targetRect.Height();
       
  2330             targetRect.iTl.iY = topY;
       
  2331 
       
  2332             TInt lineToSkip = -1;
       
  2333             
       
  2334             if ( !iExtension->iScrolling )
       
  2335                 {
       
  2336                 lineToSkip = iCurrentLine;
       
  2337                 }
       
  2338             
       
  2339             iExtension->iRecordingGc->FlushBuffer( targetRect, lineToSkip );
       
  2340             }
       
  2341         }
       
  2342     }
       
  2343 
       
  2344 void CEikDialogPage::AfterAddingNewLinesL(TInt aNewLineAdded)
       
  2345     {
       
  2346 /**
       
  2347 * void CEikDialogPage::AfterAddingNewLinesL(TInt aNewLineAdded)
       
  2348 * 
       
  2349 * Context : Every time a line is added, this should be called
       
  2350 *
       
  2351 * Function:
       
  2352 *   It is used to :
       
  2353 *   #1 register the the dialog page with the caption control.
       
  2354 *   #2 register the control on this line (e.g. an edwin) with the one above it 
       
  2355 *   #3 call Register component on the line, to set up listeners, etc.
       
  2356 *   #4 Set the editable value to whatever the dialog page's editable value is.
       
  2357 */
       
  2358     __ASSERT_DEBUG(iLines && (aNewLineAdded<=iLines->Count()), Panic(EEikDialogPanicErrorDuringAddingLine));
       
  2359     if (aNewLineAdded== -1)
       
  2360         return; // line has not been added yet.
       
  2361     CEikCaptionedControl* lineAdded = iLines->At(aNewLineAdded);
       
  2362 // if aNewLineAdded is zero, then there is no line above, else set value.
       
  2363     CEikCaptionedControl* lineVisuallyAboveAndNumericallyBelow = 
       
  2364                         (!aNewLineAdded)? 0:iLines->At(aNewLineAdded-1);
       
  2365     // #1
       
  2366     lineAdded->RegisterPageWithCaptionControl(this);
       
  2367     // #2
       
  2368     if (lineVisuallyAboveAndNumericallyBelow && iLines->At(aNewLineAdded)->iControl) 
       
  2369         // there is a line above this one and it has a control 
       
  2370         lineAdded->iControl->SetNeighbor(lineVisuallyAboveAndNumericallyBelow->iControl);
       
  2371     // #3
       
  2372     RegisterComponentL(lineAdded->iControlType, lineAdded->iControl, lineAdded); 
       
  2373     // #4
       
  2374     lineAdded->SetEditableL(iIsEditable);
       
  2375 
       
  2376     // The next is needed or phonebook's  "add field" / date will not work correctly.
       
  2377     if (IsActivated())
       
  2378         {
       
  2379         DrawDeferred();
       
  2380         }
       
  2381 
       
  2382     if (iFormControl)
       
  2383         {
       
  2384         lineAdded->SetPictographCallBack();
       
  2385         }
       
  2386 
       
  2387     if ( IsForm() )
       
  2388         {
       
  2389         if ( aNewLineAdded < ( iLines->Count() - 1 ) )
       
  2390             {
       
  2391             // new line was added as the last line
       
  2392             iExtension->iRecordingGc->InsertLineL( aNewLineAdded );
       
  2393             }
       
  2394         else
       
  2395             {
       
  2396             // new line was inserted between existing line
       
  2397             iExtension->iRecordingGc->AppendLineL();
       
  2398             }
       
  2399         }
       
  2400 
       
  2401     ExposeLine( aNewLineAdded, EFalse );
       
  2402 
       
  2403     if ( IsForm() && iSize.iHeight != 0 && aNewLineAdded != -1 )
       
  2404         iLines->MoveLineToScreen( aNewLineAdded, iPhysics->ViewTopY(), EFalse );
       
  2405     }
       
  2406 
       
  2407 TInt CEikDialogPage::GetFormFlags() const
       
  2408     {return iFormFlags;};
       
  2409 
       
  2410 void CEikDialogPage::SetFormFlag( TInt16 aFlag, TBool aEnable ) 
       
  2411     {
       
  2412     if ( aFlag >= EFormResizeOptimisationFlag ) // Dynamic Flags only - static flags are unaffected.
       
  2413         {
       
  2414         if ( aEnable )
       
  2415             iFormFlags |= aFlag ;
       
  2416         else if ( !aEnable )
       
  2417             iFormFlags &= (~aFlag) ;
       
  2418         }
       
  2419     }
       
  2420 
       
  2421 CEikCaptionedControl* CEikDialogPage::LineOnPageOrNull(TInt aLine) const
       
  2422     {
       
  2423     if (iLines) // if iLines, and there are enough lines on the page
       
  2424         if (iLines->Count() > aLine)
       
  2425             return (*iLines)[aLine];
       
  2426     return 0;
       
  2427     }
       
  2428 
       
  2429 void CEikDialogPage::RegisterComponentL(TInt aControlType, CCoeControl* aControl, CEikCaptionedControl* aLine)
       
  2430     {
       
  2431 /*
       
  2432  Private method to deal with registering components with forms/dialogs correctly so that
       
  2433  observers, etc are created.
       
  2434  */
       
  2435     if ( aControl && aLine->ControlIsAnEdwin( aControlType ) )
       
  2436         {
       
  2437         CEikEdwin* edwin=STATIC_CAST(CEikEdwin*,aControl);
       
  2438         edwin->SetEdwinSizeObserver( this );
       
  2439         edwin->SetEdwinObserver( this ) ;
       
  2440         // Pre-empt the growth of Edwin.  It mustn't get any bigger.
       
  2441         if ( !iFormControl )
       
  2442             {
       
  2443             edwin->SetMaximumHeight( iSize.iHeight );
       
  2444             }
       
  2445         }
       
  2446     if (aControl && 
       
  2447         ( aControlType==EAknCtPopupField || aControlType==EAknCtPopupFieldText))
       
  2448         {
       
  2449         CAknPopupField* popupField=0;
       
  2450         if (aControlType==EAknCtPopupField)
       
  2451             popupField = (CAknPopupField*)aControl ;
       
  2452         else 
       
  2453             popupField = (CAknPopupFieldText*)aControl ;
       
  2454         popupField->SetPopupFieldObserver(this);
       
  2455         popupField->SetMaxNumberOfLinesPermitted(aLine->MaximumNumberOfControlLinesOnVisiblePage());
       
  2456         }
       
  2457     if ( aControl && aLine->ControlIsAMfne( aControlType ) )
       
  2458         {
       
  2459         aControl->SetObserver( this );
       
  2460         }
       
  2461     if ( iFormControl )
       
  2462         {
       
  2463         // Tell the line that it is on a form - activate it to enable it draw its highlight box
       
  2464         aLine->iIsFormControl = iFormControl ;
       
  2465         if ( iFormFlags )
       
  2466             aLine->SetFormFlags( iFormFlags ) ;
       
  2467 
       
  2468         aLine->GetAknLayoutValuesL() ;  // should cause the control to have size.
       
  2469         }
       
  2470     };
       
  2471 
       
  2472 
       
  2473 void CEikDialogPage::SetPageContainer(const CEikDialogPageContainer* aPageContainer)
       
  2474     {
       
  2475     iPageContainer=aPageContainer;
       
  2476     }
       
  2477 
       
  2478 const CEikDialogPageContainer* CEikDialogPage::PageContainer() const
       
  2479     {
       
  2480     return iPageContainer;
       
  2481     }
       
  2482 
       
  2483 void CEikDialogPage::ReconsiderPageSize()
       
  2484     {
       
  2485     if ( !Rect().IsEmpty() )
       
  2486         {
       
  2487         iLines->SetRect( Rect(), iScroll->Top(), iScroll->Middle(), iScroll->Bottom() );
       
  2488         }
       
  2489     }
       
  2490 
       
  2491 EXPORT_C void CEikDialogPage::SetFormLayout(TFormLayoutSelection aLayout)
       
  2492     {
       
  2493     __ASSERT_DEBUG(iFormControl , Panic(EEikFormPanicSettingDoublePageFormLayoutOnNonForm));
       
  2494     iFormLayout=aLayout;    
       
  2495     };
       
  2496 
       
  2497 EXPORT_C CEikDialogPage::TFormLayoutSelection CEikDialogPage::FormLayout() const
       
  2498     {
       
  2499     return iFormLayout;
       
  2500     }
       
  2501 
       
  2502 TBool CEikDialogPage::IsEditable() const
       
  2503     {
       
  2504     return iIsEditable;
       
  2505     }
       
  2506 
       
  2507 TBool CEikDialogPage::IsForm() const
       
  2508     {
       
  2509     return iFormControl;
       
  2510     }
       
  2511 
       
  2512 void CEikDialogPage::SetDoubleQuery(TBool aIsDoubleQuery)
       
  2513     {   
       
  2514     iExtension->iIsDoubleQuery = aIsDoubleQuery;    
       
  2515     }
       
  2516 
       
  2517 CEikFormAnim* CEikDialogPage::AcquireAnim(
       
  2518     TBool aAcquire, MEikFormAnimObserver* aObserver ) const
       
  2519     {
       
  2520     if( iPageContainer )
       
  2521         return iPageContainer->AcquireAnim( aAcquire, aObserver );
       
  2522 
       
  2523     return NULL;
       
  2524     }
       
  2525 
       
  2526 TBool CEikDialogPage::IsAtOrOffTopOfPage(const CCoeControl* aControl) const
       
  2527     {
       
  2528     if (!iLines||!aControl)
       
  2529         return EFalse;
       
  2530     TInt lineIndex = FindLineIndex(aControl);
       
  2531     if (lineIndex==-1)
       
  2532         return EFalse;
       
  2533     CEikCaptionedControl* capCtrl =(*iLines)[lineIndex];
       
  2534     if (!capCtrl)
       
  2535         return EFalse;
       
  2536     if (capCtrl->Rect().iTl.iY<=0 )
       
  2537         return ETrue;
       
  2538     else
       
  2539         return EFalse;
       
  2540     }
       
  2541 
       
  2542 TBool CEikDialogPage::IsAtOrOffBottomOfPage(const CCoeControl* aControl) const
       
  2543     {
       
  2544     if (!iLines|| !aControl)
       
  2545         return EFalse;
       
  2546     TInt lineIndex = FindLineIndex(aControl);
       
  2547     if (lineIndex==-1)
       
  2548         return EFalse;
       
  2549     CEikCaptionedControl* capCtrl =(*iLines)[lineIndex];
       
  2550     if (!capCtrl)
       
  2551         return EFalse;
       
  2552     if (capCtrl->Rect().iBr.iY>=(iSize.iHeight))
       
  2553         return ETrue;
       
  2554     else
       
  2555         return EFalse;
       
  2556     
       
  2557     }
       
  2558 
       
  2559 /* 
       
  2560 return True if off the top
       
  2561 return False if off the top
       
  2562 */
       
  2563 
       
  2564 TBool CEikDialogPage::VisibleSizeOnPage(TInt& aHeightOfControlVisibleOnPage, const CCoeControl* aControl) const
       
  2565     {
       
  2566     if (!iLines|| !aControl)
       
  2567         {
       
  2568         aHeightOfControlVisibleOnPage=0;
       
  2569         return EFalse;
       
  2570         }
       
  2571     TInt lineIndex = FindLineIndex(aControl);
       
  2572     if (lineIndex==-1)
       
  2573         {
       
  2574         aHeightOfControlVisibleOnPage=0;
       
  2575         return EFalse;
       
  2576         }
       
  2577     CEikCaptionedControl* capCtrl =(*iLines)[lineIndex];
       
  2578     aHeightOfControlVisibleOnPage=capCtrl->Rect().Height();
       
  2579     return EFalse;
       
  2580     }
       
  2581 
       
  2582 TSize CEikDialogPage::RealDataSize() const
       
  2583     {
       
  2584     if (iLines)
       
  2585         if (iLines->Count()>0)
       
  2586             return TRect((*iLines)[0]->Rect().iTl,(*iLines)[iLines->Count()-1]->Rect().iBr).Size();
       
  2587     return iSize;
       
  2588     }
       
  2589 
       
  2590 TInt CEikDialogPage::NumberOfLines() const
       
  2591     {
       
  2592     if (iLines)
       
  2593         return iLines->Count();
       
  2594     return 0;
       
  2595     }
       
  2596 
       
  2597 CEikCaptionedControl* CEikDialogPage::LineByIndex(TInt aIndex) const
       
  2598     {
       
  2599     if (iLines->Count() > aIndex && aIndex>=0)
       
  2600         return (*iLines)[aIndex];
       
  2601     return 0;
       
  2602     }
       
  2603 
       
  2604 EXPORT_C void* CEikDialogPage::ExtensionInterface( TUid /*aInterface*/ )
       
  2605     {
       
  2606     return NULL;
       
  2607     }   
       
  2608 
       
  2609 // ---------------------------------------------------------------------------
       
  2610 // CEikDialogPage::HandleFormPointerEventL
       
  2611 // ---------------------------------------------------------------------------
       
  2612 //
       
  2613 void CEikDialogPage::HandleFormPointerEventL( const TPointerEvent& aPointerEvent )
       
  2614     {
       
  2615     if ( LineHandlerCalled() )
       
  2616         {
       
  2617         return;
       
  2618         }
       
  2619     
       
  2620     TInt touchedLine = iLines->YPositionToLineIndex( aPointerEvent.iPosition.iY + iPhysics->ViewTopY() );
       
  2621     TBool callDefaultImplementation = ETrue;
       
  2622     
       
  2623     // Tapping form's empty area takes no action of any kind. Also bounce
       
  2624     // effect can't be stopped.
       
  2625     if ( ( aPointerEvent.iType == TPointerEvent::EButton1Down && touchedLine == KErrNotFound ) || !iPhysics->CanBeStopped() )
       
  2626         {
       
  2627         IgnoreEventsUntilNextPointerUp();
       
  2628         return;
       
  2629         }
       
  2630 
       
  2631     CEikCaptionedControl* newLine = NULL;
       
  2632     TInt controlType = KErrNotFound;
       
  2633 
       
  2634     if ( touchedLine != KErrNotFound )
       
  2635         {
       
  2636         newLine = (*iLines)[touchedLine];
       
  2637         controlType = newLine->iControlType;
       
  2638         }
       
  2639 
       
  2640     TBool textSelected = EFalse;
       
  2641 
       
  2642     if ( touchedLine != iCurrentLine && newLine && 
       
  2643             !iExtension->iUsesSingleClick )
       
  2644         {
       
  2645         if ( !newLine->ControlIsAPopfield( controlType ) )
       
  2646             {
       
  2647             callDefaultImplementation = EFalse;
       
  2648             }
       
  2649         }
       
  2650 
       
  2651     if ( iCurrentLine != -1 && iCurrentLine == iExtension->iLastTouchedLine )
       
  2652         {
       
  2653         CEikCaptionedControl* currentLine = (*iLines)[iCurrentLine];
       
  2654         
       
  2655         if ( currentLine->ControlIsAnEdwin( currentLine->iControlType ) )
       
  2656             {
       
  2657             CEikEdwin* edwin = static_cast<CEikEdwin*>( currentLine->iControl );
       
  2658             textSelected = edwin->SelectionLength();
       
  2659             
       
  2660             if ( textSelected == edwin->TextLength() )
       
  2661                 {
       
  2662                 textSelected = EFalse;
       
  2663                 }
       
  2664             }
       
  2665         }
       
  2666         
       
  2667     if ( aPointerEvent.iType == TPointerEvent::EButton1Down && touchedLine != KErrNotFound )
       
  2668         {
       
  2669         iExtension->iOldCenterY = iPhysics->ViewCenter().iY;
       
  2670         TInt bottom = iExtension->iOldCenterY + iSize.iHeight - iSize.iHeight / 2;
       
  2671         if ( bottom < 0 )
       
  2672             {
       
  2673             iExtension->iBottomItem = -1;
       
  2674             }
       
  2675         else
       
  2676             {
       
  2677             iExtension->iBottomItem = bottom / (*iLines)[0]->Size().iHeight;
       
  2678             if ( iExtension->iBottomItem > iLines->Count() )
       
  2679                 {
       
  2680                 iExtension->iBottomItem = iLines->Count();
       
  2681                 }
       
  2682             }
       
  2683         TInt upper = iExtension->iOldCenterY - iSize.iHeight / 2;
       
  2684         if ( upper <= 0 )
       
  2685             {
       
  2686             iExtension->iTopItem = -1;
       
  2687             }
       
  2688         else
       
  2689             {
       
  2690             iExtension->iTopItem = upper / (*iLines)[0]->Size().iHeight;
       
  2691             if ( iExtension->iTopItem > iLines->Count() )
       
  2692                 {
       
  2693                 iExtension->iTopItem = iLines->Count();
       
  2694                 }
       
  2695             }
       
  2696         iExtension->iScrolling = EFalse;
       
  2697         iExtension->HandleFormFeedback( this, aPointerEvent, touchedLine, iCurrentLine );
       
  2698         
       
  2699         TBool wasScrolling = ( iPhysics->OngoingPhysicsAction() != 
       
  2700             CAknPhysics::EAknPhysicsActionNone );
       
  2701         iPhysics->Stop();
       
  2702         iExtension->iLastTouchedLine = touchedLine;
       
  2703         iExtension->iDragStartPosition = aPointerEvent.iPosition;
       
  2704         iExtension->iLastPointerPos = aPointerEvent.iPosition;
       
  2705         iExtension->iStartTime.HomeTime();
       
  2706 
       
  2707         if ( touchedLine != iCurrentLine )
       
  2708             {
       
  2709             iExtension->iFocusedClicked = EFalse;
       
  2710 
       
  2711             if ( iExtension->iUsesSingleClick )
       
  2712                 {
       
  2713                 if ( !wasScrolling )
       
  2714                     {
       
  2715                     HighlightVisible( ETrue );
       
  2716                     HighlightTimerCallBack( this );
       
  2717                     }
       
  2718                 }
       
  2719             else
       
  2720                 {
       
  2721                 iExtension->iHighlightTimer->Cancel();
       
  2722                 iExtension->iHighlightTimer->Start( 
       
  2723                     TTimeIntervalMicroSeconds32( iPhysics->HighlightDelay() * 1000 ),
       
  2724                     TTimeIntervalMicroSeconds32( iPhysics->HighlightDelay() * 1000 ),
       
  2725                     TCallBack( HighlightTimerCallBack, this ) );
       
  2726                 }
       
  2727             }
       
  2728         else
       
  2729             {
       
  2730             iExtension->iFocusedClicked = ETrue;
       
  2731             
       
  2732             if ( !IsEditable() && iExtension->iUsesSingleClick )
       
  2733                 {
       
  2734                 CEikCaptionedControl* currentLine = (*iLines)[iCurrentLine];
       
  2735                 
       
  2736                 if ( currentLine )
       
  2737                     {
       
  2738                     HighlightVisible( ETrue );
       
  2739                     ShowFocus( ETrue, ETrue );
       
  2740                     }
       
  2741                 }
       
  2742             }
       
  2743         }
       
  2744 
       
  2745     if ( aPointerEvent.iType == TPointerEvent::EDrag )
       
  2746         {
       
  2747         TPoint drag( iExtension->iDragStartPosition - aPointerEvent.iPosition );
       
  2748         
       
  2749         if ( Abs( drag.iY ) > iPhysics->DragThreshold() )
       
  2750             {
       
  2751             iExtension->iHighlightTimer->Cancel();
       
  2752 
       
  2753             if ( !iExtension->iScrolling && !textSelected )
       
  2754                 {
       
  2755                 if ( !IsEditable() && iExtension->iUsesSingleClick && 
       
  2756                      HighlightVisible() )
       
  2757                     {
       
  2758                     HighlightVisible( EFalse );
       
  2759                     
       
  2760                     CEikCaptionedControl* currentLine = (*iLines)[iCurrentLine];
       
  2761                     
       
  2762                     if ( currentLine )
       
  2763                         {
       
  2764                         ShowFocus( EFalse, ETrue );
       
  2765                         }
       
  2766                     }
       
  2767 
       
  2768                 iExtension->iScrolling = ETrue;
       
  2769                 iExtension->iScrolled = ETrue;
       
  2770                 iExtension->iLastPointerPos = aPointerEvent.iPosition;
       
  2771                 RemovePressedDownHighlight();
       
  2772                 iLines->MoveLineToScreen( iCurrentLine, 0, EFalse );
       
  2773                 callDefaultImplementation = EFalse;
       
  2774                 }
       
  2775             }
       
  2776 
       
  2777         if ( iExtension->iScrolling )
       
  2778             {
       
  2779             iPhysics->SetPanningPosition( 
       
  2780                 TPoint( 0, iExtension->iLastPointerPos.iY - aPointerEvent.iPosition.iY ) );
       
  2781             iExtension->iLastPointerPos = aPointerEvent.iPosition;
       
  2782             }
       
  2783         //For secret editor display
       
  2784         CEikCaptionedControl* currentLine=(*iLines)[iCurrentLine];
       
  2785         if( currentLine->ControlIsASecretEditor(currentLine->iControlType) )
       
  2786             {
       
  2787             CEikSecretEditor* edwin=(CEikSecretEditor*)currentLine->iControl;
       
  2788             edwin->EnableCursor( EFalse );
       
  2789             }
       
  2790         }                                
       
  2791     
       
  2792     if ( aPointerEvent.iType == TPointerEvent::EButton1Up )
       
  2793         {
       
  2794         iExtension->HandleFormFeedback( this, aPointerEvent, touchedLine, iCurrentLine );
       
  2795         if ( !IsEditable() && iExtension->iUsesSingleClick && 
       
  2796              HighlightVisible() )
       
  2797             {
       
  2798             HighlightVisible( EFalse );
       
  2799             
       
  2800             CEikCaptionedControl* currentLine = (*iLines)[iCurrentLine];
       
  2801 
       
  2802             if ( currentLine )
       
  2803                 {
       
  2804                 ShowFocus( EFalse, ETrue );
       
  2805                 }
       
  2806             }
       
  2807 
       
  2808         TPoint drag( iExtension->iDragStartPosition - aPointerEvent.iPosition );
       
  2809         
       
  2810         if ( !textSelected )
       
  2811             {
       
  2812             if ( !iPhysics->StartFlick( drag, iExtension->iStartTime ) )
       
  2813                 {
       
  2814                 iExtension->iScrolling = EFalse;
       
  2815                 
       
  2816                 if ( iPageObserver && GrabbingComponent() )
       
  2817                     {
       
  2818                     iPageObserver->HandleDialogPageEventL( MEikDialogPageObserver::EDialogPageTapped );
       
  2819                     }
       
  2820                 }
       
  2821             else 
       
  2822                 {
       
  2823                 callDefaultImplementation = EFalse;
       
  2824                 
       
  2825                 if ( !iExtension->iScrolling )
       
  2826                     {
       
  2827                     // feedback is given every time when new item 
       
  2828                     // appears to the screen -> follows the visual feedback
       
  2829                     iExtension->SilentFeedback( this, ETouchFeedbackSensitiveList, aPointerEvent );
       
  2830                     // It might happen that there are no drag events between down and
       
  2831                     // up if the distance is short enough.
       
  2832                     iExtension->iHighlightTimer->Cancel();
       
  2833                     iExtension->iScrolling = ETrue;
       
  2834                     iExtension->iScrolled = ETrue;
       
  2835                     iLines->MoveLineToScreen( iCurrentLine, 0, EFalse );
       
  2836                     RemovePressedDownHighlight();
       
  2837                     }
       
  2838                 }
       
  2839             }
       
  2840         }
       
  2841 
       
  2842     // forward pointer event to line's observer
       
  2843     if ( touchedLine == iCurrentLine && newLine && 
       
  2844             ( iExtension->iFocusedClicked || 
       
  2845             ( !IsEditable() && iExtension->iUsesSingleClick ) ) && 
       
  2846             !iExtension->iScrolling )
       
  2847         {
       
  2848         MPointerEventObserver* observer = newLine->PointerEventObserver();
       
  2849         
       
  2850         if ( observer )
       
  2851             {
       
  2852             iExtension->iFlags.Set( CDialogPageExtension::ELineHandlerCalled );
       
  2853             observer->PointerEvent( newLine, aPointerEvent );
       
  2854             iExtension->iFlags.Clear( CDialogPageExtension::ELineHandlerCalled );
       
  2855             }
       
  2856         }
       
  2857     
       
  2858     TBool mskPress = EFalse;
       
  2859 
       
  2860     // If the stylus is up above already focused line - emulate an MSK press
       
  2861     if ( iFormControl && !iIsEditable && // in view mode
       
  2862         aPointerEvent.iType == TPointerEvent::EButton1Up &&
       
  2863         touchedLine == iCurrentLine &&
       
  2864         ( iExtension->iFocusedClicked || iExtension->iUsesSingleClick ) &&
       
  2865         !iExtension->iScrolling )
       
  2866         {
       
  2867         mskPress = ETrue;
       
  2868         callDefaultImplementation = EFalse;
       
  2869         }
       
  2870     
       
  2871     if ( callDefaultImplementation && ( iExtension->iFocusedClicked || 
       
  2872             iExtension->iUsesSingleClick ) && newLine )
       
  2873         {
       
  2874         if ( newLine->ControlIsAPopfield( controlType ) )
       
  2875             {
       
  2876             if(aPointerEvent.iType == TPointerEvent::EButton1Down)
       
  2877                 {
       
  2878             	newLine->HandlePointerEventL(aPointerEvent);
       
  2879             	iExtension->iCapturingItem = touchedLine;       
       
  2880                 }
       
  2881             else if(aPointerEvent.iType == TPointerEvent::EButton1Up)
       
  2882                 {
       
  2883                 newLine->HandlePointerEventL(aPointerEvent);  
       
  2884                 }
       
  2885             }
       
  2886         else
       
  2887             {            
       
  2888             CCoeControl::HandlePointerEventL( aPointerEvent );
       
  2889             }
       
  2890          }
       
  2891          
       
  2892     if ( mskPress )
       
  2893         {
       
  2894         TKeyEvent key;
       
  2895         key.iCode=EKeyOK;
       
  2896         key.iModifiers=0;
       
  2897         key.iRepeats = 0;
       
  2898         CEikonEnv::Static()->SimulateKeyEventL( key, EEventKey );
       
  2899         }
       
  2900     }
       
  2901 
       
  2902 
       
  2903 // ---------------------------------------------------------------------------
       
  2904 // CEikDialogPage::UpdatePhysics
       
  2905 // ---------------------------------------------------------------------------
       
  2906 //
       
  2907 void CEikDialogPage::UpdatePhysics()
       
  2908     {
       
  2909     if ( IsForm() )
       
  2910         {
       
  2911         TPoint viewCenter( iSize.iWidth / 2, 0 );
       
  2912         
       
  2913         if ( iLines->Count() > 0 )
       
  2914             {
       
  2915             viewCenter.iY = Abs( (*iLines)[0]->Rect().iTl.iY - iPosition.iY );
       
  2916             }
       
  2917             
       
  2918         viewCenter.iY += iPhysics->ViewCenterDistance();
       
  2919         
       
  2920         if ( iExtension->iInitialLayoutDone )
       
  2921             {
       
  2922             TInt oldScreenHeight = iPhysics->ViewSize().iHeight;
       
  2923             TInt delta = ( iPhysics->ViewCenterDistance() ) - 
       
  2924                 ( oldScreenHeight / 2 );
       
  2925 
       
  2926             viewCenter = iPhysics->ViewCenter();
       
  2927             viewCenter.iY += delta;
       
  2928             }
       
  2929 
       
  2930         TSize worldSize( iLines->MinimumSize() );
       
  2931         worldSize.iHeight = Max( worldSize.iHeight, iSize.iHeight );
       
  2932 
       
  2933         TRAP_IGNORE( iPhysics->InitPhysicsL( worldSize, iSize, viewCenter ) );
       
  2934         TRAP_IGNORE( UpdateScrollBarL() );
       
  2935         }
       
  2936     }
       
  2937 
       
  2938 
       
  2939 // ---------------------------------------------------------------------------
       
  2940 // CEikDialogPage::HighlightTimerCallBack
       
  2941 // ---------------------------------------------------------------------------
       
  2942 //
       
  2943 TInt CEikDialogPage::HighlightTimerCallBack( TAny* aPtr )
       
  2944     {
       
  2945     CEikDialogPage* me = static_cast<CEikDialogPage*>( aPtr );
       
  2946     me->HandleHighlightTimer();
       
  2947     
       
  2948     return 0;
       
  2949     }
       
  2950 
       
  2951 
       
  2952 // ---------------------------------------------------------------------------
       
  2953 // CEikDialogPage::HandleHighlightTimer
       
  2954 // ---------------------------------------------------------------------------
       
  2955 //
       
  2956 void CEikDialogPage::HandleHighlightTimer()
       
  2957     {
       
  2958     iExtension->iHighlightTimer->Cancel();
       
  2959     
       
  2960     TInt touchedLine = iExtension->iLastTouchedLine;
       
  2961     
       
  2962     if ( ( touchedLine < iLines->Count() ) && ( touchedLine != iCurrentLine ) )
       
  2963         {
       
  2964         (*iLines)[touchedLine]->ActivateL();
       
  2965         
       
  2966         if ( LineIsFocusable( touchedLine ) )
       
  2967             {
       
  2968             TRAP_IGNORE( PrepareForFocusTransitionL() );
       
  2969             ChangeFocusToAndExposeL( touchedLine );
       
  2970             LineChangedL( (*iLines)[touchedLine]->iId );
       
  2971             }
       
  2972         }
       
  2973     }
       
  2974 
       
  2975 
       
  2976 
       
  2977 // ---------------------------------------------------------------------------
       
  2978 // CEikDialogPage::HighlightVisible
       
  2979 // ---------------------------------------------------------------------------
       
  2980 //
       
  2981 TBool CEikDialogPage::HighlightVisible() const
       
  2982     {
       
  2983     if ( IsEditable() || !iExtension->iUsesSingleClick )
       
  2984         {
       
  2985         return ETrue;
       
  2986         }
       
  2987     
       
  2988     return iHighlightVisible;
       
  2989     }
       
  2990 
       
  2991 
       
  2992 // ---------------------------------------------------------------------------
       
  2993 // CEikDialogPage::ScrollCacheByPixels
       
  2994 // ---------------------------------------------------------------------------
       
  2995 //
       
  2996 void CEikDialogPage::ScrollCacheByPixels( 
       
  2997 		TInt /*aDelta*/, const TDesC& /*aDebugMsg*/, TBool aDrawNow )
       
  2998     {
       
  2999     if ( iLines->Count() <= 0 )
       
  3000         return;
       
  3001     TInt bottomItem, upperItem;
       
  3002     TInt bottom = iPhysics->ViewCenter().iY + iSize.iHeight - iSize.iHeight / 2;
       
  3003     if ( bottom < 0 )
       
  3004         {
       
  3005         bottomItem = -1;
       
  3006         }
       
  3007     else
       
  3008         {
       
  3009         bottomItem = bottom / (*iLines)[0]->Size().iHeight;
       
  3010         if ( bottomItem > iLines->Count() )
       
  3011             {
       
  3012             bottomItem = iLines->Count();
       
  3013             }
       
  3014         }
       
  3015     TInt upper = iPhysics->ViewCenter().iY - iSize.iHeight / 2;
       
  3016     if ( upper <= 0 )
       
  3017         {
       
  3018         upperItem = -1;
       
  3019         }
       
  3020     else
       
  3021         {
       
  3022         upperItem = upper / (*iLines)[0]->Size().iHeight;
       
  3023         if ( upperItem > iLines->Count() )
       
  3024             {
       
  3025             upperItem = iLines->Count();
       
  3026             }
       
  3027         }
       
  3028     if ( iPhysics->OngoingPhysicsAction() != CAknPhysics::EAknPhysicsActionNone )
       
  3029         {
       
  3030         if ( upperItem == -1 || bottomItem == iLines->Count() )
       
  3031             {
       
  3032             if ( upperItem != iExtension->iTopItem || bottomItem != iExtension->iBottomItem )
       
  3033                 {
       
  3034                 iExtension->SilentFeedback( this, ETouchFeedbackSensitiveList, TPointerEvent() );
       
  3035                 }
       
  3036             }
       
  3037         else if ( upperItem >= 0 || bottomItem < iLines->Count() )
       
  3038             {
       
  3039             if ( upperItem < iExtension->iTopItem || bottomItem > iExtension->iBottomItem )
       
  3040                 {
       
  3041                 iExtension->SilentFeedback( this, ETouchFeedbackSensitiveList, TPointerEvent() );
       
  3042                 }
       
  3043             }
       
  3044         }
       
  3045     iExtension->iBottomItem = bottomItem;
       
  3046     iExtension->iTopItem = upperItem;
       
  3047     if ( aDrawNow )
       
  3048         {
       
  3049         TRAP_IGNORE( UpdateScrollBarL() );
       
  3050         DrawNow();
       
  3051         }
       
  3052     }
       
  3053 
       
  3054 
       
  3055 // ---------------------------------------------------------------------------
       
  3056 // CEikDialogPage::UpdateLineInCache
       
  3057 // ---------------------------------------------------------------------------
       
  3058 //
       
  3059 void CEikDialogPage::UpdateLineInCache( CEikCaptionedControl* aLine )
       
  3060     {
       
  3061     TInt lineIndex = iLines->FindLineIndex( aLine );
       
  3062     
       
  3063     if ( lineIndex != KErrNotFound )
       
  3064         {
       
  3065         if ( aLine->Position() != TPoint( 1000, 0 ) )
       
  3066             {
       
  3067             iExtension->iRecordingGc->SetLineRect( lineIndex, TRect( TPoint( 1000, 0 ), aLine->Rect().Size() ) );
       
  3068             }
       
  3069         else
       
  3070             {
       
  3071             iExtension->iRecordingGc->SetLineRect( lineIndex, aLine->Rect() );
       
  3072             iExtension->iRecordingGc->PurgeLine( lineIndex );
       
  3073 
       
  3074             Parent()->Parent()->Parent()->SetCustomGc( iExtension->iRecordingGc );
       
  3075             
       
  3076             aLine->DrawForeground( aLine->Rect() );
       
  3077             DrawControl( aLine );
       
  3078 
       
  3079             Parent()->Parent()->Parent()->SetCustomGc( NULL );
       
  3080             }    
       
  3081         }
       
  3082 
       
  3083     if ( iExtension->iInitialLayoutDone )
       
  3084         {
       
  3085         UpdatePhysics();
       
  3086         }
       
  3087     }
       
  3088 
       
  3089 
       
  3090 // ---------------------------------------------------------------------------
       
  3091 // CEikDialogPage::Synchronize
       
  3092 // ---------------------------------------------------------------------------
       
  3093 //
       
  3094 void CEikDialogPage::Synchronize()
       
  3095     {
       
  3096     iExtension->iScrolling = EFalse;
       
  3097     iLines->MoveLineToScreen( iCurrentLine, iPhysics->ViewTopY(), ETrue );
       
  3098     }
       
  3099 
       
  3100 
       
  3101 // ---------------------------------------------------------------------------
       
  3102 // CEikDialogPage::DrawControl
       
  3103 // ---------------------------------------------------------------------------
       
  3104 //
       
  3105 void CEikDialogPage::DrawControl( CCoeControl* aControl ) const
       
  3106     {
       
  3107     TInt count = aControl->CountComponentControls();
       
  3108     RDrawableWindow* parentWindow = aControl->DrawableWindow();
       
  3109     
       
  3110     for ( TInt i = 0; i < count; ++i )
       
  3111         {
       
  3112         CCoeControl* control = aControl->ComponentControl( i );
       
  3113         RDrawableWindow* childWindow = control->DrawableWindow();
       
  3114         
       
  3115         // Test whether child control has its own window. In that case skip
       
  3116         // recording since child windows can't be scrolled.
       
  3117         if ( parentWindow->WsHandle() != childWindow->WsHandle() )
       
  3118             {
       
  3119             continue;
       
  3120             }
       
  3121         
       
  3122         control->DrawForeground( control->Rect() );
       
  3123         DrawControl( control );
       
  3124         }
       
  3125     }
       
  3126 
       
  3127 
       
  3128 // ---------------------------------------------------------------------------
       
  3129 // CEikDialogPage::RecordLinesL
       
  3130 // ---------------------------------------------------------------------------
       
  3131 //
       
  3132 void CEikDialogPage::RecordLinesL()
       
  3133     {
       
  3134     Parent()->Parent()->Parent()->SetCustomGc( iExtension->iRecordingGc );
       
  3135     
       
  3136     iExtension->iRecordingGc->PurgeBuffer();
       
  3137 
       
  3138     CEikCaptionedControl* line = NULL;
       
  3139     
       
  3140     for ( TInt i = 0; i < iLines->Count(); ++i )
       
  3141         {
       
  3142         line = (*iLines)[i];
       
  3143         iExtension->iRecordingGc->PrepareForNewLineL( line->Rect() );
       
  3144         line->DrawForeground( line->Rect() );
       
  3145         DrawControl( line );
       
  3146         }
       
  3147 
       
  3148     Parent()->Parent()->Parent()->SetCustomGc( NULL );
       
  3149     }
       
  3150 
       
  3151 
       
  3152 // ---------------------------------------------------------------------------
       
  3153 // CEikDialogPage::RecordLineL
       
  3154 // ---------------------------------------------------------------------------
       
  3155 //
       
  3156 void CEikDialogPage::RecordLineL( TInt aLine )
       
  3157     {
       
  3158     Parent()->Parent()->Parent()->SetCustomGc( iExtension->iRecordingGc );
       
  3159     
       
  3160     CEikCaptionedControl* line = (*iLines)[aLine];
       
  3161     
       
  3162     if ( line )
       
  3163         {
       
  3164         iExtension->iRecordingGc->ReplaceLineL( aLine );
       
  3165         line->DrawForeground( (line->Rect() ) );
       
  3166         DrawControl( line );
       
  3167         }
       
  3168     
       
  3169     Parent()->Parent()->Parent()->SetCustomGc( NULL );
       
  3170     }
       
  3171 
       
  3172 
       
  3173 // ---------------------------------------------------------------------------
       
  3174 // CEikDialogPage::ScrollByPixels
       
  3175 // ---------------------------------------------------------------------------
       
  3176 //
       
  3177 void CEikDialogPage::ScrollByPixels( TInt aDelta )
       
  3178     {
       
  3179     if ( aDelta != 0 )
       
  3180         {
       
  3181         iLines->ScrollByPixels( aDelta );
       
  3182         TRAP_IGNORE( UpdateScrollBarL() );
       
  3183         DrawNow();
       
  3184         TRAP_IGNORE( RecordLinesL() );
       
  3185         }
       
  3186     }
       
  3187 
       
  3188 
       
  3189 // ---------------------------------------------------------------------------
       
  3190 // CEikDialogPage::RemovePressedDownHighlight
       
  3191 // ---------------------------------------------------------------------------
       
  3192 //
       
  3193 void CEikDialogPage::RemovePressedDownHighlight()
       
  3194     {
       
  3195     if ( iCurrentLine != -1 )
       
  3196         {
       
  3197         CEikCaptionedControl* currentLine = (*iLines)[iCurrentLine];
       
  3198         
       
  3199         if ( currentLine && currentLine->PressedDownState() )
       
  3200             {
       
  3201             currentLine->SetPressedDownState( EFalse );
       
  3202             if ( IsForm() )
       
  3203                 {
       
  3204                 RecordLineL( iCurrentLine );
       
  3205                 }
       
  3206             }
       
  3207         }
       
  3208     }
       
  3209 
       
  3210 
       
  3211 // ---------------------------------------------------------------------------
       
  3212 // CEikDialogPage::HighlightVisible
       
  3213 // ---------------------------------------------------------------------------
       
  3214 //
       
  3215 void CEikDialogPage::HighlightVisible( TBool aVisible )
       
  3216     {
       
  3217     if ( !IsEditable() )
       
  3218         {
       
  3219         iHighlightVisible = aVisible;
       
  3220         }
       
  3221     }
       
  3222 
       
  3223 
       
  3224 //------------------------------------------------------------------------------------
       
  3225 // CEikDialogPage::HandlePointerEventL()
       
  3226 // Function notifys the pages observer that the page has been tapped. (stylus down&up)
       
  3227 // The first tap to a dialog line sets focus to it (on stylus down),the second tap
       
  3228 // on the same line emulates an MSK press (on stylus up). It works also when the dialog
       
  3229 // is just opened and the (first) focused line is tapped. Any dragging to another line
       
  3230 // prevents the MSK press emulation on the subsequent stylus up event.
       
  3231 
       
  3232 // iExtension->iFocusClicked is used as a flag to indicate that the focus was previously
       
  3233 // moved to the current line. At the function beginning, if the stylus is down on the same
       
  3234 // line as the previous time, it means the current line is focused, and an MSK press must
       
  3235 // be emulated on the stylus up event. If iExtension->iFocusClicked is not set at a stylus
       
  3236 // up event, nothing happens: it means that the previous stylus down event just moved
       
  3237 // the focus to this line.
       
  3238 
       
  3239 
       
  3240 /*
       
  3241 Tactile feedback changes here potentially affect
       
  3242 - forms                - can be distinquished with IsForm(). Feedback is handled here
       
  3243 - notes and notifiers  - own feedback implementation-> should not be handled here
       
  3244 - queries              - own feedback implementation -> should not be handled here
       
  3245 - sct                  - own feedback implementation-> should not be handled here
       
  3246 - popup form           - no need for feedback
       
  3247 - color selection grid - own feedback implementation-> should not be handled here
       
  3248 
       
  3249 and of course any 3rd party stuff, which can not be reasonably handled here without
       
  3250 knowing how the 3rd party stuff should work.
       
  3251 
       
  3252 ---> only trigger feedback for form here. Anything else will be wrong.
       
  3253 */
       
  3254 
       
  3255 
       
  3256 //------------------------------------------------------------------------------------
       
  3257 //
       
  3258 void CEikDialogPage::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
  3259     {
       
  3260     // Forms have their own specialized pointer event handling if panning and flicking
       
  3261     // are enabled.
       
  3262     if ( IsForm() )
       
  3263         {
       
  3264         HandleFormPointerEventL( aPointerEvent );
       
  3265         return;
       
  3266         }
       
  3267     // Pointer event is not handled at all if the dialog page has no lines. If an event
       
  3268     // would be handled in such situation if would crash in several places inside this
       
  3269     // method and the methods called from here. Also in some occasions such a dialog page
       
  3270     // indicates that the dialog is not fully constructed yet.
       
  3271     
       
  3272     // Leaving pointer event handling undone is quite safe assumption since a dialog without
       
  3273     // lines is empty. There's nothing that could happen when such a dialog is tapped e.g.
       
  3274     // it can't be dismissed since it doesn't have any CAknNoteControls etc. And if a client
       
  3275     // application wanted to alter this behaviour it would need to override this method anyway.
       
  3276     if( !AknLayoutUtils::PenEnabled() || iLines->Count() == 0 || LineHandlerCalled() )
       
  3277         {
       
  3278         return;
       
  3279         }
       
  3280     
       
  3281     if ( PageContainer()->PageSelector()->Dialg()->Extension()->iPublicFlags.IsSet( CEikDialogExtension::EUseVirtualInput ) )
       
  3282         {
       
  3283         PageContainer()->PageSelector()->Dialg()->Extension()->iPublicFlags.Set( CEikDialogExtension::EDelayedExit );
       
  3284         }
       
  3285     
       
  3286     CCoeControl* grabbingComponent = GrabbingComponent(); 
       
  3287     TBool callDefaultImplementation = ETrue;
       
  3288     TBool focusItem = EFalse;
       
  3289     // YPosToLine is scaled to iDataWinPos, so add it to pointer Y position
       
  3290     TInt yPosition = aPointerEvent.iPosition.iY; // + iDataWinPos.iY;
       
  3291     TInt touchedLineIndex = YPosToLine2( yPosition );
       
  3292     // If the stylus is down and the touched line is already the current one,
       
  3293     // mark this fact in iExtension->iFocusedClicked to be used later when the stylus is up.
       
  3294     
       
  3295     if ( touchedLineIndex != KErrNotFound && 
       
  3296          iExtension->iCapturingItem != KErrNotFound &&
       
  3297          touchedLineIndex != iExtension->iCapturingItem )
       
  3298         {
       
  3299         iExtension->iCapturingItem = KErrNotFound;
       
  3300         }
       
  3301         
       
  3302     // Click outside of items - do nothing
       
  3303     if ( touchedLineIndex == KErrNotFound )
       
  3304         {
       
  3305         // Pan & flick capturing pointer events
       
  3306         if ( iExtension->iCapturingItem != KErrNotFound )
       
  3307             {
       
  3308             CEikCaptionedControl* capturingItem = 
       
  3309                 (*iLines)[iExtension->iCapturingItem];
       
  3310             const TInt type ( capturingItem->iControlType );
       
  3311             if ( capturingItem->ControlIsAPopfield( type ) )
       
  3312                 {
       
  3313                 capturingItem->iControl->HandlePointerEventL( aPointerEvent );
       
  3314                 if ( aPointerEvent.iType == TPointerEvent::EButton1Up )
       
  3315                     {
       
  3316                     iExtension->iCapturingItem = KErrNotFound;
       
  3317                     }
       
  3318                 }
       
  3319             }
       
  3320             
       
  3321         if( aPointerEvent.iType == TPointerEvent::EDrag || aPointerEvent.iType == TPointerEvent::EButtonRepeat )
       
  3322             {
       
  3323             TInt numLines=iLines->Count();
       
  3324             for (TInt ii=0;ii<numLines;ii++)
       
  3325                 {
       
  3326                 //If dragging out of forms, no pressed down effect.
       
  3327                 CEikCaptionedControl* thisLine=(*iLines)[ii];
       
  3328                 const TInt controlType(thisLine->iControlType);
       
  3329                 if(thisLine->ControlIsAnEdwin(controlType) || thisLine->ControlIsAMfne(controlType))
       
  3330                     {
       
  3331                     if( thisLine->PressedDownState() )
       
  3332                         {
       
  3333                         thisLine->SetPressedDownState( EFalse );
       
  3334                         thisLine->DrawDeferred();
       
  3335                         }
       
  3336                     }
       
  3337                 }
       
  3338             CAknControl::HandlePointerEventL(aPointerEvent);        
       
  3339             }
       
  3340         // Forward point up event also.
       
  3341         if ( aPointerEvent.iType == TPointerEvent::EButton1Up )
       
  3342             {
       
  3343             CAknControl::HandlePointerEventL(aPointerEvent);
       
  3344             }
       
  3345         return;
       
  3346         }
       
  3347     
       
  3348     if ( aPointerEvent.iType == TPointerEvent::EButton1Down &&
       
  3349         iCurrentLine == touchedLineIndex )
       
  3350         {
       
  3351         iExtension->iFocusedClicked = ETrue;
       
  3352         }
       
  3353 
       
  3354     if ( (NumberOfLines() > 0 && !grabbingComponent) ||
       
  3355         (IsForm() && !iIsEditable) )
       
  3356         {     
       
  3357         CEikCaptionedControl *currCtrl = (*iLines)[touchedLineIndex];
       
  3358         MPointerEventObserver *obs = currCtrl->PointerEventObserver();
       
  3359         TBool ret = ETrue;
       
  3360         if (obs)
       
  3361             {
       
  3362             iExtension->iFlags.Set( CDialogPageExtension::ELineHandlerCalled );
       
  3363             ret = obs->PointerEvent(currCtrl, aPointerEvent);
       
  3364             iExtension->iFlags.Clear( CDialogPageExtension::ELineHandlerCalled );
       
  3365             }
       
  3366 
       
  3367         // first move highlight to correct dialog line
       
  3368         if ( ret && touchedLineIndex != iCurrentLine )
       
  3369             {   
       
  3370             // activate line.          
       
  3371             (*iLines)[touchedLineIndex]->ActivateL();              
       
  3372 
       
  3373             // focus line if it is possible, PointerUp have not cause scrolling. 
       
  3374             if ( LineIsFocusable(touchedLineIndex) && 
       
  3375                 aPointerEvent.iType != TPointerEvent::EButton1Up )
       
  3376                 {    
       
  3377                 focusItem = ETrue;
       
  3378                                         
       
  3379                 CEikCaptionedControl* newLine = (*iLines)[touchedLineIndex];
       
  3380                 const TInt controlType(newLine->iControlType);
       
  3381                  
       
  3382                 // all other than colorselection grid or popupfield does just move highlight. 
       
  3383                 // CSelGrid have also focus to clicked color    
       
  3384                 if ( !newLine->ControlIsAColourSelGrid(controlType) &&
       
  3385                     !newLine->ControlIsAPopfield(controlType) )
       
  3386                     {                    
       
  3387                     callDefaultImplementation = EFalse;         
       
  3388                     }
       
  3389                 }
       
  3390             } 
       
  3391         }
       
  3392     
       
  3393     // If the stylus is dragged to a new line, focus that line and
       
  3394     // cancel the "Focused line clicked" mode (if any) for the next
       
  3395     // stylus up event (then no MSK press will be emulated)
       
  3396     if ( ( aPointerEvent.iType == TPointerEvent::EDrag || 
       
  3397            aPointerEvent.iType == TPointerEvent::EButtonRepeat ) && 
       
  3398            touchedLineIndex != iCurrentLine )
       
  3399         {
       
  3400         if ( !(*iLines)[touchedLineIndex]->IsNonFocusing() )
       
  3401             {
       
  3402             focusItem = ETrue;
       
  3403             }
       
  3404             
       
  3405         iExtension->iFocusedClicked = EFalse;
       
  3406         }
       
  3407 
       
  3408     // Click handling
       
  3409     
       
  3410     TBool mskPress = EFalse;
       
  3411     // If the stylus is up above already focused line - emulate an MSK press
       
  3412     if ( iFormControl && !iIsEditable && // in view mode
       
  3413         aPointerEvent.iType == TPointerEvent::EButton1Up &&
       
  3414         touchedLineIndex == iCurrentLine &&
       
  3415         iExtension->iFocusedClicked )
       
  3416         {
       
  3417         mskPress = ETrue;
       
  3418         iExtension->iFocusedClicked = EFalse;
       
  3419         }
       
  3420 
       
  3421     /**
       
  3422     * The local @c destroyed variable keeps track of the object destroyed state.
       
  3423     */
       
  3424     TBool destroyed = EFalse;
       
  3425         
       
  3426     if ( callDefaultImplementation )
       
  3427         {
       
  3428         CEikCaptionedControl* currentLine = (*iLines)[touchedLineIndex];
       
  3429         const TInt controlType(currentLine->iControlType);
       
  3430         
       
  3431         iExtension->iDestroyedPtr = &destroyed;
       
  3432         if ( currentLine->ControlIsAPopfield(controlType) ) 
       
  3433             {
       
  3434             if(aPointerEvent.iType == TPointerEvent::EButton1Down)
       
  3435                 {
       
  3436                 currentLine->HandlePointerEventL(aPointerEvent);
       
  3437                 iExtension->iCapturingItem = touchedLineIndex;       
       
  3438                 }
       
  3439             else if(aPointerEvent.iType == TPointerEvent::EButton1Up)
       
  3440                 {
       
  3441                 currentLine->HandlePointerEventL(aPointerEvent);  
       
  3442                 }
       
  3443             }
       
  3444         else
       
  3445             {            
       
  3446             CCoeControl::HandlePointerEventL(aPointerEvent);        
       
  3447             }
       
  3448         if ( !destroyed )
       
  3449             {
       
  3450             iExtension->iDestroyedPtr = NULL;
       
  3451             }
       
  3452         else
       
  3453             {
       
  3454             return;
       
  3455             }
       
  3456         }
       
  3457 
       
  3458     if (iCurrentLine >= 0)
       
  3459         { 
       
  3460         CEikCaptionedControl *ctrl = (*iLines)[iCurrentLine];
       
  3461         const TInt ctrlType(ctrl->iControlType);
       
  3462         if (ctrl->ControlIsAPopfield(ctrlType))
       
  3463             {
       
  3464             CAknPopupField::EAknPopupFieldSelectionMode mode = ((CAknPopupField*)ctrl->iControl)->SelectionMode();
       
  3465             if (mode == CAknPopupField::EAknPopupFieldSelectionListMode)
       
  3466                 {
       
  3467                 focusItem = EFalse;
       
  3468                 }
       
  3469             }
       
  3470         }
       
  3471         
       
  3472     TBool clear = EFalse;
       
  3473     if ( PageContainer()->PageSelector()->Dialg()->Extension()->iPublicFlags.IsSet( CEikDialogExtension::EUseVirtualInput ) )
       
  3474         {
       
  3475         clear = ETrue;
       
  3476         }
       
  3477         
       
  3478     if ( focusItem || iExtension->iFocusedClicked)
       
  3479         {
       
  3480         iExtension->HandleFormFeedback( this, aPointerEvent, touchedLineIndex, iCurrentLine );
       
  3481         }
       
  3482                 
       
  3483     if ( focusItem )
       
  3484         {
       
  3485         PrepareForFocusTransitionL();
       
  3486         
       
  3487         (*iLines)[iCurrentLine]->ScrollBackEditor();
       
  3488         ShowFocus( EFalse, EFalse );
       
  3489         iCurrentLine = touchedLineIndex;
       
  3490         ShowFocus( ETrue, EFalse );        
       
  3491         ExposeLine( iCurrentLine, EFalse );
       
  3492         LineChangedL((*iLines)[touchedLineIndex]->iId);
       
  3493         }
       
  3494 
       
  3495     else if (iPageObserver && grabbingComponent && aPointerEvent.iType == TPointerEvent::EButton1Up)
       
  3496         { 
       
  3497         iPageObserver->HandleDialogPageEventL(MEikDialogPageObserver::EDialogPageTapped);
       
  3498         }
       
  3499     
       
  3500     if (mskPress)
       
  3501         {
       
  3502         TKeyEvent key;
       
  3503         key.iCode=EKeyOK;
       
  3504         key.iModifiers=0;
       
  3505         key.iRepeats = 0;
       
  3506         CEikonEnv::Static()->SimulateKeyEventL(key, EEventKey);
       
  3507         // SimulateKeyEventL has to be last, because it can
       
  3508         // possibly delete the dialog.. Must not do anything
       
  3509         // to the dialog after the call.
       
  3510         }
       
  3511 
       
  3512     if ( clear )
       
  3513         {
       
  3514         PageContainer()->PageSelector()->Dialg()->Extension()->iPublicFlags.Clear( CEikDialogExtension::EDelayedExit );
       
  3515         }
       
  3516     }
       
  3517 
       
  3518 void CEikDialogPage::SetScbState(TBool aExternal)
       
  3519     {
       
  3520     iExtension->iExternalScrollbar = aExternal;
       
  3521     }
       
  3522     
       
  3523 TBool CEikDialogPage::ScbState() const
       
  3524     {
       
  3525     return iExtension->iExternalScrollbar;
       
  3526     }
       
  3527 
       
  3528 //
       
  3529 // CEikDialogPageContainer.
       
  3530 //
       
  3531 
       
  3532 CEikDialogPageContainer::~CEikDialogPageContainer()
       
  3533     {
       
  3534     AKNTASHOOK_REMOVE();
       
  3535     delete iAnimation;
       
  3536     if(iPageArray)
       
  3537         iPageArray->ResetAndDestroy();
       
  3538     delete iPageArray;
       
  3539     delete iSBFrame;
       
  3540     }
       
  3541 
       
  3542 CEikDialogPageContainer* CEikDialogPageContainer::NewL(const CCoeControl& aParent,MEikDialogPageObserver* aPageObserver)
       
  3543     {
       
  3544     CEikDialogPageContainer* self=CEikDialogPageContainer::NewLC(aParent,aPageObserver);
       
  3545     CleanupStack::Pop();
       
  3546     return self;
       
  3547     }
       
  3548 
       
  3549 CEikDialogPageContainer* CEikDialogPageContainer::NewLC(const CCoeControl& aParent,MEikDialogPageObserver* aPageObserver)
       
  3550     {
       
  3551     CEikDialogPageContainer* self=new(ELeave) CEikDialogPageContainer(aPageObserver);
       
  3552     CleanupStack::PushL(self);
       
  3553     self->ConstructL(aParent);
       
  3554     AKNTASHOOK_ADDL( self, "CEikDialogPageContainer" );
       
  3555     return self;
       
  3556     }
       
  3557 
       
  3558 CEikDialogPageContainer::CEikDialogPageContainer(MEikDialogPageObserver* aPageObserver)
       
  3559     : iPageObserver(aPageObserver),iActivePage(0), iForm(EFalse)
       
  3560     {
       
  3561     SetHitTest( this );
       
  3562     }
       
  3563 
       
  3564 void CEikDialogPageContainer::CommonConstructL(const CCoeControl& aParent)
       
  3565     {
       
  3566     iContext=this;
       
  3567     SetContainerWindowL( aParent );
       
  3568     CreatePageArrayL();
       
  3569     }
       
  3570 
       
  3571 void CEikDialogPageContainer::ConstructL(const CCoeControl& aParent)
       
  3572     {
       
  3573     CommonConstructL(aParent);
       
  3574     }
       
  3575 
       
  3576 void CEikDialogPageContainer::ConstructFromResourceL(TResourceReader& aReader,const CCoeControl& aParent)
       
  3577     {
       
  3578     CommonConstructL(aParent);
       
  3579 
       
  3580     const TInt numPages=aReader.ReadInt16();
       
  3581     for (TInt ii=0;ii<numPages;ii++)
       
  3582         {
       
  3583         AddPageL(ii,aReader);
       
  3584         }
       
  3585     }
       
  3586 
       
  3587 void CEikDialogPageContainer::CreatePageArrayL()
       
  3588     {
       
  3589     iPageArray=new(ELeave) CArrayPtrFlat<CEikDialogPage>(KPageArrayGranularity);
       
  3590     }
       
  3591 
       
  3592 void CEikDialogPageContainer::CreateScrollBarL(const CCoeControl& aParent)
       
  3593     {
       
  3594     if (!iSBFrame) 
       
  3595         {
       
  3596         iSBFrame=new(ELeave) CEikScrollBarFrame((CCoeControl*)&aParent, NULL, ETrue);
       
  3597         iSBFrame->CreateDoubleSpanScrollBarsL(ETrue, EFalse, ETrue, EFalse); // window owning scrollbar
       
  3598         iSBFrame->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff, CEikScrollBarFrame::EAuto);
       
  3599         iSBFrame->SetScrollBarFrameFlags(CEikScrollBarFrame::EVVisible);
       
  3600         iSBFrame->DrawBackground( EFalse, EFalse );
       
  3601         }
       
  3602     }
       
  3603 
       
  3604 void CEikDialogPageContainer::SetActivePageByIdL(TInt aPageId)
       
  3605     {
       
  3606     // ToDo : unroll this loop
       
  3607     const TInt numPages=iPageArray->Count();
       
  3608     for (TInt ii=0;ii<numPages;ii++)
       
  3609         {
       
  3610         CEikDialogPage* thisPage=(*iPageArray)[ii];
       
  3611         if (thisPage->PageId()==aPageId)
       
  3612             {
       
  3613             if (iActivePage>=0)
       
  3614                 (*iPageArray)[iActivePage]->SetInactiveL();
       
  3615             thisPage->SetActiveAndFocusL();
       
  3616             if(iActivePage!=ii)
       
  3617                 {
       
  3618                 thisPage->ReportPageChangedL();
       
  3619                 iActivePage=ii;
       
  3620                 }
       
  3621             return;
       
  3622             }
       
  3623         }
       
  3624 
       
  3625     ASSERT(EFalse); // aPageId not found.
       
  3626     }
       
  3627 
       
  3628 void CEikDialogPageContainer::SetActivePageByIndexL(TInt aPageIndex)
       
  3629     {
       
  3630     const TInt numPages=iPageArray->Count();
       
  3631     
       
  3632     if(aPageIndex>=0 && aPageIndex<numPages)
       
  3633         {
       
  3634         CArrayPtr<CEikDialogPage>& pageArray = *iPageArray;
       
  3635         if (iActivePage>=0)
       
  3636             pageArray[iActivePage]->SetInactiveL();
       
  3637         pageArray[aPageIndex]->SetActiveAndFocusL();
       
  3638         if(iActivePage!=aPageIndex)
       
  3639             {
       
  3640             pageArray[aPageIndex]->ReportPageChangedL();
       
  3641             iActivePage=aPageIndex;
       
  3642             }
       
  3643         return;
       
  3644         }
       
  3645 
       
  3646     ASSERT(EFalse); // aPageIndex not found.
       
  3647     }
       
  3648 
       
  3649 TInt CEikDialogPageContainer::ActivateFirstPageL()
       
  3650     {
       
  3651     // Activate first page that isn't dimmed.
       
  3652     // SetToolTips() ;
       
  3653     const TInt numPages=iPageArray->Count();
       
  3654     for (TInt ii=0;ii<numPages;ii++)
       
  3655         {
       
  3656         CEikDialogPage* thisPage=(*iPageArray)[ii];
       
  3657         if (!(thisPage->IsDimmed()))
       
  3658             {
       
  3659             if (iActivePage>=0)
       
  3660                 (*iPageArray)[iActivePage]->SetInactiveL();
       
  3661             thisPage->SetActiveAndFocusL();
       
  3662             if(iActivePage!=ii)
       
  3663                 {
       
  3664                 thisPage->ReportPageChangedL();
       
  3665                 iActivePage=ii;
       
  3666                 }
       
  3667             return thisPage->PageId();
       
  3668             }
       
  3669         }
       
  3670 
       
  3671     // All dimmed, so activate first.
       
  3672     CEikDialogPage* firstPage=(*iPageArray)[0];
       
  3673     if (iActivePage>=0)
       
  3674         (*iPageArray)[iActivePage]->SetInactiveL();
       
  3675     firstPage->SetActiveAndFocusL();    
       
  3676     if(iActivePage!=0)
       
  3677         {
       
  3678         firstPage->ReportPageChangedL();
       
  3679         iActivePage=0;
       
  3680         }
       
  3681     return firstPage->PageId();
       
  3682     }
       
  3683 
       
  3684 TInt CEikDialogPageContainer::PageId(TInt aIndex) const
       
  3685  
       
  3686     {
       
  3687     return (*iPageArray)[aIndex]->PageId();
       
  3688     }
       
  3689 
       
  3690 TInt CEikDialogPageContainer::PageIdFromLineId(TInt aLineId) const
       
  3691     {
       
  3692     const TInt numPages=iPageArray->Count();
       
  3693     for (TInt ii=0;ii<numPages;ii++)
       
  3694         {
       
  3695         CEikDialogPage* thisPage=(*iPageArray)[ii];
       
  3696         if (thisPage->OwnsLine(aLineId))
       
  3697             return thisPage->PageId();
       
  3698         }
       
  3699 
       
  3700     return KErrNotFound;
       
  3701     }
       
  3702 
       
  3703 TBool CEikDialogPageContainer::SetInitialFocus()
       
  3704     {
       
  3705     TBool pageAcceptedFocus=(*iPageArray)[iActivePage]->SetInitialFocus();
       
  3706 
       
  3707     if (pageAcceptedFocus)
       
  3708         SetFocus(ETrue,ENoDrawNow);
       
  3709 
       
  3710     return pageAcceptedFocus;
       
  3711     }
       
  3712 
       
  3713 void CEikDialogPageContainer::AddPageL(TInt aPageId)
       
  3714     {
       
  3715     CEikDialogPage* newPage=CEikDialogPage::NewLC(aPageId,Window(),*iSBFrame,*this,iPageObserver);
       
  3716     newPage->SetObserver(Observer());
       
  3717     newPage->MakeVisible(EFalse);
       
  3718     if(iPageArray->Count())
       
  3719         newPage->MakeVisible(EFalse);
       
  3720     iPageArray->AppendL(newPage);
       
  3721     CleanupStack::Pop();
       
  3722     newPage->SetPageContainer(this);
       
  3723     }
       
  3724 
       
  3725 void CEikDialogPageContainer::AddPageL(TInt aPageId,TResourceReader& aReader)
       
  3726     {
       
  3727     CEikDialogPage* newPage=CEikDialogPage::NewLC(aPageId,Window(),*iSBFrame,*this,iPageObserver,aReader);
       
  3728     newPage->SetObserver(Observer());
       
  3729     newPage->CopyControlContextFrom(this);
       
  3730     if(iPageArray->Count())
       
  3731         newPage->MakeVisible(EFalse);
       
  3732     iPageArray->AppendL(newPage);
       
  3733     CleanupStack::Pop();
       
  3734     newPage->SetPageContainer(this);
       
  3735     }
       
  3736 
       
  3737 CEikCaptionedControl* CEikDialogPageContainer::Line(TInt aLineId) const
       
  3738     {
       
  3739     CEikCaptionedControl* line=LineOrNull(aLineId);
       
  3740     if (line)
       
  3741         return line;
       
  3742 
       
  3743     ASSERT(EFalse); // Not found.
       
  3744     return NULL;
       
  3745     }
       
  3746 
       
  3747 CEikCaptionedControl* CEikDialogPageContainer::LineOrNull(TInt aLineId) const
       
  3748     {
       
  3749     CEikCaptionedControl* line=NULL;
       
  3750     const TInt numPages=iPageArray->Count();
       
  3751     for (TInt ii=0;ii<numPages;ii++)
       
  3752         {
       
  3753         line=(*iPageArray)[ii]->LineOrNull(aLineId);
       
  3754         if (line)
       
  3755             return line;
       
  3756         }
       
  3757 
       
  3758     return NULL; // Not found.
       
  3759     }
       
  3760 
       
  3761 CEikCaptionedControl* CEikDialogPageContainer::CurrentLine() const
       
  3762     {
       
  3763     if(iActivePage>=0)
       
  3764         return (*iPageArray)[iActivePage]->CurrentLine();
       
  3765     else
       
  3766         return NULL;
       
  3767     }
       
  3768 
       
  3769 void CEikDialogPageContainer::SetPageDensePacked(TInt aPageId,TBool aDensePacked)
       
  3770     {
       
  3771     (*iPageArray)[PageIndex(aPageId)]->SetDensePacking(aDensePacked);
       
  3772     }
       
  3773 
       
  3774 void CEikDialogPageContainer::SetAllPagesDensePacked(TBool aDensePacked)
       
  3775     {
       
  3776     const TInt numPages=iPageArray->Count();
       
  3777     for (TInt ii=0;ii<numPages;ii++)
       
  3778         (*iPageArray)[ii]->SetDensePacking(aDensePacked);
       
  3779     }
       
  3780 
       
  3781 void CEikDialogPageContainer::SetPageDimmed(TInt aPageId,TBool aDimmed,TDrawNow aDrawNow)
       
  3782     {
       
  3783     CEikDialogPage* pageToDim=(*iPageArray)[PageIndex(aPageId)];
       
  3784     pageToDim->SetDimmed(aDimmed);
       
  3785     if (aDrawNow==EDrawNow)
       
  3786         pageToDim->DrawNow();
       
  3787     }
       
  3788 
       
  3789 TInt CEikDialogPageContainer::PageIndex(TInt aPageId) const
       
  3790     {
       
  3791     const TInt numPages=iPageArray->Count();
       
  3792     for (TInt ii=0;ii<numPages;ii++)
       
  3793         {
       
  3794         if ((*iPageArray)[ii]->PageId()==aPageId)
       
  3795             return ii;
       
  3796         }
       
  3797 
       
  3798     return KErrNotFound;
       
  3799     }
       
  3800 
       
  3801 TInt CEikDialogPageContainer::LineId(const CCoeControl& aControl) const
       
  3802     {
       
  3803     const TInt numPages=iPageArray->Count();
       
  3804     for (TInt ii=0;ii<numPages;ii++)
       
  3805         {
       
  3806         TInt thisId=(*iPageArray)[ii]->LineId(aControl);
       
  3807         if (thisId!=KErrNotFound)
       
  3808             return thisId;
       
  3809         }
       
  3810 
       
  3811     return KErrNotFound;
       
  3812     }
       
  3813 
       
  3814 TBool CEikDialogPageContainer::IsActivePageDimmed() const
       
  3815     {
       
  3816     return (*iPageArray)[iActivePage]->IsDimmed();
       
  3817     }
       
  3818 
       
  3819 void CEikDialogPageContainer::InsertLineL(TInt aPosition,TInt aPageId,TInt aResourceId)
       
  3820     {
       
  3821     TInt pageIndex;
       
  3822 
       
  3823     if (aPageId==0)
       
  3824         pageIndex=iActivePage;
       
  3825     else
       
  3826         pageIndex=PageIndex(aPageId);
       
  3827 
       
  3828     (*iPageArray)[pageIndex]->InsertLineL(aPosition,aResourceId);
       
  3829     }
       
  3830 
       
  3831 void CEikDialogPageContainer::DeleteLine(TInt aLineId, TBool aRedraw)
       
  3832     {
       
  3833     (*iPageArray)[PageIndex(PageIdFromLineId(aLineId))]->DeleteLine(aLineId, aRedraw);
       
  3834     }
       
  3835 
       
  3836 void CEikDialogPageContainer::AdjustAllIds(TInt aPageId,TInt aControlIdDelta)
       
  3837     {
       
  3838     (*iPageArray)[PageIndex(aPageId)]->AdjustAllIds(aControlIdDelta);
       
  3839     }
       
  3840 
       
  3841 CCoeControl* CEikDialogPageContainer::CreateLineByTypeL(const TDesC& aCaption,TInt aLineId,TInt aControlType,TAny* aReturnValue)
       
  3842     {
       
  3843     return (*iPageArray)[iActivePage]->CreateLineByTypeL(aCaption,aLineId,aControlType,aReturnValue);
       
  3844     }
       
  3845 
       
  3846 CCoeControl* CEikDialogPageContainer::CreateLineByTypeL(const TDesC& aCaption,TInt aPageId,TInt aLineId,TInt aControlType,TAny* aReturnValue)
       
  3847     {
       
  3848     TInt pageIndex = PageIndex(aPageId);
       
  3849     ASSERT(pageIndex >= 0 && (*iPageArray)[pageIndex]);
       
  3850     CCoeControl* control=(*iPageArray)[pageIndex]->CreateLineByTypeL(aCaption,aLineId,aControlType,aReturnValue);
       
  3851     return control;
       
  3852     }
       
  3853 
       
  3854 TInt CEikDialogPageContainer::FocusLineL(TInt aLineId)
       
  3855 //
       
  3856 // If a page change is required, returns the new page index.
       
  3857 // Else returns -1.
       
  3858 //
       
  3859     {
       
  3860     // Try active page first.
       
  3861     TInt lineFocused=(*iPageArray)[iActivePage]->FocusLineL(aLineId);
       
  3862     if (lineFocused==KErrNone)
       
  3863         return -1;
       
  3864 
       
  3865     // Line not found.
       
  3866     ASSERT(EFalse);
       
  3867     return EFalse;
       
  3868     }
       
  3869 
       
  3870 TInt CEikDialogPageContainer::FindPageIndexForLineId(TInt aLineId)
       
  3871 //
       
  3872 // If a page change is required, returns the new page index.
       
  3873 // Else returns -1.
       
  3874     {
       
  3875     // Try active page first.
       
  3876     TInt lineIndex=(*iPageArray)[iActivePage]->LineIndex(aLineId);
       
  3877     if (lineIndex!=KErrNotFound)
       
  3878         return -1;
       
  3879 
       
  3880     const TInt numPages=iPageArray->Count();
       
  3881     for (TInt ii=0;ii<numPages;ii++)
       
  3882         {
       
  3883         CEikDialogPage* thisPage=(*iPageArray)[ii];
       
  3884         
       
  3885         if (ii!=iActivePage)
       
  3886             lineIndex=thisPage->LineIndex(aLineId);
       
  3887 
       
  3888         if (lineIndex!=KErrNotFound)
       
  3889             {
       
  3890             return ii;
       
  3891             }
       
  3892         }
       
  3893 
       
  3894     // Line not found.
       
  3895     ASSERT(EFalse);
       
  3896     return EFalse;
       
  3897     }
       
  3898 
       
  3899 TInt CEikDialogPageContainer::FocusedLineId() const
       
  3900     {
       
  3901     return (*iPageArray)[iActivePage]->FocusedLineId();
       
  3902     }
       
  3903 
       
  3904 void CEikDialogPageContainer::GetAutoValues()
       
  3905     {
       
  3906     const TInt numPages=iPageArray->Count();
       
  3907     for (TInt ii=0;ii<numPages;ii++)
       
  3908         (*iPageArray)[ii]->GetAutoValues();
       
  3909     }
       
  3910 
       
  3911 void CEikDialogPageContainer::Draw(const TRect& /*aRect*/) const
       
  3912     {
       
  3913     }
       
  3914 
       
  3915 TInt CEikDialogPageContainer::NumPages() const
       
  3916     {
       
  3917     return iPageArray->Count();
       
  3918     }
       
  3919 
       
  3920 void CEikDialogPageContainer::SizeChanged()
       
  3921     {
       
  3922     TRect rect( Rect() );
       
  3923     const TInt numPages = iPageArray->Count();
       
  3924     
       
  3925     for ( TInt i = 0; i < numPages; ++i )
       
  3926         {
       
  3927         (*iPageArray)[i]->SetRect( rect );
       
  3928         }
       
  3929     }
       
  3930 
       
  3931 TKeyResponse CEikDialogPageContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
       
  3932     {
       
  3933     return (*iPageArray)[iActivePage]->OfferKeyEventL(aKeyEvent,aType);
       
  3934     }
       
  3935 
       
  3936 TKeyResponse CEikDialogPageContainer::OfferUpDownKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType,CEikDialogPage::TFocusNavigationMode aFocusNavigationMode)
       
  3937     {
       
  3938     return (*iPageArray)[iActivePage]->OfferUpDownKeyEventL(aKeyEvent,aType,aFocusNavigationMode);
       
  3939     }
       
  3940 
       
  3941 TInt CEikDialogPageContainer::ActivePageId() const
       
  3942     {
       
  3943     return (*iPageArray)[iActivePage]->PageId();
       
  3944     }
       
  3945 
       
  3946 TInt CEikDialogPageContainer::ActivePageIndex() const
       
  3947     {
       
  3948     return iActivePage;
       
  3949     }
       
  3950 
       
  3951 TSize CEikDialogPageContainer::MinimumSize()
       
  3952     {
       
  3953 //  The DPC reports a minimum size that is the max of all its contained DPs, independently 
       
  3954 //  for height and width
       
  3955 
       
  3956     TSize minSize(0,0);
       
  3957 
       
  3958     TInt numPages=iPageArray->Count();
       
  3959     for (TInt ii=0;ii<numPages;ii++)
       
  3960         {
       
  3961         TSize thisPageSize((*iPageArray)[ii]->MinimumSize());
       
  3962         if (thisPageSize.iWidth>minSize.iWidth)
       
  3963             minSize.iWidth=thisPageSize.iWidth;
       
  3964         if (thisPageSize.iHeight>minSize.iHeight)
       
  3965             minSize.iHeight=thisPageSize.iHeight;
       
  3966         }
       
  3967 
       
  3968 //  Comment by RSD 11.09.2001: The following looks like the min size is never allowed to 
       
  3969 //  shrink...
       
  3970     minSize.iHeight=Max(minSize.iHeight,iSize.iHeight);
       
  3971     minSize.iWidth=Max(minSize.iWidth,iSize.iWidth);
       
  3972     return minSize;
       
  3973     }
       
  3974 
       
  3975 void CEikDialogPageContainer::PrepareForFocusLossL()
       
  3976     {
       
  3977     (*iPageArray)[iActivePage]->PrepareForFocusLossL();
       
  3978     }
       
  3979 
       
  3980 TInt CEikDialogPageContainer::CountComponentControls() const
       
  3981     {
       
  3982     TInt i = 0;
       
  3983     if (iSBFrame) 
       
  3984         i = iSBFrame->CountComponentControls();
       
  3985     return (iActivePage>=0 ? 1 : 0) + i;
       
  3986     }
       
  3987 
       
  3988 CCoeControl* CEikDialogPageContainer::ComponentControl(TInt aIndex) const
       
  3989     {
       
  3990     if (aIndex==0 && iActivePage>=0)
       
  3991         return (*iPageArray)[iActivePage];
       
  3992     
       
  3993     __ASSERT_ALWAYS(iSBFrame, User::Invariant());
       
  3994    
       
  3995     return iSBFrame->ComponentControl(aIndex-(iActivePage>=0?1:0));
       
  3996     }
       
  3997 
       
  3998 TSize CEikDialogPageContainer::PreferredSize(const TSize& aMaxSize) const
       
  3999     {
       
  4000     TSize preferredSize(0,0);
       
  4001 
       
  4002     const TInt numPages=iPageArray->Count();
       
  4003     for (TInt ii=0;ii<numPages;ii++)
       
  4004         {
       
  4005         TSize thisPageSize((*iPageArray)[ii]->PreferredSize());
       
  4006         if (thisPageSize.iWidth>preferredSize.iWidth)
       
  4007             preferredSize.iWidth=thisPageSize.iWidth;
       
  4008         if (thisPageSize.iHeight>preferredSize.iHeight)
       
  4009             preferredSize.iHeight=thisPageSize.iHeight;
       
  4010         }
       
  4011 
       
  4012     preferredSize.iWidth=Min(aMaxSize.iWidth,preferredSize.iWidth);
       
  4013 
       
  4014     return preferredSize;
       
  4015     }
       
  4016 
       
  4017 void CEikDialogPageContainer::ActivateL()
       
  4018     {
       
  4019     // Pass the activate event to child controls always.
       
  4020     CCoeControl::ActivateL();
       
  4021     //
       
  4022     // Have to do this here instead of CEikCaptionedControl::ActivateL, because CaptionedControl has no
       
  4023     // activateL overridden.
       
  4024     const TInt numPages=iPageArray->Count();
       
  4025 
       
  4026     for (TInt ii=0;ii<numPages;ii++)
       
  4027         {
       
  4028         CEikDialogPage *page = (*iPageArray)[ii];
       
  4029         TInt numLines = page->NumberOfLines();
       
  4030         for(int i=0;i<numLines;i++)
       
  4031             {
       
  4032             CEikCaptionedControl *capCC = page->LineByIndex(i);
       
  4033         
       
  4034              if ( capCC->iIsFormControl && page->FindLineIndex(page->CurrentLine()) != i)
       
  4035                  {
       
  4036 
       
  4037                  if (capCC->ControlIsAnEdwin(capCC->iControlType))
       
  4038                      {
       
  4039                      CEikEdwin *edwin = (CEikEdwin*)capCC->iControl;
       
  4040                      TRAP_IGNORE(edwin->TextView()->SetDocPosL(0)
       
  4041                            );
       
  4042                      }
       
  4043                  }
       
  4044              }
       
  4045          }  
       
  4046     }
       
  4047 
       
  4048 void CEikDialogPageContainer::FocusChanged(TDrawNow aDrawNow)
       
  4049     {
       
  4050     (*iPageArray)[iActivePage]->SetFocus(IsFocused(),aDrawNow);
       
  4051     }
       
  4052 
       
  4053 void CEikDialogPageContainer::PrepareContext(CWindowGc& /*aGc*/) const
       
  4054     {
       
  4055     }
       
  4056 
       
  4057 void CEikDialogPageContainer::ResetLineMinimumSizes()
       
  4058     {
       
  4059     (*iPageArray)[iActivePage]->ResetLineMinimumSizes();
       
  4060     }
       
  4061 
       
  4062 TInt CEikDialogPageContainer::FindLineIndex(const CCoeControl& aControl) const
       
  4063     {
       
  4064     CCoeControl* nonConstControlPtr=CONST_CAST(CCoeControl*,&aControl);
       
  4065     return (*iPageArray)[iActivePage]->FindLineIndex(nonConstControlPtr);
       
  4066     }
       
  4067 
       
  4068 TBool CEikDialogPageContainer::RotateFocusByL(TInt aDelta)
       
  4069     {
       
  4070     return (*iPageArray)[iActivePage]->RotateFocusByL(aDelta);
       
  4071     }
       
  4072 
       
  4073 TKeyResponse CEikDialogPageContainer::OfferHotKeysKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
       
  4074     {
       
  4075     return (*iPageArray)[iActivePage]->OfferHotKeysKeyEventL(aKeyEvent,aType);
       
  4076     }
       
  4077 
       
  4078 TBool CEikDialogPageContainer::TakesEnterKey()
       
  4079     {
       
  4080     return (*iPageArray)[iActivePage]->TakesEnterKey();
       
  4081     }
       
  4082 
       
  4083 CEikDialogPage* CEikDialogPageContainer::Page( TInt aPageID ) 
       
  4084     {
       
  4085     // Try returning index, not pageID
       
  4086     if ( aPageID >=1 )
       
  4087         return (*iPageArray)[ aPageID - 1 ] ;
       
  4088     else
       
  4089         // Single page only
       
  4090         return ( *iPageArray )[ aPageID ] ;
       
  4091     }
       
  4092 
       
  4093 void CEikDialogPageContainer::SetEditableL( TBool aEditable )
       
  4094     {
       
  4095     iIsEditable=aEditable;
       
  4096     (*iPageArray)[iActivePage]->SetEditableL( aEditable, ETrue ) ;
       
  4097     (*iPageArray)[iActivePage]->UpdateScrollBarL();
       
  4098     }
       
  4099 
       
  4100 CEikFormAnim* CEikDialogPageContainer::AcquireAnim(
       
  4101     TBool aAcquire, MEikFormAnimObserver* aObserver ) const
       
  4102     {
       
  4103     // You could add assertions here to make sure animation usage is exclusive
       
  4104     // (animation must be unacquired before anyone can acquire it).
       
  4105     // Unfortunately, CaptionedControl::SetCurrent usage is currently not
       
  4106     // exclusive.
       
  4107     if( iAnimation )
       
  4108         {
       
  4109         if( aAcquire )
       
  4110             {
       
  4111             iAnimation->SetObserver( aObserver );
       
  4112             return iAnimation;
       
  4113             }
       
  4114         else // Unacquire
       
  4115             {
       
  4116             iAnimation->SetObserver( NULL );
       
  4117             return NULL;
       
  4118             }
       
  4119         }
       
  4120 
       
  4121     return NULL;
       
  4122     }
       
  4123 
       
  4124 /**
       
  4125  * Writes the internal state of the control and its components to aStream.
       
  4126  * Does nothing in release mode.
       
  4127  * Designed to be overidden and base called by subclasses.
       
  4128  *
       
  4129  * @internal
       
  4130  * @since App-Framework_6.1
       
  4131  */
       
  4132 #ifndef _DEBUG
       
  4133 void CEikDialogPageContainer::WriteInternalStateL(RWriteStream&) const
       
  4134     {}
       
  4135 #else
       
  4136 void CEikDialogPageContainer::WriteInternalStateL(RWriteStream& aWriteStream) const
       
  4137     {
       
  4138     CCoeControl::WriteInternalStateL(aWriteStream);
       
  4139     }
       
  4140 #endif
       
  4141 
       
  4142 void CEikDialogPageContainer::HandleResourceChange(TInt aType)
       
  4143     {
       
  4144     // Animation is skin dependent, whenever skin changes animation changes
       
  4145     // too.
       
  4146     if( KAknsMessageSkinChange == aType )
       
  4147         {
       
  4148         if( iAnimation )
       
  4149             {
       
  4150             iAnimation->ReleaseAnimation();
       
  4151             }
       
  4152         }
       
  4153 
       
  4154     CCoeControl::HandleResourceChange(aType);
       
  4155 
       
  4156     if(aType==KEikDynamicLayoutVariantSwitch)
       
  4157         {
       
  4158         SizeChanged();
       
  4159         }
       
  4160 
       
  4161     TInt numPages = iPageArray->Count();
       
  4162     for (TInt ii=0; ii<numPages; ii++)
       
  4163         {
       
  4164         if (ii != iActivePage)      // active page already done by CCoeControl::HandleResourceChange()
       
  4165             (*iPageArray)[ii]->HandleResourceChange(aType);
       
  4166         }
       
  4167     }
       
  4168 
       
  4169 const CEikDialogPageSelector* CEikDialogPageContainer::PageSelector() const 
       
  4170     {
       
  4171     return iPageSelector;
       
  4172     }
       
  4173 
       
  4174 void CEikDialogPageContainer::SetPageSelector(const CEikDialogPageSelector* aPageSelector)
       
  4175     {
       
  4176     iPageSelector = aPageSelector;
       
  4177     }
       
  4178 
       
  4179 void CEikDialogPageContainer::SetPageFormSized()
       
  4180     {
       
  4181     iForm = ETrue;
       
  4182 
       
  4183     //
       
  4184     // Form layout
       
  4185     //
       
  4186     
       
  4187     /** Dialog page container and page have the same size */
       
  4188     TRect mainPaneRect;
       
  4189     AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EMainPane, mainPaneRect );
       
  4190     mainPaneRect = TRect( mainPaneRect.Size() );    // Moving to point (0, 0)
       
  4191     TAknLayoutRect formPaneLt;
       
  4192     formPaneLt.LayoutRect( mainPaneRect, AknLayoutScalable_Avkon::listscroll_form_pane().LayoutLine() );
       
  4193     formPaneLt.LayoutRect( formPaneLt.Rect(), AknLayoutScalable_Avkon::list_form_gen_pane().LayoutLine() );
       
  4194     
       
  4195     //
       
  4196     // End of form layout
       
  4197     //
       
  4198 
       
  4199     if ( formPaneLt.Rect() != Rect() )
       
  4200         {
       
  4201         // TODO: use static method to do variation between traditional scrolling and panning when available
       
  4202         //SetRect( formPaneLt.Rect() );
       
  4203         SetRect( mainPaneRect );
       
  4204         }
       
  4205 
       
  4206     /** Only forms have line highlight animations. Animation creation is delayed
       
  4207       * here.
       
  4208       */
       
  4209     if ( !iAnimation )
       
  4210         {
       
  4211         TRAPD( err, iAnimation = CEikFormAnim::NewL() );
       
  4212         
       
  4213         if ( KErrNone != err )
       
  4214             {
       
  4215             iAnimation = NULL;
       
  4216             }
       
  4217         }
       
  4218     }
       
  4219 
       
  4220 CEikScrollBarFrame* CEikDialogPageContainer::ScrollBar() const
       
  4221     {
       
  4222     return iSBFrame;
       
  4223     }
       
  4224 
       
  4225 TBool CEikDialogPageContainer::HitRegionContains( const TPoint& /*aPoint*/, const CCoeControl& /*aControl*/ ) const
       
  4226     {
       
  4227     if ( iActivePage >= 0 )
       
  4228         {
       
  4229         return !(*iPageArray)[iActivePage]->LineHandlerCalled();
       
  4230         }
       
  4231         
       
  4232     return ETrue;
       
  4233     }
       
  4234