widgetmodel/alfwidgetmodel/src/alfwidgetcontrol.cpp
branchRCL_3
changeset 25 4ea6f81c838a
parent 23 514d98f21c43
child 26 0e9bb658ef58
equal deleted inserted replaced
23:514d98f21c43 25:4ea6f81c838a
     1 /*
       
     2 * Copyright (c) 2007 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:  The base class for all widget controls.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <alf/alfevent.h>
       
    20 
       
    21 #include "alf/alfwidget.h"
       
    22 #include <alf/alfwidgetcontrol.h>
       
    23 #include <alf/alfmodel.h>
       
    24 #include <alf/alfwidgeteventhandler.h>
       
    25 #include "alf/alfelement.h"
       
    26 #include <alf/alfvarianttype.h>
       
    27 #include "alf/alfmodeloperation.h"
       
    28 #include <osn/ustring.h>
       
    29 #include <osn/alfptrvector.h>
       
    30 #include <alf/alfexceptions.h>
       
    31 #include <alf/alfenv.h>
       
    32 #include <alf/alfcontrolgroup.h>
       
    33 #include <alf/ialflayoutmanager.h>
       
    34 #include <alf/alfwidgetevents.h>
       
    35 #include "alf/ialfattributeowner.h"
       
    36 #include <osn/osnnew.h>
       
    37 #include <assert.h>
       
    38 
       
    39 #include "alfhostapiimpl.h"
       
    40 #include "alfwidgetcontroleventfilter.h"
       
    41 
       
    42 using namespace osncore;
       
    43 
       
    44 namespace Alf
       
    45     {
       
    46 // ======== INTERNAL DATA TYPES ========
       
    47 
       
    48 // Forward declared inside the Alf namespace
       
    49 
       
    50 
       
    51 //Internal Class to Store the Element Data
       
    52 class ElementData
       
    53     {
       
    54 public:
       
    55     //Default constructor
       
    56     ElementData():mElement(0)
       
    57         {
       
    58         }
       
    59     //Destructor
       
    60     ~ElementData()
       
    61         {
       
    62         delete mElement;
       
    63         }
       
    64     /**
       
    65      * The element. Own.
       
    66      */
       
    67     IAlfElement* mElement;
       
    68 
       
    69     /**
       
    70      * The data id range for the element.
       
    71      */
       
    72     uint mDataIdRange;
       
    73     };
       
    74 
       
    75 class AlfWidgetControlImpl
       
    76     {
       
    77 
       
    78 public:
       
    79     AlfWidgetControlImpl():mWidget(0),mEventFilter(0),mAlfHostAPIImpl(0)
       
    80         {
       
    81 
       
    82         }
       
    83     ~AlfWidgetControlImpl()
       
    84         {
       
    85 
       
    86         }
       
    87 public:
       
    88     /**
       
    89      * The element data. Elements are owned by the control.
       
    90      */
       
    91     AlfPtrVector<ElementData> mElementArray;
       
    92 
       
    93     /**
       
    94      * The event handlers. Event handlers are owned by the control.
       
    95      */
       
    96     AlfPtrVector<IAlfWidgetEventHandler> mEventHandlerArray;
       
    97 
       
    98     /**
       
    99      * The owner widget.
       
   100      */
       
   101     AlfWidget* mWidget;
       
   102     
       
   103     /**
       
   104      * PointerUp Event Filter.
       
   105      */
       
   106     AlfWidgetControlEventFilter *mEventFilter;
       
   107     
       
   108     /**
       
   109      * The state of the control.
       
   110      * The state is a combination of binary state flags.
       
   111      */
       
   112     uint mState;
       
   113     /**
       
   114      * AlfAPIImpl auto pointer.
       
   115      * This will be used to provide container control's functionality by 
       
   116      * widget control.Owned.
       
   117      */
       
   118     auto_ptr<AlfHostAPIImpl> mAlfHostAPIImpl;
       
   119     };
       
   120 
       
   121 // ======== MEMBER FUNCTIONS ========
       
   122 
       
   123 OSN_EXPORT CAlfWidgetControl::CAlfWidgetControl(CAlfEnv& aEnv)
       
   124     {
       
   125     construct(aEnv);
       
   126     }
       
   127 
       
   128 OSN_EXPORT CAlfWidgetControl::CAlfWidgetControl()
       
   129     {
       
   130     }
       
   131 
       
   132 OSN_EXPORT void* CAlfWidgetControl::operator new(
       
   133                  size_t aSize, newarg /*aEnumVal*/)  throw (std::bad_alloc)
       
   134     { 
       
   135     void* ret = 0;
       
   136     TRAPD(err, ret = CBase::operator new((TUint)aSize, ELeave));
       
   137     if(err != KErrNone)
       
   138         {
       
   139         throw std::bad_alloc();
       
   140         }
       
   141     return ret;         
       
   142     } 
       
   143 
       
   144 OSN_EXPORT void CAlfWidgetControl::construct(
       
   145     CAlfEnv& aEnv)
       
   146     {
       
   147     mWdgtControlData.reset( new (EMM) AlfWidgetControlImpl() );
       
   148     mWdgtControlData->mWidget = 0;
       
   149     //by default control is focusable and enabled
       
   150     mWdgtControlData->mState = IAlfWidgetControl::Focusable |
       
   151         IAlfWidgetControl::Enabled;
       
   152 
       
   153     // Call CAlfControl second phase constructor
       
   154     TRAPD(err, CAlfControl::ConstructL( aEnv ));
       
   155     if(err != KErrNone)
       
   156         {
       
   157         ALF_THROW(AlfException, err, "CAlfWidgetControl::construction failed.");
       
   158         }
       
   159     mWdgtControlData->mElementArray.setAutoDelete(true);
       
   160     mWdgtControlData->mEventHandlerArray.setAutoDelete(true);
       
   161     mWdgtControlData->mAlfHostAPIImpl.reset(0);
       
   162 
       
   163     // Instatiate Event filter
       
   164     mWdgtControlData->mEventFilter = 
       
   165         new (EMM) AlfWidgetControlEventFilter();
       
   166     addEventHandler(mWdgtControlData->mEventFilter);
       
   167     }
       
   168 
       
   169 OSN_EXPORT CAlfWidgetControl::~CAlfWidgetControl()
       
   170     {
       
   171     //release all connections
       
   172     while (this->ConnectionCount())
       
   173         {
       
   174         this->RemoveConnection(&(this->Connection(0)));
       
   175         }
       
   176     mWdgtControlData->mElementArray.setAutoDelete(true);
       
   177     
       
   178     for(int i = 0; i < mWdgtControlData->mElementArray.count(); ++i)
       
   179         {
       
   180         // Fetch the element
       
   181         IAlfElement *element = mWdgtControlData->mElementArray[i]->mElement;
       
   182 
       
   183         // If the element is also an event handler
       
   184         IAlfWidgetEventHandler* eventHandler =
       
   185         IAlfInterfaceBase::makeInterface<IAlfWidgetEventHandler>( element );
       
   186         int eventHandlerIndex = 
       
   187             mWdgtControlData->mEventHandlerArray.findRef( eventHandler );
       
   188         if ( eventHandler && eventHandlerIndex != KErrNotFound )
       
   189             {
       
   190              //cache auto delete state.
       
   191             bool autoDeleteState = 
       
   192                 mWdgtControlData->mEventHandlerArray.autoDelete();
       
   193             mWdgtControlData->mEventHandlerArray.setAutoDelete(false);
       
   194             mWdgtControlData->mEventHandlerArray.remove( eventHandlerIndex );
       
   195              //restore auto delete state.
       
   196             mWdgtControlData->mEventHandlerArray.setAutoDelete(
       
   197                                                      autoDeleteState);
       
   198             }
       
   199         }
       
   200     
       
   201     mWdgtControlData->mElementArray.clear();
       
   202         
       
   203     mWdgtControlData->mEventHandlerArray.setAutoDelete(true);
       
   204     mWdgtControlData->mEventHandlerArray.clear(); 
       
   205     	 
       
   206     if(mWdgtControlData->mWidget)
       
   207         {
       
   208         // false: don't delete twice
       
   209         mWdgtControlData->mWidget->setControl(0, false);
       
   210         mWdgtControlData->mWidget = 0;
       
   211         }
       
   212     }
       
   213 
       
   214 OSN_EXPORT uint CAlfWidgetControl::state() const
       
   215     {
       
   216     // Verify that the internal state stored in the member variable
       
   217     // is in sync with the CAlfWidget state. This might not be the case
       
   218     // if someone has called CAlfWidget APIs, e.g. AcquireFocus(), directly.
       
   219     
       
   220     if ( Focus() )
       
   221         {
       
   222         mWdgtControlData->mState |= IAlfWidgetControl::Focused;
       
   223         }
       
   224     else
       
   225         {
       
   226         mWdgtControlData->mState &= ~IAlfWidgetControl::Focused;
       
   227         }
       
   228 
       
   229     return mWdgtControlData->mState;
       
   230     }
       
   231 
       
   232 OSN_EXPORT void CAlfWidgetControl::setState( uint aState )
       
   233     {
       
   234      // Checks the state invariants. Throws exceptions if not OK
       
   235     checkStateInvariants(aState);
       
   236     
       
   237     // Visible
       
   238     if ( aState & IAlfWidgetControl::Visible )
       
   239         {
       
   240         enableStateVisible();
       
   241         }
       
   242     else
       
   243         {
       
   244         disableStateVisible();
       
   245         }
       
   246 
       
   247     // Enabled
       
   248     if ( aState & IAlfWidgetControl::Enabled )
       
   249         {
       
   250         enableStateEnabled();
       
   251         }
       
   252     else
       
   253         {
       
   254         disableStateEnabled();
       
   255         }
       
   256 
       
   257     // Focused
       
   258     if ( aState & IAlfWidgetControl::Focused )
       
   259         {
       
   260         enableStateFocused();
       
   261         }
       
   262     else
       
   263         {
       
   264         disableStateFocused();
       
   265         }        
       
   266 
       
   267     // Focusable
       
   268     if ( aState & IAlfWidgetControl::Focusable )
       
   269         {
       
   270         enableStateFocusable();
       
   271         }
       
   272     else
       
   273         {
       
   274         disableStateFocusable();
       
   275         }        
       
   276     }
       
   277 
       
   278 OSN_EXPORT void CAlfWidgetControl::enableState( uint aState )
       
   279     {
       
   280     // Predicts the state and checks the state invariants.
       
   281     // Throws exceptions if not OK
       
   282     predictAndCheckStateInvariants(aState, true);
       
   283 
       
   284     // Visible
       
   285     if ( aState & IAlfWidgetControl::Visible )
       
   286         {
       
   287         enableStateVisible();
       
   288         }
       
   289 
       
   290     // Enabled
       
   291     if ( aState & IAlfWidgetControl::Enabled )
       
   292         {
       
   293         enableStateEnabled();
       
   294         }
       
   295 
       
   296     // Set Focusable. This is done first, before putting on fucus
       
   297     if ( aState & IAlfWidgetControl::Focusable )
       
   298         {
       
   299         enableStateFocusable();
       
   300         }
       
   301         
       
   302     // Focused
       
   303     if ( aState & IAlfWidgetControl::Focused )
       
   304         {
       
   305         enableStateFocused();
       
   306         }
       
   307 
       
   308     }
       
   309 
       
   310 OSN_EXPORT void CAlfWidgetControl::disableState( uint aState )
       
   311     {
       
   312     // Predicts the state and checks the state invariants.
       
   313     // Throws exceptions if not OK
       
   314     predictAndCheckStateInvariants(aState, false);
       
   315 
       
   316     // Visible
       
   317     if ( aState & IAlfWidgetControl::Visible )
       
   318         {
       
   319         disableStateVisible();
       
   320         }
       
   321 
       
   322     // Enabled
       
   323     if ( aState & IAlfWidgetControl::Enabled )
       
   324         {
       
   325         disableStateEnabled();
       
   326         }
       
   327 
       
   328     // Focused
       
   329     if ( aState & IAlfWidgetControl::Focused )
       
   330         {
       
   331         disableStateFocused();
       
   332         }
       
   333 
       
   334     // Focusable
       
   335     if ( aState & IAlfWidgetControl::Focusable )
       
   336         {
       
   337         disableStateFocusable();
       
   338         }
       
   339     }
       
   340 
       
   341 OSN_EXPORT bool CAlfWidgetControl::checkState( uint aState ) const
       
   342     {
       
   343     return ( state() & aState );
       
   344     }
       
   345 
       
   346 OSN_EXPORT int CAlfWidgetControl::numEventHandlers() const
       
   347     {
       
   348     return mWdgtControlData->mEventHandlerArray.count();
       
   349     }
       
   350 
       
   351 OSN_EXPORT IAlfWidgetEventHandler& CAlfWidgetControl::eventHandler(
       
   352     int aIndex )
       
   353     {
       
   354     return *mWdgtControlData->mEventHandlerArray[aIndex];
       
   355     }
       
   356 
       
   357 OSN_EXPORT int CAlfWidgetControl::eventHandlerIndex(
       
   358     IAlfWidgetEventHandler& aEventHandler ) const
       
   359     {
       
   360     for ( int i = 0; i < mWdgtControlData->mEventHandlerArray.count(); ++i )
       
   361         {
       
   362         if ( mWdgtControlData->mEventHandlerArray[i] == &aEventHandler )
       
   363             {
       
   364             return i;
       
   365             }
       
   366         }
       
   367     return -1;
       
   368     }
       
   369 
       
   370 OSN_EXPORT IAlfWidgetEventHandler* CAlfWidgetControl::findEventHandler(
       
   371     const TAlfEvent& aEvent )
       
   372     {
       
   373     for ( int i = 0; i < mWdgtControlData->mEventHandlerArray.count(); ++i )
       
   374         {
       
   375         if ( mWdgtControlData->mEventHandlerArray[i]->accept( *this, aEvent ) )
       
   376             {
       
   377             return mWdgtControlData->mEventHandlerArray[i];
       
   378             }
       
   379         }
       
   380     return 0;
       
   381     }
       
   382 
       
   383 OSN_EXPORT void CAlfWidgetControl::addEventHandler(
       
   384     IAlfWidgetEventHandler* aEventHandler, int aIndex )
       
   385     {
       
   386     try
       
   387         {
       
   388         if ( mWdgtControlData->mEventHandlerArray.findRef( aEventHandler ) == 
       
   389              KErrNotFound )
       
   390             {
       
   391             if ( aIndex == -1 )
       
   392                 {
       
   393                 mWdgtControlData->mEventHandlerArray.resize(
       
   394                     mWdgtControlData->mEventHandlerArray.count()+1);
       
   395                 mWdgtControlData->mEventHandlerArray.insert(
       
   396                     mWdgtControlData->mEventHandlerArray.count(),
       
   397                     aEventHandler );
       
   398                 }
       
   399             else
       
   400                 {
       
   401                 mWdgtControlData->mEventHandlerArray.resize(
       
   402                     mWdgtControlData->mEventHandlerArray.count()+1);
       
   403                 mWdgtControlData->mEventHandlerArray.insert( aIndex,
       
   404                                                          aEventHandler);
       
   405                 }
       
   406             }
       
   407         }
       
   408     catch (...)
       
   409         {
       
   410         ALF_THROW(AlfWidgetException,ECommonError,"CAlfWidgetControl: Adding event handler failed.")
       
   411         }
       
   412     }
       
   413 
       
   414 OSN_EXPORT void CAlfWidgetControl::removeAndDestroyEventHandler(
       
   415     IAlfWidgetEventHandler& aEventHandler )
       
   416     {
       
   417 
       
   418     for (int i =0; i<mWdgtControlData->mEventHandlerArray.count();i++)
       
   419         {
       
   420         if (mWdgtControlData->mEventHandlerArray[i] == &aEventHandler)
       
   421             {
       
   422             IAlfWidgetEventHandler *handler = 
       
   423                 mWdgtControlData->mEventHandlerArray[i];
       
   424             //check if it is an eventhandler associated with presentation 
       
   425             if(handler->eventHandlerType() == 
       
   426                IAlfWidgetEventHandler::EPresentationEventHandler)
       
   427                 {
       
   428                 ElementData* elementData = 0;
       
   429                 // if the event handller is also an element, remove the 
       
   430                 // corresponding element data from mEventHandlerArray
       
   431                 elementData = removePesentationElementData(*handler);
       
   432                 // if the element data does not exist, remove the event handler
       
   433                 // from mEventHandlerArray and destroy it 
       
   434                 if(!elementData)
       
   435                     {
       
   436                     mWdgtControlData->mEventHandlerArray.remove( i );
       
   437                     }
       
   438                 // remove the event hanlder from the array but dont destroy it,
       
   439                 // and then delete element data which in turn will destroy the
       
   440                 // element and thus the event handler
       
   441                 else
       
   442                     {
       
   443                     // cache auto delete state.
       
   444                     bool autoDeleteState = 
       
   445                         mWdgtControlData->mEventHandlerArray.autoDelete(); 
       
   446                     mWdgtControlData->mEventHandlerArray.setAutoDelete(false);
       
   447                     mWdgtControlData->mEventHandlerArray.remove( i );
       
   448                     // restore auto delete state.
       
   449                     mWdgtControlData->mEventHandlerArray.setAutoDelete(
       
   450                                                              autoDeleteState);
       
   451                     delete elementData;
       
   452                     }
       
   453                 }
       
   454             else
       
   455                 {
       
   456                 mWdgtControlData->mEventHandlerArray.remove( i );
       
   457                 }
       
   458             return;
       
   459             }
       
   460 
       
   461         }
       
   462 
       
   463     }
       
   464 
       
   465 OSN_EXPORT void CAlfWidgetControl::removeEventHandler(
       
   466     IAlfWidgetEventHandler& aEventHandler )
       
   467     {
       
   468     for (int i =0; i<mWdgtControlData->mEventHandlerArray.count();i++)
       
   469         {
       
   470         if (mWdgtControlData->mEventHandlerArray[i] == &aEventHandler)
       
   471             {
       
   472             // cache auto delete state.
       
   473             bool autoDeleteState = 
       
   474                 mWdgtControlData->mEventHandlerArray.autoDelete();
       
   475             mWdgtControlData->mEventHandlerArray.setAutoDelete(false);
       
   476             mWdgtControlData->mEventHandlerArray.remove( i );
       
   477             // restore auto delete state.
       
   478             mWdgtControlData->mEventHandlerArray.setAutoDelete(
       
   479                                                      autoDeleteState);
       
   480             return;
       
   481             }
       
   482         }
       
   483     }
       
   484 
       
   485 OSN_EXPORT void CAlfWidgetControl::removeAndDestroyEventHandler(
       
   486     const UString& aHandlerId )
       
   487     {
       
   488     for (int i =0; i<mWdgtControlData->mEventHandlerArray.count();i++)
       
   489         {
       
   490         IAlfWidgetEventHandler* handler = 
       
   491             mWdgtControlData->mEventHandlerArray[i];
       
   492         AlfWidgetEventHandlerInitData* eventData = handler->eventHandlerData();
       
   493         if(eventData != 0)
       
   494             {
       
   495             //check for the event id/name
       
   496             if (!aHandlerId.compare(eventData->mWidgetEventHandlerId))
       
   497                 {
       
   498                 //check if it is an eventhandler associated with presentation 
       
   499                 if(handler->eventHandlerType() == 
       
   500                    IAlfWidgetEventHandler::EPresentationEventHandler)
       
   501                     {
       
   502                     ElementData* elementData = 0;
       
   503                     // if the event handller is also an element, remove the 
       
   504                     // corresponding element data from mEventHandlerArray
       
   505                     elementData = removePesentationElementData(*handler);
       
   506                     // if the element data does not exist, remove the event 
       
   507                     // handler from mEventHandlerArray and destroy it 
       
   508                     if(!elementData)
       
   509                         {
       
   510                         // removes and destoys the event handler
       
   511                         mWdgtControlData->mEventHandlerArray.remove( i );
       
   512                         }
       
   513                     // remove the event hanlder from the array but dont destroy
       
   514                     // it, and then delete element data which in turn will 
       
   515                     // destroy the element and thus the event handler      
       
   516                     else
       
   517                         {
       
   518                         // cache auto delete state.
       
   519                         bool autoDeleteState = 
       
   520                             mWdgtControlData->mEventHandlerArray.autoDelete();
       
   521                         mWdgtControlData->mEventHandlerArray.setAutoDelete(
       
   522                                                                  false);
       
   523                         mWdgtControlData->mEventHandlerArray.remove( i );
       
   524                         // restore auto delete state.
       
   525                         mWdgtControlData->mEventHandlerArray.setAutoDelete(
       
   526                                                              autoDeleteState);
       
   527                         //delete element data
       
   528                         delete elementData;
       
   529                         }
       
   530                     }
       
   531                 else
       
   532                     {
       
   533                     mWdgtControlData->mEventHandlerArray.remove( i );
       
   534                     }
       
   535                 return;
       
   536                 }
       
   537             }
       
   538         
       
   539         }
       
   540     }
       
   541     
       
   542 OSN_EXPORT void CAlfWidgetControl::removeAndDestroyPresentationEventHandlers()
       
   543     {
       
   544     int i=0;
       
   545     while(i<mWdgtControlData->mEventHandlerArray.count())
       
   546         {
       
   547         IAlfWidgetEventHandler* handler = 
       
   548                                     mWdgtControlData->mEventHandlerArray[i];
       
   549         
       
   550         //check if it is an eventhandler associated with presentation 
       
   551         if(handler->eventHandlerType() == 
       
   552                IAlfWidgetEventHandler::EPresentationEventHandler)
       
   553             {
       
   554             ElementData* elementData = 0;
       
   555             // if the event handller is also an element, remove the 
       
   556             // corresponding element data from mEventHandlerArray
       
   557             elementData = removePesentationElementData(*handler);
       
   558             // if the element data does not exist, remove the event handler
       
   559             // from mEventHandlerArray and destroy it 
       
   560             if(!elementData)
       
   561                 {
       
   562                 mWdgtControlData->mEventHandlerArray.remove( i );
       
   563                 }
       
   564             // remove the event hanlder from the array but dont destroy it,
       
   565             // and then delete element data which in turn will destroy the
       
   566             // element and thus the event handler    
       
   567             else
       
   568                 {
       
   569                 // cache auto delete state.
       
   570                 bool autoDeleteState = 
       
   571                     mWdgtControlData->mEventHandlerArray.autoDelete();
       
   572                 mWdgtControlData->mEventHandlerArray.setAutoDelete(false);
       
   573                 mWdgtControlData->mEventHandlerArray.remove( i );
       
   574                 // restore auto delete state.
       
   575                 mWdgtControlData->mEventHandlerArray.setAutoDelete(
       
   576                                                          autoDeleteState);
       
   577                 //delete element data
       
   578                 delete elementData;
       
   579                 }
       
   580             }
       
   581         else
       
   582             {
       
   583             i++;
       
   584             }
       
   585         }
       
   586     
       
   587     }
       
   588     
       
   589 OSN_EXPORT void CAlfWidgetControl::removePresentationEventHandlers()
       
   590     {
       
   591     int i=0;
       
   592     // cache auto delete state.
       
   593     bool autoDeleteState = mWdgtControlData->mEventHandlerArray.autoDelete();
       
   594     mWdgtControlData->mEventHandlerArray.setAutoDelete(false);
       
   595     while(i<mWdgtControlData->mEventHandlerArray.count())
       
   596         {
       
   597         IAlfWidgetEventHandler* handler = 
       
   598                                     mWdgtControlData->mEventHandlerArray[i];
       
   599         //check if it is an eventhandler associated with presentation 
       
   600         if(handler->eventHandlerType() == 
       
   601            IAlfWidgetEventHandler::EPresentationEventHandler)
       
   602             {
       
   603             mWdgtControlData->mEventHandlerArray.remove( i );
       
   604             }
       
   605         else
       
   606             {
       
   607             i++;
       
   608             }
       
   609         }
       
   610     // restore auto delete state.    
       
   611     mWdgtControlData->mEventHandlerArray.setAutoDelete(autoDeleteState);
       
   612     }
       
   613 
       
   614 ElementData* CAlfWidgetControl::removePesentationElementData( 
       
   615     IAlfWidgetEventHandler& aEventHandler )
       
   616     {
       
   617     IAlfElement* element =
       
   618         IAlfInterfaceBase::makeInterface<IAlfElement>( &aEventHandler );
       
   619         
       
   620     for ( int i = 0; i < mWdgtControlData->mElementArray.count(); ++i )
       
   621         {
       
   622         if ( mWdgtControlData->mElementArray[i]->mElement == element )
       
   623             {
       
   624             // cache auto delete state.
       
   625             bool autoDeleteState = 
       
   626                 mWdgtControlData->mElementArray.autoDelete();
       
   627             mWdgtControlData->mElementArray.setAutoDelete(false);
       
   628             // Store the Element Data which is to be removed.
       
   629             // This pointer will be returned to the caller
       
   630             ElementData* elementData = mWdgtControlData->mElementArray[i];
       
   631             mWdgtControlData->mElementArray.remove( i );
       
   632             // restore auto delete state.
       
   633             mWdgtControlData->mElementArray.setAutoDelete(autoDeleteState);
       
   634             return elementData;;
       
   635             }
       
   636         }
       
   637     return 0;
       
   638     }
       
   639 
       
   640 OSN_EXPORT int CAlfWidgetControl::numElements() const
       
   641     {
       
   642     return mWdgtControlData->mElementArray.count();
       
   643     }
       
   644 
       
   645 OSN_EXPORT IAlfElement& CAlfWidgetControl::element( int aIndex )
       
   646     {
       
   647     return *(mWdgtControlData->mElementArray[aIndex]->mElement);
       
   648     }
       
   649 
       
   650 OSN_EXPORT IAlfElement* CAlfWidgetControl::findElement( const char* aName )
       
   651     {
       
   652     UString name(aName);
       
   653     for ( int i = 0; i < mWdgtControlData->mElementArray.count(); ++i )
       
   654         {
       
   655         IAlfElement* element = mWdgtControlData->mElementArray[i]->mElement;
       
   656         if (name == UString(element->name()))
       
   657             {
       
   658             return element;
       
   659             }
       
   660         }
       
   661     return 0;
       
   662     }
       
   663 
       
   664 OSN_EXPORT void CAlfWidgetControl::addElement( IAlfElement* aElement )
       
   665     {
       
   666     for ( int i = 0; i < mWdgtControlData->mElementArray.count(); ++i )
       
   667         {
       
   668         if ( mWdgtControlData->mElementArray[i]->mElement == aElement )
       
   669             {
       
   670             return; // Already exists
       
   671             }
       
   672         }
       
   673     auto_ptr<ElementData> elemData( new (EMM) ElementData() );
       
   674     elemData->mElement = aElement;
       
   675     elemData->mDataIdRange = 0xFFFFFFFF;
       
   676     try
       
   677         {
       
   678         mWdgtControlData->mElementArray.resize(
       
   679                               mWdgtControlData->mElementArray.count()+1);
       
   680         mWdgtControlData->mElementArray.insert(
       
   681                               mWdgtControlData->mElementArray.count(),
       
   682                               elemData.get() );
       
   683         elemData.release(); // ownership transferred
       
   684         }
       
   685     catch (...)
       
   686         {
       
   687         // change the element of element data to 0.
       
   688         // this will ensure that the element does not get deleted when the 
       
   689         // elemData gets out of scope, since elemData was not successfully 
       
   690         // added to the array
       
   691         elemData->mElement = 0;
       
   692         ALF_THROW(AlfException,ECommonError,"AlfWidgetControl: Adding the element failed.")
       
   693         }    
       
   694     }
       
   695 
       
   696 OSN_EXPORT void CAlfWidgetControl::removeAndDestroyElement(
       
   697     const IAlfElement& aElement )
       
   698     {
       
   699     for ( int i = 0; i < mWdgtControlData->mElementArray.count(); ++i ) 
       
   700         {
       
   701         if (mWdgtControlData->mElementArray[i])
       
   702             {
       
   703             if ( mWdgtControlData->mElementArray[i]->mElement == &aElement )
       
   704                 {
       
   705                 // Remove the element
       
   706                 IAlfElement *element = 
       
   707                                 mWdgtControlData->mElementArray[i]->mElement;
       
   708 
       
   709                 // If the element is also an event handler
       
   710                 IAlfWidgetEventHandler* eventHandler =
       
   711                     IAlfInterfaceBase::makeInterface<IAlfWidgetEventHandler>(
       
   712                                            element );
       
   713                 int eventHandlerIndex = 
       
   714                     mWdgtControlData->mEventHandlerArray.findRef(
       
   715                                           eventHandler );
       
   716                 if ( eventHandler && eventHandlerIndex != KErrNotFound )
       
   717                     {
       
   718                     // cache auto delete state.
       
   719                     bool autoDeleteState = 
       
   720                         mWdgtControlData->mEventHandlerArray.autoDelete();
       
   721                     mWdgtControlData->mEventHandlerArray.setAutoDelete(false);
       
   722                     mWdgtControlData->mEventHandlerArray.remove(
       
   723                                                          eventHandlerIndex );
       
   724                     // restore auto delete state.
       
   725                     mWdgtControlData->mEventHandlerArray.setAutoDelete(
       
   726                                                              autoDeleteState);
       
   727                     }
       
   728                 // remove and destroy the element
       
   729                 mWdgtControlData->mElementArray.remove( i );
       
   730                 return;
       
   731                 }
       
   732 
       
   733             }
       
   734         }
       
   735     }
       
   736     
       
   737 OSN_EXPORT void CAlfWidgetControl::removeElement(const IAlfElement& aElement )
       
   738     {
       
   739     for ( int i = 0; i < mWdgtControlData->mElementArray.count(); ++i ) 
       
   740         {
       
   741         if (mWdgtControlData->mElementArray[i])
       
   742             {
       
   743             if ( mWdgtControlData->mElementArray[i]->mElement == &aElement )
       
   744                 {
       
   745                 // make the element pointer of elementData null, and then 
       
   746                 // destroy elementData. This will ensure that the memory
       
   747                 // allocated for the elementData is freed but the element
       
   748                 // is not destroyed
       
   749                 mWdgtControlData->mElementArray[i]->mElement = 0;
       
   750                 mWdgtControlData->mElementArray.remove(i);
       
   751                 return;
       
   752                 }
       
   753             }
       
   754         }
       
   755     }    
       
   756 
       
   757 OSN_EXPORT uint CAlfWidgetControl::elementDataId(
       
   758     const IAlfElement& aElement,
       
   759     uint aIndex,
       
   760     uint aParentDataId )
       
   761     {
       
   762     uint range = dataIdRange( aElement );
       
   763 
       
   764     if ( aIndex >= range )
       
   765         {
       
   766         }
       
   767     // In hierarchical element structures this may overflow
       
   768     return aParentDataId * range + aIndex;
       
   769     }
       
   770 
       
   771 OSN_EXPORT uint CAlfWidgetControl::parentElementDataId(
       
   772     const IAlfElement& aElement,
       
   773     uint aDataId )
       
   774     {
       
   775     uint dataIdRng = dataIdRange( aElement );
       
   776     if (0 == dataIdRng) return(0xFFFFFFFF);
       
   777     else
       
   778         return (uint)( aDataId / dataIdRange( aElement ) );
       
   779     }
       
   780 
       
   781 OSN_EXPORT uint CAlfWidgetControl::dataIdToIndex( 
       
   782     const IAlfElement& aElement,
       
   783     uint aDataId )
       
   784     {
       
   785     uint dataIdRng = dataIdRange( aElement );
       
   786     if (0 == dataIdRng) return(0xFFFFFFFF);
       
   787     else
       
   788         return aDataId % dataIdRange( aElement );
       
   789     }
       
   790 
       
   791 OSN_EXPORT IAlfVariantType* CAlfWidgetControl::elementData(
       
   792     const IAlfElement& aElement, uint aDataId )
       
   793     {
       
   794     if (!mWdgtControlData->mWidget)
       
   795         {
       
   796         return 0;	
       
   797         }
       
   798     IAlfModel* widgetModel = mWdgtControlData->mWidget->model();
       
   799     if ( !widgetModel )
       
   800         {
       
   801     	return 0;
       
   802         }
       
   803     IAlfVariantType* modelData = widgetModel->data();
       
   804     if ( !modelData || modelData->type() != IAlfVariantType::EMap )
       
   805         {
       
   806     	return 0;
       
   807         }
       
   808         
       
   809     IAlfMap* map = modelData->map();
       
   810 
       
   811     // Use "current" to traverse elements from the root to the leaf
       
   812     const IAlfElement* last = 0;
       
   813     while ( last != &aElement )
       
   814         {
       
   815         int currentDataId = aDataId;
       
   816         const IAlfElement* current;
       
   817         for ( current = &aElement ;
       
   818                 current->parentElement() != last ;
       
   819                 current = current->parentElement() )
       
   820             {
       
   821             currentDataId = parentElementDataId( *current, currentDataId );
       
   822             }
       
   823         int index = dataIdToIndex( *current, currentDataId );
       
   824         last = current;
       
   825 
       
   826         IAlfVariantType* data = map->item( UString(current->name()) );
       
   827         if ( data->type() == IAlfVariantType::EContainer )
       
   828             {
       
   829             data = data->container()->item( index );
       
   830             }
       
   831         if ( current == &aElement )
       
   832             {
       
   833             return data;
       
   834             }
       
   835         if ( data->type() == IAlfVariantType::EBranch )
       
   836             {
       
   837             // Continue with the child data
       
   838             map = data->branch()->childData();
       
   839             continue;
       
   840             }
       
   841         if ( data->type() == IAlfVariantType::EMap )
       
   842             {
       
   843             map = data->map();
       
   844             }
       
   845         else
       
   846             {
       
   847             return 0;
       
   848             }
       
   849         }
       
   850 
       
   851     return 0;
       
   852     }
       
   853 
       
   854 OSN_EXPORT void CAlfWidgetControl::setDataIdRange(
       
   855     const IAlfElement& aElement, uint aRange )
       
   856     {
       
   857     for ( int i = 0; i < mWdgtControlData->mElementArray.count(); ++i )
       
   858         {
       
   859         if ( mWdgtControlData->mElementArray[i]->mElement == &aElement )
       
   860             {
       
   861             mWdgtControlData->mElementArray[i]->mDataIdRange = aRange;
       
   862             return;
       
   863             }
       
   864         }
       
   865     }
       
   866 
       
   867 OSN_EXPORT uint CAlfWidgetControl::dataIdRange( const IAlfElement& aElement )
       
   868     {
       
   869     for ( int i = 0; i < mWdgtControlData->mElementArray.count(); ++i )
       
   870         {
       
   871         if ( mWdgtControlData->mElementArray[i]->mElement == &aElement )
       
   872             {
       
   873             return mWdgtControlData->mElementArray[i]->mDataIdRange;
       
   874             }
       
   875         }
       
   876     return 0;
       
   877     }
       
   878 
       
   879 OSN_EXPORT void CAlfWidgetControl::updatePresentation()
       
   880     {
       
   881     if ( !mWdgtControlData->mWidget || !mWdgtControlData->mWidget->model() ||
       
   882             !mWdgtControlData->mWidget->model()->data() ||
       
   883             mWdgtControlData->mWidget->model()->data()->type() != 
       
   884             IAlfVariantType::EMap )
       
   885         {
       
   886         return;
       
   887         }
       
   888     IAlfMap* map = mWdgtControlData->mWidget->model()->data()->map();
       
   889     for ( int i = 0; i < map->count(); ++i )
       
   890         {
       
   891         IAlfElement* element = findElement( map->name( i ).getUtf8() );
       
   892         if ( element )
       
   893             {
       
   894 
       
   895             int childInd = childIndex( *map, i, 0, true );
       
   896             IAlfVariantType* data = map->item( i );
       
   897             try
       
   898                 {
       
   899                 if ( data->type() == IAlfVariantType::EMap ||
       
   900                         data->type() == IAlfVariantType::EBranch)
       
   901                     {
       
   902                     // Data for a single presentation instance (visual tree)
       
   903                     element->createVisualTree( *data,
       
   904                         elementDataId( *element, childInd, 0 ),
       
   905                         element->defaultParentLayout( 0 ), childInd );
       
   906                     }
       
   907                 else if ( data->type() == IAlfVariantType::EContainer )
       
   908                     {
       
   909 
       
   910                     // Data for multiple presentation instances (visual trees)
       
   911                     IAlfContainer* container = data->container();
       
   912                     for ( int j = 0; j < container->count(); ++j )
       
   913                         {
       
   914                         element->createVisualTree( *container->item( j ),
       
   915                             elementDataId( *element, childInd + j, 0 ),
       
   916                             element->defaultParentLayout( 0 ), childInd + j );
       
   917                         }
       
   918                     }
       
   919                 }
       
   920             catch (...)
       
   921                 {
       
   922                 ALF_THROW(AlfVisualException,ECanNotCreateVisual,"CAlfWidgetControl::updatePresentation failed")
       
   923                 }
       
   924 
       
   925             }
       
   926 
       
   927         }
       
   928     }
       
   929 
       
   930 OSN_EXPORT void CAlfWidgetControl::destroyPresentation( int aTimeMilliseconds )
       
   931     {
       
   932     (void)aTimeMilliseconds;
       
   933 
       
   934     for ( int i = 0; i < mWdgtControlData->mElementArray.count(); ++i )
       
   935         {
       
   936         mWdgtControlData->mElementArray[i]->mElement->removeAndDestroyVisuals(
       
   937                                                           aTimeMilliseconds );
       
   938         }
       
   939     processEvent(TAlfEvent(EEventWidgetPresentationDestroyed));
       
   940     }
       
   941     
       
   942 OSN_EXPORT void CAlfWidgetControl::destroyVisualsAndElements(
       
   943     int aTimeMilliseconds )
       
   944     {
       
   945     (void)aTimeMilliseconds;
       
   946 
       
   947     // destroy visual trees from elements
       
   948     for( int i = 0; i < mWdgtControlData->mElementArray.count(); ++i )
       
   949         {
       
   950         mWdgtControlData->mElementArray[i]->mElement->removeAndDestroyVisuals(
       
   951                                                           aTimeMilliseconds );
       
   952         }
       
   953     // destroy elements
       
   954     while( numElements() )
       
   955         {
       
   956         removeAndDestroyElement( element(numElements()-1) );
       
   957         }	
       
   958 	
       
   959     // destroy presentation related event handlers
       
   960     removeAndDestroyPresentationEventHandlers();
       
   961 	
       
   962     // send notification
       
   963     processEvent(TAlfEvent(EEventWidgetPresentationDestroyed));		
       
   964     }
       
   965     
       
   966 OSN_EXPORT void CAlfWidgetControl::updateParentLayout()
       
   967     {
       
   968     //get the parent control
       
   969     CAlfWidgetControl* parent = dynamic_cast<CAlfWidgetControl*>(Host());
       
   970     if (parent)
       
   971         {
       
   972         IAlfLayoutManager* layoutManager = 
       
   973             CAlfWidgetControl::makeInterface<IAlfLayoutManager>(parent);
       
   974         if (layoutManager)
       
   975             {
       
   976             layoutManager->updateChildLayout(this);
       
   977             }
       
   978         }
       
   979     }
       
   980     
       
   981 OSN_EXPORT bool CAlfWidgetControl::isContainer() const
       
   982     {
       
   983     IAlfHostAPI* api = mWdgtControlData->mAlfHostAPIImpl.get();
       
   984     return (api && api->getConnectionCount() > 0);
       
   985     }
       
   986     
       
   987 OSN_EXPORT bool CAlfWidgetControl::isFocusable() const
       
   988     {
       
   989     return checkState(IAlfWidgetControl::Enabled) && 
       
   990            checkState(IAlfWidgetControl::Focusable);
       
   991     }
       
   992 
       
   993 void CAlfWidgetControl::setOwnerWidget( AlfWidget* aWidget )
       
   994     {
       
   995     mWdgtControlData->mWidget = aWidget;
       
   996     }
       
   997 
       
   998 OSN_EXPORT AlfWidget* CAlfWidgetControl::widget()
       
   999     {
       
  1000     return mWdgtControlData->mWidget;
       
  1001     }
       
  1002 
       
  1003 OSN_EXPORT AlfEventStatus CAlfWidgetControl::handleEvent(
       
  1004     const TAlfEvent& aEvent )
       
  1005     {
       
  1006     AlfEventStatus ret = EEventNotHandled;
       
  1007     if(isContainer())
       
  1008         {
       
  1009         CAlfWidgetControl* focused = 
       
  1010                     dynamic_cast<CAlfWidgetControl*>(FocusedConnection());
       
  1011         if(focused && aEvent.IsKeyEvent())
       
  1012             {
       
  1013             ret = focused->processEvent(aEvent);
       
  1014             }
       
  1015         else if ( aEvent.IsCustomEvent() )
       
  1016             {
       
  1017             int eventId = aEvent.CustomParameter();
       
  1018             switch(eventId)
       
  1019                 {
       
  1020                 case EEventFocusNextWidget:
       
  1021                     {
       
  1022                       if( handleFocusNext() )
       
  1023                           {
       
  1024                           ret = EEventConsumed;
       
  1025                           }
       
  1026                     }
       
  1027                     break;
       
  1028                 case EEventFocusPreviousWidget:
       
  1029                     {
       
  1030                       if( handleFocusPrevious() )
       
  1031                           {
       
  1032                           ret = EEventConsumed;
       
  1033                           }
       
  1034                     }
       
  1035                     break;
       
  1036                 }
       
  1037             }
       
  1038         }
       
  1039     return ret;
       
  1040 
       
  1041     }
       
  1042 
       
  1043 
       
  1044 OSN_EXPORT TBool CAlfWidgetControl::OfferEventL( const TAlfEvent& aEvent )
       
  1045     {
       
  1046     TBool ret(EFalse);
       
  1047     try
       
  1048         {
       
  1049         ret = processEvent(aEvent);  
       
  1050         }
       
  1051     catch(AlfException& ae)
       
  1052         {
       
  1053         int reason = ae.errorCode();
       
  1054         User::Leave( reason );
       
  1055         }
       
  1056     
       
  1057     return ret;
       
  1058     }
       
  1059     
       
  1060     
       
  1061     
       
  1062     
       
  1063  OSN_EXPORT AlfEventStatus CAlfWidgetControl::processEvent(
       
  1064     const TAlfEvent& aEvent )
       
  1065     {
       
  1066     AlfEventStatus ret(EEventNotHandled);
       
  1067     
       
  1068     /* If the event is not a custom event, stop execution if the widget is
       
  1069        not in enabled state. For custom event continue execution anyway. */
       
  1070     if(!(mWdgtControlData->mState & IAlfWidgetControl::Enabled) &&
       
  1071           !(aEvent.IsCustomEvent()))
       
  1072         {
       
  1073         return EEventNotHandled;    
       
  1074         }
       
  1075     
       
  1076     // Go through tunneling phase event handlers.
       
  1077     AlfEventStatus ret2 = ProcessEventHandlingPhase( tunneling, aEvent );
       
  1078     
       
  1079     if( ret2 == EEventConsumed )  
       
  1080         {
       
  1081         return EEventConsumed;  
       
  1082         }
       
  1083     else if ( ret2 == EEventHandled )     
       
  1084         {
       
  1085         ret = EEventHandled;
       
  1086         }
       
  1087 
       
  1088     // Execute business logic.
       
  1089     if(aEvent.IsPointerEvent())
       
  1090         {
       
  1091         if (aEvent.PointerDown() && isFocusable() && !Focus())
       
  1092              {
       
  1093              AcquireFocus();  
       
  1094              }
       
  1095         }
       
  1096     
       
  1097     ret2 = handleEvent( aEvent );
       
  1098     
       
  1099     if( ret2 == EEventConsumed )  
       
  1100         {
       
  1101         return EEventConsumed;  
       
  1102         }
       
  1103     else if ( ret2 == EEventHandled )     
       
  1104         {
       
  1105         ret = EEventHandled;
       
  1106         }
       
  1107     
       
  1108     // Go through bubbling phase event handlers.
       
  1109     ret2 = ProcessEventHandlingPhase( bubbling, aEvent );
       
  1110     
       
  1111     if( ret2 == EEventConsumed )  
       
  1112         {
       
  1113         return EEventConsumed;  
       
  1114         }
       
  1115     else if ( ret2 == EEventHandled )     
       
  1116         {
       
  1117         ret = EEventHandled;
       
  1118         }
       
  1119         
       
  1120     return ret;
       
  1121     }
       
  1122 
       
  1123 AlfEventStatus CAlfWidgetControl::ProcessEventHandlingPhase(
       
  1124     int aPhase, const TAlfEvent& aEvent )
       
  1125     {
       
  1126     // *** Implementation note ***
       
  1127     //
       
  1128     // offerEvent implementations may remove event handlers from the array that is
       
  1129     // being gone through. So that needs to be taken in consideration in the
       
  1130     // loop implementation.
       
  1131 
       
  1132     AlfEventStatus ret = EEventNotHandled;
       
  1133 
       
  1134     AlfPtrVector<IAlfWidgetEventHandler>& eventHandlerArray =
       
  1135         mWdgtControlData->mEventHandlerArray;    
       
  1136     
       
  1137     for (int i=0; i < eventHandlerArray.count() ; ++i)
       
  1138         {
       
  1139         IAlfWidgetEventHandler* eventHandler = 
       
  1140             mWdgtControlData->mEventHandlerArray[i];
       
  1141         
       
  1142         int phase = eventHandler->eventExecutionPhase();
       
  1143         
       
  1144         bool matchingPhase = false;
       
  1145         if ( aPhase == bubbling )
       
  1146             {
       
  1147             if ( phase == IAlfWidgetEventHandler::
       
  1148                               EBubblingPhaseEventHandler || 
       
  1149                  phase == IAlfWidgetEventHandler::
       
  1150                               ETunnellingAndBubblingPhaseEventHandler )
       
  1151                 {
       
  1152                 matchingPhase = true;
       
  1153                 }
       
  1154             }
       
  1155         else if ( aPhase == tunneling )
       
  1156             {
       
  1157             if ( phase == IAlfWidgetEventHandler::
       
  1158                               ETunnellingPhaseEventHandler || 
       
  1159                  phase == IAlfWidgetEventHandler::
       
  1160                               ETunnellingAndBubblingPhaseEventHandler )
       
  1161                 {
       
  1162                 matchingPhase = true;
       
  1163                 }            
       
  1164             }
       
  1165         
       
  1166         if ( matchingPhase )
       
  1167             {
       
  1168             // This is preparation for the situation where event handlers are
       
  1169             // removed or added during offerEvent call.
       
  1170             // Store pointer to the event handler at next index.
       
  1171             IAlfWidgetEventHandler* nextHandler = 0;
       
  1172             
       
  1173             if ( i+1 < eventHandlerArray.count() )
       
  1174                 {
       
  1175                 nextHandler = eventHandlerArray[i+1];
       
  1176                 }
       
  1177             
       
  1178             // Call offerEvent            
       
  1179             AlfEventStatus ret2 = eventHandler->offerEvent(*this, aEvent);
       
  1180             
       
  1181             // Update status in the function return value.
       
  1182             if( ret2 == EEventConsumed )  
       
  1183                 {
       
  1184                 ret = EEventConsumed;
       
  1185                 break;  
       
  1186                 }
       
  1187             else if ( ret2 == EEventHandled )
       
  1188 	            {
       
  1189 	            ret = EEventHandled;
       
  1190 	            }            
       
  1191             
       
  1192             // Now check whether next handler in the event handler array still
       
  1193             // matches with the stored pointer.
       
  1194             if ( nextHandler )
       
  1195                 {
       
  1196                 // Check whether the event handler at index i+1 is still the 
       
  1197                 // same as before calling offerEvent. If not, the array has 
       
  1198                 // been modified and the variable i needs to be set again. 
       
  1199                 if ( i+1 >= eventHandlerArray.count() ||
       
  1200                      (i+1 < eventHandlerArray.count() && 
       
  1201                      eventHandlerArray[i+1] != nextHandler) )
       
  1202                     {
       
  1203                     // Array has changed in offerEvent, the handler at index 
       
  1204                     // 'i+1' is not the same any more. Find the index of the 
       
  1205                     // current event handler again in the array and fix the
       
  1206                     // loop variable 'i' point to that and continue.
       
  1207                     int newCount = eventHandlerArray.count();
       
  1208                     for ( int j = 0 ; j < newCount ; j++ )
       
  1209                         {
       
  1210                         if ( eventHandlerArray[j] == eventHandler )
       
  1211                             {
       
  1212                             i = j;
       
  1213                             break;
       
  1214                             }
       
  1215                         }
       
  1216                     
       
  1217                     }
       
  1218                 }                        
       
  1219             }
       
  1220         }
       
  1221         
       
  1222     return ret;
       
  1223     }
       
  1224 
       
  1225 // from base class IAlfModelChangeObserver
       
  1226 
       
  1227 OSN_EXPORT void CAlfWidgetControl::modelChanged( IAlfModel& aModel )
       
  1228     {
       
  1229     (void)aModel;
       
  1230     // This way the model change animation is customizable using event handlers
       
  1231     // The default event handler could implement this:
       
  1232     destroyPresentation( 0 );
       
  1233     updatePresentation();
       
  1234     updateParentLayout();
       
  1235     }
       
  1236 
       
  1237 OSN_EXPORT void CAlfWidgetControl::dataChanging(
       
  1238     const AlfPtrVector<AlfModelOperation>& aOperations )
       
  1239     {
       
  1240     for ( int i = 0; i < aOperations.count(); ++i )
       
  1241         {
       
  1242         dataChanging( *aOperations[i] );
       
  1243         }
       
  1244     }
       
  1245 
       
  1246 OSN_EXPORT void CAlfWidgetControl::dataChanging(
       
  1247     const AlfModelOperation& aOperation )
       
  1248     {
       
  1249     int numIndices = aOperation.numContainerIndices();
       
  1250     if ( !mWdgtControlData->mWidget->model() || numIndices <= 0 )
       
  1251         {
       
  1252         return;
       
  1253         }
       
  1254     uint dataId = 0, parentDataId = 0;
       
  1255     IAlfElement* element = 0;
       
  1256     IAlfElement* parentElement = 0;
       
  1257     IAlfVariantType* data = mWdgtControlData->mWidget->model()->data();
       
  1258     if(data == 0)
       
  1259         {
       
  1260         return;
       
  1261         }
       
  1262     IAlfBranch* parentBranch = 0;
       
  1263     // Traverse the data hierarchy to find the data, dataId and the element
       
  1264     for ( int i = 0; i < numIndices; ++i )
       
  1265         {
       
  1266         int index = aOperation.containerIndex( i );
       
  1267         if ( data->type() == IAlfVariantType::EMap  &&
       
  1268                 index >= 0 && index < data->map()->count() )
       
  1269             {
       
  1270             parentElement = element;
       
  1271             element = findElement( data->map()->name( index ).getUtf8() );
       
  1272             if ( element == 0 )
       
  1273                 {
       
  1274                 return; // Not found
       
  1275                 }
       
  1276             IAlfMap* map = data->map();
       
  1277             data = data->map()->item( index );
       
  1278 
       
  1279             if ( data->type() == IAlfVariantType::EContainer )
       
  1280                 {
       
  1281                 ++i;
       
  1282                 int containerIndex = aOperation.containerIndex( i );
       
  1283                 if ( containerIndex < 0 || 
       
  1284                        containerIndex >= data->container()->count() )
       
  1285                     {
       
  1286                     break; // Not found
       
  1287                     }
       
  1288                 int childInd = 
       
  1289                     childIndex( *map, index, containerIndex, i == 1 );
       
  1290                 parentDataId = dataId;
       
  1291                 dataId = elementDataId( *element, childInd, parentDataId );
       
  1292                 data = data->container()->item( containerIndex );
       
  1293                 }
       
  1294             else
       
  1295                 {
       
  1296                 int childInd = childIndex( *map, index, 0, i == 0 );
       
  1297                 parentDataId = dataId;
       
  1298                 dataId = elementDataId( *element, childInd, parentDataId );
       
  1299                 }
       
  1300             }
       
  1301         else if ( data->type() == IAlfVariantType::EBranch &&
       
  1302                   index == 0 && i == numIndices - 1 )
       
  1303             {
       
  1304             // Changing the parent data
       
  1305             data = data->branch()->data();
       
  1306             }
       
  1307         else if ( data->type() == IAlfVariantType::EBranch && index == 1 )
       
  1308             {
       
  1309             parentBranch = data->branch();
       
  1310             data = data->branch()->childData();
       
  1311             }
       
  1312         else
       
  1313             {
       
  1314             return; // Not found
       
  1315             }
       
  1316         }
       
  1317 
       
  1318     // Perform the operation
       
  1319     if ( aOperation.operation() == AlfModelOperation::EOperationAdd )
       
  1320         {
       
  1321         if ( parentBranch )
       
  1322             {
       
  1323             // The parent is responsible for it's children
       
  1324             parentElement->createChildVisualTree( 
       
  1325                                element, aOperation.newData(),
       
  1326                                *parentBranch,aOperation.index(),
       
  1327                                parentDataId );
       
  1328             }
       
  1329         else
       
  1330             {
       
  1331             if(element)
       
  1332                 {
       
  1333                 // Data added to a root element
       
  1334                 try
       
  1335                     {
       
  1336                     element->createVisualTree(
       
  1337                                  aOperation.newData(), dataId,
       
  1338                                  element->defaultParentLayout( parentDataId ),
       
  1339                                  aOperation.index() );
       
  1340                     }
       
  1341                 catch (...)
       
  1342                     {
       
  1343                     ALF_THROW(AlfVisualException,ECanNotCreateVisual,"CAlfWidgetControl::dataChanging failed")
       
  1344                     }               
       
  1345                 }
       
  1346             else
       
  1347                 {
       
  1348                 ALF_THROW(AlfVisualException,ECanNotCreateVisual,"CAlfWidgetControl::dataChanging failed")
       
  1349                 }
       
  1350 
       
  1351             }
       
  1352         }
       
  1353     else if ( aOperation.operation() == AlfModelOperation::EOperationRemove )
       
  1354         {
       
  1355         if ( parentBranch )
       
  1356             {
       
  1357             // The parent is responsible for it's children
       
  1358             parentElement->removeChildVisualTree(
       
  1359                 element, *parentBranch, aOperation.index(), parentDataId );
       
  1360             }
       
  1361         else
       
  1362             {
       
  1363             if(element)
       
  1364                 {
       
  1365                 // Data removed from a root element
       
  1366                 element->removeVisualTree( *data, dataId );
       
  1367                 }
       
  1368             }
       
  1369         }
       
  1370     else if ( aOperation.operation() == AlfModelOperation::EOperationUpdate )
       
  1371         {
       
  1372         if(element)
       
  1373             {
       
  1374             element->updateVisualTree( aOperation.newData(), *data, dataId );            
       
  1375             }
       
  1376         }
       
  1377     }
       
  1378 
       
  1379 OSN_EXPORT void CAlfWidgetControl::dataChanged()
       
  1380     {
       
  1381     // The default implementation is empty.
       
  1382     }
       
  1383 
       
  1384 uint CAlfWidgetControl::childIndex(
       
  1385     IAlfMap& aMap, uint aMapIndex,
       
  1386     uint aContainerIndex, bool aRoot )
       
  1387     {
       
  1388     // This method is only used internally
       
  1389     const UString& elementName = aMap.name( aMapIndex );
       
  1390     int index = 0;
       
  1391     for ( int i = 0; i < aMapIndex && i < aMap.count(); ++i )
       
  1392         {
       
  1393         if ( !aRoot || elementName == aMap.name( i ) )
       
  1394             {
       
  1395             IAlfVariantType* data = aMap.item( i );
       
  1396             if ( data->type() == IAlfVariantType::EMap ||
       
  1397                     data->type() == IAlfVariantType::EBranch)
       
  1398                 {
       
  1399                 index++;
       
  1400                 }
       
  1401             else if ( data->type() == IAlfVariantType::EContainer )
       
  1402                 {
       
  1403                 index += data->container()->count();
       
  1404                 }
       
  1405             }
       
  1406         }
       
  1407     return index + aContainerIndex;
       
  1408     }
       
  1409 
       
  1410 // ---------------------------------------------------------------------------
       
  1411 // From class IAlfInterfaceBase.
       
  1412 // Getter for interfaces provided by the control.
       
  1413 // ---------------------------------------------------------------------------
       
  1414 //
       
  1415 OSN_EXPORT IAlfInterfaceBase* CAlfWidgetControl::makeInterface(
       
  1416     const IfId& aType )
       
  1417     {
       
  1418     IAlfInterfaceBase* interface = 0;
       
  1419     UString param(aType.mImplementationId);
       
  1420     if ( param == IAlfWidgetControl::type().mImplementationId )
       
  1421         {
       
  1422         return static_cast<IAlfWidgetControl*>( this );
       
  1423         }
       
  1424     else if (param == IAlfAttributeOwner::type().mImplementationId)
       
  1425         {
       
  1426         return 0; // control does not have AttributeOwner instance
       
  1427         		  // and do not try get IF from elements in control
       
  1428         }
       
  1429     // Let the layout manager create the interface that is queried.
       
  1430     else if(mWdgtControlData->mAlfHostAPIImpl.get())
       
  1431     	{
       
  1432     	IAlfLayoutManager* layoutManager = 
       
  1433     	    mWdgtControlData->mAlfHostAPIImpl->getBaseLayout();
       
  1434     	if(layoutManager)
       
  1435     		{
       
  1436     		interface = layoutManager->makeInterface(aType);
       
  1437     		}
       
  1438     	}
       
  1439 
       
  1440     if(interface == 0)
       
  1441     	{
       
  1442         //go through all the elements    
       
  1443         for (int i = 0; i < numElements() && !interface; i++)
       
  1444             {
       
  1445             IAlfElement& ele = element(i);
       
  1446             interface = ele.makeInterface(aType);
       
  1447             }
       
  1448     	}
       
  1449 
       
  1450     return interface;
       
  1451     }
       
  1452 
       
  1453 
       
  1454 OSN_EXPORT CAlfLayout* CAlfWidgetControl::ContainerLayout(
       
  1455     const CAlfControl* /*aConnected*/) const
       
  1456     {
       
  1457     if(mWdgtControlData->mAlfHostAPIImpl.get() != 0)
       
  1458         {
       
  1459         IAlfLayoutManager* layoutManager = 
       
  1460             mWdgtControlData->mAlfHostAPIImpl->getBaseLayout();
       
  1461         if(layoutManager != 0)
       
  1462         	{
       
  1463         	return &layoutManager->getLayout();
       
  1464         	}
       
  1465         }
       
  1466     return 0;
       
  1467     }
       
  1468 
       
  1469     
       
  1470 OSN_EXPORT void CAlfWidgetControl::AcquireFocus()
       
  1471     {
       
  1472     if (!FocusedConnection() && isFocusable())
       
  1473         {
       
  1474         if (isContainer())
       
  1475             {
       
  1476             IAlfHostAPI& hostApi = hostAPI();
       
  1477             //select the first connection.
       
  1478             
       
  1479             CAlfWidgetControl* firstChild = nextFocusableControl(0);
       
  1480             if (firstChild)
       
  1481                 {
       
  1482                 firstChild->AcquireFocus();
       
  1483                 }
       
  1484             }
       
  1485         else
       
  1486             {
       
  1487             CAlfControl::AcquireFocus();
       
  1488             }
       
  1489         }
       
  1490     }
       
  1491     
       
  1492 OSN_EXPORT void CAlfWidgetControl::RelinquishFocus()
       
  1493     {
       
  1494     if (Focus())
       
  1495         {
       
  1496         if (isContainer())
       
  1497             {
       
  1498             handleFocusNext();
       
  1499             }
       
  1500         else
       
  1501             {
       
  1502             //get parent control, check if it can focus next control.
       
  1503             CAlfWidgetControl* parent = 
       
  1504                 dynamic_cast<CAlfWidgetControl*>(Host());
       
  1505             if (parent)
       
  1506                 {
       
  1507                 parent->handleFocusNext();
       
  1508                 }
       
  1509                 
       
  1510             CAlfControl::RelinquishFocus();
       
  1511             }
       
  1512         }
       
  1513     }
       
  1514     
       
  1515 // ---------------------------------------------------------------------------
       
  1516 // return hostapi. create instance if needed.
       
  1517 // ---------------------------------------------------------------------------
       
  1518 //
       
  1519 IAlfHostAPI& CAlfWidgetControl::hostAPI()
       
  1520     {
       
  1521     if (!mWdgtControlData->mAlfHostAPIImpl.get()) // was it already created?
       
  1522         {
       
  1523         //late creation
       
  1524         mWdgtControlData->mAlfHostAPIImpl.reset( new (EMM) AlfHostAPIImpl() ); 
       
  1525         mWdgtControlData->mAlfHostAPIImpl->setHostControl(*this);
       
  1526         }
       
  1527         
       
  1528     return *mWdgtControlData->mAlfHostAPIImpl.get();
       
  1529     }
       
  1530     
       
  1531 OSN_EXPORT bool CAlfWidgetControl::handleFocusNext()
       
  1532     {
       
  1533     bool focusChanged = false;
       
  1534     if (isContainer())
       
  1535         {
       
  1536         CAlfWidgetControl* focused = 
       
  1537             dynamic_cast<CAlfWidgetControl*>(FocusedConnection());
       
  1538         if (focused)
       
  1539             {
       
  1540             CAlfWidgetControl* nextChild = nextFocusableControl(focused);
       
  1541                 
       
  1542             if (!nextChild)
       
  1543                 {
       
  1544                 //no next child, change focus to upper level, if that fails,
       
  1545                 //loop to first connection. 
       
  1546                 CAlfWidgetControl* parent = 
       
  1547                     dynamic_cast<CAlfWidgetControl*>(Host());
       
  1548                 if (parent)
       
  1549                     {
       
  1550                     focusChanged = parent->handleFocusNext();
       
  1551                     }
       
  1552                 if (!focusChanged)
       
  1553                     {
       
  1554                     //loop to first connection. 
       
  1555                     nextChild = nextFocusableControl(0);
       
  1556                     }
       
  1557                 }
       
  1558                 
       
  1559             //go deeper down the widget hierarchy, until a no-container widget
       
  1560             // is found
       
  1561             while(nextChild && nextChild->isContainer())
       
  1562                 {
       
  1563                 nextChild = nextChild->nextFocusableControl(0);
       
  1564                 }
       
  1565                 
       
  1566             if (nextChild)
       
  1567                 {
       
  1568                 nextChild->AcquireFocus();
       
  1569                 focusChanged = true;
       
  1570                 }
       
  1571             }
       
  1572         }
       
  1573     return focusChanged;
       
  1574     }
       
  1575     
       
  1576 OSN_EXPORT bool CAlfWidgetControl::handleFocusPrevious()
       
  1577     {
       
  1578     bool focusChanged = false;
       
  1579     if (isContainer())
       
  1580         {
       
  1581 
       
  1582         CAlfWidgetControl* focused = 
       
  1583             dynamic_cast<CAlfWidgetControl*>(FocusedConnection());
       
  1584         if (focused)
       
  1585             {
       
  1586             CAlfWidgetControl* prevChild = previousFocusableControl(
       
  1587                 focused);
       
  1588 
       
  1589             if (!prevChild)
       
  1590                 {
       
  1591                 // no previous child, change focus to upper level, if that 
       
  1592                 // fails, loop to last connection.
       
  1593                 CAlfWidgetControl* parent = 
       
  1594                     dynamic_cast<CAlfWidgetControl*>(Host());
       
  1595                 if (parent)
       
  1596                     {
       
  1597                     focusChanged = parent->handleFocusPrevious();
       
  1598                     }
       
  1599                 if (!focusChanged)
       
  1600                     {                    
       
  1601                     //loop to last connection.
       
  1602                     prevChild = previousFocusableControl(0);
       
  1603                     }
       
  1604                 }
       
  1605             //go deeper down the widget hierarchy, until a no-container widget
       
  1606             //is found. 
       
  1607             while(prevChild && prevChild->isContainer())
       
  1608                 {
       
  1609                 //in each level, select the last focused widget.
       
  1610                 prevChild = prevChild->previousFocusableControl(0);
       
  1611                 }
       
  1612                 
       
  1613             if (prevChild)
       
  1614                 {
       
  1615                 prevChild->AcquireFocus();
       
  1616                 focusChanged = true;
       
  1617                 }
       
  1618             }
       
  1619         }
       
  1620         
       
  1621     return focusChanged;
       
  1622     }
       
  1623         
       
  1624 OSN_EXPORT CAlfWidgetControl* CAlfWidgetControl::getFirstFocusable(
       
  1625     IAlfContainerWidget& aContainer)
       
  1626     {
       
  1627     CAlfWidgetControl* control = 0;
       
  1628     if (aContainer.widgetCount() > 0)
       
  1629         {
       
  1630         control = aContainer.getWidget(0)->control();
       
  1631         }
       
  1632     return control;
       
  1633     }
       
  1634 
       
  1635 OSN_EXPORT CAlfWidgetControl* CAlfWidgetControl::getLastFocusable(
       
  1636     IAlfContainerWidget& aContainer)
       
  1637     {
       
  1638     CAlfWidgetControl* control = 0;
       
  1639     if (aContainer.widgetCount() > 0)
       
  1640         {
       
  1641         IAlfWidget* w = aContainer.getWidget(aContainer.widgetCount()-1);
       
  1642         control = w->control();
       
  1643         }
       
  1644     return control;
       
  1645     }
       
  1646     
       
  1647 OSN_EXPORT CAlfWidgetControl* CAlfWidgetControl::getFocusableAfter(
       
  1648     IAlfContainerWidget& aContainer,
       
  1649     CAlfWidgetControl& aControl)
       
  1650     {
       
  1651     CAlfWidgetControl* control = 0;
       
  1652     int ind = aContainer.getWidgetIndex(*aControl.widget());
       
  1653     if (ind >= 0)
       
  1654         {
       
  1655         ind++;
       
  1656         if (ind < aContainer.widgetCount())
       
  1657             {
       
  1658             IAlfWidget* w = aContainer.getWidget(ind);
       
  1659             control = w->control();
       
  1660             }
       
  1661         }
       
  1662         
       
  1663     return control;
       
  1664     }
       
  1665 
       
  1666 OSN_EXPORT CAlfWidgetControl* CAlfWidgetControl::getFocusableBefore(
       
  1667     IAlfContainerWidget& aContainer, CAlfWidgetControl& aControl)
       
  1668     {
       
  1669     CAlfWidgetControl* control = 0;
       
  1670     int ind = aContainer.getWidgetIndex(*aControl.widget());
       
  1671     ind--;
       
  1672     if (ind >= 0)
       
  1673         {
       
  1674         IAlfWidget* w = aContainer.getWidget(ind);
       
  1675         control = w->control();
       
  1676         }
       
  1677         
       
  1678     return control;
       
  1679     }
       
  1680     
       
  1681 void CAlfWidgetControl::resetControlGroup(CAlfControlGroup& aControlGroup)
       
  1682     {
       
  1683     // If control group is already set and its same than the control group
       
  1684     // given as a parameter there's nothing we need to do.
       
  1685     if(!ControlGroup() || (ControlGroup() != &aControlGroup))
       
  1686         {
       
  1687         // Remove control from previous control group
       
  1688         if(ControlGroup())
       
  1689             {
       
  1690             ControlGroup()->Remove(this);
       
  1691             }
       
  1692         // Append control to the new control group
       
  1693         TRAPD(err, aControlGroup.AppendL(this));
       
  1694         if(err != KErrNone)
       
  1695             {
       
  1696             ALF_THROW(AlfException, err, "CAlfWidgetControl::resetControlGroup - Appending control to a new control group failed.");
       
  1697             }                    
       
  1698         }
       
  1699     }
       
  1700 
       
  1701 void CAlfWidgetControl::resetHierarchyControlGroup(
       
  1702     CAlfControlGroup& aControlGroup)
       
  1703     {
       
  1704     // Append this control to the new control group
       
  1705     resetControlGroup(aControlGroup);
       
  1706         
       
  1707     // Call this recursively to all connected controls
       
  1708     AlfHostAPIImpl* hostApi = mWdgtControlData->mAlfHostAPIImpl.get();
       
  1709     if(hostApi != 0)
       
  1710         {
       
  1711         for(int i = 0; i < hostApi->getConnectionCount(); ++i)
       
  1712             {
       
  1713             CAlfWidgetControl* connectedControl = hostApi->getConnection(i);
       
  1714             if(connectedControl)
       
  1715                 {
       
  1716                 connectedControl->resetHierarchyControlGroup(aControlGroup);
       
  1717                 }
       
  1718             }
       
  1719         }    
       
  1720     }
       
  1721     
       
  1722     
       
  1723 OSN_EXPORT void CAlfWidgetControl::FocusChanged(
       
  1724     CAlfDisplay& /*aDisplay*/,
       
  1725     TBool aFocused)
       
  1726     {
       
  1727     // Ensure that the state bit remains synched to the toolkit's version
       
  1728     if (aFocused)
       
  1729         {
       
  1730         mWdgtControlData->mState |= IAlfWidgetControl::Focused;
       
  1731         }
       
  1732     else
       
  1733         {
       
  1734         mWdgtControlData->mState &=~ IAlfWidgetControl::Focused;
       
  1735         }
       
  1736 
       
  1737     if (aFocused)
       
  1738         {
       
  1739         processEvent(TAlfEvent(EEventWidgetGainedFocus));
       
  1740         }
       
  1741     else
       
  1742         {
       
  1743         processEvent(TAlfEvent(EEventWidgetLostFocus));
       
  1744         }
       
  1745     }
       
  1746     
       
  1747 OSN_EXPORT CAlfWidgetControl* CAlfWidgetControl::nextFocusableControl(
       
  1748     CAlfWidgetControl* aControl)
       
  1749     {
       
  1750     CAlfWidgetControl* control = 0;
       
  1751     
       
  1752     if (isContainer())
       
  1753         {
       
  1754         IAlfContainerWidget* container = 
       
  1755             IAlfInterfaceBase::makeInterface<IAlfContainerWidget>(widget());
       
  1756         
       
  1757         assert(container);
       
  1758         
       
  1759         if (!aControl)
       
  1760             {
       
  1761             control = getFirstFocusable(*container);
       
  1762             }
       
  1763         else
       
  1764             {
       
  1765             control = getFocusableAfter(*container, *aControl);
       
  1766             }
       
  1767             
       
  1768         while(control && !control->isFocusable())
       
  1769             {
       
  1770             control = control->getFocusableAfter(*container, *control);
       
  1771             }
       
  1772         }
       
  1773         
       
  1774     return control;
       
  1775     }
       
  1776     
       
  1777 OSN_EXPORT CAlfWidgetControl* CAlfWidgetControl::previousFocusableControl(
       
  1778     CAlfWidgetControl* aControl)
       
  1779     {
       
  1780     CAlfWidgetControl* control = 0;
       
  1781     
       
  1782     if (isContainer())
       
  1783         {
       
  1784         IAlfContainerWidget* container = 
       
  1785             IAlfInterfaceBase::makeInterface<IAlfContainerWidget>(widget());
       
  1786         
       
  1787         assert(container);
       
  1788         
       
  1789         if (!aControl)
       
  1790             {
       
  1791             control = getLastFocusable(*container);
       
  1792             }
       
  1793         else
       
  1794             {
       
  1795             control = getFocusableBefore(*container, *aControl);
       
  1796             }
       
  1797             
       
  1798         while(control && !control->isFocusable())
       
  1799             {
       
  1800             control = control->getFocusableBefore(*container, *control);
       
  1801             }
       
  1802         }
       
  1803         
       
  1804     return control;
       
  1805     }
       
  1806 
       
  1807 
       
  1808 // ---------------------------------------------------------------------------
       
  1809 // ---------------------------------------------------------------------------
       
  1810 //
       
  1811 void CAlfWidgetControl::enableStateVisible()
       
  1812     {
       
  1813     // Only take action if the current state is different
       
  1814     if ( !(mWdgtControlData->mState & IAlfWidgetControl::Visible) )
       
  1815         {
       
  1816         // Update the new state in member variable
       
  1817         mWdgtControlData->mState |= IAlfWidgetControl::Visible;
       
  1818 
       
  1819         }    
       
  1820     }
       
  1821 
       
  1822 // ---------------------------------------------------------------------------
       
  1823 // ---------------------------------------------------------------------------
       
  1824 //
       
  1825 void CAlfWidgetControl::disableStateVisible()
       
  1826     {
       
  1827     // Only take action if the current state is different
       
  1828     if ( mWdgtControlData->mState & IAlfWidgetControl::Visible )
       
  1829         {
       
  1830         // Update the new state in member variable
       
  1831         mWdgtControlData->mState &= ~IAlfWidgetControl::Visible;
       
  1832         }    
       
  1833     }
       
  1834 
       
  1835 // ---------------------------------------------------------------------------
       
  1836 // ---------------------------------------------------------------------------
       
  1837 //
       
  1838 void CAlfWidgetControl::enableStateEnabled()
       
  1839     {
       
  1840     // Only take action if the current state is different
       
  1841     if ( !(mWdgtControlData->mState & IAlfWidgetControl::Enabled) )
       
  1842         {
       
  1843         // Update the new state in member variable
       
  1844         mWdgtControlData->mState |= IAlfWidgetControl::Enabled;
       
  1845         }        
       
  1846     }
       
  1847 
       
  1848 // ---------------------------------------------------------------------------
       
  1849 // ---------------------------------------------------------------------------
       
  1850 //
       
  1851 void CAlfWidgetControl::disableStateEnabled()
       
  1852     {
       
  1853     // Only take action if the current state is different
       
  1854     if ( mWdgtControlData->mState & IAlfWidgetControl::Enabled )
       
  1855         {
       
  1856         // Update the new state in member variable
       
  1857         mWdgtControlData->mState &= ~IAlfWidgetControl::Enabled;
       
  1858         }
       
  1859     }
       
  1860 
       
  1861 // ---------------------------------------------------------------------------
       
  1862 // ---------------------------------------------------------------------------
       
  1863 //
       
  1864 void CAlfWidgetControl::enableStateFocused()
       
  1865     {
       
  1866     // Only take action if the current state is different
       
  1867     if ( !(mWdgtControlData->mState & IAlfWidgetControl::Focused) )
       
  1868         {
       
  1869         // Set the new state
       
  1870         AcquireFocus();
       
  1871         
       
  1872         // Update the new state in member variable
       
  1873         mWdgtControlData->mState |= IAlfWidgetControl::Focused;
       
  1874         }
       
  1875     }
       
  1876 
       
  1877 // ---------------------------------------------------------------------------
       
  1878 // ---------------------------------------------------------------------------
       
  1879 //
       
  1880 void CAlfWidgetControl::disableStateFocused()
       
  1881     {
       
  1882     // Only take action if the current state is different
       
  1883     if ( mWdgtControlData->mState & IAlfWidgetControl::Focused )
       
  1884         {
       
  1885         // Set the new state
       
  1886         RelinquishFocus();
       
  1887         
       
  1888         // Update the new state in member variable
       
  1889         mWdgtControlData->mState &= ~IAlfWidgetControl::Focused;
       
  1890         }        
       
  1891     }
       
  1892 
       
  1893 // ---------------------------------------------------------------------------
       
  1894 // ---------------------------------------------------------------------------
       
  1895 //
       
  1896 void CAlfWidgetControl::enableStateFocusable()
       
  1897     {
       
  1898     // Only take action if the current state is different
       
  1899     if ( !(mWdgtControlData->mState & IAlfWidgetControl::Focusable) )
       
  1900         {
       
  1901         // Update the new state in member variable
       
  1902         mWdgtControlData->mState |= IAlfWidgetControl::Focusable;
       
  1903         }    
       
  1904     }
       
  1905 
       
  1906 // ---------------------------------------------------------------------------
       
  1907 // ---------------------------------------------------------------------------
       
  1908 //
       
  1909 void CAlfWidgetControl::disableStateFocusable()
       
  1910     {
       
  1911     // Only take action if the current state is different
       
  1912     if ( mWdgtControlData->mState & IAlfWidgetControl::Focusable )
       
  1913         {
       
  1914         // Update the new state in member variable
       
  1915         mWdgtControlData->mState &= ~IAlfWidgetControl::Focusable;
       
  1916         }    
       
  1917     }
       
  1918 
       
  1919 void CAlfWidgetControl::checkStateInvariants(uint aState)
       
  1920     {
       
  1921     // To be focused, it needs to be focusable (Focus -> Focusable)
       
  1922     if(aState & IAlfWidgetControl::Focused 
       
  1923     &&  !(aState & IAlfWidgetControl::Focusable)  )
       
  1924         {
       
  1925         ALF_THROW(AlfException, EInvalidArgument, "AlfWidgetControl() - state changing operation. Illegal state would result.");
       
  1926         }
       
  1927 
       
  1928     // To be focusable, it needs to be enabled (Focusable -> Enabled)
       
  1929     if(aState & IAlfWidgetControl::Focusable 
       
  1930     &&  !(aState & IAlfWidgetControl::Enabled)  )
       
  1931         {
       
  1932         ALF_THROW(AlfException, EInvalidArgument, "AlfWidgetControl() - state changing operation. Illegal state would result.");
       
  1933         }
       
  1934     }
       
  1935 
       
  1936 void CAlfWidgetControl::predictAndCheckStateInvariants(
       
  1937     uint aChangePattern,
       
  1938     bool aEnabling) const
       
  1939     {
       
  1940     uint predictedState(mWdgtControlData->mState);
       
  1941     if(aEnabling)
       
  1942         {
       
  1943         predictedState |= aChangePattern;
       
  1944         }
       
  1945     else
       
  1946         {
       
  1947         predictedState &= ~aChangePattern;
       
  1948         }
       
  1949     checkStateInvariants(predictedState);
       
  1950     }
       
  1951 
       
  1952 
       
  1953 } // namespace Alf
       
  1954