javauis/lcdui_akn/lcdui/src/CMIDDisplayable.cpp
branchRCL_3
changeset 14 04becd199f91
child 17 0fd27995241b
equal deleted inserted replaced
13:f5050f1da672 14:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2003-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:  Implementation of the CMIDDisplayable class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <bldvariant.hrh>
       
    20 
       
    21 #include <memory>
       
    22 #include <apgwgnam.h>
       
    23 #include <eikenv.h>
       
    24 #include <coecntrl.h>
       
    25 #include <uikon.hrh>
       
    26 // using BaflUtils::CopyWithTruncation in PopulateMenuItemsWithListL function
       
    27 #include <bautils.h>
       
    28 // using MMIDImage and MMIDBitmapImage
       
    29 #include <lcdgr.h>
       
    30 // macros definitions for resources
       
    31 #include <lcdui.rsg>
       
    32 // using TMifLcdui enumeration
       
    33 #include <lcdui.mbg>
       
    34 // Used for Avkon toolbar disabling
       
    35 #include <akntoolbar.h>
       
    36 // Layout data
       
    37 #include <layoutmetadata.cdl.h>
       
    38 #include <aknlayoutscalable_avkon.cdl.h>
       
    39 #include <e32property.h>
       
    40 //#include <SysStartup.h>
       
    41 #include <aknappui.h>
       
    42 // using CAknTitlePane in ShowTitleL() function
       
    43 #include <akntitle.h>
       
    44 // using CAknContextPane in SetMIDletIconL() function to show midlet icon
       
    45 #include <akncontext.h>
       
    46 // used for label converting for commands (in PopulateMenuItemsWithListL function)
       
    47 #include <AknBidiTextUtils.h>
       
    48 #include <avkon.hrh>
       
    49 #include <avkon.rsg>
       
    50 #include <AvkonInternalCRKeys.h>
       
    51 #include <aknstyluspopupmenu.h>
       
    52 #include <eiklabel.h>
       
    53 #ifdef RD_SCALABLE_UI_V2
       
    54 // For requiring available keyboards in the device
       
    55 #include <PtiEngine.h>
       
    56 #include <PtiDefs.h>
       
    57 #endif // RD_SCALABLE_UI_V2
       
    58 
       
    59 // OMJ storage
       
    60 #include <applicationinfo.h>
       
    61 #include <javastorageentry.h>
       
    62 #include <javastorage.h>
       
    63 #include <javastoragenames.h>
       
    64 #include <javauid.h>
       
    65 #include <javasymbianoslayer.h>
       
    66 
       
    67 #include "CMIDDisplayable.h"
       
    68 // API used in several places (iAppUi is member)
       
    69 #include "CMIDAppUi.h"
       
    70 #include "CMIDCanvas.h"
       
    71 // used in SetComponentL function
       
    72 #include "CMIDDefaultBackground.h"
       
    73 // API for ticker on displayable
       
    74 #include "CMIDTicker.h"
       
    75 #include "CMIDComponentFactory.h"
       
    76 // used for setting iMenuHandler from iUIManager (MenuHandler)
       
    77 #include "CMIDUIManager.h"
       
    78 #include "CMIDCommand.h"
       
    79 #include "CMIDForm.h"
       
    80 // using CMIDUtils::CopyBitmapL in SetMIDletIconL() function
       
    81 #include "CMIDUtils.h"
       
    82 // used in SetComponentL function
       
    83 // and used in several place for actions specific for Alert (SetTitleL, ContentSize, HandleCurrentL)
       
    84 #include "CMIDAlert.h"
       
    85 #include "CMIDAlertDialog.h"
       
    86 #include "CMIDEdwin.h"
       
    87 // used in SetComponentL function
       
    88 // used in HandleCurrentL function
       
    89 #include "CMIDTextBoxControl.h"
       
    90 #include "CMIDTextBoxDialogControl.h"
       
    91 // used in SetComponentL function
       
    92 #include "CMIDList.h"
       
    93 // using API for softkeys and their commands
       
    94 #include "CMIDSoftKey.h"
       
    95 #include "CMIDCanvasKeypad.h"
       
    96 #include "CMIDTicker.h"
       
    97 
       
    98 #include "coreuiavkonlcdui.h"
       
    99 #include "coreuiappui.h"
       
   100 
       
   101 #include <j2me/jdebug.h>
       
   102 
       
   103 /** This macro is executed each time a trapped call returns an error code different than KErrNone */
       
   104 #undef  TRAP_INSTRUMENTATION_LEAVE
       
   105 #define TRAP_INSTRUMENTATION_LEAVE(aResult) DEBUG_INT2("In CMIDDisplayable.cpp, trapped method was called at line %D and got exception %D", __LINE__, aResult);
       
   106 
       
   107 const TGulBorder::TBorderType KMIDLetBorder = TGulBorder::EThickDeepRaisedWithOutline;
       
   108 
       
   109 const TInt KCommandIdNotFound = -10000;
       
   110 const TInt KCommandIdBase = 7000;
       
   111 const TInt KItemCommandIdBase = 8000; // must be greater than KCommandIdBase
       
   112 // Special ID for built-in MSK commands. Handling of them is different because
       
   113 // built-in commands are not visible in menus, only in MSK. Built-in MSK commands
       
   114 // are commands that are set using SetMSKCommand method, but are not found in
       
   115 // command lists.
       
   116 const TInt KBuiltInMSKCommandId = 9000;
       
   117 
       
   118 // Index of the MSK in CBA, to be used when adding MSK command to CBA
       
   119 const TInt KMSKPositionInCBA = 3;
       
   120 
       
   121 /** The maximum number of softkeys on the device.
       
   122 */
       
   123 const TInt KMaxNumberOfSoftKeys = 2;
       
   124 const TInt KListLongTapAnimationDelay = 400000;
       
   125 const TInt KListLongTapDelay = 800000;
       
   126 
       
   127 
       
   128 /*
       
   129  * The allowed command types for softkeys,
       
   130  *   -1 means we have run out of allowed types.
       
   131  * More restrictive sks, eg the right sk, should come
       
   132  * before more permissive sks. This array is used to
       
   133  * initialise iSoftkeys.
       
   134  */
       
   135 const TInt KAllowedCommandTypesForSoftkeys[KMaxNumberOfSoftKeys][9] =
       
   136 {
       
   137     // Right softkey
       
   138     {
       
   139         MMIDCommand::EStop,
       
   140         MMIDCommand::ECancel,
       
   141         MMIDCommand::EBack,
       
   142         MMIDCommand::EExit,
       
   143         -1,
       
   144         -1,
       
   145         -1,
       
   146         -1,
       
   147         -1
       
   148     },
       
   149 
       
   150     // Left softkey
       
   151     {
       
   152         MMIDCommand::EStop,
       
   153         MMIDCommand::EOk,
       
   154         MMIDCommand::ECancel,
       
   155         MMIDCommand::EItem,
       
   156         MMIDCommand::EScreen,
       
   157         MMIDCommand::EBack,
       
   158         MMIDCommand::EHelp,
       
   159         MMIDCommand::EExit,
       
   160         -1
       
   161     }
       
   162 };
       
   163 
       
   164 /**
       
   165   The CBA that can have an options menu if commands are available.
       
   166   This is used as a zero-based index in iSoftkeys and must be
       
   167   less than KMaxNumberOfSoftKeys.
       
   168 */
       
   169 const TInt KOptionsMenuCBAIndex = 1; //left sk
       
   170 
       
   171 /**
       
   172   The sk position in the CBA. Must use the same ordering as
       
   173   KAllowedCommandTypesForSoftkeys and is used to initialise
       
   174   iSoftkeys.
       
   175 */
       
   176 const TInt KPositionsInCBAForSoftkeys[KMaxNumberOfSoftKeys] =
       
   177 {
       
   178     2, //Right softkey
       
   179     0 //Left softkey
       
   180 };
       
   181 
       
   182 // One ticker can be added more than one displayable. So keep track of all of them
       
   183 const TInt KAddDisplayable = 1; // add the displable to the list in ticker
       
   184 const TInt KRemoveDisplayable = 0; // Remove the displable from the list in ticker
       
   185 
       
   186 const TInt KSoftKeyLabelPropertyPositionsMSKIndex = 2;
       
   187 const TInt KSoftKeyLabelPropertyPositionsInCBA[ KSoftKeyLabelPropertyNumberOfSoftKeys ] =
       
   188 {
       
   189     0,  //LSK
       
   190     2,  //RSK
       
   191     3   //MSK
       
   192 };
       
   193 
       
   194 // class CMIDDisplayable
       
   195 
       
   196 CMIDDisplayable* CMIDDisplayable::NewL(MMIDEnv& aEnv,CMIDUIManager& aUIManager)
       
   197 {
       
   198     CMIDDisplayable* displayable = new(ELeave)CMIDDisplayable(aEnv,aUIManager);
       
   199     CleanupStack::PushL(displayable);
       
   200     displayable->ConstructL();
       
   201     CleanupStack::Pop(displayable);
       
   202     return displayable;
       
   203 }
       
   204 
       
   205 // ---------------------------------------------------------------------------
       
   206 //
       
   207 // ---------------------------------------------------------------------------
       
   208 //
       
   209 void CMIDDisplayable::ConstructL()
       
   210 {
       
   211     DEBUG("+ CMIDDisplayable::ConstructL");
       
   212 
       
   213     // Menu/commands
       
   214     // NOTE: Menu handler member variable has to be valid before
       
   215     // the <code>CCoeContol::MakeVisible</code> method is called
       
   216     // because the <code>CMIDDisplayable::MopSupplyObject</code> method
       
   217     // might be called because of that.
       
   218     iMenuHandler = iUIManager->OpenMenuHandlerL();
       
   219     iCommandList = new(ELeave) CMIDCommandList();
       
   220     iCommandList->SetCommandOffset(KCommandIdBase);
       
   221     iMSKCommand = NULL;
       
   222     iDisplayableBehindPopup = NULL;
       
   223 
       
   224     iEnv.AddObserverL(*this);
       
   225     CreateWindowL(&iEikonEnv->RootWin());
       
   226     SetMopParent(java::ui::CoreUiAvkonLcdui::getInstance().getJavaAknAppUi());
       
   227 
       
   228     //All windows are created invisible and then made visible
       
   229     //in SetComponentL(), except for Alerts (dialogs)
       
   230     MakeVisible(EFalse);
       
   231     Window().SetOrdinalPosition(-1);
       
   232 
       
   233     Window().EnableOnEvents(EEventControlOnlyWhenVisible);
       
   234     EnableDragEvents();
       
   235 
       
   236     // Long tap detection
       
   237     iLongTapDetector = CAknLongTapDetector::NewL(this);
       
   238 
       
   239     // SoftKeys
       
   240     for (TInt i = 0; i < KMaxNumberOfSoftKeys; i++)
       
   241     {
       
   242         CMIDSoftKey* softKey = CMIDSoftKey::NewLC(i, &(KAllowedCommandTypesForSoftkeys[i][0]),
       
   243                                KPositionsInCBAForSoftkeys[i]);
       
   244         User::LeaveIfError(iSoftKeys.Append(softKey));
       
   245         CleanupStack::Pop(softKey);
       
   246     }
       
   247 
       
   248     // CBA
       
   249     iCba = iMenuHandler->Cba();
       
   250 
       
   251     UpdateDisplayableRect();
       
   252     SetRect(iDisplayableRect);
       
   253 
       
   254     iBorder = TGulBorder::ENone;
       
   255 
       
   256     SetComponentsToInheritVisibility();
       
   257     // for Skin Support, Create background control context:
       
   258     iBackGroundControlContext = CAknsBasicBackgroundControlContext::NewL(
       
   259                                     KAknsIIDQsnBgAreaMain,  // Default mainpane skinning
       
   260                                     Rect(),                 // Layout to the entire client rect
       
   261                                     EFalse);
       
   262 
       
   263     iAppUi->Displayables().AppendL(this);
       
   264     iAppUi->SetEnv(iEnv);
       
   265     ActivateL();
       
   266 
       
   267     //Read JAD attribute value for On-Screen Keypad softkeys visual appearence with HW QWERTY keypad
       
   268     if (iEnv.MidletAttributeIsSetToVal(
       
   269                 LcduiMidletAttributes::KAttribOskSoftkeysInQwerty,
       
   270                 LcduiMidletAttributeValues::KPositionBottom))
       
   271     {
       
   272         iSKPositionWithQwerty = ESoftkeysBottom;
       
   273     }
       
   274     else
       
   275     {//default value
       
   276         iSKPositionWithQwerty = ESoftkeysRight;
       
   277     }
       
   278 
       
   279     DEBUG("- CMIDDisplayable::ConstructL");
       
   280 }
       
   281 
       
   282 
       
   283 
       
   284 CMIDDisplayable::CMIDDisplayable(MMIDEnv& aEnv,CMIDUIManager& aUIManager)
       
   285         :CEikBorderedControl(TGulBorder(KMIDLetBorder)),
       
   286         iUIManager(&aUIManager),iEnv(aEnv),
       
   287         iIsFullScreenMode(EFalse),iActive(EFalse), iSelectCommand(NULL), iSelectCommandEnabled(ETrue),
       
   288         iFullscreenCanvasLabelCacheIsValid(EFalse)
       
   289 #ifdef RD_TACTILE_FEEDBACK
       
   290         ,iPenInputServerConnected(EFalse)
       
   291 #endif //RD_TACTILE_FEEDBACK
       
   292         ,iIdOfMSKCommand(KErrNotFound)
       
   293 {
       
   294     iAppUi = (CMIDAppUi*)java::ui::CoreUiAvkonLcdui::getInstance().getJavaUiAppUi()->getLcduiChild();
       
   295 }
       
   296 
       
   297 CMIDDisplayable::~CMIDDisplayable()
       
   298 {
       
   299     DEBUG("+ CMIDDisplayable::CMIDDisplayable");
       
   300 
       
   301     // iPropertyWatch is CPropertyWatch object,
       
   302     // delete member call desctructor of CPropertyWatch
       
   303     // and remove active object form active scheduler
       
   304     if (iPropertyWatch)
       
   305     {
       
   306         delete iPropertyWatch;
       
   307         iPropertyWatch = NULL;
       
   308     }
       
   309 
       
   310     // Informing iEnv about deleting this
       
   311     iEnv.DisplayableIsDestructed(this);
       
   312 
       
   313     // Remove this from iEnv observer
       
   314     iEnv.RemoveObserver(*this);
       
   315 
       
   316     if (iAppUi)
       
   317     {
       
   318         iAppUi->RemoveFromStack(iContentControl);
       
   319         TInt index = iAppUi->Displayables().Find(this);
       
   320         if (index != KErrNotFound)
       
   321         {
       
   322             iAppUi->Displayables().Remove(index);
       
   323         }
       
   324     }
       
   325 
       
   326     delete iLongTapDetector;
       
   327     delete iStylusPopupMenu;
       
   328     delete iTitle;
       
   329 
       
   330 #ifdef RD_SCALABLE_UI_V2
       
   331     iUIManager->CloseCanvasKeypad(iCanvasKeypad);
       
   332     iCanvasKeypad = NULL;
       
   333 #endif //RD_SCALABLE_UI_V2
       
   334 
       
   335 #ifdef RD_TACTILE_FEEDBACK
       
   336     if (iPenInputServerConnected)
       
   337     {
       
   338         iPenInputServer.Close();
       
   339         iPenInputServerConnected = EFalse;
       
   340     }
       
   341 #endif //RD_TACTILE_FEEDBACK
       
   342 
       
   343     // if ticker is present in this displayable and displayable is
       
   344     // deleted but ticker is not, tell the ticker that displayable is
       
   345     // garbage collected.
       
   346     if (iTicker)
       
   347     {
       
   348         TRAP_IGNORE(iTicker->SetDisplayableL(this, KRemoveDisplayable));
       
   349     }
       
   350 
       
   351     delete iBackGroundControlContext;
       
   352     iBackGroundControlContext = NULL;
       
   353 
       
   354     iSoftKeys.ResetAndDestroy();
       
   355     delete iCommandList;
       
   356 
       
   357     if (iMenuHandler->GetDisplayable() == this)
       
   358     {//this may happen when the application is exiting
       
   359         iMenuHandler->SetDisplayable(NULL);
       
   360     }
       
   361 
       
   362     DEBUG("- CMIDDisplayable::CMIDDisplayable");
       
   363 }
       
   364 
       
   365 /**
       
   366  * This means we are being deleted java side. We delete ourselves.
       
   367  * However before doing this we call ReplaceBehindAlertIfNeeded().
       
   368  **/
       
   369 void CMIDDisplayable::Dispose()
       
   370 {
       
   371     if (iAppUi)
       
   372     {
       
   373         iAppUi->UnSetEnv();
       
   374     }
       
   375     ReplaceBehindAlertIfNeeded();
       
   376 
       
   377     delete this;
       
   378 }
       
   379 
       
   380 /**
       
   381  * This method is called when we are deleted java side, from Dispose().
       
   382  * This code should only execute when java side they decide to delete the
       
   383  * displayable immeditately behind a showing alert. We check if we are a
       
   384  * displayable behind an alert. If so we find another displayable (the
       
   385  * one with lowest ordinal position, ie the top most displayable except us
       
   386  * and the alert). If we find one we make it visible so that the alert will
       
   387  * not end up with a white background.
       
   388  **/
       
   389 void CMIDDisplayable::ReplaceBehindAlertIfNeeded()
       
   390 {
       
   391     if ((this != iUIManager->GetDefaultDisplayable())
       
   392             && IsVisible()
       
   393             && (iMenuHandler->GetDisplayable())
       
   394             && (iMenuHandler->GetDisplayable()->Component()->Type() == EAlert))
       
   395     {// In this case we are a faded displayable behind a dialog
       
   396         TInt numDisplayables = iAppUi->Displayables().Count();
       
   397         TInt index = -1;
       
   398         TInt currentPosition = 999;
       
   399         for (TInt i = 0; i < numDisplayables; i++)
       
   400         {
       
   401             CMIDDisplayable* disp = iAppUi->Displayables()[i];
       
   402             if ((disp != this) && (disp->DrawableWindow()->OrdinalPosition() < currentPosition)
       
   403                     && (disp->Component()->Type() != EAlert))
       
   404             {
       
   405                 currentPosition = disp->DrawableWindow()->OrdinalPosition();
       
   406                 index = i;
       
   407             }
       
   408         }
       
   409 
       
   410         if (index != -1)
       
   411         {
       
   412             CMIDDisplayable* disp = iAppUi->Displayables()[index];
       
   413             disp->MakeVisible(ETrue);
       
   414         }
       
   415     }
       
   416 }
       
   417 
       
   418 void CMIDDisplayable::Draw(const TRect& aRect) const
       
   419 {
       
   420     CWindowGc& gc = SystemGc();
       
   421 
       
   422     // Set up update region - preventing DSA to be destroyed by redrawing
       
   423     if (!iDirectContentsRegion.IsEmpty())
       
   424     {
       
   425         gc.CancelClippingRect();
       
   426         iUpdateRegion.Clear();
       
   427         iUpdateRegion.AddRect(aRect);
       
   428         // Remove occupied areas out from update region
       
   429         iUpdateRegion.SubRegion(iDirectContentsRegion);
       
   430         // Set the update region for the context
       
   431         gc.SetClippingRegion(iUpdateRegion);
       
   432     }
       
   433 
       
   434     if (iContent->Type() != ECanvas)
       
   435     {
       
   436         // Draw background
       
   437         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   438         AknsDrawUtils::Background(skin, iBackGroundControlContext, this, gc, aRect);
       
   439     }
       
   440     iBorder.Draw(gc, Rect());
       
   441 }
       
   442 
       
   443 TInt CMIDDisplayable::CountComponentControls() const
       
   444 {
       
   445     TInt count=0;
       
   446     if (iContentControl)
       
   447     {
       
   448         ++count;
       
   449     }
       
   450     return count;
       
   451 }
       
   452 
       
   453 CCoeControl* CMIDDisplayable::ComponentControl(TInt aIndex) const
       
   454 {
       
   455     switch (aIndex)
       
   456     {
       
   457     case 0:
       
   458         return iContentControl ? iContentControl: 0;
       
   459     default:
       
   460         return 0;
       
   461     }
       
   462 }
       
   463 
       
   464 void CMIDDisplayable::SizeChanged()
       
   465 {
       
   466     if (iBackGroundControlContext)
       
   467     {
       
   468         iBackGroundControlContext->SetRect(Rect());
       
   469     }
       
   470     Layout();
       
   471 }
       
   472 
       
   473 /**
       
   474  * Use the commands in aCommandList to create menu items and add them to aItems.
       
   475  */
       
   476 void CMIDDisplayable::PopulateMenuItemsWithListL
       
   477 (
       
   478     const CMIDMenuHandler::TMenuType& aMenuType, //The type of menu
       
   479     RArray<CEikMenuPaneItem::SData>& aItems, //The items that will be added to the menu
       
   480     CMIDCommandList* aCommandList, //The list of commands to be examined
       
   481     TBool aSeparator
       
   482 )
       
   483 {
       
   484     if (!aCommandList)
       
   485     {
       
   486         return;
       
   487     }
       
   488     const TBool isItemCommands = (aCommandList == iItemCommandList);
       
   489 
       
   490     CMIDCommandList* list = aCommandList;
       
   491     CEikMenuPaneItem::SData item;
       
   492 
       
   493 #ifdef RD_JAVA_S60_RELEASE_9_2
       
   494     // implicitList is used when creating options menu content.
       
   495     TBool implicitList = EFalse;
       
   496     if (iContent && iContent->Type() == EList && iContentControl)
       
   497     {
       
   498         CMIDList* list = static_cast<CMIDList*>(iContentControl);
       
   499         implicitList = list->ListChoiceType() == MMIDChoiceGroup::EImplicit;
       
   500     }
       
   501 #endif // RD_JAVA_S60_RELEASE_9_2
       
   502 
       
   503     const TInt count = list->Count();
       
   504     for (TInt ii=0; ii<count; ii++)
       
   505     {
       
   506         const CMIDCommand* command = (list->At(ii).iCommand);
       
   507 #ifdef RD_JAVA_S60_RELEASE_9_2
       
   508         // If command is mapped to any sk, do not add it to menu (pop-up menu is an exception).
       
   509         if (!iIsFullScreenMode && CommandIsMappedToSk(command) && aMenuType != CMIDMenuHandler::EPopUpMenu)
       
   510 #else
       
   511         // If command is mapped to any sk, do not add it to menu.
       
   512         if (!iIsFullScreenMode && CommandIsMappedToSk(command))
       
   513 #endif // RD_JAVA_S60_RELEASE_9_2               
       
   514         {
       
   515             continue;
       
   516         }
       
   517         // Only commands of type OK and ITEM are visible in context menu.
       
   518         // TextBox/TextField device-provided commands:
       
   519         // - "Fetch number"
       
   520         // - "Call"
       
   521         // - "Fetch e-mail address"
       
   522         // are exception. Those are visible ONLY in Options menu so here
       
   523         // they are not added to context menu.
       
   524 #ifdef RD_JAVA_S60_RELEASE_9_2
       
   525         if (aMenuType == CMIDMenuHandler::EOkMenu || aMenuType == CMIDMenuHandler::EPopUpMenu)
       
   526 #else
       
   527         if (aMenuType == CMIDMenuHandler::EOkMenu)
       
   528 #endif // RD_JAVA_S60_RELEASE_9_2            
       
   529         {
       
   530             if ((!isItemCommands &&
       
   531             (command->CommandType() != MMIDCommand::EOk) &&
       
   532             (command->CommandType() != MMIDCommand::EItem)) ||
       
   533             (command->Id() == CMIDEdwinUtils::EMenuCommandFetchPhoneNumber) ||
       
   534             (command->Id() == CMIDEdwinUtils::EMenuCommandFetchEmailAddress) ||
       
   535             (command->Id() == CMIDEdwinUtils::EMenuCommandCreatePhoneCall))
       
   536             {
       
   537                 continue;
       
   538             }
       
   539         }
       
   540 
       
   541         if (aMenuType == CMIDMenuHandler::EHelpMenu)
       
   542         {
       
   543             if (command->CommandType() != MMIDCommand::EHelp)
       
   544             {
       
   545                 continue;
       
   546             }
       
   547         }
       
   548 
       
   549         TPtrC shortLabel = const_cast<CMIDCommand*>(command)->ShortLabel();
       
   550         TPtrC longLabel  = const_cast<CMIDCommand*>(command)->Label();
       
   551 
       
   552         item.iCommandId = ii + list->CommandOffset();
       
   553         item.iCascadeId = 0;
       
   554 
       
   555         if (ii == (count-1) && aSeparator)
       
   556         {
       
   557             item.iFlags = EEikMenuItemSeparatorAfter;
       
   558         }
       
   559         else
       
   560         {
       
   561             item.iFlags = 0;
       
   562         }
       
   563 
       
   564         // Find out whether the long label fits into the menu without clipping,
       
   565         // and use the long label if it fits; otherwise use short label.
       
   566         //
       
   567         // In some scripts the visual presentation may differ from the logical text,
       
   568         // so we need to convert the text to visual presentation first.
       
   569         // The clipped clipped string is not used, only the return value is.
       
   570         //
       
   571         const CFont& font =
       
   572             *AknLayoutUtils::FontFromId(AKN_LAYOUT_TEXT_List_pane_texts__menu_single__Line_1(0).iFont);
       
   573         TInt maxMenuItemLength = CEikMenuPaneItem::SData::ENominalTextLength;
       
   574 
       
   575         TRect parentRect = Rect();
       
   576         TAknLayoutText prompt1;
       
   577         prompt1.LayoutText(parentRect, AKN_LAYOUT_TEXT_Data_query_pop_up_window_texts_Line_1(0));
       
   578         TInt layoutWidth = prompt1.TextRect().Width();
       
   579 
       
   580         HBufC* visual = HBufC::NewMaxLC(maxMenuItemLength + KAknBidiExtraSpacePerLine);
       
   581         TPtr visualPtr = visual->Des();
       
   582         TBool clip = AknBidiTextUtils::ConvertToVisualAndClip(
       
   583                          longLabel,
       
   584                          visualPtr,
       
   585                          font,
       
   586                          layoutWidth,
       
   587                          layoutWidth,
       
   588                          AknBidiTextUtils::EImplicit,
       
   589                          0xFFFF);
       
   590         CleanupStack::PopAndDestroy(visual);
       
   591 
       
   592         if (clip)
       
   593         {
       
   594             BaflUtils::CopyWithTruncation(item.iText, shortLabel);
       
   595         }
       
   596         else
       
   597         {
       
   598             BaflUtils::CopyWithTruncation(item.iText, longLabel);
       
   599         }
       
   600 
       
   601         if ((iMSKCommand) && (iMSKCommand == list->At(ii).iCommand))
       
   602         {
       
   603             User::LeaveIfError(aItems.Insert(item, 0));
       
   604         }
       
   605         else
       
   606         {
       
   607 #ifdef RD_JAVA_S60_RELEASE_9_2
       
   608             if (aMenuType == CMIDMenuHandler::EOptionsMenu)
       
   609             {
       
   610                 TBool implicitCmd = (implicitList && (command->CommandType() == MMIDCommand::EOk ||
       
   611                                                       command->CommandType() == MMIDCommand::EItem));
       
   612 
       
   613                 if (!implicitCmd)
       
   614                 {
       
   615                     User::LeaveIfError(aItems.Append(item));
       
   616                 }
       
   617                 else if (implicitCmd && iContentControl &&
       
   618                          static_cast<CMIDList*>(iContentControl)->IsHighlighted())
       
   619                 {
       
   620                     // If highlight in implicit list is False then there is no focus
       
   621                     // Item/Ok should be visible in options menu only when there is focus on item
       
   622                     User::LeaveIfError(aItems.Append(item));
       
   623                 }
       
   624             }
       
   625             else
       
   626             {
       
   627                 User::LeaveIfError(aItems.Append(item));
       
   628             }
       
   629 #else
       
   630             User::LeaveIfError(aItems.Append(item));
       
   631 #endif // RD_JAVA_S60_RELEASE_9_2        
       
   632         }
       
   633     }
       
   634 }
       
   635 
       
   636 
       
   637 /**
       
   638  * Create a list of menu items based on the type of menu and the
       
   639  * existing command lists.
       
   640  *
       
   641  * This method is executed each time the menu is displayed to the user.
       
   642  * There are two types of menus that can be displayed: context sensitive
       
   643  * - activated by the select key also known as ok-options menu -
       
   644  * or standard options menu - activated by the LSK. In the standard options
       
   645  * menu we display item and standard commands.In the context menu we display
       
   646  * item commands (if there are any) and standard commands if they are
       
   647  * of type OK or ITEM, this is taken care of by PopulateMenuItemsWithListL().
       
   648  *
       
   649  * @see PopulateMenuItemsWithListL(), CMIDMenuHandler::ShowMenuL()
       
   650  **/
       
   651 void CMIDDisplayable::CreateMenuItemsL
       
   652 (
       
   653     const CMIDMenuHandler::TMenuType& aMenuType, // the type of menu
       
   654     RArray<CEikMenuPaneItem::SData>& aMenuItems // the list of menu items
       
   655 )
       
   656 {
       
   657     aMenuItems.Reset();
       
   658 
       
   659     if (aMenuType == CMIDMenuHandler::EOkMenu)
       
   660     {
       
   661         if (iItemCommandList && iItemCommandList->Count() > 0)
       
   662         {
       
   663             PopulateMenuItemsWithListL(aMenuType, aMenuItems, iItemCommandList, EFalse);
       
   664         }
       
   665 
       
   666         // Add form commands always
       
   667         PopulateMenuItemsWithListL(aMenuType, aMenuItems, iCommandList, EFalse);
       
   668     }
       
   669     else if (aMenuType == CMIDMenuHandler::EHelpMenu)
       
   670     { // Add the Help commands only
       
   671         PopulateMenuItemsWithListL(aMenuType, aMenuItems, iCommandList, EFalse);
       
   672     }
       
   673     else if (aMenuType == CMIDMenuHandler::EOptionsMenu)
       
   674     {
       
   675         PopulateMenuItemsWithListL(aMenuType, aMenuItems, iItemCommandList, EFalse);
       
   676         PopulateMenuItemsWithListL(aMenuType, aMenuItems, iCommandList, ETrue);
       
   677     }
       
   678 }
       
   679 
       
   680 /**
       
   681  * iMenuHandler gets the commands first and handles the default ones (exit, options...).
       
   682  * The rest of the commands are passed here.
       
   683  **/
       
   684 void CMIDDisplayable::ProcessCommandL(TInt aCommandId)
       
   685 {
       
   686     if (!iActive)
       
   687     {
       
   688         return;
       
   689     }
       
   690 
       
   691     if (aCommandId == EAknSoftkeyContextOptions)
       
   692     { // MSK command to show context sensitive menu -> open it
       
   693         ShowOkOptionsMenuL();
       
   694     }
       
   695     else if (aCommandId == KBuiltInMSKCommandId)
       
   696     {
       
   697         // Handle built-in command that is not accessible from menus, only in MSK.
       
   698         // Send a notification to the observer; there always should be one in built-in
       
   699         // commands, if not it is considered to be an error.
       
   700         ASSERT(iMSKCommand->Observer());
       
   701         iMSKCommand->Observer()->ProcessCommandL(iMSKCommand);
       
   702     }
       
   703     else if (aCommandId >= KItemCommandIdBase
       
   704              && iItemCommandList->IsValidIndex(aCommandId-KItemCommandIdBase))
       
   705     {
       
   706         HandleItemCommandL(iItemCommandList->At(aCommandId-KItemCommandIdBase));
       
   707     }
       
   708     else if (aCommandId >= KCommandIdBase
       
   709              && iCommandList->IsValidIndex(aCommandId-KCommandIdBase))
       
   710     {
       
   711         HandleStandardCommandL(iCommandList->At(aCommandId-KCommandIdBase));
       
   712     }
       
   713 #ifdef RD_JAVA_S60_RELEASE_9_2
       
   714     // If command has come from pop-up menu, ensure that
       
   715     // possible pending up event is forwarded to the UI component.
       
   716     if (iContent && iContentControl)
       
   717     {
       
   718         if (iContent->Type() == EList)
       
   719         {
       
   720             CMIDList* list = static_cast<CMIDList*>(iContentControl);
       
   721             list->PostPendingUpEventL();
       
   722         }
       
   723         else if (iContent->Type() == EForm)
       
   724         {
       
   725             CMIDForm* form = static_cast<CMIDForm*>(iContentControl);
       
   726             form->PostPendingUpEventL();
       
   727         }
       
   728     }
       
   729 #endif // RD_JAVA_S60_RELEASE_9_2    
       
   730 }
       
   731 
       
   732 #ifdef RD_SCALABLE_UI_V2
       
   733 /** */
       
   734 // This function can be moved out from RD_SCALABLE_UI_V2 flag if needed.
       
   735 // It is behind this flag because currently it is used only by Touch.
       
   736 void CMIDDisplayable::ProcessCommandL(CMIDCommand* aCommand)
       
   737 {
       
   738     TInt internalID = GetInternalCommandIdFor(aCommand);
       
   739     if (internalID != KCommandIdNotFound)
       
   740     {
       
   741         ProcessCommandL(internalID);
       
   742     }
       
   743 }
       
   744 #endif //RD_SCALABLE_UI_V2
       
   745 
       
   746 /** */
       
   747 void CMIDDisplayable::HandleStandardCommandL(const TCommandEntry& aCmdEntry)
       
   748 {
       
   749     TBool postJavaEvent = ETrue;
       
   750     if (aCmdEntry.iCommand->Id() < 0)
       
   751     { //non-midlet command, see if there is an observer
       
   752         if (aCmdEntry.iCommand->Observer())
       
   753         {
       
   754             postJavaEvent = !(aCmdEntry.iCommand->Observer()->ProcessCommandL(aCmdEntry.iCommand));
       
   755         }
       
   756     }
       
   757 
       
   758     if (postJavaEvent)
       
   759     {
       
   760         iEnv.PostJavaEvent(*this, EDisplayable, ECommand, aCmdEntry.iKey);
       
   761     }
       
   762 }
       
   763 
       
   764 /** */
       
   765 void CMIDDisplayable::HandleItemCommandL(const TCommandEntry& aCmdEntry)
       
   766 {
       
   767     TBool postJavaEvent = ETrue;
       
   768     if (aCmdEntry.iCommand->Id() < 0)
       
   769     { //non-midlet command, see if there is an observer
       
   770         if (aCmdEntry.iCommand->Observer())
       
   771         {
       
   772             postJavaEvent = !(aCmdEntry.iCommand->Observer()->ProcessCommandL(aCmdEntry.iCommand));
       
   773         }
       
   774     }
       
   775 
       
   776     if (postJavaEvent && iContent->Type() == EForm)
       
   777     {
       
   778         CMIDForm* form = static_cast<CMIDForm*>(iContentControl);
       
   779         ASSERT(form);
       
   780 
       
   781         MMIDItem* item = form->CurrentItem();
       
   782         if (item)
       
   783         {
       
   784             iEnv.PostJavaEvent(*item, EItem, ECommand, aCmdEntry.iKey);
       
   785         }
       
   786     }
       
   787 }
       
   788 
       
   789 void CMIDDisplayable::HandleHelpCommandL()
       
   790 {
       
   791     // Get how many java help commands is registered
       
   792     TInt numCommands = NumCommandsForHelpOptionsMenu();
       
   793 
       
   794     // If there is only one help command, invoke the Java help event directly
       
   795     if (numCommands == 1)
       
   796     {
       
   797         TCommandEntry cmdEntry;
       
   798         cmdEntry.iCommand = NULL;
       
   799 
       
   800         if (iCommandList)
       
   801         {
       
   802             TInt index = iCommandList->HighestPriorityCommand(MMIDCommand::EHelp);
       
   803             if (index != KErrNotFound)
       
   804             {
       
   805                 cmdEntry = iCommandList->At(index);
       
   806                 iEnv.PostJavaEvent(*this, EDisplayable, ECommand, cmdEntry.iKey);
       
   807             }
       
   808         }
       
   809     }
       
   810     // If there is two or more help commands, let display the menu with these commands
       
   811     else if (numCommands > 0)
       
   812     {
       
   813         iMenuHandler->ShowMenuL(CMIDMenuHandler::EHelpMenu);
       
   814     }
       
   815 }
       
   816 
       
   817 TInt CMIDDisplayable::NumCommandsForHelpOptionsMenu() const
       
   818 {
       
   819     TInt ret = 0;
       
   820 
       
   821     // Add always HELP commands from form
       
   822     TInt numCommands = iCommandList->Count();
       
   823     for (TInt i = 0; i < numCommands; i++)
       
   824     {
       
   825         const CMIDCommand& command = *(iCommandList->At(i).iCommand);
       
   826         if (command.CommandType() == MMIDCommand::EHelp)
       
   827         {
       
   828             ret++;
       
   829         }
       
   830     }
       
   831     return ret;
       
   832 }
       
   833 
       
   834 /**
       
   835  * Find the screen or help command with highest priority
       
   836  * and if exists invokes it
       
   837  **/
       
   838 void CMIDDisplayable::HandleHighestPriorityScreenOrHelpCommandL()
       
   839 {
       
   840     // Find the highest priority screen or help command
       
   841     TInt screenOrHelpCmdIndex = GetHighestPriorityScreenOrHelpCommand();
       
   842     if (screenOrHelpCmdIndex != KErrNotFound)
       
   843     {
       
   844         HandleStandardCommandL(iCommandList->At(screenOrHelpCmdIndex));
       
   845     }
       
   846 }
       
   847 
       
   848 //
       
   849 // From MMIDDisplayable
       
   850 //
       
   851 void CMIDDisplayable::SetTitleL(const TDesC* aTitle)
       
   852 {
       
   853     delete iTitle;
       
   854     iTitle = NULL;
       
   855 
       
   856     if (aTitle)
       
   857     {
       
   858         iTitle = aTitle->AllocL();
       
   859     }
       
   860 
       
   861     if (iTitle)
       
   862     {
       
   863         iHasTitle = ETrue;
       
   864     }
       
   865     else
       
   866     {
       
   867         iHasTitle = EFalse;
       
   868     }
       
   869 
       
   870     if (iActive)
       
   871     {
       
   872         ShowTitleL();
       
   873     }
       
   874 
       
   875     if (iContent && iContent->Type() == EAlert)
       
   876     {
       
   877         CMIDAlert* alert = (CMIDAlert*) iContent;
       
   878         alert->SetTitleL(iTitle);
       
   879     }
       
   880     // Title must be forwarded to Pop-up TextBox
       
   881     else if (iContent && iContent->Type() == ETextBox && iIsPopupTextBox)
       
   882     {
       
   883         CMIDTextBoxDialogControl* textbox = (CMIDTextBoxDialogControl*) iContent;
       
   884         textbox->SetTitleL(iTitle);
       
   885     }
       
   886 }
       
   887 
       
   888 /**
       
   889  * Sets the Ticker
       
   890  *
       
   891  * StartL is called on the current displayable's ticker in these circumstances:
       
   892  * - When the MIDlet is brought to the foreground (in HandleForegroundL(ETrue))
       
   893  * - When the device is switched on (in HandleSwitchOnL(ETrue))
       
   894  * - If the MIDlet has been paused due to a CSaveNotifier event, StartL is
       
   895  *   called when the MIDlet is next brought to the foreground.(in HandleSwitchOnL(ETrue))
       
   896  * - When the displayable is made current (StartL called by framework)
       
   897  *
       
   898  * Stop is called on the current displayable's ticker in these circumstances:
       
   899  * - When the MIDlet is placed in the background.(in HandleForegroundL(EFalse) )
       
   900  * - The implementation uses the CSaveNotifier framework to provide MIDLet state changes.
       
   901  *   When the following events are received ESaveAll,ESaveQuick,ESaveData,EReleaseRAM
       
   902  *   the MIDlet is paused and the ticker is stopped.(in HandleSwitchOnL(EFalse))
       
   903  * - When the Displayable is no longer current. (Stop is called by framework)
       
   904  **/
       
   905 void CMIDDisplayable::SetTickerL(MMIDTicker* aTicker)
       
   906 {
       
   907     CMIDTicker* newTicker = static_cast< CMIDTicker* >(aTicker);
       
   908     // if it is the same do nothing
       
   909     if (iTicker == aTicker)
       
   910     {
       
   911         return;
       
   912     }
       
   913 
       
   914     if (iTicker)
       
   915     {
       
   916         // Tell the current Ticker that it has no displayable
       
   917         iTicker->SetDisplayableL(this, KRemoveDisplayable);
       
   918     }
       
   919 
       
   920     iTicker = newTicker;
       
   921     if (iTicker)
       
   922     {
       
   923         iTicker->SetDisplayableL(this, KAddDisplayable);
       
   924     }
       
   925 
       
   926     // Request ticker timer if a valid ticker has been set and
       
   927     // this is the current displayable.
       
   928     UpdateTickerL();
       
   929 }
       
   930 
       
   931 // ---------------------------------------------------------------------------
       
   932 //
       
   933 // ---------------------------------------------------------------------------
       
   934 //
       
   935 MMIDTicker* CMIDDisplayable::Ticker() const
       
   936 {
       
   937     return iTicker;
       
   938 }
       
   939 
       
   940 // ---------------------------------------------------------------------------
       
   941 // Ensures that ticker update events are generated when appropriate
       
   942 // (e.g. when active) and that this displayables ticker control is notified
       
   943 // whenever it needs to redraw.
       
   944 //
       
   945 // ResumeTicker() and SuspendTicker() deal with the ticker timer whereas
       
   946 // PauseTicker() is actually sending the ticker to the background makeing it
       
   947 // disappear.
       
   948 // ---------------------------------------------------------------------------
       
   949 void CMIDDisplayable::UpdateTickerL()
       
   950 {
       
   951     if (iActive)
       
   952     {
       
   953         iUIManager->OpenNaviPaneControllerL()->SetTickerL(iTicker);
       
   954         if (iIsFullScreenMode || iIsPopupTextBox)
       
   955         {
       
   956             iUIManager->OpenNaviPaneControllerL()->ShowTickerL(EFalse);
       
   957         }
       
   958         else
       
   959         {
       
   960             iUIManager->OpenNaviPaneControllerL()->ShowTickerL(ETrue);
       
   961         }
       
   962     }
       
   963 }
       
   964 
       
   965 // ---------------------------------------------------------------------------
       
   966 //
       
   967 // ---------------------------------------------------------------------------
       
   968 //
       
   969 void CMIDDisplayable::HandleSwitchOnL(TBool /*aSwitchOn*/)
       
   970 {
       
   971 }
       
   972 
       
   973 // ---------------------------------------------------------------------------
       
   974 //
       
   975 // ---------------------------------------------------------------------------
       
   976 //
       
   977 void CMIDDisplayable::HandleForegroundL(TBool aForeground)
       
   978 {
       
   979     DEBUG("+ CMIDDisplayable::HandleForegroundL");
       
   980 
       
   981     // send HandleForegroundL notification to Form
       
   982     if (iContent && (iContent->Type() == MMIDComponent::EForm) && iContentControl)
       
   983     {
       
   984         CMIDForm* form = static_cast<CMIDForm*>(iContentControl);
       
   985         ASSERT(form);
       
   986         form->HandleForegroundL(aForeground);
       
   987     }
       
   988 
       
   989 #ifdef RD_JAVA_NGA_ENABLED
       
   990     HandleCanvasForeground(aForeground);
       
   991 #endif // RD_JAVA_NGA_ENABLED    
       
   992 
       
   993     if (aForeground)
       
   994     {
       
   995         //If MIDlet is sent to foreground and JAD-attribute BackgroundEvent=Pause,
       
   996         //then call startApp() method for the MIDlet.
       
   997 
       
   998         if (iEnv.MidletAttributeIsSetToVal(LcduiMidletAttributes::KAttribBackgroundEvent,
       
   999                                            LcduiMidletAttributeValues::KPauseValue))
       
  1000 
       
  1001         {
       
  1002             iEnv.PostMidletEvent(EStart);
       
  1003         }
       
  1004     }
       
  1005     else //to background
       
  1006     {
       
  1007 
       
  1008         //If MIDlet is sent to background and JAD-attribute BackgroundEvent=Pause,
       
  1009         //then call pauseApp() method for the MIDlet.
       
  1010 
       
  1011         if (iEnv.MidletAttributeIsSetToVal(LcduiMidletAttributes::KAttribBackgroundEvent,
       
  1012                                            LcduiMidletAttributeValues::KPauseValue) &&
       
  1013                 !this->DrawableWindow()->IsFaded())
       
  1014 
       
  1015         {
       
  1016             iEnv.PostMidletEvent(EPause);
       
  1017         }
       
  1018     }
       
  1019     DEBUG("- CMIDDisplayable::HandleForegroundL");
       
  1020 }
       
  1021 
       
  1022 // ---------------------------------------------------------------------------
       
  1023 //
       
  1024 // ---------------------------------------------------------------------------
       
  1025 //
       
  1026 void CMIDDisplayable::HandleResourceChangeL(TInt aType)
       
  1027 {
       
  1028     DEBUG("+ CMIDDisplayable::HandleResourceChangeL");
       
  1029 
       
  1030     if (aType == KEikDynamicLayoutVariantSwitch)
       
  1031     { // dynamic orientation change
       
  1032 
       
  1033         // Correct rect is set for displayable
       
  1034         if (iActive && iCanvasKeypad)
       
  1035         { //Update correct On-Screen Keypad type
       
  1036             UpdateOnScreenKeypadSettings();
       
  1037         }
       
  1038         UpdateDisplayableRect();
       
  1039         SetRect(iDisplayableRect);
       
  1040 
       
  1041         // MIDlet icon is resized in cpane SizeChanged()
       
  1042 
       
  1043         if (!iActive && iContentControl)
       
  1044         {//The active displayable already gets this call by the CONE framework but
       
  1045             //background displayables don't, so for example a background form won't be
       
  1046             //re-laid-out if we don't call this here
       
  1047             iContentControl->HandleResourceChange(aType);
       
  1048         }
       
  1049 #ifdef RD_SCALABLE_UI_V2
       
  1050         if (iUseOnScreenKeypad && iCanvasKeypad && (iActive || this->DrawableWindow()->IsFaded()))
       
  1051         {
       
  1052             iCanvasKeypad->UpdateVisualAppearanceL(*iCanvas, iOnScreenKeyboardType, *this);
       
  1053         }
       
  1054 #endif // RD_SCALABLE_UI_V2
       
  1055         iFullscreenCanvasLabelCacheIsValid = EFalse;
       
  1056     }
       
  1057     else if (aType == KEikColorResourceChange ||
       
  1058              aType == KAknsMessageSkinChange  ||
       
  1059              aType == KUidValueCoeColorSchemeChangeEvent)
       
  1060     { //skin or color change, may need to recreate ctx icon
       
  1061         // send skin change event to non-active controls so they can also
       
  1062         // reload graphics
       
  1063         if (!iActive && iContentControl)
       
  1064         {
       
  1065             iContentControl->HandleResourceChange(aType);
       
  1066         }
       
  1067 #ifdef RD_SCALABLE_UI_V2
       
  1068         if (iUseOnScreenKeypad && iCanvasKeypad && iActive)
       
  1069         {
       
  1070             iCanvasKeypad->UpdateVisualAppearanceL(*iCanvas, iOnScreenKeyboardType, *this);
       
  1071         }
       
  1072 #endif // RD_SCALABLE_UI_V2
       
  1073         iFullscreenCanvasLabelCacheIsValid = EFalse;
       
  1074     }
       
  1075 
       
  1076     DEBUG("- CMIDDisplayable::HandleResourceChangeL");
       
  1077 
       
  1078     // Language input change, needed by TextEditor.
       
  1079     if ((aType == KEikInputLanguageChange) && iContentControl)
       
  1080     {
       
  1081         iContentControl->HandleResourceChange(aType);
       
  1082     }
       
  1083 }
       
  1084 
       
  1085 /**
       
  1086  * The container has changed it available drawing space, so resize
       
  1087  * the displayable to fit and post a size changed event.
       
  1088  **/
       
  1089 void CMIDDisplayable::Layout()
       
  1090 {
       
  1091     TBool changed(EFalse);
       
  1092 
       
  1093     //
       
  1094     // Get client area of window (within border).
       
  1095     //
       
  1096     TRect rect(iBorder.InnerRect(Rect()));
       
  1097 
       
  1098     if (iContentControl)
       
  1099     {
       
  1100         if (iContentControl->Rect() != rect)
       
  1101         {
       
  1102             // Anything left in rect is space for the content.
       
  1103             // It is arguable that the content should post the resize event as
       
  1104             // it knows its true size. Certainly that is required for Canvas.
       
  1105             iContentControl->SetRect(rect);
       
  1106             changed = ETrue;
       
  1107             TRAP_IGNORE(iUIManager->OpenNaviPaneControllerL()->LayoutTickerL());
       
  1108         }
       
  1109 
       
  1110         MMIDComponent::TType type = iContent->Type();
       
  1111         //
       
  1112         // We assume that the content width/height == control width height
       
  1113         // arguably not a valid assumption for any content - but especially
       
  1114         // invalid for Canvas when the JAD specifies an assumed size.
       
  1115         //
       
  1116         // Let Canvas's post their own size, but
       
  1117         // use the content rect size for all other displayables.
       
  1118         //
       
  1119         if (type != ECanvas && type != EGameCanvas)
       
  1120         {
       
  1121             //
       
  1122             // Only post this event for non-canvas components.
       
  1123             //
       
  1124             TSize size(rect.Size());
       
  1125             iEnv.PostJavaEvent(*this, EDisplayable, ESizeChanged, size.iWidth, size.iHeight, 0);
       
  1126         }
       
  1127     }
       
  1128 
       
  1129     if (changed)
       
  1130     {
       
  1131         DrawDeferred();
       
  1132     }
       
  1133 }
       
  1134 
       
  1135 // ---------------------------------------------------------------------------
       
  1136 //
       
  1137 // ---------------------------------------------------------------------------
       
  1138 //
       
  1139 TInt CMIDDisplayable::GetSKPositionForOSK()
       
  1140 {
       
  1141     return iSKPositionWithQwerty;
       
  1142 }
       
  1143 
       
  1144 // ---------------------------------------------------------------------------
       
  1145 //
       
  1146 // ---------------------------------------------------------------------------
       
  1147 //
       
  1148 TRect CMIDDisplayable::GetCanvasRectFromLaf()
       
  1149 {
       
  1150     DEBUG("+ CMIDDisplayable::GetCanvasRectFromLaf");
       
  1151 
       
  1152     TRect resultRect;
       
  1153     AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EScreen, resultRect);
       
  1154     TAknLayoutRect canvasRect;
       
  1155     TAknLayoutRect mainPane;
       
  1156     TAknLayoutRect mainMidpPane;
       
  1157 
       
  1158     //Read canvasRect from LAF depending on keyboard type
       
  1159     switch (iOnScreenKeyboardType)
       
  1160     {
       
  1161     case EOnScreenKeypadValueNo:
       
  1162         break;
       
  1163     case EOnScreenKeypadValueNavigationKeys:
       
  1164     {
       
  1165         if (iIsFullScreenMode)
       
  1166         {
       
  1167             if (!Layout_Meta_Data::IsLandscapeOrientation())  //portrait
       
  1168             {
       
  1169                 canvasRect.LayoutRect(resultRect, AknLayoutScalable_Avkon::midp_canvas_pane(1).LayoutLine());
       
  1170             }
       
  1171             else //landscape
       
  1172             {
       
  1173                 canvasRect.LayoutRect(resultRect, AknLayoutScalable_Avkon::midp_canvas_pane(8).LayoutLine());
       
  1174             }
       
  1175         }
       
  1176         else //normal mode
       
  1177         {
       
  1178             if (!Layout_Meta_Data::IsLandscapeOrientation())  //portrait
       
  1179             {
       
  1180                 mainPane.LayoutRect(resultRect, AknLayoutScalable_Avkon::main_pane(3).LayoutLine());
       
  1181                 mainMidpPane.LayoutRect(mainPane.Rect(), AknLayoutScalable_Avkon::main_midp_pane(0).LayoutLine());
       
  1182                 canvasRect.LayoutRect(mainMidpPane.Rect(), AknLayoutScalable_Avkon::midp_canvas_pane(4).LayoutLine());
       
  1183             }
       
  1184             else //landscape
       
  1185             {
       
  1186                 mainPane.LayoutRect(resultRect, AknLayoutScalable_Avkon::main_pane(4).LayoutLine());
       
  1187                 mainMidpPane.LayoutRect(mainPane.Rect(), AknLayoutScalable_Avkon::main_midp_pane(1).LayoutLine());
       
  1188                 canvasRect.LayoutRect(mainMidpPane.Rect(), AknLayoutScalable_Avkon::midp_canvas_pane(7).LayoutLine());
       
  1189             }
       
  1190         }
       
  1191         resultRect = canvasRect.Rect();
       
  1192         break;
       
  1193     }
       
  1194     case EOnScreenKeypadValueGameActions:
       
  1195     {
       
  1196         if (iIsFullScreenMode)
       
  1197         {
       
  1198             if (!Layout_Meta_Data::IsLandscapeOrientation())  //portrait
       
  1199             {
       
  1200                 canvasRect.LayoutRect(resultRect, AknLayoutScalable_Avkon::midp_canvas_pane(2).LayoutLine());
       
  1201             }
       
  1202             else //landscape
       
  1203             {
       
  1204                 canvasRect.LayoutRect(resultRect, AknLayoutScalable_Avkon::midp_canvas_pane(3).LayoutLine());
       
  1205             }
       
  1206         }
       
  1207         else //normal mode
       
  1208         {
       
  1209             if (!Layout_Meta_Data::IsLandscapeOrientation())  //portrait
       
  1210             {
       
  1211                 mainPane.LayoutRect(resultRect, AknLayoutScalable_Avkon::main_pane(3).LayoutLine());
       
  1212                 mainMidpPane.LayoutRect(mainPane.Rect(), AknLayoutScalable_Avkon::main_midp_pane(0).LayoutLine());
       
  1213                 canvasRect.LayoutRect(mainMidpPane.Rect(), AknLayoutScalable_Avkon::midp_canvas_pane(5).LayoutLine());
       
  1214             }
       
  1215             else//landscape
       
  1216             {
       
  1217                 mainPane.LayoutRect(resultRect, AknLayoutScalable_Avkon::main_pane(4).LayoutLine());
       
  1218                 mainMidpPane.LayoutRect(mainPane.Rect(), AknLayoutScalable_Avkon::main_midp_pane(1).LayoutLine());
       
  1219                 canvasRect.LayoutRect(mainMidpPane.Rect(), AknLayoutScalable_Avkon::midp_canvas_pane(6).LayoutLine());
       
  1220             }
       
  1221         }
       
  1222         resultRect = canvasRect.Rect();
       
  1223         break;
       
  1224     }
       
  1225     case EOnScreenKeypadValueLskRsk:
       
  1226     {
       
  1227         if (iIsFullScreenMode)
       
  1228         {
       
  1229             if (!Layout_Meta_Data::IsLandscapeOrientation())  //portrait
       
  1230             {
       
  1231                 canvasRect.LayoutRect(resultRect, AknLayoutScalable_Avkon::midp_canvas_pane(11).LayoutLine());
       
  1232             }
       
  1233             else //landscape
       
  1234             {
       
  1235                 if (iSKPositionWithQwerty == ESoftkeysRight)
       
  1236                 {
       
  1237                     canvasRect.LayoutRect(resultRect, AknLayoutScalable_Avkon::midp_canvas_pane(10).LayoutLine());
       
  1238                 }
       
  1239                 else  //default mode:Softkeys bottom
       
  1240                 {
       
  1241                     resultRect = TRect(80,0,560,360);//temp code here.LAF correction needed!
       
  1242                     //canvasRect.LayoutRect( resultRect, AknLayoutScalable_Avkon::midp_canvas_pane(9).LayoutLine() );
       
  1243 
       
  1244                     DEBUG("- CMIDDisplayable::GetCanvasRectFromLaf");
       
  1245                     return resultRect; //Temp code here.LAF correction needed!
       
  1246                 }
       
  1247             }
       
  1248         }
       
  1249         else//normal mode
       
  1250         {
       
  1251             //no need to present LSK&RSK in OSK when in normal mode Canvas
       
  1252             resultRect = TRect(0,0,0,0);
       
  1253 
       
  1254             DEBUG("- CMIDDisplayable::GetCanvasRectFromLaf");
       
  1255             return resultRect;
       
  1256         }
       
  1257         resultRect = canvasRect.Rect();
       
  1258         break;
       
  1259     }
       
  1260     default:
       
  1261     {
       
  1262         resultRect = TRect(0,0,0,0);
       
  1263         break;
       
  1264     }
       
  1265     }
       
  1266 
       
  1267     DEBUG("- CMIDDisplayable::GetCanvasRectFromLaf");
       
  1268     return resultRect;
       
  1269 }
       
  1270 
       
  1271 // ---------------------------------------------------------------------------
       
  1272 //
       
  1273 // ---------------------------------------------------------------------------
       
  1274 //
       
  1275 void CMIDDisplayable::AddCommandL(MMIDCommand* aCommand)
       
  1276 {
       
  1277     iCommandList->AddL(aCommand);
       
  1278     InitializeCbasL();
       
  1279     iMenuHandler->UpdateMenuIfVisibleL();
       
  1280 }
       
  1281 
       
  1282 // ---------------------------------------------------------------------------
       
  1283 //
       
  1284 // ---------------------------------------------------------------------------
       
  1285 //
       
  1286 void CMIDDisplayable::RemoveCommand(MMIDCommand* aCommand)
       
  1287 {
       
  1288     iCommandList->Remove(aCommand);
       
  1289     TRAP_IGNORE(InitializeCbasL());
       
  1290     TRAP_IGNORE(iMenuHandler->UpdateMenuIfVisibleL());
       
  1291 }
       
  1292 
       
  1293 // ---------------------------------------------------------------------------
       
  1294 // This method reports the total space available to the
       
  1295 // content class. Displayable subclasses may report a
       
  1296 // different value as the width/height in which case they
       
  1297 // will use a differnt mechanism.
       
  1298 // @see MMIDCanvas::ContentSize
       
  1299 // @see MMIDForm::Width
       
  1300 // @see MMIDForm::Height
       
  1301 // ---------------------------------------------------------------------------
       
  1302 TSize CMIDDisplayable::ContentSize() const
       
  1303 {
       
  1304     if (iContent->Type() == MMIDComponent::EAlert)
       
  1305     {
       
  1306         return static_cast<CMIDAlert*>(iContent)->Dialog()->Size();
       
  1307     }
       
  1308     else if (iContent->Type() == MMIDComponent::ETextBox && iIsPopupTextBox)
       
  1309     {
       
  1310         return static_cast<CMIDTextBoxDialogControl*>(iContent)->Dialog()->ContentSize();
       
  1311     }
       
  1312     else if (iContent->Type() == MMIDComponent::EForm)
       
  1313     {
       
  1314         // return the size that is available for the form items
       
  1315         // as stated in MIDP specification. This is smaller size than would be
       
  1316         // returned by the iContentControl->Size().
       
  1317         CMIDForm* form = static_cast<CMIDForm*>(iContent);
       
  1318         return TSize(form->Width(), form->Height());
       
  1319     }
       
  1320     /**
       
  1321     Size really depends on the content class, however
       
  1322     javax.microedition.lcdui.Form and javax.microedition.lcdui.Canvas
       
  1323     contain overrides to return the correct size - so polymorphism is
       
  1324     only required here for List,TextBox and Alert.
       
  1325 
       
  1326     We return the size of the content control, so as long as the content
       
  1327     control keeps its size up to date (eg alerts must have the same size as the dialog)
       
  1328     the correct size will be returned even if there is no polymorphism
       
  1329     provided by the framework. Now, for alerts UpdateSizeL() must have
       
  1330     been called, in fact when the dialog is not yet displaying they need
       
  1331     to create one, set the size and then delete the dialog immediately.
       
  1332     */
       
  1333     if (iContentControl)
       
  1334     {
       
  1335         return iContentControl->Size();
       
  1336     }
       
  1337 
       
  1338     //If there is no content then we shouldn't really exist
       
  1339     //because java side Displayable is abstract
       
  1340     return TSize(0,0);
       
  1341 }
       
  1342 
       
  1343 // ---------------------------------------------------------------------------
       
  1344 // Called by the framework when current displayable was changed
       
  1345 // in case that old and new displayable type is canvas to change osk state
       
  1346 // ---------------------------------------------------------------------------
       
  1347 void CMIDDisplayable::ChangeOSKBackgroundState(TBool aOSKBackgroundState)
       
  1348 {
       
  1349     if (iContent && iContent->Type() == ECanvas)
       
  1350     {
       
  1351         if (iCanvasKeypad)
       
  1352         {
       
  1353             iCanvasKeypad->OSKInBackground(aOSKBackgroundState);
       
  1354         }
       
  1355     }
       
  1356 }
       
  1357 
       
  1358 // ---------------------------------------------------------------------------
       
  1359 // Called by the framework when we become or stop being the active displayable.
       
  1360 // See HandleActivated(), HandleDeactivated().
       
  1361 // ---------------------------------------------------------------------------
       
  1362 void CMIDDisplayable::HandleCurrentL(TBool aCurrent)
       
  1363 {
       
  1364     DEBUG("+ CMIDDisplayable::HandleCurrentL");
       
  1365     ASSERT(iContentControl);
       
  1366     ASSERT(iContent);
       
  1367 
       
  1368     iActive = aCurrent;
       
  1369     const TType type = iContent->Type();
       
  1370 
       
  1371 #ifdef RD_JAVA_NGA_ENABLED
       
  1372     HandleCanvasForeground(aCurrent);
       
  1373 #endif // RD_JAVA_NGA_ENABLED
       
  1374 
       
  1375     if (aCurrent)
       
  1376     {
       
  1377         // when setting displayable as current remember to deactivate
       
  1378         // the default displayable if it has not been done yet
       
  1379         CMIDDisplayable* defaultDisplayable =
       
  1380             iUIManager->GetDefaultDisplayable();
       
  1381         if (defaultDisplayable &&
       
  1382                 (this != defaultDisplayable) &&
       
  1383                 defaultDisplayable->IsActive())
       
  1384         {
       
  1385             defaultDisplayable->HandleCurrentL(EFalse);
       
  1386         }
       
  1387         // "Whole screen size"-displayable behind popup type displayable is stored.
       
  1388         if (type == EAlert || (type == ETextBox && iIsPopupTextBox))
       
  1389         {
       
  1390             if (!(iMenuHandler->GetDisplayable() && (iMenuHandler->GetDisplayable()->IsPopupTextBox() ||
       
  1391                     iMenuHandler->GetDisplayable()->Component()->Type() == EAlert)))
       
  1392             {
       
  1393                 iDisplayableBehindPopup    = iMenuHandler->GetDisplayable();
       
  1394             }
       
  1395         }
       
  1396 
       
  1397         iMenuHandler->SetDisplayable(this);
       
  1398         // Tell the iAppUi about setting this as active
       
  1399         iAppUi->SetCurrentDisplayable(this);
       
  1400         HandleActivatedL();
       
  1401     }
       
  1402     else
       
  1403     {
       
  1404         HandleDeactivated();
       
  1405     }
       
  1406 
       
  1407     if (type == EAlert)
       
  1408     {// alerts do their on thing, they rely on sleeping dialogs in fact
       
  1409         CMIDAlert* alert = static_cast<CMIDAlert*>(iContentControl);
       
  1410         TRAP_IGNORE(alert->HandleCurrentL(aCurrent));
       
  1411 
       
  1412         UpdateTickerL();
       
  1413     }
       
  1414     else if (type == ETextBox && iIsPopupTextBox)
       
  1415     {// Pop-up TextBox do their on thing, they rely on sleeping dialogs in fact
       
  1416         CMIDTextBoxDialogControl* textBoxDialogControl =
       
  1417             static_cast<CMIDTextBoxDialogControl*>(iContentControl);
       
  1418         TRAP_IGNORE(textBoxDialogControl->HandleCurrentL(aCurrent));
       
  1419     }
       
  1420     else
       
  1421     {
       
  1422         if (aCurrent)
       
  1423         {
       
  1424             UpdateVisualAppearanceL();
       
  1425         }
       
  1426         else
       
  1427         {
       
  1428             // Hide the displayable except the current displayable is Alert
       
  1429             // or pop-up TextBox.
       
  1430             if ((this != iUIManager->GetDefaultDisplayable()) &&
       
  1431                     (iMenuHandler->GetDisplayable()) &&
       
  1432                     (iMenuHandler->GetDisplayable()->Component()->Type() != EAlert)  &&
       
  1433                     !(iMenuHandler->GetDisplayable()->Component()->Type() == ETextBox &&
       
  1434                       iMenuHandler->GetDisplayable()->IsPopupTextBox()))
       
  1435             {
       
  1436                 MakeVisible(EFalse);
       
  1437             }
       
  1438         }
       
  1439 
       
  1440         iContentControl->SetFocus(aCurrent);
       
  1441 
       
  1442         switch (type)
       
  1443         {
       
  1444         case EForm:
       
  1445         {
       
  1446             CMIDForm* form = static_cast<CMIDForm*>(iContentControl);
       
  1447             TRAP_IGNORE(form->HandleCurrentL(aCurrent));
       
  1448             break;
       
  1449         }
       
  1450         case ETextBox:
       
  1451         {
       
  1452             CMIDTextBoxControl* textBoxControl =
       
  1453                 static_cast<CMIDTextBoxControl*>(iContentControl);
       
  1454             TRAP_IGNORE(textBoxControl->HandleCurrentL(aCurrent));
       
  1455             break;
       
  1456         }
       
  1457         }
       
  1458     }
       
  1459 
       
  1460     DEBUG("- CMIDDisplayable::HandleCurrentL");
       
  1461 }
       
  1462 
       
  1463 /**
       
  1464  * Called when we become the active displayable, see HandleCurrent().
       
  1465  * Put icontentControl on the app UI stack and update the title.
       
  1466  **/
       
  1467 void CMIDDisplayable::HandleActivatedL()
       
  1468 {
       
  1469     DEBUG("+ CMIDDisplayable::HandleActivatedL");
       
  1470     ASSERT(iContentControl);
       
  1471 
       
  1472     if (iContentControl->IsNonFocusing()) // i.e it's a Form
       
  1473     {
       
  1474         iAppUi->AddToStackL(
       
  1475             iContentControl,
       
  1476             (ECoeStackPriorityDefault - 1),
       
  1477             ECoeStackFlagRefusesFocus);
       
  1478     }
       
  1479     else
       
  1480     {
       
  1481         iAppUi->AddToStackL(iContentControl);
       
  1482     }
       
  1483 
       
  1484     ShowTitleL();
       
  1485 
       
  1486     /* In case Canvas is in fullcsreen mode iDisplaybleRect needs to be updated.
       
  1487      * The Canvas rect has been reduced if Casvas has been displayed before (See HandleDeactivated).
       
  1488      */
       
  1489     if (iContent && iContent->Type() == ECanvas)
       
  1490     {
       
  1491         if (iCanvasKeypad)
       
  1492         {
       
  1493             UpdateOnScreenKeypadSettings();
       
  1494         }
       
  1495         UpdateDisplayableRect();
       
  1496         SetRect(iDisplayableRect);
       
  1497     }
       
  1498 
       
  1499 #ifdef RD_SCALABLE_UI_V2
       
  1500     // Hide CanvasKeypad if the current displayable is not Alert nor pop-up TextBox.
       
  1501     if (iUIManager->GetCanvasKeypad() && !iCanvasKeypad &&
       
  1502             (iContent->Type() != EAlert &&
       
  1503              !(iContent->Type() == ETextBox && iIsPopupTextBox)))
       
  1504     {
       
  1505         iUIManager->GetCanvasKeypad()->MakeVisible(EFalse);
       
  1506     }
       
  1507 #endif //RD_SCALABLE_UI_V2
       
  1508 
       
  1509     DEBUG("- CMIDDisplayable::HandleActivatedL");
       
  1510 }
       
  1511 
       
  1512 // ---------------------------------------------------------------------------
       
  1513 // Called when we stop being the active displayable, see HandleCurrent().
       
  1514 // Remove iContentControl from the app UI stack. If a menu was showing then
       
  1515 // hide it.
       
  1516 // ---------------------------------------------------------------------------
       
  1517 void CMIDDisplayable::HandleDeactivated()
       
  1518 {
       
  1519     DEBUG("+ CMIDDisplayable::HandleDeactivated");
       
  1520     ASSERT(iContentControl);
       
  1521 
       
  1522     // Make displayable behind popup/Alert non-visible if displayable behind
       
  1523     // popup/Alert is changed to Canvas when dismissing the popup/Alert.
       
  1524     // Use case: Canvas on-screen keypad visibility after displayable changes.
       
  1525     if (iDisplayableBehindPopup && iContent && (iContent->Type() == EAlert || (iContent->Type() == ETextBox && iIsPopupTextBox))
       
  1526             && iDisplayableBehindPopup != iMenuHandler->GetDisplayable())
       
  1527     {
       
  1528         if (iMenuHandler->GetDisplayable()->Component()->Type() == ECanvas ||
       
  1529                 iMenuHandler->GetDisplayable()->Component()->Type() == EGameCanvas)
       
  1530         {
       
  1531             iDisplayableBehindPopup->MakeVisible(EFalse);
       
  1532         }
       
  1533     }
       
  1534 
       
  1535     // Stop displaying commands of old displayable
       
  1536     iMenuHandler->HideMenuIfVisible();
       
  1537 
       
  1538     // Stop repeat timer if OSK set to background
       
  1539     if (iContent && iContent->Type() == ECanvas && iCanvasKeypad)
       
  1540     {
       
  1541         iCanvasKeypad->OSKInBackground(ETrue);
       
  1542     }
       
  1543 
       
  1544     iAppUi->RemoveFromStack(iContentControl);
       
  1545 
       
  1546     /* Enable status pane when Canvas in fullscreen mode is deactivated.
       
  1547      * In case there is Canvas in fullscreen mode and then setCurrent(Alert,normal mode displayable)
       
  1548      * is called, status pane stays behind the Canvas window.
       
  1549      * First we make status pane and cbas visible according to whether we
       
  1550      * are full screen or not. This determines the rect returned by iAppUi->ClientRect()
       
  1551      */
       
  1552     if (iContent && iContent->Type() == ECanvas && iIsFullScreenMode)
       
  1553     {
       
  1554         CEikStatusPane* pane = iAppUi->StatusPane();
       
  1555         pane->MakeVisible(ETrue);
       
  1556         // set right Width from APPUI client rect
       
  1557         TRect displayableRectT = iDisplayableRect;
       
  1558         TRect iDisplayableRect = iAppUi->ClientRect();
       
  1559         iDisplayableRect.iBr.iY = displayableRectT.iBr.iY;
       
  1560 
       
  1561         TRAPD(err, SetFullScreenModeL(ETrue));
       
  1562         if (err != KErrNone)
       
  1563         {
       
  1564             DEBUG_INT("CMIDDisplayable::HandleDeactivated - SetFullScreenModeL error %d", err);
       
  1565         }
       
  1566     }
       
  1567 
       
  1568     DEBUG("- CMIDDisplayable::HandleDeactivated");
       
  1569 }
       
  1570 
       
  1571 // ---------------------------------------------------------------------------
       
  1572 //
       
  1573 // ---------------------------------------------------------------------------
       
  1574 //
       
  1575 void CMIDDisplayable::UpdateVisualAppearanceL()
       
  1576 {
       
  1577     DEBUG("+ CMIDDisplayable::UpdateVisualAppearanceL");
       
  1578 
       
  1579     Window().SetOrdinalPosition(0);
       
  1580     MakeVisible(ETrue);
       
  1581 
       
  1582     // First we make status pane and cbas visible according to whether we
       
  1583     // are full screen or not. This determines the rect returned by
       
  1584     // iAppUi->ClientRect()
       
  1585     CEikStatusPane* pane = iAppUi->StatusPane();
       
  1586     pane->MakeVisible(!iIsFullScreenMode);
       
  1587 
       
  1588     java::ui::CoreUiAvkonAppUi* appUi = java::ui::CoreUiAvkonLcdui::getInstance().getJavaUiAppUi();
       
  1589     if (!iIsFullScreenMode && appUi && appUi->hidesIndicators())
       
  1590     {
       
  1591         HideIndicators();
       
  1592     }
       
  1593 
       
  1594     iCba->MakeVisible(!iIsFullScreenMode);
       
  1595 
       
  1596     // Close fixed toolbar for full screen Canvas.
       
  1597     CAknToolbar* toolbar = iAppUi->CurrentFixedToolbar();
       
  1598     if (toolbar)
       
  1599     {
       
  1600         toolbar->SetToolbarVisibility(!iIsFullScreenMode);
       
  1601     }
       
  1602 
       
  1603 #ifdef RD_SCALABLE_UI_V2
       
  1604     if ((iActive && iCanvasKeypad) || (!iActive && this->DrawableWindow()->IsFaded() && iCanvasKeypad))
       
  1605     {
       
  1606         if (iUseOnScreenKeypad)
       
  1607         {
       
  1608             iCanvasKeypad->UpdateVisualAppearanceL(
       
  1609                 *iCanvas, iOnScreenKeyboardType, *this);
       
  1610 
       
  1611             // Because keypad changed its appearance we have to assure that
       
  1612             // values for soft key label locations are updated.
       
  1613             iFullscreenCanvasLabelCacheIsValid = EFalse;
       
  1614         }
       
  1615         else
       
  1616         {
       
  1617             // Canvas keypad has to be set invisible if On-Screen keypad is
       
  1618             // not to be used. Otherwise, if the visibility not handled here,
       
  1619             // status pane and CBA area's visual appearance can be corrupted.
       
  1620             if (!iIsFullScreenMode)
       
  1621             {
       
  1622                 iCanvasKeypad->MakeVisible(EFalse);
       
  1623             }
       
  1624         }
       
  1625     }
       
  1626 #endif //RD_SCALABLE_UI_V2
       
  1627 
       
  1628     // At this point we can set the rect.
       
  1629     if (!iIsFullScreenMode && iCba)
       
  1630     {
       
  1631         InitializeCbasL();
       
  1632         iCba->DrawableWindow()->SetOrdinalPosition(0);
       
  1633     }
       
  1634 
       
  1635     UpdateTickerL();
       
  1636     DrawDeferred();
       
  1637     DEBUG("- CMIDDisplayable::UpdateVisualAppearanceL");
       
  1638 }
       
  1639 
       
  1640 // ---------------------------------------------------------------------------
       
  1641 //
       
  1642 // ---------------------------------------------------------------------------
       
  1643 //
       
  1644 void CMIDDisplayable::SetComponentL(MMIDComponent& aComponent)
       
  1645 {
       
  1646     ASSERT(!iContentControl);
       
  1647 
       
  1648     iContent = &aComponent;
       
  1649     iContentControl = NULL;
       
  1650 
       
  1651     MMIDComponent::TType type = aComponent.Type();
       
  1652     switch (type)
       
  1653     {
       
  1654     case MMIDComponent::EForm:
       
  1655         iContentControl = static_cast<CMIDForm*>(iContent);
       
  1656         break;
       
  1657     case MMIDComponent::EAlert:
       
  1658         iContentControl = static_cast<CMIDAlert*>(iContent);
       
  1659         break;
       
  1660     case MMIDComponent::ECanvas:
       
  1661     case MMIDComponent::EGameCanvas:
       
  1662     {
       
  1663         iContentControl = &(static_cast<MMIDCanvas*>(iContent)->Control());
       
  1664 #ifdef RD_SCALABLE_UI_V2
       
  1665         iCanvas = static_cast<CMIDCanvas*>(iContentControl);
       
  1666         if (AknLayoutUtils::PenEnabled())
       
  1667         {
       
  1668             iUseOnScreenKeypad = ETrue;
       
  1669             iCanvasKeypad = iUIManager->OpenCanvasKeypadL(this);
       
  1670 
       
  1671             // initialize iPropertyWatch as CPropertyWatch
       
  1672             iPropertyWatch = CPropertyWatch::NewL(this);//Property observer
       
  1673             UpdateOnScreenKeypadSettings();
       
  1674         }
       
  1675         UpdateDisplayableRect();
       
  1676         SetRect(iDisplayableRect);
       
  1677 #endif //RD_SCALABLE_UI_V2
       
  1678     }
       
  1679     break;
       
  1680     case MMIDComponent::ETextBox:
       
  1681         if (iIsPopupTextBox) // pop-up TextBox
       
  1682         {
       
  1683             iContentControl = static_cast<CMIDTextBoxDialogControl*>(iContent);
       
  1684         }
       
  1685         else                // normal TextBox
       
  1686         {
       
  1687             iContentControl = static_cast<CMIDTextBoxControl*>(iContent);
       
  1688         }
       
  1689         break;
       
  1690     case MMIDComponent::EList:
       
  1691         iContentControl = static_cast<CMIDList*>(iContent);
       
  1692         // Lengthen long tap delay to get better usability.
       
  1693         iLongTapDetector->SetTimeDelayBeforeAnimation(KListLongTapAnimationDelay);
       
  1694         iLongTapDetector->SetLongTapDelay(KListLongTapAnimationDelay + KListLongTapDelay);
       
  1695         break;
       
  1696     case MMIDComponent::EDefaultBackground:
       
  1697         iContentControl = static_cast<CMIDDefaultBackground*>(iContent);
       
  1698         break;
       
  1699     default:
       
  1700         ASSERT(iContentControl);
       
  1701     }
       
  1702     Layout();
       
  1703 
       
  1704     ASSERT(iContentControl);
       
  1705     iContentControl->ActivateL();
       
  1706 
       
  1707     DEBUG("- CMIDDisplayable::SetComponentL");
       
  1708 }
       
  1709 
       
  1710 
       
  1711 void CMIDDisplayable::UpdateOnScreenKeypadSettings()
       
  1712 {
       
  1713     DEBUG("+ CMIDDisplayable::UpdateOnScreenKeypadSettings");
       
  1714     if (iCanvasKeypad)
       
  1715     {
       
  1716         TInt hwKeyboardLayout = 0;
       
  1717 
       
  1718         if (AknLayoutUtils::PenEnabled())
       
  1719         {
       
  1720             // touch screen
       
  1721             ReadOnScreenKeypadTypeFromSuiteSettings();
       
  1722 
       
  1723             if (iOnScreenKeyboardType == EOnScreenKeypadValueNo)
       
  1724             {
       
  1725                 iUseOnScreenKeypad = EFalse;
       
  1726 
       
  1727                 DEBUG("- CMIDDisplayable::UpdateOnScreenKeypadSettings");
       
  1728                 return;
       
  1729             }
       
  1730 
       
  1731             RProperty::Get(
       
  1732                 KCRUidAvkon, KAknKeyBoardLayout, hwKeyboardLayout);
       
  1733 
       
  1734             // Avoid display of on-screen keypad on screen
       
  1735             // in landscape mode for QWERTY layout 3x11 (4) and 4x10 (3)
       
  1736             if (hwKeyboardLayout == EPtiKeyboardQwerty4x10 ||
       
  1737                     hwKeyboardLayout == EPtiKeyboardQwerty3x11)
       
  1738             {
       
  1739                 // HW keyboard is opened
       
  1740                 if (iIsFullScreenMode)
       
  1741                 {
       
  1742                     iOnScreenKeyboardType = EOnScreenKeypadValueLskRsk;
       
  1743                     iUseOnScreenKeypad = ETrue;
       
  1744                 }
       
  1745                 else
       
  1746                 {
       
  1747                     // normal mode
       
  1748                     iOnScreenKeyboardType = EOnScreenKeypadValueNo;
       
  1749                     iUseOnScreenKeypad = EFalse;
       
  1750                 }
       
  1751             }
       
  1752             else
       
  1753             {
       
  1754                 // Keypadless device or HW keyboard is closed
       
  1755                 iUseOnScreenKeypad = ETrue;
       
  1756             }
       
  1757         }
       
  1758         else
       
  1759         {
       
  1760             // no touch screen
       
  1761             iUseOnScreenKeypad = EFalse;
       
  1762             iOnScreenKeyboardType = EOnScreenKeypadValueNo;
       
  1763         }
       
  1764     }
       
  1765 
       
  1766     DEBUG("- CMIDDisplayable::UpdateOnScreenKeypadSettings");
       
  1767 }
       
  1768 
       
  1769 void CMIDDisplayable::ReadOnScreenKeypadTypeFromSuiteSettings()
       
  1770 {
       
  1771     DEBUG("+ CMIDDisplayable::ReadOnScreenKeypadTypeFromSuiteSettings");
       
  1772 
       
  1773     // Read required keyboard type
       
  1774     // 0=not defined,  1=no, 2=navigationkeys, 3=gameactions(default)
       
  1775     TRAP_IGNORE(iOnScreenKeyboardType = OnScreenKeypadL());
       
  1776     if (iOnScreenKeyboardType == EOnScreenKeypadValueUndefined)
       
  1777     {
       
  1778         // if keypad value cannot be read correctly
       
  1779         // set gameactions keypad active (ignore error silently)
       
  1780         iOnScreenKeyboardType = EOnScreenKeypadValueGameActions;
       
  1781     }
       
  1782 
       
  1783     DEBUG("- CMIDDisplayable::ReadOnScreenKeypadTypeFromSuiteSettings");
       
  1784 }
       
  1785 
       
  1786 void CMIDDisplayable::HandleOnScreenKeypadVisual()
       
  1787 {
       
  1788     DEBUG("+ CMIDDisplayable::HandleOnScreenKeypadVisual");
       
  1789     if (iActive)
       
  1790     {
       
  1791         UpdateOnScreenKeypadSettings();
       
  1792         UpdateDisplayableRect();
       
  1793         SetRect(iDisplayableRect);
       
  1794         TRAP_IGNORE(UpdateVisualAppearanceL());
       
  1795     }
       
  1796     DEBUG("- CMIDDisplayable::HandleOnScreenKeypadVisual");
       
  1797 }
       
  1798 
       
  1799 
       
  1800 // ---------------------------------------------------------------------------
       
  1801 //
       
  1802 // ---------------------------------------------------------------------------
       
  1803 //
       
  1804 CCoeControl& CMIDDisplayable::ContentWindow()
       
  1805 {
       
  1806     return *this;
       
  1807 }
       
  1808 
       
  1809 // ---------------------------------------------------------------------------
       
  1810 //
       
  1811 // ---------------------------------------------------------------------------
       
  1812 //
       
  1813 void CMIDDisplayable::SetCommandListenerExistence(TBool aExistence)
       
  1814 {
       
  1815     iCommandListenerExistence = aExistence;
       
  1816 }
       
  1817 
       
  1818 // ---------------------------------------------------------------------------
       
  1819 //
       
  1820 // ---------------------------------------------------------------------------
       
  1821 //
       
  1822 TBool CMIDDisplayable::IsCommandListenerSet() const
       
  1823 {
       
  1824     return iCommandListenerExistence;
       
  1825 }
       
  1826 
       
  1827 // ---------------------------------------------------------------------------
       
  1828 // Gets a softkey label location
       
  1829 // This can be got fot fullscreen canvas only
       
  1830 // ---------------------------------------------------------------------------
       
  1831 //
       
  1832 TBool CMIDDisplayable::SoftKeyLabelLocation(TInt aSoftKeyId, TPoint& aPosition, TSize& aSize)
       
  1833 {
       
  1834     if ((iContent->Type() == ECanvas && iIsFullScreenMode) &&
       
  1835             (aSoftKeyId > 0) &&
       
  1836             (aSoftKeyId <= KSoftKeyLabelPropertyNumberOfSoftKeys))
       
  1837     {
       
  1838         // Refresh the properties cache
       
  1839         // (can be trapped - checked by iFullscreenCanvasLabelCacheIsValid)
       
  1840         TRAPD(result, RenewFullscreenCanvasLabelCacheL());
       
  1841         if (result != KErrNone)
       
  1842         {
       
  1843             DEBUG_INT("CMIDDisplayable::SoftKeyLabelLocation - Exception from CMIDDisplayable::RenewFullscreenCanvasLabelCacheL. Error = %d", result);
       
  1844         }
       
  1845         else
       
  1846         {
       
  1847             TInt skIndex = aSoftKeyId - 1;
       
  1848             if (iFullscreenCanvasLabelCacheIsValid &&
       
  1849                     iFullscreenCanvasLabelCache[ skIndex ].iIsOn)
       
  1850             {
       
  1851 
       
  1852                 aPosition = iFullscreenCanvasLabelCache[ skIndex ].iPosition;
       
  1853                 aSize = iFullscreenCanvasLabelCache[ skIndex ].iSize;
       
  1854                 return ETrue;
       
  1855             }
       
  1856         }
       
  1857     }
       
  1858     return EFalse;
       
  1859 }
       
  1860 
       
  1861 // ---------------------------------------------------------------------------
       
  1862 // Force sync draw.
       
  1863 // ---------------------------------------------------------------------------
       
  1864 //
       
  1865 void CMIDDisplayable::DrawNow()
       
  1866 {
       
  1867     CEikBorderedControl::DrawNow();
       
  1868     if (iCba)
       
  1869         iCba->DrawNow();
       
  1870     iAppUi->StatusPane()->DrawNow();
       
  1871 }
       
  1872 
       
  1873 // ---------------------------------------------------------------------------
       
  1874 // Gets a softkey label anchor
       
  1875 // This can be got fot fullscreen canvas only
       
  1876 // ---------------------------------------------------------------------------
       
  1877 //
       
  1878 TInt CMIDDisplayable::SoftKeyLabelAnchor(TInt aSoftKeyId)
       
  1879 {
       
  1880     if ((iContent->Type() == ECanvas && iIsFullScreenMode) &&
       
  1881             (aSoftKeyId > 0) &&
       
  1882             (aSoftKeyId <= KSoftKeyLabelPropertyNumberOfSoftKeys))
       
  1883     {
       
  1884         // Refresh the properties cache
       
  1885         // (can be trapped - checked by iFullscreenCanvasLabelCacheIsValid)
       
  1886         TRAPD(result, RenewFullscreenCanvasLabelCacheL());
       
  1887         if (result != KErrNone)
       
  1888         {
       
  1889             DEBUG_INT("CMIDDisplayable::SoftKeyLabelAnchor - Exception from CMIDDisplayable::RenewFullscreenCanvasLabelCacheL. Error = %d", result);
       
  1890         }
       
  1891         else
       
  1892         {
       
  1893             TInt skIndex = aSoftKeyId - 1;
       
  1894             if (iFullscreenCanvasLabelCacheIsValid &&
       
  1895                     iFullscreenCanvasLabelCache[ skIndex ].iIsOn)
       
  1896             {
       
  1897                 return iFullscreenCanvasLabelCache[ skIndex ].iAnchor;
       
  1898             }
       
  1899         }
       
  1900     }
       
  1901     return 0;
       
  1902 }
       
  1903 
       
  1904 void CMIDDisplayable::SetS60SelectionKeyCompatibility(TBool aS60SelectionKeyCompatibility)
       
  1905 {
       
  1906     iS60SelectionKeyCompatibility = aS60SelectionKeyCompatibility;
       
  1907 }
       
  1908 
       
  1909 // ---------------------------------------------------------------------------
       
  1910 //
       
  1911 // ---------------------------------------------------------------------------
       
  1912 //
       
  1913 CMIDUIManager* CMIDDisplayable::GetUIManager() const
       
  1914 {
       
  1915     return iUIManager;
       
  1916 }
       
  1917 
       
  1918 // ---------------------------------------------------------------------------
       
  1919 //
       
  1920 // ---------------------------------------------------------------------------
       
  1921 //
       
  1922 void CMIDDisplayable::UpdateDisplayableRect()
       
  1923 {
       
  1924     DEBUG("+ CMIDDisplayable::UpdateDisplayableRect");
       
  1925 
       
  1926 #ifdef RD_SCALABLE_UI_V2
       
  1927     TRect canvasRect;
       
  1928     if (iContent)
       
  1929     {
       
  1930         if (iUseOnScreenKeypad)
       
  1931         {
       
  1932             MMIDComponent::TType type = iContent->Type();
       
  1933             if (type == ECanvas || type == EGameCanvas)
       
  1934             {
       
  1935                 canvasRect = GetCanvasRectFromLaf();
       
  1936             }
       
  1937         }
       
  1938     }
       
  1939 #endif //RD_SCALABLE_UI_V2
       
  1940     if (iIsFullScreenMode)
       
  1941     {
       
  1942         iDisplayableRect = iAppUi->ApplicationRect();
       
  1943 
       
  1944         // Update Cba because of softkey location properties
       
  1945         // (see RenewFullscreenCanvasLabelCacheL())
       
  1946         if (iCba && iActive)
       
  1947         {
       
  1948             // enable cba so that the layout is performed correctly
       
  1949             iCba->MakeVisible(ETrue);
       
  1950             iCba->SetBoundingRect(iDisplayableRect);
       
  1951             // iCba is always invisible in fullscreen
       
  1952             iCba->MakeVisible(EFalse);
       
  1953         }
       
  1954 
       
  1955 #ifdef RD_SCALABLE_UI_V2
       
  1956         if (iUseOnScreenKeypad && (canvasRect != TRect(0,0,0,0)))
       
  1957         {
       
  1958             iDisplayableRect = canvasRect;
       
  1959         }
       
  1960 #endif //RD_SCALABLE_UI_V2
       
  1961     }
       
  1962     else
       
  1963     {
       
  1964         // In case we are changing from FullScreen mode to Normal mode
       
  1965         // the status pane has to be enabled before quering client area rect.
       
  1966         CEikStatusPane* pane = iAppUi->StatusPane();
       
  1967         // Store pane visibility
       
  1968         TBool paneVisible = pane->IsVisible();
       
  1969         pane->MakeVisible(ETrue);
       
  1970 
       
  1971         iDisplayableRect = iAppUi->ClientRect();
       
  1972 
       
  1973 #ifdef RD_SCALABLE_UI_V2
       
  1974         if (iUseOnScreenKeypad && (canvasRect != TRect(0,0,0,0)))
       
  1975         {
       
  1976             iDisplayableRect = canvasRect;
       
  1977         }
       
  1978 #endif //RD_SCALABLE_UI_V2
       
  1979         if (!iActive)
       
  1980         { // Restore pane visibility. There is one pane for all displayables.
       
  1981             // Only active displayable can decide about the pane visibility.
       
  1982             // Others should not change it.
       
  1983             pane->MakeVisible(paneVisible);
       
  1984         }
       
  1985 
       
  1986         if (iCba)
       
  1987         {
       
  1988             // Store cba visibility
       
  1989             TBool cbaVisible = iCba->IsVisible();
       
  1990 
       
  1991             // enable cba so that the layout is performed correctly
       
  1992             iCba->MakeVisible(ETrue);
       
  1993 
       
  1994             iCba->SetBoundingRect(iDisplayableRect);
       
  1995             // Control pane area has to be reduced
       
  1996             iCba->ReduceRect(iDisplayableRect);
       
  1997 
       
  1998             if (!iActive)
       
  1999             { // Restore cba visibility. There is one cba for all displayables.
       
  2000                 // Only active displayable can decide about the cba visibility.
       
  2001                 // Others should not change it.
       
  2002                 iCba->MakeVisible(cbaVisible);
       
  2003             }
       
  2004         }
       
  2005     }
       
  2006 
       
  2007     DEBUG("- CMIDDisplayable::UpdateDisplayableRect");
       
  2008 }
       
  2009 
       
  2010 // ---------------------------------------------------------------------------
       
  2011 // When we are full screen (currently only Canvas supports this) we need to
       
  2012 // get rid of status pane and CBAs. We do this by calling SetRect() to the full
       
  2013 // screen rect. We also set a flag in canvas, which determines its behaviour.
       
  2014 // See CMIDCanvas::FullScreen(). We store the full screen status in iIsFullScreenMode.
       
  2015 // Note that this method is called by java side.
       
  2016 // ---------------------------------------------------------------------------
       
  2017 void CMIDDisplayable::SetFullScreenModeL(TBool aFullScreen)
       
  2018 {
       
  2019     DEBUG("+ CMIDDisplayable::SetFullScreenModeL");
       
  2020 
       
  2021     iIsFullScreenMode = aFullScreen;
       
  2022 
       
  2023     if (iContent->Type() == MMIDComponent::ECanvas)
       
  2024     {
       
  2025         static_cast<CMIDCanvas*>(iContent)->FullScreen(iIsFullScreenMode);
       
  2026     }
       
  2027     if (iCanvasKeypad)
       
  2028     {
       
  2029         UpdateOnScreenKeypadSettings();
       
  2030     }
       
  2031 
       
  2032     // Displayable rect is updated and set
       
  2033     UpdateDisplayableRect();
       
  2034     SetRect(iDisplayableRect);
       
  2035 
       
  2036     if (iActive)
       
  2037     { //this means we are the active displayable
       
  2038         UpdateVisualAppearanceL();
       
  2039     }
       
  2040 
       
  2041     if (aFullScreen)
       
  2042     {
       
  2043         iFullscreenCanvasLabelCacheIsValid = EFalse;
       
  2044     }
       
  2045 
       
  2046     DEBUG("- CMIDDisplayable::SetFullScreenModeL");
       
  2047 }
       
  2048 
       
  2049 // ---------------------------------------------------------------------------
       
  2050 // Return true if we are in full screen mode (cavas), false otherwise.
       
  2051 // @see iIsFullScreenMode
       
  2052 // @see SetFullScreenModeL().
       
  2053 // ---------------------------------------------------------------------------
       
  2054 TBool CMIDDisplayable::IsFullScreenMode() const
       
  2055 {
       
  2056     return iIsFullScreenMode;
       
  2057 }
       
  2058 
       
  2059 // ---------------------------------------------------------------------------
       
  2060 // Sets a new command to the middle soft key (MSK). This can be used e.g. by
       
  2061 // ListBox to set the selection command to the MSK. Context sensitive menu
       
  2062 // opening command is handled automatically by displayable, there is no need
       
  2063 // to set a command for that. Setting MSK via this method, overrides
       
  2064 // automatic behavior of displayable e.g. to open context menu. To unset the
       
  2065 // MSK command, set it to NULL, then the automatic behavior is effective again.
       
  2066 // ---------------------------------------------------------------------------
       
  2067 void CMIDDisplayable::SetMSKCommand(CMIDCommand* aMSKCommand)
       
  2068 {
       
  2069     CMIDCommand* oldMSKCommand = iMSKCommand;
       
  2070     iMSKCommand = aMSKCommand;
       
  2071     if (oldMSKCommand != iMSKCommand)
       
  2072     { // avoid unnecessary updating to avoid flickering
       
  2073         TRAP_IGNORE(InitializeCbasL());
       
  2074     }
       
  2075 }
       
  2076 
       
  2077 void CMIDDisplayable::SetSelectCommand(CMIDCommand* aSelectCommand)
       
  2078 {
       
  2079     if (aSelectCommand != iSelectCommand)
       
  2080     { // avoid unnecessary updating to avoid flickering
       
  2081         iSelectCommand = aSelectCommand;
       
  2082         TRAP_IGNORE(InitializeCbasL());
       
  2083     }
       
  2084 }
       
  2085 
       
  2086 void CMIDDisplayable::SetSelectCommandState(TBool aEnableSelectCommand)
       
  2087 {
       
  2088     iSelectCommandEnabled = aEnableSelectCommand;
       
  2089 }
       
  2090 
       
  2091 // ---------------------------------------------------------------------------
       
  2092 // Sets the list of form item commands associated with this Displayable on a
       
  2093 // given moment. Calling this will cause the CBA to be updated accordingly and
       
  2094 // usually it is called when focus has moved to a new Item.
       
  2095 //
       
  2096 // If the MSK command is not NULL, it will be presented in the middle soft key
       
  2097 // (MSK). Setting the MSK command here is basically equivalent to setting it with
       
  2098 // SetMSKCommand. The parameter is added here to remind the programmer and to
       
  2099 // gain a small performance benefit of not updating the CBA twice.
       
  2100 // ---------------------------------------------------------------------------
       
  2101 void CMIDDisplayable::SetItemCommandList(CMIDCommandList* aList, CMIDCommand* aMSKCommand)
       
  2102 {
       
  2103     iItemCommandList = aList;
       
  2104     if (iItemCommandList)
       
  2105     {
       
  2106         iItemCommandList->SetCommandOffset(KItemCommandIdBase);
       
  2107     }
       
  2108     CMIDCommand* oldMSKCommand = iMSKCommand;
       
  2109     iMSKCommand = aMSKCommand;
       
  2110 
       
  2111     TInt newCount = iItemCommandList ? iItemCommandList->Count() : 0;
       
  2112 
       
  2113     // To avoid flicker don't update the CBA if the old and the new command list
       
  2114     // both have 0 items (very likely).
       
  2115     if (!(iItemCommandsCount==0 && newCount==0) ||
       
  2116             oldMSKCommand != iMSKCommand
       
  2117             || iS60SelectionKeyCompatibility
       
  2118        )
       
  2119     {
       
  2120         TRAP_IGNORE(InitializeCbasL());
       
  2121     }
       
  2122 
       
  2123     // set current items commands count
       
  2124     iItemCommandsCount = newCount;
       
  2125 }
       
  2126 
       
  2127 // ---------------------------------------------------------------------------
       
  2128 // Called to show the MIDlet title in the Status Pane.
       
  2129 // ---------------------------------------------------------------------------
       
  2130 void CMIDDisplayable::ShowTitleL()
       
  2131 {
       
  2132     CEikStatusPane* pane = iAppUi->StatusPane();
       
  2133     CAknTitlePane* titlePane = (CAknTitlePane*)pane->ControlL(TUid::Uid(EEikStatusPaneUidTitle));
       
  2134 
       
  2135 
       
  2136     if ((iContent && iContent->Type() == ETextBox) && iIsPopupTextBox)
       
  2137     {
       
  2138         // No need to update status pane for pop-up TextBox, because it is not using it.
       
  2139     }
       
  2140     else if ((iContent && iContent->Type() == EAlert) || !(this->iTitle) ||
       
  2141              (this->iTitle->Length() < 1))
       
  2142     {
       
  2143         const TDesC& titleText = iEnv.MidletName();
       
  2144         titlePane->SetTextL(titleText);
       
  2145     }
       
  2146     else
       
  2147     {
       
  2148         titlePane->SetTextL(*iTitle);
       
  2149     }
       
  2150 }
       
  2151 // ---------------------------------------------------------------------------
       
  2152 // Get Tilte to
       
  2153 // ---------------------------------------------------------------------------
       
  2154 HBufC* CMIDDisplayable::Title()
       
  2155 {
       
  2156     return iTitle;
       
  2157 }
       
  2158 
       
  2159 // ---------------------------------------------------------------------------
       
  2160 // First map the first eligible command to every sk. Then for the
       
  2161 // sk that accepts the options menu, change the mapped command to
       
  2162 // the options menu if there are still commands that have not been
       
  2163 // mapped. ASSUMPTION 1: Only one sk accepts a menu and this menu is
       
  2164 // always the options menu. ASSUMPTION 2: sks are ordered so that
       
  2165 // sks that are more restrictive in the type of commands they accept
       
  2166 // come before less restrictive sks, eg the right sk comes before the
       
  2167 // left sk.
       
  2168 // Some components, for example, List, do not want MSK set if list is empty,
       
  2169 // decision is done based on enableDefaultMSK parameter value
       
  2170 //
       
  2171 // Finally draw the CBA.
       
  2172 // ---------------------------------------------------------------------------
       
  2173 void CMIDDisplayable::InitializeCbasL()
       
  2174 {
       
  2175     if (!iActive)
       
  2176     {
       
  2177         return;
       
  2178     }
       
  2179 
       
  2180     iCba->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY);
       
  2181 
       
  2182     // Initialize command lists
       
  2183     RArray<CMIDCommandList*> lists;
       
  2184     CleanupClosePushL(lists);
       
  2185     User::LeaveIfError(lists.Append(iCommandList));
       
  2186     User::LeaveIfError(lists.Append(iItemCommandList));
       
  2187 
       
  2188 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  2189     if (iSelectCommand)
       
  2190 #else
       
  2191     if (!iSelectCommandEnabled && iSelectCommand)
       
  2192 #endif // RD_JAVA_S60_RELEASE_9_2        
       
  2193     {
       
  2194         // remove the select command
       
  2195         for (TInt j = 0; j < lists.Count(); j++)
       
  2196         {
       
  2197             if (lists[j])
       
  2198             {
       
  2199                 CMIDCommandList* itemCommandList = lists[j];
       
  2200                 if (itemCommandList)
       
  2201                 {
       
  2202                     TInt index = itemCommandList->FindCommandIndex(iSelectCommand);
       
  2203                     if (index != KErrNotFound)
       
  2204                     {
       
  2205                         itemCommandList->Remove(iSelectCommand);
       
  2206                     }
       
  2207                 }
       
  2208             }
       
  2209         }
       
  2210     }
       
  2211 
       
  2212     TInt numLists = lists.Count();
       
  2213     TInt numSoftKeys = iSoftKeys.Count();
       
  2214     ResetSoftKeysAndCommands(lists);
       
  2215 
       
  2216     // First map one command to every softkey if possible,
       
  2217     // sks must have been ordered correctly, ie right key before
       
  2218     // left key or else left key might get BACK cmd if not other
       
  2219     // cmds are available.
       
  2220     for (TInt i = 0; i < numSoftKeys; i++)
       
  2221     {
       
  2222         for (TInt j = 0; j < numLists && !iSoftKeys[i]->HasAMappedCommand(); j++)
       
  2223         {
       
  2224             if (lists[j])
       
  2225             {
       
  2226                 TInt index = lists[j]->FindCommandForSoftKey(*iSoftKeys[i]);
       
  2227                 if (index != KErrNotFound)
       
  2228                 {
       
  2229                     TInt commandId = lists[j]->CommandOffset() + index;
       
  2230                     CMIDCommand* cmd = lists[j]->At(index).iCommand;
       
  2231                     iSoftKeys[i]->Map(cmd);
       
  2232                     iCba->SetCommandL(iSoftKeys[i]->PositionInCBA(),
       
  2233                                       commandId,
       
  2234                                       lists[j]->ShortLabel(index));
       
  2235                 }
       
  2236             }
       
  2237         }
       
  2238     }
       
  2239 
       
  2240     // Then for the sk that can potentially accept an options menu,
       
  2241     // see if the mapped command must be replaced by the options menu
       
  2242     // when there is at least one command that has not been mapped to any sk.
       
  2243     TBool needToDisplayMenu = EFalse;
       
  2244     for (TInt j = 0; j < numLists && !needToDisplayMenu; j++)
       
  2245     {
       
  2246         if (lists[j])
       
  2247         {
       
  2248             for (TInt i = 0; i < lists[j]->Count() && !needToDisplayMenu; i++)
       
  2249             {
       
  2250                 needToDisplayMenu = !CommandIsMappedToSk(lists[j]->At(i).iCommand);
       
  2251             }
       
  2252         }
       
  2253     }
       
  2254     if (needToDisplayMenu)
       
  2255     {
       
  2256         iSoftKeys[KOptionsMenuCBAIndex]->MappedCommand()->SetMappedToSoftKey(EFalse);
       
  2257         iSoftKeys[KOptionsMenuCBAIndex]->Map(NULL);
       
  2258         iCba->SetCommandL(iSoftKeys[KOptionsMenuCBAIndex]->PositionInCBA(),R_MIDP_SOFTKEY_OPTIONS);
       
  2259     }
       
  2260 
       
  2261     // Setup the MSK command
       
  2262     TInt contextMenuSize = NumCommandsForOkOptionsMenu();
       
  2263     // first reset stored id of command mapped to MSK
       
  2264     iIdOfMSKCommand = KErrNotFound;
       
  2265     if (!iS60SelectionKeyCompatibility)
       
  2266     {
       
  2267         if (iMSKCommand)
       
  2268         {
       
  2269             // There is a explicitly set MSK command -> it takes the precedence and gets MSK
       
  2270             TInt commandId = GetInternalCommandIdFor(iMSKCommand);
       
  2271             if (commandId == KCommandIdNotFound)
       
  2272             {// it must be a built-in command, it is the only command not contained in the command lists
       
  2273                 commandId = KBuiltInMSKCommandId;
       
  2274             }
       
  2275             iCba->SetCommandL(KMSKPositionInCBA, commandId, iMSKCommand->ShortLabel());
       
  2276             iIdOfMSKCommand = commandId;
       
  2277         }
       
  2278         else if (!iMSKCommand && (contextMenuSize == 1))
       
  2279         {
       
  2280             // There is no explicitly set MSK command and just one for the context menu.
       
  2281             // Instead of a menu, put the command to MSK directly.
       
  2282             RPointerArray<CMIDCommand> commands;
       
  2283             GetOkOptionsMenuCommands(commands);
       
  2284             ASSERT(commands.Count() == 1);
       
  2285             CMIDCommand* command = commands[0];
       
  2286             commands.Close();
       
  2287             iCba->SetCommandL(KMSKPositionInCBA,
       
  2288                               GetInternalCommandIdFor(command),
       
  2289                               command->ShortLabel());
       
  2290             iIdOfMSKCommand = GetInternalCommandIdFor(command);
       
  2291         }
       
  2292         else if (!iMSKCommand && (contextMenuSize > 1))
       
  2293         {
       
  2294             // There is no explicitly set MSK command, but there is a
       
  2295             // context sensitive menu -> display MSK command & icon for opening the menu
       
  2296             _LIT(KEmptyLabel, ""); // the label is never shown in MSK, but an icon is
       
  2297             iCba->SetCommandL(KMSKPositionInCBA, EAknSoftkeyContextOptions, KEmptyLabel);
       
  2298             iIdOfMSKCommand = EAknSoftkeyContextOptions;
       
  2299         }
       
  2300         else if (!iMSKCommand && (contextMenuSize == 0))
       
  2301         {
       
  2302             // There is no explicitly set MSK command and no OK or ITEM command defined
       
  2303             // Try to map SCREEN or HELP command with the highest priority
       
  2304             TInt screenOrHelpCmdIndex = GetHighestPriorityScreenOrHelpCommand();
       
  2305             if (screenOrHelpCmdIndex != KErrNotFound)
       
  2306             {
       
  2307                 CMIDCommand *command = iCommandList->At(screenOrHelpCmdIndex).iCommand;
       
  2308                 if (command)
       
  2309                 {
       
  2310                     // At least one SCREEN or HELP command is set, map to MSK
       
  2311                     iCba->SetCommandL(KMSKPositionInCBA,
       
  2312                                       GetInternalCommandIdFor(command),
       
  2313                                       command->ShortLabel());
       
  2314                     iIdOfMSKCommand = GetInternalCommandIdFor(command);
       
  2315                 }
       
  2316             }
       
  2317         }
       
  2318     }
       
  2319 
       
  2320     CleanupStack::PopAndDestroy(&lists);
       
  2321     iCba->DrawDeferred();
       
  2322 }
       
  2323 
       
  2324 // ---------------------------------------------------------------------------
       
  2325 // Returns an internal command id for a command. Assumes that
       
  2326 // command is not NULL.
       
  2327 // ---------------------------------------------------------------------------
       
  2328 TInt CMIDDisplayable::GetInternalCommandIdFor(CMIDCommand* aCommand) const
       
  2329 {
       
  2330     ASSERT(aCommand);
       
  2331     // See if command is part on command list, if the list exists
       
  2332     if (iCommandList)
       
  2333     {
       
  2334         // To identify the command, first find it from the list, this is based on
       
  2335         // command ids. However, commands in iCommandList and iItemCommandList may
       
  2336         // have same ids (because of Java side implementation) and thus we compare
       
  2337         // the pointer of the command in the second phase.
       
  2338         TInt index = iCommandList->FindCommandIndex(aCommand);
       
  2339         if (index != KErrNotFound && iCommandList->At(index).iCommand == aCommand)
       
  2340         {
       
  2341             return iCommandList->CommandOffset() + index;
       
  2342         }
       
  2343     }
       
  2344     // See if command is part of item command list, if the list exists
       
  2345     if (iItemCommandList)
       
  2346     {
       
  2347         // To identify the command, first find it from the list, this is based on
       
  2348         // command ids. However, commands in iCommandList and iItemCommandList may
       
  2349         // have same ids (because of Java side implementation) and thus we compare
       
  2350         // the pointer of the command in the second phase.
       
  2351         TInt index = iItemCommandList->FindCommandIndex(aCommand);
       
  2352         if (index != KErrNotFound && iItemCommandList->At(index).iCommand == aCommand)
       
  2353         {
       
  2354             return iItemCommandList->CommandOffset() + index;
       
  2355         }
       
  2356     }
       
  2357     // Did not find the requested command
       
  2358     return KCommandIdNotFound;
       
  2359 }
       
  2360 
       
  2361 // ---------------------------------------------------------------------------
       
  2362 // Return true if the command is mapped to any softkey. The same java side command seem
       
  2363 // to exist on more than one list so we use the command Id to make sure the command is not
       
  2364 // a repeatition of an existing command.
       
  2365 // ---------------------------------------------------------------------------
       
  2366 TBool CMIDDisplayable::CommandIsMappedToSk(const CMIDCommand* aCommand) const
       
  2367 {
       
  2368     DEBUG("+ CMIDDisplayable::CommandIsMappedToSk");
       
  2369 
       
  2370     TBool commandIsMapped = aCommand->IsMappedToSoftKey();
       
  2371     for (TInt k = 0; k < iSoftKeys.Count() && !commandIsMapped; k++)
       
  2372     {
       
  2373         const CMIDCommand* skCmd = iSoftKeys[k]->MappedCommand();
       
  2374         if (skCmd && skCmd == aCommand && skCmd->Id() == aCommand->Id())
       
  2375         {
       
  2376             commandIsMapped = ETrue;
       
  2377         }
       
  2378     }
       
  2379 
       
  2380     DEBUG("- CMIDDisplayable::CommandIsMappedToSk");
       
  2381     return commandIsMapped;
       
  2382 }
       
  2383 
       
  2384 // ---------------------------------------------------------------------------
       
  2385 // See how many commands eligible for the ok-optins menu we have. If we
       
  2386 // have only one command then post java event directly. Otherwise show
       
  2387 // ok-options menu. In these two cases return ETrue. If zero or negative
       
  2388 // commands do nothing and return EFalse. See also NumCommandsForOkOptionsMenu()
       
  2389 // and CMIDMenuHandler::ShowMenuL().
       
  2390 // ---------------------------------------------------------------------------
       
  2391 TBool CMIDDisplayable::ShowOkOptionsMenuL()
       
  2392 {
       
  2393     TInt numCommands = NumCommandsForOkOptionsMenu();
       
  2394 
       
  2395     if (numCommands == 1)
       
  2396     {
       
  2397         TCommandEntry cmd;
       
  2398         cmd.iCommand = NULL;
       
  2399 
       
  2400         if (iItemCommandList && iItemCommandList->Count() > 0)
       
  2401         {// there can only be one so pick the first one
       
  2402             cmd = iItemCommandList->At(0);
       
  2403 
       
  2404             if (cmd.iCommand->IsMappedToSoftKey())
       
  2405             {
       
  2406                 HandleItemCommandL(cmd);
       
  2407                 return ETrue;
       
  2408             }
       
  2409         }
       
  2410         else if (iCommandList && iCommandList->Count() > 0)
       
  2411         {
       
  2412             TInt index = iCommandList->HighestPriorityCommand(MMIDCommand::EOk);
       
  2413             if (index == KErrNotFound)
       
  2414             {// there can only be one so if the other one was KErrNotFound, this must be it
       
  2415                 index = iCommandList->HighestPriorityCommand(MMIDCommand::EItem);
       
  2416             }
       
  2417             cmd = iCommandList->At(index);
       
  2418 
       
  2419             if (cmd.iCommand->IsMappedToSoftKey())
       
  2420             {
       
  2421                 HandleStandardCommandL(cmd);
       
  2422                 return ETrue;
       
  2423             }
       
  2424         }
       
  2425     }
       
  2426 
       
  2427     if (numCommands > 0)
       
  2428     {
       
  2429         iMenuHandler->ShowMenuL(CMIDMenuHandler::EOkMenu);
       
  2430         return ETrue;
       
  2431     }
       
  2432 
       
  2433     return EFalse;
       
  2434 }
       
  2435 
       
  2436 
       
  2437 // ---------------------------------------------------------------------------
       
  2438 // Return the number of commands that can be displayed in the ok-options menu.
       
  2439 // If form has set any item commands in iItemCommandList this means that there is
       
  2440 // a form item focused and the commands for this item should be displayed in
       
  2441 // the ok-options menu along with form OK and ITEM commands.
       
  2442 //
       
  2443 // If we have no item cmds we analyse the standard command list and
       
  2444 // select only the commands of type OK or ITEM.
       
  2445 //
       
  2446 // TextBox/TextField device-provided commands:
       
  2447 // - "Fetch number"
       
  2448 // - "Call"
       
  2449 // - "Fetch e-mail address"
       
  2450 // are exception. Those are visible ONLY in Options menu so here they are
       
  2451 // removed from context menu commands count.
       
  2452 // ---------------------------------------------------------------------------
       
  2453 TInt CMIDDisplayable::NumCommandsForOkOptionsMenu() const
       
  2454 {
       
  2455     TInt ret = 0;
       
  2456 
       
  2457     if (iItemCommandList && iItemCommandList->Count() > 0)
       
  2458     {
       
  2459         TInt numItemCommands = iItemCommandList->Count();
       
  2460         for (TInt i = 0; i < numItemCommands; i++)
       
  2461         {
       
  2462             const CMIDCommand& command = *(iItemCommandList->At(i).iCommand);
       
  2463 
       
  2464             if ((command.Id() != CMIDEdwinUtils::EMenuCommandFetchPhoneNumber) &&
       
  2465                     (command.Id() != CMIDEdwinUtils::EMenuCommandFetchEmailAddress) &&
       
  2466                     (command.Id() != CMIDEdwinUtils::EMenuCommandCreatePhoneCall))
       
  2467             {
       
  2468                 ret++;
       
  2469             }
       
  2470         }
       
  2471     }
       
  2472 
       
  2473     // Add always OK and ITEM commands from form
       
  2474     TInt numCommands = iCommandList->Count();
       
  2475     for (TInt i = 0; i < numCommands; i++)
       
  2476     {
       
  2477         const CMIDCommand& command = *(iCommandList->At(i).iCommand);
       
  2478 
       
  2479         if (((command.CommandType() == MMIDCommand::EOk) ||
       
  2480                 (command.CommandType() == MMIDCommand::EItem)) &&
       
  2481                 (command.Id() != CMIDEdwinUtils::EMenuCommandFetchPhoneNumber) &&
       
  2482                 (command.Id() != CMIDEdwinUtils::EMenuCommandFetchEmailAddress) &&
       
  2483                 (command.Id() != CMIDEdwinUtils::EMenuCommandCreatePhoneCall))
       
  2484         {
       
  2485             TBool selectCommand = (&command == iSelectCommand);
       
  2486             if (selectCommand && !iSelectCommandEnabled)
       
  2487             {
       
  2488                 continue;
       
  2489             }
       
  2490             ret++;
       
  2491         }
       
  2492     }
       
  2493 
       
  2494     return ret;
       
  2495 }
       
  2496 
       
  2497 // ---------------------------------------------------------------------------
       
  2498 // Returns a pointer to the command in the iCommandList with the specified
       
  2499 // ID number. If such command is not found, returns NULL.
       
  2500 // ---------------------------------------------------------------------------
       
  2501 CMIDCommand* CMIDDisplayable::FindCommandWithId(TInt aCommandId) const
       
  2502 {
       
  2503     TInt numCommands = iCommandList->Count();
       
  2504     for (TInt i = 0; i < numCommands; i++)
       
  2505     {
       
  2506         CMIDCommand* command = iCommandList->At(i).iCommand;
       
  2507         if (command->Id() == aCommandId)
       
  2508             return command;
       
  2509     }
       
  2510     return NULL;
       
  2511 }
       
  2512 
       
  2513 // ---------------------------------------------------------------------------
       
  2514 // Retrieves the commands to be placed in the context (ok-options) menu.
       
  2515 // The commands are returned in the array, provided by the calling code.
       
  2516 // This function will empty the commands array before filling it.
       
  2517 //
       
  2518 // Only commands of type OK and ITEM are visible in context menu.
       
  2519 // TextBox/TextField device-provided commands:
       
  2520 // - "Fetch number"
       
  2521 // - "Call"
       
  2522 // - "Fetch e-mail address"
       
  2523 // are exception. Those are visible ONLY in Options menu so here
       
  2524 // they are not added to context menu commands array.
       
  2525 //
       
  2526 // If there are item commands, there are placed first. Form commands of ITEM
       
  2527 // and OK type are then included always.
       
  2528 // ---------------------------------------------------------------------------
       
  2529 void CMIDDisplayable::GetOkOptionsMenuCommands(RPointerArray<CMIDCommand>& aCommands) const
       
  2530 {
       
  2531     aCommands.Reset();
       
  2532     if (iItemCommandList && iItemCommandList->Count() > 0)
       
  2533     {
       
  2534         for (TInt i = 0; i < iItemCommandList->Count(); i++)
       
  2535         {
       
  2536             const CMIDCommand* command = iItemCommandList->At(i).iCommand;
       
  2537             if ((command->Id() != CMIDEdwinUtils::EMenuCommandFetchPhoneNumber) &&
       
  2538                     (command->Id() != CMIDEdwinUtils::EMenuCommandFetchEmailAddress) &&
       
  2539                     (command->Id() != CMIDEdwinUtils::EMenuCommandCreatePhoneCall))
       
  2540             {
       
  2541                 aCommands.Append(command);
       
  2542             }
       
  2543         }
       
  2544     }
       
  2545 
       
  2546     // add Form commands always
       
  2547     TInt numCommands = iCommandList->Count();
       
  2548     for (TInt i = 0; i < numCommands; i++)
       
  2549     {
       
  2550         const CMIDCommand* command = iCommandList->At(i).iCommand;
       
  2551         if (((command->CommandType() == MMIDCommand::EOk) ||
       
  2552                 (command->CommandType() == MMIDCommand::EItem)) &&
       
  2553                 (command->Id() != CMIDEdwinUtils::EMenuCommandFetchPhoneNumber) &&
       
  2554                 (command->Id() != CMIDEdwinUtils::EMenuCommandFetchEmailAddress) &&
       
  2555                 (command->Id() != CMIDEdwinUtils::EMenuCommandCreatePhoneCall))
       
  2556         {
       
  2557             if (!iSelectCommandEnabled && command == iSelectCommand)
       
  2558             {
       
  2559                 continue;
       
  2560             }
       
  2561             aCommands.Append(command);
       
  2562         }
       
  2563     }
       
  2564 }
       
  2565 
       
  2566 /**
       
  2567  * Retrieves index of the highest priority SCREEN command
       
  2568  * where there is no SCREEN command it retreives index
       
  2569  * of the highest priority HELP command number.
       
  2570  *
       
  2571  * When there is no such command type, it returns KErrNotFound
       
  2572  **/
       
  2573 TInt CMIDDisplayable::GetHighestPriorityScreenOrHelpCommand() const
       
  2574 {
       
  2575     TInt cmdNum = iCommandList->HighestPriorityCommand(MMIDCommand::EScreen);
       
  2576     if (cmdNum == KErrNotFound)
       
  2577         cmdNum = iCommandList->HighestPriorityCommand(MMIDCommand::EHelp);
       
  2578     return cmdNum;
       
  2579 }
       
  2580 
       
  2581 
       
  2582 // ---------------------------------------------------------------------------
       
  2583 // Removes the title, effectively showing the midlet name as the title.
       
  2584 // Used by popup-style TextBox which maintains its own title.
       
  2585 // ---------------------------------------------------------------------------
       
  2586 void CMIDDisplayable::ClearTitleL()
       
  2587 {
       
  2588     delete iTitle;
       
  2589     iTitle = NULL;
       
  2590     if (this->iActive)
       
  2591     {
       
  2592         this->ShowTitleL();
       
  2593     }
       
  2594     iHasTitle = EFalse;
       
  2595 }
       
  2596 
       
  2597 // ---------------------------------------------------------------------------
       
  2598 // Replaces the CEikButtonGroupContainer.
       
  2599 // ---------------------------------------------------------------------------
       
  2600 void CMIDDisplayable::SetCba(CEikButtonGroupContainer* aCba)
       
  2601 {
       
  2602     DEBUG("+ CMIDDisplayable::SetCba");
       
  2603 
       
  2604     ASSERT(aCba);
       
  2605     iCba = aCba;
       
  2606     iCba->DrawDeferred();
       
  2607 
       
  2608     DEBUG("- CMIDDisplayable::SetCba");
       
  2609 }
       
  2610 
       
  2611 // ---------------------------------------------------------------------------
       
  2612 // Reset the status of all sks and commands so that no command is mapped to any sk
       
  2613 // ---------------------------------------------------------------------------
       
  2614 void CMIDDisplayable::ResetSoftKeysAndCommands(const RArray<CMIDCommandList*>& aLists)
       
  2615 {
       
  2616     TInt numSoftKeys = iSoftKeys.Count();
       
  2617     for (TInt i = 0; i < numSoftKeys; i++)
       
  2618     {
       
  2619         iSoftKeys[i]->Map(NULL);
       
  2620     }
       
  2621 
       
  2622     TInt numLists = aLists.Count();
       
  2623     for (TInt j = 0; j < numLists; j++)
       
  2624     {
       
  2625         if (aLists[j])
       
  2626         {
       
  2627             aLists[j]->UnMapCommands();
       
  2628         }
       
  2629     }
       
  2630 }
       
  2631 
       
  2632 // ---------------------------------------------------------------------------
       
  2633 //
       
  2634 // ---------------------------------------------------------------------------
       
  2635 TBool CMIDDisplayable::TryDetectLongTapL(const TPointerEvent& aPointerEvent)
       
  2636 {
       
  2637     //Following code disables the cancelling of long tap to be determined as a normal tap.
       
  2638     //Cancelling of long tap (up event during long tap animation) shouldn't do anything
       
  2639     //else than cancel the animation.
       
  2640     if (iLongTapDetector->IsAnimationRunning() &&
       
  2641             aPointerEvent.iType == TPointerEvent::EButton1Up)
       
  2642     {
       
  2643         iLongTapDetector->PointerEventL(aPointerEvent);
       
  2644         return ETrue;
       
  2645     }
       
  2646     // If there is a context menu available, forward events to long tap detector
       
  2647 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  2648     if (NumCommandsForOkOptionsMenu() > 0)
       
  2649 #else
       
  2650     if (NumCommandsForOkOptionsMenu() > 1)
       
  2651 #endif // RD_JAVA_S60_RELEASE_9_2        
       
  2652     {
       
  2653         iLongTapDetector->PointerEventL(aPointerEvent);
       
  2654     }
       
  2655     if (aPointerEvent.iType == TPointerEvent::EButton1Up && iLongTapDetected)
       
  2656     {
       
  2657         iLongTapDetected = EFalse;
       
  2658         return ETrue;
       
  2659     }
       
  2660     else
       
  2661     {
       
  2662         return EFalse;
       
  2663     }
       
  2664 }
       
  2665 
       
  2666 // ---------------------------------------------------------------------------
       
  2667 //
       
  2668 // ---------------------------------------------------------------------------
       
  2669 void CMIDDisplayable::HandleLongTapEventL(const TPoint& /*aPenEventLocation*/,
       
  2670         const TPoint& aPenEventScreenLocation)
       
  2671 {
       
  2672     // Long tap was detected -> show context menu. However, make sure that the
       
  2673     // context sensitive menu is still there; it could be that the menu items
       
  2674     // have been changed while waiting for the long tap event
       
  2675     RArray<CEikMenuPaneItem::SData> menuItems; // the list of menu items
       
  2676     menuItems.Reset();
       
  2677 
       
  2678     if (iItemCommandList && iItemCommandList->Count() > 0)
       
  2679     {
       
  2680 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  2681         PopulateMenuItemsWithListL(CMIDMenuHandler::EPopUpMenu, menuItems, iItemCommandList, EFalse);
       
  2682 #else
       
  2683         PopulateMenuItemsWithListL(CMIDMenuHandler::EOkMenu, menuItems, iItemCommandList, EFalse);
       
  2684 #endif // RD_JAVA_S60_RELEASE_9_2        
       
  2685     }
       
  2686 
       
  2687     // Add form commands always
       
  2688 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  2689     PopulateMenuItemsWithListL(CMIDMenuHandler::EPopUpMenu, menuItems, iCommandList, EFalse);
       
  2690 #else
       
  2691     PopulateMenuItemsWithListL(CMIDMenuHandler::EOkMenu, menuItems, iCommandList, EFalse);
       
  2692 #endif // RD_JAVA_S60_RELEASE_9_2    
       
  2693 #ifdef RD_JAVA_S60_RELEASE_9_2
       
  2694     if (menuItems.Count() > 0)
       
  2695 #else
       
  2696     if (menuItems.Count() > 1)
       
  2697 #endif // RD_JAVA_S60_RELEASE_9_2        
       
  2698     {
       
  2699         // recreate stylus popup menu because it does not have method
       
  2700         // for clearing the menu items
       
  2701         delete iStylusPopupMenu;
       
  2702         iStylusPopupMenu = NULL;
       
  2703         iStylusPopupMenu = CAknStylusPopUpMenu::NewL(this, aPenEventScreenLocation);
       
  2704         for (TInt i = 0; i < menuItems.Count(); i++)
       
  2705         {
       
  2706             iStylusPopupMenu->AddMenuItemL(menuItems[i].iText, menuItems[i].iCommandId);
       
  2707         }
       
  2708 
       
  2709         iStylusPopupMenu->SetPosition(aPenEventScreenLocation);
       
  2710         iStylusPopupMenu->ShowMenu();
       
  2711     }
       
  2712 
       
  2713     iLongTapDetected = ETrue;
       
  2714 }
       
  2715 
       
  2716 // ---------------------------------------------------------------------------
       
  2717 //
       
  2718 // ---------------------------------------------------------------------------
       
  2719 MAknsControlContext* CMIDDisplayable::BackGroundControlContext()
       
  2720 {
       
  2721     return iBackGroundControlContext;
       
  2722 }
       
  2723 
       
  2724 // ---------------------------------------------------------------------------
       
  2725 //
       
  2726 // ---------------------------------------------------------------------------
       
  2727 CMIDCommandList* CMIDDisplayable::MainCommandList() const
       
  2728 {
       
  2729     return iCommandList;
       
  2730 }
       
  2731 
       
  2732 // ---------------------------------------------------------------------------
       
  2733 //
       
  2734 // ---------------------------------------------------------------------------
       
  2735 MMIDComponent* CMIDDisplayable::Component() const
       
  2736 {
       
  2737     return iContent;
       
  2738 }
       
  2739 
       
  2740 // ---------------------------------------------------------------------------
       
  2741 //
       
  2742 // ---------------------------------------------------------------------------
       
  2743 TInt CMIDDisplayable::CommandCount()
       
  2744 {
       
  2745     return iCommandList->Count();
       
  2746 }
       
  2747 
       
  2748 // ---------------------------------------------------------------------------
       
  2749 // Returns a boolean indicating whether a non-null title has been set by
       
  2750 // calling the Displayable's SetTitle method.
       
  2751 // ---------------------------------------------------------------------------
       
  2752 TBool CMIDDisplayable::HasTitle() const
       
  2753 {
       
  2754     return iHasTitle;
       
  2755 }
       
  2756 
       
  2757 // ---------------------------------------------------------------------------
       
  2758 //
       
  2759 // ---------------------------------------------------------------------------
       
  2760 CMIDMenuHandler* CMIDDisplayable::MenuHandler() const
       
  2761 {
       
  2762     return iMenuHandler;
       
  2763 }
       
  2764 
       
  2765 // ---------------------------------------------------------------------------
       
  2766 //
       
  2767 // ---------------------------------------------------------------------------
       
  2768 TBool CMIDDisplayable::IsActive() const
       
  2769 {
       
  2770     return iActive;
       
  2771 }
       
  2772 
       
  2773 // ---------------------------------------------------------------------------
       
  2774 //
       
  2775 // ---------------------------------------------------------------------------
       
  2776 TTypeUid::Ptr CMIDDisplayable::MopSupplyObject(TTypeUid aId)
       
  2777 {
       
  2778     if (aId.iUid == MAknsControlContext::ETypeId && iBackGroundControlContext)
       
  2779     {
       
  2780         return MAknsControlContext::SupplyMopObject(aId, iBackGroundControlContext);
       
  2781     }
       
  2782     ASSERT(iMenuHandler);
       
  2783     return SupplyMopObject(aId, iMenuHandler->Cba(), iMenuHandler->MenuBar());
       
  2784 }
       
  2785 
       
  2786 // ---------------------------------------------------------------------------
       
  2787 //
       
  2788 // ---------------------------------------------------------------------------
       
  2789 void CMIDDisplayable::NotifyContentDestroyed()
       
  2790 {
       
  2791     iContent = NULL;
       
  2792     iContentControl = NULL;
       
  2793 
       
  2794     iEnv.RemoveObserver(*this);
       
  2795 }
       
  2796 
       
  2797 /** Check virtual keyboard status. Only for touchscreen.
       
  2798   *  Returns a boolean variable:
       
  2799   *  ETrue  - VKB is opened,
       
  2800   *  EFalse - VKB is hidden.
       
  2801  **/
       
  2802 #ifdef RD_TACTILE_FEEDBACK
       
  2803 TBool CMIDDisplayable::IsVKBOnScreen()
       
  2804 {
       
  2805     TBool vkbOpen = EFalse;
       
  2806 
       
  2807     if (!iPenInputServerConnected && AknLayoutUtils::PenEnabled())
       
  2808     {
       
  2809         TInt err = iPenInputServer.Connect();
       
  2810         iPenInputServerConnected = (err == KErrNone);
       
  2811     }
       
  2812 
       
  2813     if (iPenInputServerConnected)
       
  2814     {
       
  2815         if (iPenInputServer.IsVisible())
       
  2816         {
       
  2817             vkbOpen = ETrue;
       
  2818         }
       
  2819     }
       
  2820 
       
  2821     return vkbOpen;
       
  2822 }
       
  2823 #endif //RD_TACTILE_FEEDBACK
       
  2824 
       
  2825 
       
  2826 #ifdef RD_SCALABLE_UI_V2
       
  2827 TUint CMIDDisplayable::OnScreenKeypadL()
       
  2828 {
       
  2829     DEBUG("+ CMIDDisplayable::OnScreenKeypadL");
       
  2830 
       
  2831     if (RProcess().SecureId().iId != 0x102033E6)
       
  2832     {
       
  2833         // For standalone type apps we don't show keypad.
       
  2834         return EOnScreenKeypadValueNo;
       
  2835     }
       
  2836     TUint onScreenKeypadValue = EOnScreenKeypadValueUndefined;
       
  2837 
       
  2838     std::auto_ptr<java::storage::JavaStorage> js(java::storage::JavaStorage::createInstance());
       
  2839     java::storage::JavaStorageApplicationEntry_t entries;
       
  2840     try
       
  2841     {
       
  2842         js->open();
       
  2843         java::util::Uid uid;
       
  2844         TUidToUid(iEnv.MidletSuiteUid(), uid);
       
  2845         js->read(java::storage::MIDP_PACKAGE_TABLE, uid, entries);
       
  2846         js->close();
       
  2847     }
       
  2848     catch (java::storage::JavaStorageException& ex)
       
  2849     {
       
  2850         DEBUG_INT("CMIDCanvas::IsNetworkIndicatorEnabledL: JavaStorage error: \
       
  2851             reading MIDP_PACKAGE_TABLE failed, error code = %D", ex.mStatus);
       
  2852     }
       
  2853     java::storage::JavaStorageEntry attribute;
       
  2854     attribute.setEntry(java::storage::ON_SCREEN_KEYPAD, L"");
       
  2855     java::storage::JavaStorageApplicationEntry_t::const_iterator findIterator = entries.find(attribute);
       
  2856     std::wstring res = L"";
       
  2857     if (findIterator != entries.end())
       
  2858     {
       
  2859         res = (*findIterator).entryValue();
       
  2860     }
       
  2861     entries.clear();
       
  2862 
       
  2863     if (res == L"0")
       
  2864     {
       
  2865         onScreenKeypadValue = EOnScreenKeypadValueNo;
       
  2866     }
       
  2867     else if (res == L"1")
       
  2868     {
       
  2869         onScreenKeypadValue = EOnScreenKeypadValueGameActions;
       
  2870     }
       
  2871     else if (res == L"2")
       
  2872     {
       
  2873         onScreenKeypadValue = EOnScreenKeypadValueNavigationKeys;
       
  2874     }
       
  2875 
       
  2876     DEBUG("- CMIDDisplayable::OnScreenKeypadL");
       
  2877 
       
  2878     return onScreenKeypadValue;
       
  2879 }
       
  2880 #endif // RD_SCALABLE_UI_V2
       
  2881 
       
  2882 // ---------------------------------------------------------------------------
       
  2883 //
       
  2884 // ---------------------------------------------------------------------------
       
  2885 void CMIDDisplayable::SetEmphasis(CCoeControl* /*aMenuControl*/,TBool /*aEmphasis*/)
       
  2886 {
       
  2887 
       
  2888 }
       
  2889 
       
  2890 // ---------------------------------------------------------------------------
       
  2891 // Adds a rectangle to be excluded from redrawing (for DSA)
       
  2892 // ---------------------------------------------------------------------------
       
  2893 //
       
  2894 void CMIDDisplayable::AddDirectContentArea(const TRect& aRect)
       
  2895 {
       
  2896     TDirectContentsRect rect(aRect);
       
  2897     TInt index = iDirectContentsRects.Find(
       
  2898                      rect, TIdentityRelation< TDirectContentsRect >(CMIDDisplayable::MatchDirectContentsRects));
       
  2899     if (index == KErrNotFound)
       
  2900     {
       
  2901         iDirectContentsRects.Append(rect);
       
  2902         UpdateDirectContentsRegion();
       
  2903     }
       
  2904     else
       
  2905     {
       
  2906         iDirectContentsRects[ index ].iRefCount++;
       
  2907     }
       
  2908 }
       
  2909 
       
  2910 // ---------------------------------------------------------------------------
       
  2911 // Removes a rectangle to be excluded from redrawing (for DSA)
       
  2912 // ---------------------------------------------------------------------------
       
  2913 //
       
  2914 void CMIDDisplayable::RemoveDirectContentArea(const TRect& aRect)
       
  2915 {
       
  2916     TDirectContentsRect rect(aRect);
       
  2917     TInt index = iDirectContentsRects.Find(
       
  2918                      rect, TIdentityRelation< TDirectContentsRect >(CMIDDisplayable::MatchDirectContentsRects));
       
  2919     if (index != KErrNotFound)
       
  2920     {
       
  2921         iDirectContentsRects[ index ].iRefCount--;
       
  2922         if (iDirectContentsRects[ index ].iRefCount <= 0)
       
  2923         {
       
  2924             iDirectContentsRects.Remove(index);
       
  2925             UpdateDirectContentsRegion();
       
  2926         }
       
  2927     }
       
  2928 }
       
  2929 
       
  2930 
       
  2931 // ---------------------------------------------------------------------------
       
  2932 // Matches two direct content rectangles and returns the result
       
  2933 // ---------------------------------------------------------------------------
       
  2934 //
       
  2935 TBool CMIDDisplayable::MatchDirectContentsRects
       
  2936 (
       
  2937     const TDirectContentsRect& aLhs,
       
  2938     const TDirectContentsRect& aRhs
       
  2939 )
       
  2940 {
       
  2941     return (aLhs.iRect == aRhs.iRect);
       
  2942 }
       
  2943 
       
  2944 // ---------------------------------------------------------------------------
       
  2945 // Update the direct content regions
       
  2946 // This should be called just after addition or removal of dc rectangle
       
  2947 // ---------------------------------------------------------------------------
       
  2948 //
       
  2949 void CMIDDisplayable::UpdateDirectContentsRegion()
       
  2950 {
       
  2951     iDirectContentsRegion.Clear();
       
  2952     TInt count = iDirectContentsRects.Count();
       
  2953     for (int index = 0; index < count; index++)
       
  2954     {
       
  2955         iDirectContentsRegion.AddRect(iDirectContentsRects[ index ].iRect);
       
  2956     }
       
  2957 }
       
  2958 
       
  2959 
       
  2960 TBool CMIDDisplayable::NoDirectContentAreaDefined()
       
  2961 {
       
  2962     return iDirectContentsRegion.IsEmpty();
       
  2963 }
       
  2964 
       
  2965 void CMIDDisplayable::SetPopupTextBox(TBool aPopup)
       
  2966 {
       
  2967     iIsPopupTextBox = aPopup;
       
  2968 }
       
  2969 
       
  2970 TBool CMIDDisplayable::IsPopupTextBox()
       
  2971 {
       
  2972     return iIsPopupTextBox;
       
  2973 }
       
  2974 
       
  2975 // ---------------------------------------------------------------------------
       
  2976 // Gets the location and anchor for all the softkey buttons
       
  2977 // for fullscreen canvas and stores it for later usage.
       
  2978 // The data have to marked as invalid in iFullscreenCanvasLabelCacheIsValid
       
  2979 // if any resolution / skin change is proceeding.
       
  2980 // ---------------------------------------------------------------------------
       
  2981 //
       
  2982 void CMIDDisplayable::RenewFullscreenCanvasLabelCacheL()
       
  2983 {
       
  2984     DEBUG("+ CMIDDisplayable::RenewFullscreenCanvasLabelCacheL");
       
  2985 
       
  2986     if ((iCba)   &&
       
  2987             (!iFullscreenCanvasLabelCacheIsValid) &&
       
  2988             (iCommandList))
       
  2989     {
       
  2990         TPoint move(0, 0);
       
  2991         if (iUseOnScreenKeypad)
       
  2992         {
       
  2993             // SK location have to be moved when OnScreenKeypad is active
       
  2994             TSize diff(iDisplayableRect.Size() -
       
  2995                        iAppUi->ApplicationRect().Size());
       
  2996             move = diff.AsPoint();
       
  2997         }
       
  2998 
       
  2999         for (TInt softKeyId = 0; softKeyId < KSoftKeyLabelPropertyNumberOfSoftKeys; softKeyId++)
       
  3000         {
       
  3001             iFullscreenCanvasLabelCache[softKeyId].iIsOn = EFalse;
       
  3002             TBool SKVisibility = true;
       
  3003 
       
  3004             // Check if the MSK is used in Avkon
       
  3005             if (softKeyId == KSoftKeyLabelPropertyPositionsMSKIndex)
       
  3006             {
       
  3007                 TBool MSKEnabledInPlatform;
       
  3008                 CRepository* cenRep = NULL;
       
  3009                 TRAPD(err, cenRep = CRepository::NewL(KCRUidAvkon));
       
  3010                 if (!err)
       
  3011                 {
       
  3012                     err = cenRep->Get(KAknMiddleSoftkeyEnabled, MSKEnabledInPlatform);
       
  3013                     delete cenRep;
       
  3014                 }
       
  3015 
       
  3016                 // Check the cases, in which the MSK is off
       
  3017                 if (!AknLayoutUtils::MSKEnabled() || !MSKEnabledInPlatform ||
       
  3018                         !Layout_Meta_Data::IsMSKEnabled() ||
       
  3019                         Layout_Meta_Data::IsLandscapeOrientation())
       
  3020                 {
       
  3021                     SKVisibility = false;
       
  3022                 }
       
  3023 
       
  3024             }
       
  3025 
       
  3026             if (SKVisibility)
       
  3027             {
       
  3028                 iCba->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY);
       
  3029                 TInt softKeyCbaPosition = KSoftKeyLabelPropertyPositionsInCBA[ softKeyId ];
       
  3030                 iCba->SetCommandL(softKeyCbaPosition, R_MIDP_SOFTKEY_OPTIONS);
       
  3031                 TInt cmdId = EAknSoftkeyOptions;
       
  3032                 TInt position = iCba->PositionById(cmdId);
       
  3033                 if ((position == softKeyCbaPosition) && iCba->IsCommandVisible(cmdId))
       
  3034                 {
       
  3035                     CEikCommandButton *cmdButton = (CEikCommandButton*)iCba->ControlOrNull(cmdId);
       
  3036                     if (cmdButton && cmdButton->IsVisible()  && !iCba->IsCommandDimmed(cmdId))
       
  3037                     {
       
  3038                         CEikLabel *label = (CEikLabel*)cmdButton->ComponentControl(0);
       
  3039                         if (label && label->IsVisible())
       
  3040                         {
       
  3041                             iFullscreenCanvasLabelCache[softKeyId].iPosition
       
  3042                             = label->PositionRelativeToScreen() + move;
       
  3043 
       
  3044                             iFullscreenCanvasLabelCache[softKeyId].iSize = label->Size();
       
  3045                             TGulAlignment align = label->iAlignment;
       
  3046                             TGulHAlignment hAlign = align.HAlignment();
       
  3047                             switch (hAlign)
       
  3048                             {
       
  3049                             case EHLeft:
       
  3050                                 iFullscreenCanvasLabelCache[softKeyId].iAnchor = TSoftkeyLabel::EJavaLeft;
       
  3051                                 break;
       
  3052                             case EHCenter:
       
  3053                                 iFullscreenCanvasLabelCache[softKeyId].iAnchor = TSoftkeyLabel::EJavaHCenter;
       
  3054                                 break;
       
  3055                             case EHRight:
       
  3056                                 iFullscreenCanvasLabelCache[softKeyId].iAnchor = TSoftkeyLabel::EJavaRight;
       
  3057                                 break;
       
  3058                             }
       
  3059                             TGulVAlignment vAlign = align.VAlignment();
       
  3060                             switch (vAlign)
       
  3061                             {
       
  3062                             case EVTop:
       
  3063                                 iFullscreenCanvasLabelCache[softKeyId].iAnchor |= TSoftkeyLabel::EJavaTop;
       
  3064                                 break;
       
  3065                             case EVCenter:
       
  3066                                 iFullscreenCanvasLabelCache[softKeyId].iAnchor |= TSoftkeyLabel::EJavaVCenter;
       
  3067                                 break;
       
  3068                             case EVBottom:
       
  3069                                 iFullscreenCanvasLabelCache[softKeyId].iAnchor |= TSoftkeyLabel::EJavaBottom;
       
  3070                                 break;
       
  3071                             }
       
  3072                             iFullscreenCanvasLabelCache[softKeyId].iIsOn = ETrue;
       
  3073                         }
       
  3074                     }
       
  3075                 }
       
  3076             }
       
  3077         }
       
  3078     }
       
  3079 
       
  3080     iFullscreenCanvasLabelCacheIsValid = ETrue;
       
  3081 
       
  3082     DEBUG("- CMIDDisplayable::RenewFullscreenCanvasLabelCacheL");
       
  3083 }
       
  3084 
       
  3085 #ifdef RD_JAVA_NGA_ENABLED
       
  3086 void CMIDDisplayable::HandleCanvasForeground(TBool aForeground)
       
  3087 {
       
  3088     if (iContent && iContentControl &&
       
  3089             (iContent->Type() == MMIDComponent::ECanvas ||
       
  3090              iContent->Type() == MMIDComponent::EGameCanvas))
       
  3091     {
       
  3092         CMIDCanvas* canvas = static_cast<CMIDCanvas*>(iContentControl);
       
  3093         canvas->HandleForeground(aForeground);
       
  3094     }
       
  3095 }
       
  3096 #endif // RD_JAVA_NGA_ENABLED
       
  3097 
       
  3098 void CMIDDisplayable::HandleApplicationBackground()
       
  3099 {
       
  3100     // If iCanvasKeypad exists, it notifies On-Screen Keypad
       
  3101     // about current application focus lost.
       
  3102     if (iCanvasKeypad)
       
  3103     {
       
  3104         iCanvasKeypad->HandleApplicationBackground();
       
  3105     }
       
  3106 
       
  3107 #ifdef RD_JAVA_NGA_ENABLED
       
  3108     HandleCanvasForeground(EFalse);
       
  3109 #endif // RD_JAVA_NGA_ENABLED    
       
  3110 }
       
  3111 
       
  3112 void CMIDDisplayable::ProcessMSKCommandL()
       
  3113 {
       
  3114     if (iIdOfMSKCommand != KErrNotFound)
       
  3115     {
       
  3116         ProcessCommandL(iIdOfMSKCommand);
       
  3117     }
       
  3118 }
       
  3119 
       
  3120 void CMIDDisplayable::DisplayableBehindPopupIsDestroyed()
       
  3121 {
       
  3122     // Old fullscreen Displayable is destroyed.
       
  3123     iDisplayableBehindPopup = NULL;
       
  3124 }
       
  3125 
       
  3126 void CMIDDisplayable::HideIndicator(CEikStatusPane* aSp, TInt aId)
       
  3127 {
       
  3128     TUid uid = TUid::Uid(aId);
       
  3129     CEikStatusPaneBase::TPaneCapabilities subPane = aSp->PaneCapabilities(uid);
       
  3130     if (subPane.IsPresent() && subPane.IsAppOwned())
       
  3131     {
       
  3132         CCoeControl* ctrl = NULL;
       
  3133         TRAP_IGNORE(ctrl = aSp->ControlL(uid));
       
  3134         if (ctrl)
       
  3135         {
       
  3136             ctrl->MakeVisible(EFalse);
       
  3137         }
       
  3138     }
       
  3139 }
       
  3140 
       
  3141 void CMIDDisplayable::HideIndicators()
       
  3142 {
       
  3143     CEikStatusPane* pane = iAppUi->StatusPane();
       
  3144     if (!pane)
       
  3145         return;
       
  3146 
       
  3147     HideIndicator(pane, EEikStatusPaneUidSignal);
       
  3148     HideIndicator(pane, EEikStatusPaneUidBattery);
       
  3149     HideIndicator(pane, EEikStatusPaneUidIndic);
       
  3150     HideIndicator(pane, EEikStatusPaneUidMessage);
       
  3151     HideIndicator(pane, EEikStatusPaneUidClock);
       
  3152     HideIndicator(pane, EEikStatusPaneUidDigitalClock);
       
  3153 }
       
  3154 
       
  3155 CPropertyWatch* CPropertyWatch::NewL(MMIDDisplayable* aDisplayable)
       
  3156 {
       
  3157     DEBUG("+ CPropertyWatch::NewL");
       
  3158 
       
  3159     CPropertyWatch* self = new(ELeave) CPropertyWatch;
       
  3160     CleanupStack::PushL(self);
       
  3161     self->ConstructL(aDisplayable);
       
  3162     CleanupStack::Pop(self);
       
  3163 
       
  3164     DEBUG("- CPropertyWatch::NewL");
       
  3165 
       
  3166     return self;
       
  3167 }
       
  3168 
       
  3169 CPropertyWatch::CPropertyWatch()
       
  3170         : CActive(0)
       
  3171 {
       
  3172 }
       
  3173 
       
  3174 void CPropertyWatch::ConstructL(MMIDDisplayable* aDisplayable)
       
  3175 {
       
  3176     DEBUG("+ CPropertyWatch::ConstructL");
       
  3177 
       
  3178     iDisplayable = static_cast< CMIDDisplayable* >(aDisplayable);
       
  3179     User::LeaveIfError(iProperty.Attach(KCRUidAvkon, KAknKeyBoardLayout));
       
  3180     CActiveScheduler::Add(this);
       
  3181     iDelayTimer = CPeriodic::NewL(CActive::EPriorityStandard);
       
  3182     RunL();
       
  3183 
       
  3184     DEBUG("- CPropertyWatch::ConstructL");
       
  3185 }
       
  3186 
       
  3187 CPropertyWatch::~CPropertyWatch()
       
  3188 {
       
  3189     DEBUG("+ CPropertyWatch::~CPropertyWatch");
       
  3190 
       
  3191     Cancel();
       
  3192     iProperty.Close();
       
  3193 
       
  3194     if (iDelayTimer)
       
  3195     {
       
  3196         iDelayTimer->Cancel();
       
  3197         delete iDelayTimer;
       
  3198     }
       
  3199 
       
  3200     DEBUG("- CPropertyWatch::~CPropertyWatch");
       
  3201 }
       
  3202 
       
  3203 void CPropertyWatch::DoCancel()
       
  3204 {
       
  3205     iProperty.Cancel();
       
  3206 }
       
  3207 
       
  3208 void CPropertyWatch::HandleDelayTimerEventL()
       
  3209 {
       
  3210     iDelayTimer->Cancel();
       
  3211     if (Layout_Meta_Data::IsLandscapeOrientation())
       
  3212     {
       
  3213         iDisplayable->HandleOnScreenKeypadVisual();
       
  3214     }
       
  3215 }
       
  3216 
       
  3217 TInt CPropertyWatch::DelayTimerCallbackL(TAny* aThis)
       
  3218 {
       
  3219     CPropertyWatch* observer = static_cast<CPropertyWatch*>(aThis);
       
  3220     observer->HandleDelayTimerEventL();
       
  3221     return 0;
       
  3222 }
       
  3223 
       
  3224 void CPropertyWatch::RunL()
       
  3225 {
       
  3226     DEBUG("+ CPropertyWatch::RunL");
       
  3227 
       
  3228     //Resubscribe before processing new value to prevent missing updates
       
  3229     iProperty.Subscribe(iStatus);
       
  3230     SetActive();
       
  3231 
       
  3232     if (Layout_Meta_Data::IsLandscapeOrientation())
       
  3233     {
       
  3234         iDelayTimer->Cancel();
       
  3235         iDelayTimer->Start(KTimerDelayValue, KTimerDelayValue,
       
  3236                            TCallBack(DelayTimerCallbackL, this));
       
  3237     }
       
  3238 
       
  3239     DEBUG("- CPropertyWatch::RunL");
       
  3240 }
       
  3241 
       
  3242 
       
  3243 // End of File