/*
* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:
*
*/
// INCLUDE FILES
#include <barsread.h>
#include <uikon.hrh>
#include <e32std.h>
#include <eikcapc.h>
#include <aknlayoutscalable_avkon.cdl.h>
#include <layoutmetadata.cdl.h>
#include "aknborders.h"
#include "aknconsts.h"
#include "AknUtils.h"
#include "aknPopupHeadingPane.h"
#include "aknCharMap.h"
#include "aknSctDialog.h"
#include "AknSettingCache.h"
#include "aknenv.h"
#include "AknDef.h"
#include <bautils.h>
#include <AknLayout.lag>
#include <StringLoader.h>
#include <e32property.h>
#include <AvkonInternalCRKeys.h> // KAknQwertyInputModeActive
#include <featmgr.h> // temporary
#include <PtiIndicDefs.h>
#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
#include <uikon/eikenvinterface.h>
#endif
#ifdef RD_UI_TRANSITION_EFFECTS_POPUPS
#include <gfxtranseffect/gfxtranseffect.h>
#include <akntransitionutils.h>
#endif
#include <AknTasHook.h>
#include "aknsctfocushandler.h"
#include <eikdialogext.h>
//
// class CAknCharMapDialog
//
// const TInt KHorizontalDialogMargin = 3;
// const TInt KVerticalDialogMargin = 3;
_LIT(KResFileName, "z:\\resource\\avkon.r");
const TInt KWsBufferSize = 16000;
const TInt KAknSctCBaButtonDirections = 3; // bottom, right and left
enum TCharMapDialogFlags
{
ECharMapDialogItemSelected = 0x01,
ECharMapDialogItemLockNumericKeys = 0x02,
ECharMapDialogRecentCharsRowDisabled = 0x04,
ECharMapDialogTableExitSelected = 0x08
};
// ----------------------------------------------------------------------------
// Extension class
//
// ----------------------------------------------------------------------------
//
NONSHARABLE_CLASS(CAknCharMapDialogExtension): public CBase
{
public:
static CAknCharMapDialogExtension* NewL(CAknCharMapDialog* aCaller);
~CAknCharMapDialogExtension();
private:
CAknCharMapDialogExtension(CAknCharMapDialog* aCaller);
void ConstructL();
static TInt QwertyModeChangeNotification(TAny* aObj);
void HandleQwertyModeChangeNotification();
public: // New method
void SetCharacterCaseIfRequiredL();
public:
TInt iFlags;
TBool iQwertyMode;
CAknCharMapDialog* iCaller;
TBool iHaveReceivedKeyEvent;
TInt iShowAnotherTableCharCase;
TAknCharMapPictoMode iPictoMode;
TAknCharMapEmotionMode iEmotionMode;
private:
NONSHARABLE_CLASS(CSubscriber) : public CActive
{
public:
CSubscriber(TCallBack aCallBack, RProperty& aProperty);
~CSubscriber();
public: // New functions
void SubscribeL();
void StopSubscribe();
private: // from CActive
void RunL();
void DoCancel();
private:
TCallBack iCallBack;
RProperty& iProperty;
};
private:
CSubscriber* iQwertyModeStatusSubscriber;
RProperty iQwertyModeStatusProperty;
TInt iOldCharCase;
};
// -----------------------------------------------------------------------------
// CAknCharMapDialogExtension::CAknCharMapDialogExtension
//
// Constructor of extension
// -----------------------------------------------------------------------------
//
CAknCharMapDialogExtension::CAknCharMapDialogExtension(CAknCharMapDialog* aCaller) :
iFlags(0), iQwertyMode(EFalse), iCaller(aCaller),
iShowAnotherTableCharCase(-1), iPictoMode(EAknCharMapPictoNoUse), iEmotionMode(EAknCharMapEmotionNoUse)
{
}
// -----------------------------------------------------------------------------
// CAknCharMapDialogExtension::~CAknCharMapDialogExtension
//
// Destructor of extension
// -----------------------------------------------------------------------------
//
CAknCharMapDialogExtension::~CAknCharMapDialogExtension()
{
// Stop subscribe in PubSub
if (iQwertyModeStatusSubscriber)
{
iQwertyModeStatusSubscriber->StopSubscribe();
}
iQwertyModeStatusProperty.Close();
delete iQwertyModeStatusSubscriber;
}
// -----------------------------------------------------------------------------
// CAknCharMapDialogExtension::NewL
//
// Symbian 2 phase constructor
// -----------------------------------------------------------------------------
//
CAknCharMapDialogExtension* CAknCharMapDialogExtension::NewL(CAknCharMapDialog* aCaller)
{ // static
CAknCharMapDialogExtension* self = new (ELeave) CAknCharMapDialogExtension(aCaller);
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop();
return self;
}
// -----------------------------------------------------------------------------
// CAknCharMapDialogExtension::ConstructL
//
// Symbian construction
// -----------------------------------------------------------------------------
//
void CAknCharMapDialogExtension::ConstructL()
{
// Start also listening qwerty mode status.
User::LeaveIfError(iQwertyModeStatusProperty.Attach(KCRUidAvkon,
KAknQwertyInputModeActive));
iQwertyModeStatusSubscriber = new (ELeave) CSubscriber(
TCallBack(QwertyModeChangeNotification, this), iQwertyModeStatusProperty);
iQwertyModeStatusSubscriber->SubscribeL();
iOldCharCase=-1; // no default character case at beginning
}
TInt CAknCharMapDialogExtension::QwertyModeChangeNotification(TAny* aObj)
{
if (aObj != NULL)
{
static_cast<CAknCharMapDialogExtension*>(aObj)->HandleQwertyModeChangeNotification();
return KErrNone;
}
else
{
return KErrArgument;
}
}
void CAknCharMapDialogExtension::SetCharacterCaseIfRequiredL()
{
TInt value = 0;
iQwertyModeStatusProperty.Get(value);
iQwertyMode = value;
CAknCharMap* charmapControl =
STATIC_CAST(CAknCharMap*, iCaller->Control(EAknSCTQueryContentId));
if ( (iQwertyMode) == (charmapControl->CharacterCase() == EAknSCTQwerty) )
{
// No change for Qwerty mode
return;
}
if (iQwertyMode)
{
iFlags |= ECharMapDialogItemLockNumericKeys;
iOldCharCase=charmapControl->CharacterCase();
charmapControl->SetCharacterCaseL(EAknSCTQwerty);
}
else
{
iFlags &= (~ECharMapDialogItemLockNumericKeys);
if (iOldCharCase!=-1)
{
charmapControl->SetCharacterCaseL(iOldCharCase);
}
else
{
charmapControl->SetCharacterCaseL(EAknSCTLowerCase);
iOldCharCase = EAknSCTLowerCase;
}
}
//charmapControl->DrawNow();
}
void CAknCharMapDialogExtension::HandleQwertyModeChangeNotification()
{
TInt value = 0;
iQwertyModeStatusProperty.Get(value);
iQwertyMode = value;
CAknCharMap* charmapControl =
STATIC_CAST(CAknCharMap*, iCaller->Control(EAknSCTQueryContentId));
if ( (iQwertyMode) == (charmapControl->CharacterCase() == EAknSCTQwerty) )
{
// No change for Qwerty mode
return;
}
if (iQwertyMode)
{
iFlags |= ECharMapDialogItemLockNumericKeys;
iOldCharCase=charmapControl->CharacterCase();
TRAP_IGNORE( charmapControl->SetCharacterCaseL(EAknSCTQwerty) );
}
else
{
iFlags &= ~ECharMapDialogItemLockNumericKeys;
if (iOldCharCase!=-1)
{
TRAP_IGNORE( charmapControl->SetCharacterCaseL(iOldCharCase) );
}
else
{
TRAP_IGNORE( charmapControl->SetCharacterCaseL(EAknSCTLowerCase) );
iOldCharCase = EAknSCTLowerCase;
}
}
// Reset focus.
charmapControl->TakeFocus();
// Draw new characters.
charmapControl->DrawNow();
}
// CAknCharMapDialogExtension::CSubscriber
CAknCharMapDialogExtension::CSubscriber::CSubscriber(TCallBack aCallBack, RProperty& aProperty)
: CActive(EPriorityNormal), iCallBack(aCallBack), iProperty(aProperty)
{
CActiveScheduler::Add(this);
}
CAknCharMapDialogExtension::CSubscriber::~CSubscriber()
{
Cancel();
}
void CAknCharMapDialogExtension::CSubscriber::SubscribeL()
{
if (!IsActive())
{
iProperty.Subscribe(iStatus);
SetActive();
}
}
void CAknCharMapDialogExtension::CSubscriber::StopSubscribe()
{
Cancel();
}
void CAknCharMapDialogExtension::CSubscriber::RunL()
{
if (iStatus.Int() == KErrNone)
{
iCallBack.CallBack();
SubscribeL();
}
}
void CAknCharMapDialogExtension::CSubscriber::DoCancel()
{
iProperty.Cancel();
}
// CAknCharMapDialog
EXPORT_C CAknCharMapDialog::CAknCharMapDialog(TInt aCharCase, TDes& aSpecialChars, TInt aCharSetResourceId) :
iSpecialChars(&aSpecialChars), iCharCase(aCharCase), iCharSetResourceId(aCharSetResourceId)
{
CEikDialog::SetBorder( AknBorderId::EAknBorderNotePopup );
TRAP_IGNORE(iExtension=CAknCharMapDialogExtension::NewL(this));
#ifdef RD_UI_TRANSITION_EFFECTS_POPUPS
GfxTransEffect::Register( this, KGfxContextMenuControlUid );
#endif
AKNTASHOOK_ADD( this, "CAknCharMapDialog" );
}
CAknCharMapDialog::~CAknCharMapDialog()
{
AKNTASHOOK_REMOVE();
iAvkonEnv->CancelWsBufferRequest( iWsBufferRequestId );
delete iExtension;
}
EXPORT_C void CAknCharMapDialog::HandleResourceChange(TInt aType)
{
CAknCharMap* charmapControl = static_cast<CAknCharMap*>( Control( EAknSCTQueryContentId ) );
if (aType==KEikDynamicLayoutVariantSwitch)
{
TRAP_IGNORE(iExtension->SetCharacterCaseIfRequiredL());
//DoLayout();
}
CAknDialog::HandleResourceChange(aType);
if (aType==KEikDynamicLayoutVariantSwitch)
{
// Softkeys
ButtonGroupContainer().MakeVisible(AknLayoutUtils::PenEnabled() ? EFalse : ETrue);
// Heading
CAknPopupHeadingPane* headingPane = static_cast< CAknPopupHeadingPane* >( Control( EAknSCTQueryHeadingId ) );
CEikCaptionedControl *ctrl = GetLineByLineAndPageIndex(0, EAknSCTQueryHeadingId);
if (AknLayoutUtils::PenEnabled())
{
ctrl->SetLatent(ETrue);
ctrl->SetLatentGroupLineFollows(ETrue);
TRAP_IGNORE(charmapControl->UpdateInputFieldL());
}
else
{
ctrl->SetLatent(EFalse);
ctrl->SetLatentGroupLineFollows(EFalse);
if ( headingPane && charmapControl )
{
TRAP_IGNORE(
{
headingPane->SetPageL(
charmapControl->CurrentPage(),
charmapControl->PageCount() );
const TDesC* title = (charmapControl->IsJapaneseSctUi()) ?
charmapControl->TitleWithSelectingSpecialChar() : charmapControl->Title();
if ( title )
{
headingPane->SetTextL( *title );
}
});
}
//Set softkeys
TRAP_IGNORE(SetSoftKeyL());
}
ctrl->SetFocusing(EFalse);
DoLayout();
DrawNow();
Window().SetVisible( ETrue );
}
}
EXPORT_C TBool CAknCharMapDialog::OkToExitL(TInt aButtonId)
{
CAknCharMap* charmapControl = STATIC_CAST(CAknCharMap*, Control(EAknSCTQueryContentId));
if (aButtonId == EAknSoftkeyNext)
{
TInt page = charmapControl->NextPageL();
CAknPopupHeadingPane* headingPane = STATIC_CAST(CAknPopupHeadingPane*, Control(EAknSCTQueryHeadingId));
headingPane->SetPageL(charmapControl->CurrentPage(), page);
if (page && !AknLayoutUtils::PenEnabled())
{
const TDesC* title = charmapControl->IsJapaneseSctUi() ?
charmapControl->TitleWithSelectingSpecialChar() :
charmapControl->Title();
headingPane->SetTextL(*title);
}
return(EFalse);
}
// Selection key / select softkey adds a character only if 5-key was not used
// to select multiple characters before.
if (aButtonId == EAknSoftkeyOk || aButtonId == EAknSoftkeySelect || aButtonId == EAknSoftkeyExit)
{
// In Korean UI, SCT isn't closed by pressing "Select" softkey,
// but SCT is closed by pressing "Back"(button id is EAknSoftkeyClose).
// Japanese feature for SCT will not be supported since TB9.2 PS2,
// so remove the code for Japanese SCT.
MAknSctFocusHandler* handler = charmapControl->FocusHandler();
if ( charmapControl->IsKoreanSctUi() &&
aButtonId != EAknSoftkeyExit &&
handler->FocusedControl() == charmapControl)
{
TKeyEvent key;
key.iCode=EKeySpace;
key.iModifiers=0;
handler->FocusedControl()->OfferKeyEventL(key, EEventKey);
return(EFalse);
}
// else
TKeyEvent key;
key.iCode=EKeyOK;
key.iModifiers=0;
if(handler->FocusedControl()->OfferKeyEventL(key, EEventKey) == EKeyWasNotConsumed)
{
return EFalse;
}
else
{
return handler->ExitWithKey(key.iCode);
}
}
return(ETrue);
}
EXPORT_C void CAknCharMapDialog::PreLayoutDynInitL()
{
CAknCharMap* charmapControl = STATIC_CAST(CAknCharMap*, Control(EAknSCTQueryContentId));
// Softkeys
ButtonGroupContainer().MakeVisible(AknLayoutUtils::PenEnabled() ? EFalse : ETrue);
// Heading
CAknPopupHeadingPane* headingPane = STATIC_CAST(CAknPopupHeadingPane*, Control(EAknSCTQueryHeadingId));
headingPane->SetLayout(CAknPopupHeadingPane::EColourSelectionGridHeadingPane);
charmapControl->SetTitleL(headingPane->PromptText());
SetLineNonFocusing(EAknSCTQueryHeadingId);
CEikCaptionedControl *ctrl = GetLineByLineAndPageIndex(0, EAknSCTQueryHeadingId);
ctrl->SetLatent(AknLayoutUtils::PenEnabled() ? ETrue : EFalse);
ctrl->SetLatentGroupLineFollows(AknLayoutUtils::PenEnabled() ? ETrue : EFalse);
// Pictographs
charmapControl->SetPictoMode(iExtension->iPictoMode);
// Emotion
charmapControl->SetEmotionModeL(iExtension->iEmotionMode);
// ShowAnotherTable
RArray<TInt> caseTable(3);
if (iExtension->iShowAnotherTableCharCase > 0)
{
caseTable.AppendL(iExtension->iShowAnotherTableCharCase);
}
charmapControl->SetCaseTableL(caseTable);
caseTable.Close();
//
charmapControl->SetBuffer(*iSpecialChars);
charmapControl->SetCharacterCaseL(iCharCase);
if (!AknLayoutUtils::PenEnabled())
{
if (charmapControl->PageCount() > 1)
{
const TDesC* title = charmapControl->IsJapaneseSctUi()?
charmapControl->TitleWithSelectingSpecialChar() :
charmapControl->Title();
headingPane->SetPageL(1, charmapControl->PageCount());
headingPane->SetTextL(*title);
// Set softkeys
SetSoftKeyL();
}
}
else
{
charmapControl->UpdateInputFieldL();
}
// Key events should be received even when cba is invisible
MEikButtonGroup* cba = ButtonGroupContainer().ButtonGroup();
STATIC_CAST( CEikCba*, cba)->SetButtonGroupFlags( cba->ButtonGroupFlags() | EAknCBAFlagRespondWhenInvisible );
RWsSession& wsSession = iEikonEnv->WsSession();
TInt myWgId = iEikonEnv->RootWin().Identifier();
TInt wgPrio = wsSession.GetWindowGroupOrdinalPriority(myWgId);
// we are already on forgeround, need to update priority differently
if (wgPrio == ECoeWinPriorityAlwaysAtFront)
{
iEikonEnv->RootWin().SetOrdinalPosition(0,ECoeWinPriorityAlwaysAtFront+1);
}
/// -- Change Window Priority for dialog and CBA
DrawableWindow()->SetOrdinalPosition(0,ECoeWinPriorityAlwaysAtFront); //
ButtonGroupContainer().ButtonGroup()->AsControl()->DrawableWindow()->SetOrdinalPosition(0,ECoeWinPriorityAlwaysAtFront);
CEikDialog::Extension()->SetPriority(CActive::EPriorityStandard);
}
EXPORT_C void CAknCharMapDialog::SetSizeAndPosition( const TSize& aSize )
{
if ( AknLayoutUtils::PenEnabled() )
{
CAknDialog::SetSizeAndPosition( aSize );
CAknCharMap* charmapControl = STATIC_CAST(CAknCharMap*,
Control(EAknSCTQueryContentId));
charmapControl->DrawOffscreenBackgroundIfRequired();
}
else
{
SetBorder( TGulBorder::ENone ); // No Dialog borders in SCT.
DoLayout();
}
}
EXPORT_C TKeyResponse CAknCharMapDialog::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aModifiers)
{
CAknCharMap* charmapControl = STATIC_CAST(CAknCharMap*, Control(EAknSCTQueryContentId));
CAknPopupHeadingPane* headingPane = STATIC_CAST(CAknPopupHeadingPane*, Control(EAknSCTQueryHeadingId));
TBool isLockNumericKeys = (iExtension->iFlags&ECharMapDialogItemLockNumericKeys != EFalse);
if (aModifiers == EEventKey)
{
switch (aKeyEvent.iCode)
{
case '5':
if (isLockNumericKeys || aKeyEvent.iRepeats)
{
return EKeyWasConsumed;
}
break;
case EKeySpace: // for Qwerty
// If there is only one empty position left in the buffer.
if (iSpecialChars->Length() + 1 >= iSpecialChars->MaxLength())
{
// Add the selected character to list of special chars
charmapControl->OfferKeyEventL(aKeyEvent, aModifiers);
TKeyEvent event = {EKeyOK, EKeyOK, 0, 0};
return CEikDialog::OfferKeyEventL( event, EEventKey );
}
// No break. Fall through.
case '2':
case '4':
case '6':
case '8':
if (isLockNumericKeys && aKeyEvent.iCode!=EKeySpace)
{
return EKeyWasConsumed;
}
case EKeyLeftArrow:
case EKeyRightArrow:
case EKeyUpArrow:
case EKeyDownArrow:
{
TKeyResponse res = charmapControl->OfferKeyEventL(aKeyEvent, aModifiers);
RefreshTitleAndNaviL();
return res;
}
case EKeyEnter:
case EKeyDevice3:
{
TryExitL(EAknSoftkeySelect);
return EKeyWasConsumed;
}
case '*':
{
if (!aKeyEvent.iRepeats) // switch another table when repeat count is 0 only.
{
if(iExtension->iHaveReceivedKeyEvent)
{
SwitchTablesOrPagesL();
}
else
{
iExtension->iHaveReceivedKeyEvent = ETrue;
}
}
}
break;
default:
break;
}
}
else if (aModifiers == EEventKeyUp)
{
switch (aKeyEvent.iScanCode)
{
case EStdKeyLeftFunc:
case EStdKeyRightFunc:
{
if (!aKeyEvent.iRepeats) // switch another table when repeat count is 0 only.
{
if (!isLockNumericKeys) // Check whether current input mode is Qwerty.
{
SwitchTablesOrPagesL();
}
}
}
break;
default:
break;
}
}
return CEikDialog::OfferKeyEventL( aKeyEvent, aModifiers );
}
EXPORT_C TInt CAknCharMapDialog::ExecuteLD(TInt aResourceId)
{
iWsBufferRequestId = iAvkonEnv->RequestWsBuffer( KWsBufferSize );
// Prepare real char map
CEikDialog::PrepareLC(aResourceId);
// Build up input language spesific avkon resource file
TBuf<32> fileName(KResFileName);
TInt langcode= iAvkonEnv->SettingCache().InputLanguage();
// get the phone language
TLanguage phoneLanguage = AknLangUtils::UserLanguage();
if ( (langcode & KAknLanguageMask) == ELangEnglish && phoneLanguage != ELangEnglish )
{
switch ( phoneLanguage )
{
case ELangThai:
langcode = ELangEnglish_Thailand;
break;
default:
break;
}
}
if (langcode < 10)
{
fileName.Append('0');
}
if(langcode == KLangHindiPhonetic)
langcode = ELangHindi;
fileName.AppendNum(langcode);
TResourceReader reader;
RFs& fs = iEikonEnv->FsSession();
// if input language spesific avkon resourcefile exists
if ( BaflUtils::FileExists(fs, fileName) )
{
RResourceFile resourceFile;
resourceFile.OpenL( fs, fileName );
CleanupClosePushL( resourceFile ); // push
resourceFile.ConfirmSignatureL( 0 );
// if resources with correct id exists
// -> read characters from resource and copy them to real char map
if ( resourceFile.OwnsResourceId(aResourceId) )
{
HBufC8* resource=resourceFile.AllocReadLC(aResourceId); // push
reader.SetBuffer(resource);
// Create input language specific CharMapDialog.
// Used only for reading input language spesific characters
// from avkon resource file (avkon.r**).
TBuf<32> specialChars;
CAknCharMapDialog* langDialog = new( ELeave ) CAknCharMapDialog(EAknSCTLowerCase, specialChars );
CleanupStack::PushL( langDialog ); // push
langDialog->CreateWindowL();
langDialog->ConstructFromResourceL(reader);
CAknCharMap* langMap = STATIC_CAST( CAknCharMap*, langDialog->Control( EAknSCTQueryContentId ) );
CAknCharMap* charMap = STATIC_CAST( CAknCharMap*, Control( EAknSCTQueryContentId ) );
charMap->CopyCharactersL( *langMap );
CleanupStack::PopAndDestroy(2); // langDialog, resource
}
CleanupStack::PopAndDestroy(); // resourcefile
}
// get created charmap control
CAknCharMap* charmapControl = STATIC_CAST(CAknCharMap*, Control(EAknSCTQueryContentId));
if (iCharSetResourceId)
{
TResourceReader reader;
iCoeEnv->CreateResourceReaderLC(reader, iCharSetResourceId);
charmapControl->ReadAndAddCharSetFromResourceL(reader);
CleanupStack::PopAndDestroy(); // reader
}
charmapControl->SetObserver(this);
if ( iExtension && (iExtension->iFlags & ECharMapDialogRecentCharsRowDisabled) )
{
charmapControl->DisableRecentCharsRow();
}
return(RunLD());
}
EXPORT_C void CAknCharMapDialog::CEikDialog_Reserved_1()
{
}
EXPORT_C void CAknCharMapDialog::CEikDialog_Reserved_2()
{
}
EXPORT_C void CAknCharMapDialog::CAknCharMapDialog_Reserved()
{
}
EXPORT_C void CAknCharMapDialog::ShowNoPictographs()
{
iExtension->iPictoMode = EAknCharMapPictoNoUse;
}
EXPORT_C void CAknCharMapDialog::ShowPictographsFirst()
{
iExtension->iPictoMode = EAknCharMapPictoFirst;
}
EXPORT_C void CAknCharMapDialog::SetEmotionMode(TAknCharMapEmotionMode aEmotionMode)
{
iExtension->iEmotionMode = aEmotionMode;
}
EXPORT_C void CAknCharMapDialog::ShowAnotherTable(TInt aCharCase)
{
iExtension->iShowAnotherTableCharCase = aCharCase;
}
void CAknCharMapDialog::DoLayout()
{
TAknLayoutRect dialogLayRect;
CAknCharMap* charmapControl = STATIC_CAST(CAknCharMap*, Control(EAknSCTQueryContentId));
// Number of character rows in the special char table.
TInt rows = charmapControl->HeightInRows();
if (!AknLayoutUtils::PenEnabled())
{
// Main pane without softkeys
TRect mainPaneRect;
if(!AknLayoutUtils::LayoutMetricsRect(AknLayoutUtils::EPopupParent, mainPaneRect))
{
mainPaneRect = iAvkonAppUi->ClientRect();
}
// Dialog layout, check variety first
TAknLayoutScalableParameterLimits charMapDialogVariety =
AknLayoutScalable_Avkon::popup_grid_graphic_window_ParamLimits();
TInt maxVariety = charMapDialogVariety.LastVariety();
// Check the CBA, if the orientation is not landscape
// there is not so much varieties
AknLayoutUtils::TAknCbaLocation location = AknLayoutUtils::CbaLocation();
TInt maxVarietyOffset = 0; // the offset for the certain cba location variety
TInt varietyOffset = maxVariety + 1;
// landscape variety number must be calculated offset == number of varieties
// same applies to the variety number for the biggest sized layout for the variety
if(Layout_Meta_Data::IsLandscapeOrientation())
{
varietyOffset = (maxVariety + 1)/KAknSctCBaButtonDirections; // the offset for one variety
}
// for right and left cba buttons the max variety is not zero
// the varities are ordered by the location of the cba and the descending order
// e.g the biggest sized layout first, the smallest last
if(location == AknLayoutUtils::EAknCbaLocationRight)
{
maxVarietyOffset = varietyOffset;
}
else if(location == AknLayoutUtils::EAknCbaLocationLeft)
{
maxVarietyOffset = varietyOffset + varietyOffset; // 2*
}
TInt varietyNumber = varietyOffset - rows;
// if more lines than possible to show, use the default
// (the biggest grid) variety
if(varietyNumber < 0)
varietyNumber = 0;
// if zero rows, use the minimum
else if(rows<=0)
varietyNumber -= 1;
//add the varietyoffset
varietyNumber += maxVarietyOffset;
// Layout the dialog size
dialogLayRect.LayoutRect( mainPaneRect,AknLayoutScalable_Avkon::popup_grid_graphic_window(varietyNumber));
}
else
{
dialogLayRect.LayoutRect(iAvkonAppUi->ApplicationRect(), AknLayoutScalable_Avkon::popup_grid_graphic2_window(0));
}
// Set the retangle for dialog and eventually to CAknCharMap
SetRect(dialogLayRect.Rect());
// Need to update popup heading's skin IDs to zero to draw background
// Offscreen background for picto table.
charmapControl->DrawOffscreenBackgroundIfRequired();
}
// -----------------------------------------------------------------------------
// CAknCharMapDialog::HandleControlEventL()
//
// Handles control events from char map table.
// -----------------------------------------------------------------------------
//
EXPORT_C void CAknCharMapDialog::HandleControlEventL(CCoeControl* aControl, TCoeEvent aEventType)
{
// get charmap control
CAknCharMap* charmapControl = STATIC_CAST(CAknCharMap*, Control(EAknSCTQueryContentId));
if ( charmapControl)
{
CAknPopupHeadingPane* headingPane = static_cast< CAknPopupHeadingPane* >( Control( EAknSCTQueryHeadingId ) );
if (headingPane)
{
TRAP_IGNORE(
{
headingPane->SetPageL(charmapControl->CurrentPage(),charmapControl->PageCount() );
} );
}
if (AknLayoutUtils::PenEnabled())
{
TRAP_IGNORE(charmapControl->RefreshNaviPageL());
}
}
if ( iExtension && (aControl == charmapControl) && (aEventType == EEventStateChanged) )
{
TInt status = charmapControl->StatusChanged();
if (status == EAknCharSelectedSpecialCharacter)
{
// Something has been selected from CharMap
iExtension->iFlags |= ECharMapDialogItemSelected;
}
else if (status == EAknCharChangedCategory)
{
TInt curCategory = charmapControl->CurrentCategory();
ChangeCategoryL(curCategory);
}
else if (status == EAknCharSelectedNextTableButton)
{
SwitchTablesL();
}
else if (status == EAknCharSelectedTableExitButton)
{
TryExitL(EAknSoftkeyExit);
}
}
}
// -----------------------------------------------------------------------------
// CAknCharMapDialog::HandleDialogPageEventL()
//
// Handles closing Charmap dialog after selection has been done with stylus.
// -----------------------------------------------------------------------------
//
EXPORT_C void CAknCharMapDialog::HandleDialogPageEventL(TInt aEventID)
{
if ( iExtension && aEventID == MEikDialogPageObserver::EDialogPageTapped )
{
if (iExtension->iFlags & ECharMapDialogItemSelected )
{
iExtension->iFlags = 0;
TryExitL(EAknSoftkeyOk);
}
else if (iExtension->iFlags == ECharMapDialogTableExitSelected)
{
iExtension->iFlags = 0;
TryExitL(EAknSoftkeyExit);
}
}
}
EXPORT_C void CAknCharMapDialog::LockNumericKeys(TBool aLockStatus)
{
if (aLockStatus)
{
iExtension->iFlags |= ECharMapDialogItemLockNumericKeys;
}
else
{
iExtension->iFlags &= (~ECharMapDialogItemLockNumericKeys);
}
}
EXPORT_C void CAknCharMapDialog::DisableRecentCharsRow()
{
iExtension->iFlags |= ECharMapDialogRecentCharsRowDisabled;
}
// -----------------------------------------------------------------------------
// CAknCharMapDialog::HandlePointerEventL()
//
// Handles pointer events
// -----------------------------------------------------------------------------
//
EXPORT_C void CAknCharMapDialog::HandlePointerEventL(const TPointerEvent& aPointerEvent)
{
if(!Rect().Contains(aPointerEvent.iPosition))
{
if(aPointerEvent.iType == TPointerEvent::EButton1Down)
{
TryExitL(EAknSoftkeyCancel);
return;
}
}
CAknDialog::HandlePointerEventL(aPointerEvent);
}
void CAknCharMapDialog::SwitchTablesOrPagesL()
{
if(!SwitchTablesL())
{
SwitchPagesL();
}
}
TBool CAknCharMapDialog::SwitchTablesL()
{
CAknCharMap* charmapControl = STATIC_CAST(CAknCharMap*, Control(EAknSCTQueryContentId));
CAknPopupHeadingPane* headingPane = STATIC_CAST(CAknPopupHeadingPane*, Control(EAknSCTQueryHeadingId));
TBool layoutChanged;
if (charmapControl->SwitchTablesL(layoutChanged))
{
ChangeLayoutL(layoutChanged);
SetSoftKeyL(ETrue);
return TRUE;
}
else
{
return FALSE;
}
}
void CAknCharMapDialog::SwitchPagesL()
{
CAknCharMap* charmapControl = STATIC_CAST(CAknCharMap*, Control(EAknSCTQueryContentId));
CAknPopupHeadingPane* headingPane = STATIC_CAST(CAknPopupHeadingPane*, Control(EAknSCTQueryHeadingId));
charmapControl->NextPageL();
RefreshTitleAndNaviL();
}
void CAknCharMapDialog::RefreshTitleAndNaviL()
{
CAknCharMap* charmapControl = STATIC_CAST(CAknCharMap*, Control(EAknSCTQueryContentId));
CAknPopupHeadingPane* headingPane = STATIC_CAST(CAknPopupHeadingPane*, Control(EAknSCTQueryHeadingId));
if (!AknLayoutUtils::PenEnabled())
{
const TDesC* title = charmapControl->Title();
headingPane->SetPageL(charmapControl->CurrentPage());
if (title != charmapControl->Title())
{
const TDesC* title = charmapControl->IsJapaneseSctUi() ?
charmapControl->TitleWithSelectingSpecialChar() :
charmapControl->Title();
headingPane->SetTextL(*title);
}
}
else
{
charmapControl->RefreshNaviPageL();
}
}
void CAknCharMapDialog::ChangeCategoryL(const TInt aCategory)
{
TBool layoutChanged;
CAknCharMap* charmapControl =
STATIC_CAST(CAknCharMap*, Control(EAknSCTQueryContentId));
if (charmapControl->ChangeCategoryL( aCategory, layoutChanged ))
{
ChangeLayoutL(layoutChanged);
SetSoftKeyL(ETrue);
}
}
void CAknCharMapDialog::ChangeLayoutL(const TBool aLayoutChanged)
{
CAknCharMap* charmapControl =
STATIC_CAST(CAknCharMap*, Control(EAknSCTQueryContentId));
CAknPopupHeadingPane* headingPane =
STATIC_CAST(CAknPopupHeadingPane*, Control(EAknSCTQueryHeadingId));
const TDesC* title = (charmapControl->IsJapaneseSctUi())?
charmapControl->TitleWithSelectingSpecialChar()
: charmapControl->Title();
if ( aLayoutChanged )
{
// This prevents the ugly graphics anomalies while the window
// is resized and repositioned.
Window().SetVisible( EFalse );
if (!AknLayoutUtils::PenEnabled())
{
headingPane->SetTextL(*title);
headingPane->SetPageL(1, charmapControl->PageCount());
}
DoLayout();
DrawNow();
Window().SetVisible( ETrue );
}
// If the layout is the same, do not set layout again
// as this causes flicker.
else
{
if (!AknLayoutUtils::PenEnabled())
{
headingPane->SetTextL(*title);
headingPane->SetPageL(1, charmapControl->PageCount());
}
else
{
charmapControl->RefreshNaviPageL();
}
// Offscreen background for picto table.
charmapControl->DrawOffscreenBackgroundIfRequired();
DrawNow();
}
}
void CAknCharMapDialog::SetSoftKeyL(const TBool aDrawNow /*= EFalse*/)
{
CAknCharMap* charmapControl =
STATIC_CAST(CAknCharMap*, Control(EAknSCTQueryContentId));
CEikButtonGroupContainer& cba = ButtonGroupContainer();
TInt labelId(R_AVKON_SOFTKEY_SELECT_TEXT);
TInt id(EAknSoftkeySelect);
if (charmapControl->PageCount() > 1)
{
labelId = R_AVKON_SOFTKEY_NEXT_TEXT;
id = EAknSoftkeyNext;
}
HBufC* label = StringLoader::LoadL(labelId, iCoeEnv);
CleanupStack::PushL(label);
cba.SetCommandL(0, id, label->Des());
CleanupStack::PopAndDestroy(label); // label
// In Japanese UI, right softkey is "Back".
if (charmapControl->IsJapaneseSctUi())
{
label = StringLoader::LoadL(R_AVKON_SOFTKEY_JAPAN_SCT_BACK, iCoeEnv);
CleanupStack::PushL(label);
cba.SetCommandL(2, EAknSoftkeyClose, label->Des());
CleanupStack::PopAndDestroy(label); // label
}
// Since MSK is enable from the branch of 3.1, set MSK as Select Key
if (charmapControl->PageCount() > 1 && AknLayoutUtils::MSKEnabled())
{
label = StringLoader::LoadL(R_QTN_MSK_SELECT, iCoeEnv);
CleanupStack::PushL(label);
cba.SetCommandL(3, EAknSoftkeySelect,label->Des());
CleanupStack::PopAndDestroy(label); // label
}
// Drawing
if (aDrawNow)
{
cba.DrawNow();
}
}
// End of File