uifw/AvKon/src/AknCharMap.cpp
changeset 0 2f259fa3e83a
child 4 8ca85d2f0db7
child 14 3320e4e6e8bb
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2002-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: Special character table.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <txtetext.h>
       
    21 #include <barsread.h>
       
    22 #include <eikappui.h>
       
    23 #include <eikenv.h>
       
    24 #include <aknenv.h>
       
    25 #include <eiksbfrm.h>
       
    26 #include <eikscrlb.h>
       
    27 #include <eikdialogext.h>
       
    28 #include <bidivisual.h>
       
    29 #include <avkon.rsg>
       
    30 #include "AknPanic.h"
       
    31 #include "avkon.hrh"
       
    32 #include "AknUtils.h"
       
    33 #include <aknlayoutscalable_avkon.cdl.h>
       
    34 #include <layoutmetadata.cdl.h>
       
    35 #include <AknLayout.lag>
       
    36 #include "aknCharMap.h"
       
    37 #include "aknappui.h"
       
    38 #include "aknconsts.h"
       
    39 #include "AknDef.h"
       
    40 #include <PUAcodes.hrh>
       
    41 #include <s32file.h>
       
    42 #include <AknPanic.h>
       
    43 #include "aknSctDialog.h" // CAknCharmapDialog
       
    44 #include <aknPopupHeadingPane.h>
       
    45 #include <aknfep.rsg>
       
    46 #include <bautils.h>
       
    47 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
       
    48 #include <uikon/eikenvinterface.h>
       
    49 #endif
       
    50 
       
    51 #include <AknTasHook.h>
       
    52 // For the TEikScrollBarModelType
       
    53 #include <eikscrlb.h>
       
    54 
       
    55 #include <AknsDrawUtils.h>
       
    56 #include <AknPictographInterface.h>
       
    57 #include <featmgr.h>
       
    58 #include <StringLoader.h>
       
    59 
       
    60 #include <AvkonInternalCRKeys.h>    // KCRUidAvkon, KAknRecentSctData
       
    61 #include <centralrepository.h>      // CRepository
       
    62 #include <AknsFrameBackgroundControlContext.h>
       
    63 
       
    64 #include <aknbutton.h>
       
    65 #include <gdi.h>
       
    66 #include <eikedwin.h>
       
    67 #include <gulbordr.h>
       
    68 #include <touchfeedback.h>
       
    69 #include <eiklabel.h>
       
    70 #include <aknphysics.h>
       
    71 #include <AknPriv.hrh>
       
    72 
       
    73 #include "PictograhGrouping.h"
       
    74 #include "AknSettingCache.h"
       
    75 #include "aknsctfocushandler.h"
       
    76 
       
    77 #include "AknSmileyModel.h"
       
    78 
       
    79 _LIT(KResFileName, "z:\\resource\\avkon.r");
       
    80 
       
    81 const TInt KAknSctCBaButtonDirections = 3; // bottom, right and left
       
    82 
       
    83 const TUint KThaiSCTCombiningSymbolAdd = 0xE900;
       
    84 
       
    85 enum
       
    86     {
       
    87     EAknCharMapButton1DownInGrid = 0x00000001,
       
    88     EAknCharMapHasBeenScrolledByDrag = 0x00000002,
       
    89     EAknCharMapCharsAllocated = 0x00000004, // flag that iChars points to HBufC
       
    90     EAknCharMapPressedDown = 0x00000008   // flag for press down effect
       
    91     };
       
    92 
       
    93 
       
    94 const TUint KHistoryEmptyChar = CEditableText::ETabCharacter;
       
    95 const TUint KHistoryEmptyCharForDisplay = CEditableText::ESpace;
       
    96 
       
    97 const TInt KAknSctRadioOn = 1;
       
    98 const TInt KAknSctRadioOff = 0;
       
    99 const TInt KAreaIdRecent = 0;
       
   100 const TInt KAreaIdMain   = 1;
       
   101 const TInt KAreaIdTail   = 2;
       
   102 
       
   103 
       
   104 // ----------------------------------------------------------------------------
       
   105 // TEmotionUtils definition
       
   106 // ----------------------------------------------------------------------------
       
   107 //
       
   108 
       
   109 const TUint KEmotionCharBase = 0xf880;
       
   110 
       
   111 class TEmotionUtils
       
   112     {
       
   113 public:
       
   114     static TBool IsEmotionChar(TChar aChar);
       
   115     static TChar EmotionChar(TInt aId);
       
   116     static TInt EmotionId(TChar aChar);
       
   117     static TChar EmotionSwitchToSmileyChar();
       
   118     static TChar EmotionSwitchToSctChar();
       
   119     };
       
   120 
       
   121 TBool TEmotionUtils::IsEmotionChar(TChar aChar)
       
   122     {
       
   123     return (aChar >= KEmotionCharBase);
       
   124     }
       
   125 
       
   126 TChar TEmotionUtils::EmotionChar(TInt aId)
       
   127     {
       
   128     return (KEmotionCharBase + aId);
       
   129     }
       
   130 
       
   131 TInt TEmotionUtils::EmotionId(TChar aChar)
       
   132     {
       
   133     return (TInt)(aChar - KEmotionCharBase);
       
   134     }
       
   135 
       
   136 TChar TEmotionUtils::EmotionSwitchToSmileyChar()
       
   137     {
       
   138     return KEmotionCharBase + CSmileyModel::EIconSwitchToSmiley;
       
   139     }
       
   140 
       
   141 TChar TEmotionUtils::EmotionSwitchToSctChar()
       
   142     {
       
   143     return KEmotionCharBase + CSmileyModel::EIconSwitchToSct;
       
   144     }
       
   145 
       
   146 
       
   147 // ----------------------------------------------------------------------------
       
   148 // CAknCharMapHistory definition
       
   149 // ----------------------------------------------------------------------------
       
   150 //
       
   151 /**
       
   152  *  Recent data management when a Special characters or a Pictograph characters 
       
   153  *  @lib avkon.lib
       
   154  *  @since 2.8
       
   155  *
       
   156  */
       
   157 class CAknCharMapHistory : public CBase
       
   158     {
       
   159     public: // Constructors and destructor
       
   160         /**
       
   161         * Two-phased constructor.
       
   162         */
       
   163         static CAknCharMapHistory* NewL();
       
   164 
       
   165         /**
       
   166         * Destructor.
       
   167         */
       
   168         ~CAknCharMapHistory();
       
   169 
       
   170     public: // enum
       
   171         enum THistoryType
       
   172             {
       
   173             EHistoryTypeNull = -1,
       
   174             EHistoryTypeFull = 0,
       
   175             EHistoryTypeHalf,
       
   176             EHistoryTypePicto,
       
   177             EHistoryTypePicto2,
       
   178             EHistoryTypeMax
       
   179             };
       
   180         
       
   181         enum THistoryFilter
       
   182             {
       
   183             EHistoryFilterMixed = 0, // text and emotion
       
   184             EHistoryFilterTextOnly,
       
   185             EHistoryFilterEmotionOnly,
       
   186             EHistoryFilterMax
       
   187             };
       
   188         
       
   189         enum THistorySize
       
   190             {
       
   191             KHistoryBufferSize = 15
       
   192             };
       
   193 
       
   194     public: // New functions
       
   195         /**
       
   196         * Load recent characters from file.
       
   197         * @since 2.8
       
   198         */
       
   199         TInt LoadL();
       
   200         /**
       
   201         * Reset recent data arrary.
       
   202         * @since 2.8
       
   203         */
       
   204         void ResetArray();
       
   205         /**
       
   206         * Store recent data to file.
       
   207         * @since 2.8
       
   208         */
       
   209         TInt SaveL();
       
   210         /**
       
   211         * Get recent data.
       
   212         * @since 2.8
       
   213         * @param aHistoryType The kind of charctor map, refer to THistoryType
       
   214         */
       
   215         const TDesC& RecentString(THistoryType aHistoryType, THistoryFilter aHistoryFilter=EHistoryFilterMixed);
       
   216         /**
       
   217         * Insert a character which select on SCT/Picto.
       
   218         * @since 2.8
       
   219         * @param aHistoryType The kind of charctor map, refer to THistoryType
       
   220         * @param aChar    Insert a character
       
   221         */
       
   222         void InsertChar(THistoryType aHistoryType, const TChar aChar);
       
   223 
       
   224     private:
       
   225         /**
       
   226         * C++ default constructor.
       
   227         * @since 2.8
       
   228         */
       
   229         CAknCharMapHistory();
       
   230 
       
   231         /**
       
   232         * By default Symbian 2nd phase constructor is private.
       
   233         * @since 2.8
       
   234         */
       
   235         void ConstructL();
       
   236         
       
   237     private:
       
   238         /**
       
   239         * Insert a character to a HBufC.
       
   240         * @param aHistoryBuf ahistory buffer
       
   241         * @param aChar    Insert a character
       
   242         */
       
   243         void InsertCharToHistoryBuf(TDes& aHistoryBuf, const TChar aChar);
       
   244 
       
   245     private:    // Data
       
   246         // Recent characters
       
   247         TBuf<KHistoryBufferSize> iMixedHistoryArray[EHistoryTypeMax];
       
   248         TBuf<KHistoryBufferSize> iTextHistoryArray[EHistoryTypeMax];
       
   249         TBuf<KHistoryBufferSize> iEmotionHistory;
       
   250         
       
   251         enum TBufferCount
       
   252             {
       
   253             KHistoryBufferCount = (EHistoryTypeMax+EHistoryTypeMax+1)
       
   254             };
       
   255     };
       
   256 
       
   257 
       
   258 // ----------------------------------------------------------------------------
       
   259 // Navi button class definition
       
   260 // ----------------------------------------------------------------------------
       
   261 //
       
   262 NONSHARABLE_CLASS(CAknSctNaviButton) : public CBase
       
   263     {
       
   264     public:
       
   265         static CAknSctNaviButton* NewL(
       
   266             const CCoeControl& aParent,
       
   267             TInt aButtonId,
       
   268             TResourceReader& reader);
       
   269         ~CAknSctNaviButton();
       
   270 
       
   271     private:
       
   272         CAknSctNaviButton(TInt aButtonId);
       
   273         void ConstructL(
       
   274             const CCoeControl& aParent,
       
   275             TResourceReader& reader);
       
   276 
       
   277     public:
       
   278         void SetFocused(TBool aState);
       
   279         void SetEnabled(TBool aState);
       
   280         TBool IsFocused();
       
   281         TBool IsEnabled();
       
   282 
       
   283     public:
       
   284         CAknButton* iButtonControl;
       
   285         TInt iButtonId;
       
   286         TBool iPressed;
       
   287         TBool iRepeat;
       
   288     };
       
   289 
       
   290 // ----------------------------------------------------------------------------
       
   291 // Table Navi class definition
       
   292 // ----------------------------------------------------------------------------
       
   293 //
       
   294 NONSHARABLE_CLASS(CAknSctTableNavi) : public CAknControl, public MAknSctFocusHandler
       
   295     {
       
   296     public:
       
   297         CAknSctTableNavi(CAknCharMap* aCharMap, CAknCharMapExtension* aExtension);
       
   298         ~CAknSctTableNavi();
       
   299 
       
   300     public:  // from CCoeControl
       
   301         TInt CountComponentControls() const;
       
   302         CCoeControl* ComponentControl( TInt aIndex ) const;
       
   303         virtual TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode);
       
   304         void ConstructFromResourceL(TResourceReader& aReader);
       
   305         virtual void HandlePointerEventL(const TPointerEvent& aPointerEvent);
       
   306         virtual TSize MinimumSize();
       
   307         virtual void SizeChanged();
       
   308 
       
   309     public: // from MAknSctFocusHandler
       
   310         virtual CCoeControl* FocusedControl();
       
   311         virtual TBool EnterControl(TInt aX, TInt aY);
       
   312         virtual void MoveFocus(TInt aX, TInt aY);
       
   313         virtual TBool ExitWithKey(TInt aKeycode);
       
   314         virtual TBool LeaveControl();
       
   315 
       
   316     public:
       
   317         TInt TableCount();
       
   318         void TableExitL();
       
   319         static TInt DoTableExit(TAny* aThis);
       
   320         void UpdateNextTableButtonL();
       
   321 
       
   322     private:
       
   323         TInt ButtonPosition(TInt aButtonIndex) const;
       
   324         TInt SetStatusChanged();
       
   325         void NextTableL();
       
   326 
       
   327     private:  // data
       
   328         TInt iButtonIndex;
       
   329         RPointerArray<CAknSctNaviButton> iButtonArray;
       
   330         CAknCharMap* iCharMap;
       
   331         CAknCharMapExtension* iExtension;
       
   332         CIdle *iIdle;
       
   333         
       
   334         TInt iPressedButtonIndex;
       
   335     };
       
   336 
       
   337 // ----------------------------------------------------------------------------
       
   338 // Navigator class definition
       
   339 // ----------------------------------------------------------------------------
       
   340 //
       
   341 NONSHARABLE_CLASS(CAknSctPageNavi) : public CAknControl, public MAknSctFocusHandler, public MCoeControlObserver
       
   342     {
       
   343     public:
       
   344         CAknSctPageNavi( CAknCharMap* aCharMap, CAknCharMapExtension* aExtension);
       
   345         ~CAknSctPageNavi();
       
   346 
       
   347     public: // new methods
       
   348        void UpdatePageTitleL() const;
       
   349 
       
   350     public:  // from CCoeControl
       
   351         TInt CountComponentControls() const;
       
   352         CCoeControl* ComponentControl( TInt aIndex ) const;
       
   353         virtual TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode);
       
   354         void ConstructFromResourceL(TResourceReader& aReader);
       
   355         virtual void HandlePointerEventL(const TPointerEvent& aPointerEvent);
       
   356         virtual TSize MinimumSize();
       
   357         virtual void SizeChanged();
       
   358         virtual void Draw(const TRect& aRect) const;
       
   359 
       
   360     public: // from MCoeControlObserver
       
   361         void HandleControlEventL(CCoeControl* aControl, TCoeEvent aEventType); // for button repeat
       
   362 
       
   363     public:  // from MAknSctFocusHandler
       
   364         virtual CCoeControl* FocusedControl();
       
   365         virtual TBool EnterControl(TInt aX, TInt aY);
       
   366         virtual void MoveFocus(TInt aX, TInt aY);
       
   367         virtual TBool ExitWithKey(TInt aKeycode);
       
   368         virtual TBool LeaveControl();
       
   369 
       
   370     private:
       
   371         TBool IsNextButton() const;
       
   372 
       
   373     private:  // data
       
   374         TInt iButtonIndex;
       
   375         RPointerArray<CAknSctNaviButton> iButtonArray;
       
   376         CAknCharMap* iCharMap;
       
   377         CAknCharMapExtension* iExtension;
       
   378         CEikLabel* iTitle;
       
   379     };
       
   380 
       
   381 // ----------------------------------------------------------------------------
       
   382 // Category button class defintion
       
   383 // ----------------------------------------------------------------------------
       
   384 //
       
   385 class CAknSctCategoryButton : public CBase
       
   386     {
       
   387     public:
       
   388         static CAknSctCategoryButton* NewL(
       
   389             const CCoeControl& aParent,
       
   390             TResourceReader& reader,
       
   391             TInt aCategoryButtonId,
       
   392             TInt aSctCaseId);
       
   393         ~CAknSctCategoryButton();
       
   394     private:
       
   395         CAknSctCategoryButton(
       
   396             TInt aCategoryButtonId,
       
   397             TInt aSctCaseId);
       
   398         void ConstructL(
       
   399             const CCoeControl& aParent,
       
   400             TResourceReader& reader);
       
   401 
       
   402     public:
       
   403         void SetFocused(TBool aState);
       
   404 
       
   405     public:
       
   406         CAknButton* iButtonControl;     // own
       
   407         TInt        iButtonId;
       
   408         TInt        iSctCaseId;
       
   409         TBool       iValid;
       
   410     };
       
   411 
       
   412 // ----------------------------------------------------------------------------
       
   413 // Radio button class defintion
       
   414 // ----------------------------------------------------------------------------
       
   415 //
       
   416 class CAknSctRadioButton : public CAknControl, public MAknSctFocusHandler
       
   417     {
       
   418     public:
       
   419         enum TAknSctRadioButtonFlags
       
   420             {
       
   421             EAknSctRadioButtonResize = 0x1,
       
   422             EAknSctRadioButtonEnd
       
   423             };
       
   424     public:
       
   425         CAknSctRadioButton();
       
   426         CAknSctRadioButton(CAknCharMap* aCharMap,
       
   427                            CAknCharMapExtension* aExtension);
       
   428         ~CAknSctRadioButton();
       
   429     public: // from MAknSctFocusHandler
       
   430         virtual CCoeControl* FocusedControl();
       
   431         virtual TBool EnterControl(TInt aX, TInt aY);
       
   432         virtual void MoveFocus(TInt aX, TInt aY);
       
   433         virtual TBool ExitWithKey(TInt aKeycode);
       
   434         virtual TBool LeaveControl();
       
   435 
       
   436     public:  // from CCoeControl
       
   437         TInt CountComponentControls() const;
       
   438         CCoeControl* ComponentControl( TInt aIndex ) const;
       
   439         virtual TKeyResponse OfferKeyEventL(
       
   440             const TKeyEvent& aKeyEvent, TEventCode);
       
   441         void ConstructFromResourceL(TResourceReader& aReader);
       
   442 
       
   443         /**
       
   444          * This function handles pointer events directed at the charmapdialog.
       
   445          * @param aPointerEvent The pointer event directed at the charmapdialog.
       
   446          */
       
   447         virtual void HandlePointerEventL(const TPointerEvent& aPointerEvent);
       
   448 
       
   449         virtual TSize MinimumSize();
       
   450         virtual void SizeChanged();
       
   451         virtual void Draw(const TRect& aRect) const;
       
   452 
       
   453     public:  // New function
       
   454         // The number of Buttons
       
   455         inline TInt Count() const;
       
   456 
       
   457         void SetCurrentCategory(TInt aCategory);
       
   458         void SetValidSctCase(TInt aSctCase);
       
   459         void RemoveInvalidButton();
       
   460 
       
   461     private:  // data
       
   462         RPointerArray<CAknSctCategoryButton> iButtonArray;
       
   463         MCoeControlObserver* iObserver;
       
   464         TInt iFlags;
       
   465         CAknCharMapExtension* iExtension;
       
   466         CAknCharMap* iCharMap;
       
   467         TInt iButtonIndex;
       
   468         TInt iEntryIndex;
       
   469     };
       
   470 // end of CAknSctRadioButton class definition
       
   471 
       
   472 // ----------------------------------------------------------------------------
       
   473 // Extension class defintion
       
   474 // ----------------------------------------------------------------------------
       
   475 //
       
   476 NONSHARABLE_CLASS(CAknCharMapExtension) : 
       
   477     public CBase,
       
   478     public MObjectProvider,
       
   479     public MAknSctFocusHandler,
       
   480     public MSmileyIconObserver
       
   481     {
       
   482     public:
       
   483         CAknCharMapExtension();
       
   484         ~CAknCharMapExtension();
       
   485 
       
   486     public: // new methods
       
   487         void SetCharMapControl(CAknCharMap* aCtrl);
       
   488         MAknSctFocusHandler* FocusHandler();
       
   489 
       
   490     public: // from MAknSctFocusHandler
       
   491         virtual CCoeControl* FocusedControl();
       
   492         virtual TBool EnterControl(TInt aX, TInt aY);
       
   493         virtual void MoveFocus(TInt aX, TInt aY);
       
   494         virtual TBool ExitWithKey(TInt aKeycode);
       
   495         virtual TBool LeaveControl();
       
   496 
       
   497     protected:
       
   498         TTypeUid::Ptr MopSupplyObject(TTypeUid aId);
       
   499         MObjectProvider* MopNext();
       
   500         
       
   501     private: // from MSmileyIconObserver
       
   502         virtual void ThumbnailLoaded(CSmileyIcon* aSmileyIcon);
       
   503         virtual void AnimationChanged(CSmileyIcon* aSmileyIcon);
       
   504         
       
   505     public:
       
   506         TBool IsEmotionEnabled() const;
       
   507         TBool IsShowingEmotion() const;
       
   508         TBool NeedEmotionSwitchIcon() const;
       
   509         HBufC* ReadEmotionHBufCL();
       
   510         void LoadEmotionTumbnails(const TDesC& aSctChars);
       
   511         void SetEmotionSize(const TSize& aSize);
       
   512 
       
   513         CSmileyIcon* EmotionIcon(TChar aEmotionChar);
       
   514         TBool DrawEmotion(CWindowGc& aGc, const TRect& aRect, TChar aEmotionChar);
       
   515         void HandleFocusStatusChanged(TChar aChar, TBool aIsFocused);
       
   516 
       
   517     public: // data
       
   518         MCoeControlObserver *iObserver;
       
   519         HBufC* iCharsQwerty;
       
   520         HBufC* iTitleBuf;
       
   521 
       
   522         TUint iFlags;
       
   523         TInt iMaxVisibleRows;
       
   524         CAknsFrameBackgroundControlContext* iBgContext;
       
   525         MObjectProvider* iCharMap;
       
   526         TBool iMenuSct; // Is SCT used in editing menu
       
   527         TBool iKeyOkEvent; // ETrue is set after pressing OK Key
       
   528 
       
   529         // FeatureManager
       
   530         TBool iPictographsBuffer;         // ETrue means Picto is valid.
       
   531         TBool iPictographsBufferGrouping; // ETrue means Picto grouping is valid.
       
   532         TBool iJapaneseSctUi;       // Title and Softkey for Japanese varinat
       
   533         TBool iHasCategoryButtonUi; // Has Category button UI
       
   534         CAknSctRadioButton* iRadioButton;
       
   535         TInt  iCurrentCategory;     // defined enum TAknSCTCategoryButton on avkon.hrh
       
   536 
       
   537         // QHD layout.
       
   538         CAknCharMap* iCharMapProxy;
       
   539         MAknSctFocusHandler* iFocusHandler;
       
   540         CAknSctTableNavi* iTableNavi;
       
   541         CAknSctPageNavi* iPageNavi;
       
   542         HBufC* iEntryBuf;
       
   543         CEikLabel* iCategoryTitle;
       
   544         CEikLabel* iCategoryEntry;
       
   545         TBool iSelectAllowed;
       
   546         
       
   547         // Whether or not kinetic scrolling is enabled in the device.
       
   548         // Focus scrolling is disabled if kinetic scrolling is used.
       
   549         TBool iKineticScrolling;
       
   550         // Indicates whether menu sct is highlighted or not.
       
   551         TBool iMenuSctHighlighted;
       
   552         
       
   553     public: // for Emotion
       
   554         HBufC* iCharsSmiley;
       
   555         CSmileyModel iSmileyModel;
       
   556         TChar iLastFocusedSmileyChar;
       
   557         TBool iIsShowingEmotion;
       
   558         TBool iIsEnableEmotion;
       
   559 
       
   560     public: // Single click        
       
   561        /**
       
   562         * Is single click mode enabled
       
   563         */
       
   564         TBool iSingleClickEnabled;
       
   565 
       
   566        /**
       
   567         * Is highlight visible
       
   568         */
       
   569         TBool iHighlightVisible;         
       
   570     };
       
   571 
       
   572 // ----------------------------------------------------------------------------
       
   573 // Navi button class implementation
       
   574 // ----------------------------------------------------------------------------
       
   575 //
       
   576 CAknSctNaviButton* CAknSctNaviButton::NewL(const CCoeControl& aParent, TInt aButtonId, TResourceReader& aReader)
       
   577     {
       
   578     CAknSctNaviButton* self = new( ELeave ) CAknSctNaviButton(aButtonId);
       
   579     CleanupStack::PushL( self );
       
   580     self->ConstructL(aParent, aReader);
       
   581     CleanupStack::Pop();
       
   582     return self;
       
   583     }
       
   584 
       
   585 CAknSctNaviButton::CAknSctNaviButton(TInt aButtonId) : iButtonId(aButtonId)
       
   586     {
       
   587     }
       
   588 
       
   589 void CAknSctNaviButton::ConstructL(const CCoeControl& aParent, TResourceReader& aReader)
       
   590     {
       
   591     iButtonControl = CAknButton::NewL(aReader);
       
   592     iButtonControl->SetContainerWindowL(aParent);
       
   593     }
       
   594 
       
   595 CAknSctNaviButton::~CAknSctNaviButton()
       
   596     {
       
   597     delete iButtonControl;
       
   598     }
       
   599 
       
   600 void CAknSctNaviButton::SetFocused(TBool aState)
       
   601     {
       
   602     iButtonControl->SetFocus(aState);
       
   603     iButtonControl->DrawNow();
       
   604     }
       
   605 
       
   606 void CAknSctNaviButton::SetEnabled(TBool aState)
       
   607     {
       
   608     iButtonControl->MakeVisible(aState);
       
   609     }
       
   610 
       
   611 TBool CAknSctNaviButton::IsFocused()
       
   612     {
       
   613     return iButtonControl->IsFocused();
       
   614     }
       
   615 
       
   616 TBool CAknSctNaviButton::IsEnabled()
       
   617     {
       
   618     return iButtonControl->IsVisible();
       
   619     }
       
   620 
       
   621 // ----------------------------------------------------------------------------
       
   622 // Table navi class implementation
       
   623 // ----------------------------------------------------------------------------
       
   624 //
       
   625 CAknSctTableNavi::CAknSctTableNavi(CAknCharMap* aCharMap, CAknCharMapExtension* aExtension) : 
       
   626 iCharMap(aCharMap), iExtension(aExtension)
       
   627     {
       
   628     }
       
   629 
       
   630 CAknSctTableNavi::~CAknSctTableNavi()
       
   631     {
       
   632     if (iButtonArray.Count())
       
   633         {
       
   634         iButtonArray.ResetAndDestroy();
       
   635         }
       
   636     iButtonArray.Close();
       
   637     delete iIdle;
       
   638     }
       
   639 
       
   640 TInt CAknSctTableNavi::CountComponentControls() const
       
   641     {
       
   642     return iButtonArray.Count();
       
   643     }
       
   644 
       
   645 CCoeControl* CAknSctTableNavi::ComponentControl( TInt aIndex ) const
       
   646     {
       
   647     CCoeControl* rtn;
       
   648     if (aIndex < iButtonArray.Count())
       
   649         {
       
   650         rtn = iButtonArray[aIndex]->iButtonControl;
       
   651         }
       
   652     else
       
   653         {
       
   654         rtn = NULL;
       
   655         }
       
   656     return rtn;
       
   657     }
       
   658 
       
   659 TKeyResponse CAknSctTableNavi::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aModifiers)
       
   660     {
       
   661     CAknSctNaviButton* buttonObj = iButtonArray[iButtonIndex];
       
   662     buttonObj->iButtonControl->OfferKeyEventL(aKeyEvent,aModifiers);
       
   663     TKeyResponse response = EKeyWasNotConsumed;
       
   664     TUint code=aKeyEvent.iCode;
       
   665     switch (code)
       
   666         {
       
   667         case EKeyEnter:
       
   668         case EKeyOK:
       
   669             {
       
   670             switch (buttonObj->iButtonId)
       
   671                 {
       
   672                 case EAknSctTableNaviExit:
       
   673                     {
       
   674                     iExtension->iKeyOkEvent = ETrue;
       
   675                     TableExitL();
       
   676                     response = EKeyWasConsumed;
       
   677                     }
       
   678                     break;
       
   679                 // add all supported table types here.
       
   680                 case EAknSctTableNaviSpecialChar:
       
   681                 case EAknSctTableNaviEmotion:
       
   682                     {
       
   683                     NextTableL();
       
   684                     response = EKeyWasConsumed;
       
   685                     }
       
   686                     break;
       
   687                 default:
       
   688                     break;
       
   689                 }
       
   690             }
       
   691             break;
       
   692         case EKeyLeftArrow:
       
   693         case '4':
       
   694             {
       
   695             MoveFocus(-1,0);
       
   696             response = EKeyWasConsumed;
       
   697             }
       
   698             break;
       
   699         case EKeyRightArrow:
       
   700         case '6':
       
   701             {
       
   702             MoveFocus(1,0);
       
   703             response = EKeyWasConsumed;
       
   704             }
       
   705             break;
       
   706         case EKeyUpArrow:
       
   707         case '2':
       
   708             {
       
   709             response = EKeyWasConsumed;
       
   710             if ((iButtonIndex==0) && !Layout_Meta_Data::IsLandscapeOrientation())
       
   711                 {
       
   712                 // Left page button.
       
   713                 if (iExtension->iPageNavi && iExtension->iPageNavi->EnterControl(0,0))
       
   714                     {
       
   715                     LeaveControl();
       
   716                     }
       
   717                 }
       
   718             else
       
   719                 {
       
   720                 // Last radio button.
       
   721                 if ((iButtonIndex==0) && iExtension->iRadioButton)
       
   722                     {
       
   723                     if (iExtension->iRadioButton->EnterControl(0,iExtension->iRadioButton->Count()-1))
       
   724                         {
       
   725                         LeaveControl();
       
   726                         }
       
   727                     break;
       
   728                     }
       
   729 
       
   730                 // Grid bottom row.
       
   731                 TInt xPos = ButtonPosition(iButtonIndex);
       
   732                 if (iCharMap->ColMax(0) > iCharMap->ColMax(xPos))
       
   733                     {
       
   734                     xPos = iCharMap->RowMax(iCharMap->ColMax(0));
       
   735                     }
       
   736 
       
   737                 if (iExtension->EnterControl(xPos,iCharMap->ColMax(xPos)))
       
   738                     {
       
   739                     LeaveControl();
       
   740                     break;
       
   741                     }
       
   742                 }
       
   743             }
       
   744             break;
       
   745             
       
   746         case EKeyDownArrow:
       
   747         case '8':
       
   748             {
       
   749             response = EKeyWasConsumed;
       
   750             
       
   751             // First radio button.
       
   752             if ((iButtonIndex==0) && iExtension->iRadioButton)
       
   753                 {
       
   754                 if (iExtension->iRadioButton->EnterControl(0,0))
       
   755                     {
       
   756                     LeaveControl();
       
   757                     }
       
   758                 break;
       
   759                 }
       
   760             
       
   761             // Grid top row.
       
   762             TInt xPos = ButtonPosition(iButtonIndex);
       
   763             if (iExtension->EnterControl(xPos,iCharMap->ColMin(xPos)))
       
   764                 {
       
   765                 LeaveControl();
       
   766                 break;
       
   767                 }
       
   768             }
       
   769             break;
       
   770             
       
   771         default:
       
   772             break;
       
   773         }
       
   774     return response;
       
   775     }
       
   776 
       
   777 void CAknSctTableNavi::TableExitL()
       
   778     {
       
   779     delete iIdle;
       
   780     iIdle = 0;
       
   781     iIdle = CIdle::NewL(CActive::EPriorityIdle);
       
   782     iIdle->Start(TCallBack(DoTableExit, this));
       
   783     }
       
   784 
       
   785 TInt CAknSctTableNavi::DoTableExit(TAny* aThis)
       
   786     {
       
   787     return ((CAknSctTableNavi*)aThis)->SetStatusChanged();
       
   788     }
       
   789 
       
   790 TInt CAknSctTableNavi::ButtonPosition(TInt aButtonIndex) const
       
   791     {
       
   792     // buttons behind the 1th are behavior as one button
       
   793     return (aButtonIndex==0) ? 0 : 1;
       
   794     }
       
   795 
       
   796 TInt CAknSctTableNavi::SetStatusChanged()
       
   797     {
       
   798     TRAPD(err, iCharMap->SetStatusChanged(EAknCharSelectedTableExitButton));
       
   799     return err;
       
   800     }
       
   801 
       
   802 void CAknSctTableNavi::NextTableL()
       
   803     {
       
   804     iCharMap->SetStatusChanged(EAknCharSelectedNextTableButton);
       
   805     }
       
   806 
       
   807 void CAknSctTableNavi::ConstructFromResourceL(TResourceReader& aReader)
       
   808     {
       
   809     // Table navi buttons.
       
   810     TInt counts = aReader.ReadInt16();
       
   811     for (TInt i = 0; i < counts; i++)
       
   812         {
       
   813         TInt buttonId = aReader.ReadInt16();
       
   814         TInt resId = aReader.ReadInt32();
       
   815         TResourceReader buttonReader;
       
   816         iCoeEnv->CreateResourceReaderLC(buttonReader, resId);
       
   817         CAknSctNaviButton* buttonObj = CAknSctNaviButton::NewL(*this, buttonId, buttonReader);
       
   818         iButtonArray.Append(buttonObj);
       
   819         CleanupStack::PopAndDestroy(); // buttonReader
       
   820         }
       
   821     }
       
   822 
       
   823 void CAknSctTableNavi::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
   824     {
       
   825     if (AknLayoutUtils::PenEnabled() && Rect().Contains(aPointerEvent.iPosition))
       
   826         {
       
   827         if (aPointerEvent.iType == TPointerEvent::EButton1Down)
       
   828             {
       
   829             iPressedButtonIndex = -1;
       
   830             
       
   831             for (TInt index = 0; index < iButtonArray.Count(); index++)
       
   832                 {
       
   833                 CAknSctNaviButton* buttonObj = iButtonArray[index];
       
   834                 if(buttonObj->IsEnabled())
       
   835                     {
       
   836                     TRect buttonRect = buttonObj->iButtonControl->Rect();
       
   837                     if (buttonRect.Contains(aPointerEvent.iPosition))
       
   838                         {
       
   839                         iPressedButtonIndex = index;
       
   840                         }
       
   841                     }
       
   842                 }
       
   843             }
       
   844         else if (aPointerEvent.iType == TPointerEvent::EButton1Up)
       
   845             {
       
   846             if(iPressedButtonIndex >= 0)
       
   847                 {
       
   848                 CAknSctNaviButton* buttonObj = iButtonArray[iPressedButtonIndex];
       
   849                 if(buttonObj->IsEnabled())
       
   850                     {
       
   851                     iButtonIndex = iPressedButtonIndex;
       
   852                     
       
   853                     TRect buttonRect = buttonObj->iButtonControl->Rect();
       
   854                     if (buttonRect.Contains(aPointerEvent.iPosition))
       
   855                         {
       
   856                         switch (buttonObj->iButtonId)
       
   857                             {
       
   858                             case EAknSctTableNaviExit:
       
   859                                 {
       
   860                                 iExtension->iKeyOkEvent = ETrue;
       
   861                                 TableExitL();
       
   862                                 }
       
   863                                 return;
       
   864                                 
       
   865                             case EAknSctTableNaviSpecialChar:
       
   866                             case EAknSctTableNaviEmotion:
       
   867                                 {
       
   868                                 NextTableL();
       
   869                                 }
       
   870                                 return;
       
   871                                 
       
   872                             default:
       
   873                                 break;
       
   874                             }
       
   875                         }
       
   876                     }
       
   877                 }
       
   878             }
       
   879         }
       
   880     
       
   881     CCoeControl::HandlePointerEventL(aPointerEvent);
       
   882     }
       
   883 
       
   884 TSize CAknSctTableNavi::MinimumSize()
       
   885     {
       
   886     return Rect().Size();
       
   887     }
       
   888 
       
   889 void CAknSctTableNavi::SizeChanged()
       
   890     {
       
   891     if (iButtonArray.Count()>0)
       
   892         {
       
   893 
       
   894         TInt ctrlVariety = 2;
       
   895         TInt cellVariety = 1;
       
   896         if(!iCharMap->IsJapaneseSctUi())
       
   897             {
       
   898             ctrlVariety = (iCharMap->TableCount()>1) ? 0 : 1;
       
   899             cellVariety = 0;
       
   900             }
       
   901         
       
   902         TAknLayoutRect cellLayRect, buttonLayRect;
       
   903         TRect buttonRect;
       
   904 
       
   905         // Table exit.
       
   906         cellLayRect.LayoutRect(Rect(), AknLayoutScalable_Avkon::cell_graphic2_control_pane(ctrlVariety,0));
       
   907         buttonLayRect.LayoutRect(cellLayRect.Rect(), AknLayoutScalable_Avkon::bg_button_pane_cp05(cellVariety));
       
   908         buttonRect = buttonLayRect.Rect();
       
   909 
       
   910         TAknLayoutRect iconLayRect;
       
   911         iconLayRect.LayoutRect(buttonRect, AknLayoutScalable_Avkon::cell_graphic2_control_pane_g1(cellVariety));
       
   912         TSize iconSize = iconLayRect.Rect().Size();
       
   913 
       
   914         CAknSctNaviButton* buttonObj = iButtonArray[0];
       
   915         buttonObj->iButtonControl->SetRect(buttonRect);
       
   916         buttonObj->iButtonControl->SetHighlightRect(buttonRect);
       
   917         buttonObj->iButtonControl->SetIconScaleMode(EAspectRatioPreserved);
       
   918         buttonObj->iButtonControl->SetIconSize(iconSize);
       
   919         buttonObj->SetEnabled(ETrue);
       
   920 
       
   921         // Table change.
       
   922         if (iCharMap->TableCount() > 1)
       
   923             {
       
   924             cellLayRect.LayoutRect(Rect(), AknLayoutScalable_Avkon::cell_graphic2_control_pane(ctrlVariety,1));
       
   925             buttonLayRect.LayoutRect(cellLayRect.Rect(), AknLayoutScalable_Avkon::bg_button_pane_cp05(cellVariety));
       
   926             buttonRect = buttonLayRect.Rect();
       
   927             
       
   928             for (TInt i(1); i<iButtonArray.Count(); i++)
       
   929                 {
       
   930                 CAknSctNaviButton* buttonObj = iButtonArray[i];
       
   931                 buttonObj->iButtonControl->SetRect(buttonRect);
       
   932                 buttonObj->iButtonControl->SetHighlightRect(buttonRect);
       
   933                 buttonObj->iButtonControl->SetIconScaleMode(EAspectRatioPreserved);
       
   934                 buttonObj->iButtonControl->SetIconSize(iconSize);
       
   935                 buttonObj->SetEnabled(ETrue);
       
   936                 }
       
   937             }
       
   938 
       
   939         TRAP_IGNORE(UpdateNextTableButtonL());
       
   940         }
       
   941     }
       
   942 
       
   943 
       
   944 void CAknSctTableNavi::UpdateNextTableButtonL()
       
   945     {
       
   946     
       
   947     TBool isFocused = EFalse;
       
   948     
       
   949     // table switch buttons stay in one place.
       
   950     for(TInt index(1); index<iButtonArray.Count(); index++)
       
   951         {
       
   952         CAknSctNaviButton* buttonObj = iButtonArray[index];
       
   953         if(buttonObj->IsEnabled())
       
   954             {
       
   955             isFocused = buttonObj->IsFocused();
       
   956             }
       
   957         }
       
   958     
       
   959     // fresh focused button
       
   960     for (TInt index(1); index<iButtonArray.Count(); index++)
       
   961         {
       
   962         CAknSctNaviButton* buttonObj = iButtonArray[index];
       
   963         if (iCharMap->TableCount() > 1)
       
   964             {
       
   965             switch (iCharMap->NextTableCase())
       
   966                 {
       
   967                 case EAknCharMapTableSpecialChar:
       
   968                     {
       
   969                     TBool isShown = EFalse;
       
   970                     if(iExtension->IsShowingEmotion())
       
   971                         {
       
   972                         isShown = (buttonObj->iButtonId==EAknSctTableNaviSpecialChar);
       
   973                         }
       
   974                     else
       
   975                         {
       
   976                         isShown = (buttonObj->iButtonId==EAknSctTableNaviEmotion);
       
   977                         }
       
   978                     buttonObj->SetEnabled(isShown);
       
   979                     buttonObj->SetFocused(isShown && isFocused);
       
   980                     if(isShown && isFocused)
       
   981                         {
       
   982                         iButtonIndex = index;
       
   983                         }
       
   984                     }
       
   985                     break;
       
   986 
       
   987                 default:
       
   988                     buttonObj->SetEnabled(EFalse);
       
   989                     break;
       
   990                 }
       
   991             }
       
   992         else
       
   993             {
       
   994             buttonObj->SetEnabled(EFalse);
       
   995             }
       
   996         }
       
   997     }
       
   998 
       
   999 CCoeControl* CAknSctTableNavi::FocusedControl()
       
  1000     {
       
  1001     return this;
       
  1002     }
       
  1003 
       
  1004 TBool CAknSctTableNavi::EnterControl(TInt aX, TInt /*aY*/)
       
  1005     {
       
  1006     if (IsVisible())
       
  1007         {
       
  1008         if ((aX >= 0) && (aX < iButtonArray.Count()))
       
  1009             {
       
  1010             TInt index = aX;
       
  1011             if (AknLayoutUtils::LayoutMirrored()) // reverse.
       
  1012                 {
       
  1013                 index = (iButtonArray.Count() - 1) - aX;
       
  1014                 }
       
  1015 
       
  1016             index = ButtonPosition(index);
       
  1017 
       
  1018             for(; index<iButtonArray.Count(); index++)
       
  1019                 {
       
  1020                 CAknSctNaviButton* buttonObj = iButtonArray[index];
       
  1021                 if (buttonObj->IsEnabled())
       
  1022                     {
       
  1023                     iButtonIndex = index;
       
  1024                     iExtension->iFocusHandler = this;
       
  1025                     buttonObj->SetFocused(ETrue);
       
  1026                     return ETrue;
       
  1027                     }
       
  1028                 }
       
  1029             }
       
  1030         }
       
  1031     return EFalse;
       
  1032     }
       
  1033 
       
  1034 void CAknSctTableNavi::MoveFocus(TInt aX, TInt /*aY*/)
       
  1035     {
       
  1036     TInt delta = aX;
       
  1037     if (AknLayoutUtils::LayoutMirrored()) // reverse.
       
  1038         {
       
  1039         delta = -aX;
       
  1040         }
       
  1041 
       
  1042     TInt buttonIndex = iButtonIndex + delta;
       
  1043 
       
  1044     // loop until find next position
       
  1045     for (TInt i = 0; i < iButtonArray.Count(); i++)
       
  1046         {
       
  1047 
       
  1048         if (buttonIndex > iButtonArray.Count() - 1) // goto Next control
       
  1049             {
       
  1050             if (!Layout_Meta_Data::IsLandscapeOrientation())
       
  1051                 {
       
  1052                 // First radio button.
       
  1053                 if (iExtension->iRadioButton)
       
  1054                     {
       
  1055                     if (iExtension->iRadioButton->EnterControl(0,0))
       
  1056                         {
       
  1057                         LeaveControl();
       
  1058                         }
       
  1059                     break;
       
  1060                     }
       
  1061                 // Grid start.
       
  1062                 if (iExtension->EnterControl(0,iCharMap->ColMin(0)))
       
  1063                     {
       
  1064                     LeaveControl();
       
  1065                     }
       
  1066                 }
       
  1067             else
       
  1068                 {
       
  1069                 // Left page button.
       
  1070                 if (iExtension->iPageNavi &&
       
  1071                     iExtension->iPageNavi->EnterControl(0,0))
       
  1072                     {
       
  1073                     LeaveControl();
       
  1074                     }
       
  1075                 }
       
  1076             break;
       
  1077             }
       
  1078 
       
  1079         else if (buttonIndex < 0) // goto Prev control
       
  1080             {
       
  1081             if (!Layout_Meta_Data::IsLandscapeOrientation())
       
  1082                 {
       
  1083                 // Right page button.
       
  1084                 if (iExtension->iPageNavi &&
       
  1085                     iExtension->iPageNavi->EnterControl(1,0))
       
  1086                     {
       
  1087                     LeaveControl();
       
  1088                     }
       
  1089                 }
       
  1090             else
       
  1091                 {
       
  1092                 // Grid end.
       
  1093                 TInt posY = iCharMap->ColMax(0);
       
  1094                 if (iExtension->EnterControl(iCharMap->RowMax(posY),posY))
       
  1095                     {
       
  1096                     LeaveControl();
       
  1097                     }
       
  1098                 }
       
  1099             break;
       
  1100             }
       
  1101 
       
  1102         if (iButtonArray[buttonIndex]->IsEnabled()) // goto next button in This control
       
  1103             {
       
  1104             CAknSctNaviButton* buttonObj;
       
  1105             buttonObj = iButtonArray[iButtonIndex];
       
  1106             buttonObj->SetFocused(EFalse);
       
  1107             iButtonIndex = buttonIndex;
       
  1108             buttonObj = iButtonArray[iButtonIndex];
       
  1109             buttonObj->SetFocused(ETrue);
       
  1110             break;
       
  1111             }
       
  1112         
       
  1113         buttonIndex += (delta < 0) ? -1 : 1; // get next position
       
  1114         }
       
  1115     }
       
  1116 
       
  1117 TBool CAknSctTableNavi::LeaveControl()
       
  1118     {
       
  1119     for (TInt i = 0; i < iButtonArray.Count(); i++ )
       
  1120         {
       
  1121         iButtonArray[i]->SetFocused(EFalse);
       
  1122         }
       
  1123     return ETrue;
       
  1124     }
       
  1125 
       
  1126 TBool CAknSctTableNavi::ExitWithKey(TInt /*aKeycode*/)
       
  1127     {
       
  1128     if (iButtonArray[iButtonIndex]->iButtonId != EAknSctTableNaviExit)
       
  1129         {
       
  1130         return EFalse;
       
  1131         }
       
  1132     else
       
  1133         {
       
  1134         return ETrue;
       
  1135         }
       
  1136     }
       
  1137 
       
  1138 // ----------------------------------------------------------------------------
       
  1139 // Page Navi class implementation
       
  1140 // ----------------------------------------------------------------------------
       
  1141 //
       
  1142 CAknSctPageNavi::CAknSctPageNavi(
       
  1143     CAknCharMap* aCharMap,
       
  1144     CAknCharMapExtension* aExtension)
       
  1145     :iCharMap(aCharMap),
       
  1146     iExtension(aExtension)
       
  1147     {
       
  1148     }
       
  1149 
       
  1150 CAknSctPageNavi::~CAknSctPageNavi()
       
  1151     {
       
  1152     if (iButtonArray.Count())
       
  1153         {
       
  1154         iButtonArray.ResetAndDestroy();
       
  1155         }
       
  1156     iButtonArray.Close();
       
  1157     delete iTitle;
       
  1158     }
       
  1159 
       
  1160 TInt CAknSctPageNavi::CountComponentControls() const
       
  1161     {
       
  1162     TInt num= 0;
       
  1163     if (iTitle)
       
  1164         {
       
  1165         num++;
       
  1166         }
       
  1167     if (iButtonArray.Count() > 0)
       
  1168         {
       
  1169         num += iButtonArray.Count();
       
  1170         }
       
  1171     return num;
       
  1172     }
       
  1173 
       
  1174 CCoeControl* CAknSctPageNavi::ComponentControl( TInt aIndex ) const
       
  1175     {
       
  1176     if (iTitle)
       
  1177         {
       
  1178         if ( aIndex == 0 )
       
  1179             {
       
  1180             return iTitle;
       
  1181             }
       
  1182         aIndex--;
       
  1183         }
       
  1184     if (iButtonArray.Count() > 0)
       
  1185         {
       
  1186         return iButtonArray[ aIndex ]->iButtonControl;
       
  1187         }
       
  1188     return NULL;
       
  1189     }
       
  1190 
       
  1191 TKeyResponse CAknSctPageNavi::OfferKeyEventL(
       
  1192     const TKeyEvent& aKeyEvent,
       
  1193     TEventCode aModifiers)
       
  1194     {
       
  1195     CAknSctNaviButton* buttonObj = iButtonArray[iButtonIndex];
       
  1196     buttonObj->iButtonControl->OfferKeyEventL(aKeyEvent,aModifiers);
       
  1197     TKeyResponse response = EKeyWasNotConsumed;
       
  1198     TUint code=aKeyEvent.iCode;
       
  1199     switch (code)
       
  1200         {
       
  1201         case EKeyEnter:
       
  1202         case EKeyOK:
       
  1203             {
       
  1204             switch (buttonObj->iButtonId)
       
  1205                 {
       
  1206                 case EAknSctPageNaviPrevPage:
       
  1207                     {
       
  1208                     iCharMap->PrevPageL();
       
  1209                     }
       
  1210                     break;
       
  1211                 case EAknSctPageNaviNextPage:
       
  1212                     {
       
  1213                     iCharMap->NextPageL();
       
  1214                     }
       
  1215                     break;
       
  1216                 default:
       
  1217                     return EKeyWasConsumed;
       
  1218                 }
       
  1219             buttonObj->SetFocused(ETrue);
       
  1220             response = EKeyWasConsumed;
       
  1221             UpdatePageTitleL();
       
  1222             }
       
  1223             break;
       
  1224         case EKeyLeftArrow:
       
  1225         case '4':
       
  1226             {
       
  1227             MoveFocus(-1,0);
       
  1228             response = EKeyWasConsumed;
       
  1229             }
       
  1230             break;
       
  1231         case EKeyRightArrow:
       
  1232         case '6':
       
  1233             {
       
  1234             MoveFocus(1,0);
       
  1235             response = EKeyWasConsumed;
       
  1236             }
       
  1237             break;
       
  1238         case EKeyUpArrow:
       
  1239         case '2':
       
  1240             {
       
  1241             response = EKeyWasConsumed;
       
  1242             if (!Layout_Meta_Data::IsLandscapeOrientation())
       
  1243                 {
       
  1244                 if (iExtension->iRadioButton && !IsNextButton())
       
  1245                     {
       
  1246                     // Last radio button.
       
  1247                     if (iExtension->iRadioButton->EnterControl(
       
  1248                         0,iExtension->iRadioButton->Count()-1))
       
  1249                         {
       
  1250                         LeaveControl();
       
  1251                         }
       
  1252                     break;
       
  1253                     }
       
  1254                 }
       
  1255             TInt xPos;
       
  1256             if (!Layout_Meta_Data::IsLandscapeOrientation())
       
  1257                 {
       
  1258                 xPos = IsNextButton() ? iCharMap->MaxCols() - 1 : 0;
       
  1259                 }
       
  1260             else
       
  1261                 {
       
  1262                 if (IsNextButton())
       
  1263                     {
       
  1264                     xPos = iCharMap->MaxCols() - 1;
       
  1265                     }
       
  1266                 else
       
  1267                     {
       
  1268                     xPos = !iExtension->iRadioButton ?
       
  1269                         iCharMap->TableCount() : iCharMap->MaxCols()-2;
       
  1270                     }
       
  1271                 }
       
  1272             if (iCharMap->ColMax(0) > iCharMap->ColMax(xPos))
       
  1273                 {
       
  1274                 xPos = iCharMap->RowMax(iCharMap->ColMax(0));
       
  1275                 }
       
  1276             // Grid bottom row.
       
  1277             if (iExtension->EnterControl(xPos,iCharMap->ColMax(xPos)))
       
  1278                 {
       
  1279                 LeaveControl();
       
  1280                 break;
       
  1281                 }
       
  1282             }
       
  1283             break;
       
  1284         case EKeyDownArrow:
       
  1285         case '8':
       
  1286             {
       
  1287             response = EKeyWasConsumed;
       
  1288             if (!Layout_Meta_Data::IsLandscapeOrientation())
       
  1289                 {
       
  1290                 if (!IsNextButton())
       
  1291                     {
       
  1292                     // First table button.
       
  1293                     if (iExtension->iTableNavi &&
       
  1294                         iExtension->iTableNavi->EnterControl(0,0))
       
  1295                         {
       
  1296                         LeaveControl();
       
  1297                         break;
       
  1298                         }
       
  1299                     }
       
  1300                 else
       
  1301                     {
       
  1302                     // Grid top row.
       
  1303                     TInt xPos = iCharMap->MaxCols() - 1;
       
  1304                     if (iExtension->EnterControl(xPos,iCharMap->ColMin(xPos)))
       
  1305                         {
       
  1306                         LeaveControl();
       
  1307                         break;
       
  1308                         }
       
  1309                     }
       
  1310                 }
       
  1311             else
       
  1312                 {
       
  1313                 TInt xPos;
       
  1314                 if (IsNextButton())
       
  1315                     {
       
  1316                     xPos = iCharMap->MaxCols() - 1;
       
  1317                     }
       
  1318                 else
       
  1319                     {
       
  1320                     xPos = !iExtension->iRadioButton ?
       
  1321                         iCharMap->TableCount() : iCharMap->MaxCols() - 2;
       
  1322                     }
       
  1323                 // Grid top row.
       
  1324                 if (iExtension->EnterControl(xPos,iCharMap->ColMin(xPos)))
       
  1325                     {
       
  1326                     LeaveControl();
       
  1327                     break;
       
  1328                     }
       
  1329                 }
       
  1330             }
       
  1331             break;
       
  1332         default:
       
  1333             break;
       
  1334         }
       
  1335     return response;
       
  1336     }
       
  1337 
       
  1338 TBool CAknSctPageNavi::IsNextButton() const
       
  1339     {
       
  1340     if (iButtonIndex < iButtonArray.Count() && iButtonArray[iButtonIndex])
       
  1341         {
       
  1342         return iButtonArray[iButtonIndex]->iButtonId == EAknSctPageNaviNextPage;
       
  1343         }
       
  1344     return EFalse;
       
  1345     }
       
  1346 
       
  1347 void CAknSctPageNavi::ConstructFromResourceL(TResourceReader& aReader)
       
  1348     {
       
  1349     TInt counts = aReader.ReadInt16();
       
  1350     for (TInt i = 0; i < counts; i++)
       
  1351         {
       
  1352         TInt buttonId = aReader.ReadInt16();
       
  1353         TInt resId = aReader.ReadInt32();
       
  1354         TResourceReader oneButtonReader;
       
  1355         iCoeEnv->CreateResourceReaderLC(oneButtonReader, resId);
       
  1356         CAknSctNaviButton* buttonObj =
       
  1357             CAknSctNaviButton::NewL(*this, buttonId, oneButtonReader);
       
  1358         buttonObj->iButtonControl->SetObserver(this); // for handling control events.
       
  1359         iButtonArray.Append(buttonObj);
       
  1360         CleanupStack::PopAndDestroy(); // oneButtonReader
       
  1361         }
       
  1362     iTitle = new (ELeave) CEikLabel;
       
  1363     }
       
  1364 
       
  1365 void CAknSctPageNavi::HandleControlEventL(
       
  1366     CCoeControl* aControl,
       
  1367     TCoeEvent aEventType)
       
  1368     {
       
  1369     if (aEventType == EEventStateChanged && AknLayoutUtils::PenEnabled()) // action on key repeat
       
  1370         {
       
  1371         for (TInt index=0; index < iButtonArray.Count(); index++)
       
  1372             {
       
  1373             CAknSctNaviButton* buttonObj = iButtonArray[index];
       
  1374             TRect buttonRect = buttonObj->iButtonControl->Rect();
       
  1375             if (buttonObj->iButtonControl == aControl)
       
  1376                 {
       
  1377                 if (buttonObj->IsEnabled() && buttonObj->iPressed)
       
  1378                     {
       
  1379                     iButtonIndex = index;
       
  1380                     switch (buttonObj->iButtonId)
       
  1381                         {
       
  1382                         case EAknSctPageNaviPrevPage:
       
  1383                             {
       
  1384                             buttonObj->iRepeat = ETrue; // Set button repeat.
       
  1385                             iCharMap->PrevPageL();
       
  1386                             UpdatePageTitleL();
       
  1387                             }
       
  1388                             break;
       
  1389                         case EAknSctPageNaviNextPage:
       
  1390                             {
       
  1391                             buttonObj->iRepeat = ETrue; // Set button repeat.
       
  1392                             iCharMap->NextPageL();
       
  1393                             UpdatePageTitleL();
       
  1394                             }
       
  1395                             break;
       
  1396                         default:
       
  1397                             break;
       
  1398                         }
       
  1399                     }
       
  1400                 }
       
  1401             }
       
  1402         }
       
  1403     }
       
  1404 
       
  1405 void CAknSctPageNavi::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
  1406     {
       
  1407     if (AknLayoutUtils::PenEnabled() && Rect().Contains(aPointerEvent.iPosition))
       
  1408         {
       
  1409         if (aPointerEvent.iType == TPointerEvent::EButton1Down)
       
  1410             {
       
  1411             for (TInt index=0; index < iButtonArray.Count(); index++)
       
  1412                 {
       
  1413                 CAknSctNaviButton* buttonObj = iButtonArray[index];
       
  1414                 buttonObj->iPressed = EFalse;
       
  1415                 buttonObj->iRepeat = EFalse;
       
  1416                 TRect buttonRect = buttonObj->iButtonControl->Rect();
       
  1417                 if (buttonRect.Contains(aPointerEvent.iPosition))
       
  1418                     {
       
  1419                     if (buttonObj->IsEnabled())
       
  1420                         {
       
  1421                         buttonObj->iButtonControl->SetButtonFlags(KAknButtonKeyRepeat);
       
  1422                         buttonObj->iPressed = ETrue; // Set button pressed.
       
  1423                         }
       
  1424                     }
       
  1425                 }
       
  1426             }
       
  1427         else if (aPointerEvent.iType == TPointerEvent::EButton1Up) // action on button release.
       
  1428             {
       
  1429             for (TInt index=0; index < iButtonArray.Count(); index++)
       
  1430                 {
       
  1431                 CAknSctNaviButton* buttonObj = iButtonArray[index];
       
  1432                 TRect buttonRect = buttonObj->iButtonControl->Rect();
       
  1433                 if (buttonRect.Contains(aPointerEvent.iPosition))
       
  1434                     {
       
  1435                     if (buttonObj->IsEnabled())
       
  1436                         {
       
  1437                         if (buttonObj->iPressed && !buttonObj->iRepeat)
       
  1438                             {
       
  1439                             iButtonIndex = index;
       
  1440                             switch (buttonObj->iButtonId)
       
  1441                                 {
       
  1442                                 case EAknSctPageNaviPrevPage:
       
  1443                                     {
       
  1444                                     iCharMap->PrevPageL();
       
  1445                                     UpdatePageTitleL();
       
  1446                                     }
       
  1447                                     break;
       
  1448                                 case EAknSctPageNaviNextPage:
       
  1449                                     {
       
  1450                                     iCharMap->NextPageL();
       
  1451                                     UpdatePageTitleL();
       
  1452                                     }
       
  1453                                     break;
       
  1454                                 default:
       
  1455                                     break;
       
  1456                                 }
       
  1457                             }
       
  1458                         }
       
  1459                     }
       
  1460                 buttonObj->iPressed = EFalse; // Button released.
       
  1461                 buttonObj->iRepeat = EFalse;
       
  1462                 }
       
  1463             }
       
  1464         }
       
  1465     CCoeControl::HandlePointerEventL(aPointerEvent);
       
  1466     }
       
  1467 
       
  1468 TSize CAknSctPageNavi::MinimumSize()
       
  1469     {
       
  1470     return Rect().Size();
       
  1471     }
       
  1472 
       
  1473 void CAknSctPageNavi::SizeChanged()
       
  1474     {
       
  1475 
       
  1476     TAknLayoutRect pageButtonLayRect;
       
  1477     TInt pageVariate = !iCharMap->IsJapaneseSctUi() ? ((iCharMap->TableCount() > 1) ? 0 : 1) : 2;
       
  1478                        
       
  1479     CAknSctNaviButton* buttonObj;
       
  1480     TRect rect;
       
  1481 
       
  1482     buttonObj = iButtonArray[0];
       
  1483     buttonObj->iButtonControl->SetButtonFlags(0);
       
  1484     if (!AknLayoutUtils::LayoutMirrored())
       
  1485         {
       
  1486         buttonObj->iButtonId = EAknSctPageNaviPrevPage;
       
  1487         pageButtonLayRect.LayoutRect(Rect(),AknLayoutScalable_Avkon::bg_button_pane_cp10(pageVariate));
       
  1488         }
       
  1489     else
       
  1490         {
       
  1491         buttonObj->iButtonId = EAknSctPageNaviNextPage;
       
  1492         pageButtonLayRect.LayoutRect(Rect(),AknLayoutScalable_Avkon::bg_button_pane_cp11(pageVariate));
       
  1493         }
       
  1494     rect = pageButtonLayRect.Rect();
       
  1495     buttonObj->iButtonControl->SetRect(rect);
       
  1496     buttonObj->iButtonControl->SetHighlightRect(rect);
       
  1497     TAknLayoutRect pageButtonIconLayRect;
       
  1498     pageButtonIconLayRect.LayoutRect(pageButtonLayRect.Rect(), AknLayoutScalable_Avkon::graphic2_pages_pane_g1(pageVariate));
       
  1499     buttonObj->iButtonControl->SetIconScaleMode(EAspectRatioPreserved);
       
  1500     TSize iconSize = pageButtonIconLayRect.Rect().Size();
       
  1501     buttonObj->iButtonControl->SetIconSize(iconSize);
       
  1502 
       
  1503     buttonObj = iButtonArray[1];
       
  1504     buttonObj->iButtonControl->SetButtonFlags(0);
       
  1505     if (!AknLayoutUtils::LayoutMirrored())
       
  1506         {
       
  1507         buttonObj->iButtonId = EAknSctPageNaviNextPage;
       
  1508         pageButtonLayRect.LayoutRect(Rect(), AknLayoutScalable_Avkon::bg_button_pane_cp11(pageVariate));
       
  1509         }
       
  1510     else
       
  1511         {
       
  1512         buttonObj->iButtonId = EAknSctPageNaviPrevPage;
       
  1513         pageButtonLayRect.LayoutRect(Rect(), AknLayoutScalable_Avkon::bg_button_pane_cp10(pageVariate));
       
  1514         }
       
  1515     rect = pageButtonLayRect.Rect();
       
  1516     buttonObj->iButtonControl->SetRect(rect);
       
  1517     buttonObj->iButtonControl->SetHighlightRect(rect);
       
  1518     buttonObj->iButtonControl->SetIconScaleMode(EAspectRatioPreserved);
       
  1519     buttonObj->iButtonControl->SetIconSize(iconSize);
       
  1520 
       
  1521     // Page text.
       
  1522     TRect parentRect = Rect();
       
  1523     AknLayoutUtils::LayoutLabel(iTitle, parentRect, AknLayoutScalable_Avkon::graphic2_pages_pane_t1(pageVariate).LayoutLine());
       
  1524 
       
  1525     // Page text color
       
  1526     TAknLayoutText textLayout;
       
  1527     textLayout.LayoutText(parentRect, AknLayoutScalable_Avkon::graphic2_pages_pane_t1(pageVariate));
       
  1528     TRect textRect = textLayout.TextRect();
       
  1529     TRgb color = textLayout.Color();
       
  1530     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  1531     if (skin)
       
  1532         {
       
  1533         (void)AknsUtils::GetCachedColor(skin, color, KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG6);
       
  1534         }
       
  1535     TRAP_IGNORE(AknLayoutUtils::OverrideControlColorL(*iTitle, EColorLabelText, color));
       
  1536     TRAP_IGNORE(UpdatePageTitleL());
       
  1537     }
       
  1538 
       
  1539 void CAknSctPageNavi::Draw(const TRect& /*aRect*/) const
       
  1540     {
       
  1541     TRAP_IGNORE(UpdatePageTitleL());
       
  1542     }
       
  1543 
       
  1544 void CAknSctPageNavi::UpdatePageTitleL() const
       
  1545     {
       
  1546     CArrayFix<TInt>* numbers = new(ELeave)CArrayFixFlat<TInt>(2);
       
  1547     CleanupStack::PushL(numbers);
       
  1548     numbers->AppendL(iCharMap->CurrentPage());
       
  1549     numbers->AppendL(iCharMap->PageCount());
       
  1550     HBufC* page =
       
  1551         StringLoader::LoadL(
       
  1552             R_AVKON_SPECIAL_CHARACTERS_PAGE_INDICATOR, *numbers, iEikonEnv);
       
  1553     CleanupStack::PopAndDestroy(); // numbers
       
  1554     iTitle->SetTextL(page->Des());
       
  1555     iTitle->SetBrushStyle(CGraphicsContext::ENullBrush);
       
  1556     delete page;
       
  1557     }
       
  1558 
       
  1559 CCoeControl* CAknSctPageNavi::FocusedControl()
       
  1560     {
       
  1561     return this;
       
  1562     }
       
  1563 
       
  1564 TBool CAknSctPageNavi::EnterControl(TInt aX, TInt /*aY*/)
       
  1565     {
       
  1566     if (IsVisible())
       
  1567         {
       
  1568         if ((aX >= 0) && (aX < iButtonArray.Count()))
       
  1569             {
       
  1570             CAknSctNaviButton* buttonObj;
       
  1571             buttonObj = iButtonArray[iButtonIndex];
       
  1572             buttonObj->SetFocused(EFalse);
       
  1573             TInt index = aX;
       
  1574             if (AknLayoutUtils::LayoutMirrored()) // reverse.
       
  1575                 {
       
  1576                 index = iButtonArray.Count() - 1 - aX;
       
  1577                 }
       
  1578             buttonObj = iButtonArray[index];
       
  1579             if (buttonObj->IsEnabled())
       
  1580                 {
       
  1581                 iButtonIndex = index;
       
  1582                 iExtension->iFocusHandler = this;
       
  1583                 buttonObj->SetFocused(ETrue);
       
  1584                 return ETrue;
       
  1585                 }
       
  1586             }
       
  1587         }
       
  1588     return EFalse;
       
  1589     }
       
  1590 
       
  1591 void CAknSctPageNavi::MoveFocus(TInt aX, TInt /*aY*/)
       
  1592     {
       
  1593     TInt delta = aX;
       
  1594     TInt buttonIndex = iButtonIndex + delta;
       
  1595     for (TInt i = 0; i < iButtonArray.Count(); i++)
       
  1596         {
       
  1597         if (buttonIndex > iButtonArray.Count() - 1) // Next control.
       
  1598             {
       
  1599             if (!AknLayoutUtils::LayoutMirrored())
       
  1600                 {
       
  1601                 if (!Layout_Meta_Data::IsLandscapeOrientation())
       
  1602                     {
       
  1603                     // First table button.
       
  1604                     if (iExtension->iTableNavi &&
       
  1605                         iExtension->iTableNavi->EnterControl(0,0))
       
  1606                         {
       
  1607                         LeaveControl();
       
  1608                         break;
       
  1609                         }
       
  1610                     }
       
  1611                 else
       
  1612                     {
       
  1613                     // First radio button.
       
  1614                     if (iExtension->iRadioButton &&
       
  1615                         iExtension->iRadioButton->EnterControl(0,0))
       
  1616                         {
       
  1617                         LeaveControl();
       
  1618                         break;
       
  1619                         }
       
  1620                     // Grid start.
       
  1621                     TInt yPos = iCharMap->ColMin(0);
       
  1622                     if (iExtension->EnterControl(iCharMap->RowMin(yPos),yPos))
       
  1623                         {
       
  1624                         LeaveControl();
       
  1625                         break;
       
  1626                         }
       
  1627                     }
       
  1628                 }
       
  1629             else
       
  1630                 {
       
  1631                 if (!Layout_Meta_Data::IsLandscapeOrientation())
       
  1632                     {
       
  1633                     // Grid end.
       
  1634                     TInt yPos = iCharMap->ColMax(0);
       
  1635                     if (iExtension->EnterControl(iCharMap->RowMax(yPos),yPos))
       
  1636                         {
       
  1637                         LeaveControl();
       
  1638                         break;
       
  1639                         }
       
  1640                     }
       
  1641                 else
       
  1642                     {
       
  1643                     // Last table button.
       
  1644                     TInt xPos = iCharMap->TableCount() - 1;
       
  1645                     if (iExtension->iTableNavi &&
       
  1646                         iExtension->iTableNavi->EnterControl(xPos,0))
       
  1647                         {
       
  1648                         LeaveControl();
       
  1649                         break;
       
  1650                         }
       
  1651                     }
       
  1652                 }
       
  1653             break;
       
  1654             }
       
  1655         else if (buttonIndex < 0) // Prev control
       
  1656             {
       
  1657             if (!AknLayoutUtils::LayoutMirrored())
       
  1658                 {
       
  1659                 if (!Layout_Meta_Data::IsLandscapeOrientation())
       
  1660                     {
       
  1661                     // Grid end.
       
  1662                     TInt yPos = iCharMap->ColMax(0);
       
  1663                     if (iExtension->EnterControl(iCharMap->RowMax(yPos),yPos))
       
  1664                         {
       
  1665                         LeaveControl();
       
  1666                         break;
       
  1667                         }
       
  1668                     }
       
  1669                 else
       
  1670                     {
       
  1671                     // Last table button.
       
  1672                     if (iExtension->iTableNavi && 
       
  1673                         iExtension->iTableNavi->EnterControl(iCharMap->TableCount()-1,0))
       
  1674                         {
       
  1675                         LeaveControl();
       
  1676                         break;
       
  1677                         }
       
  1678                     }
       
  1679                 }
       
  1680             else
       
  1681                 {
       
  1682                 if (!Layout_Meta_Data::IsLandscapeOrientation())
       
  1683                     {
       
  1684                     // First table button.
       
  1685                     if (iExtension->iTableNavi &&
       
  1686                         iExtension->iTableNavi->EnterControl(0,0))
       
  1687                         {
       
  1688                         LeaveControl();
       
  1689                         break;
       
  1690                         }
       
  1691                     }
       
  1692                 else
       
  1693                     {
       
  1694                     // Grid start.
       
  1695                     TInt yPos = iCharMap->ColMin(0);
       
  1696                     if (iExtension->EnterControl(iCharMap->RowMin(yPos),yPos))
       
  1697                         {
       
  1698                         LeaveControl();
       
  1699                         break;
       
  1700                         }
       
  1701                     }
       
  1702                 }
       
  1703             }
       
  1704 
       
  1705         if (iButtonArray[buttonIndex]->IsEnabled()) // This control
       
  1706             {
       
  1707             CAknSctNaviButton* buttonObj;
       
  1708             buttonObj = iButtonArray[iButtonIndex];
       
  1709             buttonObj->SetFocused(EFalse);
       
  1710             iButtonIndex = buttonIndex;
       
  1711             buttonObj = iButtonArray[iButtonIndex];
       
  1712             buttonObj->SetFocused(ETrue);
       
  1713             break;
       
  1714             }
       
  1715         buttonIndex += (delta < 0) ? -1 : 1;
       
  1716         }
       
  1717     }
       
  1718 
       
  1719 TBool CAknSctPageNavi::LeaveControl()
       
  1720     {
       
  1721     for (TInt i = 0; i < iButtonArray.Count(); i++ )
       
  1722         {
       
  1723         iButtonArray[i]->SetFocused(EFalse);
       
  1724         }
       
  1725     return ETrue;
       
  1726     }
       
  1727 
       
  1728 TBool CAknSctPageNavi::ExitWithKey(TInt /*aKeycode*/)
       
  1729     {
       
  1730     return EFalse;
       
  1731     }
       
  1732 
       
  1733 // ----------------------------------------------------------------------------
       
  1734 // Category button class implementation
       
  1735 // ----------------------------------------------------------------------------
       
  1736 //
       
  1737 CAknSctCategoryButton* CAknSctCategoryButton::NewL(
       
  1738     const CCoeControl& aParent,
       
  1739     TResourceReader& reader,
       
  1740     TInt aCategoryButtonId,
       
  1741     TInt aSctCaseId)
       
  1742     {
       
  1743     CAknSctCategoryButton* self =
       
  1744         new( ELeave ) CAknSctCategoryButton(aCategoryButtonId, aSctCaseId);
       
  1745 
       
  1746     CleanupStack::PushL( self );
       
  1747     self->ConstructL(aParent, reader);
       
  1748     CleanupStack::Pop();
       
  1749 
       
  1750     return self;
       
  1751     }
       
  1752 
       
  1753 CAknSctCategoryButton::CAknSctCategoryButton(
       
  1754     TInt aCategoryButtonId,
       
  1755     TInt aSctCaseId)
       
  1756     : iButtonId(aCategoryButtonId)
       
  1757     , iSctCaseId(aSctCaseId)
       
  1758     {
       
  1759     }
       
  1760 
       
  1761 void CAknSctCategoryButton::ConstructL(
       
  1762     const CCoeControl& aParent,
       
  1763     TResourceReader& aReader)
       
  1764     {
       
  1765     iButtonControl = CAknButton::NewL(aReader);
       
  1766     iButtonControl->SetContainerWindowL(aParent);
       
  1767     }
       
  1768 
       
  1769 CAknSctCategoryButton::~CAknSctCategoryButton()
       
  1770     {
       
  1771     delete iButtonControl;
       
  1772     }
       
  1773 
       
  1774 void CAknSctCategoryButton::SetFocused(TBool aState)
       
  1775     {
       
  1776     iButtonControl->SetFocus(aState);
       
  1777     iButtonControl->DrawNow();
       
  1778     }
       
  1779 
       
  1780 
       
  1781 // ----------------------------------------------------------------------------
       
  1782 // Radio button class implementation
       
  1783 // ----------------------------------------------------------------------------
       
  1784 //
       
  1785 CAknSctRadioButton::CAknSctRadioButton()
       
  1786     {
       
  1787     }
       
  1788 
       
  1789 CAknSctRadioButton::CAknSctRadioButton(
       
  1790     CAknCharMap* aCharMap,
       
  1791     CAknCharMapExtension* aExtension)
       
  1792     :iExtension(aExtension),
       
  1793     iCharMap(aCharMap)
       
  1794     {
       
  1795     }
       
  1796 
       
  1797 CAknSctRadioButton::~CAknSctRadioButton()
       
  1798     {
       
  1799     iButtonArray.ResetAndDestroy();
       
  1800     iButtonArray.Close();
       
  1801     }
       
  1802 
       
  1803 TInt CAknSctRadioButton::CountComponentControls() const
       
  1804     {
       
  1805     return iButtonArray.Count();
       
  1806     }
       
  1807 
       
  1808 CCoeControl* CAknSctRadioButton::ComponentControl( TInt aIndex ) const
       
  1809     {
       
  1810     if (aIndex < iButtonArray.Count())
       
  1811         {
       
  1812         return iButtonArray[aIndex]->iButtonControl;
       
  1813         }
       
  1814     return NULL;
       
  1815     }
       
  1816 
       
  1817 TKeyResponse CAknSctRadioButton::OfferKeyEventL(
       
  1818     const TKeyEvent& aKeyEvent,
       
  1819     TEventCode /*aModifiers*/)
       
  1820     {
       
  1821     TKeyResponse responce = EKeyWasNotConsumed;
       
  1822     TUint code=aKeyEvent.iCode;
       
  1823     switch (code)
       
  1824         {
       
  1825         case EKeyEnter:
       
  1826         case EKeyOK:
       
  1827             {
       
  1828             if (AknLayoutUtils::PenEnabled())
       
  1829                 {
       
  1830                 // Grid.
       
  1831                 TInt yPos = iCharMap->ColMin(0);
       
  1832                 TInt xPos = iCharMap->RowMin(yPos);
       
  1833                 if (iExtension->EnterControl(xPos,yPos))
       
  1834                     {
       
  1835                     CAknButton* buttonCtrlObj;
       
  1836                     TInt currentIndex;
       
  1837                     TInt newIndex;
       
  1838                     for (TInt index=0; index < iButtonArray.Count(); index++)
       
  1839                         {
       
  1840                         buttonCtrlObj = iButtonArray[index]->iButtonControl;
       
  1841                         currentIndex = buttonCtrlObj->StateIndex();
       
  1842                         if (index == iButtonIndex)
       
  1843                             {
       
  1844                             newIndex = KAknSctRadioOn;
       
  1845                             }
       
  1846                         else
       
  1847                             {
       
  1848                             newIndex = KAknSctRadioOff;
       
  1849                             }
       
  1850                         if (currentIndex != newIndex)
       
  1851                             {
       
  1852                             buttonCtrlObj->SetCurrentState(newIndex, ETrue);
       
  1853                             if (newIndex == KAknSctRadioOn)
       
  1854                                 {
       
  1855                                 iExtension->iCurrentCategory =
       
  1856                                     iButtonArray[index]->iButtonId;
       
  1857                                 iCharMap->SetStatusChanged(EAknCharChangedCategory);
       
  1858                                 }
       
  1859                             }
       
  1860                         }
       
  1861                     LeaveControl();
       
  1862                     }
       
  1863                 }
       
  1864             responce = EKeyWasConsumed;
       
  1865             }
       
  1866             break;
       
  1867         case EKeyLeftArrow:
       
  1868         case '4':
       
  1869             {
       
  1870             responce = EKeyWasConsumed;
       
  1871             if (AknLayoutUtils::PenEnabled())
       
  1872                 {
       
  1873                 TInt yPos = iButtonIndex - 1;
       
  1874                 if (iCharMap->RowMax(yPos) < 0)
       
  1875                     {
       
  1876                     if (Layout_Meta_Data::IsLandscapeOrientation())
       
  1877                         {
       
  1878                         if (iExtension->iRadioButton)
       
  1879                             {
       
  1880                             // Right page button.
       
  1881                             if (iExtension->iPageNavi &&
       
  1882                                 iExtension->iPageNavi->EnterControl(1,0))
       
  1883                                 {
       
  1884                                 LeaveControl();
       
  1885                                 break;
       
  1886                                 }
       
  1887                             }
       
  1888                         }
       
  1889                     // Next button up.
       
  1890                     MoveFocus(0,-1);
       
  1891                     break;
       
  1892                     }
       
  1893                 else
       
  1894                     {
       
  1895                     //Previous row end.
       
  1896                     TInt xPos = iCharMap->RowMax(yPos);
       
  1897                     if (iExtension->EnterControl(xPos,yPos))
       
  1898                         {
       
  1899                         LeaveControl();
       
  1900                         break;
       
  1901                         }
       
  1902                     }
       
  1903                 break;
       
  1904                 }
       
  1905             // Move by grid.
       
  1906             iCharMap->TakeFocus();
       
  1907             TInt xPos = iCharMap->CursorPos().iX;
       
  1908             TInt yPos = iCharMap->CursorPos().iY;
       
  1909             if (xPos == 0)
       
  1910                 {
       
  1911                 iCharMap->MoveFocus(-1,0);
       
  1912                 }
       
  1913             iCharMap->ShowFocus();
       
  1914             }
       
  1915             break;
       
  1916         case EKeyRightArrow:
       
  1917         case '6':
       
  1918             {
       
  1919             responce = EKeyWasConsumed;
       
  1920             if (AknLayoutUtils::PenEnabled())
       
  1921                 {
       
  1922                 TInt yPos = iButtonIndex;
       
  1923                 if (iCharMap->RowMax(yPos) < 0)
       
  1924                     {
       
  1925                     // Next button down.
       
  1926                     MoveFocus(0,1);
       
  1927                     break;
       
  1928                     }
       
  1929                 else
       
  1930                     {
       
  1931                     // 1st cell in the row.
       
  1932                     if (iExtension->EnterControl(0,yPos))
       
  1933                         {
       
  1934                         LeaveControl();
       
  1935                         break;
       
  1936                         }
       
  1937                     }
       
  1938                 break;
       
  1939                 }
       
  1940             // Move by grid.
       
  1941             iCharMap->TakeFocus();
       
  1942             TInt xPos = iCharMap->CursorPos().iX;
       
  1943             TInt yPos = iCharMap->CursorPos().iY;
       
  1944             if (xPos == iCharMap->RowMax(yPos))
       
  1945                 {
       
  1946                 iCharMap->MoveFocus(1,0);
       
  1947                 }
       
  1948             iCharMap->ShowFocus();
       
  1949             }
       
  1950             break;
       
  1951         case EKeyDownArrow:
       
  1952         case '8':
       
  1953             {
       
  1954             MoveFocus(0, 1);
       
  1955             responce = EKeyWasConsumed;
       
  1956             }
       
  1957             break;
       
  1958         case EKeyUpArrow:
       
  1959         case '2':
       
  1960             {
       
  1961             MoveFocus(0,-1);
       
  1962             responce = EKeyWasConsumed;
       
  1963             }
       
  1964             break;
       
  1965         default:
       
  1966             break;
       
  1967         }
       
  1968     return responce;
       
  1969     }
       
  1970 
       
  1971 void CAknSctRadioButton::ConstructFromResourceL(TResourceReader& aReader)
       
  1972     {
       
  1973     TInt counts = aReader.ReadInt16();
       
  1974     TResourceReader reader;
       
  1975     TInt categorybutton_id;
       
  1976     TInt sctcase_id;
       
  1977     TInt resId;
       
  1978     CAknSctCategoryButton* buttonObj;
       
  1979     TBool allowCreation;
       
  1980 
       
  1981     for (TInt index=0; index < counts; index++)
       
  1982         {
       
  1983         allowCreation = EFalse;
       
  1984         // button id
       
  1985         categorybutton_id = aReader.ReadInt16();
       
  1986         sctcase_id = aReader.ReadInt16();
       
  1987         switch (categorybutton_id)
       
  1988             {
       
  1989             case EAknSCTCategoryButtonHalfCase:
       
  1990             case EAknSCTCategoryButtonFullCase:
       
  1991                 allowCreation = ETrue;
       
  1992                 break;
       
  1993             case EAknSCTCategoryButtonPicto:
       
  1994                 if (iExtension->iPictographsBuffer)
       
  1995                     {
       
  1996                     allowCreation = ETrue;
       
  1997                     }
       
  1998                 break;
       
  1999             case EAknSCTCategoryButtonPicto1:
       
  2000             case EAknSCTCategoryButtonPicto2:
       
  2001                 if (iExtension->iPictographsBuffer &&
       
  2002                     iExtension->iPictographsBufferGrouping)
       
  2003                     {
       
  2004                     allowCreation = ETrue;
       
  2005                     }
       
  2006                 break;
       
  2007             default:
       
  2008                 break;
       
  2009             }
       
  2010 
       
  2011         if (allowCreation)
       
  2012             {
       
  2013             // read the button resource
       
  2014             resId = aReader.ReadInt32();
       
  2015             iCoeEnv->CreateResourceReaderLC( reader, resId );
       
  2016             // create Category button object
       
  2017             buttonObj = CAknSctCategoryButton::NewL(
       
  2018                 *this, reader, categorybutton_id, sctcase_id);
       
  2019             // Append button
       
  2020             iButtonArray.Append(buttonObj);
       
  2021             CleanupStack::PopAndDestroy(); // reader
       
  2022             }
       
  2023         else
       
  2024             {
       
  2025             // Skip data
       
  2026             resId = aReader.ReadInt32();
       
  2027             }
       
  2028         }
       
  2029 
       
  2030     }
       
  2031 
       
  2032 void CAknSctRadioButton::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
  2033     {
       
  2034     TRect rect(Rect());
       
  2035     if (AknLayoutUtils::PenEnabled() && rect.Contains(aPointerEvent.iPosition))
       
  2036         {
       
  2037         if (aPointerEvent.iType == TPointerEvent::EButton1Down)
       
  2038             {
       
  2039             CAknButton* buttonCtrlObj;
       
  2040             TRect rectButton;
       
  2041             TInt currentIndex;
       
  2042             TInt newIndex;
       
  2043             for (TInt index=0; index < iButtonArray.Count(); index++)
       
  2044                 {
       
  2045                 buttonCtrlObj = iButtonArray[index]->iButtonControl;
       
  2046                 rectButton = buttonCtrlObj->Rect();
       
  2047                 currentIndex = buttonCtrlObj->StateIndex();
       
  2048 
       
  2049                 if (rectButton.Contains(aPointerEvent.iPosition))
       
  2050                     {
       
  2051                     newIndex = KAknSctRadioOn;
       
  2052                     }
       
  2053                 else
       
  2054                     {
       
  2055                     newIndex = KAknSctRadioOff;
       
  2056                     }
       
  2057                 if (currentIndex != newIndex)
       
  2058                     {
       
  2059                     buttonCtrlObj->SetCurrentState(newIndex, ETrue);
       
  2060                     if (newIndex == KAknSctRadioOn)
       
  2061                         {
       
  2062                         if (AknLayoutUtils::PenEnabled())
       
  2063                             {
       
  2064                             iButtonIndex = index;
       
  2065                             }
       
  2066                         iExtension->iCurrentCategory =
       
  2067                             iButtonArray[index]->iButtonId;
       
  2068                         iCharMap->SetStatusChanged(EAknCharChangedCategory);
       
  2069                         }
       
  2070                     }
       
  2071                 }
       
  2072             }
       
  2073         else if (aPointerEvent.iType == TPointerEvent::EDrag)
       
  2074             {
       
  2075             }
       
  2076         else if (aPointerEvent.iType == TPointerEvent::EButton1Up)
       
  2077             {
       
  2078             }
       
  2079         }
       
  2080     else
       
  2081         {
       
  2082         CCoeControl::HandlePointerEventL(aPointerEvent);
       
  2083         }
       
  2084     }
       
  2085 
       
  2086 TSize CAknSctRadioButton::MinimumSize()
       
  2087     {
       
  2088     TAknLayoutRect oneButtonLayRect;
       
  2089     if (!AknLayoutUtils::PenEnabled())
       
  2090         {
       
  2091         TAknLayoutScalableParameterLimits charMapDialogVariety =
       
  2092             AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
       
  2093 
       
  2094         // Main pane without softkeys
       
  2095         TRect mainPaneRect;
       
  2096         if(!AknLayoutUtils::LayoutMetricsRect(
       
  2097             AknLayoutUtils::EPopupParent, mainPaneRect))
       
  2098             {
       
  2099             mainPaneRect = iAvkonAppUi->ClientRect();
       
  2100             }
       
  2101 
       
  2102         // Calc the variety
       
  2103         TInt maxVariety = charMapDialogVariety.LastVariety();
       
  2104 
       
  2105         TAknLayoutRect popupGridLayRect;
       
  2106         popupGridLayRect.LayoutRect(mainPaneRect,
       
  2107             AknLayoutScalable_Avkon::popup_grid_graphic_window(maxVariety));
       
  2108 
       
  2109         // Calculate the size relatively
       
  2110         TRect relativeDialog(TPoint(0,0),popupGridLayRect.Rect().Size());
       
  2111 
       
  2112         // Get the layout of the actual character grid with scrollbar
       
  2113         TAknLayoutRect gridWithScrollLayRect;
       
  2114         gridWithScrollLayRect.LayoutRect(relativeDialog,
       
  2115             AknLayoutScalable_Avkon::listscroll_popup_graphic_pane());
       
  2116 
       
  2117         TAknLayoutRect categoryButtonLayRect;
       
  2118         categoryButtonLayRect.LayoutRect(gridWithScrollLayRect.Rect(),
       
  2119             AknLayoutScalable_Avkon::grid_sct_catagory_button_pane());
       
  2120 
       
  2121         oneButtonLayRect.LayoutRect(categoryButtonLayRect.Rect(),
       
  2122             AknLayoutScalable_Avkon::cell_sct_catagory_button_pane());
       
  2123         }
       
  2124     else
       
  2125         {
       
  2126         TAknLayoutRect popupGridLayRect;
       
  2127         popupGridLayRect.LayoutRect(iAvkonAppUi->ApplicationRect(),
       
  2128             AknLayoutScalable_Avkon::popup_grid_graphic2_window(0));
       
  2129 
       
  2130         TAknLayoutRect oneButtonLayRect;
       
  2131         TAknLayoutRect categoryButtonLayRect;
       
  2132         if (!Layout_Meta_Data::IsLandscapeOrientation())
       
  2133             {
       
  2134             oneButtonLayRect.LayoutRect(popupGridLayRect.Rect(),
       
  2135                 AknLayoutScalable_Avkon::grid_graphic2_control_pane(4));
       
  2136 
       
  2137             categoryButtonLayRect.LayoutRect(popupGridLayRect.Rect(),
       
  2138                 AknLayoutScalable_Avkon::grid_graphic2_catg_pane(0));
       
  2139             }
       
  2140         else
       
  2141             {
       
  2142             oneButtonLayRect.LayoutRect(popupGridLayRect.Rect(),
       
  2143                 AknLayoutScalable_Avkon::grid_graphic2_control_pane(5));
       
  2144 
       
  2145             categoryButtonLayRect.LayoutRect(popupGridLayRect.Rect(),
       
  2146                 AknLayoutScalable_Avkon::grid_graphic2_catg_pane(1));
       
  2147 
       
  2148             }
       
  2149         }
       
  2150 
       
  2151     TSize size(oneButtonLayRect.Rect().Width(),
       
  2152         oneButtonLayRect.Rect().Height() * iButtonArray.Count());
       
  2153     return size;
       
  2154     }
       
  2155 
       
  2156 void CAknSctRadioButton::SizeChanged()
       
  2157     {
       
  2158     TRect base;
       
  2159     if (!AknLayoutUtils::PenEnabled())
       
  2160         {
       
  2161         TAknLayoutScalableParameterLimits charMapDialogVariety =
       
  2162             AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
       
  2163 
       
  2164         // Main pane without softkeys
       
  2165         TRect mainPaneRect;
       
  2166         if(!AknLayoutUtils::LayoutMetricsRect(
       
  2167             AknLayoutUtils::EPopupParent, mainPaneRect))
       
  2168             {
       
  2169             mainPaneRect = iAvkonAppUi->ClientRect();
       
  2170             }
       
  2171 
       
  2172         // Calc the variety
       
  2173         TInt maxVariety = charMapDialogVariety.LastVariety();
       
  2174 
       
  2175         TAknLayoutRect popupGridLayRect;
       
  2176         popupGridLayRect.LayoutRect(mainPaneRect,
       
  2177             AknLayoutScalable_Avkon::popup_grid_graphic_window(maxVariety));
       
  2178 
       
  2179         // Calculate the size relatively
       
  2180         TRect relativeDialog(TPoint(0,0), popupGridLayRect.Rect().Size());
       
  2181 
       
  2182         // Get the layout of the actual character grid with scrollbar
       
  2183         TAknLayoutRect gridWithScrollLayRect;
       
  2184         gridWithScrollLayRect.LayoutRect(relativeDialog,
       
  2185             AknLayoutScalable_Avkon::listscroll_popup_graphic_pane());
       
  2186 
       
  2187         TAknLayoutRect categoryButtonLayRect;
       
  2188         categoryButtonLayRect.LayoutRect(gridWithScrollLayRect.Rect(),
       
  2189             AknLayoutScalable_Avkon::grid_sct_catagory_button_pane());
       
  2190 
       
  2191         TAknLayoutRect oneButtonLayRect;
       
  2192         oneButtonLayRect.LayoutRect(categoryButtonLayRect.Rect(),
       
  2193             AknLayoutScalable_Avkon::cell_sct_catagory_button_pane());
       
  2194 
       
  2195         base = oneButtonLayRect.Rect();
       
  2196         }
       
  2197     else
       
  2198         {
       
  2199         TAknLayoutRect popupGridLayRect;
       
  2200         popupGridLayRect.LayoutRect(iAvkonAppUi->ApplicationRect(),
       
  2201             AknLayoutScalable_Avkon::popup_grid_graphic2_window(0));
       
  2202 
       
  2203         TAknLayoutRect oneButtonLayRect;
       
  2204         TAknLayoutRect categoryButtonLayRect;
       
  2205         if ( !Layout_Meta_Data::IsLandscapeOrientation() )
       
  2206             {
       
  2207             oneButtonLayRect.LayoutRect(popupGridLayRect.Rect(),
       
  2208                 AknLayoutScalable_Avkon::grid_graphic2_control_pane(4));
       
  2209 
       
  2210             categoryButtonLayRect.LayoutRect(popupGridLayRect.Rect(),
       
  2211                 AknLayoutScalable_Avkon::grid_graphic2_catg_pane(0));
       
  2212             }
       
  2213         else
       
  2214             {
       
  2215             oneButtonLayRect.LayoutRect(popupGridLayRect.Rect(),
       
  2216                 AknLayoutScalable_Avkon::grid_graphic2_control_pane(5));
       
  2217 
       
  2218             categoryButtonLayRect.LayoutRect(popupGridLayRect.Rect(),
       
  2219                 AknLayoutScalable_Avkon::grid_graphic2_catg_pane(1));
       
  2220 
       
  2221             }
       
  2222         base.iTl = categoryButtonLayRect.Rect().iTl;
       
  2223         base.SetSize(oneButtonLayRect.Rect().Size());
       
  2224         }
       
  2225 
       
  2226     if (iButtonArray.Count() > 0)
       
  2227         {
       
  2228         CAknButton* buttonCtrlObj;
       
  2229 
       
  2230         TMargins8 margins;
       
  2231         margins.iTop = 1;
       
  2232         margins.iBottom = 0;
       
  2233         margins.iLeft = 0;
       
  2234         margins.iRight = 0;
       
  2235 
       
  2236         // Change the size of buttons
       
  2237         for (TInt index=0; index < iButtonArray.Count(); index++)
       
  2238             {
       
  2239             buttonCtrlObj = iButtonArray[index]->iButtonControl;
       
  2240             if (buttonCtrlObj)
       
  2241                 {
       
  2242                 if (AknLayoutUtils::PenEnabled())
       
  2243                     {
       
  2244                     buttonCtrlObj->SetHighlightRect(base);
       
  2245                     }
       
  2246                 buttonCtrlObj->SetRect( base );
       
  2247                 buttonCtrlObj->SetIconSize( base.Size() );
       
  2248                 buttonCtrlObj->SetMargins( margins );
       
  2249                 buttonCtrlObj->SetIconScaleMode(EAspectRatioPreserved);
       
  2250                 base.Move(TPoint(0, base.Size().iHeight));
       
  2251                 }
       
  2252             }
       
  2253         }
       
  2254     }
       
  2255 
       
  2256 void CAknSctRadioButton::Draw(const TRect& /*aRect*/) const
       
  2257     {
       
  2258     // no draw
       
  2259     }
       
  2260 
       
  2261 /**
       
  2262  * Returns ETrue if the aFlag bitfield in iFlags is set, EFalse if it
       
  2263  * is clear
       
  2264  */
       
  2265 inline TInt CAknSctRadioButton::Count() const
       
  2266     {
       
  2267     return iButtonArray.Count();
       
  2268     }
       
  2269 
       
  2270 void CAknSctRadioButton::SetCurrentCategory(TInt aCategory)
       
  2271     {
       
  2272     CAknSctCategoryButton* buttonObj;
       
  2273     TInt status;
       
  2274 
       
  2275     for (TInt index=0; index < iButtonArray.Count(); index++)
       
  2276         {
       
  2277         buttonObj = iButtonArray[index];
       
  2278         status = (buttonObj->iButtonId == aCategory)?
       
  2279                      KAknSctRadioOn : KAknSctRadioOff;
       
  2280         buttonObj->iButtonControl->SetCurrentState(status, ETrue);
       
  2281         }
       
  2282     }
       
  2283 
       
  2284 void CAknSctRadioButton::SetValidSctCase(TInt aSctCase)
       
  2285     {
       
  2286     CAknSctCategoryButton* buttonObj;
       
  2287 
       
  2288     for (TInt index=0; index < iButtonArray.Count(); index++)
       
  2289         {
       
  2290         buttonObj = iButtonArray[index];
       
  2291         if (buttonObj->iSctCaseId == aSctCase)
       
  2292             {
       
  2293             buttonObj->iValid = ETrue;
       
  2294             break;
       
  2295             }
       
  2296         // Here is the special case for Half-width/Lower/Upper
       
  2297         else if (buttonObj->iSctCaseId == EAknSCTHalfCase
       
  2298               && (aSctCase == EAknSCTLowerCase
       
  2299                  || aSctCase == EAknSCTUpperCase)
       
  2300                 )
       
  2301             {
       
  2302             buttonObj->iValid = ETrue;
       
  2303             break;
       
  2304             }
       
  2305         }
       
  2306     }
       
  2307 
       
  2308 void CAknSctRadioButton::RemoveInvalidButton()
       
  2309     {
       
  2310     CAknSctCategoryButton* buttonObj;
       
  2311 
       
  2312     for (TInt index=iButtonArray.Count()-1; index >= 0; index--)
       
  2313         {
       
  2314         buttonObj = iButtonArray[index];
       
  2315         if (!buttonObj->iValid)
       
  2316             {
       
  2317             if (buttonObj->iSctCaseId == EAknSCTHalfCase)
       
  2318                 {
       
  2319                 if (iButtonArray.Count() > 1)
       
  2320                     {
       
  2321                     delete buttonObj;
       
  2322                     iButtonArray.Remove(index);
       
  2323                     }
       
  2324                 }
       
  2325             else
       
  2326                 {
       
  2327                 delete buttonObj;
       
  2328                 iButtonArray.Remove(index);
       
  2329                 }
       
  2330             }
       
  2331         }
       
  2332     }
       
  2333 
       
  2334 CCoeControl* CAknSctRadioButton::FocusedControl()
       
  2335     {
       
  2336     return this;
       
  2337     }
       
  2338 
       
  2339 TBool CAknSctRadioButton::EnterControl(TInt /*aX*/, TInt aY)
       
  2340     {
       
  2341     if (IsVisible())
       
  2342         {
       
  2343         if ((aY >= 0) && (aY < Count()))
       
  2344             {
       
  2345             if (iExtension->iHasCategoryButtonUi)
       
  2346                 {
       
  2347                 iEntryIndex = aY;
       
  2348                 iExtension->iFocusHandler = this;
       
  2349                 if (AknLayoutUtils::PenEnabled())
       
  2350                     {
       
  2351                     iButtonIndex = aY;
       
  2352                     CAknSctCategoryButton* buttonObj =
       
  2353                         iButtonArray[iButtonIndex];
       
  2354                     buttonObj->SetFocused(ETrue);
       
  2355                     }
       
  2356                 return ETrue;
       
  2357                 }
       
  2358             }
       
  2359         }
       
  2360     return EFalse;
       
  2361     }
       
  2362 
       
  2363 void CAknSctRadioButton::MoveFocus(TInt /*aX*/, TInt aY)
       
  2364     {
       
  2365     CAknSctCategoryButton* buttonObj;
       
  2366     CAknButton* buttonCtrlObj;
       
  2367     TInt buttonIndex = iButtonIndex + aY;
       
  2368     if (buttonIndex > iButtonArray.Count() - 1)
       
  2369         {
       
  2370         if (!AknLayoutUtils::PenEnabled())
       
  2371             {
       
  2372              // First radio button.
       
  2373             buttonIndex = 0;
       
  2374             }
       
  2375         else
       
  2376             {
       
  2377             if (!Layout_Meta_Data::IsLandscapeOrientation())
       
  2378                 {
       
  2379                 // Left page button.
       
  2380                 if (iExtension->iPageNavi &&
       
  2381                     iExtension->iPageNavi->EnterControl(0,0))
       
  2382                     {
       
  2383                     LeaveControl();
       
  2384                     return;
       
  2385                     }
       
  2386                 }
       
  2387             else
       
  2388                 {
       
  2389                 // First table button.
       
  2390                 if (iExtension->iTableNavi &&
       
  2391                     iExtension->iTableNavi->EnterControl(0,0))
       
  2392                     {
       
  2393                     LeaveControl();
       
  2394                     return;
       
  2395                     }
       
  2396                 }
       
  2397             }
       
  2398         }
       
  2399     else if (buttonIndex < 0)
       
  2400         {
       
  2401          if (!AknLayoutUtils::PenEnabled())
       
  2402             {
       
  2403             // Last radio button.
       
  2404             buttonIndex = iButtonArray.Count() - 1;
       
  2405             }
       
  2406          else
       
  2407             {
       
  2408             // First table button.
       
  2409             if (iExtension->iTableNavi &&
       
  2410                 iExtension->iTableNavi->EnterControl(0,0))
       
  2411                 {
       
  2412                 LeaveControl();
       
  2413                 return;
       
  2414                 }
       
  2415             }
       
  2416         }
       
  2417 
       
  2418     if (!AknLayoutUtils::PenEnabled())
       
  2419         {
       
  2420         buttonObj = iButtonArray[iButtonIndex];
       
  2421         buttonCtrlObj = buttonObj->iButtonControl;
       
  2422         buttonCtrlObj->SetCurrentState(KAknSctRadioOff, ETrue);
       
  2423         iButtonIndex = buttonIndex;
       
  2424         buttonObj = iButtonArray[iButtonIndex];
       
  2425         buttonCtrlObj = buttonObj->iButtonControl;
       
  2426         buttonCtrlObj->SetCurrentState(KAknSctRadioOn, ETrue);
       
  2427         iExtension->iCurrentCategory =
       
  2428             iButtonArray[buttonIndex]->iButtonId;
       
  2429         iCharMap->SetStatusChanged(EAknCharChangedCategory);
       
  2430         }
       
  2431     else
       
  2432         {
       
  2433         buttonObj = iButtonArray[iButtonIndex];
       
  2434         buttonObj->SetFocused(EFalse);
       
  2435         iButtonIndex = buttonIndex;
       
  2436         buttonObj = iButtonArray[iButtonIndex];
       
  2437         buttonObj->SetFocused(ETrue);
       
  2438         }
       
  2439     }
       
  2440 
       
  2441 TBool CAknSctRadioButton::LeaveControl()
       
  2442     {
       
  2443     for (TInt i = 0; i < iButtonArray.Count(); i++ )
       
  2444         {
       
  2445         iButtonArray[i]->SetFocused(EFalse);
       
  2446         }
       
  2447     return ETrue;
       
  2448     }
       
  2449 
       
  2450 TBool CAknSctRadioButton::ExitWithKey(TInt /*aKeycode*/)
       
  2451     {
       
  2452     return EFalse;
       
  2453     }
       
  2454 
       
  2455 // ----------------------------------------------------------------------------
       
  2456 // Extension class implementation
       
  2457 // ----------------------------------------------------------------------------
       
  2458 //
       
  2459 CAknCharMapExtension::CAknCharMapExtension() : iSmileyModel(this)
       
  2460 ,iSingleClickEnabled( iAvkonAppUi->IsSingleClickCompatible() )
       
  2461     {
       
  2462     iObserver = NULL;
       
  2463     iPictographsBuffer = FeatureManager::FeatureSupported(KFeatureIdJapanesePicto);
       
  2464     iPictographsBufferGrouping = FeatureManager::FeatureSupported(KFeatureIdJapanesePictographsGrouping);
       
  2465     iKineticScrolling = CAknPhysics::FeatureEnabled();
       
  2466 
       
  2467     TRAP_IGNORE(iSmileyModel.LoadResourceL());
       
  2468     }
       
  2469 
       
  2470 TTypeUid::Ptr CAknCharMapExtension::MopSupplyObject(TTypeUid aId)
       
  2471     {
       
  2472     return MAknsControlContext::SupplyMopObject(aId, iBgContext );
       
  2473     }
       
  2474 
       
  2475 MObjectProvider* CAknCharMapExtension::MopNext()
       
  2476     {
       
  2477     return iCharMap;
       
  2478     }
       
  2479 
       
  2480 CAknCharMapExtension::~CAknCharMapExtension()
       
  2481     {
       
  2482     delete iCharsSmiley;
       
  2483     delete iCharsQwerty;
       
  2484     delete iBgContext;
       
  2485 
       
  2486     delete iRadioButton;
       
  2487     delete iTitleBuf;
       
  2488 
       
  2489     delete iPageNavi;
       
  2490     delete iTableNavi;
       
  2491     delete iCategoryTitle;
       
  2492     delete iCategoryEntry;
       
  2493     delete iEntryBuf;
       
  2494     }
       
  2495 
       
  2496 void CAknCharMapExtension::SetCharMapControl(CAknCharMap* aCtrl)
       
  2497     {
       
  2498     iCharMapProxy = aCtrl;
       
  2499     }
       
  2500 
       
  2501 MAknSctFocusHandler* CAknCharMapExtension::FocusHandler()
       
  2502     {
       
  2503     return iFocusHandler;
       
  2504     }
       
  2505 
       
  2506 CCoeControl* CAknCharMapExtension::FocusedControl()
       
  2507     {
       
  2508     return iCharMapProxy;
       
  2509     }
       
  2510 
       
  2511 TBool CAknCharMapExtension::EnterControl(TInt aX, TInt aY)
       
  2512     {
       
  2513     if(iCharMapProxy->EnterControl(aX, aY))
       
  2514         {
       
  2515         iFocusHandler = this;
       
  2516         iCharMapProxy->HandleFocusStatusChanged();
       
  2517         return ETrue;
       
  2518         }
       
  2519     else
       
  2520         {
       
  2521         return EFalse;
       
  2522         }
       
  2523     }
       
  2524 
       
  2525 void CAknCharMapExtension::MoveFocus(TInt aX, TInt aY)
       
  2526     {
       
  2527     iCharMapProxy->TakeFocus();
       
  2528     TRAP_IGNORE(iCharMapProxy->MoveFocus(aX, aY));
       
  2529     }
       
  2530 
       
  2531 TBool CAknCharMapExtension::LeaveControl()
       
  2532     {
       
  2533     return iCharMapProxy->LeaveControl();
       
  2534     }
       
  2535 
       
  2536 TBool CAknCharMapExtension::ExitWithKey(TInt /*aKeycode*/)
       
  2537     {
       
  2538     return ETrue;
       
  2539     }
       
  2540 
       
  2541 void CAknCharMapExtension::ThumbnailLoaded(CSmileyIcon* /*aSmileyIcon*/)
       
  2542     {
       
  2543     iCharMapProxy->DrawDeferred();
       
  2544     }
       
  2545 
       
  2546 void CAknCharMapExtension::AnimationChanged(CSmileyIcon* /*aSmileyIcon*/)
       
  2547     {
       
  2548     iCharMapProxy->DrawCursor();
       
  2549     }
       
  2550 
       
  2551 TBool CAknCharMapExtension::IsEmotionEnabled() const
       
  2552     {
       
  2553     return iIsEnableEmotion;
       
  2554     }
       
  2555 
       
  2556 TBool CAknCharMapExtension::IsShowingEmotion() const
       
  2557     {
       
  2558     return iIsShowingEmotion;
       
  2559     }
       
  2560 
       
  2561 TBool CAknCharMapExtension::NeedEmotionSwitchIcon() const
       
  2562     {
       
  2563     // Emotion switch char
       
  2564     TBool needEmotionSwitchIcon = (!AknLayoutUtils::PenEnabled() && IsEmotionEnabled() && !iMenuSct);
       
  2565     return needEmotionSwitchIcon;
       
  2566     }
       
  2567 
       
  2568 HBufC* CAknCharMapExtension::ReadEmotionHBufCL()
       
  2569     {
       
  2570     TInt smileyCount = iSmileyModel.Count();
       
  2571     HBufC* charsSmiley = HBufC::NewL(smileyCount);
       
  2572     TPtr charsSmileyPtr(charsSmiley->Des());
       
  2573     for(TInt id(CSmileyModel::EIconSmiley); id<smileyCount; id++)
       
  2574         {
       
  2575         charsSmileyPtr.Append(TEmotionUtils::EmotionChar(id));
       
  2576         }
       
  2577     
       
  2578     return charsSmiley;
       
  2579     }
       
  2580 
       
  2581 void CAknCharMapExtension::LoadEmotionTumbnails(const TDesC& aSctChars)
       
  2582     {
       
  2583     for(TInt i(0); i<aSctChars.Length(); i++)
       
  2584         {
       
  2585         iSmileyModel.LoadThumbnailAsyn(TEmotionUtils::EmotionId(aSctChars[i]));
       
  2586         }
       
  2587     }
       
  2588 
       
  2589 void CAknCharMapExtension::SetEmotionSize(const TSize& aSize)
       
  2590     {
       
  2591     TInt unit = Min(aSize.iWidth, aSize.iHeight);
       
  2592     iSmileyModel.SetSize(TSize(unit,unit));
       
  2593     }
       
  2594 
       
  2595 CSmileyIcon* CAknCharMapExtension::EmotionIcon(TChar aEmotionChar)
       
  2596     {
       
  2597     if(TEmotionUtils::IsEmotionChar(aEmotionChar))
       
  2598         {
       
  2599         return iSmileyModel[TEmotionUtils::EmotionId(aEmotionChar)];
       
  2600         }
       
  2601     else
       
  2602         {
       
  2603         return NULL;
       
  2604         }
       
  2605     }
       
  2606 
       
  2607 TBool CAknCharMapExtension::DrawEmotion(CWindowGc& aGc, const TRect& aRect, TChar aEmotionChar)
       
  2608     {
       
  2609     CSmileyIcon* icon = EmotionIcon(aEmotionChar);
       
  2610     if(icon && icon->ReadyToDraw())
       
  2611         {
       
  2612         TRect iconRect(TPoint(),icon->Size());
       
  2613         TInt xoffset = (aRect.Width() - iconRect.Width()) / 2;
       
  2614         TInt yoffset = (aRect.Height() - iconRect.Height()) / 2;
       
  2615 
       
  2616         aGc.BitBltMasked(aRect.iTl+TPoint(xoffset,yoffset), icon->Image(), iconRect, icon->Mask(), FALSE);
       
  2617         return ETrue;
       
  2618         }
       
  2619     else
       
  2620         {
       
  2621         return EFalse;
       
  2622         }
       
  2623     }
       
  2624 
       
  2625 const TInt KEmotionAnimationRepeatCount = 30; // 30 times
       
  2626 const TInt KEmotionAnimationDelay = 150*1000; // 0.15s
       
  2627 
       
  2628 void CAknCharMapExtension::HandleFocusStatusChanged(TChar aChar, TBool aIsFocused)
       
  2629     {
       
  2630     CSmileyIcon* lastIcon = EmotionIcon(iLastFocusedSmileyChar);
       
  2631     if(lastIcon)
       
  2632         {
       
  2633         lastIcon->StopAnimation();
       
  2634         }
       
  2635     
       
  2636     CSmileyIcon* focusedIcon = EmotionIcon(aChar);
       
  2637     if(focusedIcon)
       
  2638         {
       
  2639         if(aIsFocused)
       
  2640             {
       
  2641             if(iHighlightVisible)
       
  2642                 {
       
  2643                 TRAP_IGNORE(focusedIcon->PlayAnimationL(KEmotionAnimationRepeatCount, KEmotionAnimationDelay));
       
  2644                 }
       
  2645             }
       
  2646         else
       
  2647             {
       
  2648             focusedIcon->StopAnimation();
       
  2649             }
       
  2650         }
       
  2651     
       
  2652     iLastFocusedSmileyChar = aChar;
       
  2653     }
       
  2654 
       
  2655 
       
  2656 // ============================ MEMBER FUNCTIONS ===============================
       
  2657 
       
  2658 // -----------------------------------------------------------------------------
       
  2659 // CAknCharMapHistory::NewL
       
  2660 // Two-phased constructor.
       
  2661 // -----------------------------------------------------------------------------
       
  2662 //
       
  2663 CAknCharMapHistory* CAknCharMapHistory::NewL()
       
  2664     {
       
  2665     CAknCharMapHistory* self = new (ELeave) CAknCharMapHistory;
       
  2666     CleanupStack::PushL(self);
       
  2667     self->ConstructL();
       
  2668     CleanupStack::Pop();
       
  2669     return self;
       
  2670     }
       
  2671 
       
  2672 // -----------------------------------------------------------------------------
       
  2673 // CAknCharMapHistory::ConstructL
       
  2674 // Symbian 2nd phase constructor can leave.
       
  2675 // -----------------------------------------------------------------------------
       
  2676 //
       
  2677 void CAknCharMapHistory::ConstructL()
       
  2678     {
       
  2679     LoadL();
       
  2680     }
       
  2681 
       
  2682 // -----------------------------------------------------------------------------
       
  2683 // CAknCharMapHistory::CAknCharMapHistory
       
  2684 // C++ default constructor can NOT contain any code, that
       
  2685 // might leave.
       
  2686 // -----------------------------------------------------------------------------
       
  2687 //
       
  2688 CAknCharMapHistory::CAknCharMapHistory()
       
  2689     {
       
  2690     }
       
  2691 
       
  2692 // Destructor
       
  2693 CAknCharMapHistory::~CAknCharMapHistory()
       
  2694     {
       
  2695     ResetArray();
       
  2696     }
       
  2697 
       
  2698 // -----------------------------------------------------------------------------
       
  2699 // CAknCharMapHistory::LoadL()
       
  2700 // Load recent characters from file
       
  2701 // -----------------------------------------------------------------------------
       
  2702 //
       
  2703 TInt CAknCharMapHistory::LoadL()
       
  2704     {
       
  2705     // get the value of recently characters
       
  2706     const TInt length = KHistoryBufferSize * KHistoryBufferCount;
       
  2707     TBuf<length> buf;
       
  2708 
       
  2709     CRepository* repository = CRepository::NewLC(KCRUidAvkon);
       
  2710     TInt err = repository->Get(KAknRecentSctData, buf); // Get KAknRecentSctData value
       
  2711     if (err == KErrNone)
       
  2712         {
       
  2713         if (buf.Length() != length) // buffer is not wanted
       
  2714             {
       
  2715             buf.Fill(KHistoryEmptyChar, length); // set default characters (default=tab character)
       
  2716             err = repository->Set(KAknRecentSctData, buf); // Create KAknRecentSctData key
       
  2717             }
       
  2718         }
       
  2719     CleanupStack::PopAndDestroy(repository); // repository
       
  2720     
       
  2721     // reset arrary
       
  2722     ResetArray();
       
  2723 
       
  2724     // set recently characters to array
       
  2725     TInt parsePos = 0;
       
  2726     for (TInt i=0; i<EHistoryTypeMax; i++)
       
  2727         {
       
  2728         if (err != KErrNone)
       
  2729             {
       
  2730             // if err occurs, empty characters are set to recently characters.
       
  2731             iMixedHistoryArray[i].Fill(KHistoryEmptyChar, KHistoryBufferSize);
       
  2732             iTextHistoryArray[i].Fill(KHistoryEmptyChar, KHistoryBufferSize);
       
  2733             }
       
  2734         else
       
  2735             {
       
  2736             // parse from buf
       
  2737             iMixedHistoryArray[i].Copy(buf.Mid(parsePos, KHistoryBufferSize)); // mixed 
       
  2738             parsePos += KHistoryBufferSize;
       
  2739             
       
  2740             iTextHistoryArray[i].Copy(buf.Mid(parsePos, KHistoryBufferSize)); // text
       
  2741             parsePos += KHistoryBufferSize;
       
  2742             }
       
  2743         }
       
  2744 
       
  2745     if (err != KErrNone)
       
  2746         {
       
  2747         iEmotionHistory.Fill(KHistoryEmptyChar, KHistoryBufferSize);
       
  2748         }
       
  2749     else
       
  2750         {
       
  2751         // parse from buf
       
  2752         iEmotionHistory.Copy(buf.Mid(parsePos, KHistoryBufferSize));
       
  2753         }
       
  2754 
       
  2755     return KErrNone;
       
  2756     }
       
  2757 
       
  2758 // -----------------------------------------------------------------------------
       
  2759 // CAknCharMapHistory::ResetArray()
       
  2760 // Reset recent arrary
       
  2761 // -----------------------------------------------------------------------------
       
  2762 //
       
  2763 void CAknCharMapHistory::ResetArray()
       
  2764     {
       
  2765     for(TInt i=0; i<EHistoryTypeMax; i++)
       
  2766         {
       
  2767         iMixedHistoryArray[i].Zero();
       
  2768         iTextHistoryArray[i].Zero();
       
  2769         }
       
  2770 
       
  2771     iEmotionHistory.Zero();
       
  2772     }
       
  2773 
       
  2774 // -----------------------------------------------------------------------------
       
  2775 // CAknCharMapHistory::SaveL()
       
  2776 // Save recent characters
       
  2777 // -----------------------------------------------------------------------------
       
  2778 //
       
  2779 TInt CAknCharMapHistory::SaveL()
       
  2780     {
       
  2781     // save all recent used characters to buffer
       
  2782     const TInt length = KHistoryBufferSize * KHistoryBufferCount;
       
  2783     TBuf<length> buf;
       
  2784     
       
  2785     for (TInt i=0; i<EHistoryTypeMax; i++)
       
  2786         {
       
  2787         buf.Append(iMixedHistoryArray[i]);
       
  2788         buf.Append(iTextHistoryArray[i]);
       
  2789         }
       
  2790     
       
  2791     buf.Append(iEmotionHistory);
       
  2792 
       
  2793     // Set KAknRecentSctData value
       
  2794     CRepository* repository = CRepository::NewLC(KCRUidAvkon);
       
  2795     TInt err = repository->Set(KAknRecentSctData, buf);
       
  2796     CleanupStack::PopAndDestroy(repository); // repository
       
  2797     
       
  2798     return err;
       
  2799     }
       
  2800 
       
  2801 // -----------------------------------------------------------------------------
       
  2802 // CAknCharMapHistory::RecentString()
       
  2803 // Get recent data
       
  2804 // -----------------------------------------------------------------------------
       
  2805 //
       
  2806 const TDesC& CAknCharMapHistory::RecentString(THistoryType aHistoryType, THistoryFilter aHistoryFilter)
       
  2807     {
       
  2808     __ASSERT_ALWAYS((EHistoryTypeFull<=aHistoryType && aHistoryType<EHistoryTypeMax), Panic(EAknPanicInvalidValue));
       
  2809     
       
  2810     switch(aHistoryFilter)
       
  2811         {
       
  2812         case EHistoryFilterMixed:
       
  2813             break;
       
  2814             
       
  2815         case EHistoryFilterTextOnly:
       
  2816             return iTextHistoryArray[aHistoryType];
       
  2817             
       
  2818         case EHistoryFilterEmotionOnly:
       
  2819             return iEmotionHistory;
       
  2820 
       
  2821         default:
       
  2822             break;
       
  2823         }
       
  2824     
       
  2825     return iMixedHistoryArray[aHistoryType];
       
  2826     }
       
  2827 
       
  2828 // -----------------------------------------------------------------------------
       
  2829 // CAknCharMapHistory::InsertChar()
       
  2830 // Insert a character which select on SCT/Picto.
       
  2831 // -----------------------------------------------------------------------------
       
  2832 //
       
  2833 void CAknCharMapHistory::InsertChar(THistoryType aHistoryType, const TChar aChar)
       
  2834     {
       
  2835     __ASSERT_ALWAYS((EHistoryTypeFull<=aHistoryType && aHistoryType<EHistoryTypeMax), Panic(EAknPanicInvalidValue));
       
  2836 
       
  2837     InsertCharToHistoryBuf(iMixedHistoryArray[aHistoryType], aChar);
       
  2838 
       
  2839     if(TEmotionUtils::IsEmotionChar(aChar))
       
  2840         {
       
  2841         InsertCharToHistoryBuf(iEmotionHistory, aChar);
       
  2842         }
       
  2843     else
       
  2844         {
       
  2845         InsertCharToHistoryBuf(iTextHistoryArray[aHistoryType], aChar);
       
  2846         }
       
  2847     }
       
  2848 
       
  2849 void CAknCharMapHistory::InsertCharToHistoryBuf(TDes& aHistoryBuf, const TChar aChar)
       
  2850     {
       
  2851     TInt pos = aHistoryBuf.Locate(aChar);
       
  2852     if(pos != 0)
       
  2853         {
       
  2854         if(pos == KErrNotFound)
       
  2855             {
       
  2856             aHistoryBuf.SetLength(aHistoryBuf.Length() - 1);
       
  2857             }
       
  2858         else
       
  2859             {
       
  2860             aHistoryBuf.Delete(pos, 1);
       
  2861             }
       
  2862         
       
  2863         TBuf<1> charBuf;
       
  2864         charBuf.Append(aChar);
       
  2865         aHistoryBuf.Insert(0, charBuf);
       
  2866         }
       
  2867     }
       
  2868 
       
  2869 
       
  2870 // ============================ MEMBER FUNCTIONS ===============================
       
  2871 
       
  2872 // -----------------------------------------------------------------------------
       
  2873 // CAknCharMap::LengthOfRecentChar()
       
  2874 // Get the length of the recent charactors.
       
  2875 // -----------------------------------------------------------------------------
       
  2876 //
       
  2877 TInt CAknCharMap::LengthOfRecentChar()
       
  2878     {
       
  2879     TInt len(0);
       
  2880     if ( iChars != NULL )
       
  2881         {
       
  2882         for ( TInt index=0; index < iMaxColumns; index++ )
       
  2883             {
       
  2884             if ( (*iChars)[index] != KHistoryEmptyChar )
       
  2885                 {
       
  2886                 len++;
       
  2887                 }
       
  2888             else
       
  2889                 {
       
  2890                 break;
       
  2891                 }
       
  2892             }
       
  2893         }
       
  2894     return len;
       
  2895     }
       
  2896 
       
  2897 
       
  2898 EXPORT_C CAknCharMap::CAknCharMap() : iMaxColumns(-1)
       
  2899     {
       
  2900     // Must be created here to get the member variables available
       
  2901     TRAPD(err, iExtension = new (ELeave) CAknCharMapExtension);
       
  2902     iExtension->iCharMap = this;
       
  2903 
       
  2904     if(err)
       
  2905         return;
       
  2906 
       
  2907     iExtension->iFlags = 0x00;
       
  2908 
       
  2909     // if feature language is Japanese
       
  2910     CAknEnv* env = CAknEnv::Static();
       
  2911     if (env)
       
  2912         {
       
  2913         if (env->IsFeatureLanguage(KFeatureIdJapanese))
       
  2914             {
       
  2915             iExtension->iJapaneseSctUi = ETrue;
       
  2916             iExtension->iHasCategoryButtonUi = ETrue;
       
  2917             }
       
  2918         }
       
  2919     iExtension->iFocusHandler = iExtension;
       
  2920     iExtension->SetCharMapControl(this);
       
  2921 	
       
  2922     if ( iExtension->iSingleClickEnabled )
       
  2923         {
       
  2924         iExtension->iHighlightVisible = EFalse;
       
  2925         }
       
  2926     
       
  2927     DoLayout();
       
  2928     
       
  2929     AKNTASHOOK_ADD( this, "CAknCharMap" );
       
  2930     }
       
  2931 
       
  2932 EXPORT_C CAknCharMap::~CAknCharMap()
       
  2933     {
       
  2934     AKNTASHOOK_REMOVE();
       
  2935 
       
  2936     delete iCharsBufferFull;
       
  2937     delete iCharsBufferHalf;
       
  2938     delete iCharsBufferLower;
       
  2939     delete iCharsBufferUpper;
       
  2940     delete iCharsBufferNumeric;
       
  2941     delete iPictographsBuffer;
       
  2942     delete iPictographsBuffer2;
       
  2943     
       
  2944     delete iSBFrame;
       
  2945     delete iPictoInterface;
       
  2946 
       
  2947 
       
  2948     delete iTitleDefault;
       
  2949     delete iTitleFull;
       
  2950     delete iTitleHalf;
       
  2951     delete iTitlePicto;
       
  2952     delete iTitlePicto2;
       
  2953 
       
  2954     // menu sct replaces the iChars with on HBufC
       
  2955     if (iExtension->iFlags & EAknCharMapCharsAllocated) // iChars  contains HBufC
       
  2956         {                                               // so delete it
       
  2957         delete iChars;
       
  2958         }
       
  2959 
       
  2960 
       
  2961     delete iExtension;
       
  2962     delete iCharMapHistory;
       
  2963 
       
  2964     iSpecialCharCases.Close();
       
  2965     iSpecialCharPages.Close();
       
  2966     iPictographCases.Close();
       
  2967     iPictographPages.Close();
       
  2968     MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  2969     feedback->RemoveFeedbackForControl( this );
       
  2970    }
       
  2971 
       
  2972 void CAknCharMap::DoLayout()
       
  2973     {
       
  2974     TAknTextLineLayout specialCharItemLayout;
       
  2975     if (AknLayoutUtils::PenEnabled() && !Extension()->iMenuSct)
       
  2976         {
       
  2977         if ( Layout_Meta_Data::IsLandscapeOrientation() )
       
  2978             {
       
  2979             specialCharItemLayout =
       
  2980                 AknLayoutScalable_Avkon::cell_graphic2_pane_t1(1);
       
  2981             }
       
  2982         else if (IsJapaneseSctUi())
       
  2983             {
       
  2984             specialCharItemLayout =
       
  2985                 AknLayoutScalable_Avkon::cell_graphic2_pane_t1(2);
       
  2986             }
       
  2987         else
       
  2988             {
       
  2989             specialCharItemLayout =
       
  2990                 AknLayoutScalable_Avkon::cell_graphic2_pane_t1(0);
       
  2991             }
       
  2992         }
       
  2993     else
       
  2994         {
       
  2995         specialCharItemLayout =
       
  2996             AknLayoutScalable_Avkon::cell_graphic_popup_pane_t2();
       
  2997         }
       
  2998     iFont = AknLayoutUtils::FontFromId ( specialCharItemLayout.FontId() );
       
  2999     if (iPictoInterface)
       
  3000         {
       
  3001         __ASSERT_ALWAYS(iFont, Panic(EAknPanicNullPointer));
       
  3002         iCurrentPictographHeight = EHeight16;
       
  3003         iPictoInterface->Interface()->SelectPictographHeightForFont(*iFont,iCurrentPictographHeight);
       
  3004         }
       
  3005     iIsMirrored = AknLayoutUtils::LayoutMirrored();
       
  3006     iDrawnBefore = EFalse;
       
  3007     CountMaxColumnsAndCellSizes();
       
  3008     SizeChanged();
       
  3009 
       
  3010     // load Emotion icon resource, but not load images
       
  3011     TSize iconSize(iGridItemWidth,iGridItemHeight);
       
  3012     iconSize.iWidth = iconSize.iWidth * 2 / 3;
       
  3013     iconSize.iHeight = iconSize.iHeight * 2 / 3;
       
  3014     Extension()->SetEmotionSize(iconSize);
       
  3015     }
       
  3016 
       
  3017 
       
  3018 EXPORT_C void CAknCharMap::ConstructFromResourceL(TResourceReader& aReader)
       
  3019     {
       
  3020     CEikDialog* dlg;
       
  3021     MopGetObject(dlg);
       
  3022     CEikDialogExtension* dlgExtension = dlg ? dlg->Extension():NULL;
       
  3023     if (dlgExtension)
       
  3024         {
       
  3025         if (CAknEnv::Static()->TransparencyEnabled())
       
  3026             {
       
  3027             // CAknCharMapDialog doesn't have extension
       
  3028             dlgExtension->iPublicFlags.Set(
       
  3029                 CEikDialogExtension::EClipChildControlRect);
       
  3030             }
       
  3031 
       
  3032         if (AknLayoutUtils::PenEnabled()) // for full screen touch ui.
       
  3033             {
       
  3034             dlgExtension->iPublicFlags.Set(
       
  3035                 CEikDialogExtension::EUseVirtualInput);
       
  3036             }
       
  3037         else
       
  3038             {
       
  3039             dlgExtension->iPublicFlags.Clear(
       
  3040                 CEikDialogExtension::EUseVirtualInput);
       
  3041             }
       
  3042         }
       
  3043 
       
  3044     // Special character set.
       
  3045     ReadCharSetFromResourceL(aReader);
       
  3046 
       
  3047     // Pictograph character set.
       
  3048     TBool offscreen = EFalse;
       
  3049     if ( iExtension->iPictographsBuffer )
       
  3050         {
       
  3051         CreatePictoCharL();
       
  3052         offscreen = ETrue;
       
  3053         }
       
  3054 
       
  3055     SetCharacterCaseL(EAknSCTLowerCase);
       
  3056 
       
  3057     // Recent character set.
       
  3058     if (!iCharMapHistory)
       
  3059         {
       
  3060         iCharMapHistory = CAknCharMapHistory::NewL();
       
  3061         AppendRecentCharL();
       
  3062         }
       
  3063 
       
  3064     // Touch support.
       
  3065     if (AknLayoutUtils::PenEnabled())
       
  3066         {
       
  3067         if ( DrawableWindow() )
       
  3068             {
       
  3069             EnableDragEvents();
       
  3070             SetGloballyCapturing(ETrue);
       
  3071             SetPointerCapture(ETrue);
       
  3072             }
       
  3073         }
       
  3074 
       
  3075     // Alternate components.
       
  3076     if (AknLayoutUtils::PenEnabled())
       
  3077         {
       
  3078         if (iExtension->iHasCategoryButtonUi)
       
  3079             {
       
  3080             EnableCategoryInputFieldL();
       
  3081             EnableCategoryButtonsL();
       
  3082             }
       
  3083         EnableNavigationButtonsL();
       
  3084         }
       
  3085     else
       
  3086         {
       
  3087         if (iExtension->iHasCategoryButtonUi)
       
  3088             {
       
  3089             EnableCategoryButtonsL();
       
  3090             }
       
  3091         }
       
  3092 
       
  3093     // Offscreen background.
       
  3094     if (offscreen)
       
  3095         {
       
  3096         CreateOffscreenBackgroundL();
       
  3097         }
       
  3098 
       
  3099     iExtension->iBgContext = 
       
  3100     CAknsFrameBackgroundControlContext::NewL(KAknsIIDQsnFrPopup, TRect(0,0,1,1), TRect(0,0,1,1), EFalse);
       
  3101     }
       
  3102 
       
  3103 
       
  3104 EXPORT_C TInt CAknCharMap::HeightInRows()
       
  3105     {
       
  3106     return (iShowCasesRef->Count()>1 ? iMaxColumns+1 : iRows);
       
  3107     }
       
  3108 
       
  3109 EXPORT_C void CAknCharMap::SetEmotionModeL(TAknCharMapEmotionMode aEmotionMode)
       
  3110     {
       
  3111     TBool isCurrentEnable = iExtension->iIsEnableEmotion;
       
  3112     
       
  3113     switch(aEmotionMode)
       
  3114         {
       
  3115         case EAknCharMapEmotionUse:
       
  3116             iExtension->iIsShowingEmotion = EFalse;
       
  3117             iExtension->iIsEnableEmotion = ETrue;
       
  3118             break;
       
  3119 
       
  3120         case EAknCharMapEmotionFirst:
       
  3121             iExtension->iIsShowingEmotion = ETrue;
       
  3122             iExtension->iIsEnableEmotion = ETrue;
       
  3123             break;
       
  3124 
       
  3125         default:
       
  3126             iExtension->iIsShowingEmotion = EFalse;
       
  3127             iExtension->iIsEnableEmotion = EFalse;
       
  3128             break;
       
  3129         }
       
  3130 
       
  3131     if(isCurrentEnable!=iExtension->iIsEnableEmotion && iExtension->NeedEmotionSwitchIcon())
       
  3132         {
       
  3133         DisableRecentCharsRow();
       
  3134         AppendRecentCharL();
       
  3135         SetCharacterCaseL(iSpecialCharCase);
       
  3136         }
       
  3137     }
       
  3138 
       
  3139 EXPORT_C void CAknCharMap::SetCharacterCaseL(TInt aCharCase)
       
  3140     {
       
  3141     __ASSERT_DEBUG( iExtension, Panic(EAknPanicInvalidResourceData));
       
  3142     
       
  3143     // PictoMode
       
  3144     if(aCharCase & EAknCharMapPictoNoUse)
       
  3145         {
       
  3146         SetPictoMode(EAknCharMapPictoNoUse);
       
  3147         }
       
  3148     else if(aCharCase & EAknCharMapPictoFirst)
       
  3149         {
       
  3150         SetPictoMode(EAknCharMapPictoFirst);
       
  3151         }
       
  3152 
       
  3153     // EmotionMode
       
  3154     if(aCharCase & EAknCharMapEmotionNoUse)
       
  3155         {
       
  3156         SetEmotionModeL(EAknCharMapEmotionNoUse);
       
  3157         }
       
  3158     else if(aCharCase & EAknCharMapEmotionUse)
       
  3159         {
       
  3160         SetEmotionModeL(EAknCharMapEmotionUse);
       
  3161         }
       
  3162     else if(aCharCase & EAknCharMapEmotionFirst)
       
  3163         {
       
  3164         SetEmotionModeL(EAknCharMapEmotionFirst);
       
  3165         }
       
  3166     
       
  3167     // do set character case
       
  3168     iSpecialCharCase = aCharCase & KCharMapCaseMask;
       
  3169 
       
  3170     if (iChaMapTableCase != EAknCharMapTableSpecialChar)
       
  3171         {
       
  3172         if (iCaseIndex == 1)
       
  3173             {
       
  3174             iChars = iPictographsBuffer2;
       
  3175             }
       
  3176         else
       
  3177             {
       
  3178             iChars = iPictographsBuffer;
       
  3179             }
       
  3180         iShowCasesRef = &iPictographCases;
       
  3181         iShowPagesRef = &iPictographPages;
       
  3182         }
       
  3183     else
       
  3184         {
       
  3185         iShowCasesRef = &iSpecialCharCases;
       
  3186         iShowPagesRef = &iSpecialCharPages;
       
  3187         
       
  3188         // default
       
  3189         iSpecialCharCase = EAknSCTLowerCase;
       
  3190         iChars = iCharsBufferLower;
       
  3191         
       
  3192         if(iExtension->iCharsSmiley && iExtension->IsShowingEmotion())
       
  3193             {
       
  3194             iChars = iExtension->iCharsSmiley;
       
  3195             }
       
  3196         else if (iCharsBufferUpper && iSpecialCharCase==EAknSCTUpperCase)
       
  3197             {
       
  3198             iChars = iCharsBufferUpper;
       
  3199             }
       
  3200         else if (iCharsBufferNumeric && iSpecialCharCase==EAknSCTNumeric)
       
  3201             {
       
  3202             iChars = iCharsBufferNumeric;
       
  3203             }
       
  3204         else if (iCharsBufferFull && iSpecialCharCase==EAknSCTFullCase)
       
  3205             {
       
  3206             iChars = iCharsBufferFull;
       
  3207             }
       
  3208         else if (iCharsBufferHalf && iSpecialCharCase==EAknSCTHalfCase)
       
  3209             {
       
  3210             iChars = iCharsBufferHalf;
       
  3211             }
       
  3212         else if (iExtension->iCharsQwerty && iSpecialCharCase==EAknSCTQwerty)
       
  3213             {
       
  3214             iChars = iExtension->iCharsQwerty;
       
  3215             }
       
  3216         }
       
  3217 
       
  3218     // calculate page count for all pages
       
  3219     iSpecialCharPages.Reset(); // reset the current page count for different charsets
       
  3220     TRAP_IGNORE(
       
  3221         {
       
  3222         iSpecialCharPages.AppendL( PageCountFromChars(*iChars) );
       
  3223         for (TInt i(1); i < iSpecialCharCases.Count(); ++i)
       
  3224             {
       
  3225             HBufC* chars = CharsFromCase(iSpecialCharCases[i]);
       
  3226             if (chars)
       
  3227                 {
       
  3228                 iSpecialCharPages.AppendL( PageCountFromChars(*chars) );
       
  3229                 }
       
  3230             }
       
  3231         } );
       
  3232 
       
  3233     __ASSERT_ALWAYS( iChars && iChars->Length()>0, Panic(EAknPanicInvalidResourceData));
       
  3234     
       
  3235     iRows = ((iChars->Length() - 1) / iMaxColumns ) + 1 ;
       
  3236     iFirstVisibleRow = 0;
       
  3237     iAnimated = EFalse;
       
  3238     iCursorPos = TPoint(0, 0);
       
  3239 
       
  3240     if ( (iChaMapTableCase!=EAknCharMapTableSpecialChar && !iPictoInterface->Interface()->IsPictograph((*iChars)[0])) || 
       
  3241          (iChaMapTableCase==EAknCharMapTableSpecialChar && (*iChars)[0]==KHistoryEmptyChar && !Extension()->iMenuSct) )
       
  3242         {
       
  3243         iCursorPos = TPoint(0, 1);
       
  3244         }
       
  3245 
       
  3246     iExtension->iCurrentCategory = Category();
       
  3247     if (iExtension->iRadioButton)
       
  3248         {
       
  3249         iExtension->iRadioButton->SetCurrentCategory(iExtension->iCurrentCategory);
       
  3250         }
       
  3251 
       
  3252     // Create and set the scb visible even though there is nothing to scroll
       
  3253     delete iSBFrame;
       
  3254     iSBFrame=NULL;
       
  3255 
       
  3256     if ( !AknLayoutUtils::PenEnabled() && !Extension()->iMenuSct )    // No scrollbars in use.
       
  3257         {
       
  3258         iSBFrame=new(ELeave) CEikScrollBarFrame(this, NULL, ETrue);
       
  3259         iSBFrame->CreateDoubleSpanScrollBarsL(EFalse, EFalse, ETrue, EFalse); // non-window owning scrollbar
       
  3260         iSBFrame->SetScrollBarVisibilityL(CEikScrollBarFrame::EOff,CEikScrollBarFrame::EAuto);
       
  3261         iSBFrame->VerticalScrollBar()->SetMopParent(iExtension);
       
  3262         UpdateScrollIndicatorL();
       
  3263         }
       
  3264     
       
  3265     iExtension->LoadEmotionTumbnails(*iChars);
       
  3266 
       
  3267     CAknSctPageNavi* pageNavi = Extension()->iPageNavi;
       
  3268     if(pageNavi)
       
  3269         {
       
  3270         pageNavi->MakeVisible(PageCount()>1);
       
  3271         }
       
  3272     
       
  3273     HandleFocusStatusChanged();
       
  3274     
       
  3275     }
       
  3276 
       
  3277 EXPORT_C void CAknCharMap::SetBuffer(TDes& aSpecialChars)
       
  3278     {
       
  3279     iFetcherCharsBuffer = &aSpecialChars;
       
  3280     }
       
  3281 
       
  3282 void CAknCharMap::ReadCharSetFromResourceL(TResourceReader& aReader)
       
  3283     {
       
  3284     __ASSERT_DEBUG(iExtension, Panic(EAknPanicInvalidResourceData));
       
  3285 
       
  3286     iChars = NULL;
       
  3287     
       
  3288     delete iCharsBufferHalf;
       
  3289     iCharsBufferHalf = NULL;
       
  3290     delete iCharsBufferFull;
       
  3291     iCharsBufferFull = NULL;
       
  3292     delete iCharsBufferLower;
       
  3293     iCharsBufferLower = NULL;
       
  3294     delete iCharsBufferUpper;
       
  3295     iCharsBufferUpper = NULL;
       
  3296     delete iCharsBufferNumeric;
       
  3297     iCharsBufferNumeric = NULL;
       
  3298     delete iExtension->iCharsQwerty;
       
  3299     iExtension->iCharsQwerty = NULL;
       
  3300     delete iExtension->iCharsSmiley;
       
  3301     iExtension->iCharsSmiley = NULL;
       
  3302 
       
  3303     TInt component_count=aReader.ReadInt16();
       
  3304     for (TInt ii=0;ii<component_count;ii++)
       
  3305         {
       
  3306         TInt component_id=aReader.ReadInt16();
       
  3307         switch(component_id)
       
  3308             {
       
  3309             case EAknSCTLowerCase:
       
  3310                 iCharsBufferLower = aReader.ReadHBufCL();
       
  3311                 break;
       
  3312             case EAknSCTUpperCase:
       
  3313                 iCharsBufferUpper = aReader.ReadHBufCL();
       
  3314                 break;
       
  3315             case EAknSCTNumeric:
       
  3316                 iCharsBufferNumeric = aReader.ReadHBufCL();
       
  3317                 break;
       
  3318             case EAknSCTFullCase:
       
  3319                 iCharsBufferFull = AppendTextL(iCharsBufferFull, aReader.ReadHBufCL());
       
  3320                 break;
       
  3321             case EAknSCTHalfCase:
       
  3322                 iCharsBufferHalf = AppendTextL(iCharsBufferHalf, aReader.ReadHBufCL());
       
  3323                 break;
       
  3324             case EAknSCTQwerty:
       
  3325                  iExtension->iCharsQwerty = aReader.ReadHBufCL();
       
  3326                  break;
       
  3327             default:
       
  3328                 break;
       
  3329             }
       
  3330         }
       
  3331     
       
  3332     iExtension->iCharsSmiley = iExtension->ReadEmotionHBufCL();
       
  3333 
       
  3334     // EFalse is set to iSetRecentSct variable when setting special
       
  3335     // characters from resouce.
       
  3336     iSetRecentSct = EFalse;
       
  3337     }
       
  3338 
       
  3339 
       
  3340 void CAknCharMap::ReadAndAddCharSetFromResourceL(TResourceReader& aReader)
       
  3341     {
       
  3342     ReadCharSetFromResourceL( aReader );
       
  3343 
       
  3344     // Add recent used characters
       
  3345     if ( iCharMapHistory )
       
  3346         {
       
  3347         delete iCharMapHistory;
       
  3348         iCharMapHistory = NULL;
       
  3349         }
       
  3350     iCharMapHistory = CAknCharMapHistory::NewL();
       
  3351     AppendRecentCharL();
       
  3352     }
       
  3353 
       
  3354 EXPORT_C TSize CAknCharMap::MinimumSize()
       
  3355     {
       
  3356     TRect rect;
       
  3357     if (!AknLayoutUtils::PenEnabled() || Extension()->iMenuSct)
       
  3358         {
       
  3359         TRect mainPaneRect;
       
  3360         if(!AknLayoutUtils::LayoutMetricsRect(
       
  3361             AknLayoutUtils::EPopupParent, mainPaneRect))
       
  3362             {
       
  3363             mainPaneRect = iAvkonAppUi->ClientRect();
       
  3364             }
       
  3365 
       
  3366         TAknLayoutScalableParameterLimits charMapDialogVariety =
       
  3367             AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
       
  3368 
       
  3369         TInt maxVariety = charMapDialogVariety.LastVariety();
       
  3370 
       
  3371         AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation();
       
  3372         TInt maxVarietyOffset = 0;
       
  3373         TInt varietyOffset = maxVariety + 1;
       
  3374 
       
  3375         if(Layout_Meta_Data::IsLandscapeOrientation())
       
  3376             {
       
  3377             varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections;
       
  3378             }
       
  3379 
       
  3380         if(location == AknLayoutUtils::EAknCbaLocationRight)
       
  3381             {
       
  3382             maxVarietyOffset = varietyOffset;
       
  3383             }
       
  3384         else if(location == AknLayoutUtils::EAknCbaLocationLeft)
       
  3385             {
       
  3386             maxVarietyOffset = varietyOffset + varietyOffset;
       
  3387             }
       
  3388 
       
  3389         TInt varietyNumber = varietyOffset - iRows;
       
  3390 
       
  3391         if(varietyNumber < 0)
       
  3392             {
       
  3393             varietyNumber = 0;
       
  3394             }
       
  3395         else if(iRows<=0)
       
  3396             {
       
  3397             varietyNumber -= 1;
       
  3398             }
       
  3399 
       
  3400         varietyNumber += maxVarietyOffset;
       
  3401 
       
  3402         TAknLayoutRect popupGridLayRect;
       
  3403         popupGridLayRect.LayoutRect( mainPaneRect,
       
  3404             AknLayoutScalable_Avkon::popup_grid_graphic_window(varietyNumber));
       
  3405 
       
  3406         TAknLayoutRect gridWithScrollLayRect;
       
  3407         gridWithScrollLayRect.LayoutRect(popupGridLayRect.Rect(),
       
  3408             AknLayoutScalable_Avkon::listscroll_popup_graphic_pane());
       
  3409 
       
  3410         rect = gridWithScrollLayRect.Rect();
       
  3411         }
       
  3412     else
       
  3413         {
       
  3414         TAknLayoutRect popupGridLayRect;
       
  3415         popupGridLayRect.LayoutRect(iAvkonAppUi->ApplicationRect(),
       
  3416             AknLayoutScalable_Avkon::popup_grid_graphic2_window(0));
       
  3417 
       
  3418         rect = popupGridLayRect.Rect();
       
  3419         }
       
  3420 
       
  3421     return rect.Size();
       
  3422     }
       
  3423 
       
  3424 
       
  3425 // This method is needed to set correct initial value to scroll indicator.
       
  3426 EXPORT_C void CAknCharMap::ActivateL()
       
  3427     {
       
  3428     CCoeControl::ActivateL();
       
  3429     if (iRows > iExtension->iMaxVisibleRows)
       
  3430         {
       
  3431         UpdateScrollIndicatorL();
       
  3432         }
       
  3433     }
       
  3434 
       
  3435 
       
  3436 EXPORT_C TKeyResponse CAknCharMap::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aModifiers)
       
  3437     {
       
  3438     // Other key events.
       
  3439     if (iExtension->iFocusHandler->FocusedControl() != this)
       
  3440         {
       
  3441         return iExtension->iFocusHandler->FocusedControl()->OfferKeyEventL(aKeyEvent, aModifiers);
       
  3442         }
       
  3443 
       
  3444     // Grid key events.
       
  3445     if( ((*iChars)[0] == KHistoryEmptyChar) &&
       
  3446         ((*iChars)[iChars->Length()-1] == KHistoryEmptyChar))
       
  3447         {
       
  3448         return EKeyWasConsumed;
       
  3449         }
       
  3450     
       
  3451     TUint code=aKeyEvent.iCode;
       
  3452 	
       
  3453     // First key event enables the highlight
       
  3454     if ( iExtension->iSingleClickEnabled && !iExtension->iHighlightVisible )
       
  3455         {
       
  3456         if ( code == EKeyUpArrow || code == EKeyDownArrow || 
       
  3457              code == EKeyLeftArrow || code == EKeyRightArrow || 
       
  3458              code == EKeyEnter )
       
  3459             {
       
  3460             iExtension->iHighlightVisible = ETrue;
       
  3461             iCursorPos = TPoint( 0, 0 );
       
  3462             DrawCursor();
       
  3463             HandleFocusStatusChanged();
       
  3464             return EKeyWasConsumed;
       
  3465             }
       
  3466         }
       
  3467     
       
  3468     switch (code)
       
  3469         {
       
  3470         case EKeyLeftArrow:
       
  3471         case '4':
       
  3472             {
       
  3473             if (iExtension->iRadioButton && (iCursorPos.iX == 0)) // Radio button.
       
  3474                 {
       
  3475                 if (iExtension->iRadioButton->EnterControl(iCursorPos.iX,iCursorPos.iY))
       
  3476                     {
       
  3477                     LeaveControl();
       
  3478                     break;
       
  3479                     }
       
  3480                 }
       
  3481 
       
  3482             if (AknLayoutUtils::PenEnabled())
       
  3483                 {
       
  3484                 if (!iIsMirrored)
       
  3485                     {
       
  3486                     if ((iCursorPos.iX == 0) && (iCursorPos.iY == ColMin(0)))
       
  3487                         {
       
  3488                         if (!Layout_Meta_Data::IsLandscapeOrientation())
       
  3489                             {
       
  3490                             // Last table button.
       
  3491                             if (iExtension->iTableNavi &&
       
  3492                                 iExtension->iTableNavi->EnterControl(TableCount() - 1,0))
       
  3493                                 {
       
  3494                                 LeaveControl();
       
  3495                                 break;
       
  3496                                 }
       
  3497                             }
       
  3498                         else
       
  3499                             {
       
  3500                             // Right page button.
       
  3501                             if (iExtension->iPageNavi &&
       
  3502                                 iExtension->iPageNavi->EnterControl(1,0))
       
  3503                                 {
       
  3504                                 LeaveControl();
       
  3505                                 break;
       
  3506                                 }
       
  3507                             }
       
  3508                         }
       
  3509                     }
       
  3510                 else
       
  3511                     {
       
  3512                     if (((iCursorPos.iY == ColMax(0)) && (iCursorPos.iX == RowMax(ColMax(0)))))
       
  3513                         {
       
  3514                         if (!Layout_Meta_Data::IsLandscapeOrientation())
       
  3515                             {
       
  3516                             // Left page button.
       
  3517                             if (iExtension->iPageNavi &&
       
  3518                                 iExtension->iPageNavi->EnterControl(0,0))
       
  3519                                 {
       
  3520                                 LeaveControl();
       
  3521                                 break;
       
  3522                                 }
       
  3523                             }
       
  3524                         else
       
  3525                             {
       
  3526                             // First table button.
       
  3527                             if (iExtension->iTableNavi &&
       
  3528                                 iExtension->iTableNavi->EnterControl(0,0))
       
  3529                                 {
       
  3530                                 LeaveControl();
       
  3531                                 break;
       
  3532                                 }
       
  3533                             }
       
  3534                         }
       
  3535                     }
       
  3536                 }
       
  3537             MoveFocus(-1,0);
       
  3538             break;
       
  3539             }
       
  3540         case EKeyRightArrow:
       
  3541         case '6':
       
  3542             {
       
  3543             if (iExtension->iRadioButton &&
       
  3544                 (iCursorPos.iX == RowMax(iCursorPos.iY)) &&
       
  3545                     (iCursorPos.iY <= (iExtension->iRadioButton->Count() - 2)))
       
  3546                 {
       
  3547                 // Radio button.
       
  3548                 if (iExtension->iRadioButton->EnterControl(iCursorPos.iX,iCursorPos.iY+1))
       
  3549                     {
       
  3550                     LeaveControl();
       
  3551                     break;
       
  3552                     }
       
  3553                 }
       
  3554             if (AknLayoutUtils::PenEnabled())
       
  3555                 {
       
  3556                 if (!iIsMirrored)
       
  3557                     {
       
  3558                     if ((iCursorPos.iY == ColMax(0)) &&
       
  3559                         (iCursorPos.iX == RowMax(ColMax(0))))
       
  3560                         {
       
  3561                         if (!Layout_Meta_Data::IsLandscapeOrientation())
       
  3562                             {
       
  3563                             // Left page button.
       
  3564                             if (iExtension->iPageNavi &&
       
  3565                                 iExtension->iPageNavi->EnterControl(0,0))
       
  3566                                 {
       
  3567                                 LeaveControl();
       
  3568                                 break;
       
  3569                                 }
       
  3570                             }
       
  3571                         else
       
  3572                             {
       
  3573                             // First table button.
       
  3574                             if (iExtension->iTableNavi &&
       
  3575                                 iExtension->iTableNavi->EnterControl(0,0))
       
  3576                                 {
       
  3577                                 LeaveControl();
       
  3578                                 break;
       
  3579                                 }
       
  3580                             }
       
  3581                         }
       
  3582                     }
       
  3583                 else
       
  3584                     {
       
  3585                     if ((iCursorPos.iY == ColMin(0)) &&
       
  3586                         (iCursorPos.iX == 0))
       
  3587                         {
       
  3588                         if (!Layout_Meta_Data::IsLandscapeOrientation())
       
  3589                             {
       
  3590                             // First table button.
       
  3591                             if (iExtension->iTableNavi &&
       
  3592                                 iExtension->iTableNavi->EnterControl(0,0))
       
  3593                                 {
       
  3594                                 LeaveControl();
       
  3595                                 break;
       
  3596                                 }
       
  3597 
       
  3598                             }
       
  3599                         else
       
  3600                             {
       
  3601                             // Left page button.
       
  3602                             if (iExtension->iPageNavi &&
       
  3603                                 iExtension->iPageNavi->EnterControl(1,0))
       
  3604                                 {
       
  3605                                 LeaveControl();
       
  3606                                 break;
       
  3607                                 }
       
  3608                             }
       
  3609                         }
       
  3610                     }
       
  3611                 }
       
  3612             MoveFocus(1,0);
       
  3613             break;
       
  3614             }
       
  3615         case EKeyUpArrow:
       
  3616         case '2':
       
  3617             {
       
  3618             if (AknLayoutUtils::PenEnabled())
       
  3619                 {
       
  3620                 if (iCursorPos.iY == ColMin(iCursorPos.iX))
       
  3621                     {
       
  3622                     if (!iExtension->iRadioButton && iCursorPos.iX < TableCount())
       
  3623                         {
       
  3624                         // Table button up.
       
  3625                         if ( iExtension->iTableNavi &&
       
  3626                             iExtension->iTableNavi->EnterControl(iCursorPos.iX,0))
       
  3627                             {
       
  3628                             LeaveControl();
       
  3629                             break;
       
  3630                             }
       
  3631                         }
       
  3632                     else
       
  3633                         {
       
  3634                         if (iCursorPos.iX == MaxCols() - 1)
       
  3635                             {
       
  3636                             // Right page button.
       
  3637                             if ( iExtension->iPageNavi &&
       
  3638                                 iExtension->iPageNavi->EnterControl(1,0))
       
  3639                                 {
       
  3640                                 LeaveControl();
       
  3641                                 break;
       
  3642                                 }
       
  3643                             }
       
  3644                         if (Layout_Meta_Data::IsLandscapeOrientation())
       
  3645                             {
       
  3646                             if ((!iExtension->iRadioButton &&
       
  3647                                  (iCursorPos.iX == TableCount())) ||
       
  3648                                ((iExtension->iRadioButton) &&
       
  3649                                  (iCursorPos.iX == MaxCols()-2)))
       
  3650                                 {
       
  3651                                 // Left page button.
       
  3652                                 if ( iExtension->iPageNavi &&
       
  3653                                     iExtension->iPageNavi->EnterControl(0,0))
       
  3654                                     {
       
  3655                                     LeaveControl();
       
  3656                                     break;
       
  3657                                     }
       
  3658                                 }
       
  3659                             }
       
  3660                         // Grid bottom row.
       
  3661                         if (ColMax(0) > ColMax(iCursorPos.iX))
       
  3662                             {
       
  3663                             EnterControl(RowMax(ColMax(0)), ColMax(0));
       
  3664                             break;
       
  3665                             }
       
  3666                         EnterControl(iCursorPos.iX, ColMax( iCursorPos.iX));
       
  3667                         break;
       
  3668                         }
       
  3669                     }
       
  3670                 }
       
  3671             MoveFocus(0,-1);
       
  3672             break;
       
  3673             }
       
  3674         case EKeyDownArrow:
       
  3675         case '8':
       
  3676             {
       
  3677             if (AknLayoutUtils::PenEnabled())
       
  3678                 {
       
  3679                 if (iCursorPos.iY == ColMax(iCursorPos.iX))
       
  3680                     {
       
  3681                     if (iCursorPos.iX > RowMax(ColMax(0)))
       
  3682                         {
       
  3683                         // Grid last item.
       
  3684                         EnterControl(RowMax(ColMax(0)), ColMax(0));
       
  3685                         break;
       
  3686                         }
       
  3687                     if ((iCursorPos.iX == MaxCols() - 1) ||
       
  3688                         (!Layout_Meta_Data::IsLandscapeOrientation() &&
       
  3689                             iExtension->iRadioButton &&
       
  3690                                 (iCursorPos.iX == MaxCols() - 2)))
       
  3691                         {
       
  3692                         // Right page button.
       
  3693                         if (iExtension->iPageNavi &&
       
  3694                             iExtension->iPageNavi->EnterControl(1,0))
       
  3695                             {
       
  3696                             LeaveControl();
       
  3697                             break;
       
  3698                             }
       
  3699                         }
       
  3700                     if ((Layout_Meta_Data::IsLandscapeOrientation() &&
       
  3701                             !iExtension->iRadioButton &&
       
  3702                                 (iCursorPos.iX == TableCount())) ||
       
  3703                         (!Layout_Meta_Data::IsLandscapeOrientation() &&
       
  3704                             (iCursorPos.iX == 0)) ||
       
  3705                         (Layout_Meta_Data::IsLandscapeOrientation() &&
       
  3706                             iExtension->iRadioButton &&
       
  3707                                 (iCursorPos.iX == MaxCols() - 2)))
       
  3708                         {
       
  3709                         // Left page button.
       
  3710                         if (iExtension->iPageNavi &&
       
  3711                             iExtension->iPageNavi->EnterControl(0,0))
       
  3712                             {
       
  3713                             LeaveControl();
       
  3714                             break;
       
  3715                             }
       
  3716                         }
       
  3717                     if (!iExtension->iRadioButton &&
       
  3718                             iCursorPos.iX < TableCount())
       
  3719                         {
       
  3720                          // Table button down.
       
  3721                         if (iExtension->iTableNavi &&
       
  3722                             iExtension->iTableNavi->EnterControl(iCursorPos.iX,0))
       
  3723                             {
       
  3724                             LeaveControl();
       
  3725                             break;
       
  3726                             }
       
  3727                         }
       
  3728                     // Grid top row.
       
  3729                     EnterControl(iCursorPos.iX, ColMin(iCursorPos.iX));
       
  3730                     break;
       
  3731                     }
       
  3732                 }
       
  3733             MoveFocus(0,1);
       
  3734             break;
       
  3735             }
       
  3736         case '5':
       
  3737         case EKeySpace:
       
  3738             {
       
  3739             AppendFocusSctToDestinationBufferL();
       
  3740             }
       
  3741             break;
       
  3742         case EKeyEnter:
       
  3743         case EKeyOK:
       
  3744             if(!Extension()->iKeyOkEvent)
       
  3745                 {
       
  3746                 if(AppendFocusSctToDestinationBufferL())
       
  3747                     {
       
  3748                     Extension()->iKeyOkEvent = ETrue;
       
  3749                     }
       
  3750                 else
       
  3751                     {
       
  3752                     return EKeyWasNotConsumed;
       
  3753                     }
       
  3754                 }
       
  3755             break;
       
  3756         default:
       
  3757             return EKeyWasNotConsumed;
       
  3758 
       
  3759         }
       
  3760     return EKeyWasConsumed;
       
  3761     }
       
  3762 
       
  3763 EXPORT_C TCoeInputCapabilities CAknCharMap::InputCapabilities() const
       
  3764     {
       
  3765     return TCoeInputCapabilities(TCoeInputCapabilities::EAllText);
       
  3766     }
       
  3767 
       
  3768 /**
       
  3769 * Control position of this control is registered for skin library when necessary
       
  3770 * in CEikDialogPage::SetDataPosition, so we do not do that in this method.
       
  3771 */
       
  3772 EXPORT_C void CAknCharMap::SizeChanged()
       
  3773     {
       
  3774     
       
  3775     if (!AknLayoutUtils::PenEnabled() || Extension()->iMenuSct)
       
  3776         {
       
  3777         TRect mainPaneRect;
       
  3778         if(!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EPopupParent, mainPaneRect))
       
  3779             {
       
  3780             mainPaneRect = iAvkonAppUi->ClientRect();
       
  3781             }
       
  3782 
       
  3783         TAknLayoutScalableParameterLimits charMapDialogVariety =
       
  3784             AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
       
  3785 
       
  3786         TInt maxVariety = charMapDialogVariety.LastVariety();
       
  3787 
       
  3788         AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation();
       
  3789         TInt maxVarietyOffset = 0;
       
  3790         TInt varietyOffset = maxVariety + 1;
       
  3791         if(Layout_Meta_Data::IsLandscapeOrientation())
       
  3792             {
       
  3793             varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections;
       
  3794             }
       
  3795         if(location == AknLayoutUtils::EAknCbaLocationRight)
       
  3796             {
       
  3797             maxVarietyOffset = varietyOffset;
       
  3798             }
       
  3799         else if(location == AknLayoutUtils::EAknCbaLocationLeft)
       
  3800             {
       
  3801             maxVarietyOffset = varietyOffset + varietyOffset;
       
  3802             }
       
  3803 
       
  3804         TInt varietyNumber = varietyOffset - iRows;
       
  3805         if(varietyNumber < 0)
       
  3806             {
       
  3807             varietyNumber = 0;
       
  3808             }
       
  3809         else if(iRows<=0)
       
  3810             {
       
  3811             varietyNumber -= 1;
       
  3812             }
       
  3813         varietyNumber += maxVarietyOffset;
       
  3814 
       
  3815         TAknLayoutRect popupGridLayRect;
       
  3816         popupGridLayRect.LayoutRect(mainPaneRect, AknLayoutScalable_Avkon::popup_grid_graphic_window(varietyNumber));
       
  3817 
       
  3818         TRect relativePopup(TPoint(0,0), popupGridLayRect.Rect().Size());
       
  3819 
       
  3820         TAknLayoutRect gridWithScrollLayRect;
       
  3821         gridWithScrollLayRect.LayoutRect(relativePopup, AknLayoutScalable_Avkon::listscroll_popup_graphic_pane());
       
  3822 
       
  3823         TAknLayoutRect gridLayRect;
       
  3824         if (iExtension->iHasCategoryButtonUi)
       
  3825             {
       
  3826             gridLayRect.LayoutRect(gridWithScrollLayRect.Rect(), AknLayoutScalable_Avkon::grid_graphic_popup_pane(2));
       
  3827             }
       
  3828         else
       
  3829             {
       
  3830             gridLayRect.LayoutRect(gridWithScrollLayRect.Rect(), AknLayoutScalable_Avkon::grid_graphic_popup_pane(0));
       
  3831             }
       
  3832 
       
  3833         // Grid.
       
  3834         TRect contentRect = Extension()->iMenuSct ? Rect() : gridLayRect.Rect();
       
  3835         if ( Extension()->iMenuSct )
       
  3836             {
       
  3837             contentRect.iBr.iY -= (contentRect.Height() - Rect().Height());
       
  3838             }
       
  3839         iOffset.iY = contentRect.iTl.iY + 1;
       
  3840         iGridTopLeft.iY = contentRect.iTl.iY;
       
  3841         if ( iIsMirrored )
       
  3842             {
       
  3843             iOffset.iX = contentRect.iBr.iX - iGridItemWidth + 1;
       
  3844             iGridTopLeft.iX = contentRect.iBr.iX - iGridItemWidth;
       
  3845             }
       
  3846         else
       
  3847             {
       
  3848             iOffset.iX = contentRect.iTl.iX + 1;
       
  3849             iGridTopLeft.iX = contentRect.iTl.iX;
       
  3850             }
       
  3851 
       
  3852         // Category buttons.
       
  3853         if (iExtension && iExtension->iHasCategoryButtonUi)
       
  3854             {
       
  3855             if (iExtension->iRadioButton)
       
  3856                 {
       
  3857                 TAknLayoutRect categoryButtonLayRect;
       
  3858                 categoryButtonLayRect.LayoutRect(gridWithScrollLayRect.Rect(),AknLayoutScalable_Avkon::grid_sct_catagory_button_pane());
       
  3859 
       
  3860                 TAknLayoutRect oneButtonLayRect;
       
  3861                 oneButtonLayRect.LayoutRect(categoryButtonLayRect.Rect(),AknLayoutScalable_Avkon::cell_sct_catagory_button_pane());
       
  3862 
       
  3863                 TSize size(oneButtonLayRect.Rect().Width(), oneButtonLayRect.Rect().Height()*iExtension->iRadioButton->Count());
       
  3864                 TRect rectRadio(categoryButtonLayRect.Rect().iTl, size);
       
  3865                 iExtension->iRadioButton->SetRect(rectRadio);
       
  3866                 }
       
  3867             }
       
  3868 
       
  3869 
       
  3870         // Background context.
       
  3871         if(iExtension && iExtension->iBgContext)
       
  3872             {
       
  3873             TInt varietyNumber = Layout_Meta_Data::IsLandscapeOrientation() ? 1 : 0;
       
  3874             TAknLayoutRect innerRect;
       
  3875             innerRect.LayoutRect(relativePopup, AknLayoutScalable_Avkon::bg_popup_window_pane_g1(varietyNumber));
       
  3876             iExtension->iBgContext->SetFrameRects( relativePopup, innerRect.Rect() );
       
  3877             }
       
  3878 
       
  3879         TRAP_IGNORE( UpdateScrollIndicatorL() );
       
  3880         }
       
  3881     else
       
  3882         {
       
  3883         
       
  3884         TInt variety;
       
  3885         if (!IsJapaneseSctUi())
       
  3886             {
       
  3887             variety = Layout_Meta_Data::IsLandscapeOrientation() ? 3 : 1;
       
  3888             if(TableCount() > 1) variety--;
       
  3889             }
       
  3890         else
       
  3891             {
       
  3892             variety = Layout_Meta_Data::IsLandscapeOrientation() ? 5 : 4;
       
  3893             }
       
  3894         
       
  3895         // Popup.
       
  3896         TAknLayoutRect popupGridLayRect;
       
  3897         popupGridLayRect.LayoutRect(iAvkonAppUi->ApplicationRect(), AknLayoutScalable_Avkon::popup_grid_graphic2_window(0));
       
  3898         TRect popupGridRect = popupGridLayRect.Rect();
       
  3899 
       
  3900         // Grid.
       
  3901         TAknLayoutRect gridLayRect;
       
  3902         gridLayRect.LayoutRect(popupGridRect, AknLayoutScalable_Avkon::grid_graphic2_pane(variety));
       
  3903         TRect gridRect = gridLayRect.Rect();
       
  3904 
       
  3905         iOffset.iY = gridRect.iTl.iY + 1;
       
  3906         iGridTopLeft.iY = gridRect.iTl.iY;
       
  3907         if ( iIsMirrored )
       
  3908             {
       
  3909             iOffset.iX = gridRect.iBr.iX - iGridItemWidth + 1;
       
  3910             iGridTopLeft.iX = gridRect.iBr.iX - iGridItemWidth;
       
  3911             }
       
  3912         else
       
  3913             {
       
  3914             iOffset.iX = gridRect.iTl.iX + 1;
       
  3915             iGridTopLeft.iX = gridRect.iTl.iX;
       
  3916             }
       
  3917 
       
  3918         // Category
       
  3919         if (iExtension->iHasCategoryButtonUi && iExtension->iRadioButton) // Radio buttons.
       
  3920             {
       
  3921             TAknLayoutRect oneButtonLayRect;
       
  3922             TAknLayoutRect categoryButtonLayRect;
       
  3923             TInt oneButtonLayVariety, categoryButtonLayVariety;
       
  3924             
       
  3925             if (Layout_Meta_Data::IsLandscapeOrientation())
       
  3926                 {
       
  3927                 oneButtonLayVariety = 5;
       
  3928                 categoryButtonLayVariety = 1;
       
  3929                 }
       
  3930             else
       
  3931                 {
       
  3932                 oneButtonLayVariety = 4;
       
  3933                 categoryButtonLayVariety = 0;
       
  3934                 }
       
  3935             
       
  3936             oneButtonLayRect.LayoutRect(popupGridRect, AknLayoutScalable_Avkon::grid_graphic2_control_pane(oneButtonLayVariety));
       
  3937             categoryButtonLayRect.LayoutRect(popupGridRect, AknLayoutScalable_Avkon::grid_graphic2_catg_pane(categoryButtonLayVariety));
       
  3938 
       
  3939             TSize size(oneButtonLayRect.Rect().Width(), 
       
  3940                        oneButtonLayRect.Rect().Height() * iExtension->iRadioButton->Count());
       
  3941             TRect rectRadio(categoryButtonLayRect.Rect().iTl, size);
       
  3942             iExtension->iRadioButton->SetRect(rectRadio);
       
  3943             }
       
  3944 
       
  3945         // Table navigation.
       
  3946         if (iExtension->iTableNavi)
       
  3947             {
       
  3948             TAknLayoutRect tableNaviLayRect;
       
  3949             tableNaviLayRect.LayoutRect(popupGridRect, AknLayoutScalable_Avkon::grid_graphic2_control_pane(variety));
       
  3950             iExtension->iTableNavi->SetRect(tableNaviLayRect.Rect());
       
  3951             }
       
  3952 
       
  3953         // Page navigation.
       
  3954         if (iExtension->iPageNavi)
       
  3955             {
       
  3956             if (PageCount() > 1)
       
  3957                 {
       
  3958                 iExtension->iPageNavi->MakeVisible(ETrue);
       
  3959                 
       
  3960                 TAknLayoutRect pageNaviLayRect;
       
  3961                 pageNaviLayRect.LayoutRect(popupGridRect, AknLayoutScalable_Avkon::graphic2_pages_pane(variety));
       
  3962                 iExtension->iPageNavi->SetRect(pageNaviLayRect.Rect());
       
  3963                 }
       
  3964             else
       
  3965                 {
       
  3966                 iExtension->iPageNavi->MakeVisible(EFalse);
       
  3967                 }
       
  3968             }
       
  3969 
       
  3970         // Background context.
       
  3971         if(iExtension->iBgContext)
       
  3972             {
       
  3973             TAknLayoutRect innerRect;
       
  3974             innerRect.LayoutRect(popupGridRect, AknLayoutScalable_Avkon::bg_popup_window_pane_cp21(variety));
       
  3975 
       
  3976             TRect relativePopupRect(TPoint(0,0), popupGridRect.Size());
       
  3977             iExtension->iBgContext->SetFrameRects(relativePopupRect,innerRect.Rect());
       
  3978             }
       
  3979 
       
  3980         }
       
  3981     }
       
  3982 
       
  3983 EXPORT_C void CAknCharMap::HandleResourceChange(TInt aType)
       
  3984     {
       
  3985     TRAP_IGNORE(DoHandleResourceChangeL(aType));
       
  3986     CCoeControl::HandleResourceChange(aType);
       
  3987     }
       
  3988 
       
  3989 void CAknCharMap::DoHandleResourceChangeL(TInt aType)
       
  3990     {
       
  3991     if (aType == KEikDynamicLayoutVariantSwitch)
       
  3992         {
       
  3993         TInt cursorIndexBeforeSwitch = (iFirstVisibleRow + iCursorPos.iY) * iMaxColumns + iCursorPos.iX;
       
  3994         TInt recentLengthBeforeSwitch = iMaxColumns;
       
  3995         TBool recentWasSetBeforeSwitch = iSetRecentSct;
       
  3996 
       
  3997         // Disabled because the buffer content may change due to diffent layout.
       
  3998         if (recentWasSetBeforeSwitch) DisableRecentCharsRow();
       
  3999 
       
  4000         // Calculate the new magnitudes (iMaxColumns, etc.).
       
  4001         DoLayout();
       
  4002 
       
  4003         // Append right amount of recent characters due to different layout.
       
  4004         if (recentWasSetBeforeSwitch) AppendRecentCharL();
       
  4005 
       
  4006         // Sets the character case because the buffer content may have changed.
       
  4007         SetCharacterCaseL(iSpecialCharCase);
       
  4008 
       
  4009         // status after layout switch.
       
  4010         TInt recentLengthAfterSwitch = iMaxColumns; // recentLength has changed after switch
       
  4011         TInt cursorIndexAfterSwitch;
       
  4012         if(cursorIndexBeforeSwitch < recentLengthBeforeSwitch)
       
  4013             {
       
  4014             cursorIndexAfterSwitch = cursorIndexBeforeSwitch;
       
  4015             }
       
  4016         else
       
  4017             {
       
  4018             cursorIndexAfterSwitch = cursorIndexBeforeSwitch - recentLengthBeforeSwitch + recentLengthAfterSwitch;
       
  4019             }
       
  4020 
       
  4021         // the new first row is the top row on the page where the new focus is.
       
  4022         TInt pageVolume = iMaxColumns * iExtension->iMaxVisibleRows;
       
  4023         iFirstVisibleRow = (cursorIndexAfterSwitch / pageVolume * pageVolume) / iMaxColumns;
       
  4024 
       
  4025         // the cursor positions are relative to current page
       
  4026         TInt cursorIndexAfterSwitchInPage = cursorIndexAfterSwitch - (iMaxColumns * iFirstVisibleRow);
       
  4027         iCursorPos.iX = cursorIndexAfterSwitchInPage % iMaxColumns;
       
  4028         iCursorPos.iY = cursorIndexAfterSwitchInPage / iMaxColumns;
       
  4029         
       
  4030         iOldCursorPos = iCursorPos;
       
  4031 
       
  4032         // for full screen touch UI.
       
  4033         CEikDialog* dlg;
       
  4034         MopGetObject(dlg);
       
  4035         CEikDialogExtension* dlgExtension = dlg ? dlg->Extension() : NULL;
       
  4036         if (dlgExtension)
       
  4037             {
       
  4038             if (AknLayoutUtils::PenEnabled())
       
  4039                 {
       
  4040                 dlgExtension->iPublicFlags.Set(CEikDialogExtension::EUseVirtualInput);
       
  4041                 }
       
  4042             else
       
  4043                 {
       
  4044                 dlgExtension->iPublicFlags.Clear(CEikDialogExtension::EUseVirtualInput);
       
  4045                 }
       
  4046             }
       
  4047 
       
  4048         // Sets alternate UI controls.
       
  4049         if (iExtension->iHasCategoryButtonUi)
       
  4050             {
       
  4051             if (AknLayoutUtils::PenEnabled())
       
  4052                 {
       
  4053                 EnableCategoryInputFieldL();
       
  4054                 EnableNavigationButtonsL();
       
  4055                 }
       
  4056             else
       
  4057                 {
       
  4058                 DisableCategoryInputFieldL();
       
  4059                 DisableNavigationButtonsL();
       
  4060                 }
       
  4061             EnableCategoryButtonsL();
       
  4062             }
       
  4063         else
       
  4064             {
       
  4065             DisableCategoryInputFieldL();
       
  4066             DisableCategoryButtonsL();
       
  4067             if (AknLayoutUtils::PenEnabled())
       
  4068                 {
       
  4069                 EnableNavigationButtonsL();
       
  4070                 }
       
  4071             else
       
  4072                 {
       
  4073                 DisableNavigationButtonsL();
       
  4074                 }
       
  4075             }
       
  4076 
       
  4077         // and finally updates the page counts (from setcasetable)
       
  4078         iSpecialCharPages.Reset(); // reset the current page count for different charsets
       
  4079         iSpecialCharPages.AppendL( PageCountFromChars(*iChars) );
       
  4080         for (TInt i(1); i < iSpecialCharCases.Count(); ++i)
       
  4081             {
       
  4082             HBufC* chars = CharsFromCase(iSpecialCharCases[i]);
       
  4083             if (chars) iSpecialCharPages.AppendL( PageCountFromChars(*chars) );
       
  4084             }
       
  4085 
       
  4086         if (iExtension->iPictographsBuffer && iPictoInterface)
       
  4087             {
       
  4088             __ASSERT_ALWAYS(iPictoInterface->Interface(), Panic(EAknPanicNullPointer));
       
  4089             iPictographPages.Reset();
       
  4090             iPictographCases.Reset();
       
  4091             iPictographPages.AppendL( PageCountFromChars(*iPictographsBuffer) );
       
  4092             iPictographCases.AppendL(EAknCharMapTablePicto);
       
  4093             if (iExtension->iPictographsBufferGrouping)
       
  4094                 {
       
  4095                 iPictographPages.AppendL( PageCountFromChars(*iPictographsBuffer2) );
       
  4096                 iPictographCases.AppendL( EAknCharMapTablePicto2 );
       
  4097                 }
       
  4098             }
       
  4099 
       
  4100         UpdateScrollIndicatorL();
       
  4101         RefreshNaviPageL();
       
  4102 
       
  4103         // create the background again as the background size has changed
       
  4104         // !resize an option but the cost only differs with the creation of the graphic objects!
       
  4105         CreateOffscreenBackgroundL();
       
  4106         iOffscreenBgDrawn = EFalse;
       
  4107         }
       
  4108 
       
  4109     else if ( aType == KAknsMessageSkinChange )
       
  4110         {
       
  4111         iOffscreenBgDrawn = EFalse;
       
  4112         }
       
  4113     else if ( aType == KAknMessageFocusLost && iExtension->iHighlightVisible )
       
  4114         {
       
  4115         iExtension->iHighlightVisible = EFalse;
       
  4116         DrawCursor();
       
  4117         }
       
  4118     }
       
  4119 
       
  4120 void CAknCharMap::EnableNavigationButtonsL()
       
  4121     {
       
  4122     if ( iExtension )
       
  4123         {
       
  4124         if ( !iExtension->iTableNavi )
       
  4125             {
       
  4126             iExtension->iTableNavi = new(ELeave) CAknSctTableNavi(this, iExtension);
       
  4127             iExtension->iTableNavi->SetContainerWindowL(*this);
       
  4128             TResourceReader reader;
       
  4129             iCoeEnv->CreateResourceReaderLC(reader, R_AVKON_SCT_TABLE_NAVI_CONTROL);
       
  4130             iExtension->iTableNavi->ConstructFromResourceL(reader);
       
  4131             iExtension->iTableNavi->SetNonFocusing();
       
  4132             iExtension->iTableNavi->SetMopParent(iExtension);
       
  4133             CleanupStack::PopAndDestroy(); // reader
       
  4134             }
       
  4135 
       
  4136         iExtension->iTableNavi->MakeVisible(ETrue);
       
  4137 
       
  4138         if ( !iExtension->iPageNavi )
       
  4139             {
       
  4140             iExtension->iPageNavi = new(ELeave) CAknSctPageNavi(this, iExtension);
       
  4141             iExtension->iPageNavi->SetContainerWindowL(*this);
       
  4142             TResourceReader reader;
       
  4143             iCoeEnv->CreateResourceReaderLC(reader, R_AVKON_SCT_PAGE_NAVI_CONTROL);
       
  4144             iExtension->iPageNavi->ConstructFromResourceL(reader);
       
  4145             iExtension->iPageNavi->SetNonFocusing();
       
  4146             iExtension->iPageNavi->SetMopParent(iExtension);
       
  4147             CleanupStack::PopAndDestroy(); // reader
       
  4148             }
       
  4149 
       
  4150         iExtension->iPageNavi->MakeVisible(ETrue);
       
  4151         }
       
  4152     }
       
  4153 
       
  4154 void CAknCharMap::DisableNavigationButtonsL()
       
  4155     {
       
  4156     if ( iExtension && iExtension->iTableNavi )
       
  4157         {
       
  4158         iExtension->iTableNavi->MakeVisible( EFalse );
       
  4159         }
       
  4160     if ( iExtension && iExtension->iPageNavi )
       
  4161         {
       
  4162         iExtension->iPageNavi->MakeVisible( EFalse );
       
  4163         }
       
  4164     }
       
  4165 
       
  4166 void CAknCharMap::EnableCategoryButtonsL()
       
  4167     {
       
  4168     if (!iExtension->iRadioButton)
       
  4169         {
       
  4170         iExtension->iRadioButton = new(ELeave) CAknSctRadioButton(this, iExtension);
       
  4171         iExtension->iRadioButton->SetContainerWindowL(*this);
       
  4172         TResourceReader reader;
       
  4173         iCoeEnv->CreateResourceReaderLC(reader, R_AVKON_SCT_CATEGORY_BUTTON_CONTROL);
       
  4174         iExtension->iRadioButton->ConstructFromResourceL(reader);
       
  4175         iExtension->iRadioButton->SetNonFocusing();
       
  4176         iExtension->iRadioButton->SetMopParent(iExtension);
       
  4177         CleanupStack::PopAndDestroy(); // reader
       
  4178         }
       
  4179     iExtension->iRadioButton->MakeVisible(ETrue);
       
  4180     }
       
  4181 
       
  4182 void CAknCharMap::DisableCategoryButtonsL()
       
  4183     {
       
  4184     if (iExtension && iExtension->iRadioButton)
       
  4185         {
       
  4186         iExtension->iRadioButton->MakeVisible(EFalse);
       
  4187         }
       
  4188     }
       
  4189 
       
  4190 void CAknCharMap::EnableCategoryInputFieldL()
       
  4191     {
       
  4192     TAknLayoutRect popupGridLayRect;
       
  4193     popupGridLayRect.LayoutRect(iAvkonAppUi->ApplicationRect(),
       
  4194         AknLayoutScalable_Avkon::popup_grid_graphic2_window(0));
       
  4195 
       
  4196     // Enable title field.
       
  4197     if (!iExtension->iCategoryTitle)
       
  4198         {
       
  4199         iExtension->iCategoryTitle = new(ELeave) CEikLabel;
       
  4200         iExtension->iCategoryTitle->SetContainerWindowL(*this);
       
  4201         iExtension->iCategoryTitle->SetTextL(KNullDesC());
       
  4202         }
       
  4203     Extension()->iCategoryTitle->SetBrushStyle(CGraphicsContext::ENullBrush);
       
  4204     TInt variety = Layout_Meta_Data::IsLandscapeOrientation() ? 1 : 0;
       
  4205     AknLayoutUtils::LayoutLabel(iExtension->iCategoryTitle, popupGridLayRect.Rect(),
       
  4206         AknLayoutScalable_Avkon::popup_grid_graphic2_window_t1(variety));
       
  4207     TAknLayoutText titleLayRect;
       
  4208     titleLayRect.LayoutText(popupGridLayRect.Rect(),
       
  4209         AknLayoutScalable_Avkon::popup_grid_graphic2_window_t1(variety).LayoutLine());
       
  4210     TRgb color = titleLayRect.Color();
       
  4211     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  4212     if( skin )
       
  4213         {
       
  4214         (void)AknsUtils::GetCachedColor(skin, color,
       
  4215             KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG6);
       
  4216         }
       
  4217     TRAP_IGNORE(AknLayoutUtils::OverrideControlColorL(*(iExtension->iCategoryTitle),
       
  4218         EColorLabelText, color));
       
  4219     if (iExtension->iPictographsBuffer && iPictoInterface)
       
  4220         {
       
  4221         iExtension->iCategoryTitle->EnablePictographsL(*iPictoInterface);
       
  4222         }
       
  4223     iExtension->iCategoryTitle->MakeVisible(ETrue);
       
  4224 
       
  4225 
       
  4226     // Enable entry field.
       
  4227     if (!iExtension->iCategoryEntry)
       
  4228         {
       
  4229         iExtension->iCategoryEntry = new(ELeave) CEikLabel;
       
  4230         iExtension->iCategoryEntry->SetContainerWindowL(*this);
       
  4231         iExtension->iCategoryEntry->SetTextL(KNullDesC());
       
  4232         }
       
  4233     Extension()->iCategoryEntry->SetBrushStyle(CGraphicsContext::ENullBrush);
       
  4234     AknLayoutUtils::LayoutLabel(iExtension->iCategoryEntry, popupGridLayRect.Rect(),
       
  4235         AknLayoutScalable_Avkon::popup_grid_graphic2_window_t2(variety));
       
  4236     TAknLayoutText entryLayRect;
       
  4237     entryLayRect.LayoutText(popupGridLayRect.Rect(),
       
  4238         AknLayoutScalable_Avkon::popup_grid_graphic2_window_t2(variety).LayoutLine());
       
  4239     color = entryLayRect.Color();
       
  4240     if( skin )
       
  4241         {
       
  4242         (void)AknsUtils::GetCachedColor(skin, color,
       
  4243             KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG6);
       
  4244         }
       
  4245     TRAP_IGNORE( AknLayoutUtils::OverrideControlColorL(*(iExtension->iCategoryEntry),
       
  4246         EColorLabelText, color));
       
  4247     if (iExtension->iPictographsBuffer && iPictoInterface)
       
  4248         {
       
  4249         iExtension->iCategoryEntry->EnablePictographsL(*iPictoInterface);
       
  4250         }
       
  4251     iExtension->iCategoryEntry->MakeVisible(ETrue);
       
  4252 
       
  4253     UpdateInputFieldL();
       
  4254     }
       
  4255 
       
  4256 void CAknCharMap::DisableCategoryInputFieldL()
       
  4257     {
       
  4258     if (iExtension->iCategoryTitle)
       
  4259         {
       
  4260         iExtension->iCategoryTitle->MakeVisible(EFalse);
       
  4261         }
       
  4262 
       
  4263     if (iExtension->iCategoryEntry)
       
  4264         {
       
  4265         iExtension->iCategoryEntry->MakeVisible(EFalse);
       
  4266         }
       
  4267     }
       
  4268 
       
  4269 
       
  4270 void CAknCharMap::Draw(const TRect& /*aRect*/) const
       
  4271     {
       
  4272     TInt cursorPos = 0;
       
  4273 
       
  4274     CWindowGc& gc=SystemGc();
       
  4275     gc.UseFont(iFont);
       
  4276 
       
  4277     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  4278     MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
       
  4279 
       
  4280     TRect rect = Rect();
       
  4281 
       
  4282     if (!AknLayoutUtils::PenEnabled() || Extension()->iMenuSct)
       
  4283         {
       
  4284         TRect mainPaneRect;
       
  4285         if(!AknLayoutUtils::LayoutMetricsRect(
       
  4286             AknLayoutUtils::EPopupParent, mainPaneRect))
       
  4287             {
       
  4288             mainPaneRect = iAvkonAppUi->ClientRect();
       
  4289             }
       
  4290 
       
  4291         TAknLayoutScalableParameterLimits charMapDialogVariety =
       
  4292             AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
       
  4293 
       
  4294         TInt maxVariety = charMapDialogVariety.LastVariety();
       
  4295 
       
  4296         AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation();
       
  4297         TInt maxVarietyOffset = 0;
       
  4298         TInt varietyOffset = maxVariety + 1;
       
  4299 
       
  4300         if(Layout_Meta_Data::IsLandscapeOrientation())
       
  4301             {
       
  4302             varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections;
       
  4303             }
       
  4304 
       
  4305         if(location == AknLayoutUtils::EAknCbaLocationRight)
       
  4306             {
       
  4307             maxVarietyOffset = varietyOffset;
       
  4308             }
       
  4309         else if(location == AknLayoutUtils::EAknCbaLocationLeft)
       
  4310             {
       
  4311             maxVarietyOffset = varietyOffset + varietyOffset; // 2*
       
  4312             }
       
  4313 
       
  4314         TInt varietyNumber = varietyOffset - iRows;
       
  4315 
       
  4316         if(varietyNumber < 0)
       
  4317             {
       
  4318             varietyNumber = 0;
       
  4319             }
       
  4320         else if(iRows<=0)
       
  4321             {
       
  4322             varietyNumber -= 1;
       
  4323             }
       
  4324         varietyNumber += maxVarietyOffset;
       
  4325 
       
  4326         TAknLayoutRect popupGridLayRect;
       
  4327         popupGridLayRect.LayoutRect(mainPaneRect,
       
  4328             AknLayoutScalable_Avkon::popup_grid_graphic_window(varietyNumber));
       
  4329 
       
  4330         // Background height.
       
  4331         TInt backgroundHeightOffset =
       
  4332             popupGridLayRect.Rect().Height() - rect.iBr.iY;
       
  4333 
       
  4334         rect.iBr.iY += backgroundHeightOffset;
       
  4335         }
       
  4336     else
       
  4337         {
       
  4338         TAknLayoutRect popupGridLayRect;
       
  4339         popupGridLayRect.LayoutRect(iAvkonAppUi->ApplicationRect(),
       
  4340             AknLayoutScalable_Avkon::popup_grid_graphic2_window(0));
       
  4341 
       
  4342         // Background height.
       
  4343         TInt backgroundHeightOffset =
       
  4344             popupGridLayRect.Rect().Height() - rect.iBr.iY;
       
  4345 
       
  4346         rect.iBr.iY += backgroundHeightOffset * 2;
       
  4347         }
       
  4348 
       
  4349     // Grid (main).
       
  4350     if ( !Extension()->iMenuSct )
       
  4351         {
       
  4352         // 1) Draw the background
       
  4353 
       
  4354         // Check if we got an offscreen bitmap allocated for skin background and
       
  4355         // there is bitmap background in the current skin.
       
  4356 		if( CAknEnv::Static()->TransparencyEnabled() )
       
  4357 			{
       
  4358 			TRegionFix<10> clipReg;
       
  4359 			clipReg.AddRect(rect);
       
  4360 			if ( iFirstVisibleRow == 0 && iSetRecentSct )
       
  4361 				{
       
  4362 				TPoint pos = iGridTopLeft;
       
  4363 				TInt endX = pos.iX + iGridItemWidth * iMaxColumns + 1;
       
  4364 				TInt endY = pos.iY + iGridItemHeight;
       
  4365 				// eliminate the overlap area between menu sct and the first menu item.
       
  4366 				if ( Extension()->iMenuSct )
       
  4367 					{
       
  4368 					endY--;
       
  4369 					}
       
  4370 				clipReg.SubRect( TRect( pos, TPoint( endX, endY ) ) );
       
  4371 				}
       
  4372 			// Take scroll bar out of clip region
       
  4373 			if (iSBFrame)
       
  4374 				{
       
  4375 				clipReg.SubRect(iSBFrame->GetScrollBarHandle(
       
  4376 					CEikScrollBar::EVertical)->Rect());
       
  4377 				}
       
  4378 			gc.SetClippingRegion(clipReg);
       
  4379 			}
       
  4380 		AknsDrawUtils::Background( skin, cc, this, gc, rect,KAknsDrawParamNoClearUnderImage);
       
  4381 		if( CAknEnv::Static()->TransparencyEnabled() )
       
  4382 			{
       
  4383 			gc.CancelClippingRegion();
       
  4384 			}
       
  4385 
       
  4386         gc.SetPenStyle(CGraphicsContext::ESolidPen);
       
  4387         gc.SetBrushStyle(CGraphicsContext::ENullBrush);
       
  4388         gc.SetPenSize(TSize(1,1));
       
  4389 
       
  4390         // 2) Draw the grid
       
  4391         DrawGrid(gc);
       
  4392         }
       
  4393 
       
  4394     // Grid (recent).
       
  4395     if (iFirstVisibleRow==0 && iSetRecentSct)
       
  4396         {
       
  4397         DrawRecentCharFrame(gc);
       
  4398         }
       
  4399 
       
  4400     // Cell items.
       
  4401     TInt charIndex = iFirstVisibleRow * iMaxColumns;
       
  4402     cursorPos = iCursorPos.iX + iCursorPos.iY * iMaxColumns;
       
  4403     TInt numberOfChars = NumberOfVisibleChars();
       
  4404     TBool highlighted = EFalse;
       
  4405     for (TInt j = 0; j < numberOfChars; j++)
       
  4406         {
       
  4407 
       
  4408         // emotions in next line are all ready to draw
       
  4409         if((j%iMaxColumns) == 0)
       
  4410             {
       
  4411             if(!EmotionsAreAllReadyToDraw(charIndex, iMaxColumns)) break;
       
  4412             }
       
  4413         
       
  4414         // grid is focused and cursor pos is same with the current index.
       
  4415         if ( iExtension->iMenuSct )
       
  4416         	{
       
  4417             highlighted = iExtension->iMenuSctHighlighted && 
       
  4418                           (iExtension->iFocusHandler->FocusedControl()==this) && 
       
  4419                           (j==cursorPos);
       
  4420         	}
       
  4421         else
       
  4422         	{
       
  4423         	highlighted = ((iExtension->iFocusHandler->FocusedControl()==this) && (j==cursorPos));
       
  4424         	}
       
  4425         DrawItem(gc, CursorRect(j, charIndex), charIndex, highlighted, EFalse);
       
  4426         charIndex++;
       
  4427         }
       
  4428     iDrawnBefore = ETrue;
       
  4429     gc.DiscardFont();
       
  4430     }
       
  4431 
       
  4432 //--------------------------------------------------------------
       
  4433 // Return how many chars to be drawn
       
  4434 //--------------------------------------------------------------
       
  4435 //
       
  4436 TInt CAknCharMap::NumberOfVisibleChars() const
       
  4437     {
       
  4438     TInt numberOfCharsToBeDrawn = iChars->Length();
       
  4439     numberOfCharsToBeDrawn -= (iFirstVisibleRow * iMaxColumns);
       
  4440     if ( numberOfCharsToBeDrawn > (iExtension->iMaxVisibleRows * iMaxColumns))
       
  4441         {
       
  4442         numberOfCharsToBeDrawn = iExtension->iMaxVisibleRows * iMaxColumns;
       
  4443         }
       
  4444     __ASSERT_DEBUG( numberOfCharsToBeDrawn >= 1, Panic(EAknPanicOutOfRange));
       
  4445 
       
  4446     if(Extension()->iMenuSct)
       
  4447         {
       
  4448         return Min(iExtension->iMaxVisibleRows * iMaxColumns, iChars->Length());
       
  4449         }
       
  4450     return numberOfCharsToBeDrawn;
       
  4451     }
       
  4452 
       
  4453 /**
       
  4454 *
       
  4455 * Local method to return the RTL mirrored character for the (LTR) input character
       
  4456 *
       
  4457 * The method has buffers ready to accept surrogate pairs when they become supported in the
       
  4458 * descriptor methods.
       
  4459 *
       
  4460 * The return buffer is padded with extra characters that in theory may arise in bidirectional
       
  4461 * conversion, but since only one character is input, no leading "zero width joiner" will be
       
  4462 * at index 0.  Hence, the resulting character at 0 is returned, with no check for the zero width
       
  4463 * joiner.
       
  4464 */
       
  4465 TChar MirrorChar(TChar a)
       
  4466     {
       
  4467     TBuf<2> buf; // ready for when surrogate pairs need handling
       
  4468     buf.Append(a);
       
  4469     TBidirectionalState::TRunInfo ri;
       
  4470     TBidiLogicalToVisual bl2v(buf, ETrue, &ri, 1); // Only 1 run info element passed
       
  4471     bl2v.Reorder();
       
  4472     TBuf<2+TBidiLogicalToVisual::KMinCharAvailable> result;
       
  4473     bl2v.GetVisualLine(result, 0, buf.Length(), 0xFFFF);
       
  4474     // Always use index 0 as this situation can not result in a zero-width joiner at index 0
       
  4475     return result[0];  // This return is not surrogate pair-ready
       
  4476     }
       
  4477 
       
  4478 //-------------------------------------------------------------------------
       
  4479 // Set the pen, color, brush, etc. before drawing the frame of a special char
       
  4480 // item.
       
  4481 // Note: The frame is inside the cell.
       
  4482 //-------------------------------------------------------------------------
       
  4483 //
       
  4484 void CAknCharMap::SetItemFrameStyle( CWindowGc& aGc) const
       
  4485     {
       
  4486     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  4487     MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
       
  4488     TRgb colorFrame = AKN_LAF_COLOR(215);
       
  4489     AknsUtils::GetCachedColor( skin, colorFrame,
       
  4490         KAknsIIDQsnLineColors, EAknsCIQsnLineColorsCG7 );
       
  4491     aGc.SetPenColor(colorFrame);
       
  4492     aGc.SetPenSize(TSize(1,1));
       
  4493     }
       
  4494 
       
  4495 //--------------------------------------------------------------
       
  4496 // Draw the rect edge lines which are inside the cell and around
       
  4497 // the char.
       
  4498 //--------------------------------------------------------------
       
  4499 //
       
  4500 void CAknCharMap::DrawItemFrame( CWindowGc& aGc,
       
  4501         const TRect& aItemRect, TInt aCharIndex,
       
  4502         TBool aHighlighted,
       
  4503         TBool /*aDrawBackground*/ ) const
       
  4504     {
       
  4505     SetItemFrameStyle(aGc);
       
  4506 
       
  4507     if(IsRecentChar(aCharIndex))
       
  4508         {
       
  4509         // recent char hasn't inner frames.
       
  4510         return;
       
  4511         }
       
  4512     if( aHighlighted )
       
  4513         {
       
  4514         aGc.DrawRect( aItemRect );
       
  4515         }
       
  4516     }
       
  4517 
       
  4518 //--------------------------------------------------------------
       
  4519 // brush the background rect inside the cell.
       
  4520 //--------------------------------------------------------------
       
  4521 //
       
  4522 void CAknCharMap::DrawItemShade( CWindowGc& aGc,
       
  4523         const TRect& aItemRect, TInt /*aCharIndex*/,
       
  4524         TBool aHighlighted,
       
  4525         TBool aDrawBackground ) const
       
  4526     {
       
  4527 
       
  4528     TRect innerRect = aItemRect;
       
  4529     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  4530     MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
       
  4531 
       
  4532     if( aHighlighted )
       
  4533         {
       
  4534         TRgb color = AKN_LAF_COLOR(210);
       
  4535 		
       
  4536         if( !( iExtension->iFlags & EAknCharMapPressedDown ) 
       
  4537             || iExtension->iSingleClickEnabled )
       
  4538             {
       
  4539             AknsUtils::GetCachedColor( skin, 
       
  4540                     color, 
       
  4541                     KAknsIIDQsnHighlightColors, 
       
  4542                     EAknsCIQsnHighlightColorsCG1 );
       
  4543             }
       
  4544 			
       
  4545         else
       
  4546             {
       
  4547             AknsUtils::GetCachedColor( skin, color, KAknsIIDQsnHighlightColors, EAknsCIQsnHighlightColorsCG2 );
       
  4548             }
       
  4549         aGc.SetBrushColor(color);
       
  4550         aGc.Clear( innerRect );
       
  4551         }
       
  4552     else if( aDrawBackground )
       
  4553         {
       
  4554         if ( iExtension->iBgContext )
       
  4555             {
       
  4556             cc = iExtension->iBgContext;
       
  4557             }
       
  4558         AknsDrawUtils::Background( skin, cc, this, aGc, innerRect );
       
  4559         }
       
  4560     }
       
  4561 
       
  4562 void CAknCharMap::DrawItem(
       
  4563     CWindowGc& aGc,
       
  4564     const TRect& aSctPosition,
       
  4565     TInt aCharIndex,
       
  4566     TBool aHighlighted,
       
  4567     TBool aDrawBackground ) const
       
  4568     {
       
  4569     if (iChaMapTableCase!=EAknCharMapTableSpecialChar && iPictoInterface)
       
  4570         {
       
  4571         DrawPicto(aGc, aSctPosition, aCharIndex, aHighlighted, aDrawBackground);
       
  4572         return;
       
  4573         }
       
  4574     
       
  4575     if ( iExtension->iSingleClickEnabled &&
       
  4576          !iExtension->iHighlightVisible )
       
  4577         {
       
  4578         aHighlighted = EFalse;
       
  4579         }
       
  4580     
       
  4581     DrawItemShade(aGc, aSctPosition, aCharIndex, aHighlighted, aDrawBackground);
       
  4582     
       
  4583     DrawItemFrame(aGc, aSctPosition, aCharIndex, aHighlighted, aDrawBackground);
       
  4584 
       
  4585     TAknTextLineLayout specialCharItemLayout;
       
  4586     if (AknLayoutUtils::PenEnabled() && !Extension()->iMenuSct)
       
  4587         {
       
  4588         if ( Layout_Meta_Data::IsLandscapeOrientation() )
       
  4589             {
       
  4590             specialCharItemLayout = AknLayoutScalable_Avkon::cell_graphic2_pane_t1(1);
       
  4591             }
       
  4592         else if (IsJapaneseSctUi())
       
  4593             {
       
  4594             specialCharItemLayout = AknLayoutScalable_Avkon::cell_graphic2_pane_t1(2);
       
  4595             }
       
  4596         else
       
  4597             {
       
  4598             specialCharItemLayout = AknLayoutScalable_Avkon::cell_graphic2_pane_t1(0);
       
  4599             }
       
  4600         }
       
  4601     else
       
  4602         {
       
  4603         specialCharItemLayout = AknLayoutScalable_Avkon::cell_graphic_popup_pane_t2();
       
  4604         }
       
  4605 
       
  4606     TRect textRect = aSctPosition;
       
  4607     if( IsRecentChar(aCharIndex) )
       
  4608         {
       
  4609         textRect.Move(0, -1);       //because height of recent char frame decreased 1.
       
  4610         if( Extension()->iMenuSct )
       
  4611             {
       
  4612             textRect.Move(0, -1);   //because menu sct will also shrink 1.
       
  4613             }
       
  4614         }
       
  4615     TAknLayoutText textLayout;
       
  4616     textLayout.LayoutText(textRect, specialCharItemLayout);
       
  4617 
       
  4618     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  4619     MAknsControlContext* cc = AknsDrawUtils::ControlContext( this );
       
  4620 
       
  4621     TRgb color;
       
  4622     TBuf<1> symbol;
       
  4623     TChar character = '\t';
       
  4624     character = (*iChars)[ aCharIndex ];
       
  4625 
       
  4626     // Is Mirrored language (Arabic or Hebrew) used as input language
       
  4627     TBool mirroredLanguage(
       
  4628         AknTextUtils::CurrentScriptDirectionality() == TBidiText::ERightToLeft);
       
  4629 
       
  4630     //  Obtain mirrored forms
       
  4631     if ( mirroredLanguage )
       
  4632         {
       
  4633         TChar oldCharacter( character );
       
  4634         character = MirrorChar( oldCharacter );
       
  4635         }
       
  4636     // Note: the character is now mirrored.  The following visual substitution may need to be
       
  4637     // aware of this:
       
  4638 
       
  4639     _LIT(KChar,"%c");
       
  4640 
       
  4641     // Special cases if needed to use PUA symbols on screen
       
  4642     if ( (character == CEditableText::EParagraphDelimiter) || (character == 0x000A) ) // Line feed
       
  4643         {
       
  4644         if ( mirroredLanguage )
       
  4645             {
       
  4646             symbol.Format(KChar, KPuaCodeMirroredLineFeedSymbol); // Symbol for mirrored line feed
       
  4647             }
       
  4648         else
       
  4649             {
       
  4650             symbol.Format(KChar, KPuaCodeLineFeedSymbol); // Symbol for line feed
       
  4651             }
       
  4652         }
       
  4653     else if ( character == CEditableText::ESpace ) // Space
       
  4654         {
       
  4655         symbol.Format(KChar, KPuaCodeSpaceSymbol); // Symbol for space
       
  4656         }
       
  4657     else if ( character == 0x3000 ) // Full width Space
       
  4658         {
       
  4659         symbol.Format(KChar, KPuaCodeFullWidthSpaceSymbol); // Symbol for space
       
  4660         }
       
  4661     else if ( character == 0x200E ) // RLM
       
  4662         {
       
  4663         symbol.Format(KChar, KPuaCodeRightToLeftSymbol); // Symbol for RLM
       
  4664         }
       
  4665     else if ( character == 0x200F ) // LRM
       
  4666         {
       
  4667         symbol.Format(KChar, KPuaCodeLeftToRightSymbol); // Symbol for LRM
       
  4668         }
       
  4669     else if ( ( character == 0x0E31 ||
       
  4670         0x0E33 <= character && character <= 0x0E3A) ||
       
  4671         (0x0E47 <= character && character <= 0x0E4E) ) // Thai SCT-cases
       
  4672         {
       
  4673         symbol.Format(KChar, TUint(character)+KThaiSCTCombiningSymbolAdd);
       
  4674         }
       
  4675     else if ( character == KHistoryEmptyChar )
       
  4676         {
       
  4677         symbol.Format(KChar, KHistoryEmptyCharForDisplay);
       
  4678         }
       
  4679     else  // Defaul case - show symbol as it is
       
  4680         {
       
  4681         symbol.Format(KChar, static_cast<TInt>(character));
       
  4682         }
       
  4683 
       
  4684     if ( aHighlighted )
       
  4685         {
       
  4686         AknsUtils::GetCachedColor( skin, color,
       
  4687             KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG24 );
       
  4688         }
       
  4689     else
       
  4690         {
       
  4691         AknsUtils::GetCachedColor( skin, color,
       
  4692             KAknsIIDQsnTextColors, EAknsCIQsnTextColorsCG19 );
       
  4693         }
       
  4694     
       
  4695     if(TEmotionUtils::IsEmotionChar(symbol[0]))
       
  4696         {
       
  4697         iExtension->DrawEmotion(aGc, textLayout.TextRect(), symbol[0]);
       
  4698         }
       
  4699     else
       
  4700         {
       
  4701         textLayout.DrawText( aGc, symbol, EFalse, color );
       
  4702         }
       
  4703     
       
  4704     }
       
  4705 
       
  4706 
       
  4707 //-------------------------------------------------------
       
  4708 // Set the color, pen, style for drawing recent char map
       
  4709 // frame
       
  4710 //-------------------------------------------------------
       
  4711 //
       
  4712 void CAknCharMap::SetRecentCharFrameStyle( CWindowGc& aGc) const
       
  4713     {
       
  4714     TRgb colorRecentLine = AKN_LAF_COLOR(215);
       
  4715     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  4716     AknsUtils::GetCachedColor( skin, colorRecentLine,
       
  4717             KAknsIIDQsnLineColors, EAknsCIQsnLineColorsCG7 );
       
  4718     aGc.SetPenColor(colorRecentLine);
       
  4719     aGc.SetPenSize(TSize(2,2));
       
  4720     }
       
  4721 
       
  4722 //-------------------------------------------------------
       
  4723 // Draw the outter thick frame for the all recent chars.
       
  4724 //-------------------------------------------------------
       
  4725 //
       
  4726 void CAknCharMap::DrawRecentCharFrame( CWindowGc& aGc) const
       
  4727     {
       
  4728     MAknsSkinInstance*   skin = AknsUtils::SkinInstance();
       
  4729     MAknsControlContext* cc = iExtension->iBgContext;
       
  4730     if ( !cc )
       
  4731         {
       
  4732         cc = AknsDrawUtils::ControlContext( this );
       
  4733         }
       
  4734 
       
  4735     TPoint pos = iGridTopLeft;
       
  4736     TInt endX = pos.iX + iGridItemWidth * iMaxColumns + 1;
       
  4737     TInt endY = pos.iY + iGridItemHeight;
       
  4738     TRect drawRect(TPoint(pos.iX, pos.iY), TPoint(endX, endY));
       
  4739     // eliminate the overlap area between menu sct and the first menu item.
       
  4740     if ( Extension()->iMenuSct )
       
  4741         {
       
  4742         drawRect = Rect();
       
  4743         endY--;
       
  4744         }
       
  4745 
       
  4746     AknsDrawUtils::Background( skin, cc, this, aGc, drawRect );
       
  4747 
       
  4748     SetRecentCharFrameStyle(aGc);
       
  4749     if(iIsMirrored)
       
  4750         {
       
  4751         pos.iX = iGridTopLeft.iX - ((iMaxColumns - 1) * iGridItemWidth);
       
  4752         endX = iGridTopLeft.iX + iGridItemWidth + 1;
       
  4753         }
       
  4754 
       
  4755     aGc.DrawRect( TRect(TPoint(pos.iX-1, pos.iY-1), TPoint(endX, endY)));
       
  4756     
       
  4757     MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  4758     CFeedbackSpec* spec = CFeedbackSpec::New();
       
  4759 
       
  4760     if ( spec && feedback )
       
  4761         {
       
  4762         CAknCharMap* mutableThis = MUTABLE_CAST( CAknCharMap* ,this );
       
  4763         TInt recentChars = mutableThis->LengthOfRecentChar();
       
  4764         TRect rect;
       
  4765         spec->AddFeedback( ETouchEventStylusDown, 
       
  4766                            ETouchFeedbackList );
       
  4767         rect.SetRect( pos, TPoint( pos.iX + recentChars * iGridItemWidth, pos.iY + iGridItemHeight ));
       
  4768         if ( iIsMirrored )
       
  4769             {
       
  4770             TInt emptyRecentSlots = iMaxColumns - recentChars;
       
  4771             rect.Move( emptyRecentSlots * iGridItemWidth, 0 );
       
  4772             }
       
  4773         feedback->SetFeedbackArea( this, KAreaIdRecent, rect, spec );
       
  4774         
       
  4775         delete spec;
       
  4776         }
       
  4777     }
       
  4778 
       
  4779 //-------------------------------------------------------
       
  4780 // Set the pen, color, brush, etc. to draw the char map
       
  4781 // grid
       
  4782 //-------------------------------------------------------
       
  4783 //
       
  4784 void CAknCharMap::SetGridStyle( CWindowGc& aGc) const
       
  4785     {
       
  4786     TRgb colorLine = AKN_LAF_COLOR(219);
       
  4787     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  4788     AknsUtils::GetCachedColor( skin, colorLine,
       
  4789             KAknsIIDQsnLineColors, EAknsCIQsnLineColorsCG5 );
       
  4790     aGc.SetPenColor(colorLine);
       
  4791     aGc.SetPenSize(TSize(1,1));
       
  4792     }
       
  4793 
       
  4794 //-------------------------------------------------------
       
  4795 // draw the char map grid
       
  4796 // Note: only draw the grid, do not draw the recent char
       
  4797 // map frame.
       
  4798 //-------------------------------------------------------
       
  4799 //
       
  4800 void CAknCharMap::DrawGrid( CWindowGc& aGc) const
       
  4801     {
       
  4802     SetGridStyle(aGc);
       
  4803 
       
  4804     //
       
  4805     // a better method: (0~MaxChars) do:[:each| each drawRect.]
       
  4806     //
       
  4807     const TSize gridItemRectSize( iGridItemWidth + 1, iGridItemHeight + 1);
       
  4808     TInt numberOfCells = NumberOfVisibleChars();
       
  4809     TPoint pos = iGridTopLeft;
       
  4810     TInt ii=0;
       
  4811     if (iFirstVisibleRow == 0 && iSetRecentSct)
       
  4812         {
       
  4813         pos.iY += iGridItemHeight;  //skip the recent char area
       
  4814         ii=iMaxColumns;
       
  4815         }
       
  4816     else
       
  4817         {
       
  4818         // remove area for recent characters because they does not exist in this view
       
  4819         MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  4820         if ( feedback )
       
  4821             {
       
  4822             feedback->RemoveFeedbackArea( this, KAreaIdRecent );
       
  4823             }
       
  4824         }
       
  4825     for(; ii < numberOfCells; ++ii)
       
  4826         {
       
  4827         aGc.DrawRect(TRect( pos, gridItemRectSize ));
       
  4828 
       
  4829         if ( iIsMirrored )
       
  4830             {
       
  4831             pos.iX -= iGridItemWidth;
       
  4832             }
       
  4833         else
       
  4834             {
       
  4835             pos.iX += iGridItemWidth;
       
  4836             }
       
  4837 
       
  4838         if( (ii+1) % iMaxColumns == 0 )
       
  4839             {
       
  4840             pos.iX  = iGridTopLeft.iX;   //reset for each row.
       
  4841             pos.iY += iGridItemHeight;
       
  4842             }
       
  4843         }
       
  4844     MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  4845     CFeedbackSpec* spec = CFeedbackSpec::New();
       
  4846 
       
  4847     if ( feedback && spec )
       
  4848         {
       
  4849         TInt orphans = NumberOfVisibleChars() % iMaxColumns;
       
  4850         TInt rows = NumberOfVisibleChars() / iMaxColumns;
       
  4851         CAknCharMap* mutableThis = MUTABLE_CAST( CAknCharMap* ,this );
       
  4852         TInt recentChars = mutableThis->LengthOfRecentChar();    
       
  4853         TRect rectMain;
       
  4854         TPoint nextTopLeft = iGridTopLeft;    
       
  4855 
       
  4856         if ( CurrentPage() == 1 )
       
  4857             {
       
  4858             nextTopLeft.iY += iGridItemHeight;
       
  4859             if ( rows > 0 )
       
  4860                 rows--;
       
  4861             }
       
  4862 
       
  4863         rectMain.SetRect( nextTopLeft, TPoint(nextTopLeft.iX + iMaxColumns * iGridItemWidth, nextTopLeft.iY + rows * iGridItemHeight) );
       
  4864         if ( iIsMirrored )
       
  4865             {
       
  4866             rectMain.Move( ( 1 - iMaxColumns ) * iGridItemWidth, 0 );
       
  4867             }
       
  4868 
       
  4869         spec->AddFeedback( ETouchEventStylusDown, 
       
  4870                            ETouchFeedbackList );
       
  4871         if ( rows )
       
  4872             {
       
  4873             feedback->SetFeedbackArea( this, KAreaIdMain, rectMain, spec );
       
  4874             }
       
  4875         else
       
  4876             {
       
  4877             feedback->RemoveFeedbackArea( this, KAreaIdMain );
       
  4878             }
       
  4879 
       
  4880         nextTopLeft.iY = rectMain.iBr.iY;
       
  4881             
       
  4882         if ( orphans )
       
  4883             {
       
  4884             TRect rectOrphans;
       
  4885             rectOrphans.SetRect( TPoint( iGridTopLeft.iX, pos.iY), TPoint( iGridTopLeft.iX + orphans * iGridItemWidth, pos.iY + iGridItemHeight) );
       
  4886             if ( iIsMirrored )
       
  4887                 {
       
  4888                 rectOrphans.Move( ( 1 - orphans ) * iGridItemWidth, 0 );
       
  4889                 }
       
  4890 
       
  4891             feedback->SetFeedbackArea( this, KAreaIdTail, rectOrphans, spec );
       
  4892             }
       
  4893         else
       
  4894             {
       
  4895             // remove feedback area for tail area because all rows of grid has maximum number of characters
       
  4896             feedback->RemoveFeedbackArea( this, KAreaIdTail );
       
  4897             }
       
  4898         
       
  4899         delete spec;
       
  4900         }        
       
  4901     }
       
  4902 
       
  4903 // Optimizes drawing. Only cursor is drawn.
       
  4904 void CAknCharMap::DrawCursor() const
       
  4905     {
       
  4906     // Whole SCT has to be drawn at least once.
       
  4907     // If the user presses arrow key before SCT has been drawn,
       
  4908     // only cursor position is drawn without this check.
       
  4909     if ( !iDrawnBefore )
       
  4910         {
       
  4911         DrawNow();
       
  4912         }
       
  4913     else
       
  4914         {
       
  4915         CWindowGc& gc = SystemGc();
       
  4916         // Only redraw old and new cursor position cells
       
  4917         if( !CAknEnv::Static()->TransparencyEnabled() )
       
  4918             {
       
  4919             ActivateGc();
       
  4920             gc.UseFont(iFont);
       
  4921             }
       
  4922 
       
  4923         TInt cursorPos = 0;
       
  4924         if ( iOldCursorPos != iCursorPos )
       
  4925             {
       
  4926             // Redraw only if old pos different from current pos
       
  4927             cursorPos = iOldCursorPos.iX + iOldCursorPos.iY * iMaxColumns;
       
  4928             DrawCell( cursorPos, EFalse );
       
  4929             }
       
  4930 
       
  4931         cursorPos = iCursorPos.iX + iCursorPos.iY * iMaxColumns;
       
  4932         DrawCell( cursorPos, (iExtension->iFocusHandler->FocusedControl()==this) );
       
  4933 
       
  4934         if( !CAknEnv::Static()->TransparencyEnabled() )
       
  4935             {
       
  4936             gc.DiscardFont();
       
  4937             DeactivateGc();
       
  4938             }
       
  4939         }
       
  4940     }
       
  4941 
       
  4942 // -----------------------------------------------------------------------------
       
  4943 // CAknCharMap::DrawCell
       
  4944 // -----------------------------------------------------------------------------
       
  4945 //
       
  4946 void CAknCharMap::DrawCell(
       
  4947     TInt aCursorPos,
       
  4948     TBool aHighLighted ) const
       
  4949     {
       
  4950     // calculate character index
       
  4951     TInt charIndex = aCursorPos + iFirstVisibleRow * iMaxColumns;
       
  4952     if(charIndex >= iChars->Length())
       
  4953         {
       
  4954         return;
       
  4955         }
       
  4956 
       
  4957     // If we are only redrawing for animations, no need to draw non-animated items.
       
  4958     if (iChaMapTableCase!=EAknCharMapTableSpecialChar && iPictoInterface)
       
  4959         {
       
  4960         if ( iAnimated && 
       
  4961              !iPictoInterface->Interface()->IsAnimated((*iChars)[charIndex],iCurrentPictographHeight) )
       
  4962             {
       
  4963             return;
       
  4964             }
       
  4965         }
       
  4966 
       
  4967     TRect rect = CursorRect( aCursorPos, charIndex );
       
  4968 
       
  4969     if( CAknEnv::Static()->TransparencyEnabled() )
       
  4970         {
       
  4971 
       
  4972         const TBool backedUp = IsBackedUp();
       
  4973         if ( !backedUp )
       
  4974             {
       
  4975             Window().Invalidate( rect );
       
  4976             Window().BeginRedraw( rect );
       
  4977             }
       
  4978 
       
  4979         ActivateGc();
       
  4980         CWindowGc& gc = SystemGc();
       
  4981         gc.UseFont(iFont);
       
  4982 
       
  4983         DrawItem( SystemGc(), rect, charIndex, aHighLighted, ETrue );
       
  4984 
       
  4985         gc.DiscardFont();
       
  4986         DeactivateGc();
       
  4987 
       
  4988         if ( !backedUp )
       
  4989             {
       
  4990             Window().EndRedraw();
       
  4991             }
       
  4992         }
       
  4993     else
       
  4994         {
       
  4995         if ( !Extension()->iMenuSct )
       
  4996             {
       
  4997             Window().Invalidate( rect );
       
  4998             Window().BeginRedraw( rect );
       
  4999             DrawItem( SystemGc(), rect, charIndex, aHighLighted, ETrue );
       
  5000             Window().EndRedraw();
       
  5001             }
       
  5002         else
       
  5003             {
       
  5004             DrawItem( SystemGc(), rect, charIndex, aHighLighted, ETrue );
       
  5005             }
       
  5006         }
       
  5007     }
       
  5008 
       
  5009 // -----------------------------------------------------------------------------
       
  5010 // CAknCharMap::CursorRect
       
  5011 // -----------------------------------------------------------------------------
       
  5012 //
       
  5013 TRect CAknCharMap::CursorRect( TInt aCursorPos, TInt aCharIndex) const
       
  5014     {
       
  5015     TPoint pos = iOffset;
       
  5016 
       
  5017     if (iIsMirrored)
       
  5018         {
       
  5019         pos.iX -= (aCursorPos % iMaxColumns) * iGridItemWidth;
       
  5020         }
       
  5021     else // Not mirrored
       
  5022         {
       
  5023         pos.iX += (aCursorPos % iMaxColumns) * iGridItemWidth;
       
  5024         }
       
  5025 
       
  5026     pos.iY += (aCursorPos / iMaxColumns) * iGridItemHeight;
       
  5027     TRect res = TRect( pos, TSize( iGridItemWidth - 2, iGridItemHeight - 2 ) );
       
  5028     if(IsRecentChar(aCharIndex))
       
  5029         {
       
  5030         res.iBr.iY --; //because the width of recent char frame is 2 but not 1.
       
  5031         }
       
  5032      // Eliminate the overlap between menu sct and the first menu option' item
       
  5033      if ( Extension()->iMenuSct )
       
  5034         {
       
  5035         res.iBr.iY --;
       
  5036         }
       
  5037     return res;
       
  5038     }
       
  5039 
       
  5040 // -----------------------------------------------------------------------------
       
  5041 // CAknCharMap::MoveCursorL
       
  5042 // -----------------------------------------------------------------------------
       
  5043 //
       
  5044 void CAknCharMap::MoveCursorL(TInt aDeltaX, TInt aDeltaY)
       
  5045     {
       
  5046     __ASSERT_DEBUG(
       
  5047         (aDeltaX <= 1) && (aDeltaX >= -1) &&
       
  5048         (aDeltaY <= 1) && (aDeltaY >= -1) &&
       
  5049         ((aDeltaX * aDeltaY) == 0), Panic(EAknPanicOutOfRange));
       
  5050 
       
  5051     if (iIsMirrored)
       
  5052         aDeltaX = -aDeltaX;
       
  5053 
       
  5054     iOldCursorPos = iCursorPos;
       
  5055     TInt oldFirstVisibleRow = iFirstVisibleRow;
       
  5056 
       
  5057     TInt globalYPos = iCursorPos.iY + iFirstVisibleRow;
       
  5058     TInt lastColumnOnLastRow(0);
       
  5059     if ( Extension()->iMenuSct )
       
  5060         {
       
  5061         lastColumnOnLastRow = LengthOfRecentChar() - 1;
       
  5062         }
       
  5063     else
       
  5064         {
       
  5065         lastColumnOnLastRow = (iChars->Length() - 1) % iMaxColumns;
       
  5066         }
       
  5067 
       
  5068     TInt checktable(-1);
       
  5069     TInt skipchar = aDeltaX != 0 ? 1: 0;
       
  5070     TBool caseChange(EFalse);
       
  5071 
       
  5072     // First line is NULL when Cursor was second line
       
  5073     if ( (iCursorPos.iY+iFirstVisibleRow == 1) && 
       
  5074          ( (iChaMapTableCase!=EAknCharMapTableSpecialChar && !iPictoInterface->Interface()->IsPictograph((*iChars)[0])) || 
       
  5075            (iChaMapTableCase==EAknCharMapTableSpecialChar && (*iChars)[0]==KHistoryEmptyChar) ) 
       
  5076        )
       
  5077         {
       
  5078         caseChange = ETrue;
       
  5079         // Cursor was on the second line
       
  5080         if (aDeltaY < 0)
       
  5081             {
       
  5082             globalYPos--;
       
  5083             }
       
  5084         // Cursor was on the second line and first position
       
  5085         if (aDeltaX < 0 && iCursorPos.iX == 0)
       
  5086             {
       
  5087             globalYPos--;
       
  5088             //iCursorPos.iY = 0;
       
  5089             iCursorPos.iX = 0;
       
  5090             }
       
  5091         }
       
  5092     else
       
  5093         {
       
  5094         TInt delta = aDeltaX != 0 ? aDeltaX: aDeltaY;
       
  5095         TInt next = aDeltaX != 0 ? aDeltaX: 0;
       
  5096         TInt charIndex = iCursorPos.iX +
       
  5097                 (iCursorPos.iY + aDeltaY + iFirstVisibleRow) * iMaxColumns; //the x index includes the current row
       
  5098 
       
  5099         for(TInt i(0); i <= iMaxColumns; ++i)
       
  5100             {
       
  5101             if (aDeltaY < 0 && charIndex < 0)
       
  5102                 {
       
  5103                 charIndex = 0;
       
  5104                 caseChange = ETrue; // prev case
       
  5105                 }
       
  5106             if (aDeltaY > 0 && iChars->Length() <= charIndex) // index 0 length 1 etc.
       
  5107                 {
       
  5108                 // set Position(iCursorPos.iX, 0)
       
  5109                 charIndex = iChars->Length() - 1;//iCursorPos.iX;
       
  5110                 i = charIndex;
       
  5111                 caseChange = ETrue; // next case
       
  5112                 }
       
  5113             if (aDeltaX < 0 && charIndex <= 0)
       
  5114                 {
       
  5115                 charIndex = iChars->Length() - 1;
       
  5116                 caseChange = ETrue; // prev case
       
  5117                 }
       
  5118             if (aDeltaX > 0 && iChars->Length() - 1 <= charIndex)
       
  5119                 {
       
  5120                 charIndex = 0;
       
  5121                 caseChange = ETrue; // next case
       
  5122                 }
       
  5123             if (caseChange && iShowCasesRef->Count() > 1)
       
  5124                 {
       
  5125                 // change case
       
  5126                 break;
       
  5127                 }
       
  5128             if ( (iChaMapTableCase!=EAknCharMapTableSpecialChar && iPictoInterface->Interface()->IsPictograph((*iChars)[charIndex+next])) || 
       
  5129                  (iChaMapTableCase==EAknCharMapTableSpecialChar && (*iChars)[charIndex+next]!=KHistoryEmptyChar) )
       
  5130                 {
       
  5131                 break;
       
  5132                 }
       
  5133             charIndex += delta;
       
  5134             skipchar++;
       
  5135             }
       
  5136         }
       
  5137 
       
  5138     if (aDeltaX < 0)
       
  5139         {
       
  5140         // Cursor was moved to left.
       
  5141         if (iCursorPos.iX > skipchar - 1)
       
  5142             {
       
  5143             iCursorPos.iX -= skipchar;
       
  5144             }
       
  5145         else
       
  5146             {
       
  5147             if (skipchar > iMaxColumns)
       
  5148                 {
       
  5149                 globalYPos--;
       
  5150                 iCursorPos.iX = iMaxColumns;
       
  5151                 }
       
  5152             // Go to previous line
       
  5153             globalYPos--;
       
  5154             if (globalYPos < 0)
       
  5155                 {
       
  5156                 // Cursor was on the first line - go to last line.
       
  5157                 globalYPos = iRows - 1;
       
  5158                 // x - position to the last item on the last row.
       
  5159                 iCursorPos.iX = lastColumnOnLastRow;
       
  5160                 checktable = iMaxColumns;
       
  5161                 }
       
  5162             else
       
  5163                 {
       
  5164                 // x - position to last column.
       
  5165                 iCursorPos.iX = iMaxColumns - skipchar;
       
  5166                 }
       
  5167             }
       
  5168         }
       
  5169 
       
  5170     if (aDeltaX > 0)
       
  5171         {
       
  5172         // Cursor was moved to right.
       
  5173         if (globalYPos < iRows - 1)
       
  5174             {
       
  5175             // Not in the last row.
       
  5176             if (iCursorPos.iX < iMaxColumns - skipchar)
       
  5177                 {
       
  5178                 // If not on the last columns, move cursor to next column.
       
  5179                 iCursorPos.iX += skipchar;
       
  5180                 }
       
  5181             else
       
  5182                 {
       
  5183                 // Cursor was on last column,
       
  5184                 // move to first column of the next line.
       
  5185                 iCursorPos.iX = 0;
       
  5186                 globalYPos++;
       
  5187                 }
       
  5188             }
       
  5189         else
       
  5190             {
       
  5191             // Currently on the last row.
       
  5192             if ( iCursorPos.iX < lastColumnOnLastRow )
       
  5193                 {
       
  5194                 // If there are more items on this row, move cursor to next item.
       
  5195                 iCursorPos.iX++;
       
  5196                 }
       
  5197             else
       
  5198                 {
       
  5199                 // No more item on the current row.
       
  5200                 // Move to first item on the first row.
       
  5201                 iCursorPos.iX = 0;
       
  5202                 checktable = 0;
       
  5203                 globalYPos = 0;
       
  5204                 }
       
  5205             }
       
  5206         }
       
  5207 
       
  5208     if (aDeltaY < 0)
       
  5209         {
       
  5210         iCursorPos.iX -= skipchar;
       
  5211         if (iCursorPos.iX < 0)
       
  5212             {
       
  5213             iCursorPos.iX += (iMaxColumns - 1);
       
  5214             globalYPos--;
       
  5215             }
       
  5216         // Cursor was moved to up.
       
  5217         if (globalYPos > 0)
       
  5218             {
       
  5219             // Cursor was not on the first line - move it to previous row.
       
  5220             globalYPos--;
       
  5221             }
       
  5222         else
       
  5223             {
       
  5224             checktable = iCursorPos.iX;
       
  5225             // Move cursot to last to row.
       
  5226             globalYPos = iRows - 1;
       
  5227             if (iCursorPos.iX > lastColumnOnLastRow)
       
  5228                 {
       
  5229                 // No items in the current column on the last row -
       
  5230                 // move cursor to last item on the row.
       
  5231                 iCursorPos.iX = lastColumnOnLastRow;
       
  5232                 }
       
  5233             }
       
  5234         }
       
  5235 
       
  5236     if (aDeltaY > 0)
       
  5237         {
       
  5238         iCursorPos.iX = (iCursorPos.iX + skipchar) % iMaxColumns;
       
  5239         globalYPos += (iCursorPos.iX + skipchar) / iMaxColumns;
       
  5240         // Cursor was moved to down.
       
  5241         if (globalYPos < iRows - 1)
       
  5242             {
       
  5243             // Cursor is not on the last row. Move cursor to next row.
       
  5244             globalYPos++;
       
  5245             if (globalYPos == iRows - 1 && iCursorPos.iX > lastColumnOnLastRow)
       
  5246                 {
       
  5247                 // No items in the current column on the last row -
       
  5248                 // move cursor to last item on the row.
       
  5249                 iCursorPos.iX = lastColumnOnLastRow;
       
  5250                 }
       
  5251             }
       
  5252         else
       
  5253             {
       
  5254             // Cursor was at the last row - move it to the first row.
       
  5255             globalYPos = 0;
       
  5256             checktable = iCursorPos.iX;
       
  5257             }
       
  5258         }
       
  5259     iCursorPos.iY = globalYPos - iFirstVisibleRow;
       
  5260 
       
  5261     if (globalYPos < iFirstVisibleRow)
       
  5262         {
       
  5263         // Cursor was moved from the top row.
       
  5264         if (globalYPos <= 0)
       
  5265             {
       
  5266             iFirstVisibleRow = 0;
       
  5267             iCursorPos = TPoint(iCursorPos.iX, 0);
       
  5268             }
       
  5269         else
       
  5270             {
       
  5271             // If cursor was moved up out of the visible area - show it again.
       
  5272             iFirstVisibleRow -= iExtension->iMaxVisibleRows;
       
  5273             iCursorPos = TPoint(iCursorPos.iX, iExtension->iMaxVisibleRows - 1);
       
  5274             }
       
  5275         }
       
  5276 
       
  5277     if (globalYPos > iFirstVisibleRow + iExtension->iMaxVisibleRows - 1)
       
  5278         {
       
  5279         if (globalYPos == iRows - 1)
       
  5280             {
       
  5281             // When cursor has moved from the top line,
       
  5282             // it is adjusted to a page boundary.
       
  5283             iFirstVisibleRow = VisibleRows();
       
  5284             iCursorPos = TPoint(
       
  5285                 iCursorPos.iX,
       
  5286                 (iRows - 1) % iExtension->iMaxVisibleRows
       
  5287                 );
       
  5288             }
       
  5289         else
       
  5290             {
       
  5291             // If cursor was moved down out of the visible area - show it again.
       
  5292             iFirstVisibleRow += iExtension->iMaxVisibleRows;
       
  5293             iCursorPos = TPoint(iCursorPos.iX, 0);
       
  5294             }
       
  5295         }
       
  5296 
       
  5297     TInt increment(1);
       
  5298     if (aDeltaY < 0 || aDeltaX < 0)
       
  5299         {
       
  5300         increment = -1;
       
  5301         }
       
  5302     if (checktable >= 0 && SwitchAnotherTableL(increment) > 0)
       
  5303         {
       
  5304         TInt lastColumnOnLastRow = ((iChars->Length() - 1) % iMaxColumns);
       
  5305         TPoint pt(checktable, 0);
       
  5306         if (aDeltaY < 0 || aDeltaX < 0)
       
  5307             {
       
  5308             iFirstVisibleRow =
       
  5309                 ((*iShowPagesRef)[iCaseIndex] - 1) * iExtension->iMaxVisibleRows;
       
  5310             pt.iX = Min(pt.iX, lastColumnOnLastRow);
       
  5311             pt.iY = iRows - 1;
       
  5312             if (iRows > iExtension->iMaxVisibleRows)
       
  5313                 {
       
  5314                 pt.iY -= (((iRows-1) / iExtension->iMaxVisibleRows) * iExtension->iMaxVisibleRows);
       
  5315                 }
       
  5316 
       
  5317             }
       
  5318         else if (iRows == 1)
       
  5319             {
       
  5320             pt.iX = Min(pt.iX, lastColumnOnLastRow);
       
  5321             }
       
  5322         else if (caseChange)
       
  5323             {
       
  5324             // When first line is NULL, cursor is moved to the second line
       
  5325             TInt index = pt.iX + (pt.iY + iFirstVisibleRow) * iMaxColumns;
       
  5326             for (; index >= 0 ; index--)
       
  5327                 {
       
  5328                 if ( (iChaMapTableCase!=EAknCharMapTableSpecialChar && iPictoInterface->Interface()->IsPictograph((*iChars)[index])) || 
       
  5329                      (iChaMapTableCase==EAknCharMapTableSpecialChar && (*iChars)[index] != KHistoryEmptyChar) )
       
  5330                     {
       
  5331                     break;
       
  5332                     }
       
  5333                 }
       
  5334             if (index < 0)
       
  5335                 {
       
  5336                 pt.iY = 1;
       
  5337                 }
       
  5338             else
       
  5339                 {
       
  5340                 pt.iX = index;
       
  5341                 }
       
  5342             }
       
  5343         
       
  5344         HandleFocusStatusChanged();
       
  5345 
       
  5346         iCursorPos = pt;
       
  5347         UpdateScrollIndicatorL();
       
  5348         DrawNow();
       
  5349         }
       
  5350     else
       
  5351         {
       
  5352         if (caseChange)
       
  5353             {
       
  5354             TPoint pt(iCursorPos);
       
  5355             // When first line is NULL, cursor is moved to the second line
       
  5356             TInt index = pt.iX + (pt.iY + iFirstVisibleRow) * iMaxColumns;
       
  5357             for (; index >= 0 ; index--)
       
  5358                 {
       
  5359                 if ( (iChaMapTableCase!=EAknCharMapTableSpecialChar && iPictoInterface->Interface()->IsPictograph((*iChars)[index])) || 
       
  5360                      (iChaMapTableCase==EAknCharMapTableSpecialChar && (*iChars)[index]!=KHistoryEmptyChar) )
       
  5361                     {
       
  5362                     break;
       
  5363                     }
       
  5364                 }
       
  5365             if (index < 0)
       
  5366                 {
       
  5367                 pt.iY = 1;
       
  5368                 }
       
  5369             else
       
  5370                 {
       
  5371                 pt.iX = (index % iMaxColumns);
       
  5372                 }
       
  5373             iCursorPos = pt;
       
  5374             }
       
  5375 
       
  5376         if ((iRows > iExtension->iMaxVisibleRows) &&
       
  5377             (iOldCursorPos.iY + oldFirstVisibleRow != iCursorPos.iY + iFirstVisibleRow))
       
  5378             {
       
  5379             UpdateScrollIndicatorL();
       
  5380             }
       
  5381         
       
  5382         HandleFocusStatusChanged();
       
  5383 
       
  5384         if (oldFirstVisibleRow == iFirstVisibleRow)
       
  5385             {
       
  5386                 // Draw only cursor if the view to the content was not scrolled.
       
  5387             DrawCursor();
       
  5388             }
       
  5389         else
       
  5390             {
       
  5391             DrawNow();
       
  5392             }
       
  5393         }
       
  5394     }
       
  5395 
       
  5396 void CAknCharMap::UpdateScrollIndicatorL()
       
  5397     {
       
  5398     if ( !iSBFrame )
       
  5399         {
       
  5400         return;
       
  5401         }
       
  5402     TEikScrollBarModel hSbarModel;
       
  5403     TEikScrollBarModel vSbarModel;
       
  5404 
       
  5405     TEikScrollBarFrameLayout layout;
       
  5406 
       
  5407     // Main pane without softkeys
       
  5408     TRect mainPaneRect;
       
  5409     if(!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EPopupParent, mainPaneRect))
       
  5410         {
       
  5411         mainPaneRect = iAvkonAppUi->ClientRect();
       
  5412         }
       
  5413 
       
  5414     // Dialog layout, check variety first
       
  5415     TAknLayoutScalableParameterLimits charMapDialogVariety =
       
  5416         AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
       
  5417 
       
  5418     TInt maxVariety = charMapDialogVariety.LastVariety();
       
  5419 
       
  5420     // Check the CBA, if the orientation is not landscape
       
  5421     // there is not so much varieties
       
  5422     AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation();
       
  5423     TInt maxVarietyOffset = 0; // the offset for the certain cba location variety
       
  5424     TInt varietyOffset = maxVariety + 1;
       
  5425 
       
  5426     // landscape variety number must be calculated offset == number of varieties
       
  5427     // same applies to the variety number for the biggest sized layout for the variety
       
  5428     if(Layout_Meta_Data::IsLandscapeOrientation())
       
  5429         {
       
  5430         varietyOffset = (maxVariety + 1)/KAknSctCBaButtonDirections; // the offset for one variety
       
  5431         }
       
  5432 
       
  5433     // for right and left cba buttons the max variety is not zero
       
  5434     // the varities are ordered by the location of the cba and the descending order
       
  5435     // e.g the biggest sized layout first, the smallest last
       
  5436     if(location == AknLayoutUtils::EAknCbaLocationRight)
       
  5437         {
       
  5438         maxVarietyOffset = varietyOffset;
       
  5439         }
       
  5440     else if(location == AknLayoutUtils::EAknCbaLocationLeft)
       
  5441         {
       
  5442         maxVarietyOffset = varietyOffset + varietyOffset; // 2*
       
  5443         }
       
  5444 
       
  5445     TInt varietyNumber = varietyOffset - iRows;
       
  5446 
       
  5447     // if more lines than possible to show, use the default
       
  5448     // (the biggest grid) variety
       
  5449     if(varietyNumber < 0)
       
  5450         varietyNumber = 0;
       
  5451     // if zero rows, use the minimum
       
  5452     else if(iRows<=0)
       
  5453         varietyNumber -= 1;
       
  5454 
       
  5455     //add the varietyoffset
       
  5456     varietyNumber += maxVarietyOffset;
       
  5457 
       
  5458     // Layout the dialog size
       
  5459     TAknLayoutRect dialogLayRect;
       
  5460     dialogLayRect.LayoutRect( mainPaneRect,
       
  5461         AknLayoutScalable_Avkon::popup_grid_graphic_window(varietyNumber));
       
  5462 
       
  5463     TRect dialogRect = dialogLayRect.Rect();
       
  5464 
       
  5465     // Get the layout of the actual character grid with scrollbar
       
  5466     TAknLayoutRect gridWithScrollLayRect;
       
  5467 
       
  5468     gridWithScrollLayRect.LayoutRect(TRect(TPoint(0,0),TSize(dialogRect.Size())),
       
  5469         AknLayoutScalable_Avkon::listscroll_popup_graphic_pane());
       
  5470 
       
  5471     // Calculate the relative rect for the grid
       
  5472     TRect parent = gridWithScrollLayRect.Rect();
       
  5473 
       
  5474     TAknWindowComponentLayout scrollbarLayout;
       
  5475     if (iExtension->iHasCategoryButtonUi)
       
  5476         {
       
  5477         scrollbarLayout = AknLayoutScalable_Avkon::scroll_pane_cp5(1);
       
  5478         }
       
  5479     else
       
  5480         {
       
  5481         scrollbarLayout = AknLayoutScalable_Avkon::scroll_pane_cp5(0);
       
  5482         }
       
  5483 
       
  5484     vSbarModel.iScrollSpan = PageCount() * iExtension->iMaxVisibleRows;
       
  5485     vSbarModel.iThumbSpan = iExtension->iMaxVisibleRows;
       
  5486 
       
  5487     if (iSBFrame && iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan)
       
  5488         {
       
  5489         // For EDoubleSpan type scrollbar
       
  5490         vSbarModel.iThumbPosition = (CurrentPage()-1) * iExtension->iMaxVisibleRows;
       
  5491         TAknDoubleSpanScrollBarModel hDsSbarModel(hSbarModel);
       
  5492         TAknDoubleSpanScrollBarModel vDsSbarModel(vSbarModel);
       
  5493 
       
  5494         iSBFrame->Tile(&vDsSbarModel);
       
  5495         AknLayoutUtils::LayoutVerticalScrollBar(iSBFrame, parent,
       
  5496         scrollbarLayout);
       
  5497         iSBFrame->SetVFocusPosToThumbPos(vDsSbarModel.FocusPosition());
       
  5498         }
       
  5499     else
       
  5500         {
       
  5501         // For EArrowHead type scrollbar
       
  5502         vSbarModel.iThumbPosition = iCursorPos.iY + iFirstVisibleRow;
       
  5503         iSBFrame->TileL(&hSbarModel,&vSbarModel,parent,parent,layout);
       
  5504         iSBFrame->SetVFocusPosToThumbPos(vSbarModel.iThumbPosition);
       
  5505         }
       
  5506     }
       
  5507 
       
  5508 void CAknCharMap::Reserved_1()
       
  5509     {
       
  5510     }
       
  5511 
       
  5512 void CAknCharMap::Reserved_2()
       
  5513     {
       
  5514     }
       
  5515 
       
  5516 const TDesC* CAknCharMap::LowerCaseCharacters() const
       
  5517     {
       
  5518     return iCharsBufferLower;
       
  5519     }
       
  5520 
       
  5521 const TDesC* CAknCharMap::UpperCaseCharacters() const
       
  5522     {
       
  5523     return iCharsBufferUpper;
       
  5524     }
       
  5525 
       
  5526 const TDesC* CAknCharMap::NumericCharacters() const
       
  5527     {
       
  5528     return iCharsBufferNumeric;
       
  5529     }
       
  5530 
       
  5531 void CAknCharMap::CopyCharactersL( const CAknCharMap& aCharMap )
       
  5532     {
       
  5533     const TDesC* chars = aCharMap.LowerCaseCharacters();
       
  5534     if ( chars )
       
  5535         {
       
  5536         delete iCharsBufferLower;
       
  5537         iCharsBufferLower = NULL;
       
  5538         if (Extension()->iMenuSct)
       
  5539             {
       
  5540             iCharsBufferLower = chars->Mid(iMaxColumns).AllocL();
       
  5541             }
       
  5542         else
       
  5543             {
       
  5544             iCharsBufferLower = chars->AllocL();
       
  5545             }
       
  5546         }
       
  5547 
       
  5548     chars = aCharMap.UpperCaseCharacters();
       
  5549     if ( chars )
       
  5550         {
       
  5551         delete iCharsBufferUpper;
       
  5552         iCharsBufferUpper = NULL;
       
  5553         if (Extension()->iMenuSct)
       
  5554             {
       
  5555             iCharsBufferUpper = chars->Mid(iMaxColumns).AllocL();
       
  5556             }
       
  5557         else
       
  5558             {
       
  5559             iCharsBufferUpper = chars->AllocL();
       
  5560             }
       
  5561         }
       
  5562 
       
  5563     chars = aCharMap.NumericCharacters();
       
  5564     if ( chars )
       
  5565         {
       
  5566         delete iCharsBufferNumeric;
       
  5567         iCharsBufferNumeric = NULL;
       
  5568         if (Extension()->iMenuSct)
       
  5569             {
       
  5570             iCharsBufferNumeric = chars->Mid(iMaxColumns).AllocL();
       
  5571             }
       
  5572         else
       
  5573             {
       
  5574             iCharsBufferNumeric = chars->AllocL();
       
  5575             }
       
  5576         }
       
  5577 
       
  5578     chars = NULL;
       
  5579     if (aCharMap.iExtension)
       
  5580         {
       
  5581         chars = aCharMap.iExtension->iCharsQwerty;
       
  5582         }
       
  5583     if ( chars )
       
  5584         {
       
  5585         delete iExtension->iCharsQwerty;
       
  5586         iExtension->iCharsQwerty = NULL;
       
  5587         if (Extension()->iMenuSct)
       
  5588             {
       
  5589             iExtension->iCharsQwerty = chars->Mid(iMaxColumns).AllocL();
       
  5590             }
       
  5591         else
       
  5592             {
       
  5593             iExtension->iCharsQwerty = chars->AllocL();
       
  5594             }
       
  5595         }
       
  5596     }
       
  5597 
       
  5598 void CAknCharMap::DrawPictographArea()
       
  5599     {
       
  5600     if (iChaMapTableCase != EAknCharMapTableSpecialChar)
       
  5601         {
       
  5602         CWindowGc& gc = SystemGc();
       
  5603         if( !CAknEnv::Static()->TransparencyEnabled() )
       
  5604             {
       
  5605             ActivateGc();
       
  5606             gc.UseFont( iFont );
       
  5607             }
       
  5608 
       
  5609         // Calculate the number of items.
       
  5610         TInt numberOfCharsToBeDrawn = iChars->Length();
       
  5611         numberOfCharsToBeDrawn -= (iFirstVisibleRow * iMaxColumns);
       
  5612         if ( numberOfCharsToBeDrawn > (iExtension->iMaxVisibleRows * iMaxColumns))
       
  5613             {
       
  5614             numberOfCharsToBeDrawn = iExtension->iMaxVisibleRows * iMaxColumns;
       
  5615             }
       
  5616         __ASSERT_DEBUG( numberOfCharsToBeDrawn >= 1, Panic(EAknPanicOutOfRange));
       
  5617 
       
  5618         // Draw all items. Implementation takes care that only animated
       
  5619         // items are actually redrawn.
       
  5620 
       
  5621         iAnimated = ETrue;
       
  5622 
       
  5623         TInt cursorPos = iCursorPos.iX + iCursorPos.iY * iMaxColumns;
       
  5624 
       
  5625         for (TInt j = 0; j < numberOfCharsToBeDrawn; j++)
       
  5626             {
       
  5627             DrawCell( j, j == cursorPos );
       
  5628             }
       
  5629 
       
  5630         iAnimated = EFalse;
       
  5631 
       
  5632         if( !CAknEnv::Static()->TransparencyEnabled() )
       
  5633             {
       
  5634             gc.DiscardFont();
       
  5635             DeactivateGc();
       
  5636             }
       
  5637         }
       
  5638     }
       
  5639 
       
  5640 TInt CAknCharMap::PageCount() const
       
  5641     {
       
  5642     TInt page(0);
       
  5643     for (TInt i(0); i < iShowCasesRef->Count(); ++i)
       
  5644         {
       
  5645         page += (*iShowPagesRef)[i];
       
  5646         }
       
  5647 
       
  5648     return page;
       
  5649     }
       
  5650 
       
  5651 TInt CAknCharMap::CurrentPage() const
       
  5652     {
       
  5653     TInt page(0);
       
  5654     for (TInt i(0); i < iCaseIndex; ++i)
       
  5655         {
       
  5656         page += (*iShowPagesRef)[i];
       
  5657         }
       
  5658 
       
  5659     return ((iCursorPos.iY + iFirstVisibleRow) / iExtension->iMaxVisibleRows) + 1 + page;
       
  5660     }
       
  5661 
       
  5662 
       
  5663 TBool CAknCharMap::HasPictoInterface() const
       
  5664     {
       
  5665     return (iPictoInterface != NULL);
       
  5666     }
       
  5667 
       
  5668 TBool CAknCharMap::SwitchTablesL(TBool& aLayoutChanged)
       
  5669     {
       
  5670     aLayoutChanged = EFalse;
       
  5671 
       
  5672     TBool result(EFalse);
       
  5673 
       
  5674     if (iPictoInterface)
       
  5675         {
       
  5676         TInt oldVisibleRows = Min(iRows, iExtension->iMaxVisibleRows);
       
  5677 
       
  5678         iChaMapTableCase = (iChaMapTableCase!=EAknCharMapTableSpecialChar) ? EAknCharMapTableSpecialChar : EAknCharMapTablePicto;
       
  5679         iCaseIndex = 0;
       
  5680 
       
  5681         // In case picto, char case must be kept same as previous value.
       
  5682         TInt charcase = (iChaMapTableCase==EAknCharMapTableSpecialChar) ? iSpecialCharCases[iCaseIndex] : iSpecialCharCase;
       
  5683         SetCharacterCaseL(charcase);
       
  5684 
       
  5685         TInt visibleRows = Min(iRows, iExtension->iMaxVisibleRows);
       
  5686 
       
  5687         // Return also information whether the layout changed or not.
       
  5688         aLayoutChanged = (oldVisibleRows != visibleRows);
       
  5689 
       
  5690         if (!AknLayoutUtils::PenEnabled())
       
  5691             {
       
  5692             UpdateScrollIndicatorL();
       
  5693             }
       
  5694         else
       
  5695             {
       
  5696             UpdateInputFieldL();
       
  5697             }
       
  5698 
       
  5699         if (aLayoutChanged)
       
  5700             {
       
  5701             // If the number of the visible row is changed,
       
  5702             // it is necessary to re-create the background.
       
  5703             CreateOffscreenBackgroundL();
       
  5704             }
       
  5705 
       
  5706         result = ETrue;
       
  5707         }
       
  5708     else
       
  5709         {
       
  5710         result = SwitchSctAndEmotionL();
       
  5711         }
       
  5712 
       
  5713     return result;
       
  5714     }
       
  5715 
       
  5716 void CAknCharMap::CreateOffscreenBackgroundL()
       
  5717     {
       
  5718 	
       
  5719     }
       
  5720 
       
  5721 TInt CAknCharMap::NextPageL()
       
  5722     {
       
  5723     HandleFocusStatusChanged(EFalse);
       
  5724     
       
  5725     TInt page(0);
       
  5726     iFirstVisibleRow =
       
  5727         (((iCursorPos.iY + iFirstVisibleRow) / iExtension->iMaxVisibleRows) + 1)
       
  5728                                                     * iExtension->iMaxVisibleRows;
       
  5729     if (iFirstVisibleRow > VisibleRows())
       
  5730         {
       
  5731         iFirstVisibleRow = 0;
       
  5732 
       
  5733         if(iFirstVisibleRow == 0 &&
       
  5734         ( (iChaMapTableCase!=EAknCharMapTableSpecialChar && !iPictoInterface->Interface()->IsPictograph((*iChars)[0])) || 
       
  5735           (iChaMapTableCase==EAknCharMapTableSpecialChar && (*iChars)[0]==KHistoryEmptyChar)) )
       
  5736             {
       
  5737             iCursorPos = TPoint(0, 1);
       
  5738             }
       
  5739         else
       
  5740             {
       
  5741             iCursorPos = TPoint(0, 0);
       
  5742             }
       
  5743 
       
  5744         page = SwitchAnotherTableL(1);
       
  5745         }
       
  5746     else
       
  5747         {
       
  5748         if(iFirstVisibleRow == 0 &&
       
  5749         ( (iChaMapTableCase!=EAknCharMapTableSpecialChar && !iPictoInterface->Interface()->IsPictograph((*iChars)[0])) || 
       
  5750           (iChaMapTableCase==EAknCharMapTableSpecialChar && (*iChars)[0] == KHistoryEmptyChar)) )
       
  5751             {
       
  5752             iCursorPos = TPoint(0, 1);
       
  5753             }
       
  5754         else
       
  5755             {
       
  5756             iCursorPos = TPoint(0, 0);
       
  5757             }
       
  5758 
       
  5759         }
       
  5760     UpdateHeadingPane( ETrue );
       
  5761     UpdateScrollIndicatorL();
       
  5762     HandleFocusStatusChanged();
       
  5763     DrawNow();
       
  5764 
       
  5765     return page;
       
  5766     }
       
  5767 
       
  5768 TInt CAknCharMap::PrevPageL()
       
  5769     {
       
  5770     HandleFocusStatusChanged(EFalse);
       
  5771     
       
  5772     TInt page(0);
       
  5773     TInt firstVisibleRow =
       
  5774         (((iCursorPos.iY + iFirstVisibleRow) / iExtension->iMaxVisibleRows) - 1) *
       
  5775             iExtension->iMaxVisibleRows;
       
  5776     if (firstVisibleRow < 0)
       
  5777         {
       
  5778         SwitchAnotherTableL(-1);
       
  5779         iFirstVisibleRow = ((*iShowPagesRef)[iCaseIndex] - 1 ) * iExtension->iMaxVisibleRows;
       
  5780         if(iFirstVisibleRow == 0 &&
       
  5781             ( (iChaMapTableCase!=EAknCharMapTableSpecialChar && !iPictoInterface->Interface()->IsPictograph((*iChars)[0])) || 
       
  5782               (iChaMapTableCase==EAknCharMapTableSpecialChar && (*iChars)[0] == KHistoryEmptyChar)) )
       
  5783             {
       
  5784             iCursorPos = TPoint(0, 1);
       
  5785             }
       
  5786         else
       
  5787             {
       
  5788             iCursorPos = TPoint(0, 0);
       
  5789             }
       
  5790         }
       
  5791     else
       
  5792         {
       
  5793         iFirstVisibleRow = firstVisibleRow;
       
  5794         if(iFirstVisibleRow == 0 &&
       
  5795             ( (iChaMapTableCase!=EAknCharMapTableSpecialChar && !iPictoInterface->Interface()->IsPictograph((*iChars)[0])) || 
       
  5796               (iChaMapTableCase==EAknCharMapTableSpecialChar && (*iChars)[0] == KHistoryEmptyChar)) )
       
  5797             {
       
  5798             iCursorPos = TPoint(0, 1);
       
  5799             }
       
  5800         else
       
  5801             {
       
  5802             iCursorPos = TPoint(0, 0);
       
  5803             }
       
  5804         }
       
  5805     UpdateHeadingPane( ETrue );
       
  5806     UpdateScrollIndicatorL();
       
  5807     HandleFocusStatusChanged();
       
  5808     DrawNow();
       
  5809 
       
  5810     return page;
       
  5811     }
       
  5812 
       
  5813 HBufC* CAknCharMap::AppendTextL(HBufC* aChars, HBufC* aText)
       
  5814     {
       
  5815     if (!aChars)
       
  5816         {
       
  5817         return aText;
       
  5818         }
       
  5819 
       
  5820     aChars = aChars->ReAllocL(aChars->Length() + aText->Length());
       
  5821     aChars->Des().Append(aText->Des());
       
  5822     delete aText;
       
  5823 
       
  5824     return aChars;
       
  5825     }
       
  5826 
       
  5827 void CAknCharMap::DrawPicto(
       
  5828     CWindowGc& aGc,
       
  5829     const TRect& aSctPosition,
       
  5830     TInt aCharIndex,
       
  5831     TBool aHighlighted,
       
  5832     TBool aDrawBackground ) const
       
  5833     {
       
  5834     MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
  5835 
       
  5836     if (aHighlighted)
       
  5837         {
       
  5838         //aGc.SetPenColor(AKN_LAF_COLOR(215));
       
  5839         TRgb color = AKN_LAF_COLOR(215);
       
  5840         AknsUtils::GetCachedColor( skin, color,
       
  5841             KAknsIIDQsnLineColors, EAknsCIQsnLineColorsCG7 );
       
  5842         aGc.SetPenColor(color);
       
  5843         if (!IsRecentChar(aCharIndex))
       
  5844             {
       
  5845             aGc.DrawRect( aSctPosition );
       
  5846             }
       
  5847 
       
  5848         // Shrink by one pixel in all directions.
       
  5849         TRect innerRect = aSctPosition;
       
  5850         if (!IsRecentChar(aCharIndex))
       
  5851             {
       
  5852             innerRect.Shrink(1,1);
       
  5853             }
       
  5854 
       
  5855 
       
  5856         color = AKN_LAF_COLOR(210);
       
  5857         AknsUtils::GetCachedColor(skin,color,
       
  5858             KAknsIIDQsnHighlightColors,EAknsCIQsnHighlightColorsCG1);
       
  5859         aGc.SetBrushColor(color);
       
  5860         aGc.Clear( innerRect );
       
  5861         }
       
  5862 
       
  5863     // Draw the background of the item if requested
       
  5864     else if ( aDrawBackground )
       
  5865         {
       
  5866 		aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
       
  5867 		aGc.SetBrushColor(AKN_LAF_COLOR(0));
       
  5868 
       
  5869 		TRect innerRect = aSctPosition;
       
  5870 		if (IsRecentChar(aCharIndex))
       
  5871 			{
       
  5872 			innerRect.Shrink(1,1);
       
  5873 			}
       
  5874 		aGc.Clear( innerRect );
       
  5875         }
       
  5876     if (iPictoInterface->Interface()->IsPictograph((*iChars)[aCharIndex]))
       
  5877         {
       
  5878         if (iExtension->iPictographsBufferGrouping)
       
  5879             {
       
  5880             TAknPictographDrawingMode drawingMode =
       
  5881                 aHighlighted?EDrawingModeWhite:EDrawingModeNormal;
       
  5882             iPictoInterface->Interface()->SetPictographDrawingMode(drawingMode);
       
  5883             }
       
  5884         iPictoInterface->Interface()->DrawPictograph(
       
  5885             aGc,
       
  5886             aSctPosition,
       
  5887             (*iChars)[aCharIndex],
       
  5888             iCurrentPictographHeight );
       
  5889         }
       
  5890     }
       
  5891 
       
  5892 void CAknCharMap::DrawOffscreenBackgroundIfRequired() const
       
  5893     {
       
  5894 	
       
  5895     }
       
  5896 
       
  5897 EXPORT_C CCoeControl* CAknCharMap::ComponentControl(TInt aIndex) const
       
  5898     {
       
  5899     if (iSBFrame && iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan)
       
  5900         {
       
  5901         if ( aIndex == 0 )
       
  5902             {
       
  5903             return iSBFrame->VerticalScrollBar();
       
  5904             }
       
  5905         aIndex--;
       
  5906         }
       
  5907 
       
  5908     if (iExtension->iRadioButton)
       
  5909         {
       
  5910          if ( aIndex == 0 )
       
  5911             {
       
  5912             return iExtension->iRadioButton;
       
  5913             }
       
  5914         aIndex--;
       
  5915         }
       
  5916 
       
  5917     if (iExtension->iCategoryTitle)
       
  5918         {
       
  5919         if ( aIndex == 0 )
       
  5920             {
       
  5921             return iExtension->iCategoryTitle;
       
  5922             }
       
  5923         aIndex--;
       
  5924         }
       
  5925     if (iExtension->iCategoryEntry)
       
  5926         {
       
  5927         if ( aIndex == 0 )
       
  5928             {
       
  5929             return iExtension->iCategoryEntry;
       
  5930             }
       
  5931         aIndex--;
       
  5932         }
       
  5933 
       
  5934     if (iExtension->iTableNavi)
       
  5935         {
       
  5936          if ( aIndex == 0 )
       
  5937             {
       
  5938             return iExtension->iTableNavi;
       
  5939             }
       
  5940         aIndex--;
       
  5941         }
       
  5942     if (iExtension->iPageNavi)
       
  5943         {
       
  5944          if ( aIndex == 0 )
       
  5945             {
       
  5946             return iExtension->iPageNavi;
       
  5947             }
       
  5948         aIndex--;
       
  5949         }
       
  5950 
       
  5951     return NULL;
       
  5952     }
       
  5953 
       
  5954 EXPORT_C TInt CAknCharMap::CountComponentControls() const
       
  5955     {
       
  5956     TInt num = 0;
       
  5957     if (iSBFrame && iSBFrame->TypeOfVScrollBar() == CEikScrollBarFrame::EDoubleSpan)
       
  5958         {
       
  5959         num++;
       
  5960         }
       
  5961     if (iExtension->iRadioButton)
       
  5962         {
       
  5963         num++;
       
  5964         }
       
  5965     if (iExtension->iCategoryTitle)
       
  5966         {
       
  5967         num++;
       
  5968         }
       
  5969     if (iExtension->iCategoryEntry)
       
  5970         {
       
  5971         num++;
       
  5972         }
       
  5973     if (iExtension->iTableNavi)
       
  5974         {
       
  5975         num++;
       
  5976         }
       
  5977     if (iExtension->iPageNavi)
       
  5978         {
       
  5979         num++;
       
  5980         }
       
  5981     return num;
       
  5982     }
       
  5983 
       
  5984 void CAknCharMap::SetPictoMode(TAknCharMapPictoMode aMode)
       
  5985     {
       
  5986     if (aMode == EAknCharMapPictoNoUse)
       
  5987         {
       
  5988         delete iPictoInterface;
       
  5989         iPictoInterface = NULL;
       
  5990         }
       
  5991     else if (aMode == EAknCharMapPictoFirst)
       
  5992         {
       
  5993         iChaMapTableCase = EAknCharMapTablePicto;
       
  5994         }
       
  5995     }
       
  5996 
       
  5997 void CAknCharMap::SetCaseTableL(const RArray<TInt> & aCase)
       
  5998     {
       
  5999 
       
  6000     // set current case characters to display on SCT
       
  6001     HBufC* currentcasechars = iCharsBufferLower;
       
  6002     if (iCharsBufferUpper && iSpecialCharCase==EAknSCTUpperCase)
       
  6003         currentcasechars = iCharsBufferUpper;
       
  6004     else if (iCharsBufferNumeric && iSpecialCharCase==EAknSCTNumeric)
       
  6005         currentcasechars = iCharsBufferNumeric;
       
  6006     else if (iCharsBufferFull && iSpecialCharCase==EAknSCTFullCase)
       
  6007         currentcasechars = iCharsBufferFull;
       
  6008     else if (iCharsBufferHalf && iSpecialCharCase==EAknSCTHalfCase)
       
  6009         currentcasechars = iCharsBufferHalf;
       
  6010     else if (iExtension->iCharsQwerty && iSpecialCharCase==EAknSCTQwerty)
       
  6011         currentcasechars = iExtension->iCharsQwerty;
       
  6012 
       
  6013     iSpecialCharPages.AppendL( PageCountFromChars(*currentcasechars) );
       
  6014 
       
  6015     iSpecialCharCases.AppendL( iSpecialCharCase );
       
  6016     if (iExtension->iRadioButton)
       
  6017         {
       
  6018         // Set the sct case mode to valid
       
  6019         iExtension->iRadioButton->SetValidSctCase(iSpecialCharCase);
       
  6020         }
       
  6021 
       
  6022     if (aCase.Count() > 0)
       
  6023         {
       
  6024         for (TInt i(0); i < aCase.Count(); ++i)
       
  6025             {
       
  6026             HBufC* chars = CharsFromCase(aCase[i]);
       
  6027             if (chars)
       
  6028                 {
       
  6029                 iSpecialCharCases.AppendL( aCase[i] );
       
  6030                 iSpecialCharPages.AppendL( PageCountFromChars(*chars) );
       
  6031                 if (iExtension->iRadioButton)
       
  6032                     {
       
  6033                     // Set the sct case mode to valid
       
  6034                     iExtension->iRadioButton->SetValidSctCase(aCase[i]);
       
  6035                     }
       
  6036                 }
       
  6037             }
       
  6038         }
       
  6039 
       
  6040     if (iExtension->iPictographsBuffer && iPictoInterface)
       
  6041         {
       
  6042         __ASSERT_ALWAYS(
       
  6043             iPictoInterface->Interface(), Panic(EAknPanicNullPointer));
       
  6044 
       
  6045         iPictographPages.AppendL( PageCountFromChars(*iPictographsBuffer) );
       
  6046         iPictographCases.AppendL(EAknCharMapTablePicto);
       
  6047         if (iExtension->iPictographsBufferGrouping)
       
  6048             {
       
  6049             iPictographPages.AppendL( PageCountFromChars(*iPictographsBuffer2) );
       
  6050             iPictographCases.AppendL(EAknCharMapTablePicto2);
       
  6051             if (iExtension->iRadioButton)
       
  6052                 {
       
  6053                 // Set the sct case mode to valid
       
  6054                 iExtension->iRadioButton->SetValidSctCase(EAknSCTPictograph1);
       
  6055                 iExtension->iRadioButton->SetValidSctCase(EAknSCTPictograph2);
       
  6056                 }
       
  6057             }
       
  6058         else
       
  6059             {
       
  6060             if (iExtension->iRadioButton)
       
  6061                 {
       
  6062                 // Set the sct case mode to valid
       
  6063                 iExtension->iRadioButton->SetValidSctCase(EAknSCTPictograph);
       
  6064                 }
       
  6065             }
       
  6066         }
       
  6067 
       
  6068     if (iExtension->iRadioButton)
       
  6069         {
       
  6070         // Remove invalid category buttons
       
  6071         iExtension->iRadioButton->RemoveInvalidButton();
       
  6072         __ASSERT_DEBUG( iExtension->iRadioButton->Count() > 0,
       
  6073             Panic(EAknPanicInvalidValue));
       
  6074         }
       
  6075     }
       
  6076 
       
  6077 void CAknCharMap::SetTitleL(TPtrC aTitle)
       
  6078     {
       
  6079     iTitleDefault = HBufC::NewL(aTitle.Length());
       
  6080     iTitleDefault->Des().Copy(aTitle);
       
  6081 
       
  6082     HBufC* title;
       
  6083     if (iExtension->iPictographsBufferGrouping)
       
  6084         {
       
  6085         title = StringLoader::LoadLC(
       
  6086             R_AVKON_SPECIAL_CHARACTERS_PICTOGRAPH1, iCoeEnv);
       
  6087         iTitlePicto = HBufC::NewL(title->Length());
       
  6088         iTitlePicto->Des().Copy(*title);
       
  6089         CleanupStack::PopAndDestroy(title); // title
       
  6090 
       
  6091         title = StringLoader::LoadLC(
       
  6092             R_AVKON_SPECIAL_CHARACTERS_PICTOGRAPH2, iCoeEnv);
       
  6093         iTitlePicto2 = HBufC::NewL(title->Length());
       
  6094         iTitlePicto2->Des().Copy(*title);
       
  6095         CleanupStack::PopAndDestroy(title); // title
       
  6096         }
       
  6097     else
       
  6098         {
       
  6099         title = StringLoader::LoadLC(
       
  6100             R_AVKON_SPECIAL_CHARACTERS_PICTOGRAPH, iCoeEnv);
       
  6101         iTitlePicto = HBufC::NewL(title->Length());
       
  6102         iTitlePicto->Des().Copy(*title);
       
  6103         CleanupStack::PopAndDestroy(title); // title
       
  6104         // Picto2 isn't used.
       
  6105         iTitlePicto2 = NULL;
       
  6106         }
       
  6107 
       
  6108     title = StringLoader::LoadLC(
       
  6109         R_AVKON_SPECIAL_CHARACTERS_HALF_SYMBOL, iCoeEnv);
       
  6110     iTitleHalf = HBufC::NewL(title->Length());
       
  6111     iTitleHalf->Des().Copy(*title);
       
  6112     CleanupStack::PopAndDestroy(); // title
       
  6113 
       
  6114     title = StringLoader::LoadLC(
       
  6115         R_AVKON_SPECIAL_CHARACTERS_FULL_SYMBOL, iCoeEnv);
       
  6116     iTitleFull = HBufC::NewL(title->Length());
       
  6117     iTitleFull->Des().Copy(*title);
       
  6118     CleanupStack::PopAndDestroy(); // title
       
  6119     }
       
  6120 
       
  6121 const TDesC* CAknCharMap::Title() const
       
  6122     {
       
  6123     HBufC* title = iTitleDefault;
       
  6124     if (iChaMapTableCase == EAknCharMapTableSpecialChar)
       
  6125         {
       
  6126         if (iSpecialCharCase == EAknSCTHalfCase)
       
  6127             {
       
  6128             title = iTitleHalf;
       
  6129             }
       
  6130         if (iSpecialCharCase == EAknSCTFullCase)
       
  6131             {
       
  6132             title = iTitleFull;
       
  6133             }
       
  6134         }
       
  6135     else
       
  6136         {
       
  6137         if (iCaseIndex == 1)
       
  6138             {
       
  6139             title = iTitlePicto2;
       
  6140             }
       
  6141         else
       
  6142             {
       
  6143             title = iTitlePicto;
       
  6144             }
       
  6145         }
       
  6146     return title;
       
  6147     }
       
  6148 
       
  6149 TInt CAknCharMap::SwitchAnotherTableL(TInt aIncrement)
       
  6150     {
       
  6151     TInt page(0);
       
  6152     if (iShowCasesRef->Count() > 1)
       
  6153         {
       
  6154         iCaseIndex += aIncrement;
       
  6155         if (iShowCasesRef->Count() - 1 < iCaseIndex)
       
  6156             {
       
  6157             iCaseIndex = 0;
       
  6158             }
       
  6159         if (iCaseIndex < 0)
       
  6160             {
       
  6161             iCaseIndex = iShowCasesRef->Count() - 1;
       
  6162             }
       
  6163         SetCharacterCaseL((*iShowCasesRef)[iCaseIndex]);
       
  6164         page = PageCount();
       
  6165         }
       
  6166     return page;
       
  6167     }
       
  6168 
       
  6169 void CAknCharMap::CountMaxColumnsAndCellSizes()
       
  6170     {
       
  6171     TRect mainPaneRect;
       
  6172     if (!AknLayoutUtils::PenEnabled() || Extension()->iMenuSct)
       
  6173         {
       
  6174         if(!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EMainPane, mainPaneRect))
       
  6175             {
       
  6176             mainPaneRect = iAvkonAppUi->ClientRect();
       
  6177             }
       
  6178 
       
  6179         TAknLayoutScalableParameterLimits charMapDialogVariety =
       
  6180             AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
       
  6181 
       
  6182         TInt maxVariety = charMapDialogVariety.LastVariety();
       
  6183 
       
  6184         AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation();
       
  6185         TInt maxVarietyOffset = 0;
       
  6186         TInt varietyOffset = maxVariety + 1;
       
  6187         if(Layout_Meta_Data::IsLandscapeOrientation())
       
  6188             {
       
  6189             varietyOffset = (maxVariety + 1) / KAknSctCBaButtonDirections;
       
  6190             }
       
  6191 
       
  6192         if(location == AknLayoutUtils::EAknCbaLocationRight)
       
  6193             {
       
  6194             maxVarietyOffset = varietyOffset;
       
  6195             }
       
  6196         else if(location == AknLayoutUtils::EAknCbaLocationLeft)
       
  6197             {
       
  6198             maxVarietyOffset = varietyOffset + varietyOffset;
       
  6199             }
       
  6200 
       
  6201         TAknLayoutRect popupGridLayRect;
       
  6202         popupGridLayRect.LayoutRect(mainPaneRect,
       
  6203             AknLayoutScalable_Avkon::popup_grid_graphic_window(maxVarietyOffset));
       
  6204 
       
  6205         TAknLayoutRect gridWithScrollLayRect;
       
  6206         gridWithScrollLayRect.LayoutRect(popupGridLayRect.Rect(),
       
  6207             AknLayoutScalable_Avkon::listscroll_popup_graphic_pane());
       
  6208 
       
  6209 
       
  6210         TAknLayoutRect gridLayRect;
       
  6211         if (iExtension->iHasCategoryButtonUi)
       
  6212             {
       
  6213             gridLayRect.LayoutRect(gridWithScrollLayRect.Rect(),
       
  6214                 AknLayoutScalable_Avkon::grid_graphic_popup_pane(2));
       
  6215             }
       
  6216         else
       
  6217             {
       
  6218             gridLayRect.LayoutRect(gridWithScrollLayRect.Rect(),
       
  6219                 AknLayoutScalable_Avkon::grid_graphic_popup_pane(0));
       
  6220             }
       
  6221 
       
  6222         TRect gridRect = Extension()->iMenuSct ? Rect(): gridLayRect.Rect();
       
  6223 
       
  6224         TAknLayoutRect firstCellLayRect;
       
  6225         firstCellLayRect.LayoutRect(gridRect,
       
  6226             AknLayoutScalable_Avkon::cell_graphic_popup_pane_cp2(0,0,0));
       
  6227 
       
  6228         TRect firstCellRect;
       
  6229         if ( Extension()->iMenuSct )
       
  6230             {
       
  6231             firstCellRect = TRect( TPoint(0, 0),
       
  6232                  TSize( firstCellLayRect.Rect().Width(), Rect().Height() ) );
       
  6233             }
       
  6234         else
       
  6235             {
       
  6236             firstCellRect = firstCellLayRect.Rect();
       
  6237             }
       
  6238 
       
  6239         TAknLayoutRect rightCellLayRect;
       
  6240         rightCellLayRect.LayoutRect(gridRect,
       
  6241             AknLayoutScalable_Avkon::cell_graphic_popup_pane_cp2(0,1,0));
       
  6242 
       
  6243         TInt firstVisibleIndex = iFirstVisibleRow * iMaxColumns;
       
  6244         // Max columns.
       
  6245         iMaxColumns = gridRect.Width() / firstCellRect.Width();
       
  6246         iFirstVisibleRow = firstVisibleIndex / iMaxColumns;
       
  6247 
       
  6248         // Max visible rows.
       
  6249         iExtension->iMaxVisibleRows = gridRect.Height() / firstCellRect.Height();
       
  6250 
       
  6251         // Cell width.
       
  6252         iGridItemWidth =
       
  6253             rightCellLayRect.Rect().iTl.iX - firstCellLayRect.Rect().iTl.iX;
       
  6254         if (iGridItemWidth < 0)
       
  6255             {
       
  6256             iGridItemWidth = -iGridItemWidth;
       
  6257             }
       
  6258 
       
  6259         // Cell height.
       
  6260         if ( Extension()->iMenuSct )
       
  6261             {
       
  6262             iGridItemHeight = firstCellRect.Height();
       
  6263             }
       
  6264         else
       
  6265             {
       
  6266             TAknLayoutRect downCellLayRect;
       
  6267             downCellLayRect.LayoutRect(gridRect,
       
  6268                 AknLayoutScalable_Avkon::cell_graphic_popup_pane_cp2(0,0,1));
       
  6269             iGridItemHeight =
       
  6270                 downCellLayRect.Rect().iTl.iY - firstCellLayRect.Rect().iTl.iY;
       
  6271             }
       
  6272         }
       
  6273     else
       
  6274         {
       
  6275         TAknLayoutRect popupGridLayRect;
       
  6276         popupGridLayRect.LayoutRect(iAvkonAppUi->ApplicationRect(),
       
  6277             AknLayoutScalable_Avkon::popup_grid_graphic2_window(0));
       
  6278 
       
  6279         TRect popupGridRect = popupGridLayRect.Rect();
       
  6280 
       
  6281         TInt gridVariety;
       
  6282         if (!IsJapaneseSctUi())
       
  6283             {
       
  6284             if(!Layout_Meta_Data::IsLandscapeOrientation())
       
  6285                 {
       
  6286                 gridVariety = (TableCount() > 1) ? 0 : 1;
       
  6287                 }
       
  6288             else
       
  6289                 {
       
  6290                 gridVariety = (TableCount() > 1) ? 2 : 3;
       
  6291                 }
       
  6292             }
       
  6293         else
       
  6294             {
       
  6295             gridVariety = !Layout_Meta_Data::IsLandscapeOrientation() ? 4 : 5;
       
  6296             }
       
  6297 
       
  6298         TAknLayoutRect gridLayRect;
       
  6299         gridLayRect.LayoutRect(popupGridRect,
       
  6300             AknLayoutScalable_Avkon::grid_graphic2_pane(gridVariety));
       
  6301 
       
  6302         TRect gridRect = gridLayRect.Rect();
       
  6303 
       
  6304         TAknLayoutRect firstCellLayRect;
       
  6305         firstCellLayRect.LayoutRect(popupGridRect,
       
  6306             AknLayoutScalable_Avkon::aid_size_cell_graphic2(gridVariety,0,0));
       
  6307 
       
  6308         TRect firstCellRect = firstCellLayRect.Rect();
       
  6309         TInt firstVisibleIndex = iFirstVisibleRow * iMaxColumns;
       
  6310 
       
  6311         // Max columns.
       
  6312         iMaxColumns = gridRect.Width() / firstCellRect.Width();
       
  6313         iFirstVisibleRow = firstVisibleIndex / iMaxColumns;
       
  6314 
       
  6315         // Max visible rows.
       
  6316         iExtension->iMaxVisibleRows = gridRect.Height() / firstCellRect.Height();
       
  6317 
       
  6318         // Cell width.
       
  6319         iGridItemWidth = firstCellRect.Width();
       
  6320 
       
  6321         // Cell height.
       
  6322         iGridItemHeight = firstCellRect.Height();
       
  6323         }
       
  6324     }
       
  6325 
       
  6326 HBufC* CAknCharMap::CharsFromCase(TInt aCharCase) const
       
  6327     {
       
  6328    __ASSERT_DEBUG( iExtension, Panic(EAknPanicInvalidValue));
       
  6329 
       
  6330     HBufC* chars = NULL;
       
  6331     switch (aCharCase)
       
  6332         {
       
  6333         case EAknSCTLowerCase:
       
  6334             chars = iCharsBufferLower;
       
  6335             break;
       
  6336         case EAknSCTUpperCase:
       
  6337             chars = iCharsBufferUpper;
       
  6338             break;
       
  6339         case EAknSCTNumeric:
       
  6340             chars = iCharsBufferNumeric;
       
  6341             break;
       
  6342         case EAknSCTFullCase:
       
  6343             chars = iCharsBufferFull;
       
  6344             break;
       
  6345         case EAknSCTHalfCase:
       
  6346             chars = iCharsBufferHalf;
       
  6347             break;
       
  6348         case EAknSCTQwerty:
       
  6349              chars = iExtension->iCharsQwerty;
       
  6350             break;
       
  6351         default:
       
  6352             break;
       
  6353         }
       
  6354     return chars;
       
  6355     }
       
  6356 
       
  6357 TInt CAknCharMap::PageCountFromChars(TDesC& aChars) const
       
  6358     {
       
  6359     TInt page(aChars.Length() / (iExtension->iMaxVisibleRows * iMaxColumns));
       
  6360     if ((page * (iExtension->iMaxVisibleRows * iMaxColumns)) != aChars.Length())
       
  6361         {
       
  6362         page++;
       
  6363         }
       
  6364     return page;
       
  6365     }
       
  6366 
       
  6367 TInt CAknCharMap::VisibleRows() const
       
  6368     {
       
  6369     TInt count((*iShowPagesRef)[iCaseIndex] - 1);
       
  6370     return count * iExtension->iMaxVisibleRows;
       
  6371     }
       
  6372 
       
  6373 void CAknCharMap::CreatePictoCharL()
       
  6374     {
       
  6375     if (!iExtension->iPictographsBuffer)
       
  6376         {
       
  6377         return;
       
  6378         }
       
  6379 
       
  6380     delete iPictographsBuffer;
       
  6381     iPictographsBuffer = NULL;
       
  6382     delete iPictographsBuffer2;
       
  6383     iPictographsBuffer2 = NULL;
       
  6384     delete iPictoInterface;
       
  6385     iPictoInterface = NULL;
       
  6386 
       
  6387     iPictoInterface = CAknPictographInterface::NewL(*this, *this);
       
  6388     if (iPictoInterface)
       
  6389         {
       
  6390         __ASSERT_ALWAYS(iFont, Panic(EAknPanicNullPointer));
       
  6391         iCurrentPictographHeight = EHeight16;
       
  6392         iPictoInterface->Interface()->SelectPictographHeightForFont(*iFont,iCurrentPictographHeight);
       
  6393         }
       
  6394 
       
  6395     // set pictograph characters
       
  6396     if (iExtension->iPictographsBufferGrouping)
       
  6397         {
       
  6398         for (TInt index=0; index < 2; index++)
       
  6399             {
       
  6400             PictograhGrouping::TAknPictographGroupType type =
       
  6401                 ( index == 0 )? PictograhGrouping::TAknPictographGroup1
       
  6402                                 : PictograhGrouping::TAknPictographGroup2;
       
  6403             // get pictograph characters
       
  6404             HBufC* temp = PictograhGrouping::AllocStringLC(type);
       
  6405             HBufC* buf = HBufC::NewL(temp->Length());
       
  6406             TPtr ptr(buf->Des());
       
  6407             ptr.Append(*temp);
       
  6408             CleanupStack::PopAndDestroy(temp); // temp
       
  6409 
       
  6410             if ( index == 0 )
       
  6411                 {
       
  6412                 iPictographsBuffer = buf;
       
  6413                 }
       
  6414             else
       
  6415                 {
       
  6416                 iPictographsBuffer2 = buf;
       
  6417                 }
       
  6418             }
       
  6419         }
       
  6420     else if ( iPictoInterface )
       
  6421         {
       
  6422         // get pictograph characters
       
  6423         HBufC* temp =
       
  6424             iPictoInterface->Interface()->SupportedPictographCodesL();
       
  6425         CleanupStack::PushL(temp);
       
  6426 
       
  6427         iPictographsBuffer = HBufC::NewL(temp->Length());
       
  6428         TPtr ptr = iPictographsBuffer->Des();
       
  6429         ptr.Append(*temp);
       
  6430         CleanupStack::PopAndDestroy(temp); // temp
       
  6431 
       
  6432         // picto2 is not used.
       
  6433         iPictographsBuffer2 = NULL;
       
  6434         }
       
  6435 
       
  6436     // EFalse is set to iSetRecentPic variable when setting special
       
  6437     // characters from resouce.
       
  6438     iSetRecentPic = EFalse;
       
  6439     }
       
  6440 
       
  6441 //--------------------------------------------------------------------------
       
  6442 // void CAknCharMap::HandlePointerEventL()
       
  6443 // The function works in two different ways. First (1), if the pointer is set
       
  6444 // down or dragged the "focus" shall either move to it or follow the pointer.
       
  6445 // Second (2) when the pointer is lifted the char below the pointer is set in
       
  6446 // to the array in which all the special characters are placed by the normal
       
  6447 // (rocker) method.
       
  6448 //--------------------------------------------------------------------------
       
  6449 EXPORT_C void CAknCharMap::HandlePointerEventL(const TPointerEvent& aPointerEvent)
       
  6450     {
       
  6451     if ( AknLayoutUtils::PenEnabled() && Rect().Contains(aPointerEvent.iPosition))
       
  6452         {
       
  6453         if (iExtension->iFocusHandler->FocusedControl() != this)// Tapping will move focus to grid.
       
  6454             {
       
  6455             iExtension->iFocusHandler->LeaveControl();
       
  6456             iExtension->iFocusHandler = iExtension;
       
  6457             }
       
  6458 
       
  6459         TInt newGridX; // For the whole
       
  6460         TInt newGridY; // For the whole grid.
       
  6461         TInt yInPixels = aPointerEvent.iPosition.iY - iGridTopLeft.iY;
       
  6462         newGridY = yInPixels / iGridItemHeight;
       
  6463 
       
  6464         newGridX = -1;
       
  6465 
       
  6466         if ( iIsMirrored )
       
  6467             {
       
  6468             TInt topRight = iGridTopLeft.iX - ( iMaxColumns - 1 ) * iGridItemWidth;
       
  6469             TInt topLeft = iGridTopLeft.iX + iGridItemWidth;
       
  6470             if ( ( aPointerEvent.iPosition.iX > topRight ) &&
       
  6471                 ( aPointerEvent.iPosition.iX < topLeft ) )
       
  6472                 {
       
  6473                 newGridX = ( topLeft - aPointerEvent.iPosition.iX ) / iGridItemWidth;
       
  6474                 }
       
  6475             }
       
  6476         else if ((aPointerEvent.iPosition.iX - iGridTopLeft.iX) > 0)
       
  6477             {
       
  6478             newGridX = (aPointerEvent.iPosition.iX - iGridTopLeft.iX) / iGridItemWidth;
       
  6479             }
       
  6480 
       
  6481         // The pointer has been set down or dragged into the area of the grid. (it might be in
       
  6482         // the "white space" at the end of the grid)
       
  6483         if ((yInPixels >= 0 && yInPixels < iGridItemHeight * iExtension->iMaxVisibleRows) &&
       
  6484             // When the pointer is in rows except the recent character row
       
  6485             ((((newGridY + iFirstVisibleRow) != 0) && newGridX < iMaxColumns && newGridX >= 0) ||
       
  6486             // When the pointer is in the recent character row
       
  6487             ( (newGridY + iFirstVisibleRow == 0) && (newGridX< LengthOfRecentChar()))) )
       
  6488             {
       
  6489             // For any action to be taken, the pointer event must either be a Button1Down or a drag event
       
  6490             // which has originated from a Button1Down in to the grid.
       
  6491             if (iExtension->iFlags&EAknCharMapHasBeenScrolledByDrag ||
       
  6492                 aPointerEvent.iType == TPointerEvent::EButton1Down  ||
       
  6493                 iExtension->iFlags&EAknCharMapButton1DownInGrid)
       
  6494                 {
       
  6495                 if (aPointerEvent.iType == TPointerEvent::EButton1Down)
       
  6496                     {
       
  6497                     iExtension->iSelectAllowed = ETrue; // enable selection.
       
  6498                     }
       
  6499                 iExtension->iFlags |= EAknCharMapButton1DownInGrid;
       
  6500                 TUint globalY = newGridY + iFirstVisibleRow;
       
  6501                 if (iChars->Length() > globalY * iMaxColumns + newGridX)
       
  6502                     {
       
  6503                     if (aPointerEvent.iType == TPointerEvent::EButton1Down ||
       
  6504                         aPointerEvent.iType == TPointerEvent::EDrag)
       
  6505                         {
       
  6506                         if (iCursorPos.iX+(iCursorPos.iY+iFirstVisibleRow)*iMaxColumns < iChars->Length())
       
  6507                             {
       
  6508                             iOldCursorPos = iCursorPos;
       
  6509                             }
       
  6510                         else
       
  6511                             {
       
  6512                             iOldCursorPos.iX = 0;
       
  6513                             iOldCursorPos.iY = 0;
       
  6514                             }
       
  6515 
       
  6516                         iCursorPos.iY = newGridY;
       
  6517                         iCursorPos.iX = newGridX;
       
  6518 
       
  6519                         if( iExtension->iSingleClickEnabled && 
       
  6520                             iExtension->iHighlightVisible &&
       
  6521                             aPointerEvent.iType == TPointerEvent::EDrag )
       
  6522                             {
       
  6523                             TInt focusPos = iCursorPos.iX + ( iFirstVisibleRow + 
       
  6524                                     iCursorPos.iY ) * iMaxColumns;
       
  6525                             TInt oldFocusPos = iOldCursorPos.iX + (
       
  6526                                     iFirstVisibleRow + 
       
  6527                                     iOldCursorPos.iY ) * iMaxColumns;
       
  6528                             if ( focusPos != oldFocusPos )
       
  6529                                 {
       
  6530                                 iExtension->iHighlightVisible = EFalse;
       
  6531                                 iExtension->iSelectAllowed = EFalse;
       
  6532                                 }
       
  6533                             }
       
  6534                         
       
  6535                         if ( aPointerEvent.iType == TPointerEvent::EButton1Down )
       
  6536                             {
       
  6537                             iExtension->iFlags |= EAknCharMapPressedDown;
       
  6538                             }
       
  6539                         else if ( iOldCursorPos != iCursorPos )
       
  6540                             {
       
  6541                             iExtension->iFlags &= (~EAknCharMapPressedDown);
       
  6542                             }
       
  6543                                 
       
  6544                         // down event on an item, play feedback
       
  6545                         MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  6546                         if ( feedback &&
       
  6547                              aPointerEvent.iType == TPointerEvent::EButton1Down )
       
  6548                             {
       
  6549                             feedback->InstantFeedback( this, ETouchFeedbackList );
       
  6550                             }
       
  6551                         if ( aPointerEvent.iType == TPointerEvent::EDrag &&
       
  6552                              iCursorPos != iOldCursorPos )
       
  6553                             {
       
  6554                             // Disable selection.
       
  6555                             iExtension->iSelectAllowed = EFalse;
       
  6556 
       
  6557                             if ( iExtension->iKineticScrolling )
       
  6558                                 {
       
  6559                                 // Don't allow changing the item by dragging.
       
  6560                                 iCursorPos = iOldCursorPos;
       
  6561                                 }
       
  6562                             }
       
  6563 
       
  6564                         if( aPointerEvent.iType == TPointerEvent::EButton1Down )
       
  6565                             {
       
  6566                             if( iExtension->iSingleClickEnabled )
       
  6567                                 {
       
  6568                                 iExtension->iHighlightVisible = ETrue;
       
  6569                                 }
       
  6570                         
       
  6571                             HandleFocusStatusChanged();
       
  6572                             }
       
  6573                         
       
  6574                         DrawCursor();
       
  6575                         }
       
  6576                     else if (aPointerEvent.iType == TPointerEvent::EButton1Up)
       
  6577                         {
       
  6578                         // Observe that selection has been changed, so char map dialog can get
       
  6579                         // selected char, add it to text and close.
       
  6580                         if (iExtension->iObserver &&
       
  6581                             iExtension->iFlags & EAknCharMapPressedDown)
       
  6582                             {
       
  6583                             iStatusChanged =
       
  6584                                 iExtension->iSelectAllowed ?
       
  6585                                     EAknCharSelectedSpecialCharacter : EAknCharNoSelection;
       
  6586                             // up event hit the same item that was selected by down event,
       
  6587                             // play feedback
       
  6588                             MTouchFeedback* feedback = MTouchFeedback::Instance();
       
  6589                             if ( feedback )
       
  6590                                 {
       
  6591                                 feedback->InstantFeedback( this, 
       
  6592                                                            ETouchFeedbackList,
       
  6593                                                            ETouchFeedbackVibra,
       
  6594                                                            TPointerEvent() );
       
  6595                                 }
       
  6596 
       
  6597                             iExtension->iObserver->HandleControlEventL(
       
  6598                                 this, MCoeControlObserver::EEventStateChanged);
       
  6599                             }
       
  6600                         }
       
  6601                     }
       
  6602                 // The user tapped on a cell which does not have item. Remove highlight
       
  6603                 else if ( iExtension->iSingleClickEnabled ) 
       
  6604                     {
       
  6605                     iExtension->iHighlightVisible = EFalse;
       
  6606                     DrawCursor();
       
  6607                     }
       
  6608                 }
       
  6609             }
       
  6610         else if ( iExtension->iSingleClickEnabled )
       
  6611             {
       
  6612             iExtension->iHighlightVisible = EFalse;
       
  6613             DrawCursor();
       
  6614             }
       
  6615 			
       
  6616         CCoeControl::HandlePointerEventL(aPointerEvent);
       
  6617 
       
  6618         // if Stylus is lifted we clear all flags.
       
  6619         if (aPointerEvent.iType == TPointerEvent::EButton1Up)
       
  6620             {
       
  6621             iExtension->iFlags &= (~EAknCharMapButton1DownInGrid);
       
  6622             iExtension->iFlags &= (~EAknCharMapHasBeenScrolledByDrag);
       
  6623             iExtension->iFlags &= (~EAknCharMapPressedDown);
       
  6624             if ( !iSBFrame )
       
  6625                 {
       
  6626                 return;
       
  6627                 }
       
  6628             CEikScrollBar* vScrollBar = iSBFrame->VerticalScrollBar();
       
  6629             if(vScrollBar)
       
  6630                 {
       
  6631                 vScrollBar->HandlePointerEventL(aPointerEvent);
       
  6632                 }
       
  6633             }
       
  6634         }
       
  6635     }
       
  6636 
       
  6637 // -----------------------------------------------------------------------------
       
  6638 // CAknCharMap::SetObserver
       
  6639 // Sets the observer.
       
  6640 // -----------------------------------------------------------------------------
       
  6641 //
       
  6642 EXPORT_C void CAknCharMap::SetObserver( MCoeControlObserver* aObserver  )
       
  6643     {
       
  6644     if (iExtension)
       
  6645         {
       
  6646         iExtension->iObserver = aObserver;
       
  6647         }
       
  6648     }
       
  6649 
       
  6650 // -----------------------------------------------------------------------------
       
  6651 // CAknCharMap::HandleScrollEventL
       
  6652 // Handles the different scroll events so that the map reacts accordingly.
       
  6653 // -----------------------------------------------------------------------------
       
  6654 //
       
  6655 void CAknCharMap::HandleScrollEventL(
       
  6656     CEikScrollBar* aScrollBar,
       
  6657     TEikScrollEvent aEventType)
       
  6658     {
       
  6659     TBool update = EFalse;
       
  6660 
       
  6661     switch (aEventType)
       
  6662         {
       
  6663         case EEikScrollUp:
       
  6664         case EEikScrollPageUp:
       
  6665             {
       
  6666             // nothing done if we are already on the first page.
       
  6667             if (iFirstVisibleRow != 0)
       
  6668                 {
       
  6669                 iFirstVisibleRow -= iExtension->iMaxVisibleRows;
       
  6670                 update = ETrue;
       
  6671                 }
       
  6672             if(iFirstVisibleRow == 0 &&
       
  6673             ( (iChaMapTableCase!=EAknCharMapTableSpecialChar && !iPictoInterface->Interface()->IsPictograph((*iChars)[0])) || 
       
  6674               (iChaMapTableCase==EAknCharMapTableSpecialChar && (*iChars)[0]==KHistoryEmptyChar)) )
       
  6675                 {
       
  6676                 iCursorPos = TPoint(0, 1);
       
  6677                 }
       
  6678             else
       
  6679                 {
       
  6680                 iCursorPos = TPoint(0, 0);
       
  6681                 }
       
  6682 
       
  6683             UpdateHeadingPane( ETrue );
       
  6684             UpdateScrollIndicatorL();
       
  6685             }
       
  6686         break;
       
  6687         case EEikScrollDown:
       
  6688         case EEikScrollPageDown:
       
  6689             {
       
  6690             // nothing done if we are already on the last page.
       
  6691             if (iFirstVisibleRow != (PageCount() -1 ) * iExtension->iMaxVisibleRows)
       
  6692                 {
       
  6693                 iFirstVisibleRow += iExtension->iMaxVisibleRows;
       
  6694                 update = ETrue;
       
  6695                 }
       
  6696             iCursorPos = TPoint(0, 0);
       
  6697             UpdateHeadingPane( ETrue );
       
  6698             UpdateScrollIndicatorL();
       
  6699             }
       
  6700         break;
       
  6701         case EEikScrollThumbDragVert:
       
  6702             {
       
  6703             TInt thumbPosition;
       
  6704             TInt halfPage = iExtension->iMaxVisibleRows/2;
       
  6705             // Ask which type of scrollbar is shown
       
  6706             CAknAppUi* appUi = iAvkonAppUi;
       
  6707             TBool isDoubleSpan =
       
  6708                 CEikScrollBarFrame::EDoubleSpan == iSBFrame->TypeOfVScrollBar();
       
  6709             if (isDoubleSpan)
       
  6710                 {
       
  6711                 thumbPosition =
       
  6712                     static_cast <const TAknDoubleSpanScrollBarModel*>
       
  6713                         (aScrollBar->Model())->FocusPosition();
       
  6714                 }
       
  6715             else
       
  6716                 {
       
  6717                 thumbPosition = aScrollBar->Model()->iThumbPosition;
       
  6718                 }
       
  6719 
       
  6720             // If the slider is in the range of less then a half page from a possible correct thumb position.
       
  6721             // thus 0 <= iFirstVisibleRow - thumbPosition < halfPage. Or in the other direction:
       
  6722             // 0 <= thumbPosition - iFirstVisibleRow < halfPage
       
  6723             if (!((0 <= iFirstVisibleRow - thumbPosition &&
       
  6724                         iFirstVisibleRow - thumbPosition < halfPage )||
       
  6725                   (0 <= thumbPosition - iFirstVisibleRow &&
       
  6726                         thumbPosition - iFirstVisibleRow < halfPage)))
       
  6727                 {
       
  6728                 TReal toRound = thumbPosition/(TReal)iExtension->iMaxVisibleRows;
       
  6729                 if (toRound * 2 > (TInt)toRound * 2 + 1)
       
  6730                     {
       
  6731                     toRound++;
       
  6732                     }
       
  6733                 iFirstVisibleRow = (TInt)toRound * iExtension->iMaxVisibleRows;
       
  6734                 if(iFirstVisibleRow == 0 &&
       
  6735                 ( (iChaMapTableCase!=EAknCharMapTableSpecialChar && !iPictoInterface->Interface()->IsPictograph((*iChars)[0])) || 
       
  6736                   (iChaMapTableCase==EAknCharMapTableSpecialChar && (*iChars)[0]==KHistoryEmptyChar)) )
       
  6737                     {
       
  6738                     iCursorPos = TPoint(0, 1);
       
  6739                     }
       
  6740                 else
       
  6741                     {
       
  6742                     iCursorPos = TPoint(0, 0);
       
  6743                     }
       
  6744                 UpdateHeadingPane( EFalse );
       
  6745                 update = ETrue;
       
  6746                 }
       
  6747             }
       
  6748         break;
       
  6749         case EEikScrollThumbReleaseVert:
       
  6750             {
       
  6751             UpdateScrollIndicatorL();
       
  6752             }
       
  6753         break;
       
  6754         case EEikScrollLeft: // flow through
       
  6755         case EEikScrollRight: // flow through
       
  6756         case EEikScrollPageLeft: // flow through
       
  6757         case EEikScrollPageRight: // flow through
       
  6758         case EEikScrollThumbDragHoriz: // flow through
       
  6759         case EEikScrollThumbReleaseHoriz: // flow through
       
  6760             // do nothing
       
  6761             break;
       
  6762         default:
       
  6763             // do nothing
       
  6764             break;
       
  6765         }
       
  6766      // If we have move up to the first page we check the first low is empty or not and
       
  6767      // set iCursorPos respective
       
  6768     if (iFirstVisibleRow == 0 and iCursorPos.iY == 0)
       
  6769         {
       
  6770          if ( (iChaMapTableCase!=EAknCharMapTableSpecialChar && !iPictoInterface->Interface()->IsPictograph((*iChars)[iCursorPos.iX])) || 
       
  6771               (iChaMapTableCase==EAknCharMapTableSpecialChar && (*iChars)[iCursorPos.iX]==KHistoryEmptyChar && !Extension()->iMenuSct) )
       
  6772             {
       
  6773             iCursorPos =  TPoint(iCursorPos.iX, 1);
       
  6774             }
       
  6775         }
       
  6776 // If we have moved down to the last page we check that the cursor is in a place where it can be
       
  6777 // drawn.
       
  6778     if (iFirstVisibleRow == (iRows/iExtension->iMaxVisibleRows) * iExtension->iMaxVisibleRows)
       
  6779         {
       
  6780         // the old cursor is set to a "safe" position where it at least can be.
       
  6781         iOldCursorPos.iX = 0;
       
  6782         iOldCursorPos.iY = 0;
       
  6783         // if the last page has only one line which isn't filled complitely.
       
  6784         if (iChars->Length()%iMaxColumns - 1 < iCursorPos.iX && iRows%iExtension->iMaxVisibleRows == 1)
       
  6785             {
       
  6786             iCursorPos.iX = iChars->Length()%iMaxColumns - 1;
       
  6787             }
       
  6788         // If the cursor is in a position where it would go unto a spot with out
       
  6789         // a character when scrolled.
       
  6790         if (iCursorPos.iY + iFirstVisibleRow >= iRows)
       
  6791             {
       
  6792             if (iChars->Length()%iMaxColumns > iCursorPos.iX)
       
  6793                 {
       
  6794                 iCursorPos.iY = iRows - 1 - iFirstVisibleRow;
       
  6795                 }
       
  6796             else
       
  6797                 {
       
  6798                 iCursorPos.iY = iRows - 2 - iFirstVisibleRow;
       
  6799                 }
       
  6800             }
       
  6801         // If the cursor is actually on the last row, but is still in the
       
  6802         // area where there is now chars. (the rest of the last row)
       
  6803         if (iChars->Length() <= (iFirstVisibleRow + iCursorPos.iY) * iMaxColumns + iCursorPos.iX && 
       
  6804             iCursorPos.iY + iFirstVisibleRow + 1 == iRows)
       
  6805             {
       
  6806             iCursorPos.iY--;
       
  6807             }
       
  6808         // if the corrections did not help and the cursor is in the area
       
  6809         // where there is a valid row, but no chars anymore
       
  6810         }
       
  6811 
       
  6812     // to avoid flicker we draw only if there really was something new to draw.
       
  6813     if (update)
       
  6814         {
       
  6815         if (iExtension->iObserver)
       
  6816             {
       
  6817             iExtension->iObserver->HandleControlEventL(this, MCoeControlObserver::EEventRequestFocus);
       
  6818             }
       
  6819         
       
  6820         HandleFocusStatusChanged();
       
  6821         DrawDeferred();
       
  6822         }
       
  6823     }
       
  6824 
       
  6825 // -----------------------------------------------------------------------------
       
  6826 // CAknCharMapHistory::AppendRecentCharL()
       
  6827 // Append the recent data to SCT/Picto data
       
  6828 // -----------------------------------------------------------------------------
       
  6829 //
       
  6830 void CAknCharMap::AppendRecentCharL()
       
  6831     {
       
  6832     __ASSERT_ALWAYS( iCharMapHistory, Panic(EAknPanicInvalidValue));
       
  6833     __ASSERT_DEBUG( iExtension, Panic(EAknPanicInvalidValue));
       
  6834     
       
  6835     if(iSetRecentSct) return;
       
  6836 
       
  6837     for (TInt index=0; index < 8; index++ )
       
  6838         {
       
  6839         
       
  6840         CAknCharMapHistory::THistoryType historyType = CAknCharMapHistory::EHistoryTypeNull;
       
  6841         HBufC** charsBuf = NULL;
       
  6842 
       
  6843         switch (index)
       
  6844             {
       
  6845             case 0:
       
  6846                 historyType = CAknCharMapHistory::EHistoryTypeFull;
       
  6847                 charsBuf = &iCharsBufferFull;
       
  6848                 break;
       
  6849             case 1:
       
  6850                 historyType = CAknCharMapHistory::EHistoryTypeHalf;
       
  6851                 charsBuf = &iCharsBufferHalf;
       
  6852                 break;
       
  6853             case 2:
       
  6854                 historyType = CAknCharMapHistory::EHistoryTypeHalf;
       
  6855                 charsBuf = &iCharsBufferLower;
       
  6856                 break;
       
  6857             case 3:
       
  6858                 historyType = CAknCharMapHistory::EHistoryTypeHalf;
       
  6859                 charsBuf = &iCharsBufferUpper;
       
  6860                 break;
       
  6861             case 4:
       
  6862                 historyType = CAknCharMapHistory::EHistoryTypeHalf;
       
  6863                 charsBuf = &iCharsBufferNumeric;
       
  6864                 break;
       
  6865             case 5:
       
  6866                 historyType = CAknCharMapHistory::EHistoryTypePicto;
       
  6867                 charsBuf = &iPictographsBuffer;
       
  6868                 break;
       
  6869             case 6:
       
  6870                 historyType = CAknCharMapHistory::EHistoryTypePicto2;
       
  6871                 charsBuf = &iPictographsBuffer2;
       
  6872                 break;
       
  6873             case 7:
       
  6874                 historyType = CAknCharMapHistory::EHistoryTypeHalf;
       
  6875                 charsBuf = &iExtension->iCharsQwerty;
       
  6876                 break;
       
  6877             default:
       
  6878                 break;
       
  6879             }
       
  6880         
       
  6881         TPtrC textHistory = iCharMapHistory->RecentString(historyType, CAknCharMapHistory::EHistoryFilterTextOnly);
       
  6882         
       
  6883         *charsBuf = InsertSwitchCharAndHistoryToCharsBufL(*charsBuf, 
       
  6884                                                           TEmotionUtils::EmotionSwitchToSmileyChar(), 
       
  6885                                                           textHistory);
       
  6886         }
       
  6887     
       
  6888     // Emotion history
       
  6889     TPtrC emotionHistory = iCharMapHistory->RecentString(CAknCharMapHistory::EHistoryTypeFull, CAknCharMapHistory::EHistoryFilterEmotionOnly);
       
  6890     iExtension->iCharsSmiley = InsertSwitchCharAndHistoryToCharsBufL(iExtension->iCharsSmiley, 
       
  6891                                                                      TEmotionUtils::EmotionSwitchToSctChar(), 
       
  6892                                                                      emotionHistory);
       
  6893 
       
  6894     // ETrue are set to each variable when setting the recent used characters.
       
  6895     iSetRecentSct = ETrue;
       
  6896     iSetRecentPic = ETrue;
       
  6897     }
       
  6898 
       
  6899 HBufC* CAknCharMap::InsertSwitchCharAndHistoryToCharsBufL(HBufC* aCharsBuf, TChar aSwitchChar, const TDesC& aHistory)
       
  6900     {
       
  6901     if (aCharsBuf)
       
  6902         {
       
  6903         // Check whether recent charcters are included in base charcters.
       
  6904         TBuf<CAknCharMapHistory::KHistoryBufferSize+5> insertBuffer;
       
  6905         for (TInt index=0; index<aHistory.Length(); index++)
       
  6906             {
       
  6907             TChar txt = aHistory[index];
       
  6908             if(aCharsBuf->Locate(txt)!=KErrNotFound || TEmotionUtils::IsEmotionChar(txt) || txt==KHistoryEmptyChar)
       
  6909                 {
       
  6910                 insertBuffer.Append(txt);
       
  6911                 }
       
  6912             }
       
  6913 
       
  6914         while(insertBuffer.Length() < iMaxColumns)  // empty history stuff
       
  6915             {
       
  6916             insertBuffer.Append(KHistoryEmptyChar);
       
  6917             }
       
  6918         
       
  6919         insertBuffer.SetLength(iMaxColumns);        // max length is one line
       
  6920         
       
  6921         // Emotion switch char
       
  6922         if(Extension()->NeedEmotionSwitchIcon())
       
  6923             {
       
  6924             insertBuffer.Append(aSwitchChar);
       
  6925             }
       
  6926 
       
  6927         // insert to des buffer
       
  6928         TInt charsLength = insertBuffer.Length() + aCharsBuf->Length(); // history + Emotion swich char + text
       
  6929         aCharsBuf = aCharsBuf->ReAllocL(charsLength);
       
  6930         aCharsBuf->Des().Insert(0, insertBuffer);                       // history
       
  6931         }
       
  6932 
       
  6933     return aCharsBuf;
       
  6934     }
       
  6935 
       
  6936 // -----------------------------------------------------------------------------
       
  6937 // CAknCharMapHistory::IsRecentChar()
       
  6938 // Check whether the character(of index) is recent data, or not
       
  6939 // The default value of first argument is 0.
       
  6940 // -----------------------------------------------------------------------------
       
  6941 //
       
  6942 TBool CAknCharMap::IsRecentChar(TInt aIndex /*=0*/) const
       
  6943     {
       
  6944     TBool rtn = EFalse;
       
  6945     if (iCharMapHistory)
       
  6946         {
       
  6947         switch (iChaMapTableCase)
       
  6948             {
       
  6949             case EAknCharMapTableSpecialChar:
       
  6950                 switch (iSpecialCharCase)
       
  6951                     {
       
  6952                     case EAknSCTHalfCase:
       
  6953                     case EAknSCTLowerCase:
       
  6954                     case EAknSCTUpperCase:
       
  6955                     case EAknSCTNumeric:
       
  6956                     case EAknSCTQwerty:
       
  6957                     case EAknSCTFullCase:
       
  6958                         if (aIndex<iMaxColumns && iSetRecentSct)
       
  6959                             {
       
  6960                             rtn = ETrue;
       
  6961                             }
       
  6962                         break;
       
  6963                     default:
       
  6964                         break;
       
  6965                     }
       
  6966                 break;
       
  6967             case EAknCharMapTablePicto:
       
  6968             case EAknCharMapTablePicto2:
       
  6969                 if (aIndex<iMaxColumns && iSetRecentSct)
       
  6970                     {
       
  6971                     rtn = ETrue;
       
  6972                     }
       
  6973                 break;
       
  6974             default:
       
  6975                 break;
       
  6976             }
       
  6977         }
       
  6978     return rtn;
       
  6979     }
       
  6980 
       
  6981 // -----------------------------------------------------------------------------
       
  6982 // CAknCharMapHistory::SaveRecentDataL()
       
  6983 // Save the recent data
       
  6984 // -----------------------------------------------------------------------------
       
  6985 //
       
  6986 void CAknCharMap::SaveRecentDataL(TChar aChar)
       
  6987     {
       
  6988     __ASSERT_ALWAYS( iCharMapHistory, Panic(EAknPanicInvalidValue));
       
  6989 
       
  6990     CAknCharMapHistory::THistoryType historyType = CAknCharMapHistory::EHistoryTypeNull;
       
  6991 
       
  6992     switch (iChaMapTableCase)
       
  6993         {
       
  6994         case EAknCharMapTableSpecialChar:
       
  6995             switch (iSpecialCharCase)
       
  6996                 {
       
  6997                 case EAknSCTHalfCase:
       
  6998                 case EAknSCTLowerCase:
       
  6999                 case EAknSCTUpperCase:
       
  7000                 case EAknSCTNumeric:
       
  7001                 case EAknSCTQwerty:
       
  7002                     historyType = CAknCharMapHistory::EHistoryTypeHalf;
       
  7003                     break;
       
  7004                 case EAknSCTFullCase:
       
  7005                     historyType = CAknCharMapHistory::EHistoryTypeFull;
       
  7006                     break;
       
  7007                 default:
       
  7008                     break;
       
  7009                 }
       
  7010             break;
       
  7011             
       
  7012         case EAknCharMapTablePicto:
       
  7013         case EAknCharMapTablePicto2:
       
  7014             historyType = (iCaseIndex==0) ? CAknCharMapHistory::EHistoryTypePicto : CAknCharMapHistory::EHistoryTypePicto2;
       
  7015             break;
       
  7016             
       
  7017         default:
       
  7018             break;
       
  7019         }
       
  7020     
       
  7021     if (historyType > CAknCharMapHistory::EHistoryTypeNull)
       
  7022         {
       
  7023         iCharMapHistory->InsertChar(historyType, aChar);
       
  7024         }
       
  7025 
       
  7026     // Save recent data
       
  7027     iCharMapHistory->SaveL();
       
  7028     }
       
  7029 
       
  7030 // -----------------------------------------------------------------------------
       
  7031 // CAknCharMap::ConstructMenuSctRowL()
       
  7032 // Constructs the SCT for editing menu.
       
  7033 // -----------------------------------------------------------------------------
       
  7034 //
       
  7035 EXPORT_C void CAknCharMap::ConstructMenuSctRowL()
       
  7036     {
       
  7037     Extension()->iMenuSct = ETrue;
       
  7038     TResourceReader reader;
       
  7039 
       
  7040     TInt resourceId = R_AVKON_MENU_SCT_ROW_DEFAULT_CONTENTS;
       
  7041     if (FeatureManager::FeatureSupported(KFeatureIdChinese))
       
  7042         {
       
  7043         resourceId = R_AVKON_MENU_SCT_ROW_DEFAULT_CONTENTS_CHINESE;
       
  7044         }
       
  7045 
       
  7046     CCoeEnv::Static()->CreateResourceReaderLC( reader, resourceId );
       
  7047     ConstructFromResourceL( reader );
       
  7048     CleanupStack::PopAndDestroy();
       
  7049     }
       
  7050 
       
  7051 
       
  7052 EXPORT_C void CAknCharMap::ConstructMenuSctRowL(TInt aResourceId)
       
  7053     {
       
  7054     Extension()->iMenuSct = ETrue;
       
  7055     Extension()->iMenuSctHighlighted = ETrue;
       
  7056     TResourceReader reader;
       
  7057     CCoeEnv::Static()->CreateResourceReaderLC( reader,
       
  7058                                 aResourceId );
       
  7059     ConstructFromResourceL( reader );
       
  7060     CleanupStack::PopAndDestroy();
       
  7061     }
       
  7062 
       
  7063 
       
  7064 // -----------------------------------------------------------------------------
       
  7065 // CAknCharMap::ConstructMenuSctRowFromDialogL()
       
  7066 // Constructs the SCT for editing menu from the set resource.
       
  7067 // -----------------------------------------------------------------------------
       
  7068 //
       
  7069 EXPORT_C void CAknCharMap::ConstructMenuSctRowFromDialogL(TInt aResourceId)
       
  7070     {
       
  7071     Extension()->iMenuSct = ETrue;
       
  7072     Extension()->iMenuSctHighlighted = ETrue;
       
  7073 
       
  7074     CEikDialog* dialog = new(ELeave) CEikDialog();
       
  7075     dialog->ReadResourceLC(aResourceId);
       
  7076     CAknCharMap* charmapControl = STATIC_CAST(CAknCharMap*, dialog->Control(EAknSCTQueryContentId));
       
  7077 
       
  7078     // the code below emulates ConstructFromResourceL(), but gets value from charmapControl
       
  7079     CopyCharactersL(*charmapControl);     // replaces ReadCharSetFromResourceL()
       
  7080     CleanupStack::PopAndDestroy(dialog);
       
  7081     TBuf<32> fileName(KResFileName);
       
  7082     TInt langcode= iAvkonEnv->SettingCache().InputLanguage();
       
  7083     if (langcode < 10)
       
  7084         {
       
  7085         fileName.Append('0');
       
  7086         }
       
  7087     fileName.AppendNum(langcode);
       
  7088     TResourceReader reader;
       
  7089     RFs& fs = iEikonEnv->FsSession();
       
  7090     if ( BaflUtils::FileExists(fs, fileName) )
       
  7091         {
       
  7092         RResourceFile resourceFile;
       
  7093         resourceFile.OpenL( fs, fileName );
       
  7094         CleanupClosePushL( resourceFile ); // push
       
  7095         resourceFile.ConfirmSignatureL( 0 );
       
  7096         if ( resourceFile.OwnsResourceId(aResourceId) )
       
  7097             {
       
  7098             HBufC8* resource=
       
  7099                 resourceFile.AllocReadLC(aResourceId); // push
       
  7100             reader.SetBuffer(resource);
       
  7101             TBuf<32> specialChars;
       
  7102             CAknCharMapDialog* langDialog =
       
  7103                 new( ELeave ) CAknCharMapDialog(
       
  7104                     EAknSCTLowerCase, specialChars );
       
  7105             CleanupStack::PushL( langDialog ); // push
       
  7106             langDialog->CreateWindowL();
       
  7107             langDialog->ConstructFromResourceL(reader);
       
  7108             CAknCharMap* langMap = STATIC_CAST( CAknCharMap*,
       
  7109                 langDialog->Control( EAknSCTQueryContentId ) );
       
  7110             CopyCharactersL( *langMap );
       
  7111             CleanupStack::PopAndDestroy(2); // langDialog, resource
       
  7112             }
       
  7113         CleanupStack::PopAndDestroy(); // resourcefile
       
  7114         }
       
  7115 
       
  7116     if ( iExtension->iPictographsBuffer )
       
  7117         {
       
  7118         CreatePictoCharL();
       
  7119         }
       
  7120 
       
  7121     if (!iCharMapHistory)
       
  7122         {
       
  7123         iCharMapHistory = CAknCharMapHistory::NewL();
       
  7124         iSetRecentSct = ETrue;
       
  7125         iSetRecentPic = ETrue;
       
  7126         }
       
  7127 
       
  7128     if ( iExtension->iPictographsBuffer )
       
  7129         {
       
  7130         CreateOffscreenBackgroundL();
       
  7131         }
       
  7132 
       
  7133     delete iExtension->iBgContext;
       
  7134     iExtension->iBgContext = NULL;
       
  7135 
       
  7136     if ( DrawableWindow() && AknLayoutUtils::PenEnabled() )
       
  7137         {
       
  7138         EnableDragEvents();
       
  7139         SetGloballyCapturing( ETrue );
       
  7140         SetPointerCapture( ETrue );
       
  7141         }
       
  7142     }
       
  7143 
       
  7144 // -----------------------------------------------------------------------------
       
  7145 // CAknCharMap::HighlightSctRow()
       
  7146 // Highlight the row of recent used character according to argument.
       
  7147 // -----------------------------------------------------------------------------
       
  7148 //
       
  7149 EXPORT_C void CAknCharMap::HighlightSctRow(TBool aHighlight)
       
  7150     {
       
  7151     // If the row is empty, nothing to do
       
  7152     if (LengthOfRecentChar() == 0)
       
  7153         {
       
  7154         return;
       
  7155         }
       
  7156     
       
  7157     HandleFocusStatusChanged(aHighlight);
       
  7158     
       
  7159     CWindowGc& gc = SystemGc();
       
  7160     if( !CAknEnv::Static()->TransparencyEnabled() )
       
  7161         {
       
  7162         ActivateGc();
       
  7163         gc.UseFont(iFont);
       
  7164         }
       
  7165 
       
  7166     TInt cursorPos = iCursorPos.iX + iCursorPos.iY * iMaxColumns;
       
  7167     DrawCell( cursorPos, aHighlight );
       
  7168 
       
  7169     if( !CAknEnv::Static()->TransparencyEnabled() )
       
  7170         {
       
  7171         gc.DiscardFont();
       
  7172         DeactivateGc();
       
  7173         }
       
  7174     // Menu SCT is being used.
       
  7175     if ( Extension()->iMenuSct )
       
  7176     	{
       
  7177     	Extension()->iMenuSctHighlighted = aHighlight;
       
  7178     	}
       
  7179     }
       
  7180 // -----------------------------------------------------------------------------
       
  7181 // CAknCharMap::SetMenuSctRect()
       
  7182 // Sets the rect for menu SCT.
       
  7183 // -----------------------------------------------------------------------------
       
  7184 //
       
  7185 EXPORT_C void CAknCharMap::SetMenuSctRect( const TRect& aRect )
       
  7186     {
       
  7187     
       
  7188     if(Rect() == aRect) return;
       
  7189     
       
  7190     SetRect( aRect );
       
  7191 
       
  7192     if ( !iIsMirrored )
       
  7193         {
       
  7194         iGridTopLeft = aRect.iTl;
       
  7195         iOffset.iX = aRect.iTl.iX + 1;
       
  7196         iOffset.iY = aRect.iTl.iY + 1;
       
  7197         }
       
  7198     else
       
  7199         {
       
  7200         iGridTopLeft.iX = aRect.iBr.iX;
       
  7201         iGridTopLeft.iY = aRect.iTl.iY;
       
  7202         iOffset.iX = aRect.iTl.iX + 1;
       
  7203         iOffset.iY = aRect.iTl.iY + 1;
       
  7204         }
       
  7205 
       
  7206 
       
  7207     DoLayout();
       
  7208     
       
  7209     if (iCharMapHistory)
       
  7210         {
       
  7211         CAknCharMapHistory::THistoryType charmap = CAknCharMapHistory::EHistoryTypeNull;
       
  7212         
       
  7213         switch (iSpecialCharCase)
       
  7214             {
       
  7215             case 0: // lower
       
  7216                 charmap = CAknCharMapHistory::EHistoryTypeHalf;
       
  7217                 break;
       
  7218             case 1: // upper
       
  7219                 charmap = CAknCharMapHistory::EHistoryTypeHalf;
       
  7220                 break;
       
  7221             case 2: // numeric
       
  7222                 charmap = CAknCharMapHistory::EHistoryTypeHalf;
       
  7223                 break;
       
  7224             case 3: // full
       
  7225                 charmap = CAknCharMapHistory::EHistoryTypeFull;
       
  7226                 break;
       
  7227             case 4: // half
       
  7228                 charmap = CAknCharMapHistory::EHistoryTypeHalf;
       
  7229                 break;
       
  7230             case 5: // qwerty
       
  7231                 charmap = CAknCharMapHistory::EHistoryTypeHalf;
       
  7232                 break;
       
  7233             case 6: // picto
       
  7234                 charmap = CAknCharMapHistory::EHistoryTypePicto;
       
  7235                 break;
       
  7236             case 7: // picto 2
       
  7237                 charmap = CAknCharMapHistory::EHistoryTypePicto2;
       
  7238                 break;
       
  7239             default:
       
  7240                 break;
       
  7241             }
       
  7242         
       
  7243         CAknCharMapHistory::THistoryFilter historyFilter;
       
  7244         if(iExtension->IsEmotionEnabled())
       
  7245             {
       
  7246             historyFilter = CAknCharMapHistory::EHistoryFilterMixed;
       
  7247             }
       
  7248         else
       
  7249             {
       
  7250             historyFilter = CAknCharMapHistory::EHistoryFilterTextOnly;
       
  7251             }
       
  7252         
       
  7253         const TDesC& recentChars = iCharMapHistory->RecentString(charmap, historyFilter);
       
  7254         
       
  7255         // if iChars already contains HBufC, delete iChars and reset ichars
       
  7256         if (iExtension->iFlags & EAknCharMapCharsAllocated)
       
  7257             {
       
  7258             delete iChars;
       
  7259             iChars = NULL;
       
  7260             if (iChaMapTableCase != EAknCharMapTableSpecialChar)
       
  7261                 {
       
  7262                 if (iCaseIndex == 1)
       
  7263                     {
       
  7264                     iChars = iPictographsBuffer2;
       
  7265                     }
       
  7266                 else
       
  7267                     {
       
  7268                     iChars = iPictographsBuffer;
       
  7269                     }
       
  7270                 iShowCasesRef = &iPictographCases;
       
  7271                 iShowPagesRef = &iPictographPages;
       
  7272                 }
       
  7273             else
       
  7274                 {
       
  7275                 iShowCasesRef = &iSpecialCharCases;
       
  7276                 iShowPagesRef = &iSpecialCharPages;
       
  7277                 iChars = iCharsBufferLower;
       
  7278                 if (iCharsBufferUpper && iSpecialCharCase==EAknSCTUpperCase)
       
  7279                     iChars = iCharsBufferUpper;
       
  7280                 else if (iCharsBufferNumeric && iSpecialCharCase==EAknSCTNumeric)
       
  7281                     iChars = iCharsBufferNumeric;
       
  7282                 else if (iCharsBufferFull && iSpecialCharCase==EAknSCTFullCase)
       
  7283                     iChars = iCharsBufferFull;
       
  7284                 else if (iCharsBufferHalf && iSpecialCharCase==EAknSCTHalfCase)
       
  7285                     iChars = iCharsBufferHalf;
       
  7286                 else if (iExtension->iCharsQwerty && iSpecialCharCase==EAknSCTQwerty)
       
  7287                     iChars = iExtension->iCharsQwerty;
       
  7288 
       
  7289                 if(iChars == iCharsBufferLower)
       
  7290                     {
       
  7291                     iSpecialCharCase = EAknSCTLowerCase;
       
  7292                     }
       
  7293                 }
       
  7294             // mark that iChars doesn't point to HBufC
       
  7295             iExtension->iFlags &= (~EAknCharMapCharsAllocated);
       
  7296             }
       
  7297         iRows = 1;
       
  7298         TPtrC realChars = iChars->Des(); // get only the SCT chars
       
  7299 
       
  7300         // Check whether recent charcters are included in base charcters.
       
  7301         HBufC* newrecent = HBufC::New(recentChars.Length());
       
  7302         if( newrecent == NULL)
       
  7303             {
       
  7304             return;
       
  7305             }
       
  7306 
       
  7307         TPtr ptrrecent(newrecent->Des());
       
  7308         ptrrecent.Copy(recentChars);
       
  7309         for (TInt index=0; index < ptrrecent.Length(); index++)
       
  7310             {
       
  7311             if (ptrrecent[index] != KHistoryEmptyChar)
       
  7312                 {
       
  7313                 if(TEmotionUtils::IsEmotionChar(ptrrecent[index]))
       
  7314                     {
       
  7315                     continue;
       
  7316                     }
       
  7317                 else
       
  7318                     {
       
  7319                     TInt err = realChars.Locate(ptrrecent[index]);
       
  7320                     if (err == KErrNotFound)
       
  7321                         {
       
  7322                         ptrrecent.Delete(index,1);
       
  7323                         ptrrecent.Append(KHistoryEmptyChar);
       
  7324                         index--;
       
  7325                         }                       
       
  7326                     }
       
  7327                 }
       
  7328             }
       
  7329         if (iExtension->iFlags & EAknCharMapCharsAllocated) // iChars already contains HBufC
       
  7330             {                                               // so delete old instance
       
  7331             delete iChars;
       
  7332             iChars = NULL;
       
  7333             }
       
  7334 
       
  7335         iChars = newrecent;
       
  7336         iChars->Des().SetLength(iMaxColumns);
       
  7337         if (iChaMapTableCase==EAknCharMapTableSpecialChar && (*iChars)[0] == KHistoryEmptyChar)
       
  7338             {
       
  7339             iCursorPos = TPoint(0, 1);
       
  7340             }
       
  7341         if (iCursorPos.iX >= iMaxColumns)
       
  7342             {
       
  7343             iCursorPos = TPoint(0, 0);
       
  7344             }
       
  7345         iExtension->iFlags |= EAknCharMapCharsAllocated; // mark that iChars points to HBufC
       
  7346         }
       
  7347     
       
  7348     iExtension->LoadEmotionTumbnails(*iChars);
       
  7349 
       
  7350     HandleFocusStatusChanged();
       
  7351     }
       
  7352 
       
  7353 // -----------------------------------------------------------------------------
       
  7354 // CAknCharMap::CharacterCase()
       
  7355 // Get current character case.
       
  7356 // -----------------------------------------------------------------------------
       
  7357 //
       
  7358 TInt CAknCharMap::CharacterCase()
       
  7359     {
       
  7360     return iSpecialCharCase;
       
  7361     }
       
  7362 
       
  7363 // -----------------------------------------------------------------------------
       
  7364 // CAknCharMap::DisableRecentCharsRow()
       
  7365 // Hides the first row that shows recent characters.
       
  7366 // -----------------------------------------------------------------------------
       
  7367 //
       
  7368 void CAknCharMap::DisableRecentCharsRow()
       
  7369     {
       
  7370     if(!iSetRecentSct) return;
       
  7371     
       
  7372     iSetRecentSct = EFalse;
       
  7373     iSetRecentPic = EFalse;
       
  7374     
       
  7375     TInt insertedLength = iMaxColumns;
       
  7376     
       
  7377     // Emotion switch char
       
  7378     if(Extension()->NeedEmotionSwitchIcon())
       
  7379         {
       
  7380         insertedLength++;
       
  7381         }
       
  7382 
       
  7383     for (TInt index=0; index < 8; index++ )
       
  7384         {
       
  7385         HBufC** base = NULL;
       
  7386         
       
  7387         switch (index)
       
  7388             {
       
  7389             case 0:
       
  7390                 base = &iCharsBufferFull;
       
  7391                 break;
       
  7392             case 1:
       
  7393                 base = &iCharsBufferHalf;
       
  7394                 break;
       
  7395             case 2:
       
  7396                 base = &iCharsBufferLower;
       
  7397                 break;
       
  7398             case 3:
       
  7399                 base = &iCharsBufferUpper;
       
  7400                 break;
       
  7401             case 4:
       
  7402                 base = &iCharsBufferNumeric;
       
  7403                 break;
       
  7404             case 5:
       
  7405                 base = &iPictographsBuffer;
       
  7406                 break;
       
  7407             case 6:
       
  7408                 base = &iExtension->iCharsQwerty;
       
  7409                 break;
       
  7410             case 7:
       
  7411                 base = &iPictographsBuffer2;
       
  7412                 break;
       
  7413             default:
       
  7414                 break;
       
  7415             }
       
  7416         
       
  7417         if (*base)
       
  7418             {
       
  7419             // Remove recent characters from the beginning.
       
  7420             // Length of removed characters is iMaxColumns
       
  7421             (*base)->Des().Delete(0, insertedLength);
       
  7422             }
       
  7423         }
       
  7424     
       
  7425     // delete Emotion history
       
  7426     iExtension->iCharsSmiley->Des().Delete(0, insertedLength);
       
  7427     }
       
  7428 
       
  7429 
       
  7430 // -----------------------------------------------------------------------------
       
  7431 // CAknCharMap::Extension
       
  7432 // Asserts that extension object has been created.
       
  7433 // -----------------------------------------------------------------------------
       
  7434 //
       
  7435 CAknCharMapExtension* CAknCharMap::Extension() const
       
  7436     {
       
  7437     __ASSERT_ALWAYS( iExtension, Panic( EAknPanicNullPointer ) );
       
  7438     return iExtension;
       
  7439     }
       
  7440 
       
  7441 // -----------------------------------------------------------------------------
       
  7442 // CAknCharMap::UpdateHeadingPane
       
  7443 // Updates page number and title in Heading Pane.
       
  7444 // -----------------------------------------------------------------------------
       
  7445 //
       
  7446 void CAknCharMap::UpdateHeadingPane( TBool aUpdateTitle )
       
  7447     {
       
  7448     if (iExtension->iObserver &&
       
  7449         !AknLayoutUtils::PenEnabled() && !Extension()->iMenuSct)
       
  7450         {
       
  7451         CAknCharMapDialog* dialog =
       
  7452             static_cast<CAknCharMapDialog*>(iExtension->iObserver );
       
  7453         CAknPopupHeadingPane* headingPane =
       
  7454             static_cast< CAknPopupHeadingPane* >
       
  7455                 (dialog-> Control( EAknSCTQueryHeadingId ) );
       
  7456 
       
  7457         if ( headingPane )
       
  7458             {
       
  7459             TRAP_IGNORE(
       
  7460                 {
       
  7461                 // Update heading pane's page number
       
  7462                 headingPane->SetPageL( CurrentPage(), PageCount() );
       
  7463 
       
  7464                 // Update also title if requested
       
  7465                 if ( aUpdateTitle)
       
  7466                     {
       
  7467                     const TDesC* title = (IsJapaneseSctUi())?
       
  7468                                          TitleWithSelectingSpecialChar()
       
  7469                                          :Title();
       
  7470                     if ( title )
       
  7471                         {
       
  7472                         //
       
  7473                         headingPane->SetTextL( *title );
       
  7474                         }
       
  7475                     }
       
  7476                 } );
       
  7477             }
       
  7478         }
       
  7479     }
       
  7480 
       
  7481 
       
  7482 
       
  7483 
       
  7484 void CAknCharMap::SetStatusChanged(const TInt aStatusChanged)
       
  7485     {
       
  7486     iStatusChanged = aStatusChanged;
       
  7487     if (iExtension->iObserver)
       
  7488         {
       
  7489         TRAP_IGNORE( iExtension->iObserver->HandleControlEventL(this, MCoeControlObserver::EEventStateChanged) );
       
  7490         }
       
  7491     }
       
  7492 
       
  7493 TInt CAknCharMap::StatusChanged()
       
  7494     {
       
  7495     return iStatusChanged;
       
  7496     }
       
  7497 
       
  7498 TInt CAknCharMap::CurrentCategory()
       
  7499     {
       
  7500     return iExtension->iCurrentCategory;
       
  7501     }
       
  7502 
       
  7503 TInt CAknCharMap::Category()
       
  7504     {
       
  7505     TInt category = EAknSCTCategoryButtonHalfCase;
       
  7506     if (iChaMapTableCase == EAknCharMapTableSpecialChar)
       
  7507         {
       
  7508         if (iSpecialCharCase == EAknSCTFullCase)
       
  7509             {
       
  7510             category = EAknSCTCategoryButtonFullCase;
       
  7511             }
       
  7512         }
       
  7513     else
       
  7514         {
       
  7515         if (iExtension->iPictographsBufferGrouping)
       
  7516             {
       
  7517             category = (iCaseIndex == 1) ?
       
  7518                 EAknSCTCategoryButtonPicto2 : EAknSCTCategoryButtonPicto1;
       
  7519             }
       
  7520         else
       
  7521             {
       
  7522             category = EAknSCTCategoryButtonPicto;
       
  7523             }
       
  7524         }
       
  7525     return category;
       
  7526     }
       
  7527 
       
  7528 /**
       
  7529  * Change to new category
       
  7530  */
       
  7531 TBool CAknCharMap::ChangeCategoryL(const TInt aCategory, TBool& aLayoutChanged)
       
  7532     {
       
  7533     TBool result(ETrue);
       
  7534 
       
  7535     aLayoutChanged = EFalse;
       
  7536 
       
  7537     TInt oldVisibleRows = iRows;
       
  7538     if (oldVisibleRows > iExtension->iMaxVisibleRows)
       
  7539         {
       
  7540         oldVisibleRows = iExtension->iMaxVisibleRows;
       
  7541         }
       
  7542 
       
  7543     switch (aCategory)
       
  7544         {
       
  7545         case EAknSCTCategoryButtonHalfCase:
       
  7546             iChaMapTableCase = EAknCharMapTableSpecialChar;
       
  7547             SetCharacterCaseL(EAknSCTHalfCase);
       
  7548             break;
       
  7549         case EAknSCTCategoryButtonFullCase:
       
  7550             iChaMapTableCase = EAknCharMapTableSpecialChar;
       
  7551             SetCharacterCaseL(EAknSCTFullCase);
       
  7552             break;
       
  7553         case EAknSCTCategoryButtonPicto:
       
  7554             iChaMapTableCase = EAknCharMapTablePicto;
       
  7555             iCaseIndex = 0;
       
  7556             SetCharacterCaseL(iSpecialCharCase);
       
  7557             break;
       
  7558         case EAknSCTCategoryButtonPicto1:
       
  7559             iChaMapTableCase = EAknCharMapTablePicto;
       
  7560             iCaseIndex = 0;
       
  7561             SetCharacterCaseL(iSpecialCharCase);
       
  7562             break;
       
  7563         case EAknSCTCategoryButtonPicto2:
       
  7564             iChaMapTableCase = EAknCharMapTablePicto;
       
  7565             iCaseIndex = 1;
       
  7566             SetCharacterCaseL(iSpecialCharCase);
       
  7567             break;
       
  7568         default:
       
  7569             Panic(EAknPanicOutOfRange);
       
  7570             break;
       
  7571         }
       
  7572 
       
  7573     TInt visibleRows = iRows;
       
  7574     if (visibleRows > iExtension->iMaxVisibleRows)
       
  7575         {
       
  7576         visibleRows = iExtension->iMaxVisibleRows;
       
  7577         }
       
  7578 
       
  7579     // Return also information whether the layout changed or not.
       
  7580     aLayoutChanged = ( oldVisibleRows != visibleRows );
       
  7581 
       
  7582     UpdateScrollIndicatorL();
       
  7583 
       
  7584     UpdateInputFieldL();
       
  7585 
       
  7586     RefreshNaviPageL();
       
  7587 
       
  7588     if (aLayoutChanged)
       
  7589         {
       
  7590         // If the number of the visible row is changed,
       
  7591         // it is necessary to re-create the background.
       
  7592         CreateOffscreenBackgroundL();
       
  7593         }
       
  7594     return result;
       
  7595     }
       
  7596 
       
  7597 
       
  7598 TBool CAknCharMap::IsSupportCategoryButtonUi() const
       
  7599     {
       
  7600     return (iExtension)? iExtension->iHasCategoryButtonUi : EFalse;
       
  7601     }
       
  7602 
       
  7603 TBool CAknCharMap::IsJapaneseSctUi() const
       
  7604     {
       
  7605     return (iExtension)? iExtension->iJapaneseSctUi : EFalse;
       
  7606     }
       
  7607 
       
  7608 // -----------------------------------------------------------------------------
       
  7609 // CAknCharMap::TitleWithSelectingSpecialChar()
       
  7610 // Return the title string with the selecting special characters
       
  7611 // -----------------------------------------------------------------------------
       
  7612 //
       
  7613 
       
  7614 const TDesC* CAknCharMap::TitleWithSelectingSpecialChar()
       
  7615     {
       
  7616     const TDesC* title = Title();
       
  7617     TRAPD(err, CreateTitleWithSelectingSpecialCharL(title));
       
  7618     if (err != KErrNone)
       
  7619         {
       
  7620         return title;
       
  7621         }
       
  7622     else
       
  7623         {
       
  7624         return Extension()->iTitleBuf;
       
  7625         }
       
  7626     }
       
  7627 
       
  7628 // -----------------------------------------------------------------------------
       
  7629 // CAknCharMap::ChangeFocusSct()
       
  7630 // Change the current focus either Grid or Category buttons
       
  7631 // If aFocusOn is EFalse, from Grid to Category buttons,
       
  7632 // If aFocusOn is ETrue, from Category buttons to Grid
       
  7633 // -----------------------------------------------------------------------------
       
  7634 //
       
  7635 void CAknCharMap::ChangeFocusSct(TBool aFocusOn)
       
  7636     {
       
  7637     CWindowGc& gc = SystemGc();
       
  7638     if( !CAknEnv::Static()->TransparencyEnabled() )
       
  7639         {
       
  7640         ActivateGc();
       
  7641         gc.UseFont(iFont);
       
  7642         }
       
  7643 
       
  7644     TInt cursorPos = iCursorPos.iX + iCursorPos.iY * iMaxColumns;
       
  7645     DrawCell( cursorPos, aFocusOn );
       
  7646 
       
  7647     if( !CAknEnv::Static()->TransparencyEnabled() )
       
  7648         {
       
  7649         gc.DiscardFont();
       
  7650         DeactivateGc();
       
  7651         }
       
  7652     }
       
  7653 
       
  7654 // -----------------------------------------------------------------------------
       
  7655 // CAknCharMap::CreateTitleWithSelectingSpecialCharL()
       
  7656 // Create the string mixing title and the selecting special characters,
       
  7657 // and Set it to Extension()->iTitleBuf.
       
  7658 // -----------------------------------------------------------------------------
       
  7659 //
       
  7660 void CAknCharMap::CreateTitleWithSelectingSpecialCharL(const TDesC* aTitle)
       
  7661     {
       
  7662     const TDesC* title = aTitle;
       
  7663     if ( title )
       
  7664         {
       
  7665         if (!AknLayoutUtils::PenEnabled())
       
  7666             {
       
  7667             CAknCharMapDialog* dialog =
       
  7668                 static_cast<CAknCharMapDialog*>(iExtension->iObserver);
       
  7669             CAknPopupHeadingPane* headingPane =
       
  7670                 static_cast<CAknPopupHeadingPane*>(
       
  7671                     dialog->Control(EAknSCTQueryHeadingId));
       
  7672             if (Extension()->iTitleBuf)
       
  7673                 {
       
  7674                 delete Extension()->iTitleBuf;
       
  7675                 Extension()->iTitleBuf =NULL;
       
  7676                 }
       
  7677             Extension()->iTitleBuf =
       
  7678                 HBufC::NewL(title->Length() + iFetcherCharsBuffer->Length());
       
  7679             TPtr titlePtr(Extension()->iTitleBuf->Des());
       
  7680             HBufC* tempBuf = iFetcherCharsBuffer->AllocLC();
       
  7681             TPtr tempPtr(tempBuf->Des());
       
  7682 
       
  7683             CCoeControl* titleCtrl = (CCoeControl*)headingPane->Prompt();
       
  7684             TRect promptRect = titleCtrl->Rect();
       
  7685 
       
  7686             TInt varietyIndex = (AknLayoutUtils::PenEnabled())? 3 : 1;
       
  7687             TAknTextComponentLayout textLayout =
       
  7688                 AknLayoutScalable_Avkon::heading_pane_t1(varietyIndex);
       
  7689 
       
  7690             TRect parentRect;
       
  7691             TAknLayoutRect popupRect;
       
  7692             if(!AknLayoutUtils::LayoutMetricsRect(
       
  7693                 AknLayoutUtils::EPopupParent, parentRect))
       
  7694                 {
       
  7695                 parentRect = iAvkonAppUi->ClientRect();
       
  7696                 }
       
  7697             popupRect.LayoutRect(parentRect,
       
  7698                 AknLayoutScalable_Avkon::popup_window_general(1));
       
  7699 
       
  7700             TAknLayoutRect headingRect;
       
  7701             TAknWindowComponentLayout headingPaneLayout =
       
  7702                 AknLayoutScalable_Avkon::heading_pane(0);
       
  7703             headingRect.LayoutRect(TRect(TPoint(0,0),
       
  7704                 popupRect.Rect().Size()), headingPaneLayout);
       
  7705             parentRect = headingRect.Rect();
       
  7706 
       
  7707             TAknLayoutText textRect;
       
  7708             textRect.LayoutText(parentRect, textLayout);
       
  7709             TInt controlWidth = textRect.TextRect().Width();
       
  7710 
       
  7711             const CFont* promptFont =
       
  7712                 AknLayoutUtils::FontFromId( textLayout.Font() );
       
  7713 
       
  7714             TInt titleWidth = promptFont->TextWidthInPixels(*title);
       
  7715             TInt textWidth = promptFont->TextWidthInPixels(tempPtr);
       
  7716             FOREVER
       
  7717                 {
       
  7718                 if (titleWidth >= controlWidth)
       
  7719                     {
       
  7720                     titlePtr.Append(*title);
       
  7721                     break;
       
  7722                     }
       
  7723                 if (controlWidth >= (titleWidth + textWidth))
       
  7724                     {
       
  7725                     titlePtr.Append(*title);
       
  7726                     titlePtr.Append(tempPtr);
       
  7727                     break;
       
  7728                     }
       
  7729                 if (tempPtr.Length() > 1)
       
  7730                     {
       
  7731                     tempPtr.Delete(0,1);
       
  7732                     tempPtr[0] = CEditableText::EEllipsis;
       
  7733                     textWidth = promptFont->TextWidthInPixels(tempPtr);
       
  7734                     }
       
  7735                 else
       
  7736                     {
       
  7737                     titleWidth = controlWidth + 1;
       
  7738                     }
       
  7739                 }
       
  7740             CleanupStack::PopAndDestroy(tempBuf);
       
  7741             }
       
  7742         }
       
  7743     }
       
  7744 
       
  7745 void CAknCharMap::RefreshNaviPageL()
       
  7746     {
       
  7747     if (iExtension->iPageNavi)
       
  7748         {
       
  7749         iExtension->iPageNavi->UpdatePageTitleL();
       
  7750         }
       
  7751     }
       
  7752 
       
  7753 TAknChaMapTableCase CAknCharMap::NextTableCase() const
       
  7754     {
       
  7755     return EAknCharMapTableSpecialChar; // Currently no other maps supported.
       
  7756     }
       
  7757 
       
  7758 MAknSctFocusHandler* CAknCharMap::FocusHandler()
       
  7759     {
       
  7760     return iExtension->iFocusHandler;
       
  7761     }
       
  7762 
       
  7763 CCoeControl* CAknCharMap::FocusedControl()
       
  7764     {
       
  7765     return this;
       
  7766     }
       
  7767 
       
  7768 TBool CAknCharMap::EnterControl(TInt aX, TInt aY)
       
  7769     {
       
  7770     if ((aY < 0) || (aY >= iExtension->iMaxVisibleRows))
       
  7771         {
       
  7772         return EFalse; // Out of grid.
       
  7773         }
       
  7774 
       
  7775     if ((aX < 0) || (aX >= iMaxColumns))
       
  7776         {
       
  7777         return EFalse; // Out of grid.
       
  7778         }
       
  7779 
       
  7780     TInt pos = 0;
       
  7781 
       
  7782     CWindowGc& gc = SystemGc();
       
  7783     if(!CAknEnv::Static()->TransparencyEnabled())
       
  7784         {
       
  7785         ActivateGc();
       
  7786         gc.UseFont(iFont);
       
  7787         }
       
  7788 
       
  7789     // clear cell
       
  7790     pos = iCursorPos.iX + iCursorPos.iY * iMaxColumns;
       
  7791     DrawCell( pos, EFalse );
       
  7792 
       
  7793     iCursorPos = TPoint(aX, aY); // new pos.
       
  7794 
       
  7795     // highlight cell
       
  7796     pos = iCursorPos.iX + iCursorPos.iY * iMaxColumns;
       
  7797     DrawCell( pos, ETrue );
       
  7798 
       
  7799     UpdateHeadingPane( ETrue );
       
  7800 
       
  7801     if( !CAknEnv::Static()->TransparencyEnabled() )
       
  7802         {
       
  7803         gc.DiscardFont();
       
  7804         DeactivateGc();
       
  7805         }
       
  7806 
       
  7807     return ETrue;
       
  7808     }
       
  7809 
       
  7810 void CAknCharMap::MoveFocus(TInt aX, TInt aY)
       
  7811     {
       
  7812     TRAP_IGNORE(MoveCursorL(aX,aY));
       
  7813     }
       
  7814 
       
  7815 TBool CAknCharMap::LeaveControl()
       
  7816     {
       
  7817     HandleFocusStatusChanged(EFalse);
       
  7818     
       
  7819     CWindowGc& gc = SystemGc();
       
  7820     if( !CAknEnv::Static()->TransparencyEnabled() )
       
  7821         {
       
  7822         ActivateGc();
       
  7823         gc.UseFont(iFont);
       
  7824         }
       
  7825 
       
  7826     TInt pos = iCursorPos.iX + iCursorPos.iY * iMaxColumns;
       
  7827     DrawCell( pos, EFalse );
       
  7828 
       
  7829     if( !CAknEnv::Static()->TransparencyEnabled() )
       
  7830         {
       
  7831         gc.DiscardFont();
       
  7832         DeactivateGc();
       
  7833         }
       
  7834 
       
  7835     return ETrue;
       
  7836     }
       
  7837 
       
  7838 TInt CAknCharMap::TableCount() const
       
  7839     {
       
  7840     // Numbers of tables excluding pictographs.
       
  7841     // there will be sct table and Emotion table(if enabled)
       
  7842     return Extension()->IsEmotionEnabled() ? 2 : 1;
       
  7843     }
       
  7844 
       
  7845 void CAknCharMap::UpdateInputFieldL()
       
  7846     {
       
  7847     if (!iExtension)
       
  7848         {
       
  7849         return; // Not ready for updates.
       
  7850         }
       
  7851 
       
  7852     TInt variety = Layout_Meta_Data::IsLandscapeOrientation() ? 1 : 0;
       
  7853 
       
  7854     // Update title field.
       
  7855     const TDesC* title = Title();
       
  7856     if (iExtension->iCategoryTitle && title)
       
  7857         {
       
  7858         iExtension->iCategoryTitle->SetTextL(*title);
       
  7859         Window().Invalidate(iExtension->iCategoryTitle->Rect());
       
  7860         iExtension->iCategoryTitle->SetBrushStyle(
       
  7861             CGraphicsContext::ENullBrush);
       
  7862         }
       
  7863 
       
  7864     // Update entry field.
       
  7865     if (iExtension->iCategoryEntry &&
       
  7866         iFetcherCharsBuffer && iFetcherCharsBuffer->Length()>0)
       
  7867         {
       
  7868         if (Extension()->iEntryBuf)
       
  7869             {
       
  7870             delete Extension()->iEntryBuf;
       
  7871             Extension()->iEntryBuf =NULL;
       
  7872             }
       
  7873         Extension()->iEntryBuf =
       
  7874             HBufC::NewL(iFetcherCharsBuffer->Length());
       
  7875         TPtr entryPtr(Extension()->iEntryBuf->Des());
       
  7876 
       
  7877         HBufC* tempBuf = iFetcherCharsBuffer->AllocLC();
       
  7878         TPtr tempPtr(tempBuf->Des());
       
  7879 
       
  7880         TInt variety =
       
  7881             Layout_Meta_Data::IsLandscapeOrientation() ? 1 : 0;
       
  7882         const CFont* entryFont = AknLayoutUtils::FontFromId(
       
  7883             AknLayoutScalable_Avkon::popup_grid_graphic2_window_t2(variety).Font());
       
  7884         TInt entryWidth = entryFont->TextWidthInPixels(tempPtr);
       
  7885 
       
  7886         TInt controlWidth = Extension()->iCategoryEntry->Size().iWidth;
       
  7887 
       
  7888         FOREVER
       
  7889             {
       
  7890             if (entryWidth < controlWidth)
       
  7891                 {
       
  7892                 entryPtr.Append(tempPtr);
       
  7893                 break;
       
  7894                 }
       
  7895             if (tempPtr.Length() > 1)
       
  7896                 {
       
  7897                 tempPtr.Delete(0,1);
       
  7898                 tempPtr[0] = CEditableText::EEllipsis;
       
  7899                 entryWidth = entryFont->TextWidthInPixels(tempPtr);
       
  7900                 }
       
  7901             else
       
  7902                 {
       
  7903                 entryWidth = controlWidth + 1;
       
  7904                 }
       
  7905             }
       
  7906 
       
  7907         Extension()->iCategoryEntry->SetTextL(tempPtr);
       
  7908         Window().Invalidate(iExtension->iCategoryEntry->Rect());
       
  7909         Extension()->iCategoryEntry->SetBrushStyle(
       
  7910             CGraphicsContext::ENullBrush);
       
  7911 
       
  7912         CleanupStack::PopAndDestroy(tempBuf);
       
  7913         }
       
  7914     }
       
  7915 
       
  7916 TInt CAknCharMap::RowMin(TInt aRow) const
       
  7917     {
       
  7918     TInt index = KErrNotFound;
       
  7919     if ((aRow >= 0) && (aRow < iExtension->iMaxVisibleRows))
       
  7920         {
       
  7921         TInt start = (iFirstVisibleRow + aRow) * iMaxColumns;
       
  7922         for (TInt i = 0; i < iMaxColumns; i++)
       
  7923             {
       
  7924             TInt pos = start + i;
       
  7925             if ((pos >= 0) && (pos < iChars->Length()))
       
  7926                 {
       
  7927                 if ((*iChars)[pos] != KHistoryEmptyChar)
       
  7928                     {
       
  7929                     index = i; // the first valid cell in the row.
       
  7930                     break;
       
  7931                     }
       
  7932                 }
       
  7933             }
       
  7934         }
       
  7935     return index;
       
  7936     }
       
  7937 
       
  7938 TInt CAknCharMap::RowMax(TInt aRow) const
       
  7939     {
       
  7940     TInt index = KErrNotFound;
       
  7941     if ((aRow >= 0) && (aRow < iExtension->iMaxVisibleRows))
       
  7942         {
       
  7943         TInt start = (iFirstVisibleRow + aRow) * iMaxColumns;
       
  7944         for (TInt i = iMaxColumns - 1; i >= 0; i--)
       
  7945             {
       
  7946             TInt pos = start + i;
       
  7947             if ((pos >= 0) && (pos < iChars->Length()))
       
  7948                 {
       
  7949                 if ((*iChars)[pos] != KHistoryEmptyChar)
       
  7950                     {
       
  7951                     index = i; // the last valid cell in the row.
       
  7952                     break;
       
  7953                     }
       
  7954                 }
       
  7955             }
       
  7956         }
       
  7957     return index;
       
  7958     }
       
  7959 
       
  7960 TInt CAknCharMap::ColMin(TInt aCol) const
       
  7961     {
       
  7962     TInt index = KErrNotFound;
       
  7963     if ((aCol >= 0) && (aCol < iMaxColumns))
       
  7964         {
       
  7965         TInt start = iFirstVisibleRow * iMaxColumns + aCol;
       
  7966         for (TInt i = 0; i < iExtension->iMaxVisibleRows; i++)
       
  7967             {
       
  7968             TInt pos = start + iMaxColumns * i;
       
  7969             if ((pos >= 0) && (pos < iChars->Length()))
       
  7970                 {
       
  7971                 if ((*iChars)[pos] != KHistoryEmptyChar)
       
  7972                     {
       
  7973                     index = i; // the first valid cell in the column.
       
  7974                     break;
       
  7975                     }
       
  7976                 }
       
  7977             }
       
  7978         }
       
  7979     return index;
       
  7980     }
       
  7981 
       
  7982 TInt CAknCharMap::ColMax(TInt aCol) const
       
  7983     {
       
  7984     TInt index = KErrNotFound;
       
  7985     if ((aCol >= 0) && (aCol < iMaxColumns))
       
  7986         {
       
  7987         TInt start = iFirstVisibleRow * iMaxColumns + aCol;
       
  7988         for (TInt i = iExtension->iMaxVisibleRows - 1; i >= 0; i--)
       
  7989             {
       
  7990             TInt pos = start + iMaxColumns * i;
       
  7991             if ((pos >= 0) && (pos < iChars->Length()))
       
  7992                 {
       
  7993                 if ((*iChars)[pos] != KHistoryEmptyChar)
       
  7994                     {
       
  7995                     index = i; // the last valid cell in the column.
       
  7996                     break;
       
  7997                     }
       
  7998                 }
       
  7999             }
       
  8000         }
       
  8001     return index;
       
  8002     }
       
  8003 
       
  8004 TInt CAknCharMap::MaxCols() const
       
  8005     {
       
  8006     return iMaxColumns;
       
  8007     }
       
  8008 
       
  8009 TBool CAknCharMap::TakeFocus()
       
  8010     {
       
  8011     TInt success = EFalse;
       
  8012     if (iExtension->iFocusHandler->FocusedControl() != this)
       
  8013         {
       
  8014         iExtension->iFocusHandler->LeaveControl();
       
  8015         iExtension->iFocusHandler = iExtension;
       
  8016         success = ETrue;
       
  8017         }
       
  8018     return success;
       
  8019     }
       
  8020 
       
  8021 void CAknCharMap::ShowFocus()
       
  8022     {
       
  8023     ChangeFocusSct(ETrue);
       
  8024     }
       
  8025 
       
  8026 TPoint CAknCharMap::CursorPos()
       
  8027     {
       
  8028     return iCursorPos;
       
  8029     }
       
  8030 
       
  8031 
       
  8032 // for emotion added
       
  8033 
       
  8034 void CAknCharMap::HandleFocusStatusChanged(TBool aIsFocused)
       
  8035     {
       
  8036     TInt focusPos = iCursorPos.iX + (iFirstVisibleRow + iCursorPos.iY) * iMaxColumns;
       
  8037     if(focusPos>=0 && focusPos<iChars->Length())
       
  8038         {
       
  8039         aIsFocused &= (iExtension->iFocusHandler->FocusedControl()==this);
       
  8040         iExtension->HandleFocusStatusChanged((*iChars)[focusPos], aIsFocused);
       
  8041         }
       
  8042     }
       
  8043 
       
  8044 TBool CAknCharMap::EmotionsAreAllReadyToDraw(TInt aIndex, TInt aCount) const
       
  8045     {
       
  8046     for(TInt i(0); i<aCount; i++)
       
  8047         {
       
  8048         if(aIndex < iChars->Length())
       
  8049             {
       
  8050             TChar name = (*iChars)[aIndex++];
       
  8051             CSmileyIcon* icon = iExtension->EmotionIcon(name);
       
  8052             if(icon && !icon->ReadyToDraw())
       
  8053                 {
       
  8054                 return EFalse;
       
  8055                 }
       
  8056             }
       
  8057         else
       
  8058             {
       
  8059             break;
       
  8060             }
       
  8061         }
       
  8062     
       
  8063     return ETrue;
       
  8064     }
       
  8065 
       
  8066 void CAknCharMap::GetFocusSctName(TChar& aChar, TDes& aName) const
       
  8067     {
       
  8068     TInt pos = iMaxColumns * (iFirstVisibleRow + iCursorPos.iY) + iCursorPos.iX;
       
  8069     
       
  8070     aChar = (*iChars)[pos];
       
  8071     
       
  8072     aName.Zero();
       
  8073     
       
  8074     if(TEmotionUtils::IsEmotionChar(aChar))
       
  8075         {
       
  8076         CSmileyIcon* icon = iExtension->EmotionIcon(aChar);
       
  8077         if ( icon )
       
  8078             {
       
  8079             aName.Append(icon->Name());
       
  8080             }
       
  8081         }
       
  8082     else
       
  8083         {
       
  8084         aName.Append(aChar);
       
  8085         }
       
  8086     }
       
  8087 
       
  8088 TBool CAknCharMap::HaveBufferToAppendFocusSct() const
       
  8089     {
       
  8090     TChar sctChar;
       
  8091     TBuf<10> sctName;
       
  8092     GetFocusSctName(sctChar, sctName);
       
  8093     
       
  8094     return ( iFetcherCharsBuffer->Length() + sctName.Length() < iFetcherCharsBuffer->MaxLength() );
       
  8095     }
       
  8096 
       
  8097 TBool CAknCharMap::AppendFocusSctToDestinationBufferL()
       
  8098     {
       
  8099     TBool appended = EFalse;
       
  8100     
       
  8101     TChar sctChar;
       
  8102     TBuf<10> sctName;
       
  8103     GetFocusSctName(sctChar, sctName);
       
  8104 
       
  8105     if(Extension()->NeedEmotionSwitchIcon() && 
       
  8106        (sctChar==TEmotionUtils::EmotionSwitchToSctChar() || sctChar==TEmotionUtils::EmotionSwitchToSmileyChar()))
       
  8107         {
       
  8108         SwitchSctAndEmotionL();
       
  8109         }
       
  8110     else if(iFetcherCharsBuffer->Length() + sctName.Length() < iFetcherCharsBuffer->MaxLength())
       
  8111         {
       
  8112         iFetcherCharsBuffer->Append(sctName);
       
  8113 
       
  8114         if (iCharMapHistory)
       
  8115             {
       
  8116             SaveRecentDataL(sctChar);
       
  8117             }
       
  8118         
       
  8119         appended = ETrue;
       
  8120         }
       
  8121     else
       
  8122         {
       
  8123         return EFalse; // return here
       
  8124         }
       
  8125         
       
  8126     if (!Extension()->iMenuSct)
       
  8127         {
       
  8128         UpdateHeadingPane( ETrue );
       
  8129         }
       
  8130     
       
  8131     if (iExtension->iCategoryEntry)
       
  8132         {
       
  8133         iExtension->iCategoryEntry->SetTextL(*iFetcherCharsBuffer);
       
  8134         UpdateInputFieldL();
       
  8135         }
       
  8136 
       
  8137     return appended;
       
  8138 
       
  8139     }
       
  8140 
       
  8141 TBool CAknCharMap::SwitchSctAndEmotionL()
       
  8142     {
       
  8143     if(Extension()->IsEmotionEnabled())
       
  8144         {
       
  8145         Extension()->iIsShowingEmotion = !Extension()->IsShowingEmotion();
       
  8146         
       
  8147         SetCharacterCaseL(iSpecialCharCase);
       
  8148         
       
  8149         CAknSctTableNavi* tableNavi = Extension()->iTableNavi;
       
  8150         if(tableNavi)
       
  8151             {
       
  8152             tableNavi->UpdateNextTableButtonL();
       
  8153             }
       
  8154 
       
  8155         DrawNow();
       
  8156         
       
  8157         return ETrue;
       
  8158         }
       
  8159     else
       
  8160         {
       
  8161         return EFalse;
       
  8162         }
       
  8163     }
       
  8164 
       
  8165 
       
  8166 //  End of File