javauis/lcdui_akn/lcdui/src/CMIDEdwinUtils.cpp
branchRCL_3
changeset 14 04becd199f91
child 21 4376525cdefb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/lcdui_akn/lcdui/src/CMIDEdwinUtils.cpp	Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,1506 @@
+/*
+* Copyright (c) 2008 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:  Keymappings etc. customized for Series 60.
+*
+*/
+
+
+// INCLUDE FILES
+#include <CVPbkContactLinkArray.h>
+#include <MVPbkContactLink.h>
+#include <CVPbkContactManager.h>
+#include <MVPbkStoreContact.h>
+#include <MVPbkContactOperationBase.h>
+#include <MVPbkContactFieldData.h>
+#include <MVPbkContactFieldTextData.h>
+
+#include <CPbk2SortOrderManager.h>
+#include <Pbk2ContactNameFormatterFactory.h>
+#include <MPbk2ContactNameFormatter.h>
+
+// Avkon dialog for info notes
+#include <aknnotewrappers.h>
+
+// for fetching contacts from phonebook
+#include <CPbk2StoreConfiguration.h>
+#include <MVPbkStoreContact.h>
+#include <CVPbkContactLinkArray.h>
+#include <MVPbkContactFieldTextData.h>
+#include <MVPbkContactStoreList.h>
+#include <CVPbkContactManager.h>
+
+// aiw used to invoke phonebook
+#include <AiwContactSelectionDataTypes.h>
+
+// phone client API classes for starting phone call
+#include <AiwCommon.h>
+#include <aiwdialdata.h>
+#include <aiwdialdataext.h>
+
+// FeatureManager::FeatureSupported(KFeatureIdThai) used in SetInitialInputModeL
+#include <featmgr.h>
+// CAknExtendedInputCapabilities for extended input capabilities
+#include <aknextendedinputcapabilities.h>
+
+#include <StringLoader.h>
+
+
+#include <eikenv.h>
+#include <eikappui.h>
+#include <coecntrl.h>
+
+#include <EIKCOCTL.rsg>
+
+#include <aknenv.h>
+#include <AknUtils.h>
+#include <AknSettingCache.h>
+
+#include <aknappui.h>
+
+#include <AknsUtils.h>
+
+#include <j2me/jdebug.h>
+
+#include "CMIDKeyDecoder.h"
+#include "CMIDEdwinUtils.h"
+
+#include <lcdui.rsg>
+
+#undef  TRAP_INSTRUMENTATION_LEAVE
+#define TRAP_INSTRUMENTATION_LEAVE(aResult) DEBUG_INT2("In CMIDEdwin.cpp, trapped method was called at line %D and got exception %D", __LINE__, aResult);
+
+CMIDEdwinUtils* CMIDEdwinUtils::NewL(MMIDTextBox* aTextBox, const TChar aDecimalSeparator)
+{
+    CMIDEdwinUtils* utils = new(ELeave) CMIDEdwinUtils(aTextBox, aDecimalSeparator);
+    CleanupStack::PushL(utils);
+    utils->ConstructL();
+    CleanupStack::Pop(utils);
+    return utils;
+}
+
+CMIDEdwinUtils::CMIDEdwinUtils(MMIDTextBox* aTextBox, const TChar aDecimalSeparator)
+        : iTextBox(aTextBox), iDecimalSeparator(aDecimalSeparator)
+{}
+
+void CMIDEdwinUtils::ConstructL()
+{
+}
+
+/**
+ * Checks whether the given text is valid within the given constraints.
+ * When the contents of the TextBox are set PROGRAMMATICALLY (parameter aActualContents
+ * is true), constraint validity is checked more strictly, as some constraints
+ * allow certain strings while the user is typing but not as the actual contents.
+ */
+TBool CMIDEdwinUtils::ConstraintsValidForText(const TDesC& aText,TUint aConstraints, TBool aActualContents)
+{
+    TUint constraint = aConstraints & MMIDTextField::EConstraintMask;
+    if (constraint == MMIDTextField::EAny)
+        return ETrue;
+    //
+    TBool valid = ETrue;
+    switch (constraint)
+    {
+    case MMIDTextField::EMailAddr:
+    case MMIDTextField::EUrl:
+        valid = IsTextValid(aText);
+        break;
+    case MMIDTextField::ENumeric:
+        if (aActualContents)
+        {
+            valid = IsJavaInteger(aText);
+        }
+        else
+        {
+            valid = IsNumeric(aText);
+        }
+        break;
+    case MMIDTextField::EPhoneNumber:
+        valid = CMIDEdwinUtils::IsPhoneNumber(aText);
+        break;
+    case MMIDTextField::EDecimal:
+        if (aActualContents)
+        {
+            valid = IsJavaFloatingPointLiteral(aText);
+        }
+        else
+        {
+            valid = IsDecimal(aText, iDecimalSeparator);
+        }
+        break;
+    default:
+        ASSERT(EFalse);
+    }
+    return valid;
+}
+
+TBool CMIDEdwinUtils::ConstraintsValidForInsertedTextL(const TDesC& aText, const TDesC& aTextToInsert, TInt aPos, TUint aConstraints, TBool aActualContents)
+{
+    HBufC* text = HBufC::NewL(aText.Length() + aTextToInsert.Length());
+    TPtr ptr = text->Des();
+    ptr.Copy(aText);
+    ptr.Insert(aPos,aTextToInsert);
+    TBool valid = ConstraintsValidForText(ptr, aConstraints, aActualContents);
+    delete text;
+    return valid;
+}
+
+
+TBool CMIDEdwinUtils::IsHotKeyL(const TKeyEvent& aKeyEvent, CCoeEnv* aCoeEnv)
+{
+    TBuf<24> buf;
+    if (aKeyEvent.iModifiers & EModifierShift)
+    {
+        aCoeEnv->ReadResourceL(buf,R_EIK_EDWIN_SHIFT_CTRL_HOTKEYS);
+    }
+    else
+    {
+        aCoeEnv->ReadResourceL(buf,R_EIK_EDWIN_CTRL_HOTKEYS);
+    }
+    const TInt ret=buf.Locate(TChar(aKeyEvent.iCode+'a'-1));
+    switch (ret)
+    {
+    case CEikEdwin::EHotKeyCut:
+    case CEikEdwin::EHotKeyCopy:
+    case CEikEdwin::EHotKeyPaste:
+    case CEikEdwin::EHotKeyUndo:
+    case CEikEdwin::EHotKeyFind:
+    case CEikEdwin::EHotKeyInsertChar:
+        return ETrue;
+    default:
+        return EFalse;
+    }
+}
+
+TBool CMIDEdwinUtils::IsNavigationKey(const TKeyEvent& aKeyEvent)
+{
+    switch (aKeyEvent.iCode)
+    {
+    case EKeyDownArrow:
+    case EKeyUpArrow:
+    case EKeyLeftArrow:
+    case EKeyRightArrow:
+    case EKeyBackspace:
+    case EKeyDelete:
+    case EKeyEscape:
+    case EKeyPageUp:
+    case EKeyPageDown:
+    case EKeyHome:
+    case EKeyEnd:
+        return ETrue;
+    default:
+        return EFalse;
+    }
+}
+
+TBool CMIDEdwinUtils::IsPhoneNumber(const TDesC& aText)
+{
+    TInt pos = aText.Length();
+    for (; pos>0;)
+    {
+        TChar ch((aText)[--pos]);
+        // allow also digits in non-western numbers
+        if (IsNumeric(ch))
+            continue;
+
+        switch (ch)
+        {
+        case '+':
+        case '*':
+        case '#':
+        case 'p':
+        case 'w':
+            break;
+        default:
+            return EFalse;
+        }
+    }
+    return ETrue;
+}
+
+/**
+ * Tests whether a typed string is a legal NUMERIC string. This test is more
+ * loose than that in IsJavaInteger(), as "-" is a
+ * legal text value during typing but not when set programmatically.
+ */
+TBool CMIDEdwinUtils::IsNumeric(const TDesC& aText)
+{
+    TInt length = aText.Length();
+    TInt pos = length;
+    for (; pos>0;)
+    {
+        TChar ch((aText)[--pos]);
+        //
+        if (IsNumeric(ch))
+            continue;
+        //
+        switch (ch)
+        {
+        case '-':
+            if (pos != 0)
+                return EFalse;
+            break;
+        default:
+            return EFalse;
+        }
+    }
+    return ETrue;
+}
+
+/**
+* Tests whether a character is legal number, correct values
+* are 0-9 and all language variants (arabic etc.)
+*/
+TBool CMIDEdwinUtils::IsNumeric(const TChar& aChar)
+{
+    return ((aChar >= '0' && aChar <= '9')            // Western
+            || (aChar >= 0x0660 && aChar <= 0x0669)  // Arabic-Indic
+            || (aChar >= 0x06F0 && aChar <= 0x06F9)  // Extended Arabic-Indic
+            || (aChar >= 0x0966 && aChar <= 0x096F)  // Devanagari
+            || (aChar >= 0xFF10 && aChar <= 0xFF19)  // Fullwidth
+           );
+}
+
+/**
+ * Tests whether the given string is a legal NUMERIC string when set
+ * programmatically.
+ *
+ * According to the Java API spec, a string cannot be parsed into an int if:
+ * Any character of the string is not a digit of the specified radix,
+ * except that the first character may be a minus sign '-' ('\u002D')
+ * provided that the string is longer than length 1.
+ */
+TBool CMIDEdwinUtils::IsJavaInteger(const TDesC& aText)
+{
+    if (!IsNumeric(aText))
+    {
+        return EFalse;
+    }
+    // additional test #1: "-" is illegal
+    if (aText.Length() == 1)
+    {
+        if ((aText.Locate(TChar('-')) == 0))
+        {
+            return EFalse;
+        }
+    }
+    return ETrue;
+}
+
+/**
+ * Tests whether a typed text is a valid one.
+ */
+TBool CMIDEdwinUtils::IsTextValid(const TDesC& aText)
+{
+    TInt pos = aText.Length();
+    while (pos-- > 0)
+    {
+        TChar ch((aText)[ pos ]);
+
+        // IsValidChar function will check chars over 255
+        if (!IsValidChar(ch.GetNumericValue()) || ch == 0x7f)
+        {
+            return EFalse;
+        }
+    }
+
+    return ETrue;
+}
+
+/**
+ * Tests whether a char is a valid. Tests only characters over 255
+ */
+TBool CMIDEdwinUtils::IsValidChar(TInt aChar) const
+{
+    TBool ret(ETrue);
+
+    // Tests only characters over 255
+    if (aChar >= 0xFF)
+    {
+        // 0x20AC - Unicode for euro sign
+        if (aChar == 0x20AC || aChar == CEditableText::EParagraphDelimiter ||
+                aChar == CEditableText::ELineBreak)
+        {
+            ret = ETrue;
+        }
+        else
+        {
+            ret = EFalse;
+        }
+    }
+
+    return ret;
+}
+
+/**
+ * Tests whether a typed string is a legal DECIMAL string. This test is more
+ * loose than that in IsJavaFloatingPointLiteral(), as ".", "-" and "-." are
+ * legal text values during typing but not when set programmatically.
+ */
+TBool CMIDEdwinUtils::IsDecimal(const TDesC& aText, const TChar aDecimalSeparator)
+{
+    TInt length = aText.Length();
+    TInt pos = length;
+    for (; pos>0;)
+    {
+        TChar ch((aText)[--pos]);
+        //
+        if (ch.IsDigit())
+        {
+            continue;
+        }
+        else if (ch == '-')
+        {
+            if (pos != 0)
+                return EFalse;
+        }
+        else if (ch == aDecimalSeparator)
+        {
+            if (aText.Locate(aDecimalSeparator) != aText.LocateReverse(aDecimalSeparator))
+                return EFalse;
+        }
+        else
+        {
+            return EFalse;
+        }
+    }
+    return ETrue;
+}
+
+/**
+ * Tests whether the given string is a legal DECIMAL string when set
+ * programmatically.
+ */
+TBool CMIDEdwinUtils::IsJavaFloatingPointLiteral(const TDesC& aText)
+{
+    if (!IsDecimal(aText, '.'))
+    {
+        return EFalse;
+    }
+    // additional test #1: "." and "-" are illegal
+    if (aText.Length() == 1)
+    {
+        if ((aText.Locate(TChar('.')) == 0) || (aText.Locate(TChar('-')) == 0))
+        {
+            return EFalse;
+        }
+    }
+    // additional test #2: "-." is illegal
+    if (aText.Length() == 2)
+    {
+        if ((aText.Locate(TChar('-')) == 0) && (aText.Locate(TChar('.')) == 1))
+        {
+            return EFalse;
+        }
+    }
+    return ETrue;
+}
+
+void CMIDEdwinUtils::RemoveNonPhoneNumberChars(HBufC* buf)
+{
+    TPtr text = buf->Des();
+    for (TInt pos=0; pos < text.Length();)
+    {
+        TChar ch((text)[pos]);
+        // allow also digits in non-western numbers
+        if (IsNumeric(ch))
+        {
+            ++pos;
+            continue;
+        }
+
+        switch (ch)
+        {
+        case '+':
+        case '*':
+        case '#':
+        case 'p':
+        case 'w':
+            ++pos;
+            continue;
+        }
+        text.Delete(pos, 1);
+    }
+}
+
+/** Converts from java format text to localized (visible) format.
+@see ConvertToLocalizedDecimalLC() */
+HBufC* CMIDEdwinUtils::ConvertToLocalizedLC(const TDesC& aText, TUint aConstraints)
+{
+    HBufC* text = NULL;
+    if ((aConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EDecimal)
+    {
+        text = ConvertToLocalizedDecimalLC(aText);
+    }
+    else
+    {
+        text = aText.AllocLC();
+        TBool supportLineBreaks(ETrue);
+
+        // Convert breaks if needed if constraints that do not allow line
+        // breaks.
+        if (aConstraints & MMIDTextField::EUrl ||
+                aConstraints & MMIDTextField::EMailAddr)
+        {
+            // Line breaks are not supported
+            supportLineBreaks = EFalse;
+        }
+
+        CMIDUtils::MapJavaToETextChars(text, supportLineBreaks);
+    }
+    return text;
+}
+
+/** Converts decimal point, if any, to a localized decimal separator. */
+HBufC* CMIDEdwinUtils::ConvertToLocalizedDecimalLC(const TDesC& aText)
+{
+    HBufC* buf = aText.AllocLC();
+    TPtr text = buf->Des();
+    TInt pos = buf->Length();
+    for (; pos>0;)
+    {
+        TText& ch = text[--pos];
+        if (ch == '.')
+            ch = (TText)iDecimalSeparator;
+    }
+    return buf;
+}
+
+/** Converts localized decimal separator, if any, to a decimal point. */
+void CMIDEdwinUtils::ConvertFromLocalizedDecimal(HBufC* buf)
+{
+    TPtr text = buf->Des();
+    TInt pos = buf->Length();
+    for (; pos>0;)
+    {
+        TText& ch = text[--pos];
+        if (ch == (TText)iDecimalSeparator)
+            ch = '.';
+    }
+}
+
+
+TLanguage CMIDEdwinUtils::SelectLanguage(TInt aCharSubset,
+        TLanguage aDefaultLanguage)
+{
+    TLanguage language = CAknEnv::Static()->SettingCache().InputLanguage();
+    if (IsLanguageInCharSubset(language, aCharSubset))
+    {
+        return language;        // global input language
+    }
+    language = User::Language();
+    if (IsLanguageInCharSubset(language, aCharSubset))
+    {
+        return language;        // display language
+    }
+    return aDefaultLanguage;    // given default
+}
+
+/**
+ * Returns ETrue if the given language belongs to the given MIDP character subset.
+ */
+TBool CMIDEdwinUtils::IsLanguageInCharSubset(TLanguage aLanguage, TInt aCharSubset)
+{
+    switch (aLanguage)
+    {
+        // Cyrillic languages:
+    case ELangBulgarian:
+    case ELangRussian:
+    case ELangSerbian:
+    case ELangUkrainian:
+        return (aCharSubset == EMidpUcbCyrillic);
+
+        // Arabic languages:
+    case ELangArabic:
+    case ELangFarsi:
+    case ELangUrdu:
+        return (aCharSubset == EMidpUcbArabic);
+
+        // Traditional Chinese languages, support latin, too:
+    case ELangTaiwanChinese:
+    case ELangHongKongChinese:
+        return (aCharSubset == EMidpIsTraditionalHanzi ||
+                aCharSubset == EMidpIsLatin);
+        // Devanagari script languages
+    case ELangHindi:
+    case ELangMarathi:
+        return (aCharSubset == EMidpUcbDevanagari);
+
+        // Single languages that belong to other character subsets than latin
+    case ELangHebrew:
+    case ELangGreek:
+    case ELangVietnamese:  // not yet in 3.0
+    case ELangThai:
+        return (aCharSubset == EMidpCharSubsetNone);
+
+        // All the rest are latin languages; Japanese and Simplified Chinese
+        // included here,  because they support latin, too
+    default:
+        return (aCharSubset == EMidpIsLatin);
+    }
+}
+/**
+ * Returns ETrue if number conversion is needed.
+ */
+TBool CMIDEdwinUtils::IsNumberConversionNeeded(TInt aConstraints)
+{
+    TUint constraint = aConstraints & MMIDTextField::EConstraintMask;
+    if (constraint == 0)
+        return AknTextUtils::DigitModeQuery(AknTextUtils::EDigitModeEditorDefault);
+    else if ((constraint == MMIDTextField::ENumeric
+              || constraint == MMIDTextField::EDecimal
+              || constraint == MMIDTextField::EPhoneNumber
+             ) && AknTextUtils::DigitModeQuery(AknTextUtils::EDigitModeNumberEditor)
+            )
+        return ETrue;
+    else if ((constraint == MMIDTextField::EMailAddr
+              || constraint == MMIDTextField::EUrl
+             ) && AknTextUtils::DigitModeQuery(AknTextUtils::EDigitModeNumberEditor)
+            )
+        return ETrue;
+
+    return EFalse;
+}
+
+void CMIDEdwinUtils::CreatePhoneCallL(TInt aTextLength, RWsSession aWsSession, CEikEdwin* aEdwin)
+{
+    if (aTextLength == 0 || aTextLength > AIWDialDataExt::KMaximumPhoneNumberLength)
+    {
+        return;  // silently ignore empty or too long number
+    }
+
+    /*
+     * Get the current window group. Needed to activate the current app window
+     * @note Temporary. This might not necessarily be the front-most window group,
+     *  as window groups can disable keyboard focus.
+     */
+    RWsSession  wsSession = aWsSession;
+    TInt currWindowGroup = wsSession.GetFocusWindowGroup();
+
+    // ask for confirmation (as required by MIDP)
+    CCallConfirmationDialog* dlg = CCallConfirmationDialog::NewL(aEdwin->GetTextInHBufL()->Des());
+
+    if (!dlg->ExecuteLD(R_MIDP_CONFIRMATION_DIALOG))
+        return;
+
+    // Create service handler instance
+    CAiwServiceHandler* aiwServiceHandler = CAiwServiceHandler::NewLC();  // cleanup stack 1
+
+    // Create AIW interest
+    RCriteriaArray interest;
+    CleanupClosePushL(interest);        // cleanup stack 2
+    CAiwCriteriaItem* criteria = CAiwCriteriaItem::NewLC(
+                                     KAiwCmdCall, KAiwCmdCall,
+                                     _L8("*"));     // cleanup stack 3
+    TUid base;
+    base.iUid = KAiwClassBase;
+    criteria->SetServiceClass(base);
+    User::LeaveIfError(interest.Append(criteria));
+
+    // attach to AIW interest
+    aiwServiceHandler->AttachL(interest);
+
+    // create dial data
+    CAiwDialData* dialData = CAiwDialData::NewLC();  // cleanup stack 4
+
+    // define call parameters
+    dialData->SetCallType(CAiwDialData::EAIWVoice);     // voice call
+
+    // Use GetTextL to convert allow conversion of non-western numbers
+    HBufC* phoneNumber = iTextBox->GetTextL();  // get the phone number
+    CleanupStack::PushL(phoneNumber);       // cleanup stack 5 in case something leaves
+    dialData->SetPhoneNumberL(*phoneNumber);
+
+    // the window group where it switches to after the phone call
+    dialData->SetWindowGroup(currWindowGroup);
+
+    CAiwGenericParamList& paramList = aiwServiceHandler->InParamListL();
+    dialData->FillInParamListL(paramList);
+
+    // Execute AIW command with notification callback
+    aiwServiceHandler->ExecuteServiceCmdL(KAiwCmdCall, paramList,
+                                          aiwServiceHandler->OutParamListL(),
+                                          0, NULL);
+
+    // detach from AIW interest
+    aiwServiceHandler->DetachL(interest);
+
+    // aiwServiceHandler, interest, criteria, dialData, phoneNumber
+    CleanupStack::PopAndDestroy(5);
+
+    aiwServiceHandler = NULL;
+    phoneNumber = NULL;
+}
+
+void CMIDEdwinUtils::SetInitialInputModeL(const TDesC& aCharacterSubset, TUint aConstraints, TInt& aInitialCurrentCase,
+        TInt& aInitialCurrentInputMode, TLanguage& aInitialCurrentLanguage)
+{
+    TInt initialCurrentCase = 0;
+    TInt initialCurrentInputMode = 0;
+    TLanguage initialCurrentLanguage = ELangTest;  // 0
+
+    TUint constraint = aConstraints & MMIDTextField::EConstraintMask;
+    if (constraint == MMIDTextField::EAny ||
+            constraint == MMIDTextField::EMailAddr ||
+            constraint == MMIDTextField::EUrl)
+    {
+        if (aCharacterSubset.Length() == 0)
+        {
+            // null: default input mode
+            initialCurrentLanguage = CAknEnv::Static()->SettingCache().InputLanguage();
+            initialCurrentCase = EAknEditorTextCase;
+        }
+        else if (aCharacterSubset.Compare(KMidpUppercaseLatin) == 0)
+        {
+            // MIDP_UPPERCASE_LATIN
+            // ignored if INITIAL_CAPS_SENTENCE or INITIAL_CAPS_WORD modifier in ANY
+            if (!(aConstraints & MMIDTextField::EInitialCapsWordSentence ||
+                    aConstraints & MMIDTextField::EInitialCapsWord) ||
+                    constraint != MMIDTextField::EAny)
+            {
+                initialCurrentLanguage = CMIDEdwinUtils::SelectLanguage(EMidpIsLatin, ELangEnglish);
+                initialCurrentInputMode = EAknEditorTextInputMode;
+                initialCurrentCase = EAknEditorUpperCase;
+            }
+        }
+        else if (aCharacterSubset.Compare(KMidpLowercaseLatin) == 0)
+        {
+            // MIDP_LOWERCASE_LATIN
+            // ignored if INITIAL_CAPS_SENTENCE or INITIAL_CAPS_WORD modifier in ANY
+            if (!(aConstraints & MMIDTextField::EInitialCapsWordSentence ||
+                    aConstraints & MMIDTextField::EInitialCapsWord) ||
+                    constraint != MMIDTextField::EAny)
+            {
+                initialCurrentLanguage = CMIDEdwinUtils::SelectLanguage(EMidpIsLatin, ELangEnglish);
+                initialCurrentInputMode = EAknEditorTextInputMode;
+                initialCurrentCase = EAknEditorLowerCase;
+            }
+        }
+        else if (aCharacterSubset.Compare(KUcbBasicLatin) == 0 ||
+                 aCharacterSubset.Compare(KIsLatin) == 0)
+        {
+            // UCB_BASIC_LATIN, IS_LATIN
+            initialCurrentLanguage = CMIDEdwinUtils::SelectLanguage(EMidpIsLatin, ELangEnglish);
+            initialCurrentInputMode = EAknEditorTextInputMode;
+            initialCurrentCase = EAknEditorTextCase;
+        }
+        else if (aCharacterSubset.Compare(KIsLatinDigits) == 0)
+        {
+            // IS_LATIN_DIGITS
+            initialCurrentInputMode = EAknEditorNumericInputMode;
+        }
+        else if (aCharacterSubset.Compare(KUcbArabic) == 0)
+        {
+            // UCB_ARABIC
+            initialCurrentLanguage = ELangArabic;
+        }
+        else if (aCharacterSubset.Compare(KUcbHebrew) == 0)
+        {
+            // UCB_HEBREW
+            initialCurrentLanguage = ELangHebrew;
+        }
+        else if (aCharacterSubset.Compare(KUcbGreek) == 0)
+        {
+            // UCB_GREEK
+            initialCurrentLanguage = ELangGreek;
+            initialCurrentCase = EAknEditorTextCase;
+        }
+        else if (aCharacterSubset.Compare(KUcbCyrillic) == 0)
+        {
+            // UCB_CYRILLIC
+            initialCurrentLanguage = CMIDEdwinUtils::SelectLanguage(EMidpUcbCyrillic, ELangRussian);
+            initialCurrentCase = EAknEditorTextCase;
+        }
+        else if (aCharacterSubset.Compare(KUcbDevanagari) == 0)
+        {
+            // UCB_DEVANAGARI
+            initialCurrentLanguage = CMIDEdwinUtils::SelectLanguage(EMidpUcbDevanagari, ELangHindi);
+        }
+        else if (aCharacterSubset.Compare(KUcbThai) == 0)
+        {
+            // UCB_THAI
+            if (FeatureManager::FeatureSupported(KFeatureIdThai))
+            {
+                initialCurrentLanguage = ELangThai;
+            }
+        }
+        else if (aCharacterSubset.Compare(KIsSimplifiedHanzi) == 0)
+        {
+            // IS_SIMPLIIFED_HANZI
+            if (FeatureManager::FeatureSupported(KFeatureIdChinese))
+            {
+                initialCurrentLanguage = ELangPrcChinese;
+            }
+        }
+        else if (aCharacterSubset.Compare(KIsTraditionalHanzi) == 0)
+        {
+            // IS_TRADITIONAL_HANZI
+            if (FeatureManager::FeatureSupported(KFeatureIdChinese))
+            {
+                initialCurrentLanguage = CMIDEdwinUtils::SelectLanguage(EMidpIsTraditionalHanzi,
+                                         ELangTest);  // No suitable default for initial input language
+            }
+        }
+        else if (aCharacterSubset.Compare(KUcbKatakana) == 0)
+        {
+            // UCB_KATAKANA
+            if (FeatureManager::FeatureSupported(KFeatureIdJapanese))
+            {
+                initialCurrentLanguage = ELangJapanese;
+                initialCurrentInputMode = EAknEditorFullWidthKatakanaInputMode;
+            }
+        }
+        else if (aCharacterSubset.Compare(KUcbHiragana) == 0 ||
+                 aCharacterSubset.Compare(KIsKanji) == 0)
+        {
+            // UCB_HIRAGANA, IS_KANJI
+            if (FeatureManager::FeatureSupported(KFeatureIdJapanese))
+            {
+                initialCurrentLanguage = ELangJapanese;
+                initialCurrentInputMode = EAknEditorHiraganaKanjiInputMode;
+            }
+        }
+        else if (aCharacterSubset.Compare(KIsHalfwidthKatakana) == 0)
+        {
+            // IS_HALFWIDTH_KATAKANA
+            if (FeatureManager::FeatureSupported(KFeatureIdJapanese))
+            {
+                initialCurrentLanguage = ELangJapanese;
+                initialCurrentInputMode = EAknEditorKatakanaInputMode;
+            }
+        }
+        else if (aCharacterSubset.Compare(KIsFullwidthDigits) == 0)
+        {
+            // IS_FULLWIDTH_DIGITS
+            if (FeatureManager::FeatureSupported(KFeatureIdJapanese))
+            {
+                initialCurrentLanguage = ELangJapanese;
+                initialCurrentInputMode = EAknEditorFullWidthNumericInputMode;
+            }
+        }
+        else if (aCharacterSubset.Compare(KIsFullwidthLatin) == 0)
+        {
+            // IS_FULLWIDTH_LATIN
+            if (FeatureManager::FeatureSupported(KFeatureIdJapanese))
+            {
+                initialCurrentLanguage = ELangJapanese;
+                initialCurrentInputMode = EAknEditorFullWidthTextInputMode;
+            }
+        }
+        else if (aCharacterSubset.Compare(KXNokiaVietnamese) == 0)
+        {
+            // X_NOKIA_VIETNAMESE
+            initialCurrentLanguage = ELangVietnamese;
+            initialCurrentInputMode = EAknEditorTextInputMode;
+            initialCurrentCase = EAknEditorTextCase;
+        }
+        else if (aCharacterSubset.Compare(KXNokiaUrdu) == 0)
+        {
+            // X_NOKIA_URDU
+            initialCurrentLanguage = ELangUrdu;
+            initialCurrentInputMode = EAknEditorTextInputMode;
+        }
+        else if (aCharacterSubset.Compare(KXNokiaFarsi) == 0)
+        {
+            // X_NOKIA_FARSI
+            initialCurrentLanguage = ELangFarsi;
+            initialCurrentInputMode = EAknEditorTextInputMode;
+        }
+
+        aInitialCurrentCase = initialCurrentCase;
+        aInitialCurrentInputMode = initialCurrentInputMode;
+        aInitialCurrentLanguage = initialCurrentLanguage;
+    }
+}
+
+void CMIDEdwinUtils::SetFEPModeAndCharFormat(TUint aConstraints, CEikEdwin* aEdwin)
+{
+    // by default, allow all case modes
+    aEdwin->SetAknEditorPermittedCaseModes(EAknEditorAllCaseModes);
+    aEdwin->SetAknEditorCase(EAknEditorTextCase);
+    if (aEdwin->TextView())
+    {
+        //This sets secret editors as one liners.
+        //This is disabled because secret editors convert paragraph delimiters
+        //in spaces and because the line wrapping works differently depending
+        //on wheather the temporary char is displayed or the '*' is displayed.
+        TRAP_IGNORE(aEdwin->SetWordWrapL(aConstraints & MMIDTextField::EPassword ? EFalse : ETrue));
+    }
+    aEdwin->SetAknEditorFlags(EAknEditorFlagDefault);
+    aEdwin->SetAknEditorSpecialCharacterTable(-1);
+
+    // handle all constraints and the PASSWORD modifier
+    TUint constraint = aConstraints & MMIDTextField::EConstraintMask;
+    if ((constraint == MMIDTextField::EAny) && (aConstraints & MMIDTextField::EPassword))
+    {
+        constraint = MMIDTextField::EPassword;
+    }
+
+    switch (constraint)
+    {
+    case MMIDTextField::EAny:
+        aEdwin->SetAknEditorAllowedInputModes(EAknEditorTextInputMode | EAknEditorNumericInputMode);
+        aEdwin->SetAknEditorInputMode(EAknEditorTextInputMode);
+        // Calling AknEditorCurrentInputMode during construction caused problems in Chinese
+
+        // handle other modifiers
+        if ((aConstraints & MMIDTextField::ENonPredictive) || (aConstraints & MMIDTextField::ESensitive))
+        {
+            aEdwin->SetAknEditorFlags(EAknEditorFlagNoT9 | EAknEditorFlagDeliverVirtualKeyEventsToApplication);
+        }
+        else
+        {
+            aEdwin->SetAknEditorFlags(EAknEditorFlagDeliverVirtualKeyEventsToApplication);
+        }
+        if ((aConstraints & MMIDTextField::EInitialCapsWordSentence) || (aConstraints & MMIDTextField::EInitialCapsWord))
+        {
+            aEdwin->SetAknEditorCurrentCase(EAknEditorTextCase);
+        }
+        aEdwin->SetAknEditorSpecialCharacterTable(R_MIDP_TEXTBOX_SPECIAL_CHARACTER_TABLE_DIALOG);
+        break;
+    case MMIDTextField::EMailAddr:
+    case MMIDTextField::EUrl:
+    case MMIDTextField::EPassword:
+        // set auto capitalization off, permit only UpperCase and LowerCase modes
+        aEdwin->SetAknEditorPermittedCaseModes(EAknEditorUpperCase | EAknEditorLowerCase);
+
+        aEdwin->SetAknEditorAllowedInputModes(EAknEditorTextInputMode | EAknEditorNumericInputMode);
+        aEdwin->SetAknEditorInputMode(EAknEditorTextInputMode);
+        aEdwin->SetAknEditorCurrentInputMode(EAknEditorTextInputMode);
+        aEdwin->SetAknEditorCase(EAknEditorLowerCase);
+        aEdwin->SetAknEditorCurrentCase(EAknEditorLowerCase);
+        aEdwin->SetAknEditorFlags(EAknEditorFlagNoT9 | EAknEditorFlagDeliverVirtualKeyEventsToApplication);
+        aEdwin->SetAknEditorSpecialCharacterTable(R_MIDP_TEXTBOX_SPECIAL_CHARACTER_TABLE_DIALOG);
+        break;
+    case MMIDTextField::ENumeric:
+    {
+        aEdwin->SetAknEditorCase(EAknSCTNumeric);
+        aEdwin->SetAknEditorAllowedInputModes(EAknEditorNumericInputMode);
+        aEdwin->SetAknEditorInputMode(EAknEditorNumericInputMode);
+        aEdwin->SetAknEditorCurrentInputMode(EAknEditorNumericInputMode);
+        aEdwin->SetAknEditorNumericKeymap(EAknEditorPlainNumberModeKeymap);
+        //Disable SCT
+        CAknExtendedInputCapabilities* extendedInputCapabilities = NULL;
+        aEdwin->MopGetObject(extendedInputCapabilities);
+        if (extendedInputCapabilities)
+        {
+            extendedInputCapabilities->SetCapabilities(
+                extendedInputCapabilities->Capabilities() |
+                CAknExtendedInputCapabilities::EDisableSCT);
+        }
+        aEdwin->SetAknEditorFlags(EAknEditorFlagFixedCase | EAknEditorFlagNoT9 |
+                                  EAknEditorFlagUseSCTNumericCharmap | EAknEditorFlagDeliverVirtualKeyEventsToApplication);
+        aEdwin->SetAknEditorSpecialCharacterTable(R_MIDP_TEXTBOX_NUMERIC_MODE_DIALOG);
+    }
+    break;
+    case MMIDTextField::EDecimal:
+        aEdwin->SetAknEditorCase(EAknSCTNumeric);
+        aEdwin->SetAknEditorAllowedInputModes(EAknEditorNumericInputMode);
+        aEdwin->SetAknEditorInputMode(EAknEditorNumericInputMode);
+        aEdwin->SetAknEditorCurrentInputMode(EAknEditorNumericInputMode);
+        aEdwin->SetAknEditorFlags(EAknEditorFlagFixedCase | EAknEditorFlagNoT9 |
+                                  EAknEditorFlagUseSCTNumericCharmap | EAknEditorFlagDeliverVirtualKeyEventsToApplication);
+        aEdwin->SetAknEditorNumericKeymap(EAknEditorPlainNumberModeKeymap);
+        if (iDecimalSeparator == ',')
+        {
+            aEdwin->SetAknEditorSpecialCharacterTable(R_MIDP_TEXTBOX_DECIMAL_MODE_WITH_COMMA_DIALOG);
+        }
+        else
+        {
+            aEdwin->SetAknEditorSpecialCharacterTable(R_MIDP_TEXTBOX_DECIMAL_MODE_DIALOG);
+        }
+        break;
+    case MMIDTextField::EPhoneNumber:
+        aEdwin->SetAknEditorAllowedInputModes(EAknEditorNumericInputMode);
+        aEdwin->SetAknEditorInputMode(EAknEditorNumericInputMode);
+        aEdwin->SetAknEditorCurrentInputMode(EAknEditorNumericInputMode);
+        aEdwin->SetAknEditorFlags(EAknEditorFlagFixedCase | EAknEditorFlagNoT9 |
+                                  EAknEditorFlagDeliverVirtualKeyEventsToApplication);
+        aEdwin->SetAknEditorNumericKeymap(EAknEditorStandardNumberModeKeymap);
+        break;
+    }
+
+    // make changes take effect
+    TRAP_IGNORE(aEdwin->NotifyEditorStateObserverOfStateChangeL());
+
+}
+
+// ---------------------------------------------------------------------------
+// CMIDEdwinUtils::CropToSingleLine
+// ---------------------------------------------------------------------------
+//
+void CMIDEdwinUtils::CropToSingleLine(TDes& aText)
+{
+    DEBUG_STR("CMIDEdwinUtils::CropToSingleLine +, aText=%S", aText);
+
+    TInt index = aText.Length();
+    while (index-- > 0)
+    {
+        TChar ch((aText)[ index ]);
+        TChar::TCategory category = ch.GetCategory();
+
+        // CR or LF character
+        if (ch == 0x0D || ch == 0x0A ||
+                category == TChar::EZlCategory || category == TChar::EZpCategory)
+        {
+            aText.Delete(index, 1);
+        }
+    }
+
+    DEBUG_STR("CMIDEdwinUtils::CropToSingleLine -, aText=%S", aText);
+}
+
+// ---------------------------------------------------------------------------
+// CMIDEdwinUtils::ConvertToUnicodeBreaks
+// ---------------------------------------------------------------------------
+//
+void CMIDEdwinUtils::ConvertToUnicodeBreaks(TDes& aText)
+{
+    DEBUG_STR("CMIDEdwinUtils::ConvertToUnicodeBreaks +, aText=%S", aText);
+
+    const TInt length = aText.Length();
+    TText* ptr = const_cast < TText* >(aText.Ptr());
+    TInt index  = 0;
+
+    while (index < length)
+    {
+        if (ptr[ index ] == 0x0D || ptr[ index ] == 0x0A)
+        {
+            break;
+        }
+
+        index++;
+    }
+
+    TText prevChar    = 0;
+    TInt  finalLength = index;
+
+    while (index < length)
+    {
+        TText ch = ptr[ index ];
+
+        if (ch != 0x0D && ch != 0x0A)
+        {
+            ptr[ finalLength++ ] = ch;
+        }
+        else
+        {
+            // Do not modify valid line breaks (CRLF)
+            if (!(ch == 0x0A && prevChar == 0x0D))
+            {
+                ptr[ finalLength++ ] = CEditableText::EParagraphDelimiter;
+            }
+        }
+
+        prevChar = ch;
+        index++;
+    }
+
+    aText.SetLength(finalLength);
+
+    DEBUG_STR("CMIDEdwinUtils::ConvertToUnicodeBreaks -, aText=%S", aText);
+}
+
+/***************************************************************************
+*
+* Class CPasswordBoxGlobalText
+*
+****************************************************************************/
+
+CPasswordBoxGlobalText::CPasswordBoxGlobalText(const CParaFormatLayer* aGlobalParaLayer,
+        const CCharFormatLayer* aGlobalCharLayer,
+        CEikEdwin& aTextComponent)
+        : CGlobalText(aGlobalParaLayer,aGlobalCharLayer), iTextComponent(aTextComponent), iClearCharPos(-1)
+{}
+
+void CPasswordBoxGlobalText::ConstructL()
+{
+    CGlobalText::ConstructL(CEditableText::ESegmentedStorage,CEditableText::EDefaultTextGranularity);
+
+    iTimer = CPeriodic::NewL(CActive::EPriorityStandard);
+    iClearText = HBufC::NewL(CEditableText::EDefaultTextGranularity);
+}
+
+CPasswordBoxGlobalText::~CPasswordBoxGlobalText()
+{
+    delete iClearText;
+    delete iTimer;
+}
+
+/** */
+void CPasswordBoxGlobalText::Reset()
+{
+    if (iTimer->IsActive())
+    { //commit any previous character before deleting or else we
+        // may crash in the timer callback when trying to replace an uncommited
+        // but already deleted char
+        TRAP_IGNORE(DoTimerCallbackL(EFalse));
+    }
+    // clear local (hidden) copy
+    TPtr ptr = iClearText->Des();
+    ptr.SetLength(0);
+
+    CGlobalText::Reset();
+}
+
+/**
+ * Support for pasting in the TextBox with PASSWORD constraint. The normal insertion
+ * mechanism is not used in the paste operation, so it must be handled separately
+ * here. This is an overriden method that stores the pasted chars to the local
+ * store and puts masked chars (*) to the visible store (in super class).
+ */
+TInt CPasswordBoxGlobalText::PasteFromStoreL(const CStreamStore& aStore,const CStreamDictionary& aDictionary,TInt aPos)
+{
+    // 1. Paste clipboard text (to visible text)
+    TInt numCharsPasted = CGlobalText::PasteFromStoreL(aStore, aDictionary, aPos);
+    // 2. Insert the pasted text to the local clear text store
+    TPtrC ptr = Read(aPos, numCharsPasted);
+    SaveClearTextL(aPos, ptr);
+    // 3. Mask the visible text
+    for (int i = 0; i < numCharsPasted; i++)
+    {
+        TPtrC charToProcess = Read(aPos+i, 1);
+        TChar replaceChar   = KPasswordEchoChar;
+        if (charToProcess[0] == CEditableText::EParagraphDelimiter)
+        {
+            replaceChar = ' ';
+        }
+        CGlobalText::DeleteL(aPos+i,1);
+        CGlobalText::InsertL(aPos+i, replaceChar);
+    }
+    return numCharsPasted;
+}
+
+/** Insert a single character. First of all save the character in the clear text by
+calling SaveClearTextL(). Then if the character is a paragraph delimiter insert a space.
+Otherwise if we are in alpha mode insert the clear character and start the timer. Otherwise
+insert the asterisks. */
+void CPasswordBoxGlobalText::InsertL(TInt aPos, const TChar& aChar)
+{
+    TBuf<1> buf;
+    buf.Append(aChar);
+    SaveClearTextL(aPos, buf);
+
+    if (aChar == CEditableText::EParagraphDelimiter)
+    {
+        CGlobalText::InsertL(aPos, ' ');
+    }
+    else if (iTextComponent.AknEditorCurrentInputMode() & KInputModesRequiringFeedbackWithSingleChar)
+    {
+        if (iTimer->IsActive() && iClearCharPos != aPos)
+        { //commit any previous character in a different position
+            DoTimerCallbackL(ETrue);
+        }
+        else
+        { //or restart the timer if the char is in the same position (multi-tap looping)
+            iTimer->Cancel();
+        }
+
+        CGlobalText::InsertL(aPos, aChar);
+        if (!iRejectNextKey) //For example the Enter key will be rejected
+        {
+            iClearCharPos = aPos;
+            iTimer->Start(KPasswordCharTimeout, KPasswordCharTimeout, TCallBack(TimerCallback, this));
+        }
+        else
+        {
+            iRejectNextKey = EFalse;
+        }
+    }
+    else
+    {
+        CGlobalText::InsertL(aPos, KPasswordEchoChar);
+    }
+}
+
+/** Insert one or more characters. If inserting only one character rely
+on InsertL() accepting only one char. Otherwise, save the clear text by
+calling SaveClearTextL(). Then for every character either insert an asterisk
+or a space if the character is a space delimiter. Note: this method is
+called at start-up so it makes no sense to show a temporary clear character. */
+void CPasswordBoxGlobalText::InsertL(TInt aPos,const TDesC& aBuf)
+{
+    if (aBuf.Length() == 1)
+    {
+        CPasswordBoxGlobalText::InsertL(aPos, aBuf[0]);
+    }
+    else if (aBuf.Length() > 1 && (iTextComponent.AknEditorCurrentInputMode() & KInputModesRequiringFeedbackWithString))
+    {
+        // When writing in kanji or hiragana input mode, the characters are entered in
+        // sequences. Insert the sequence char by char so that the user will see the last
+        // character temporarily for feedback.
+        for (TInt i = 0; i < aBuf.Length(); i++)
+        {
+            InsertL(aPos + i, aBuf[i]);
+        }
+    }
+    else
+    {
+        SaveClearTextL(aPos, aBuf);
+
+        for (TInt i = 0; i < aBuf.Length(); i++)
+        {
+            if (aBuf[i] == CEditableText::EParagraphDelimiter)
+            {
+                CGlobalText::InsertL(aPos + i, ' ');
+            }
+            else
+            {
+                CGlobalText::InsertL(aPos + i, KPasswordEchoChar);
+            }
+        }
+    }
+}
+
+/** Delete one or more chars, this makes sure our clear text stays
+in sync. */
+TBool CPasswordBoxGlobalText::DeleteL(TInt aPos,TInt aLength)
+{
+    if (iTimer->IsActive())
+    { //commit any previous character before deleting or else we
+        // may crash in the timer callback when trying to replace an uncommited
+        // but already deleted char
+        DoTimerCallbackL(EFalse);
+    }
+
+    TPtr ptr = iClearText->Des();
+    ptr.Delete(aPos, aLength);
+
+    return CGlobalText::DeleteL(aPos, aLength);
+}
+
+/** This method is called by edwin when returning text to the user via
+a GetText() call. We make sure we return the clear text instead of the
+asterisks used by edwin. */
+void CPasswordBoxGlobalText::Extract(TDes& aBuf,TInt aPos) const
+{
+    aBuf.SetLength(0);
+    aBuf.Append(iClearText->Mid(aPos));
+}
+
+/** This method is called by edwin when returning text to the user via
+a GetText() call. We make sure we return the clear text instead of the
+asterisks used by edwin. */
+void CPasswordBoxGlobalText::Extract(TDes& aBuf,TInt aPos,TInt aLength) const
+{
+    aBuf.SetLength(0);
+    aBuf.Append(iClearText->Mid(aPos, aLength));
+}
+
+/** We save our clear text. We reallocate if not enough memory. */
+void CPasswordBoxGlobalText::SaveClearTextL(TInt aPos,const TDesC& aBuf)
+{
+    ASSERT(iClearText);
+    TPtr ptr = iClearText->Des();
+
+    TInt totalLength = ptr.Length() + aBuf.Length();
+    if (totalLength > ptr.MaxLength())
+    {
+        iClearText = iClearText->ReAllocL(totalLength);
+        ptr = iClearText->Des();
+    }
+
+    ptr.Insert(aPos,aBuf);
+}
+
+/** The timer callback, see DoTimerCallbackL() */
+TInt CPasswordBoxGlobalText::TimerCallback(TAny* aThis)
+{
+    CPasswordBoxGlobalText* self = STATIC_CAST(CPasswordBoxGlobalText*, aThis);
+    ASSERT(self);
+
+    TRAPD(err, self->DoTimerCallbackL(ETrue));
+    return err;
+}
+
+/** It is time to remove the temporary clear character. Do a delete at iClearCharPos and
+then insert an asterisk at this position. Then we need to notify the edwin to update its
+characters, NotifyNewFormatL(). Note: this is only needed when inserting a char from the
+special char table or when holding a key down so that a number is inserted even if in alpha
+input mode. Otherwise you do not notice the differece as edwin update its text anyway when
+commiting a fep transaction after a timeout that is just about longer than our timeout.
+*/
+void CPasswordBoxGlobalText::DoTimerCallbackL(TBool aNotifyFormat)
+{
+    iTimer->Cancel();
+
+    ASSERT(iClearCharPos != -1 && (DocumentLength() > iClearCharPos)); //udeb builds only
+    if (iClearCharPos != -1 && (DocumentLength() > iClearCharPos)) //prevent crash in urel builds
+    {
+        CGlobalText::DeleteL(iClearCharPos,1);
+        CGlobalText::InsertL(iClearCharPos, KPasswordEchoChar);
+
+        DEBUG_INT("CMIDEdwin::DoTimerCallbackL, skip NotifiyNewFormatL = %D", aNotifyFormat);
+        // NotifyNewFormat can not be called after a char deletion or when the
+        // text editor does not have a view assosiated with it. The latter happens
+        // when text is set to the field before it is shown.
+        //
+        if (aNotifyFormat && iTextComponent.TextView())
+        {
+            iTextComponent.NotifyNewFormatL();
+        }
+        iTextComponent.DrawDeferred();
+    }
+}
+
+
+/***************************************************************************
+*
+* Class CCallConfirmationDialog
+*
+****************************************************************************/
+
+CCallConfirmationDialog* CCallConfirmationDialog::NewL(const TDesC& aNumber, const TTone& aTone)
+{
+    CCallConfirmationDialog* self = new(ELeave) CCallConfirmationDialog(aTone);
+    CleanupStack::PushL(self);
+    self->ConstructL(aNumber);
+    CleanupStack::Pop(self);
+    return self;
+}
+
+CCallConfirmationDialog::CCallConfirmationDialog(const TTone aTone)
+        : CAknQueryDialog(aTone), iResources(*CCoeEnv::Static())
+{
+}
+
+CCallConfirmationDialog::~CCallConfirmationDialog()
+{
+    iResources.Close();
+}
+
+TKeyResponse CCallConfirmationDialog::OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
+{
+    if (aType == EEventKey && aKeyEvent.iCode == EKeyYes)
+    {
+        TryExitL(EKeyYes);
+        return EKeyWasConsumed;
+    }
+    else
+    {
+        return CAknDialog::OfferKeyEventL(aKeyEvent, aType);
+    }
+}
+
+TBool CCallConfirmationDialog::OkToExitL(TInt aButtonId)
+{
+    if (EKeyYes == aButtonId)
+    {
+        return ETrue;
+    }
+    else
+    {
+        TBool retValue(CAknDialog::OkToExitL(aButtonId));
+        return retValue;
+    }
+}
+
+TInt CCallConfirmationDialog::MappedCommandId(TInt aButtonId)
+{
+    switch (aButtonId)
+    {
+    case EKeyYes:
+        return EKeyYes;
+    default :
+        return CEikDialog::MappedCommandId(aButtonId);
+    }
+}
+
+void CCallConfirmationDialog::ConstructL(const TDesC& aNumber)
+{
+    HBufC* bufNumber = aNumber.AllocLC();
+    TPtr bufNumberPtr = bufNumber->Des();
+    AknTextUtils::DisplayTextLanguageSpecificNumberConversion(bufNumberPtr);
+    HBufC* prompt = StringLoader::LoadLC(R_MIDP_QUEST_CALL_NUMBER, bufNumberPtr);
+    SetPromptL(*prompt);
+    CleanupStack::PopAndDestroy(2);   // bufNumber, prompt
+}
+
+
+/**
+ * class CMIDAiwPbk2Client
+ */
+CMIDAiwPbk2Client* CMIDAiwPbk2Client::NewL(MMIDTextBox& aEdwin)
+{
+    CMIDAiwPbk2Client* self = new(ELeave) CMIDAiwPbk2Client(aEdwin);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+}
+
+void CMIDAiwPbk2Client::ConstructL()
+{
+    iServiceHandler = CAiwServiceHandler::NewL();
+
+    //attach interest
+    iServiceHandler->AttachL(R_PBK2_CONTACT_SELECTION_INTEREST);
+
+    //create contact manager with same configuration like in current phonebook
+    CPbk2StoreConfiguration* configuration = CPbk2StoreConfiguration::NewL();
+    CleanupStack::PushL(configuration);
+
+    CVPbkContactStoreUriArray* uriArray = configuration->CurrentConfigurationL();
+    CleanupStack::PushL(uriArray);
+
+    iContactManager = CVPbkContactManager::NewL(*uriArray);
+
+    CleanupStack::PopAndDestroy(uriArray);
+
+    CleanupStack::PopAndDestroy(configuration);
+}
+
+
+CMIDAiwPbk2Client::CMIDAiwPbk2Client(MMIDTextBox& aEdwin): iEdwin(aEdwin)
+{
+}
+
+CMIDAiwPbk2Client::~CMIDAiwPbk2Client()
+{
+    delete iServiceHandler;
+    delete iContactManager;
+    delete iFetchedLinks;
+}
+
+/**
+ * Entry point
+ */
+void CMIDAiwPbk2Client::FetchFromPhoneBookL(TInt aCmdId)
+{
+    iCmdId = aCmdId;
+    //open contact stores
+    iContactManager->ContactStoresL().OpenAllL(*this);
+}
+
+
+/**
+ * Open contact stores callback methods
+ */
+void CMIDAiwPbk2Client::StoreReady(MVPbkContactStore&)
+{
+}
+void CMIDAiwPbk2Client::StoreUnavailable(MVPbkContactStore& , TInt)
+{
+}
+void CMIDAiwPbk2Client::HandleStoreEventL(MVPbkContactStore& , TVPbkContactStoreEvent)
+{
+}
+
+/**
+ * Stores are sucesfully open
+ */
+void CMIDAiwPbk2Client::OpenComplete()
+{
+    TRAPD(err, OpenCompleteL());
+
+    if (err != KErrNone)
+    {
+        DEBUG_INT("CMIDAiwPbk2Client::OpenComplete - Exception. Error = %d", err);
+    }
+}
+/**
+ * Stores are sucesfully open
+ */
+void CMIDAiwPbk2Client::OpenCompleteL()
+{
+
+    CAiwGenericParamList& paramList = iServiceHandler->InParamListL();
+    //single item fetch
+    TRAPD(err,
+          paramList.AppendL(
+              TAiwGenericParam(
+                  EGenericParamContactSelectionData,
+                  TAiwVariant(TAiwSingleItemSelectionDataV1Pckg(TAiwSingleItemSelectionDataV1().
+                              SetAddressSelectType((TAiwAddressSelectType)iCmdId).
+                              SetFlags(0))))));
+
+    if (err != KErrNone)
+    {
+        DEBUG_INT("CMIDAiwPbk2Client::OpenComplete - Exception from paramList.AppendL. Error = %d", err);
+    }
+
+    //execute service with handlenotify observer
+    TRAP(err,
+         iServiceHandler->ExecuteServiceCmdL(KAiwCmdSelect, paramList,
+                                             iServiceHandler->OutParamListL(),
+                                             0, this));
+
+    if (err != KErrNone)
+    {
+        DEBUG_INT("CMIDAiwPbk2Client::OpenComplete - Exception from ExecuteServiceCmdL. Error = %d", err);
+    }
+
+}
+
+/**
+ * Retrieving of single contact suceeded
+ */
+void CMIDAiwPbk2Client::VPbkSingleContactOperationComplete(MVPbkContactOperationBase&, MVPbkStoreContact* aContact)
+{
+
+    delete iRetrieveOperation;
+    iRetrieveOperation = NULL;
+
+    MVPbkStoreContactField* field = aContact->Fields().RetrieveField(*iCurrentLink);
+
+    TPtrC text = MVPbkContactFieldTextData::Cast(field->FieldData()).Text();
+
+    TRAPD(err, iEdwin.SetTextL(text));
+    if (err != KErrNone)
+    {
+        DEBUG_INT("CMIDAiwPbk2Client::VPbkSingleContactOperationComplete - Exception from Edwin.SetTextL. Error = %d", err);
+    }
+
+    delete aContact;
+
+}
+
+/**
+ * Retrieving of single contact failed
+ */
+void CMIDAiwPbk2Client::VPbkSingleContactOperationFailed(MVPbkContactOperationBase&, TInt)
+{
+    delete iRetrieveOperation;
+    iRetrieveOperation = NULL;
+}
+
+/**
+ * AiwNotify callback
+ */
+TInt CMIDAiwPbk2Client::HandleNotifyL(TInt aCmdId, TInt aEventId,
+                                      CAiwGenericParamList& aEventParamList, const CAiwGenericParamList&)
+{
+    if (aCmdId == KAiwCmdSelect && aEventId == KAiwEventCompleted)
+    {
+        TInt index = 0 ;
+        const TAiwGenericParam* param = aEventParamList.FindFirst(index, EGenericParamContactLinkArray);
+        if (param)
+        {
+            TPtrC8 contactLinks = param->Value().AsData();
+
+            iFetchedLinks = iContactManager->CreateLinksLC(contactLinks);
+            CleanupStack::Pop();
+
+            iCurrentLink = &iFetchedLinks->At(index);
+
+            iRetrieveOperation = iContactManager->RetrieveContactL(*iCurrentLink, *this);
+
+        }
+    }
+    // other status do not interests us, just continue till eventcompleted
+    return 1;
+}
+
+
+// End of File