--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/lcdui_akn/lcdui/src/CMIDEdwin.cpp Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,1440 @@
+/*
+* Copyright (c) 2003-2006 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: Base class for TextField and TextBox
+*
+*/
+
+
+#include <eikenv.h>
+#include <eikappui.h>
+#include <coecntrl.h>
+// macros for resources
+#include <EIKCOCTL.rsg>
+
+#include <AknUtils.h>
+// usied for playing error sounds when text input
+#include <aknsoundsystem.h>
+#include <aknenv.h>
+// CAknSettingCache used for obtaining input language
+#include <AknSettingCache.h>
+#include <AknIndicatorContainer.h>
+#include <aknEditStateIndicator.h>
+
+#include <applayout.cdl.h> // LAF
+#include <aknlayoutscalable_apps.cdl.h> // LAF
+#include <aknlayoutscalable_avkon.cdl.h> // LAF
+#include <AknLayoutFont.h>
+// CAknExtendedInputCapabilities for extended input capabilities
+#include <aknextendedinputcapabilities.h>
+
+#include <lcdui.rsg>
+// Avkon dialog for info notes
+#include <aknnotewrappers.h>
+
+// for fetching contacts from phonebook
+// CPbk2StoreConfiguration for contact manager
+#include <CPbk2StoreConfiguration.h>
+// used in CMIDAiwPbk2Client::VPbkSingleContactOperationComplete to retrieving single contact
+#include <MVPbkStoreContact.h>
+// MVPbkContactLinkArray* iFetchedLinks
+#include <CVPbkContactLinkArray.h>
+// used in CMIDAiwPbk2Client::VPbkSingleContactOperationComplete
+#include <MVPbkContactFieldTextData.h>
+// used for open all contact stores
+#include <MVPbkContactStoreList.h>
+// API for iContactManager
+#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>
+// using AIWDialDataExt::KMaximumPhoneNumberLength
+#include <aiwdialdataext.h>
+
+// loading string from resource
+#include <StringLoader.h>
+
+// FEP CR
+// constants for FEP
+#include <AknFepInternalCRKeys.h>
+#include <centralrepository.h>
+
+#include <j2me/jdebug.h>
+
+#include "CMIDEdwin.h"
+#include "CMIDTextFieldItem.h"
+#include "CMIDComponentFactory.h"
+#include "CMIDUtils.h"
+#include "CMIDUIManager.h"
+
+#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);
+
+// class CMIDEdwin
+
+void CMIDEdwin::ConstructL(const TDesC& aText,TInt aMaxSize)
+{
+
+ // Set decimal separator according to the current locale.
+ // Note: decimal separators other than ',' and '.' are currently not supported
+ TLocale loc;
+ iDecimalSeparator = loc.DecimalSeparator();
+ if (iDecimalSeparator != ',')
+ {
+ iDecimalSeparator = '.';
+ }
+
+ iEdwinUtils = CMIDEdwinUtils::NewL(this, iDecimalSeparator);
+
+ // if text is invalid according to constraints, throw IllegalArgumentException,
+ // except for a PHONENUMBER which only has the invalid characters removed
+ if ((iConstraints & MMIDTextField::EConstraintMask) != MMIDTextField::EPhoneNumber
+ && !iEdwinUtils->ConstraintsValidForText(aText,iConstraints,ETrue))
+ {
+ User::Leave(KErrArgument);
+ }
+
+ iMaxSize = aMaxSize;
+ if (iDisplayable)
+ {
+ iUIManager = iDisplayable->GetUIManager();
+ SetContainerWindowL(*iDisplayable);
+ SetAknEditorFlags(EAknEditorFlagEnableScrollBars | AknEdwinFlags());
+ }
+ else
+ {
+ iUIManager = iTextFieldItem->GetUIManager();
+ // TextField does not have any displayable yet available (before Form.Append())
+ // and EikEdwin needs to have a proper container window set, otherwise it may crash in singleLineEditor mode
+ CCoeControl::SetContainerWindowL(*(iUIManager->OpenMenuHandlerL()->GetDisplayable()));
+ }
+
+ TBool singleLineEditor = (iConstraints & MMIDTextField::EPassword);
+
+ AknEditUtils::ConstructEditingL(this, // aEdwin
+ aMaxSize, // aEditingSpace
+ (singleLineEditor ? 1 : 0), // aEditingWindow
+ EAknEditorCharactersLowerCase, // aCharacterCase
+ EAknEditorAlignLeft, // aJustification
+ ETrue, // aAllowedToMoveInsertionPoint
+ ETrue, // aCursorYesNo
+ EFalse); // aOverflowYesNo
+
+ if (iConstraints & MMIDTextField::EPassword)
+ {
+ iEdwinUserFlags |= CEikEdwin::EUserSuppliedText;
+ CreatePasswordTextL();
+ }
+
+ HBufC* buf = aText.AllocLC();
+ CMIDUtils::MapJavaToETextChars(buf);
+ if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber)
+ {
+ iEdwinUtils->RemoveNonPhoneNumberChars(buf);
+ }
+ CEikEdwin::SetTextL(buf);
+ CreateTextViewL();
+ ProcessModifiers();
+ CleanupStack::PopAndDestroy(buf);
+ SetFEPModeAndCharFormat();
+ AddEdwinObserverL(this); // see HandleEdwinEventL
+ CreateNonMidletCommandsL();
+
+
+ iUIManager->OpenNaviPaneControllerL()->AddTickerObserverL(this);
+
+ // set the cursor position
+ CEikEdwin::SetCursorPosL(TextLength(), EFalse);
+
+ // Publish MIDP constraints via input capabilities of the CEikEdwin
+ // The information is needed by chinese VKB/HWR system that adjusts its behavior
+ // based on MIDP constraints (most notably by checking if the field is a PASSWORD field).
+ TCoeInputCapabilities inputCapabilities = InputCapabilities();
+ if (inputCapabilities != TCoeInputCapabilities::ENone)
+ {
+ MObjectProvider* mop = inputCapabilities.ObjectProvider();
+ if (mop)
+ {
+ CAknExtendedInputCapabilities* extendedInputCapabilities = NULL;
+ extendedInputCapabilities = mop->MopGetObject(extendedInputCapabilities);
+ if (extendedInputCapabilities)
+ {
+ extendedInputCapabilities->SetMIDPConstraints(iConstraints);
+ }
+ }
+ }
+
+ iThisMultitapKey = 0; // reset key counter
+ iLastMultitapKey = 0;
+}
+
+CMIDEdwin::CMIDEdwin(
+ TUint aConstraints, MMIDDisplayable* aDisplayable, CMIDTextFieldItem* aTextFieldItem)
+ : iDisplayable(static_cast<CMIDDisplayable*>(aDisplayable)),
+ iTextFieldItem(aTextFieldItem),
+ iConstraints(aConstraints),
+ iStateChanged(EFalse),
+ iKeyEventsPending(EFalse),
+ iInitialCurrentCase(0),
+ iInitialCurrentInputMode(0),
+ iInitialCurrentLanguage(ELangTest)
+{
+}
+
+CMIDEdwin::~CMIDEdwin()
+{
+ //phonebook fetch
+ delete iAiwPbkClient;
+ //edwin utils
+ delete iEdwinUtils;
+ if (iUIManager && iUIManager->GetNaviPaneController())
+ {
+ iUIManager->GetNaviPaneController()->RemoveTickerObserver(this);
+ }
+ RemoveNonMidletCommands();
+}
+
+void CMIDEdwin::DeleteTextL(TInt aOffset,TInt aLength)
+{
+ // get all initial values before deletion
+ TInt oldSize = Size();
+ HBufC* oldText = GetTextInHBufL();
+ CleanupStack::PushL(oldText);
+ // get cursor position before deletion
+ TInt cursorPos = CEikEdwin::CursorPos();
+
+ if (IsReadyToDraw())
+ ClearSelectionL();
+
+ TInt withoutFEPSize = Size();
+ // if size is different then FEP transaction was canceled and some letters
+ // are missing - must work with original text
+ if (withoutFEPSize != oldSize)
+ {
+ CEikEdwin::SetTextL(oldText);
+ }
+
+ //
+ // Do the deletion, then roll back if it leaves invalid text
+ //
+ iText->DeleteL(aOffset,aLength);
+ //
+ TBool valid = iEdwinUtils->ConstraintsValidForText(Read(), iConstraints, ETrue);
+ if (!valid)
+ {
+ CEikEdwin::SetTextL(oldText);
+ }
+ CleanupStack::PopAndDestroy(oldText);
+
+ HandleTextChangedL();
+ if (IsReadyToDraw())
+ SetSelectionL(aOffset,aOffset);
+
+ if (!valid)
+ {
+ User::Leave(KErrArgument);
+ }
+
+ // Handle cursor moving
+ // Cursor is in the middle of delete area
+ if ((cursorPos > aOffset) && (cursorPos < (aOffset + aLength)))
+ {
+ CEikEdwin::SetCursorPosL(aOffset, EFalse);
+ }
+ // cursor is on the right side of delete area
+ else if (cursorPos > (aOffset + aLength))
+ {
+ TInt newPosition = cursorPos - aLength;
+ if (newPosition < 0)
+ {
+ newPosition = 0;
+ }
+ CEikEdwin::SetCursorPosL(newPosition, EFalse);
+ }
+ // cursor is on the left side of delete area
+ else
+ {
+ CEikEdwin::SetCursorPosL(cursorPos, EFalse);
+ }
+}
+
+void CMIDEdwin::SetTextL(const TDesC& aText)
+{
+ // if text is invalid according to constraints, throw IllegalArgumentException,
+ // except for a PHONENUMBER which only has the invalid characters removed
+ if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber)
+ {
+ }
+ else if (!iEdwinUtils->ConstraintsValidForText(aText, iConstraints, ETrue))
+ {
+ User::Leave(KErrArgument);
+ }
+
+ HBufC* buf = iEdwinUtils->ConvertToLocalizedLC(aText, iConstraints);
+
+ if (IsNumberConversionNeeded())
+ {
+ TPtr ptr = buf->Des();
+ AknTextUtils::LanguageSpecificNumberConversion(ptr);
+ }
+
+ if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber)
+ {
+ iEdwinUtils->RemoveNonPhoneNumberChars(buf);
+ }
+ CEikEdwin::SetTextL(buf);
+ HandleTextChangedL();
+ CleanupStack::PopAndDestroy(buf);
+
+ // move cursor to end of the new text
+ CEikEdwin::SetCursorPosL(TextLength(), EFalse);
+}
+
+/** The first part of this method validates existing text + new text.
+Then it carries on with text insertion. */
+void CMIDEdwin::InsertTextL(const TDesC& aText, TInt aPosition)
+{
+ //VALIDATE EXISTING TEXT
+ HBufC* temp = NULL;
+ if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EDecimal)
+ {
+ // Convert decimal content to unlocalized form before testing validity
+ // of insertion.
+ temp = GetTextInHBufL();
+ if (temp)
+ {
+ CleanupStack::PushL(temp);
+ iEdwinUtils->ConvertFromLocalizedDecimal(temp);
+ }
+ }
+
+ if (aPosition < 0)
+ aPosition = 0;
+
+ TInt size = TextLength();
+ if (aPosition > size)
+ aPosition = size;
+
+ // if text is invalid according to constraints, throw IllegalArgumentException,
+ // except for a PHONENUMBER which only has the invalid characters removed
+ if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber)
+ {
+ }
+ else if (!iEdwinUtils->ConstraintsValidForInsertedTextL((temp ? temp->Des() : Read()), aText, aPosition, iConstraints, ETrue))
+ {
+ User::Leave(KErrArgument);
+ }
+ if (temp)
+ {
+ CleanupStack::PopAndDestroy(temp);
+ temp = NULL;
+ }
+ //
+ //TEXT INSERTION STARTS HERE
+ if (IsReadyToDraw())
+ {
+ ClearSelectionL();
+ }
+
+ temp = iEdwinUtils->ConvertToLocalizedLC(aText, iConstraints);
+
+
+ if (IsNumberConversionNeeded())
+ {
+ TPtr ptr = temp->Des();
+ AknTextUtils::LanguageSpecificNumberConversion(ptr);
+ }
+
+ if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber)
+ {
+ iEdwinUtils->RemoveNonPhoneNumberChars(temp);
+ }
+ iText->InsertL(aPosition, temp->Des());
+
+ HandleTextChangedL();
+
+ // Get the cursor position and move it forward along with inserter characters, if
+ // characters were inserted on the left side of the cursor.
+ TInt cursorPos = CEikEdwin::CursorPos();
+ TInt numberOfAddedCharacters = TextLength() - size;
+
+ if (cursorPos >= aPosition)
+ {
+ if ((cursorPos + numberOfAddedCharacters) < iMaxSize)
+ {
+ CEikEdwin::SetCursorPosL(cursorPos + numberOfAddedCharacters, EFalse);
+ }
+ }
+
+ UpdateTextCapacityIndicatorValueL();
+
+ CleanupStack::PopAndDestroy(temp);
+}
+
+/** Not used in current implementation; functionality
+ provided in CMIDEdwinControl and CMIDTextFieldItem
+ */
+void CMIDEdwin::SetConstraintsL(TUint /*aConstraints*/)
+{
+}
+
+void CMIDEdwin::SetTextWithNewConstraintsL(HBufC* aText)
+{
+ // If the current contents of the TextBox do not match the new constraints,the
+ // contents are set to empty, except for a PHONENUMBER which only has the
+ // invalid characters removed. Otherwise, set the text as given.
+ if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber)
+ {
+ iEdwinUtils->RemoveNonPhoneNumberChars(aText);
+ CEikEdwin::SetTextL(aText);
+ }
+ else if (!iEdwinUtils->ConstraintsValidForText(aText->Des(), iConstraints & MMIDTextField::EConstraintMask, ETrue))
+ {
+ CEikEdwin::SetTextL(&KNullDesC);
+ }
+ else
+ {
+ CEikEdwin::SetTextL(aText);
+ }
+ HandleTextChangedL();
+}
+
+
+TInt CMIDEdwin::SetMaxSizeL(TInt aMaxSize)
+{
+ TInt size = TextLength();
+ if (aMaxSize < size)
+ {
+ DeleteTextL(aMaxSize,size-aMaxSize);
+ }
+ iMaxSize = aMaxSize;
+ SetTextLimit(iMaxSize);
+ return iMaxSize;
+}
+
+TInt CMIDEdwin::GetMaxSize()
+{
+ return iMaxSize;
+}
+
+
+TInt CMIDEdwin::Size()
+{
+ TRAP_IGNORE(ResetNumericContentL());
+ return TextLength();
+}
+
+TInt CMIDEdwin::GetCaretPosition()
+{
+ TRAP_IGNORE(ResetNumericContentL());
+ return CursorPos();
+}
+
+/** For a NUMERIC TextBox, clear the contents if the "displayed contents" are
+ in a state that is not valid "actual contents" for the current constraints.
+*/
+void CMIDEdwin::ResetNumericContentL()
+{
+ if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::ENumeric)
+ {
+ HBufC* buf = GetTextInHBufL();
+ if (buf != NULL)
+ {
+ CleanupStack::PushL(buf);
+ if (!iEdwinUtils->ConstraintsValidForText(buf->Des(), iConstraints, ETrue))
+ {
+ (buf->Des()).SetLength(0);
+ CEikEdwin::SetTextL(buf);
+ }
+ CleanupStack::PopAndDestroy(buf);
+ }
+ }
+}
+
+HBufC* CMIDEdwin::GetTextL()
+{
+ HBufC* buf = GetTextInHBufL();
+ if (!buf)
+ {
+ buf = HBufC::NewL(0);
+ }
+ // convert decimal from localized to MIDlet-visible representation
+ if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EDecimal)
+ {
+ iEdwinUtils->ConvertFromLocalizedDecimal(buf);
+ }
+
+ if (IsNumberConversionNeeded())
+ {
+ TPtr ptr = buf->Des();
+ AknTextUtils::ConvertDigitsTo(ptr, EDigitTypeWestern);
+ }
+
+ if (!iEdwinUtils->ConstraintsValidForText(buf->Des(), iConstraints, ETrue))
+ {
+ // The "displayed contents" of the TextBox may be in a state that is
+ // not valid "actual contents" for the current constraints; in that
+ // case, return an empty string and clear the TextBox contents.
+ (buf->Des()).SetLength(0);
+ CEikEdwin::SetTextL(buf);
+ }
+ else
+ {
+ // Otherwise, return a copy of the contents where newlines etc. are
+ // mapped to their Java representations.
+ CMIDUtils::MapETextToJavaChars(buf);
+ }
+ return buf;
+}
+
+
+void CMIDEdwin::CreatePasswordTextL()
+{
+ CGlobalText* oldGText = STATIC_CAST(CGlobalText*,iText);
+ CPasswordBoxGlobalText* text=new(ELeave) CPasswordBoxGlobalText
+ (oldGText->GlobalParaFormatLayer(),oldGText->GlobalCharFormatLayer(),*this);
+ CleanupStack::PushL(text);
+ text->ConstructL();
+ CleanupStack::Pop(text);
+
+ delete iText;
+ iText = NULL;
+
+ SetDocumentContentL(*text,CEikEdwin::EUseText);
+}
+
+/**
+ * Need to recreate TextView here such that it uses the right window
+ */
+void CMIDEdwin::SetContainerWindowL(const CCoeControl& aContainer)
+{
+ SetObserver(this); //Prevent MCoeControlObserver::EEventStateChanged going to Form
+
+ CEikEdwin::SetContainerWindowL(aContainer);
+}
+
+TKeyResponse CMIDEdwin::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
+{
+ // store the key pressed last time, used for warning beeps while reaching size limit
+ if (aType == EEventKeyDown)
+ {
+ iLastMultitapKey = iThisMultitapKey;
+ iThisMultitapKey = aKeyEvent.iScanCode;
+ }
+
+ if (aType == EEventKeyDown)
+ {
+ iKeyEventsPending = ETrue;
+ }
+ else if (aType == EEventKeyUp)
+ {
+ iKeyEventsPending = EFalse;
+ }
+ //
+ // Post ItemStateChangedEvent before a command is delivered to the Form's CommandListener
+ //
+ TUint scanCode = aKeyEvent.iScanCode;
+ TBool losingFocus = EFalse;
+
+ CMIDMenuHandler* menuHandler = iUIManager->GetMenuHandler();
+ // Enter Key
+ //
+ //TextFieldItem
+ if (iTextFieldItem)
+ {
+ // QWERTY and VKB Enter Key
+ if (scanCode == EStdKeyEnter && aType == EEventKeyDown && !useEnterKey)
+ {
+ useEnterKey=true;
+ }
+ if ((scanCode == EStdKeyEnter && aType == EEventKeyUp && useEnterKey) ||
+ (aType == EEventKey && aKeyEvent.iCode == EKeyEnter))
+ //TextFieldItem with NUMERIC,DECIMAL and PHONENUMBER constraint
+ if (IsConstraintSet(MMIDTextField::ENumeric) ||
+ IsConstraintSet(MMIDTextField::EDecimal) ||
+ IsConstraintSet(MMIDTextField::ENumeric + MMIDTextField::EPassword))
+ {
+ useEnterKey=false;
+ //Activate default command
+ if (iTextFieldItem->DefaultCommand())
+ {
+ menuHandler->ProcessCommandL(
+ iTextFieldItem->CommandList()->CommandOffset() +
+ iTextFieldItem->CommandList()->FindCommandIndex(iTextFieldItem->DefaultCommand()));
+ }
+ // Show ctx menu or activate command
+ else
+ {
+ menuHandler->ShowMenuL(CMIDMenuHandler::EOkMenu);
+ if (menuHandler->MenuItemsCount() <= 1)
+ menuHandler->ProcessCommandL(iTextFieldItem->CommandList()->CommandOffset());
+ }
+
+ return EKeyWasConsumed;
+
+ }
+ else
+ {
+ //TextFieldItem with PHONENUMBER constraint
+ if (IsConstraintSet(MMIDTextField::EPhoneNumber) ||
+ IsConstraintSet(MMIDTextField::EPhoneNumber + MMIDTextField::EPassword))
+ {
+ useEnterKey = false;
+ //Activate default command
+ if (iTextFieldItem->DefaultCommand())
+ {
+ menuHandler->ProcessCommandL(
+ iTextFieldItem->CommandList()->CommandOffset() +
+ iTextFieldItem->CommandList()->FindCommandIndex(iTextFieldItem->DefaultCommand()));
+ }
+ // Show options menu or activate command
+ else
+ {
+ menuHandler->ShowMenuL(CMIDMenuHandler::EOkMenu);
+ if (menuHandler->MenuItemsCount() == 1)
+ {
+ menuHandler->ProcessCommandL(iTextFieldItem->CommandList()->CommandOffset());
+ }
+ }
+ return EKeyWasConsumed;
+ }
+ else
+ {
+ //TextFieldItem with ANY,PASSWORD constraint
+ if (iConstraints == MMIDTextField::EPassword)
+ {
+ useEnterKey=false;
+ //Activate default command
+ if (iTextFieldItem->DefaultCommand())
+ {
+ menuHandler->ProcessCommandL(
+ iTextFieldItem->CommandList()->CommandOffset() +
+ iTextFieldItem->CommandList()->FindCommandIndex(iTextFieldItem->DefaultCommand()));
+ }
+ // Show options menu or activate command
+ else
+ {
+ menuHandler->ShowMenuL(CMIDMenuHandler::EOkMenu);
+ if (menuHandler->MenuItemsCount() == 1)
+ {
+ menuHandler->ProcessCommandL(
+ iTextFieldItem->CommandList()->CommandOffset());
+ }
+ }
+ return EKeyWasConsumed;
+
+ }
+
+ }
+ }
+ if (aKeyEvent.iCode == EKeyEnter && aType == EEventKey)
+ {
+ //TextFieldItem with EMAILADDR constraint
+ if (IsConstraintSet(MMIDTextField::EMailAddr) ||
+ IsConstraintSet(MMIDTextField::EUrl))
+ {
+ //Show menu or activate command
+ if (!iTextFieldItem->DefaultCommand())
+ {
+ menuHandler->ShowMenuL(CMIDMenuHandler::EOkMenu);
+ if (menuHandler->MenuItemsCount() <= 1)
+ {
+ menuHandler->ProcessCommandL(
+ iTextFieldItem->CommandList()->CommandOffset());
+ }
+ return EKeyWasConsumed;
+ }
+
+ }
+ }
+ }
+ // End Enter Key
+ //
+
+ //
+ // keyboard menu
+ //
+ switch (scanCode)
+ {
+ case EStdKeyF1:
+ case EStdKeyMenu:
+ losingFocus=ETrue;
+ }
+ //
+ // Pause the ticker for five sec if # key received
+ if (aKeyEvent.iScanCode == EStdKeyHash && !IsReadOnly()) //0x7f
+ {
+ iUIManager->OpenNaviPaneControllerL()->PauseTickerL(TICKER_PAUSE_INTERVAL, this);
+ }
+ //
+ // Non keyboard zoom,menu,etc.
+ //
+ if (scanCode>=ESpecialKeyBase && scanCode<(ESpecialKeyBase+ESpecialKeyCount))
+ losingFocus=ETrue;
+ //
+ // CBA buttons:
+ //
+ if (scanCode>=EStdKeyDevice0 && scanCode<=EStdKeyDeviceF)
+ losingFocus=ETrue;
+ //
+ if (iTextFieldItem && losingFocus && iStateChanged)
+ {
+ iTextFieldItem->HandleControlEventL(this,MCoeControlObserver::EEventStateChanged);
+ iStateChanged=EFalse;
+ }
+
+ // ignore up and down arrows on PASSWORD TextField to avoid funny behaviour
+ // with line breaks
+ if (iDisplayable && (iConstraints & MMIDTextField::EPassword)
+ && (aKeyEvent.iCode == EKeyDownArrow || aKeyEvent.iCode == EKeyUpArrow))
+ {
+ return EKeyWasConsumed;
+ }
+
+ // when pressing the send key on a phonenumber-type box, call the number
+#ifdef RD_SCALABLE_UI_V2
+ if ((aType == EEventKey) && (scanCode == EStdKeyYes))
+#else
+ if ((aType == EEventKeyUp) && (scanCode == EStdKeyYes))
+#endif // RD_SCALABLE_UI_V2
+ {
+ if ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber)
+ {
+ CreatePhoneCallL();
+ return EKeyWasConsumed;
+ }
+ }
+
+#ifdef RD_SCALABLE_UI_V2
+ if ((aType == EEventKey) && (iConstraints & MMIDTextField::EPassword)
+#else
+ if ((aType == EEventKeyDown) && (iConstraints & MMIDTextField::EPassword)
+#endif // RD_SCALABLE_UI_V2
+ && iTextFieldItem) // type == TextField
+ {
+ static_cast<CPasswordBoxGlobalText*>(iText)->RejectNextKey(scanCode == EStdKeyEnter);
+ }
+
+#ifdef RD_SCALABLE_UI_V2
+ if (IsConstraintSet(MMIDTextField::ENumeric) && (aType == EEventKey || aType == EEventKeyUp) && !IsReadOnly() &&
+#else
+ if (IsConstraintSet(MMIDTextField::ENumeric) && (aType == EEventKeyUp) && !IsReadOnly() &&
+#endif // RD_SCALABLE_UI_V2
+ ((scanCode==EStdKeyNkpAsterisk) || (scanCode == EStdKeyMinus) || (scanCode==EStdKeyNkpMinus) || (scanCode == 0x2A) || (scanCode == 0x2D)))
+ {
+ HandleMinusCharEventL(EEventTextUpdate);
+ CEikEdwin::ReportEdwinEventL(EEventTextUpdate);
+ UpdateTextCapacityIndicatorValueL();
+ return EKeyWasConsumed;
+ }
+
+ //handling of qwerty keypad "-" or "." pressing in Decimal mode
+#ifdef RD_SCALABLE_UI_V2
+ if (IsConstraintSet(MMIDTextField::EDecimal) && (aType == EEventKey) && !IsReadOnly() &&
+#else
+ if (IsConstraintSet(MMIDTextField::EDecimal) && (aType == EEventKeyUp) && !IsReadOnly() &&
+#endif // RD_SCALABLE_UI_V2
+ ((scanCode==EStdKeyMinus) || (scanCode==EStdKeyFullStop)))
+ {
+ CPlainText* res = CEikEdwin::Text();
+ TInt textLength = CEikEdwin::TextLength();
+ if (scanCode == EStdKeyMinus)
+ {
+ res->InsertL(CEikEdwin::CursorPos(), KMinusChar);
+ }
+ else if (scanCode == EStdKeyFullStop)
+ {
+ res->InsertL(CEikEdwin::CursorPos(), KFullStopChar);
+ }
+
+ HandleTextChangedL(); // notify editor about the text changes
+ CEikEdwin::ReportEdwinEventL(EEventTextUpdate);
+ if (CEikEdwin::TextLength() < iMaxSize)
+ {
+ CEikEdwin::SetCursorPosL(CEikEdwin::CursorPos() + 1, EFalse);
+ }
+ }
+ //Error tone playing case1:
+ //Play error tone if TextBox/TextField is read-only or maximum length has been reached.
+ //Here is handling of keys 0...9 for full keyboard and itu-t, but NOT virtual keyboard.
+ if (aType == EEventKeyDown
+ && ((scanCode >= KKeyQwerty0 && scanCode <= KKeyQwerty9)
+ || scanCode == EStdKeyHash
+ || scanCode == EStdKeyNkpAsterisk
+ || scanCode == KMidpKeyNkpAsteriskHW))
+ {
+ if ((scanCode == EStdKeyNkpAsterisk || scanCode == KMidpKeyNkpAsteriskHW)
+ && !IsReadOnly() && IsConstraintSet(MMIDTextField::ENumeric))
+ {
+ //Do nothing here in case of minus char toggle
+ }
+ else if (IsReadOnly())
+ {
+ iAvkonAppUi->KeySounds()->PlaySound(EAvkonSIDErrorTone);
+ UpdateTextCapacityIndicatorValueL();
+ return EKeyWasConsumed;
+ }
+
+ // All possible sources of warning beep are separated to be easy to read
+ else if (TextLength() >= iMaxSize)
+ {
+ TInt ret = KErrNone;
+ TInt inputModeValue = AknEditorCurrentInputMode();
+ if (inputModeValue != EAknEditorTextInputMode)
+ {
+ iAvkonAppUi->KeySounds()->PlaySound(EAvkonSIDErrorTone);
+ UpdateTextCapacityIndicatorValueL();
+ return EKeyWasConsumed;
+ }
+
+ TInt aknRepositoryValue = 0;
+ CRepository* aknFepRepository = NULL;
+ TRAP(ret, aknFepRepository = CRepository::NewL(KCRUidAknFep));
+ if ((ret != KErrNone) || (!aknFepRepository))
+ {
+ // if we cannot get the repository (something is wrong), play nothing
+ UpdateTextCapacityIndicatorValueL();
+ return EKeyWasConsumed;
+ }
+ aknFepRepository->Get(KAknFepPredTxtFlag, aknRepositoryValue);
+
+ delete aknFepRepository;
+ aknFepRepository = NULL;
+
+ if (aknRepositoryValue == 1) // 1 means the predictive input is on
+ {
+ iAvkonAppUi->KeySounds()->PlaySound(EAvkonSIDErrorTone);
+ UpdateTextCapacityIndicatorValueL();
+ return EKeyWasConsumed;
+ }
+ // now only nonpredictive textinput is left
+ if (iThisMultitapKey != iLastMultitapKey) // different key tapped -> no multitap
+ {
+ iAvkonAppUi->KeySounds()->PlaySound(EAvkonSIDErrorTone);
+ UpdateTextCapacityIndicatorValueL();
+ iThisMultitapKey = 0;
+ iLastMultitapKey = 0;
+ return EKeyWasConsumed;
+ }
+ }
+ }
+
+ if (aType != EEventKey)
+ {
+ UpdateTextCapacityIndicatorValueL();
+ return EKeyWasConsumed;
+ }
+
+
+ TKeyResponse response = EKeyWasNotConsumed;
+
+ //Error tone playing case2:
+ //Play error tone if TextBox/TextField is read-only or maximum length has been reached.
+ //Here is handling of full keyboard keys(NOT 0...9) and all virtual keyboard keys.
+ //(Note: Virtual keyboard sends only EEventKey type events, not up or down events)
+ //(Note: Error tone is played when there is no text to be replaced i.e. no text has been painted)
+ if (!iEdwinUtils->IsNavigationKey(aKeyEvent) && !iEdwinUtils->IsHotKeyL(aKeyEvent, iCoeEnv) && !aKeyEvent.iCode == EKeyYes &&
+ (!iKeyEventsPending || (scanCode < KKeyQwerty0 || scanCode > KKeyQwerty9)))
+ {
+ if (IsReadOnly() || (TextLength() >= iMaxSize && aKeyEvent.iCode != EKeyBackspace))
+ {
+ //SelectionLength() > 0 if text has been selected/painted
+ if (SelectionLength() == 0)
+ {
+ iAvkonAppUi->KeySounds()->PlaySound(EAvkonSIDErrorTone);
+ }
+ response = CEikEdwin::OfferKeyEventL(aKeyEvent,aType);
+ UpdateTextCapacityIndicatorValueL();
+ return response;
+ }
+ }
+
+ TBool valid = EFalse;
+ //
+ if (iEdwinUtils->IsNavigationKey(aKeyEvent) || iEdwinUtils->IsHotKeyL(aKeyEvent, iCoeEnv))
+ {
+ HBufC* oldText = GetTextInHBufL();
+ CleanupStack::PushL(oldText);
+ TCursorSelection sel = Selection();
+ //
+ response = CEikEdwin::OfferKeyEventL(aKeyEvent,aType);
+ valid = iEdwinUtils->ConstraintsValidForText(iText?Read():TPtrC(),iConstraints,EFalse);
+ //
+ if (!valid)
+ {
+ CEikEdwin::SetTextL(oldText);
+ HandleTextChangedL();
+ SetSelectionL(sel.iCursorPos,sel.iAnchorPos);
+ response = EKeyWasConsumed;
+ }
+ //
+ CleanupStack::PopAndDestroy(oldText);
+ UpdateTextCapacityIndicatorValueL();
+ return response;
+ }
+ else
+ {
+ TBuf<1> key;
+ key.Append(TChar(aKeyEvent.iCode));
+ valid = iEdwinUtils->ConstraintsValidForInsertedTextL(iText?Read():TPtrC(), key, CursorPos(), iConstraints, EFalse);
+ if (valid)
+ {
+ if (iTextFieldItem && (aKeyEvent.iCode == EKeyEnter) &&
+ (((iConstraints & MMIDTextField::EConstraintMask) != MMIDTextField::EAny) ||
+ (iConstraints & MMIDTextField::EPassword)))
+ {//enter key for NON ANY or ANY | PASSWORD editors
+ return EKeyWasNotConsumed; //must do command triggering in this case
+ }
+
+ response = CEikEdwin::OfferKeyEventL(aKeyEvent,aType);
+ UpdateTextCapacityIndicatorValueL();
+ }
+ return response;
+ }
+}
+
+void CMIDEdwin::FocusChanged(TDrawNow aDrawNow)
+{
+ CEikEdwin::FocusChanged(aDrawNow);
+ TBool isFocused = IsFocused();
+ TInt ret = KErrNone;
+
+ // in case of TextFieldItem iDisplayable is not valid do not use it.
+ if (!iDisplayable && iTextFieldItem->Form() == NULL)
+ {
+ return;
+ }
+
+ if (!IsReadOnly())
+ {
+ if (isFocused)
+ {
+ TRAP(
+ ret,
+ iUIManager->OpenNaviPaneControllerL()->PauseTickerL(TICKER_PAUSE_INTERVAL, this));
+ }
+ else
+ {
+ TRAP(
+ ret,
+ iUIManager->OpenNaviPaneControllerL()->PauseTickerL(0, this));
+ }
+ }
+ //
+ // Post ItemStateChangedEvent if focus moves away
+ //
+ if (iTextFieldItem && !isFocused && (iStateChanged))
+ {
+ TRAP(ret,iTextFieldItem->HandleControlEventL(this,MCoeControlObserver::EEventStateChanged));
+ iStateChanged=EFalse;
+ }
+
+ // Show text input indicator is the last thing we want to do
+ TRAP(ret,UpdateTextCapacityIndicatorValueL());
+}
+
+void CMIDEdwin::HandleControlEventL(CCoeControl* /*aControl*/,TCoeEvent aEventType)
+{
+ switch (aEventType)
+ {
+ case MCoeControlObserver::EEventStateChanged:
+ iStateChanged=ETrue;
+ break;
+ default:
+ break;
+ }
+}
+
+void CMIDEdwin::ProcessModifiers()
+{
+ // set general edwin attributes according to TextBox constraints
+ SetReadOnly(iConstraints & MMIDTextField::EUneditable);
+}
+
+void CMIDEdwin::HandleMinusCharEventL(TEdwinEvent aEventType)
+{
+
+ if ((aEventType == EEventTextUpdate) && ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::ENumeric))
+ {
+ ClearSelectionL();
+ CPlainText* res = CEikEdwin::Text();
+ TBuf<1> firstChar;
+ if (CEikEdwin::TextLength() != 0)
+ {
+ res->Extract(firstChar, 0, 1);
+ }
+ TInt cursorPos = CEikEdwin::CursorPos();
+ //toggle '-' char in the first position
+ TInt pos = firstChar.Locate(TChar('-'));
+ if (pos == KErrNotFound)
+ {
+ if (CEikEdwin::TextLength() < iMaxSize)
+ {
+ res->InsertL(0, KMinusChar);
+ cursorPos++;
+ }
+ else
+ {
+ //play error sound if text limit is to be exceeded
+ iAvkonAppUi->KeySounds()->PlaySound(EAvkonSIDErrorTone);
+ }
+ }
+ else
+ {
+ TBool deletion = res->DeleteL(0,1);
+ if (cursorPos >= 1)
+ {
+ cursorPos--;
+ }
+ }
+ HandleTextChangedL(); // notify editor about the text changes
+ CEikEdwin::SetCursorPosL(cursorPos, EFalse);
+ }
+}
+
+void CMIDEdwin::HandleEdwinEventL(CEikEdwin* aEdwin, TEdwinEvent aEventType)
+{
+ if (iTextFieldItem && aEventType == MEikEdwinObserver::EEventTextUpdate)
+ {
+ // notify Java that text has changed with itemStateChanged()
+ iTextFieldItem->HandleControlEventL(aEdwin, MCoeControlObserver::EEventStateChanged);
+ }
+
+ if (aEventType == MEikEdwinObserver::EEventTextUpdate)
+ {
+ // handles clearing multitap counter
+ if ((iLastMultitapKey != 0) && (iLastMultitapKey != iThisMultitapKey))
+ {
+ iLastMultitapKey = 0;
+ }
+ else
+ {
+ iThisMultitapKey = 0;
+ iLastMultitapKey = 0;
+ }
+
+ TBool textChanged = EFalse;
+
+ // in DECIMAL mode, don't allow changes that would result
+ // in an illegal string;
+ // 1) if there is a minus, it must be the first character
+ // 2) there can be at most one decimal separator
+ if ((iConstraints &
+ MMIDTextField::EConstraintMask) == MMIDTextField::EDecimal)
+ {
+ HBufC* res = NULL;
+ TRAPD(err, { res = GetTextInHBufL();});
+ if (err != KErrNone || !res)
+ {
+ return;
+ }
+ CleanupStack::PushL(res);
+
+ TInt illegalCharPos = -1;
+ TPtr16 ptr = res->Des();
+ TInt minusPos = ptr.LocateReverse(TChar('-'));
+
+ // check if minus sign is inserted on incorrect place
+ // (not at the beginning)
+ if ((minusPos != KErrNotFound) && (minusPos != 0))
+ {
+ // check if minus sign isn't inserted twice
+ if (minusPos != ptr.Locate(TChar('-')))
+ {
+ illegalCharPos = minusPos;
+ }
+ // insert minus char at the beginning of decimal field
+ else
+ {
+ ptr.Delete(minusPos, 1);
+ ptr.Insert(0, KMinusChar);
+ minusPos = 0;
+ CEikEdwin::SetTextL(res);
+ textChanged = ETrue;
+ }
+ }
+
+ TInt pointPosL = ptr.Locate(iDecimalSeparator);
+ TInt pointPosR = ptr.LocateReverse(iDecimalSeparator);
+ TInt cursorPos = CEikEdwin::CursorPos();
+ if ((minusPos != KErrNotFound) && (pointPosL == 0))
+ {
+ illegalCharPos = pointPosL;
+ }
+ else if (pointPosL != pointPosR)
+ {
+ illegalCharPos = pointPosR;
+ }
+
+ // if minus or dot/comma char is displayed more than once
+ if (illegalCharPos >= 0)
+ {
+ // deleting second minus or dot/comma char
+ // and set cursor position on the right place
+ ptr.Delete(illegalCharPos, 1);
+ CEikEdwin::SetTextL(res);
+ textChanged = ETrue;
+ if (cursorPos >= 1)
+ {
+ if (cursorPos == illegalCharPos)
+ {
+ cursorPos--;
+ }
+ CEikEdwin::SetCursorPosL(cursorPos, EFalse);
+ }
+ }
+ CleanupStack::Pop(res);
+ delete res;
+ }
+ else if (((iConstraints &
+ MMIDTextField::EConstraintMask) == MMIDTextField::EMailAddr)||
+ ((iConstraints &
+ MMIDTextField::EConstraintMask) == MMIDTextField::EUrl))
+ {
+ HBufC* res = NULL;
+ TRAPD(err, { res = GetTextL();});
+ if (err != KErrNone || !res)
+ {
+ return;
+ }
+ CleanupStack::PushL(res);
+
+ // In EMAIL and URL mode, don't allow changes that would result
+ // in an illegal string; if there is '/n' or '/f', and line breaks
+ // are not supported, chars need to be changed to space
+ // SetText function before actual text change checks if line
+ // breaks are not supported
+ SetTextL(*res);
+ textChanged = ETrue;
+ CleanupStack::Pop(res);
+ delete res;
+ }
+
+ // if there were any modifications the text is updated
+ if (textChanged)
+ {
+ HandleTextChangedL();
+ }
+ }
+
+
+}
+
+void CMIDEdwin::SetInitialInputModeL(const TDesC& aCharacterSubset)
+{
+ iEdwinUtils->SetInitialInputModeL(aCharacterSubset,
+ iConstraints,
+ iInitialCurrentCase,
+ iInitialCurrentInputMode,
+ iInitialCurrentLanguage);
+
+ TUint constraint = iConstraints & MMIDTextField::EConstraintMask;
+
+ // Set permitted case modes for TextBox in lowercase or uppercase mode.
+ if (aCharacterSubset.Compare(KMidpUppercaseLatin) == 0 ||
+ aCharacterSubset.Compare(KMidpLowercaseLatin) == 0)
+ {
+ //Setting permited case mode for TextField in ANY do panic
+ //when TextField loses focus.
+ if (iTextFieldItem && iConstraints == MMIDTextField::EAny)
+ {
+ return;
+ }
+ // MIDP_UPPERCASE_LATIN or MIDP_LOWERCASE_LATIN are ignored if
+ // INITIAL_CAPS_SENTENCE or INITIAL_CAPS_WORD modifier in ANY.
+ if (!(iConstraints & MMIDTextField::EInitialCapsWordSentence ||
+ iConstraints & MMIDTextField::EInitialCapsWord) ||
+ constraint != MMIDTextField::EAny)
+ {
+ // If initial input mode is uppercase or lowercase then permit
+ // only explicit case mode changes, automatic changes are not
+ // allowed.
+ SetAknEditorPermittedCaseModes(EAknEditorUpperCase |
+ EAknEditorLowerCase);
+ }
+ }
+ else
+ {
+ SetAknEditorPermittedCaseModes(EAknEditorAllCaseModes);
+ }
+
+}
+
+
+TBool CMIDEdwin::IsNumberConversionNeeded()
+{
+ return iEdwinUtils->IsNumberConversionNeeded(GetConstraints());
+}
+
+void CMIDEdwin::SetFEPModeAndCharFormat()
+{
+ iEdwinUtils->SetFEPModeAndCharFormat(iConstraints, this);
+}
+
+/** Create non-midlet commands according to the constraints and add them
+to either the displayable or to the item. Commands will be processed in ProcessCommandL(). */
+void CMIDEdwin::CreateNonMidletCommandsL()
+{
+ RPointerArray<MMIDCommand> array;
+ CleanupClosePushL(array);
+
+ if (((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber) && !(iConstraints & MMIDTextField::EUneditable))
+ {
+ AddCommandToArrayL(array, R_MIDP_PB_FETCH_NUMBER_SHORT_COMMAND_TEXT, R_MIDP_PB_FETCH_NUMBER_COMMAND_TEXT, CMIDEdwinUtils::EMenuCommandFetchPhoneNumber);
+ AddCommandToArrayL(array, R_MIDP_CREATE_CALL_SHORT_COMMAND_TEXT, R_MIDP_CREATE_CALL_COMMAND_TEXT, CMIDEdwinUtils::EMenuCommandCreatePhoneCall);
+ }
+
+ if (((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EPhoneNumber) && (iConstraints & MMIDTextField::EUneditable))
+ {
+ AddCommandToArrayL(array, R_MIDP_CREATE_CALL_SHORT_COMMAND_TEXT, R_MIDP_CREATE_CALL_COMMAND_TEXT, CMIDEdwinUtils::EMenuCommandCreatePhoneCall);
+ }
+
+ if (((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EMailAddr) && !(iConstraints & MMIDTextField::EUneditable))
+ {
+ AddCommandToArrayL(array, R_MIDP_PB_FETCH_EMAIL_SHORT_COMMAND_TEXT, R_MIDP_PB_FETCH_EMAIL_COMMAND_TEXT, CMIDEdwinUtils::EMenuCommandFetchEmailAddress);
+ }
+ AddCommandsToEdwinL(array);
+
+ CleanupStack::PopAndDestroy(&array);
+}
+
+/**
+Creates and adds new command to array based on shot & long label resource ids
+and other parameters.
+*/
+void CMIDEdwin::AddCommandToArrayL(RPointerArray<MMIDCommand>& aArray,
+ TInt aCommandResIdShort, TInt aCommandResIdLong, TInt aCommandId)
+{
+ TBuf<64> shortLabel;
+ iEikonEnv->ReadResourceL(shortLabel, aCommandResIdShort);
+ TBuf<64> longLabel;
+ iEikonEnv->ReadResourceL(longLabel, aCommandResIdLong);
+
+
+ MMIDCommand* cmd = CMIDCommand::NewL(shortLabel, longLabel, MMIDCommand::EItem, 0, aCommandId);
+ CleanupStack::PushL(cmd);
+
+ STATIC_CAST(CMIDCommand*,cmd)->SetObserver(this);
+
+ aArray.AppendL(cmd);
+ CleanupStack::Pop(cmd);
+}
+
+/**
+Creates and adds new command to array, short label is the same as long label.
+*/
+void CMIDEdwin::AddCommandToArrayL(RPointerArray<MMIDCommand>& aArray,
+ TInt aCommandResId, TInt aCommandId)
+{
+ AddCommandToArrayL(aArray, aCommandResId, aCommandResId, aCommandId);
+}
+
+/** This method is called from the destructor and removes
+ the commands added by CreateNonMidletCommandsL(). To do
+ this we examine cmds on the list (either of the displayable
+ or the item as applicable) and remove those whose observer is us.
+ */
+void CMIDEdwin::RemoveNonMidletCommands()
+{
+ CMIDCommandList* list = NULL;
+ if (iDisplayable)
+ {
+ list = STATIC_CAST(CMIDDisplayable*, iDisplayable)->MainCommandList();
+ }
+ else if (iTextFieldItem)
+ {
+ list = STATIC_CAST(CMIDTextFieldItem*, iTextFieldItem)->CommandList();
+ }
+
+ if (!list)
+ {
+ return;
+ }
+
+ for (TInt i = 0; i < list->Count(); i++)
+ {
+ CMIDCommand* cmd = list->At(i).iCommand;
+ if (cmd && (cmd->Observer() == this))
+ {
+ list->Remove(cmd);
+ cmd->Dispose();
+ i--;
+ }
+ }
+}
+
+/** Process non-midlet commands according to their unique negative id. See
+MMIDCommandObserver, FetchFromPhoneBoolL() and CreateNonMidletCommandsL(). */
+TBool CMIDEdwin::ProcessCommandL(CMIDCommand* aCommand)
+{
+ ASSERT(aCommand);
+ TBool ret = EFalse;
+
+ switch (aCommand->Id())
+ {
+ case CMIDEdwinUtils::EMenuCommandFetchPhoneNumber:
+ // for fetching data from phonebook
+ if (!iAiwPbkClient)
+ {
+ iAiwPbkClient = CMIDAiwPbk2Client::NewL(*this);
+ }
+ iAiwPbkClient->FetchFromPhoneBookL(EAiwPhoneNumberSelect);
+ ret = ETrue;
+ break;
+ case CMIDEdwinUtils::EMenuCommandFetchEmailAddress:
+ // for fetching data from phonebook
+ if (!iAiwPbkClient)
+ {
+ iAiwPbkClient = CMIDAiwPbk2Client::NewL(*this);
+ }
+ iAiwPbkClient->FetchFromPhoneBookL(EAiwEMailSelect);
+ ret = ETrue;
+ break;
+ case CMIDEdwinUtils::EMenuCommandCreatePhoneCall:
+ CreatePhoneCallL();
+ ret = ETrue;
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+void CMIDEdwin::CreatePhoneCallL()
+{
+ iEdwinUtils->CreatePhoneCallL(TextLength(), CCoeEnv::Static()->WsSession(), this);
+}
+
+/** From MTickerObserver: If the ticker is showing disable the displaying of
+edit indicators in the navi pane. **/
+void CMIDEdwin::TickerShowing(TBool aShowing)
+{
+ TInt flags = aShowing ? EAknEditorFlagNoEditIndicators | AknEdwinFlags() :
+ ~EAknEditorFlagNoEditIndicators & AknEdwinFlags();
+
+ SetAknEditorFlags(flags);
+}
+
+void CMIDEdwin::HandleCurrentL(TBool aActivate)
+{
+ // when becoming the current Displayable, set editor input mode
+ // to the one set by SetInitialInputModeL
+ if (aActivate &&
+ ((iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EAny ||
+ (iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EMailAddr ||
+ (iConstraints & MMIDTextField::EConstraintMask) == MMIDTextField::EUrl))
+ {
+ if (iInitialCurrentLanguage)
+ {
+ SetAknEditorLocalLanguage(iInitialCurrentLanguage);
+ if (iInitialCurrentInputMode == 0)
+ {
+ // clears any number mode used previously
+ SetAknEditorCurrentInputMode(EAknEditorNullInputMode);
+ }
+ }
+
+ if (iInitialCurrentInputMode)
+ {
+ SetAknEditorCurrentInputMode(iInitialCurrentInputMode);
+ }
+
+ if (iInitialCurrentCase)
+ {
+ TInt initialCurrentCase = iInitialCurrentCase;
+ if ((iConstraints & MMIDTextField::EPassword ||
+ iConstraints & MMIDTextField::EMailAddr ||
+ iConstraints & MMIDTextField::EUrl) &&
+ iInitialCurrentCase == EAknEditorTextCase)
+ {
+ // Text case is not used in passwords, emailaddrs and urls
+ initialCurrentCase = EAknEditorLowerCase;
+ }
+ SetAknEditorCurrentCase(initialCurrentCase);
+ SetAknEditorCase(initialCurrentCase);
+ }
+ }
+ if (aActivate)
+ {
+ UpdateTextCapacityIndicatorValueL();
+ }
+}
+
+/** Update the text capacity indicator if we have focus and are not read only.*/
+void CMIDEdwin::UpdateTextCapacityIndicatorValueL()
+{
+ TBool isActive = iDisplayable ? iDisplayable->IsActive() :
+ (iTextFieldItem->Form() ? iTextFieldItem->Form()->CurrentDisplayable().IsActive() : EFalse);
+
+ if (IsFocused() && isActive && !(iConstraints & MMIDTextField::EUneditable))
+ {
+ // Navi pane controller is opened on constructor phase so it should exists
+ iUIManager->OpenNaviPaneControllerL()->UpdateTextInputIndicatorL(
+ iMaxSize - TextLength());
+ iDisplayingCapacityIndic = ETrue;
+ }
+ else if (iDisplayingCapacityIndic)
+ {
+ // Navi pane controller is opened on constructor phase so it should exists
+ iUIManager->OpenNaviPaneControllerL()->UpdateTextInputIndicatorL(-1);
+ iDisplayingCapacityIndic = EFalse;
+ }
+}
+
+/** Updates capacity indicator when text is pasted. */
+void CMIDEdwin::HandleTextPastedL(TInt aStartPos,TInt& aLength)
+{
+ // When TextBox field is NUMERIC, PHONENUMBER or DECIMAL new line
+ // characters if exists in copied text must be filtered out before pasting
+
+ if ((IsConstraintSet(MMIDTextField::ENumeric) ||
+ IsConstraintSet(MMIDTextField::EPhoneNumber) ||
+ IsConstraintSet(MMIDTextField::EDecimal)) != EFalse)
+ {
+ HBufC* hbuf = GetTextInHBufL();
+ TPtr strPtr = hbuf->Des();
+ TInt firstPos = strPtr.Find(KLineSeparator);
+
+ if (firstPos != KErrNotFound)
+ {
+ CleanupStack::PushL(hbuf);
+ while (firstPos != KErrNotFound)
+ {
+ strPtr.Delete(firstPos, KLineSeparator().Length());
+ firstPos = strPtr.Find(KLineSeparator);
+ }
+ CEikEdwin::SetTextL(hbuf);
+ CleanupStack::Pop(hbuf);
+ }
+ delete hbuf;
+ }
+ UpdateTextCapacityIndicatorValueL();
+ CEikEdwin::HandleTextPastedL(aStartPos, aLength);
+}
+
+TPtrC CMIDEdwin::Read() const
+{
+ if (iConstraints & MMIDTextField::EPassword)
+ {
+ return static_cast<CPasswordBoxGlobalText*>(iText)->ClearText();
+ }
+ else
+ {
+ return iText->Read(0,TextLength());
+ }
+}