javauis/lcdui_akn/lcdui/src/CMIDTextEditorEdwin.cpp
branchRCL_3
changeset 19 04becd199f91
child 23 98ccebc37403
equal deleted inserted replaced
16:f5050f1da672 19:04becd199f91
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Defines a custom editor window for Text editor component.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INTERNAL INCLUDES
       
    20 #include "CMIDTextEditorEdwin.h"
       
    21 #include "CMIDEdwinUtils.h"
       
    22 #include "CMIDTextEditorEdwinCustomDraw.h"
       
    23 #include "CMIDEditingStateIndicator.h"
       
    24 
       
    25 // EXTERNAL INCLUDES
       
    26 #include <MMIDTextEditor.h> // MMIDTextEditorObserver
       
    27 #include <aknextendedinputcapabilities.h>
       
    28 #include <AknSettingCache.h>
       
    29 #include <eikedwob.h>
       
    30 #include <j2me/jdebug.h>
       
    31 
       
    32 const TInt KColorOpaque = 255;
       
    33 const TInt KCharMinus   = 0x2d;
       
    34 
       
    35 // ---------------------------------------------------------------------------
       
    36 // CMIDTextEditorEdwin::CMIDTextEditorEdwin
       
    37 // ---------------------------------------------------------------------------
       
    38 //
       
    39 CMIDTextEditorEdwin::CMIDTextEditorEdwin(CMIDEdwinUtils& aEdwinUtils)
       
    40         : CEikEdwin(),
       
    41         iMultiline(EFalse),
       
    42         iCursorPosForAction(KErrNotFound),
       
    43         iEdwinUtils(aEdwinUtils)
       
    44 {
       
    45     DEBUG("CMIDTextEditorEdwin::CMIDTextEditorEdwin +");
       
    46 
       
    47     // Set margins to zero
       
    48     TMargins8 margins;
       
    49     margins.SetAllValuesTo(0);
       
    50     SetBorderViewMargins(margins);
       
    51     // Set layout
       
    52     CAknEnv::Static()->GetCurrentLayoutId(iDirection);
       
    53     // Set visible content height
       
    54     iVisibleContentHeight = 0;
       
    55     // Set border to zero
       
    56     SetBorder(TGulBorder::ENone);
       
    57     SetFocusing(ETrue);
       
    58     DEBUG("CMIDTextEditorEdwin::CMIDTextEditorEdwin -");
       
    59 }
       
    60 
       
    61 // ---------------------------------------------------------------------------
       
    62 // CMIDTextEditorEdwin::~CMIDTextEditorEdwin
       
    63 // ---------------------------------------------------------------------------
       
    64 //
       
    65 CMIDTextEditorEdwin::~CMIDTextEditorEdwin()
       
    66 {
       
    67     DEBUG("CMIDTextEditorEdwin::~CMIDTextEditorEdwin");
       
    68 }
       
    69 
       
    70 // ---------------------------------------------------------------------------
       
    71 // CMIDTextEditorEdwin::ConstructL
       
    72 // (other items were commented in the header file)
       
    73 // ---------------------------------------------------------------------------
       
    74 //
       
    75 void CMIDTextEditorEdwin::ConstructL(
       
    76     TInt aEdwinFlags,
       
    77     TInt aWidthInChars,
       
    78     TInt aTextLimit,
       
    79     TInt aNumberOfLines)
       
    80 {
       
    81     DEBUG("CMIDTextEditorEdwin::ConstructL +");
       
    82 
       
    83     CEikEdwin::ConstructL(
       
    84         aEdwinFlags, aWidthInChars, aTextLimit, aNumberOfLines);
       
    85 
       
    86     // Supress all background drawing of CEikEdwin so that this editor
       
    87     // can draw the correct custom color to the background.
       
    88     SetSuppressBackgroundDrawing(ETrue);
       
    89 
       
    90     // No background control context. This way it is possible to change the
       
    91     // background color of the text editor. By default, it is white.
       
    92     SetSkinBackgroundControlContextL(NULL);
       
    93 
       
    94     // Observer events in the editor. Note that this must be done in order
       
    95     // to avoid resulting incorrect content in numeric and decimal editors
       
    96     SetEdwinObserver(this);
       
    97 
       
    98     // To have the line where cursor is properly displayed.
       
    99     if (iLayout)
       
   100     {
       
   101         iLayout->RestrictScrollToTopsOfLines(EFalse);
       
   102     }
       
   103 
       
   104     DEBUG("CMIDTextEditorEdwin::ConstructL -");
       
   105 }
       
   106 
       
   107 // ---------------------------------------------------------------------------
       
   108 // CMIDTextEditorEdwin::OfferKeyEventL
       
   109 // (other items were commented in the header file)
       
   110 // ---------------------------------------------------------------------------
       
   111 //
       
   112 TKeyResponse CMIDTextEditorEdwin::OfferKeyEventL(
       
   113     const TKeyEvent& aKeyEvent,
       
   114     TEventCode aType)
       
   115 {
       
   116     DEBUG_INT("CMIDTextEditorEdwin::OfferKeyEventL +, aType=%d", aType);
       
   117 
       
   118     TKeyResponse response = EKeyWasNotConsumed;
       
   119 
       
   120     if ((aType == EEventKey) &&
       
   121             (aKeyEvent.iCode == EKeyEnter) &&
       
   122             (!iMultiline ||
       
   123              iConstraints & MMIDTextField::EPassword ||
       
   124              !IsConstraintSet(MMIDTextField::EAny)))
       
   125     {
       
   126         // Enter key for single-line editor, password and other than any
       
   127         // editors is simply passed on.
       
   128         DEBUG("CMIDTextEditorEdwin::OfferKeyEventL -, ignoring enter");
       
   129 
       
   130         return response;
       
   131     }
       
   132 
       
   133     // Offer key event to editor window if it is set focused and visible.
       
   134     // If the editor is set hidden, OfferKeyEventL will update the content
       
   135     // in the editor and draw it. So the editor content CANNOT be modified
       
   136     // if it is not visible and focused.
       
   137     if (IsFocused() && IsVisible())
       
   138     {
       
   139         DEBUG("CMIDTextEditorEdwin::OfferKeyEventL, focused=true");
       
   140 
       
   141         // Edwin does not report cursor movements with text updates
       
   142         // Store the current position here for future use.
       
   143         iCursorPosForAction = CursorPos();
       
   144 
       
   145         // Try handling special characters.
       
   146         response = HandleSpecialKeyEventsL(aKeyEvent, aType);
       
   147 
       
   148         // Not handled, try with CEikEdwin
       
   149         if (response == EKeyWasNotConsumed)
       
   150         {
       
   151             // Old text is needed if the new content is not valid for the
       
   152             // given set of constraints. This validation is made because
       
   153             // CEikEdwin and FEP seem to input text that is not always
       
   154             // valid for the given Java-specific constraints. No very
       
   155             // optimized solution to allocate heap here but at least this
       
   156             // solution is bulletproof and prevents illegal contents.
       
   157             // This also prevents that the implementation does not ignore
       
   158             // special characters such as navigation and hotkeys.
       
   159             HBufC* oldContent = GetTextInHBufL();
       
   160 
       
   161             CleanupStack::PushL(oldContent);
       
   162 
       
   163             response = CEikEdwin::OfferKeyEventL(aKeyEvent, aType);
       
   164 
       
   165             // Validate new content and undo if not valid.
       
   166             if (!iEdwinUtils.ConstraintsValidForText(
       
   167                         Read(), iConstraints, EFalse))
       
   168             {
       
   169                 CEikEdwin::SetTextL(oldContent);
       
   170                 // Notify about text change.
       
   171                 HandleTextChangedL();
       
   172                 // Restore cursor's original position.
       
   173                 SetCursorPosL(iCursorPosForAction, EFalse);
       
   174             }
       
   175 
       
   176             CleanupStack::PopAndDestroy(oldContent);
       
   177         }
       
   178 
       
   179         // Update current selection.
       
   180         iSelection = Selection();
       
   181 
       
   182         // Draw now so that background gets updated. Otherwise the
       
   183         // content may not be updated (e.g. cursor may be visible
       
   184         // if a line is deleted from the editor.
       
   185         // Transparency needs whole redraw of the editor's content.
       
   186         if (IsTransparent())
       
   187         {
       
   188             iParent->DrawNow(Rect());
       
   189         }
       
   190         else
       
   191         {
       
   192             DrawDeferred();
       
   193         }
       
   194     }
       
   195 
       
   196     DEBUG("CMIDTextEditorEdwin::OfferKeyEventL -");
       
   197 
       
   198     return response;
       
   199 }
       
   200 
       
   201 // ---------------------------------------------------------------------------
       
   202 // CMIDTextEditorEdwin::Traverse
       
   203 // (other items were commented in the header file)
       
   204 // ---------------------------------------------------------------------------
       
   205 //
       
   206 TBool CMIDTextEditorEdwin::Traverse(const TKeyEvent& aEvent)
       
   207 {
       
   208     TInt cursorPos = CursorPos();
       
   209     TBool traverse = EFalse;
       
   210 
       
   211     if ((aEvent.iCode == EKeyDownArrow) ||
       
   212             (aEvent.iScanCode == EStdKeyDownArrow))
       
   213     {
       
   214         if (TextLength() == cursorPos)
       
   215         {
       
   216             traverse = ETrue;
       
   217         }
       
   218 
       
   219     }
       
   220     else if ((aEvent.iCode == EKeyUpArrow) ||
       
   221              (aEvent.iScanCode == EStdKeyUpArrow))
       
   222     {
       
   223         if (cursorPos == 0)
       
   224         {
       
   225             traverse = ETrue;
       
   226         }
       
   227 
       
   228     }
       
   229 
       
   230     return traverse;
       
   231 }
       
   232 // ---------------------------------------------------------------------------
       
   233 // CMIDTextEditorEdwin::Draw
       
   234 // (other items were commented in the header file)
       
   235 // ---------------------------------------------------------------------------
       
   236 //
       
   237 void CMIDTextEditorEdwin::Draw(const TRect& aRect) const
       
   238 {
       
   239     DEBUG("CMIDTextEditorEdwin::Draw +");
       
   240 
       
   241     // Part of transparency workaround. Set drawing active.
       
   242     iDrawInvoked = ETrue;
       
   243 
       
   244     // Background color is drawn before other content.
       
   245     // Note that in order this to work, the background drawing of CEikEdwin
       
   246     // needs to be suppressed. Custom drawer cannot be used due to flickering
       
   247     // problems. Currently it just handles the selection color.
       
   248     CWindowGc& gc = SystemGc();
       
   249 
       
   250     // Draw background with alpha.
       
   251     gc.SetBrushColor(iBackgroundColor);
       
   252     gc.Clear(aRect);
       
   253 
       
   254     // Now draw the content of the editor.
       
   255     CEikEdwin::Draw(aRect);
       
   256 
       
   257     // Part of transparency workaround. Set drawing not active.
       
   258     iDrawInvoked = EFalse;
       
   259 
       
   260     if (iObserver)
       
   261     {
       
   262         iObserver->NotifyInputAction(
       
   263             MMIDTextEditorObserver::EActionPaintRequest);
       
   264     }
       
   265     DEBUG("CMIDTextEditorEdwin::Draw -");
       
   266 }
       
   267 
       
   268 // ---------------------------------------------------------------------------
       
   269 // CMIDTextEditorEdwin::DrawOngoing
       
   270 // Part of transparency workaround. Returns the current draw status
       
   271 // of this editor window.
       
   272 // ---------------------------------------------------------------------------
       
   273 //
       
   274 TBool CMIDTextEditorEdwin::DrawOngoing() const
       
   275 {
       
   276     return iDrawInvoked;
       
   277 }
       
   278 
       
   279 // ---------------------------------------------------------------------------
       
   280 // CMIDTextEditorEdwin::Redraw
       
   281 // Part of transparency workaround. Returns the current draw status
       
   282 // of this editor window.
       
   283 // ---------------------------------------------------------------------------
       
   284 //
       
   285 void CMIDTextEditorEdwin::Redraw() const
       
   286 {
       
   287     // Do not redraw if draw is already ongoing.
       
   288     if (iDrawInvoked || !iParent)
       
   289     {
       
   290         return;
       
   291     }
       
   292 
       
   293     // If the editor has a transaprent background, the parent
       
   294     // needs to be redrawn in that case. Note that DrawNow
       
   295     // is not applicable here because this is used from the
       
   296     // custom draw which may invoke this method during CTextView
       
   297     // redraw causing a panic to occur.
       
   298     if (IsTransparent())
       
   299     {
       
   300         iParent->DrawDeferred();
       
   301     }
       
   302     else
       
   303     {
       
   304         // No transparency. Draw this control only.
       
   305         DrawDeferred();
       
   306     }
       
   307 }
       
   308 
       
   309 // ---------------------------------------------------------------------------
       
   310 // CMIDTextEditorEdwin::IsTransparent
       
   311 // (other items were commented in the header file)
       
   312 // ---------------------------------------------------------------------------
       
   313 //
       
   314 TBool CMIDTextEditorEdwin::IsTransparent() const
       
   315 {
       
   316     return (iBackgroundColor.Alpha() < KColorOpaque);
       
   317 }
       
   318 
       
   319 // ---------------------------------------------------------------------------
       
   320 // CMIDTextEditorEdwin::FocusChanged
       
   321 // (other items were commented in the header file)
       
   322 // ---------------------------------------------------------------------------
       
   323 //
       
   324 void CMIDTextEditorEdwin::FocusChanged(TDrawNow aDrawNow)
       
   325 {
       
   326     DEBUG("CMIDTextEditorEdwin::FocusChanged +");
       
   327 
       
   328     CEikEdwin::FocusChanged(aDrawNow);
       
   329 
       
   330     // Apply initial input mode change when the editor has been focused.
       
   331     // Note that initial input mode change must be applied only when
       
   332     // an editing session starts (according to MIDP specification).
       
   333     // See CMIDEdwin::HandleCurrentL()
       
   334 
       
   335     if (IsFocused() &&
       
   336             (IsConstraintSet(MMIDTextField::EAny) ||
       
   337              IsConstraintSet(MMIDTextField::EMailAddr) ||
       
   338              IsConstraintSet(MMIDTextField::EUrl)))
       
   339     {
       
   340         // Set current language.
       
   341         if (iInitialCurrentLanguage)
       
   342         {
       
   343             DEBUG("CMIDTextEditorEdwin::FocusChanged, \
       
   344 applying current language");
       
   345 
       
   346             SetAknEditorLocalLanguage(iInitialCurrentLanguage);
       
   347 
       
   348             if (iInitialCurrentInputMode == 0)
       
   349             {
       
   350                 DEBUG("CMIDTextEditorEdwin::FocusChanged, null input mode");
       
   351 
       
   352                 // Clears any number mode used previously
       
   353                 SetAknEditorCurrentInputMode(EAknEditorNullInputMode);
       
   354             }
       
   355         }
       
   356 
       
   357         // Set current input mode.
       
   358         if (iInitialCurrentInputMode)
       
   359         {
       
   360             DEBUG("CMIDTextEditorEdwin::FocusChanged, \
       
   361 applying current input mode");
       
   362 
       
   363             SetAknEditorCurrentInputMode(iInitialCurrentInputMode);
       
   364         }
       
   365 
       
   366         // Set current case.
       
   367         if (iInitialCurrentCase)
       
   368         {
       
   369             DEBUG("CMIDTextEditorEdwin::FocusChanged, \
       
   370 applying current case");
       
   371 
       
   372             TInt initialCurrentCase = iInitialCurrentCase;
       
   373 
       
   374             if ((iConstraints & MMIDTextField::EPassword ||
       
   375                     IsConstraintSet(MMIDTextField::EMailAddr) ||
       
   376                     IsConstraintSet(MMIDTextField::EUrl)) &&
       
   377                     iInitialCurrentCase == EAknEditorTextCase)
       
   378             {
       
   379                 // Text case is not used in passwords, emailaddrs and urls
       
   380                 initialCurrentCase = EAknEditorLowerCase;
       
   381             }
       
   382 
       
   383             SetAknEditorCurrentCase(initialCurrentCase);
       
   384             SetAknEditorCase(initialCurrentCase);
       
   385         }
       
   386     }
       
   387 
       
   388     DEBUG("CMIDTextEditorEdwin::FocusChanged -");
       
   389 }
       
   390 
       
   391 // ---------------------------------------------------------------------------
       
   392 // CMIDTextEditorEdwin::PositionChanged
       
   393 // (other items were commented in the header file)
       
   394 // ---------------------------------------------------------------------------
       
   395 //
       
   396 void CMIDTextEditorEdwin::PositionChanged()
       
   397 {
       
   398     DEBUG("CMIDTextEditorEdwin::PositionChanged +");
       
   399 
       
   400     CCoeControl::PositionChanged();
       
   401 
       
   402     // Text view may have not been created yet.
       
   403     if (iTextView)
       
   404     {
       
   405         // Adjust the view rect to the text view
       
   406         iTextView->SetViewRect(Rect());
       
   407     }
       
   408 
       
   409     DEBUG("CMIDTextEditorEdwin::PositionChanged -");
       
   410 }
       
   411 
       
   412 // ---------------------------------------------------------------------------
       
   413 // CMIDTextEditorEdwin::PositionChanged
       
   414 // (other items were commented in the header file)
       
   415 // ---------------------------------------------------------------------------
       
   416 //
       
   417 void CMIDTextEditorEdwin::OverrideColorL(TInt aLogicalColor, TRgb aColor)
       
   418 {
       
   419     CCoeControl::OverrideColorL(aLogicalColor, aColor);
       
   420 
       
   421     if (aLogicalColor == EColorControlBackground)
       
   422     {
       
   423         iBackgroundColor = aColor;
       
   424     }
       
   425 
       
   426     // Suppress background drawing if the editor is transparent.
       
   427     SetSuppressBackgroundDrawing(IsTransparent());
       
   428 }
       
   429 
       
   430 // ---------------------------------------------------------------------------
       
   431 // CMIDTextEditorEdwin::CreateCustomDrawL
       
   432 // (other items were commented in the header file)
       
   433 // ---------------------------------------------------------------------------
       
   434 //
       
   435 CLafEdwinCustomDrawBase* CMIDTextEditorEdwin::CreateCustomDrawL()
       
   436 {
       
   437     DEBUG("CMIDTextEditorEdwin::CreateCustomDrawL +");
       
   438 
       
   439     // First create the parent custom draw that handles the drawing of
       
   440     // text and other related components.
       
   441     const MFormCustomDraw* customDraw = CEikEdwin::CreateCustomDrawL();
       
   442 
       
   443     // Create text editor specific custom draw that handles the
       
   444     // setting of selection color.
       
   445     CLafEdwinCustomDrawBase* ret = new(ELeave)CMIDTextEditorEdwinCustomDraw(
       
   446         iEikonEnv->LafEnv(), *customDraw, *this);
       
   447 
       
   448     DEBUG("CMIDTextEditorEdwin::CreateCustomDrawL -");
       
   449 
       
   450     return ret;
       
   451 }
       
   452 
       
   453 // ---------------------------------------------------------------------------
       
   454 // CMIDTextEditorEdwin::HandleTextPastedL
       
   455 // (other items were commented in the header file)
       
   456 // ---------------------------------------------------------------------------
       
   457 //
       
   458 void CMIDTextEditorEdwin::HandleTextPastedL(TInt aStartPos, TInt& aLength)
       
   459 {
       
   460     DEBUG_INT2(
       
   461         "CMIDTextEditorEdwin::HandleTextPastedL +, aStartPos=%d, aLength=%d",
       
   462         aStartPos, aLength);
       
   463 
       
   464     HBufC* content = GetTextInHBufL(); // May return NULL
       
   465     if (!content)
       
   466     {
       
   467         // For guaranteeing that this method does not crash in any case.
       
   468         return;
       
   469     }
       
   470 
       
   471     CleanupStack::PushL(content);
       
   472 
       
   473     // Check that the pasted text is valid for the given set of constraints.
       
   474     if (!iEdwinUtils.ConstraintsValidForText(
       
   475                 content->Des(), iConstraints, ETrue))
       
   476     {
       
   477         DEBUG("CMIDTextEditorEdwin::HandleTextPastedL, \
       
   478 constraints not valid");
       
   479 
       
   480         // Remove pasted content from the text and set it back.
       
   481         iText->DeleteL(aStartPos, aLength);
       
   482         // Notify about the change.
       
   483         HandleTextChangedL();
       
   484     }
       
   485     // Convert breaks if needed if constraints that do not allow line breaks.
       
   486     // Note that numeric, decimal and phonenumber do not allow line breaks
       
   487     // and are checked before this so no need to check here again.
       
   488     else if (!IsWrapEnabled() ||
       
   489              iConstraints & MMIDTextField::EPassword  ||
       
   490              IsConstraintSet(MMIDTextField::EUrl) ||
       
   491              IsConstraintSet(MMIDTextField::EMailAddr))
       
   492     {
       
   493         DEBUG("CMIDTextEditorEdwin::HandleTextPastedL, \
       
   494 cropping to single line");
       
   495 
       
   496         TPtr ptr = content->Des();
       
   497         iEdwinUtils.CropToSingleLine(ptr);
       
   498         CEikEdwin::SetTextL(content);
       
   499         // Notify about content change.
       
   500         HandleTextChangedL();
       
   501     }
       
   502 
       
   503     CleanupStack::PopAndDestroy(content);
       
   504 
       
   505     DEBUG("CMIDTextEditorEdwin::HandleTextPastedL -");
       
   506 }
       
   507 
       
   508 // ---------------------------------------------------------------------------
       
   509 // CMIDTextEditorEdwin::HandleTextChangedL
       
   510 // (other items were commented in the header file)
       
   511 // ---------------------------------------------------------------------------
       
   512 //
       
   513 void CMIDTextEditorEdwin::HandleTextChangedL()
       
   514 {
       
   515     DEBUG("CMIDTextEditorEdwin::HandleTextChangedL +");
       
   516 
       
   517     // Call edwin's method to format the text and redraw.
       
   518     CEikEdwin::HandleTextChangedL();
       
   519 
       
   520     // Report edwin event.
       
   521     ReportEdwinEventL(MEikEdwinObserver::EEventTextUpdate);
       
   522 
       
   523     DEBUG("CMIDTextEditorEdwin::HandleTextChangedL -");
       
   524 }
       
   525 
       
   526 // ---------------------------------------------------------------------------
       
   527 // CMIDTextEditorEdwin::HandleResourceChangeL
       
   528 // (other items were commented in the header file)
       
   529 // ---------------------------------------------------------------------------
       
   530 //
       
   531 void CMIDTextEditorEdwin::HandleResourceChange(TInt aType)
       
   532 {
       
   533     // Notification about language change
       
   534     if (aType == KEikInputLanguageChange)
       
   535     {
       
   536         if (iObserver)
       
   537         {
       
   538             TInt event = MMIDTextEditorObserver::EActionLanguageChange;
       
   539             TAknLayoutId currentLayoutId;
       
   540             CAknEnv::Static()->GetCurrentLayoutId(currentLayoutId);
       
   541             if (iDirection != currentLayoutId)
       
   542             {
       
   543                 iDirection = currentLayoutId;
       
   544                 event |= MMIDTextEditorObserver::EActionDirectionChange;
       
   545             }
       
   546             iObserver->NotifyInputAction(event);
       
   547         }
       
   548     }
       
   549 }
       
   550 
       
   551 // ---------------------------------------------------------------------------
       
   552 // CMIDTextEditorEdwin::HandleEdwinEventL
       
   553 // (other items were commented in the header file)
       
   554 // ---------------------------------------------------------------------------
       
   555 //
       
   556 void CMIDTextEditorEdwin::HandleEdwinEventL(
       
   557     CEikEdwin* /*aEdwin*/,
       
   558     TEdwinEvent aEventType)
       
   559 {
       
   560     DEBUG_INT("CMIDTextEditorEdwin::HandleEdwinEventL +, aEventType=%d",
       
   561               aEventType);
       
   562 
       
   563     if (aEventType == EEventTextUpdate && (
       
   564                 IsConstraintSet(MMIDTextField::EDecimal) ||
       
   565                 IsConstraintSet(MMIDTextField::ENumeric)))
       
   566     {
       
   567         // Do not report events if the content was invalid.
       
   568         if (RemoveInvalidNumericContentL())
       
   569         {
       
   570             return;
       
   571         }
       
   572     }
       
   573 
       
   574     // Notify observer if set.
       
   575     if (iObserver)
       
   576     {
       
   577         switch (aEventType)
       
   578         {
       
   579         case EEventNavigation:
       
   580         {
       
   581             TInt event = MMIDTextEditorObserver::EActionCaretMove;
       
   582             TInt newVisiblecontentHeight = VisibleContentPosition();
       
   583 
       
   584             // Check if cursor has moved. This must be done because
       
   585             // currently edwin does not report cursor position movement
       
   586             // when text is changed due to user input.
       
   587             if ((iVisibleContentHeight != newVisiblecontentHeight) &&
       
   588                     (iCursorPosForAction != CursorPos()))
       
   589             {
       
   590                 event |= MMIDTextEditorObserver::EActionScrollbarChange;
       
   591                 // Reported, reset here to avoid multiple notifications.
       
   592                 iVisibleContentHeight = newVisiblecontentHeight;
       
   593             }
       
   594 
       
   595             iObserver->NotifyInputAction(event);
       
   596             break;
       
   597         }
       
   598         case EEventFormatChanged: // Fallthrough
       
   599         case EEventTextUpdate:
       
   600         {
       
   601             TInt event = MMIDTextEditorObserver::EActionContentChange;
       
   602 
       
   603             // Check if cursor has moved. This must be done because
       
   604             // currently edwin does not report cursor position movement
       
   605             // when text is changed due to user input.
       
   606             if (iCursorPosForAction != KErrNotFound &&
       
   607                     iCursorPosForAction != CursorPos())
       
   608             {
       
   609                 event |= MMIDTextEditorObserver::EActionCaretMove;
       
   610                 // Reported, reset here to avoid multiple notifications.
       
   611                 iCursorPosForAction = KErrNotFound;
       
   612             }
       
   613 
       
   614             iObserver->NotifyInputAction(event);
       
   615             break;
       
   616         }
       
   617         case EEventScroll:
       
   618         {
       
   619             break;
       
   620         }
       
   621         default:
       
   622         {
       
   623             // Not handled.
       
   624             break;
       
   625         }
       
   626         }
       
   627     }
       
   628 
       
   629     DEBUG("CMIDTextEditorEdwin::HandleEdwinEventL -");
       
   630 }
       
   631 
       
   632 // ---------------------------------------------------------------------------
       
   633 // CMIDTextEditorEdwin::HandlePointerEventL
       
   634 // (other items were commented in the header file)
       
   635 // ---------------------------------------------------------------------------
       
   636 //
       
   637 #ifdef RD_SCALABLE_UI_V2
       
   638 void CMIDTextEditorEdwin::HandlePointerEventL(
       
   639     const TPointerEvent &aPointerEvent)
       
   640 {
       
   641     DEBUG("CMIDTextEditorEdwin::HandlePointerEventL +");
       
   642     if (AknLayoutUtils::PenEnabled())
       
   643     {
       
   644         CEikEdwin::HandlePointerEventL(aPointerEvent);
       
   645     }
       
   646     DEBUG("CMIDTextEditorEdwin::HandlePointerEventL -");
       
   647 }
       
   648 #endif // RD_SCALABLE_UI_V2
       
   649 
       
   650 
       
   651 // ---------------------------------------------------------------------------
       
   652 // CMIDTextEditorEdwin::HandleSpecialKEyEventsL
       
   653 // (other items were commented in the header file)
       
   654 // ---------------------------------------------------------------------------
       
   655 //
       
   656 TKeyResponse CMIDTextEditorEdwin::HandleSpecialKeyEventsL(
       
   657     const TKeyEvent& aKeyEvent,
       
   658     TEventCode aType)
       
   659 {
       
   660     DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL +");
       
   661 
       
   662     TKeyResponse response = EKeyWasNotConsumed;
       
   663 
       
   664     // Do not handle anything if text's maximum lenght has been reached
       
   665     // or if the editor is set to read only state.
       
   666     if (TextLength() >= MaxLength() || IsReadOnly())
       
   667     {
       
   668         DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL -, \
       
   669 max size reached");
       
   670 
       
   671         return response;
       
   672     }
       
   673 
       
   674     TUint sc = aKeyEvent.iScanCode;
       
   675 
       
   676     DEBUG_INT2("CMIDTextEditorEdwin::HandleSpecialKeyEventsL, \
       
   677 scanCode=0x%x, iConstraints=0x%x", sc, iConstraints);
       
   678 
       
   679     TBool dec = IsConstraintSet(MMIDTextField::EDecimal);
       
   680     TBool num = IsConstraintSet(MMIDTextField::ENumeric);
       
   681 
       
   682     // Try to handle minus and full stop characters separately.
       
   683     // Other than EEventKey events are ignored.
       
   684 
       
   685     if ((dec || num) &&
       
   686             (aType == EEventKey) &&
       
   687             (sc == EStdKeyMinus || sc == EStdKeyNkpMinus ||
       
   688              sc == EStdKeyFullStop || sc == EStdKeyNkpFullStop ||
       
   689              sc == EStdKeyNkpAsterisk || sc == KMidpKeyNkpAsteriskHW))
       
   690     {
       
   691         DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL, \
       
   692 handling special");
       
   693 
       
   694         TInt cursorPos = CursorPos();
       
   695         TPtrC content = Read();
       
   696 
       
   697         // Toggle minus character. Decimal editor uses SCT so do not toggle
       
   698         // from asterisk key in that case.
       
   699         if ((sc == EStdKeyMinus || sc == EStdKeyNkpMinus) ||
       
   700                 ((sc == EStdKeyNkpAsterisk || sc == KMidpKeyNkpAsteriskHW)
       
   701                  && num))
       
   702         {
       
   703             DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL, \
       
   704 toggle minus");
       
   705 
       
   706             if (content.Find(KMinusChar) == KErrNotFound)
       
   707             {
       
   708                 iText->InsertL(0, KMinusChar);
       
   709                 cursorPos++;
       
   710             }
       
   711             else
       
   712             {
       
   713                 iText->DeleteL(0, 1);
       
   714                 cursorPos--;
       
   715             }
       
   716 
       
   717             HandleTextChangedL();
       
   718             ReportEdwinEventL(MEikEdwinObserver::EEventTextUpdate);
       
   719             SetCursorPosL(cursorPos, EFalse);
       
   720 
       
   721             response = EKeyWasConsumed;
       
   722         }
       
   723         else if (dec && (sc == EStdKeyFullStop ||
       
   724                          sc == EStdKeyNkpFullStop))
       
   725         {
       
   726             TLocale locale;
       
   727             TChar decimalSeparator(locale.DecimalSeparator());
       
   728 
       
   729             if (content.Locate(decimalSeparator) == KErrNotFound)
       
   730             {
       
   731                 DEBUG("CMIDTextEditorEdwin::HandleSpecialKeyEventsL, \
       
   732 inserting full stop");
       
   733 
       
   734                 // Insert full stop sign into to cursor's current position.
       
   735                 iText->InsertL(cursorPos, decimalSeparator);
       
   736                 HandleTextChangedL();
       
   737                 ReportEdwinEventL(MEikEdwinObserver::EEventTextUpdate);
       
   738                 SetCursorPosL(cursorPos + 1, EFalse);
       
   739 
       
   740                 response = EKeyWasConsumed;
       
   741             }
       
   742         }
       
   743     }
       
   744 
       
   745     DEBUG_INT("CMIDTextEditorEdwin::HandleSpecialKeyEventsL - response=%d",
       
   746               response);
       
   747 
       
   748     return response;
       
   749 }
       
   750 
       
   751 // ---------------------------------------------------------------------------
       
   752 // CMIDTextEditorEdwin::SetTopParent
       
   753 // (other items are commented in the header file)
       
   754 // ---------------------------------------------------------------------------
       
   755 //
       
   756 void CMIDTextEditorEdwin::SetTopParent(CCoeControl* aControl)
       
   757 {
       
   758     iParent = aControl;
       
   759 }
       
   760 
       
   761 // ---------------------------------------------------------------------------
       
   762 // CMIDTextEditorEdwin::SetObserver
       
   763 // (other items are commented in the header file)
       
   764 // ---------------------------------------------------------------------------
       
   765 //
       
   766 void CMIDTextEditorEdwin::SetObserver(MMIDTextEditorObserver* aObserver)
       
   767 {
       
   768     DEBUG("CMIDTextEditorEdwin::SetObserver +");
       
   769 
       
   770     iObserver = aObserver;
       
   771 
       
   772     DEBUG("CMIDTextEditorEdwin::SetObserver -");
       
   773 }
       
   774 
       
   775 // ---------------------------------------------------------------------------
       
   776 // CMIDTextEditorEdwin::SetEditingStateIndicator
       
   777 // (other items were commented in the header file)
       
   778 // ---------------------------------------------------------------------------
       
   779 //
       
   780 void CMIDTextEditorEdwin::SetEditingStateIndicator(
       
   781     CMIDEditingStateIndicator* aIndicator)
       
   782 {
       
   783     DEBUG("CMIDTextEditorEdwin::SetEditingStateIndicator +");
       
   784 
       
   785     // Indicator can be set to NULL.
       
   786     iIndicator = aIndicator;
       
   787 
       
   788     DEBUG("CMIDTextEditorEdwin::SetEditingStateIndicator -");
       
   789 }
       
   790 
       
   791 // ---------------------------------------------------------------------------
       
   792 // CMIDTextEditorEdwin::SetConstraintsL
       
   793 // (other items were commented in the header file)
       
   794 // ---------------------------------------------------------------------------
       
   795 //
       
   796 void CMIDTextEditorEdwin::SetConstraintsL(TUint aConstraints)
       
   797 {
       
   798     DEBUG("CMIDTextEditorEdwin::SetConstraintsL +");
       
   799 
       
   800     // Note that this method cannot be 100% leave-safe due to the current
       
   801     // CEikEdwin implementation.
       
   802 
       
   803     __ASSERT_DEBUG(iText, User::Invariant());
       
   804 
       
   805     // Apply document content.
       
   806     CGlobalText* newText = NULL;
       
   807     CGlobalText* oldText = static_cast< CGlobalText* >(iText);
       
   808 
       
   809     const CParaFormatLayer* paraFormatLayer =
       
   810         oldText->GlobalParaFormatLayer();
       
   811 
       
   812     const CCharFormatLayer* charFormatLayer =
       
   813         oldText->GlobalCharFormatLayer();
       
   814 
       
   815     TBool enableCcpuSupport = ETrue;
       
   816 
       
   817     // Create password text if mode is password (non-restrictive).
       
   818     if (aConstraints & MMIDTextField::EPassword)
       
   819     {
       
   820         DEBUG(
       
   821             "CMIDTextEditorEdwin::SetConstraintsL, creating password text");
       
   822 
       
   823         // Password editors must not use CCPU support according to
       
   824         // S60 Editing specification.
       
   825         enableCcpuSupport = EFalse;
       
   826 
       
   827         CPasswordBoxGlobalText* text = new(ELeave)CPasswordBoxGlobalText(
       
   828             paraFormatLayer, charFormatLayer, *this);
       
   829 
       
   830         CleanupStack::PushL(text);
       
   831         text->ConstructL();
       
   832         CleanupStack::Pop(text);
       
   833 
       
   834         newText = text;
       
   835     }
       
   836     else // Default, no password.
       
   837     {
       
   838         // Use default global text in the editor.
       
   839         newText = CGlobalText::NewL(paraFormatLayer, charFormatLayer);
       
   840     }
       
   841 
       
   842     CleanupStack::PushL(newText);
       
   843     SetDocumentContentL(newText);
       
   844 
       
   845     // Disable or enable CCPU support here.
       
   846     EnableCcpuSupportL(enableCcpuSupport);
       
   847 
       
   848     // Store constraints here. Rest of the method is leave-safe
       
   849     // and RestoreDefaultInputState uses the capabilities.
       
   850     iConstraints = aConstraints;
       
   851 
       
   852     // Restore default input state before making any modifications. This
       
   853     // ensures that the next input constraints are set correctly and
       
   854     // that the previous constraints do not affect on the new input modes.
       
   855     // This should be done in CMIDEdwinUtils::SetFEPModeAndCharFormat()
       
   856     // but it does not reset all the necessary input parameters.
       
   857     RestoreDefaultInputState();
       
   858 
       
   859     // Set uneditable if set as current mode.
       
   860     SetReadOnly(aConstraints & MMIDTextField::EUneditable);
       
   861 
       
   862     // Use edwin utils to set the FEP mode and character format.
       
   863     iEdwinUtils.SetFEPModeAndCharFormat(aConstraints, this);
       
   864 
       
   865     // Publish MIDP constraints via input capabilities of CEikEdwin.
       
   866     CAknExtendedInputCapabilities* caps = AknInputCaps();
       
   867     if (caps)
       
   868     {
       
   869         DEBUG(
       
   870             "CMIDTextEditorEdwin::SetConstraintsL, setting MIDP constaints");
       
   871 
       
   872         caps->SetMIDPConstraints(aConstraints);
       
   873     }
       
   874 
       
   875     // CMIDEdwinUtils modify the multiline state of the editor
       
   876     // thus it needs the be set again here. Passwords are always
       
   877     // single line editors.
       
   878     if (!(aConstraints & MMIDTextField::EPassword))
       
   879     {
       
   880         SetWordWrapL(iMultiline);
       
   881     }
       
   882     else
       
   883     {
       
   884         SetWordWrapL(EFalse);
       
   885     }
       
   886     CleanupStack::Pop(newText);
       
   887 
       
   888     DEBUG("CMIDTextEditorEdwin::SetConstraintsL +");
       
   889 }
       
   890 
       
   891 // ---------------------------------------------------------------------------
       
   892 // CMIDTextEditorEdwin::SetInitialInputModeL
       
   893 // (other items were commented in the header file)
       
   894 // ---------------------------------------------------------------------------
       
   895 //
       
   896 void CMIDTextEditorEdwin::SetInitialInputModeL(
       
   897     const TDesC& aCharacterSubset)
       
   898 {
       
   899     DEBUG_STR(
       
   900         "CMIDTextEditorEdwin::SetInitialInputModeL +, aCharacterSubset=%S",
       
   901         aCharacterSubset);
       
   902 
       
   903     // Set initial input mode. Note that the change is performed
       
   904     // after the next editing session starts. See MIDP specification.
       
   905     // See CMIDEdwin::SetInitialInputModeL
       
   906 
       
   907     iEdwinUtils.SetInitialInputModeL(
       
   908         aCharacterSubset,
       
   909         iConstraints,
       
   910         iInitialCurrentCase,
       
   911         iInitialCurrentInputMode,
       
   912         iInitialCurrentLanguage);
       
   913 
       
   914     // Set permitted case modes for edwin in lowercase or uppercase mode.
       
   915     if (aCharacterSubset.Compare(KMidpUppercaseLatin) == 0 ||
       
   916             aCharacterSubset.Compare(KMidpLowercaseLatin) == 0)
       
   917     {
       
   918         DEBUG("CMIDTextEditorEdwin::SetInitialInputModeL, latin");
       
   919 
       
   920         // MIDP_UPPERCASE_LATIN or MIDP_LOWERCASE_LATIN are ignored if
       
   921         // INITIAL_CAPS_SENTENCE or INITIAL_CAPS_WORD modifier in ANY.
       
   922         if (!(iConstraints & MMIDTextField::EInitialCapsWordSentence ||
       
   923                 iConstraints & MMIDTextField::EInitialCapsWord) ||
       
   924                 !IsConstraintSet(MMIDTextField::EAny))
       
   925         {
       
   926             // If initial input mode is uppercase or lowercase then permit
       
   927             // only explicit case mode changes, automatic changes are not
       
   928             // allowed.
       
   929             SetAknEditorPermittedCaseModes(
       
   930                 EAknEditorUpperCase | EAknEditorLowerCase);
       
   931         }
       
   932     }
       
   933     else
       
   934     {
       
   935         SetAknEditorPermittedCaseModes(EAknEditorAllCaseModes);
       
   936     }
       
   937 
       
   938     DEBUG("CMIDTextEditorEdwin::SetInitialInputModeL -");
       
   939 }
       
   940 
       
   941 // ---------------------------------------------------------------------------
       
   942 // CMIDTextEditorEdwin::RestoreDefaultInputState
       
   943 // (other items were commented in the header file)
       
   944 // ---------------------------------------------------------------------------
       
   945 //
       
   946 void CMIDTextEditorEdwin::RestoreDefaultInputState()
       
   947 {
       
   948     DEBUG("CMIDTextEditorEdwin::RestoreEdwinDefaultInputState +");
       
   949 
       
   950     // Restore the default input state. It is not possible to directly
       
   951     // call CAknEditorState object from CEikEdwin since it is currently
       
   952     // used internally only. The default state set here is the same
       
   953     // that is set when CAknEditorState is constructed. See
       
   954     // CAknEditorState::CAknEditorState in aknedsts.cpp for details.
       
   955 
       
   956     SetAknEditorCase(EAknEditorTextCase);
       
   957     SetAknEditorPermittedCaseModes(EAknEditorAllCaseModes);
       
   958     SetAknEditorFlags(EAknEditorFlagDefault);
       
   959     SetAknEditorSpecialCharacterTable(KErrNotFound);
       
   960     SetAknEditorInputMode(EAknEditorTextInputMode);
       
   961     SetAknEditorAllowedInputModes(EAknEditorAllInputModes);
       
   962     SetAknEditorCurrentInputMode(EAknEditorTextInputMode);
       
   963     SetAknEditorCurrentCase(EAknEditorTextCase);
       
   964     SetAknEditorNumericKeymap(EAknEditorAlphanumericNumberModeKeymap);
       
   965     SetAknEditorLocalLanguage(
       
   966         CAknEnv::Static()->SettingCache().InputLanguage());
       
   967 
       
   968     // Enable SCT in other than numeric editors. Note that asterisk toggles
       
   969     // the minus character so the SCT must not be enabled because of that.
       
   970     if (!IsConstraintSet(MMIDTextField::ENumeric))
       
   971     {
       
   972         CAknExtendedInputCapabilities* caps = AknInputCaps();
       
   973         if (caps)
       
   974         {
       
   975             DEBUG("CMIDTextEditorEdwin::RestoreEdwinDefaultInputState,\
       
   976  disable SCT");
       
   977 
       
   978             caps->SetCapabilities(
       
   979                 caps->Capabilities() &
       
   980                 ~CAknExtendedInputCapabilities::EDisableSCT);
       
   981         }
       
   982     }
       
   983 
       
   984     // Reset initial input mode also.
       
   985     iInitialCurrentCase = 0;
       
   986     iInitialCurrentInputMode = 0;
       
   987     iInitialCurrentLanguage = ELangTest;
       
   988 
       
   989     DEBUG("CMIDTextEditorEdwin::RestoreEdwinDefaultInputState -");
       
   990 }
       
   991 
       
   992 // ---------------------------------------------------------------------------
       
   993 // CMIDTextEditorEdwin::SetCursorPosL
       
   994 // (other items were commented in the header file)
       
   995 // ---------------------------------------------------------------------------
       
   996 //
       
   997 void CMIDTextEditorEdwin::SetCursorPosL(
       
   998     TInt aCursorPosition,
       
   999     TBool aSelect)
       
  1000 {
       
  1001     DEBUG_INT("CMIDTextEditorEdwin::SetCursorPosL +, aCursorPosition=%d",
       
  1002               aCursorPosition);
       
  1003 
       
  1004     // Set cursor if the editor has a valid parent.
       
  1005     if (IsInitialized())
       
  1006     {
       
  1007         CEikEdwin::SetCursorPosL(aCursorPosition, aSelect);
       
  1008     }
       
  1009     // Do not deliver event if the position actually does not change.
       
  1010     else if (CursorPos() != aCursorPosition)
       
  1011     {
       
  1012         // Event has to be delivered to the registered observer
       
  1013         // even if the editor window has not been initialized.
       
  1014         ReportEdwinEventL(MEikEdwinObserver::EEventNavigation);
       
  1015     }
       
  1016 
       
  1017     if (aSelect)
       
  1018     {
       
  1019         // CEikEdwin does not store selection if not initialized.
       
  1020         // Store it in order to avoid errors when setting selection
       
  1021         // before parent is stored.
       
  1022         iSelection.SetSelection(iCursorPosition, aCursorPosition);
       
  1023     }
       
  1024     else // Clear selection.
       
  1025     {
       
  1026         iSelection.SetSelection(0, 0);
       
  1027     }
       
  1028 
       
  1029     // Editor window does not know the position yet because it has not
       
  1030     // been activated. Store the position to a member variable. Note that
       
  1031     // this must be set when the editor is activated.
       
  1032     // Cursor needs to be stored all the time because change of the
       
  1033     // parent object may cause the cursor to be changed in CEikEdwin.
       
  1034     iCursorPosition = aCursorPosition;
       
  1035 
       
  1036     DEBUG("CMIDTextEditorEdwin::SetCursorPosL -");
       
  1037 }
       
  1038 
       
  1039 // ---------------------------------------------------------------------------
       
  1040 // CMIDTextEditorEdwin::CursorPos
       
  1041 // (other items are commented in the header file)
       
  1042 // ---------------------------------------------------------------------------
       
  1043 //
       
  1044 TInt CMIDTextEditorEdwin::CursorPos() const
       
  1045 {
       
  1046     DEBUG("CMIDTextEditorEdwin::CursorPos +");
       
  1047 
       
  1048     // The control may have not been initialized yet (i.e. SetParentL has
       
  1049     // not been called). Do not get cursor position in that case because
       
  1050     // it crashes due to missing text view in the CEikEdwin.
       
  1051     TInt cursorPosition(
       
  1052         (IsInitialized() ? CEikEdwin::CursorPos() : iCursorPosition));
       
  1053 
       
  1054     DEBUG_INT("CMIDTextEditorEdwin::CursorPos -, cursorPosition=%d",
       
  1055               cursorPosition);
       
  1056 
       
  1057     return cursorPosition;
       
  1058 }
       
  1059 
       
  1060 // ---------------------------------------------------------------------------
       
  1061 // CMIDTextEditorEdwin::Selection
       
  1062 // (other items were commented in the header file)
       
  1063 // ---------------------------------------------------------------------------
       
  1064 //
       
  1065 TCursorSelection CMIDTextEditorEdwin::Selection()
       
  1066 {
       
  1067     DEBUG("CMIDTextEditorEdwin::Selection +");
       
  1068 
       
  1069     TCursorSelection selection(iSelection);
       
  1070 
       
  1071     // Selection is not returned correctly if the editor has not been
       
  1072     // initialized.
       
  1073     if (IsInitialized())
       
  1074     {
       
  1075         selection = CEikEdwin::Selection();
       
  1076     }
       
  1077 
       
  1078     DEBUG("CMIDTextEditorEdwin::Selection -");
       
  1079 
       
  1080     return selection;
       
  1081 }
       
  1082 
       
  1083 // ---------------------------------------------------------------------------
       
  1084 // CMIDTextEditorEdwin::SetWordWrapL
       
  1085 // (other items were commented in the header file)
       
  1086 // ---------------------------------------------------------------------------
       
  1087 //
       
  1088 void CMIDTextEditorEdwin::SetWordWrapL(TBool aWrapIsOn)
       
  1089 {
       
  1090     DEBUG_INT("CMIDTextEditorEdwin::SetWordWrapL +, aWrapIsOn=%d",
       
  1091               aWrapIsOn);
       
  1092 
       
  1093     // CEikEdwin crashes when setting word wrap before it
       
  1094     // has a valid container window. Multiline state is set
       
  1095     // in InitializeL() method again when called.
       
  1096     if (IsInitialized())
       
  1097     {
       
  1098         CEikEdwin::SetWordWrapL(aWrapIsOn);
       
  1099 
       
  1100         // Apply line and paragraph breaks.
       
  1101         if (!aWrapIsOn)
       
  1102         {
       
  1103             AddFlagToUserFlags(CEikEdwin::ENoLineOrParaBreaks);
       
  1104         }
       
  1105         else
       
  1106         {
       
  1107             RemoveFlagFromUserFlags(CEikEdwin::ENoLineOrParaBreaks);
       
  1108         }
       
  1109     }
       
  1110 
       
  1111     iMultiline = aWrapIsOn;
       
  1112 
       
  1113     DEBUG("CMIDTextEditorEdwin::SetCursorPosL -");
       
  1114 }
       
  1115 
       
  1116 // ---------------------------------------------------------------------------
       
  1117 // CMIDTextEditorEdwin::IsWrapEnabled
       
  1118 // (other items were commented in the header file)
       
  1119 // ---------------------------------------------------------------------------
       
  1120 //
       
  1121 TBool CMIDTextEditorEdwin::IsWrapEnabled() const
       
  1122 {
       
  1123     return iMultiline;
       
  1124 }
       
  1125 
       
  1126 // ---------------------------------------------------------------------------
       
  1127 // CMIDTextEditorEdwin::SetSize
       
  1128 // (other items were commented in the header file)
       
  1129 // ---------------------------------------------------------------------------
       
  1130 //
       
  1131 void CMIDTextEditorEdwin::SetSize(TInt aWidth, TInt aHeight)
       
  1132 {
       
  1133     DEBUG("CMIDTextEditorEdwin::SetSize +");
       
  1134 
       
  1135     // Set the width of the editor window. Note that EWidthInPixels is set
       
  1136     // so this method uses the parameter as pixels instead of chars.
       
  1137     CalculateWidth(aWidth);
       
  1138     // Set minimum and maximum height to the same value.
       
  1139     SetMinimumHeight(aHeight);
       
  1140     SetMaximumHeight(aHeight);
       
  1141 
       
  1142     TSize size(aWidth, aHeight);
       
  1143     // Set size of the UI control if container has been set. Otherwise
       
  1144     // this will panic the editor window at some point.
       
  1145     if (IsInitialized())
       
  1146     {
       
  1147         CCoeControl::SetSize(size);
       
  1148     }
       
  1149 
       
  1150     // Store the size for later use when set parent has been called.
       
  1151     iSize = size;
       
  1152 
       
  1153     DEBUG("CMIDTextEditorEdwin::SetSize -");
       
  1154 }
       
  1155 
       
  1156 // ---------------------------------------------------------------------------
       
  1157 // CMIDTextEditorEdwin::Size
       
  1158 // (other items were commented in the header file)
       
  1159 // ---------------------------------------------------------------------------
       
  1160 //
       
  1161 TSize CMIDTextEditorEdwin::Size() const
       
  1162 {
       
  1163     DEBUG("CMIDTextEditorEdwin::Size +");
       
  1164 
       
  1165     TSize size(iSize);
       
  1166 
       
  1167     // Check if editor has been initialized.
       
  1168     if (IsInitialized())
       
  1169     {
       
  1170         size = CCoeControl::Size();
       
  1171     }
       
  1172 
       
  1173     DEBUG("CMIDTextEditorEdwin::Size -");
       
  1174 
       
  1175     return size;
       
  1176 }
       
  1177 
       
  1178 // ---------------------------------------------------------------------------
       
  1179 // CMIDTextEditorEdwin::IsInitialized
       
  1180 // (other items were commented in the header file)
       
  1181 // ---------------------------------------------------------------------------
       
  1182 //
       
  1183 TBool CMIDTextEditorEdwin::IsInitialized() const
       
  1184 {
       
  1185     DEBUG_INT("CMIDTextEditorEdwin::IsInitialized, iInitialized=%d",
       
  1186               iInitialized);
       
  1187 
       
  1188     // Currently, the text editor is considered as constructed when the text
       
  1189     // view has been created and the editor window has been activated.
       
  1190     return iInitialized;
       
  1191 }
       
  1192 
       
  1193 // ---------------------------------------------------------------------------
       
  1194 // CMIDTextEditorEdwin::InitializeL
       
  1195 // (other items were commented in the header file)
       
  1196 // ---------------------------------------------------------------------------
       
  1197 //
       
  1198 void CMIDTextEditorEdwin::InitializeL()
       
  1199 {
       
  1200     DEBUG("CMIDTextEditorEdwin::InitializeL +");
       
  1201 
       
  1202     if (!iInitialized)
       
  1203     {
       
  1204         CreateTextViewL();
       
  1205         ActivateL();
       
  1206 
       
  1207         // Set colors here in order to avoid crash when parent
       
  1208         // has not been set by CMIDTextEditor.
       
  1209         SetBackgroundColorL(iBackgroundColor);
       
  1210         iTextView->SetBackgroundColor(iBackgroundColor);
       
  1211 
       
  1212         // Set selection set before initialization.
       
  1213         CEikEdwin::SetCursorPosL(iCursorPosition, EFalse);
       
  1214 
       
  1215         // Selection overrides cursor's position
       
  1216         if (iSelection.Length() > 0)
       
  1217         {
       
  1218             CEikEdwin::SetCursorPosL(iSelection.LowerPos(), EFalse);
       
  1219             CEikEdwin::SetCursorPosL(iSelection.HigherPos(), ETrue);
       
  1220         }
       
  1221 
       
  1222         // By default, editor is unfocused and not visible. Note
       
  1223         // that hide and show cannot be called before set parent.
       
  1224         SetFocus(EFalse);
       
  1225         MakeVisible(EFalse);
       
  1226         // Apply current size.
       
  1227         CCoeControl::SetSize(iSize);
       
  1228         iInitialized = true;
       
  1229         // Apply current multiline status. iInitialized must be true here.
       
  1230         SetWordWrapL(iMultiline);
       
  1231     }
       
  1232 
       
  1233     DEBUG("CMIDTextEditorEdwin::InitializeL -");
       
  1234 }
       
  1235 
       
  1236 // ---------------------------------------------------------------------------
       
  1237 // CMIDTextEditorEdwin::Uninitialize
       
  1238 // (other items were commented in the header file)
       
  1239 // ---------------------------------------------------------------------------
       
  1240 //
       
  1241 void CMIDTextEditorEdwin::Uninitialize()
       
  1242 {
       
  1243     DEBUG("CMIDTextEditorEdwin::Uninitialize +");
       
  1244 
       
  1245     if (iInitialized)
       
  1246     {
       
  1247         // Remove focus and hide the editor.
       
  1248         SetFocus(EFalse);
       
  1249         MakeVisible(EFalse);
       
  1250         // Store cursor's current position.
       
  1251         iCursorPosition = CEikEdwin::CursorPos();
       
  1252 
       
  1253         iInitialized = false;
       
  1254         iParent = NULL;
       
  1255     }
       
  1256 
       
  1257     DEBUG("CMIDTextEditorEdwin::Uninitialize -");
       
  1258 }
       
  1259 
       
  1260 // ---------------------------------------------------------------------------
       
  1261 // CMIDTextEditorEdwin::EditorWindowHeight
       
  1262 // (other items were commented in the header file)
       
  1263 // ---------------------------------------------------------------------------
       
  1264 //
       
  1265 TInt CMIDTextEditorEdwin::EditorWindowHeight() const
       
  1266 {
       
  1267     DEBUG("CMIDTextEditorEdwin::EditorWindowHeight +");
       
  1268 
       
  1269     TInt minimumHeight = iSize.iHeight;
       
  1270     if (iNumberOfLines == 0)
       
  1271     {
       
  1272         if (MinimumHeight() > 0)
       
  1273         {
       
  1274             minimumHeight = MinimumHeight();
       
  1275         }
       
  1276     }
       
  1277     else
       
  1278     {
       
  1279         minimumHeight = (LineHeight() * iNumberOfLines)
       
  1280                         + iBorder.SizeDelta().iHeight
       
  1281                         + iMargins.iTop
       
  1282                         + iMargins.iBottom;
       
  1283     }
       
  1284 
       
  1285     DEBUG_INT("CMIDTextEditorEdwin::EditorWindowHeight - , height=%d",
       
  1286               minimumHeight);
       
  1287 
       
  1288     return minimumHeight;
       
  1289 }
       
  1290 
       
  1291 // ---------------------------------------------------------------------------
       
  1292 // CMIDTextEditorEdwin::NumberOfLines
       
  1293 // (other items were commented in the header file)
       
  1294 // ---------------------------------------------------------------------------
       
  1295 //
       
  1296 TInt CMIDTextEditorEdwin::NumberOfLines() const
       
  1297 {
       
  1298     __ASSERT_DEBUG(iLayout, User::Invariant());
       
  1299 
       
  1300     return iLayout->NumFormattedLines();
       
  1301 }
       
  1302 
       
  1303 // ---------------------------------------------------------------------------
       
  1304 // CMIDTextEditorEdwin::LineHeight
       
  1305 // (other items were commented in the header file)
       
  1306 // ---------------------------------------------------------------------------
       
  1307 //
       
  1308 TInt CMIDTextEditorEdwin::LineHeight() const
       
  1309 {
       
  1310     __ASSERT_DEBUG(iLayout, User::Invariant());
       
  1311 
       
  1312     TInt lineHeight = iLayout->FormattedHeightInPixels();
       
  1313     const TInt docLength = iLayout->DocumentLength();
       
  1314     if (docLength > 0)
       
  1315     {
       
  1316         const TInt numFormattedLines = iLayout->NumFormattedLines();
       
  1317         lineHeight = lineHeight / numFormattedLines;
       
  1318     }
       
  1319 
       
  1320     return lineHeight;
       
  1321 }
       
  1322 
       
  1323 // ---------------------------------------------------------------------------
       
  1324 // CMIDTextEditorEdwin::VisibleContentPosition
       
  1325 // (other items were commented in the header file)
       
  1326 // ---------------------------------------------------------------------------
       
  1327 //
       
  1328 TInt CMIDTextEditorEdwin::VisibleContentPosition() const
       
  1329 {
       
  1330     DEBUG("CMIDTextEditorEdwin::VisibleContentPosition +");
       
  1331 
       
  1332     __ASSERT_DEBUG(iLayout, User::Invariant());
       
  1333 
       
  1334     DEBUG_INT("CMIDTextEditorEdwin::VisibleContentPosition -, pos=%d",
       
  1335               iLayout->PixelsAboveBand());
       
  1336 
       
  1337     return iLayout->PixelsAboveBand();
       
  1338 }
       
  1339 
       
  1340 // ---------------------------------------------------------------------------
       
  1341 // CMIDTextEditorEdwin::Read
       
  1342 // (other items were commented in the header file)
       
  1343 // ---------------------------------------------------------------------------
       
  1344 //
       
  1345 const TPtrC CMIDTextEditorEdwin::Read() const
       
  1346 {
       
  1347     if (iConstraints & MMIDTextField::EPassword)
       
  1348     {
       
  1349         return static_cast< CPasswordBoxGlobalText* >(iText)->ClearText();
       
  1350     }
       
  1351 
       
  1352     return iText->Read(0, TextLength());
       
  1353 }
       
  1354 
       
  1355 // ---------------------------------------------------------------------------
       
  1356 // CMIDTextEditorEdwin::MopSupplyObject
       
  1357 // (other items were commented in the header file)
       
  1358 // ---------------------------------------------------------------------------
       
  1359 //
       
  1360 TTypeUid::Ptr CMIDTextEditorEdwin::MopSupplyObject(TTypeUid aId)
       
  1361 {
       
  1362     // Try supplying custom indicator.
       
  1363     TTypeUid::Ptr id((
       
  1364                          iIndicator ? iIndicator->SupplyIndicatorMopObject(aId)
       
  1365                          : TTypeUid::Null()));
       
  1366 
       
  1367     // Indicator was not supplied. Try supplying from CEikEdwin.
       
  1368     if (!(id.Pointer()))
       
  1369     {
       
  1370         return CEikEdwin::MopSupplyObject(aId);
       
  1371     }
       
  1372 
       
  1373     return id;
       
  1374 }
       
  1375 
       
  1376 // ---------------------------------------------------------------------------
       
  1377 // CMIDTextEditorEdwin::SetDocumentContentL
       
  1378 // (other items were commented in the header file)
       
  1379 // ---------------------------------------------------------------------------
       
  1380 //
       
  1381 void CMIDTextEditorEdwin::SetDocumentContentL(CGlobalText* aText)
       
  1382 {
       
  1383     DEBUG("CMIDTextEditorEdwin::SetDocumentContentL +");
       
  1384 
       
  1385     // Even though the method takes a reference in it, the ownership
       
  1386     // is still transferred to CEikEdwin. And current iText is simply
       
  1387     // left ignored. Store it locally and delete after successful
       
  1388     // operation
       
  1389     CPlainText* temp = iText;
       
  1390     TRAPD(err, CEikEdwin::SetDocumentContentL(
       
  1391               *aText, CEikEdwin::EUseText));
       
  1392 
       
  1393     if (err != KErrNone)
       
  1394     {
       
  1395         // Failed but the ownership was transferred... State has been changed
       
  1396         // but we avoid leaking any memory at this point which is better.
       
  1397         // Restore the text back. This is not bulletproof, but leaves
       
  1398         // the text state as it was before trying to set the new text.
       
  1399         delete iText;
       
  1400         iText = temp;
       
  1401         User::Leave(err);
       
  1402     }
       
  1403 
       
  1404     // Everything went fine. Delete the old iText.
       
  1405     delete temp;
       
  1406 
       
  1407     DEBUG("CMIDTextEditorEdwin::SetDocumentContentL -");
       
  1408 }
       
  1409 
       
  1410 // ---------------------------------------------------------------------------
       
  1411 // CMIDTextEditorEdwin::AknInputCaps
       
  1412 // (other items were commented in the header file)
       
  1413 // ---------------------------------------------------------------------------
       
  1414 //
       
  1415 CAknExtendedInputCapabilities* CMIDTextEditorEdwin::AknInputCaps() const
       
  1416 {
       
  1417     CAknExtendedInputCapabilities* caps = NULL;
       
  1418 
       
  1419     TCoeInputCapabilities inputCapabilities = InputCapabilities();
       
  1420     if (inputCapabilities != TCoeInputCapabilities::ENone)
       
  1421     {
       
  1422         DEBUG("CMIDTextEditorEdwin::AknInputCaps, editor has input caps");
       
  1423 
       
  1424         // Get input capabilities object provider.
       
  1425         MObjectProvider* provider = inputCapabilities.ObjectProvider();
       
  1426         if (provider)
       
  1427         {
       
  1428             DEBUG(
       
  1429                 "CMIDTextEditorEdwin::AknInputCaps, object provider found");
       
  1430 
       
  1431             // MopGetObjects needs a reference to a pointer to an object
       
  1432             // of a type that is to be retrieved. NULL is OK here.
       
  1433             caps = provider->MopGetObject(caps);
       
  1434         }
       
  1435     }
       
  1436 
       
  1437     return caps;
       
  1438 }
       
  1439 
       
  1440 // ---------------------------------------------------------------------------
       
  1441 // CMIDTextEditorEdwin::RemoveInvalidNumericContentL
       
  1442 // (other items were commented in the header file)
       
  1443 // ---------------------------------------------------------------------------
       
  1444 //
       
  1445 TBool CMIDTextEditorEdwin::RemoveInvalidNumericContentL()
       
  1446 {
       
  1447     DEBUG("CMIDTextEditorEdwin::RemoveInvalidNumericContentL +");
       
  1448 
       
  1449     TBool textChanged = EFalse;
       
  1450     TPtrC content = Read();
       
  1451 
       
  1452     // Handle content change in numeric and decimal editors if the
       
  1453     // content is not valid for the given set of constraints.
       
  1454     if (!iEdwinUtils.ConstraintsValidForText(content, iConstraints, ETrue))
       
  1455     {
       
  1456         DEBUG("CMIDTextEditorEdwin::RemoveInvalidNumericContentL, \
       
  1457 content not valid");
       
  1458 
       
  1459         TLocale locale;
       
  1460         TChar decimal(locale.DecimalSeparator());
       
  1461         TChar minus(KCharMinus);
       
  1462 
       
  1463         TInt cursorPos = CursorPos();
       
  1464         TInt minusPos = content.Locate(minus);
       
  1465         TInt decimalPos = content.Locate(decimal);
       
  1466 
       
  1467         // Validate that minus character has been entered correctly
       
  1468         // First cases in which there is only minus and separator.
       
  1469         if (content.Length() == 1 &&
       
  1470                 ((decimalPos == 0) || (minusPos == 0)))
       
  1471         {
       
  1472             iText->DeleteL(0, 1);
       
  1473             cursorPos = 0;
       
  1474         }
       
  1475         else if (content.Length() == 2 &&
       
  1476                  ((minusPos == 0) && (decimalPos == 1)))
       
  1477         {
       
  1478             iText->DeleteL(0, 2);
       
  1479             cursorPos = 0;
       
  1480         }
       
  1481         else
       
  1482         {
       
  1483             // Other cases. Minus and decimal somewhere in the content.
       
  1484             if (minusPos != KErrNotFound)
       
  1485             {
       
  1486                 // The first is valid. Remove all other minus chars.
       
  1487                 minusPos = content.LocateReverse(minus);
       
  1488                 while (minusPos != 0 && minusPos != KErrNotFound)
       
  1489                 {
       
  1490                     iText->DeleteL(minusPos, 1);
       
  1491                     minusPos = content.LocateReverse(minus);
       
  1492                     cursorPos--;
       
  1493                 }
       
  1494             }
       
  1495 
       
  1496             // Decimal position may have changed.
       
  1497             decimalPos = content.Locate(decimal);
       
  1498 
       
  1499             if (decimalPos != KErrNotFound)
       
  1500             {
       
  1501                 // The first is valid. Remove all other separators.
       
  1502                 TInt secondPos = content.LocateReverse(decimal);
       
  1503                 while (secondPos != decimalPos)
       
  1504                 {
       
  1505                     iText->DeleteL(secondPos, 1);
       
  1506                     secondPos = content.LocateReverse(decimal);
       
  1507                     cursorPos--;
       
  1508                 }
       
  1509             }
       
  1510         }
       
  1511 
       
  1512         // Do not report event again so call base class' method.
       
  1513         CEikEdwin::HandleTextChangedL();
       
  1514         // Restore cursor's original position.
       
  1515         SetCursorPosL(cursorPos, EFalse);
       
  1516         textChanged = ETrue;
       
  1517     }
       
  1518 
       
  1519     DEBUG_INT(
       
  1520         "CMIDTextEditorEdwin::RemoveInvalidNumericContentL -, textChanged=%d",
       
  1521         textChanged);
       
  1522 
       
  1523     return textChanged;
       
  1524 }
       
  1525 
       
  1526 // End of file