--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/javauis/lcdui_akn/lcdui/src/CMIDTextEditorEdwin.cpp Tue Apr 27 16:30:29 2010 +0300
@@ -0,0 +1,1526 @@
+/*
+* Copyright (c) 2009 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:
+*
+* Defines a custom editor window for Text editor component.
+*
+*/
+
+
+// INTERNAL INCLUDES
+#include "CMIDTextEditorEdwin.h"
+#include "CMIDEdwinUtils.h"
+#include "CMIDTextEditorEdwinCustomDraw.h"
+#include "CMIDEditingStateIndicator.h"
+
+// EXTERNAL INCLUDES
+#include <MMIDTextEditor.h> // MMIDTextEditorObserver
+#include <aknextendedinputcapabilities.h>
+#include <AknSettingCache.h>
+#include <eikedwob.h>
+#include <j2me/jdebug.h>
+
+const TInt KColorOpaque = 255;
+const TInt KCharMinus = 0x2d;
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::CMIDTextEditorEdwin
+// ---------------------------------------------------------------------------
+//
+CMIDTextEditorEdwin::CMIDTextEditorEdwin(CMIDEdwinUtils& aEdwinUtils)
+ : CEikEdwin(),
+ iMultiline(EFalse),
+ iCursorPosForAction(KErrNotFound),
+ iEdwinUtils(aEdwinUtils)
+{
+ DEBUG("CMIDTextEditorEdwin::CMIDTextEditorEdwin +");
+
+ // Set margins to zero
+ TMargins8 margins;
+ margins.SetAllValuesTo(0);
+ SetBorderViewMargins(margins);
+ // Set layout
+ CAknEnv::Static()->GetCurrentLayoutId(iDirection);
+ // Set visible content height
+ iVisibleContentHeight = 0;
+ // Set border to zero
+ SetBorder(TGulBorder::ENone);
+ SetFocusing(ETrue);
+ DEBUG("CMIDTextEditorEdwin::CMIDTextEditorEdwin -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::~CMIDTextEditorEdwin
+// ---------------------------------------------------------------------------
+//
+CMIDTextEditorEdwin::~CMIDTextEditorEdwin()
+{
+ DEBUG("CMIDTextEditorEdwin::~CMIDTextEditorEdwin");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::ConstructL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::ConstructL(
+ TInt aEdwinFlags,
+ TInt aWidthInChars,
+ TInt aTextLimit,
+ TInt aNumberOfLines)
+{
+ DEBUG("CMIDTextEditorEdwin::ConstructL +");
+
+ CEikEdwin::ConstructL(
+ aEdwinFlags, aWidthInChars, aTextLimit, aNumberOfLines);
+
+ // Supress all background drawing of CEikEdwin so that this editor
+ // can draw the correct custom color to the background.
+ SetSuppressBackgroundDrawing(ETrue);
+
+ // No background control context. This way it is possible to change the
+ // background color of the text editor. By default, it is white.
+ SetSkinBackgroundControlContextL(NULL);
+
+ // Observer events in the editor. Note that this must be done in order
+ // to avoid resulting incorrect content in numeric and decimal editors
+ SetEdwinObserver(this);
+
+ // To have the line where cursor is properly displayed.
+ if (iLayout)
+ {
+ iLayout->RestrictScrollToTopsOfLines(EFalse);
+ }
+
+ DEBUG("CMIDTextEditorEdwin::ConstructL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::OfferKeyEventL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TKeyResponse CMIDTextEditorEdwin::OfferKeyEventL(
+ const TKeyEvent& aKeyEvent,
+ TEventCode aType)
+{
+ DEBUG_INT("CMIDTextEditorEdwin::OfferKeyEventL +, aType=%d", aType);
+
+ TKeyResponse response = EKeyWasNotConsumed;
+
+ if ((aType == EEventKey) &&
+ (aKeyEvent.iCode == EKeyEnter) &&
+ (!iMultiline ||
+ iConstraints & MMIDTextField::EPassword ||
+ !IsConstraintSet(MMIDTextField::EAny)))
+ {
+ // Enter key for single-line editor, password and other than any
+ // editors is simply passed on.
+ DEBUG("CMIDTextEditorEdwin::OfferKeyEventL -, ignoring enter");
+
+ return response;
+ }
+
+ // Offer key event to editor window if it is set focused and visible.
+ // If the editor is set hidden, OfferKeyEventL will update the content
+ // in the editor and draw it. So the editor content CANNOT be modified
+ // if it is not visible and focused.
+ if (IsFocused() && IsVisible())
+ {
+ DEBUG("CMIDTextEditorEdwin::OfferKeyEventL, focused=true");
+
+ // Edwin does not report cursor movements with text updates
+ // Store the current position here for future use.
+ iCursorPosForAction = CursorPos();
+
+ // Try handling special characters.
+ response = HandleSpecialKeyEventsL(aKeyEvent, aType);
+
+ // Not handled, try with CEikEdwin
+ if (response == EKeyWasNotConsumed)
+ {
+ // Old text is needed if the new content is not valid for the
+ // given set of constraints. This validation is made because
+ // CEikEdwin and FEP seem to input text that is not always
+ // valid for the given Java-specific constraints. No very
+ // optimized solution to allocate heap here but at least this
+ // solution is bulletproof and prevents illegal contents.
+ // This also prevents that the implementation does not ignore
+ // special characters such as navigation and hotkeys.
+ HBufC* oldContent = GetTextInHBufL();
+
+ CleanupStack::PushL(oldContent);
+
+ response = CEikEdwin::OfferKeyEventL(aKeyEvent, aType);
+
+ // Validate new content and undo if not valid.
+ if (!iEdwinUtils.ConstraintsValidForText(
+ Read(), iConstraints, EFalse))
+ {
+ CEikEdwin::SetTextL(oldContent);
+ // Notify about text change.
+ HandleTextChangedL();
+ // Restore cursor's original position.
+ SetCursorPosL(iCursorPosForAction, EFalse);
+ }
+
+ CleanupStack::PopAndDestroy(oldContent);
+ }
+
+ // Update current selection.
+ iSelection = Selection();
+
+ // Draw now so that background gets updated. Otherwise the
+ // content may not be updated (e.g. cursor may be visible
+ // if a line is deleted from the editor.
+ // Transparency needs whole redraw of the editor's content.
+ if (IsTransparent())
+ {
+ iParent->DrawNow(Rect());
+ }
+ else
+ {
+ DrawDeferred();
+ }
+ }
+
+ DEBUG("CMIDTextEditorEdwin::OfferKeyEventL -");
+
+ return response;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::Traverse
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TBool CMIDTextEditorEdwin::Traverse(const TKeyEvent& aEvent)
+{
+ TInt cursorPos = CursorPos();
+ TBool traverse = EFalse;
+
+ if ((aEvent.iCode == EKeyDownArrow) ||
+ (aEvent.iScanCode == EStdKeyDownArrow))
+ {
+ if (TextLength() == cursorPos)
+ {
+ traverse = ETrue;
+ }
+
+ }
+ else if ((aEvent.iCode == EKeyUpArrow) ||
+ (aEvent.iScanCode == EStdKeyUpArrow))
+ {
+ if (cursorPos == 0)
+ {
+ traverse = ETrue;
+ }
+
+ }
+
+ return traverse;
+}
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::Draw
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::Draw(const TRect& aRect) const
+{
+ DEBUG("CMIDTextEditorEdwin::Draw +");
+
+ // Part of transparency workaround. Set drawing active.
+ iDrawInvoked = ETrue;
+
+ // Background color is drawn before other content.
+ // Note that in order this to work, the background drawing of CEikEdwin
+ // needs to be suppressed. Custom drawer cannot be used due to flickering
+ // problems. Currently it just handles the selection color.
+ CWindowGc& gc = SystemGc();
+
+ // Draw background with alpha.
+ gc.SetBrushColor(iBackgroundColor);
+ gc.Clear(aRect);
+
+ // Now draw the content of the editor.
+ CEikEdwin::Draw(aRect);
+
+ // Part of transparency workaround. Set drawing not active.
+ iDrawInvoked = EFalse;
+
+ if (iObserver)
+ {
+ iObserver->NotifyInputAction(
+ MMIDTextEditorObserver::EActionPaintRequest);
+ }
+ DEBUG("CMIDTextEditorEdwin::Draw -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::DrawOngoing
+// Part of transparency workaround. Returns the current draw status
+// of this editor window.
+// ---------------------------------------------------------------------------
+//
+TBool CMIDTextEditorEdwin::DrawOngoing() const
+{
+ return iDrawInvoked;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::Redraw
+// Part of transparency workaround. Returns the current draw status
+// of this editor window.
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::Redraw() const
+{
+ // Do not redraw if draw is already ongoing.
+ if (iDrawInvoked || !iParent)
+ {
+ return;
+ }
+
+ // If the editor has a transaprent background, the parent
+ // needs to be redrawn in that case. Note that DrawNow
+ // is not applicable here because this is used from the
+ // custom draw which may invoke this method during CTextView
+ // redraw causing a panic to occur.
+ if (IsTransparent())
+ {
+ iParent->DrawDeferred();
+ }
+ else
+ {
+ // No transparency. Draw this control only.
+ DrawDeferred();
+ }
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::IsTransparent
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TBool CMIDTextEditorEdwin::IsTransparent() const
+{
+ return (iBackgroundColor.Alpha() < KColorOpaque);
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::FocusChanged
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::FocusChanged(TDrawNow aDrawNow)
+{
+ DEBUG("CMIDTextEditorEdwin::FocusChanged +");
+
+ CEikEdwin::FocusChanged(aDrawNow);
+
+ // Apply initial input mode change when the editor has been focused.
+ // Note that initial input mode change must be applied only when
+ // an editing session starts (according to MIDP specification).
+ // See CMIDEdwin::HandleCurrentL()
+
+ if (IsFocused() &&
+ (IsConstraintSet(MMIDTextField::EAny) ||
+ IsConstraintSet(MMIDTextField::EMailAddr) ||
+ IsConstraintSet(MMIDTextField::EUrl)))
+ {
+ // Set current language.
+ if (iInitialCurrentLanguage)
+ {
+ DEBUG("CMIDTextEditorEdwin::FocusChanged, \
+applying current language");
+
+ SetAknEditorLocalLanguage(iInitialCurrentLanguage);
+
+ if (iInitialCurrentInputMode == 0)
+ {
+ DEBUG("CMIDTextEditorEdwin::FocusChanged, null input mode");
+
+ // Clears any number mode used previously
+ SetAknEditorCurrentInputMode(EAknEditorNullInputMode);
+ }
+ }
+
+ // Set current input mode.
+ if (iInitialCurrentInputMode)
+ {
+ DEBUG("CMIDTextEditorEdwin::FocusChanged, \
+applying current input mode");
+
+ SetAknEditorCurrentInputMode(iInitialCurrentInputMode);
+ }
+
+ // Set current case.
+ if (iInitialCurrentCase)
+ {
+ DEBUG("CMIDTextEditorEdwin::FocusChanged, \
+applying current case");
+
+ TInt initialCurrentCase = iInitialCurrentCase;
+
+ if ((iConstraints & MMIDTextField::EPassword ||
+ IsConstraintSet(MMIDTextField::EMailAddr) ||
+ IsConstraintSet(MMIDTextField::EUrl)) &&
+ iInitialCurrentCase == EAknEditorTextCase)
+ {
+ // Text case is not used in passwords, emailaddrs and urls
+ initialCurrentCase = EAknEditorLowerCase;
+ }
+
+ SetAknEditorCurrentCase(initialCurrentCase);
+ SetAknEditorCase(initialCurrentCase);
+ }
+ }
+
+ DEBUG("CMIDTextEditorEdwin::FocusChanged -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::PositionChanged
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::PositionChanged()
+{
+ DEBUG("CMIDTextEditorEdwin::PositionChanged +");
+
+ CCoeControl::PositionChanged();
+
+ // Text view may have not been created yet.
+ if (iTextView)
+ {
+ // Adjust the view rect to the text view
+ iTextView->SetViewRect(Rect());
+ }
+
+ DEBUG("CMIDTextEditorEdwin::PositionChanged -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::PositionChanged
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::OverrideColorL(TInt aLogicalColor, TRgb aColor)
+{
+ CCoeControl::OverrideColorL(aLogicalColor, aColor);
+
+ if (aLogicalColor == EColorControlBackground)
+ {
+ iBackgroundColor = aColor;
+ }
+
+ // Suppress background drawing if the editor is transparent.
+ SetSuppressBackgroundDrawing(IsTransparent());
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::CreateCustomDrawL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+CLafEdwinCustomDrawBase* CMIDTextEditorEdwin::CreateCustomDrawL()
+{
+ DEBUG("CMIDTextEditorEdwin::CreateCustomDrawL +");
+
+ // First create the parent custom draw that handles the drawing of
+ // text and other related components.
+ const MFormCustomDraw* customDraw = CEikEdwin::CreateCustomDrawL();
+
+ // Create text editor specific custom draw that handles the
+ // setting of selection color.
+ CLafEdwinCustomDrawBase* ret = new(ELeave)CMIDTextEditorEdwinCustomDraw(
+ iEikonEnv->LafEnv(), *customDraw, *this);
+
+ DEBUG("CMIDTextEditorEdwin::CreateCustomDrawL -");
+
+ return ret;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::HandleTextPastedL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::HandleTextPastedL(TInt aStartPos, TInt& aLength)
+{
+ DEBUG_INT2(
+ "CMIDTextEditorEdwin::HandleTextPastedL +, aStartPos=%d, aLength=%d",
+ aStartPos, aLength);
+
+ HBufC* content = GetTextInHBufL(); // May return NULL
+ if (!content)
+ {
+ // For guaranteeing that this method does not crash in any case.
+ return;
+ }
+
+ CleanupStack::PushL(content);
+
+ // Check that the pasted text is valid for the given set of constraints.
+ if (!iEdwinUtils.ConstraintsValidForText(
+ content->Des(), iConstraints, ETrue))
+ {
+ DEBUG("CMIDTextEditorEdwin::HandleTextPastedL, \
+constraints not valid");
+
+ // Remove pasted content from the text and set it back.
+ iText->DeleteL(aStartPos, aLength);
+ // Notify about the change.
+ HandleTextChangedL();
+ }
+ // Convert breaks if needed if constraints that do not allow line breaks.
+ // Note that numeric, decimal and phonenumber do not allow line breaks
+ // and are checked before this so no need to check here again.
+ else if (!IsWrapEnabled() ||
+ iConstraints & MMIDTextField::EPassword ||
+ IsConstraintSet(MMIDTextField::EUrl) ||
+ IsConstraintSet(MMIDTextField::EMailAddr))
+ {
+ DEBUG("CMIDTextEditorEdwin::HandleTextPastedL, \
+cropping to single line");
+
+ TPtr ptr = content->Des();
+ iEdwinUtils.CropToSingleLine(ptr);
+ CEikEdwin::SetTextL(content);
+ // Notify about content change.
+ HandleTextChangedL();
+ }
+
+ CleanupStack::PopAndDestroy(content);
+
+ DEBUG("CMIDTextEditorEdwin::HandleTextPastedL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::HandleTextChangedL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::HandleTextChangedL()
+{
+ DEBUG("CMIDTextEditorEdwin::HandleTextChangedL +");
+
+ // Call edwin's method to format the text and redraw.
+ CEikEdwin::HandleTextChangedL();
+
+ // Report edwin event.
+ ReportEdwinEventL(MEikEdwinObserver::EEventTextUpdate);
+
+ DEBUG("CMIDTextEditorEdwin::HandleTextChangedL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::HandleResourceChangeL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::HandleResourceChange(TInt aType)
+{
+ // Notification about language change
+ if (aType == KEikInputLanguageChange)
+ {
+ if (iObserver)
+ {
+ TInt event = MMIDTextEditorObserver::EActionLanguageChange;
+ TAknLayoutId currentLayoutId;
+ CAknEnv::Static()->GetCurrentLayoutId(currentLayoutId);
+ if (iDirection != currentLayoutId)
+ {
+ iDirection = currentLayoutId;
+ event |= MMIDTextEditorObserver::EActionDirectionChange;
+ }
+ iObserver->NotifyInputAction(event);
+ }
+ }
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::HandleEdwinEventL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::HandleEdwinEventL(
+ CEikEdwin* /*aEdwin*/,
+ TEdwinEvent aEventType)
+{
+ DEBUG_INT("CMIDTextEditorEdwin::HandleEdwinEventL +, aEventType=%d",
+ aEventType);
+
+ if (aEventType == EEventTextUpdate && (
+ IsConstraintSet(MMIDTextField::EDecimal) ||
+ IsConstraintSet(MMIDTextField::ENumeric)))
+ {
+ // Do not report events if the content was invalid.
+ if (RemoveInvalidNumericContentL())
+ {
+ return;
+ }
+ }
+
+ // Notify observer if set.
+ if (iObserver)
+ {
+ switch (aEventType)
+ {
+ case EEventNavigation:
+ {
+ TInt event = MMIDTextEditorObserver::EActionCaretMove;
+ TInt newVisiblecontentHeight = VisibleContentPosition();
+
+ // Check if cursor has moved. This must be done because
+ // currently edwin does not report cursor position movement
+ // when text is changed due to user input.
+ if ((iVisibleContentHeight != newVisiblecontentHeight) &&
+ (iCursorPosForAction != CursorPos()))
+ {
+ event |= MMIDTextEditorObserver::EActionScrollbarChange;
+ // Reported, reset here to avoid multiple notifications.
+ iVisibleContentHeight = newVisiblecontentHeight;
+ }
+
+ iObserver->NotifyInputAction(event);
+ break;
+ }
+ case EEventFormatChanged: // Fallthrough
+ case EEventTextUpdate:
+ {
+ TInt event = MMIDTextEditorObserver::EActionContentChange;
+
+ // Check if cursor has moved. This must be done because
+ // currently edwin does not report cursor position movement
+ // when text is changed due to user input.
+ if (iCursorPosForAction != KErrNotFound &&
+ iCursorPosForAction != CursorPos())
+ {
+ event |= MMIDTextEditorObserver::EActionCaretMove;
+ // Reported, reset here to avoid multiple notifications.
+ iCursorPosForAction = KErrNotFound;
+ }
+
+ iObserver->NotifyInputAction(event);
+ break;
+ }
+ case EEventScroll:
+ {
+ break;
+ }
+ default:
+ {
+ // Not handled.
+ break;
+ }
+ }
+ }
+
+ DEBUG("CMIDTextEditorEdwin::HandleEdwinEventL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::HandlePointerEventL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+#ifdef RD_SCALABLE_UI_V2
+void CMIDTextEditorEdwin::HandlePointerEventL(
+ const TPointerEvent &aPointerEvent)
+{
+ DEBUG("CMIDTextEditorEdwin::HandlePointerEventL +");
+ if (AknLayoutUtils::PenEnabled())
+ {
+ CEikEdwin::HandlePointerEventL(aPointerEvent);
+ }
+ DEBUG("CMIDTextEditorEdwin::HandlePointerEventL -");
+}
+#endif // RD_SCALABLE_UI_V2
+
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::HandleSpecialKEyEventsL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TKeyResponse CMIDTextEditorEdwin::HandleSpecialKeyEventsL(
+ const TKeyEvent& aKeyEvent,
+ TEventCode aType)
+{
+ DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL +");
+
+ TKeyResponse response = EKeyWasNotConsumed;
+
+ // Do not handle anything if text's maximum lenght has been reached
+ // or if the editor is set to read only state.
+ if (TextLength() >= MaxLength() || IsReadOnly())
+ {
+ DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL -, \
+max size reached");
+
+ return response;
+ }
+
+ TUint sc = aKeyEvent.iScanCode;
+
+ DEBUG_INT2("CMIDTextEditorEdwin::HandleSpecialKeyEventsL, \
+scanCode=0x%x, iConstraints=0x%x", sc, iConstraints);
+
+ TBool dec = IsConstraintSet(MMIDTextField::EDecimal);
+ TBool num = IsConstraintSet(MMIDTextField::ENumeric);
+
+ // Try to handle minus and full stop characters separately.
+ // Other than EEventKey events are ignored.
+
+ if ((dec || num) &&
+ (aType == EEventKey) &&
+ (sc == EStdKeyMinus || sc == EStdKeyNkpMinus ||
+ sc == EStdKeyFullStop || sc == EStdKeyNkpFullStop ||
+ sc == EStdKeyNkpAsterisk || sc == KMidpKeyNkpAsteriskHW))
+ {
+ DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL, \
+handling special");
+
+ TInt cursorPos = CursorPos();
+ TPtrC content = Read();
+
+ // Toggle minus character. Decimal editor uses SCT so do not toggle
+ // from asterisk key in that case.
+ if ((sc == EStdKeyMinus || sc == EStdKeyNkpMinus) ||
+ ((sc == EStdKeyNkpAsterisk || sc == KMidpKeyNkpAsteriskHW)
+ && num))
+ {
+ DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL, \
+toggle minus");
+
+ if (content.Find(KMinusChar) == KErrNotFound)
+ {
+ iText->InsertL(0, KMinusChar);
+ cursorPos++;
+ }
+ else
+ {
+ iText->DeleteL(0, 1);
+ cursorPos--;
+ }
+
+ HandleTextChangedL();
+ ReportEdwinEventL(MEikEdwinObserver::EEventTextUpdate);
+ SetCursorPosL(cursorPos, EFalse);
+
+ response = EKeyWasConsumed;
+ }
+ else if (dec && (sc == EStdKeyFullStop ||
+ sc == EStdKeyNkpFullStop))
+ {
+ TLocale locale;
+ TChar decimalSeparator(locale.DecimalSeparator());
+
+ if (content.Locate(decimalSeparator) == KErrNotFound)
+ {
+ DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL, \
+inserting full stop");
+
+ // Insert full stop sign into to cursor's current position.
+ iText->InsertL(cursorPos, decimalSeparator);
+ HandleTextChangedL();
+ ReportEdwinEventL(MEikEdwinObserver::EEventTextUpdate);
+ SetCursorPosL(cursorPos + 1, EFalse);
+
+ response = EKeyWasConsumed;
+ }
+ }
+ }
+
+ DEBUG_INT("CMIDTextEditorEdwin::HandleSpecialKeyEventsL - response=%d",
+ response);
+
+ return response;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetTopParent
+// (other items are commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetTopParent(CCoeControl* aControl)
+{
+ iParent = aControl;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetObserver
+// (other items are commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetObserver(MMIDTextEditorObserver* aObserver)
+{
+ DEBUG("CMIDTextEditorEdwin::SetObserver +");
+
+ iObserver = aObserver;
+
+ DEBUG("CMIDTextEditorEdwin::SetObserver -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetEditingStateIndicator
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetEditingStateIndicator(
+ CMIDEditingStateIndicator* aIndicator)
+{
+ DEBUG("CMIDTextEditorEdwin::SetEditingStateIndicator +");
+
+ // Indicator can be set to NULL.
+ iIndicator = aIndicator;
+
+ DEBUG("CMIDTextEditorEdwin::SetEditingStateIndicator -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetConstraintsL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetConstraintsL(TUint aConstraints)
+{
+ DEBUG("CMIDTextEditorEdwin::SetConstraintsL +");
+
+ // Note that this method cannot be 100% leave-safe due to the current
+ // CEikEdwin implementation.
+
+ __ASSERT_DEBUG(iText, User::Invariant());
+
+ // Apply document content.
+ CGlobalText* newText = NULL;
+ CGlobalText* oldText = static_cast< CGlobalText* >(iText);
+
+ const CParaFormatLayer* paraFormatLayer =
+ oldText->GlobalParaFormatLayer();
+
+ const CCharFormatLayer* charFormatLayer =
+ oldText->GlobalCharFormatLayer();
+
+ TBool enableCcpuSupport = ETrue;
+
+ // Create password text if mode is password (non-restrictive).
+ if (aConstraints & MMIDTextField::EPassword)
+ {
+ DEBUG(
+ "CMIDTextEditorEdwin::SetConstraintsL, creating password text");
+
+ // Password editors must not use CCPU support according to
+ // S60 Editing specification.
+ enableCcpuSupport = EFalse;
+
+ CPasswordBoxGlobalText* text = new(ELeave)CPasswordBoxGlobalText(
+ paraFormatLayer, charFormatLayer, *this);
+
+ CleanupStack::PushL(text);
+ text->ConstructL();
+ CleanupStack::Pop(text);
+
+ newText = text;
+ }
+ else // Default, no password.
+ {
+ // Use default global text in the editor.
+ newText = CGlobalText::NewL(paraFormatLayer, charFormatLayer);
+ }
+
+ CleanupStack::PushL(newText);
+ SetDocumentContentL(newText);
+
+ // Disable or enable CCPU support here.
+ EnableCcpuSupportL(enableCcpuSupport);
+
+ // Store constraints here. Rest of the method is leave-safe
+ // and RestoreDefaultInputState uses the capabilities.
+ iConstraints = aConstraints;
+
+ // Restore default input state before making any modifications. This
+ // ensures that the next input constraints are set correctly and
+ // that the previous constraints do not affect on the new input modes.
+ // This should be done in CMIDEdwinUtils::SetFEPModeAndCharFormat()
+ // but it does not reset all the necessary input parameters.
+ RestoreDefaultInputState();
+
+ // Set uneditable if set as current mode.
+ SetReadOnly(aConstraints & MMIDTextField::EUneditable);
+
+ // Use edwin utils to set the FEP mode and character format.
+ iEdwinUtils.SetFEPModeAndCharFormat(aConstraints, this);
+
+ // Publish MIDP constraints via input capabilities of CEikEdwin.
+ CAknExtendedInputCapabilities* caps = AknInputCaps();
+ if (caps)
+ {
+ DEBUG(
+ "CMIDTextEditorEdwin::SetConstraintsL, setting MIDP constaints");
+
+ caps->SetMIDPConstraints(aConstraints);
+ }
+
+ // CMIDEdwinUtils modify the multiline state of the editor
+ // thus it needs the be set again here. Passwords are always
+ // single line editors.
+ if (!(aConstraints & MMIDTextField::EPassword))
+ {
+ SetWordWrapL(iMultiline);
+ }
+ else
+ {
+ SetWordWrapL(EFalse);
+ }
+ CleanupStack::Pop(newText);
+
+ DEBUG("CMIDTextEditorEdwin::SetConstraintsL +");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetInitialInputModeL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetInitialInputModeL(
+ const TDesC& aCharacterSubset)
+{
+ DEBUG_STR(
+ "CMIDTextEditorEdwin::SetInitialInputModeL +, aCharacterSubset=%S",
+ aCharacterSubset);
+
+ // Set initial input mode. Note that the change is performed
+ // after the next editing session starts. See MIDP specification.
+ // See CMIDEdwin::SetInitialInputModeL
+
+ iEdwinUtils.SetInitialInputModeL(
+ aCharacterSubset,
+ iConstraints,
+ iInitialCurrentCase,
+ iInitialCurrentInputMode,
+ iInitialCurrentLanguage);
+
+ // Set permitted case modes for edwin in lowercase or uppercase mode.
+ if (aCharacterSubset.Compare(KMidpUppercaseLatin) == 0 ||
+ aCharacterSubset.Compare(KMidpLowercaseLatin) == 0)
+ {
+ DEBUG("CMIDTextEditorEdwin::SetInitialInputModeL, latin");
+
+ // 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) ||
+ !IsConstraintSet(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);
+ }
+
+ DEBUG("CMIDTextEditorEdwin::SetInitialInputModeL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::RestoreDefaultInputState
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::RestoreDefaultInputState()
+{
+ DEBUG("CMIDTextEditorEdwin::RestoreEdwinDefaultInputState +");
+
+ // Restore the default input state. It is not possible to directly
+ // call CAknEditorState object from CEikEdwin since it is currently
+ // used internally only. The default state set here is the same
+ // that is set when CAknEditorState is constructed. See
+ // CAknEditorState::CAknEditorState in aknedsts.cpp for details.
+
+ SetAknEditorCase(EAknEditorTextCase);
+ SetAknEditorPermittedCaseModes(EAknEditorAllCaseModes);
+ SetAknEditorFlags(EAknEditorFlagDefault);
+ SetAknEditorSpecialCharacterTable(KErrNotFound);
+ SetAknEditorInputMode(EAknEditorTextInputMode);
+ SetAknEditorAllowedInputModes(EAknEditorAllInputModes);
+ SetAknEditorCurrentInputMode(EAknEditorTextInputMode);
+ SetAknEditorCurrentCase(EAknEditorTextCase);
+ SetAknEditorNumericKeymap(EAknEditorAlphanumericNumberModeKeymap);
+ SetAknEditorLocalLanguage(
+ CAknEnv::Static()->SettingCache().InputLanguage());
+
+ // Enable SCT in other than numeric editors. Note that asterisk toggles
+ // the minus character so the SCT must not be enabled because of that.
+ if (!IsConstraintSet(MMIDTextField::ENumeric))
+ {
+ CAknExtendedInputCapabilities* caps = AknInputCaps();
+ if (caps)
+ {
+ DEBUG("CMIDTextEditorEdwin::RestoreEdwinDefaultInputState,\
+ disable SCT");
+
+ caps->SetCapabilities(
+ caps->Capabilities() &
+ ~CAknExtendedInputCapabilities::EDisableSCT);
+ }
+ }
+
+ // Reset initial input mode also.
+ iInitialCurrentCase = 0;
+ iInitialCurrentInputMode = 0;
+ iInitialCurrentLanguage = ELangTest;
+
+ DEBUG("CMIDTextEditorEdwin::RestoreEdwinDefaultInputState -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetCursorPosL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetCursorPosL(
+ TInt aCursorPosition,
+ TBool aSelect)
+{
+ DEBUG_INT("CMIDTextEditorEdwin::SetCursorPosL +, aCursorPosition=%d",
+ aCursorPosition);
+
+ // Set cursor if the editor has a valid parent.
+ if (IsInitialized())
+ {
+ CEikEdwin::SetCursorPosL(aCursorPosition, aSelect);
+ }
+ // Do not deliver event if the position actually does not change.
+ else if (CursorPos() != aCursorPosition)
+ {
+ // Event has to be delivered to the registered observer
+ // even if the editor window has not been initialized.
+ ReportEdwinEventL(MEikEdwinObserver::EEventNavigation);
+ }
+
+ if (aSelect)
+ {
+ // CEikEdwin does not store selection if not initialized.
+ // Store it in order to avoid errors when setting selection
+ // before parent is stored.
+ iSelection.SetSelection(iCursorPosition, aCursorPosition);
+ }
+ else // Clear selection.
+ {
+ iSelection.SetSelection(0, 0);
+ }
+
+ // Editor window does not know the position yet because it has not
+ // been activated. Store the position to a member variable. Note that
+ // this must be set when the editor is activated.
+ // Cursor needs to be stored all the time because change of the
+ // parent object may cause the cursor to be changed in CEikEdwin.
+ iCursorPosition = aCursorPosition;
+
+ DEBUG("CMIDTextEditorEdwin::SetCursorPosL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::CursorPos
+// (other items are commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TInt CMIDTextEditorEdwin::CursorPos() const
+{
+ DEBUG("CMIDTextEditorEdwin::CursorPos +");
+
+ // The control may have not been initialized yet (i.e. SetParentL has
+ // not been called). Do not get cursor position in that case because
+ // it crashes due to missing text view in the CEikEdwin.
+ TInt cursorPosition(
+ (IsInitialized() ? CEikEdwin::CursorPos() : iCursorPosition));
+
+ DEBUG_INT("CMIDTextEditorEdwin::CursorPos -, cursorPosition=%d",
+ cursorPosition);
+
+ return cursorPosition;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::Selection
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TCursorSelection CMIDTextEditorEdwin::Selection()
+{
+ DEBUG("CMIDTextEditorEdwin::Selection +");
+
+ TCursorSelection selection(iSelection);
+
+ // Selection is not returned correctly if the editor has not been
+ // initialized.
+ if (IsInitialized())
+ {
+ selection = CEikEdwin::Selection();
+ }
+
+ DEBUG("CMIDTextEditorEdwin::Selection -");
+
+ return selection;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetWordWrapL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetWordWrapL(TBool aWrapIsOn)
+{
+ DEBUG_INT("CMIDTextEditorEdwin::SetWordWrapL +, aWrapIsOn=%d",
+ aWrapIsOn);
+
+ // CEikEdwin crashes when setting word wrap before it
+ // has a valid container window. Multiline state is set
+ // in InitializeL() method again when called.
+ if (IsInitialized())
+ {
+ CEikEdwin::SetWordWrapL(aWrapIsOn);
+
+ // Apply line and paragraph breaks.
+ if (!aWrapIsOn)
+ {
+ AddFlagToUserFlags(CEikEdwin::ENoLineOrParaBreaks);
+ }
+ else
+ {
+ RemoveFlagFromUserFlags(CEikEdwin::ENoLineOrParaBreaks);
+ }
+ }
+
+ iMultiline = aWrapIsOn;
+
+ DEBUG("CMIDTextEditorEdwin::SetCursorPosL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::IsWrapEnabled
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TBool CMIDTextEditorEdwin::IsWrapEnabled() const
+{
+ return iMultiline;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetSize
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetSize(TInt aWidth, TInt aHeight)
+{
+ DEBUG("CMIDTextEditorEdwin::SetSize +");
+
+ // Set the width of the editor window. Note that EWidthInPixels is set
+ // so this method uses the parameter as pixels instead of chars.
+ CalculateWidth(aWidth);
+ // Set minimum and maximum height to the same value.
+ SetMinimumHeight(aHeight);
+ SetMaximumHeight(aHeight);
+
+ TSize size(aWidth, aHeight);
+ // Set size of the UI control if container has been set. Otherwise
+ // this will panic the editor window at some point.
+ if (IsInitialized())
+ {
+ CCoeControl::SetSize(size);
+ }
+
+ // Store the size for later use when set parent has been called.
+ iSize = size;
+
+ DEBUG("CMIDTextEditorEdwin::SetSize -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::Size
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TSize CMIDTextEditorEdwin::Size() const
+{
+ DEBUG("CMIDTextEditorEdwin::Size +");
+
+ TSize size(iSize);
+
+ // Check if editor has been initialized.
+ if (IsInitialized())
+ {
+ size = CCoeControl::Size();
+ }
+
+ DEBUG("CMIDTextEditorEdwin::Size -");
+
+ return size;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::IsInitialized
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TBool CMIDTextEditorEdwin::IsInitialized() const
+{
+ DEBUG_INT("CMIDTextEditorEdwin::IsInitialized, iInitialized=%d",
+ iInitialized);
+
+ // Currently, the text editor is considered as constructed when the text
+ // view has been created and the editor window has been activated.
+ return iInitialized;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::InitializeL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::InitializeL()
+{
+ DEBUG("CMIDTextEditorEdwin::InitializeL +");
+
+ if (!iInitialized)
+ {
+ CreateTextViewL();
+ ActivateL();
+
+ // Set colors here in order to avoid crash when parent
+ // has not been set by CMIDTextEditor.
+ SetBackgroundColorL(iBackgroundColor);
+ iTextView->SetBackgroundColor(iBackgroundColor);
+
+ // Set selection set before initialization.
+ CEikEdwin::SetCursorPosL(iCursorPosition, EFalse);
+
+ // Selection overrides cursor's position
+ if (iSelection.Length() > 0)
+ {
+ CEikEdwin::SetCursorPosL(iSelection.LowerPos(), EFalse);
+ CEikEdwin::SetCursorPosL(iSelection.HigherPos(), ETrue);
+ }
+
+ // By default, editor is unfocused and not visible. Note
+ // that hide and show cannot be called before set parent.
+ SetFocus(EFalse);
+ MakeVisible(EFalse);
+ // Apply current size.
+ CCoeControl::SetSize(iSize);
+ iInitialized = true;
+ // Apply current multiline status. iInitialized must be true here.
+ SetWordWrapL(iMultiline);
+ }
+
+ DEBUG("CMIDTextEditorEdwin::InitializeL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::Uninitialize
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::Uninitialize()
+{
+ DEBUG("CMIDTextEditorEdwin::Uninitialize +");
+
+ if (iInitialized)
+ {
+ // Remove focus and hide the editor.
+ SetFocus(EFalse);
+ MakeVisible(EFalse);
+ // Store cursor's current position.
+ iCursorPosition = CEikEdwin::CursorPos();
+
+ iInitialized = false;
+ iParent = NULL;
+ }
+
+ DEBUG("CMIDTextEditorEdwin::Uninitialize -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::EditorWindowHeight
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TInt CMIDTextEditorEdwin::EditorWindowHeight() const
+{
+ DEBUG("CMIDTextEditorEdwin::EditorWindowHeight +");
+
+ TInt minimumHeight = iSize.iHeight;
+ if (iNumberOfLines == 0)
+ {
+ if (MinimumHeight() > 0)
+ {
+ minimumHeight = MinimumHeight();
+ }
+ }
+ else
+ {
+ minimumHeight = (LineHeight() * iNumberOfLines)
+ + iBorder.SizeDelta().iHeight
+ + iMargins.iTop
+ + iMargins.iBottom;
+ }
+
+ DEBUG_INT("CMIDTextEditorEdwin::EditorWindowHeight - , height=%d",
+ minimumHeight);
+
+ return minimumHeight;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::NumberOfLines
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TInt CMIDTextEditorEdwin::NumberOfLines() const
+{
+ __ASSERT_DEBUG(iLayout, User::Invariant());
+
+ return iLayout->NumFormattedLines();
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::LineHeight
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TInt CMIDTextEditorEdwin::LineHeight() const
+{
+ __ASSERT_DEBUG(iLayout, User::Invariant());
+
+ TInt lineHeight = iLayout->FormattedHeightInPixels();
+ const TInt docLength = iLayout->DocumentLength();
+ if (docLength > 0)
+ {
+ const TInt numFormattedLines = iLayout->NumFormattedLines();
+ lineHeight = lineHeight / numFormattedLines;
+ }
+
+ return lineHeight;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::VisibleContentPosition
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TInt CMIDTextEditorEdwin::VisibleContentPosition() const
+{
+ DEBUG("CMIDTextEditorEdwin::VisibleContentPosition +");
+
+ __ASSERT_DEBUG(iLayout, User::Invariant());
+
+ DEBUG_INT("CMIDTextEditorEdwin::VisibleContentPosition -, pos=%d",
+ iLayout->PixelsAboveBand());
+
+ return iLayout->PixelsAboveBand();
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::Read
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+const TPtrC CMIDTextEditorEdwin::Read() const
+{
+ if (iConstraints & MMIDTextField::EPassword)
+ {
+ return static_cast< CPasswordBoxGlobalText* >(iText)->ClearText();
+ }
+
+ return iText->Read(0, TextLength());
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::MopSupplyObject
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TTypeUid::Ptr CMIDTextEditorEdwin::MopSupplyObject(TTypeUid aId)
+{
+ // Try supplying custom indicator.
+ TTypeUid::Ptr id((
+ iIndicator ? iIndicator->SupplyIndicatorMopObject(aId)
+ : TTypeUid::Null()));
+
+ // Indicator was not supplied. Try supplying from CEikEdwin.
+ if (!(id.Pointer()))
+ {
+ return CEikEdwin::MopSupplyObject(aId);
+ }
+
+ return id;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::SetDocumentContentL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+void CMIDTextEditorEdwin::SetDocumentContentL(CGlobalText* aText)
+{
+ DEBUG("CMIDTextEditorEdwin::SetDocumentContentL +");
+
+ // Even though the method takes a reference in it, the ownership
+ // is still transferred to CEikEdwin. And current iText is simply
+ // left ignored. Store it locally and delete after successful
+ // operation
+ CPlainText* temp = iText;
+ TRAPD(err, CEikEdwin::SetDocumentContentL(
+ *aText, CEikEdwin::EUseText));
+
+ if (err != KErrNone)
+ {
+ // Failed but the ownership was transferred... State has been changed
+ // but we avoid leaking any memory at this point which is better.
+ // Restore the text back. This is not bulletproof, but leaves
+ // the text state as it was before trying to set the new text.
+ delete iText;
+ iText = temp;
+ User::Leave(err);
+ }
+
+ // Everything went fine. Delete the old iText.
+ delete temp;
+
+ DEBUG("CMIDTextEditorEdwin::SetDocumentContentL -");
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::AknInputCaps
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+CAknExtendedInputCapabilities* CMIDTextEditorEdwin::AknInputCaps() const
+{
+ CAknExtendedInputCapabilities* caps = NULL;
+
+ TCoeInputCapabilities inputCapabilities = InputCapabilities();
+ if (inputCapabilities != TCoeInputCapabilities::ENone)
+ {
+ DEBUG("CMIDTextEditorEdwin::AknInputCaps, editor has input caps");
+
+ // Get input capabilities object provider.
+ MObjectProvider* provider = inputCapabilities.ObjectProvider();
+ if (provider)
+ {
+ DEBUG(
+ "CMIDTextEditorEdwin::AknInputCaps, object provider found");
+
+ // MopGetObjects needs a reference to a pointer to an object
+ // of a type that is to be retrieved. NULL is OK here.
+ caps = provider->MopGetObject(caps);
+ }
+ }
+
+ return caps;
+}
+
+// ---------------------------------------------------------------------------
+// CMIDTextEditorEdwin::RemoveInvalidNumericContentL
+// (other items were commented in the header file)
+// ---------------------------------------------------------------------------
+//
+TBool CMIDTextEditorEdwin::RemoveInvalidNumericContentL()
+{
+ DEBUG("CMIDTextEditorEdwin::RemoveInvalidNumericContentL +");
+
+ TBool textChanged = EFalse;
+ TPtrC content = Read();
+
+ // Handle content change in numeric and decimal editors if the
+ // content is not valid for the given set of constraints.
+ if (!iEdwinUtils.ConstraintsValidForText(content, iConstraints, ETrue))
+ {
+ DEBUG("CMIDTextEditorEdwin::RemoveInvalidNumericContentL, \
+content not valid");
+
+ TLocale locale;
+ TChar decimal(locale.DecimalSeparator());
+ TChar minus(KCharMinus);
+
+ TInt cursorPos = CursorPos();
+ TInt minusPos = content.Locate(minus);
+ TInt decimalPos = content.Locate(decimal);
+
+ // Validate that minus character has been entered correctly
+ // First cases in which there is only minus and separator.
+ if (content.Length() == 1 &&
+ ((decimalPos == 0) || (minusPos == 0)))
+ {
+ iText->DeleteL(0, 1);
+ cursorPos = 0;
+ }
+ else if (content.Length() == 2 &&
+ ((minusPos == 0) && (decimalPos == 1)))
+ {
+ iText->DeleteL(0, 2);
+ cursorPos = 0;
+ }
+ else
+ {
+ // Other cases. Minus and decimal somewhere in the content.
+ if (minusPos != KErrNotFound)
+ {
+ // The first is valid. Remove all other minus chars.
+ minusPos = content.LocateReverse(minus);
+ while (minusPos != 0 && minusPos != KErrNotFound)
+ {
+ iText->DeleteL(minusPos, 1);
+ minusPos = content.LocateReverse(minus);
+ cursorPos--;
+ }
+ }
+
+ // Decimal position may have changed.
+ decimalPos = content.Locate(decimal);
+
+ if (decimalPos != KErrNotFound)
+ {
+ // The first is valid. Remove all other separators.
+ TInt secondPos = content.LocateReverse(decimal);
+ while (secondPos != decimalPos)
+ {
+ iText->DeleteL(secondPos, 1);
+ secondPos = content.LocateReverse(decimal);
+ cursorPos--;
+ }
+ }
+ }
+
+ // Do not report event again so call base class' method.
+ CEikEdwin::HandleTextChangedL();
+ // Restore cursor's original position.
+ SetCursorPosL(cursorPos, EFalse);
+ textChanged = ETrue;
+ }
+
+ DEBUG_INT(
+ "CMIDTextEditorEdwin::RemoveInvalidNumericContentL -, textChanged=%d",
+ textChanged);
+
+ return textChanged;
+}
+
+// End of file