textinput/peninputvkbcn/ctrlsrc/peninputvkbcompositionfield.cpp
changeset 0 eb1f2e154e89
child 12 5e18d8c489d6
equal deleted inserted replaced
-1:000000000000 0:eb1f2e154e89
       
     1 /*
       
     2 * Copyright (c) 2002-2005 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 * Description:  vkb conposition field implementation
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <peninputlayoutbasecontrol.h>
       
    20 
       
    21 #include <AknsDrawUtils.h> 
       
    22 #include <barsread.h>
       
    23 
       
    24 #include "peninputvkbcompositionfield.h"
       
    25 
       
    26 #include "peninputvkbevent.h"
       
    27 
       
    28 #include "peninputvkb.hrh"
       
    29 
       
    30 #include "peninputvkbdataprovider.h"
       
    31 
       
    32 #include "AknFepVkbPinyinAnalyser.h"
       
    33 
       
    34 #include "AknFepVkbPinyinAnalyserDb.h"
       
    35 #include "peninputvkbdatamgr.h"
       
    36 
       
    37 //Tone make
       
    38 const TUint16 KCharToneMarkZhuyin1 = 0x0020;
       
    39 const TUint16 KCharToneMarkPinyin1 = 0x02C9;
       
    40 const TUint16 KCharToneMark2 = 0x02CA;
       
    41 const TUint16 KCharToneMark3 = 0x02C7;
       
    42 const TUint16 KCharToneMark4 = 0x02CB;
       
    43 const TUint16 KCharToneMark5 = 0x02D9;
       
    44 
       
    45 const TInt32 KInvalidResId = -1;
       
    46 
       
    47 const TInt KInvalidImg = -1 ;
       
    48 
       
    49 //Manual stroke separator char
       
    50 const TUint16 KStrokeManuSeparator = 0x2022;
       
    51 //Manul separator char       
       
    52 const TUint KManulSeparator = 0x0027; // "'"
       
    53 //Manul separator char       
       
    54 const TUint KAutoSeparator = 0x002e;   //"."
       
    55 
       
    56 
       
    57 _LIT(KWildChar, "\xFF1F");
       
    58 
       
    59 _LIT(KInternalWildChar, "\x002B");
       
    60 
       
    61 // ---------------------------------------------------------
       
    62 // Helper function
       
    63 // ---------------------------------------------------------
       
    64 //
       
    65 //Don't test aKey's length, treat as programming error!
       
    66 inline TBool IsKeyToneMark(const TDesC& aKey)
       
    67     {
       
    68     return   (aKey[0] == KCharToneMarkZhuyin1 ||
       
    69               aKey[0] == KCharToneMarkPinyin1 ||
       
    70               aKey[0] == KCharToneMark2 ||
       
    71               aKey[0] == KCharToneMark3 ||
       
    72               aKey[0] == KCharToneMark4 ||
       
    73               aKey[0] == KCharToneMark5 );
       
    74     }
       
    75     
       
    76 inline TBool IsKeyAutoSeparator(const TDesC& aKey)
       
    77     {
       
    78     return (aKey[0] == KAutoSeparator );
       
    79     }
       
    80 
       
    81 inline TBool IsKeyManualSeparator(const TDesC& aKey)
       
    82     {
       
    83     return (aKey[0] == KManulSeparator || aKey[0] == KStrokeManuSeparator);
       
    84     }
       
    85     
       
    86 inline TBool IsKeyInternalWildChar(const TDesC& aKey)
       
    87     {
       
    88     return (aKey[0] == KInternalWildChar()[0] );
       
    89     }
       
    90 
       
    91 
       
    92     
       
    93 // ---------------------------------------------------------
       
    94 // Constructor
       
    95 // ---------------------------------------------------------
       
    96 //
       
    97 CCompositionElement* CCompositionElement::NewLC(const TDesC& aKey)
       
    98     {
       
    99     TInt keyType = EElementTypeCompositionChar;   
       
   100     if( IsKeyAutoSeparator(aKey) )
       
   101         {
       
   102         keyType = EElementTypeAutoSeparator;
       
   103         }
       
   104     else if( IsKeyManualSeparator(aKey) )
       
   105         {
       
   106         keyType = EElementTypeManualSeparator;
       
   107         }
       
   108     else if( IsKeyToneMark(aKey) )
       
   109         {
       
   110         keyType = EElementTypeTonemark;
       
   111         }
       
   112 
       
   113     CCompositionElement* self = new (ELeave) CCompositionElement(keyType);
       
   114     
       
   115     CleanupStack::PushL(self);
       
   116 
       
   117     if( IsKeyInternalWildChar(aKey) )
       
   118         {
       
   119         self->BaseConstructL(KWildChar);
       
   120         }
       
   121     else
       
   122         {
       
   123         self->BaseConstructL(aKey);
       
   124         }
       
   125     
       
   126     
       
   127     return self;
       
   128     }
       
   129 
       
   130 // ---------------------------------------------------------
       
   131 // Constructor
       
   132 // ---------------------------------------------------------
       
   133 //
       
   134 CCompositionElement::CCompositionElement(TInt aKeyType)
       
   135 :iKeyType(aKeyType)
       
   136     {
       
   137     }
       
   138     
       
   139 // ---------------------------------------------------------
       
   140 // Constructor
       
   141 // ---------------------------------------------------------
       
   142 //
       
   143 void CCompositionElement::BaseConstructL(const TDesC& aKey)
       
   144     {
       
   145     iKey = aKey.AllocL();
       
   146     }
       
   147     
       
   148 // ---------------------------------------------------------
       
   149 // Destructor
       
   150 // ---------------------------------------------------------
       
   151 //
       
   152 CCompositionElement::~CCompositionElement()
       
   153     {
       
   154     delete iKey;
       
   155     }
       
   156 
       
   157 // ---------------------------------------------------------
       
   158 // Get original input length
       
   159 // ---------------------------------------------------------
       
   160 //
       
   161 TInt CCompositionElement::OriginalCount() const
       
   162     {
       
   163     TInt result = (IsAutoSeparator() || !iKey)? 0 : iKey->Length();
       
   164     
       
   165     return result;
       
   166     }
       
   167     
       
   168 // ---------------------------------------------------------
       
   169 // UnConvert and insert the original elements back
       
   170 // ---------------------------------------------------------
       
   171 //
       
   172 TInt CCompositionElement::UndoConvertL(CAknFepVkbCompositionField* /*aField*/, TInt /*aStartPos*/)
       
   173     {
       
   174     return 0;
       
   175     }
       
   176 
       
   177 // ---------------------------------------------------------
       
   178 // Get the content  of original input
       
   179 // ---------------------------------------------------------
       
   180 //
       
   181 const CCompositionElement* CCompositionElement::OriginalContent( TInt /*aIndex*/ ) const
       
   182     {
       
   183     return NULL;
       
   184     }
       
   185 
       
   186 // ---------------------------------------------------------
       
   187 // Constructor
       
   188 // ---------------------------------------------------------
       
   189 //
       
   190 CCompositionConvertedElement* CCompositionConvertedElement::NewLC(const TDesC& aKey)
       
   191     {
       
   192     CCompositionConvertedElement* self = new (ELeave) CCompositionConvertedElement();
       
   193     
       
   194     CleanupStack::PushL(self);
       
   195     self->ConstructL(aKey);
       
   196     
       
   197     return self;
       
   198     }
       
   199 
       
   200 // ---------------------------------------------------------
       
   201 // Constructor
       
   202 // ---------------------------------------------------------
       
   203 //
       
   204 CCompositionConvertedElement::CCompositionConvertedElement()
       
   205 :CCompositionElement(EElementTypeConvertedChar)
       
   206     {
       
   207     }
       
   208     
       
   209 // ---------------------------------------------------------
       
   210 // Constructor
       
   211 // ---------------------------------------------------------
       
   212 //
       
   213 void CCompositionConvertedElement::ConstructL(const TDesC& aKey)
       
   214     {
       
   215     BaseConstructL(aKey);
       
   216     }
       
   217 
       
   218 // ---------------------------------------------------------
       
   219 // Destructor
       
   220 // ---------------------------------------------------------
       
   221 //
       
   222 CCompositionConvertedElement::~CCompositionConvertedElement()
       
   223     {
       
   224     iOriginalElements.ResetAndDestroy();
       
   225     iOriginalElements.Close();
       
   226     }
       
   227 
       
   228 // ---------------------------------------------------------
       
   229 // UnConvert and insert the original elements back
       
   230 // ---------------------------------------------------------
       
   231 //
       
   232 TInt CCompositionConvertedElement::UndoConvertL(CAknFepVkbCompositionField* aField, 
       
   233                                                TInt aStartPos)
       
   234     {
       
   235     ASSERT(aStartPos >=0 && aStartPos < aField->Length());
       
   236     
       
   237     TInt length = iOriginalElements.Count();
       
   238     
       
   239     for (TInt i = length -1 ; i >= 0 ; i --)
       
   240         {
       
   241         aField->InsertL(aStartPos, iOriginalElements[i] );
       
   242         
       
   243         //ownership transfer to CAknFepVkbCompositionField
       
   244         iOriginalElements.Remove(i);
       
   245         }
       
   246         
       
   247     return length;
       
   248     }
       
   249 
       
   250 // ---------------------------------------------------------
       
   251 // Append an original element
       
   252 // ---------------------------------------------------------
       
   253 //
       
   254 void CCompositionConvertedElement::AppendOriginal(const CCompositionElement* aElements)
       
   255     {
       
   256     iOriginalElements.Append(aElements);
       
   257     }
       
   258 
       
   259 // ---------------------------------------------------------
       
   260 // Get original input length
       
   261 // ---------------------------------------------------------
       
   262 //
       
   263 TInt CCompositionConvertedElement::OriginalCount() const
       
   264     {
       
   265     return iOriginalElements.Count();
       
   266     }
       
   267     
       
   268 // ---------------------------------------------------------
       
   269 // Get the content  of original input
       
   270 // ---------------------------------------------------------
       
   271 //
       
   272 const CCompositionElement* CCompositionConvertedElement::OriginalContent( TInt aIndex ) const
       
   273     {
       
   274     if( aIndex < 0 || aIndex > iOriginalElements.Count() - 1 )
       
   275         {
       
   276         return NULL;
       
   277         }
       
   278     return iOriginalElements[aIndex];
       
   279     }
       
   280     
       
   281 // ---------------------------------------------------------
       
   282 // Constructor
       
   283 // ---------------------------------------------------------
       
   284 //
       
   285 CAknFepVkbCompositionField* CAknFepVkbCompositionField::NewL(TInt aMaxLength,
       
   286                                                             TRect aRect,
       
   287                                                             CFepUiLayout* aUiLayout,
       
   288                                                             TInt aControlId,
       
   289                                                             MAknFepVkbDataProvider* aDataProvider )
       
   290     {
       
   291     CAknFepVkbCompositionField* self = new (ELeave) CAknFepVkbCompositionField(aMaxLength,
       
   292                                                                               aRect,
       
   293                                                                               aUiLayout,
       
   294                                                                               aControlId,
       
   295                                                                               aDataProvider );
       
   296     
       
   297     CleanupStack::PushL(self);
       
   298     self->ConstructL();
       
   299     CleanupStack::Pop(self);
       
   300     
       
   301     return self;
       
   302     }
       
   303 
       
   304 // ---------------------------------------------------------
       
   305 // C++ Constructor
       
   306 // ---------------------------------------------------------
       
   307 //
       
   308 CAknFepVkbCompositionField::CAknFepVkbCompositionField(TInt aMaxLength,
       
   309                                                       TRect aRect,
       
   310                                                       CFepUiLayout* aUiLayout,
       
   311                                                       TInt aControlId,
       
   312                                                       MAknFepVkbDataProvider* aDataProvider)
       
   313 : CFepLayoutEditAreaBase(aRect,aUiLayout,aControlId)
       
   314     {
       
   315     //iMaxLength <=0 means no max length limited
       
   316     iMaxLength = aMaxLength;
       
   317     iCurrentPos = 0;
       
   318     iFirstSegment = NULL;
       
   319     iDataProvider = aDataProvider;
       
   320     
       
   321     iIsValidSpells = EFalse;
       
   322 
       
   323     }
       
   324 
       
   325 // ---------------------------------------------------------
       
   326 // 2nd Constructor
       
   327 // ---------------------------------------------------------
       
   328 //
       
   329 void CAknFepVkbCompositionField::ConstructL()
       
   330     {
       
   331     //No cursor in construction
       
   332     BaseConstructL();
       
   333     //iBufferForCommit = HBufC::NewL(KDefaultLen);
       
   334  
       
   335     
       
   336     CPinyinAnalyserDbFeed* pZhuyinDb = CPinyinAnalyserDbFeed::NewL( EPinyinAnalyserTypeZhuyin );
       
   337     CleanupStack::PushL( pZhuyinDb );
       
   338     iZhuyinAnalyser = CAknFepVkbPinyinAnalyser::NewL( pZhuyinDb );
       
   339     CleanupStack::Pop( pZhuyinDb );
       
   340     
       
   341     CPinyinAnalyserDbFeed* pPinyinDb = CPinyinAnalyserDbFeed::NewL( EPinyinAnalyserTypePinyin );
       
   342     CleanupStack::PushL( pPinyinDb );
       
   343     iPinyinAnalyser = CAknFepVkbPinyinAnalyser::NewL( pPinyinDb );
       
   344     CleanupStack::Pop( pPinyinDb );
       
   345     
       
   346     
       
   347     }
       
   348 
       
   349 // ---------------------------------------------------------
       
   350 // Destructor
       
   351 // ---------------------------------------------------------
       
   352 //
       
   353 CAknFepVkbCompositionField::~CAknFepVkbCompositionField()
       
   354     {
       
   355     iElements.ResetAndDestroy();
       
   356     iElements.Close();
       
   357     //delete iBufferForCommit;
       
   358     delete iFirstSegment;
       
   359     delete iZhuyinAnalyser;
       
   360     delete iPinyinAnalyser;
       
   361     }
       
   362 
       
   363 // ---------------------------------------------------------
       
   364 // Handle events in
       
   365 // ---------------------------------------------------------
       
   366 //
       
   367 void CAknFepVkbCompositionField::HandleControlEvent(TInt aEventType, 
       
   368                                                              CFepUiBaseCtrl* /*aCtrl*/, 
       
   369                                                              const TDesC& aEventData)
       
   370     {
       
   371     TBuf<4> buf;    
       
   372     switch (aEventType)
       
   373         {
       
   374         case EEventVirtualKeyUp:
       
   375             {
       
   376             TKeyEvent* event = (TKeyEvent*) aEventData.Ptr();
       
   377             buf.Append(TChar(event->iScanCode));	
       
   378             //assume keys are insertable
       
   379             TRAP_IGNORE(HandleInsertL(buf));
       
   380             break;
       
   381             }
       
   382         case EVkbEventKeySpace:
       
   383             {
       
   384             TInt imLayout = iDataProvider->RequestData(EAknFepDataTypeIMLayout);
       
   385             if (imLayout == EAknFepVkbImCnCangjie)
       
   386                 {
       
   387                 if(!IsValidSpell())
       
   388                     {
       
   389                     break;
       
   390                     }
       
   391                 
       
   392                 RBuf firstCandidate(static_cast<CAknFepVkbDataMgr*>(iDataProvider)->Candidates()[0]); 
       
   393                 firstCandidate.AppendNum( 0 );
       
   394                 TRAP_IGNORE(HandleConvertedResultL(firstCandidate));
       
   395                 }
       
   396             else
       
   397                 {
       
   398                 TKeyEvent* event = (TKeyEvent*) aEventData.Ptr();
       
   399                 buf.Append(TChar(event->iCode));	
       
   400                 //assume keys are insertable
       
   401                 TRAP_IGNORE(HandleInsertL(buf));
       
   402                 }
       
   403             break;
       
   404             }        
       
   405         case EVkbEventKeyEnter:
       
   406             TRAP_IGNORE(HandleFlushL());        
       
   407             break;
       
   408         case EPeninputLayoutEventBack:
       
   409             TRAP_IGNORE(HandleBackL());
       
   410             break;
       
   411 		case EVkbEventLeftArrow:
       
   412 			{
       
   413 		    TCursorSelection currentCursorSelection;
       
   414 		    currentCursorSelection = Selection();
       
   415 		    
       
   416 		    if (ETrue)
       
   417 		        {
       
   418 	            if (currentCursorSelection.iCursorPos == 0)
       
   419 	                {
       
   420 	                currentCursorSelection.iCursorPos = TextLength();
       
   421 	                }
       
   422 	            else 
       
   423 	                {
       
   424 	                currentCursorSelection.iCursorPos--;
       
   425 	                if(currentCursorSelection.iCursorPos > 0 &&
       
   426 						iElements[currentCursorSelection.iCursorPos - 1]->IsAutoSeparator())
       
   427 	                    {
       
   428 	                    currentCursorSelection.iCursorPos--;		                
       
   429 		                }
       
   430 	                }
       
   431 		        }
       
   432 		        
       
   433 		    TCursorSelection movedCursor(currentCursorSelection.iCursorPos, 
       
   434                                      currentCursorSelection.iCursorPos);
       
   435 		    UpdateCursorSelection(movedCursor);
       
   436 		    break;
       
   437 			}
       
   438 		case EVkbEventRightArrow:
       
   439 			{
       
   440 			TCursorSelection currentCursorSelection;
       
   441 			currentCursorSelection = Selection();
       
   442 
       
   443 		    if (currentCursorSelection.iCursorPos == TextLength())
       
   444 		        {
       
   445 		        currentCursorSelection.iCursorPos = 0;
       
   446 		        }
       
   447 		    else 
       
   448 		        {
       
   449 		        currentCursorSelection.iCursorPos++;
       
   450 				if(currentCursorSelection.iCursorPos < TextLength() &&
       
   451 					iElements[currentCursorSelection.iCursorPos - 1]->IsAutoSeparator())
       
   452                   {
       
   453                   currentCursorSelection.iCursorPos++;
       
   454                   }
       
   455 		        
       
   456 		        }	        
       
   457 
       
   458 			TCursorSelection movedCursor(currentCursorSelection.iCursorPos, 
       
   459                                    currentCursorSelection.iCursorPos);
       
   460 			UpdateCursorSelection(movedCursor);
       
   461 			break;
       
   462 			}
       
   463         case EEventControlFocusLost:
       
   464             SetFocus(EFalse);
       
   465             break;
       
   466         case EEventControlFocusGained:
       
   467             SetFocus();
       
   468             break;
       
   469         case EVkbEventCompFieldAnalysisResponse:
       
   470             TRAP_IGNORE(HandleAnalysisResponseL(aEventData));
       
   471             break;
       
   472         case EVkbEventCandidateSelected:
       
   473             TRAP_IGNORE(HandleConvertedResultL(aEventData));
       
   474             break;
       
   475         case EVkbEventWindowClose:
       
   476         case EVkbEventClearContent:
       
   477             TRAP_IGNORE(ClearTextL());
       
   478             break;
       
   479         default:
       
   480             break;
       
   481         }
       
   482     }
       
   483 
       
   484 // ---------------------------------------------------------
       
   485 // Count of elements
       
   486 // ---------------------------------------------------------
       
   487 //
       
   488 TInt CAknFepVkbCompositionField::Length() const
       
   489     {
       
   490     return iElements.Count();
       
   491     }
       
   492 
       
   493 // ---------------------------------------------------------
       
   494 // Set warning color
       
   495 // ---------------------------------------------------------
       
   496 //
       
   497 void CAknFepVkbCompositionField::SetWarningColor(const TRgb& aColor) 
       
   498     {
       
   499     iWarningColor = aColor;
       
   500     }
       
   501     
       
   502 // ---------------------------------------------------------
       
   503 // Set normal color
       
   504 // ---------------------------------------------------------
       
   505 //
       
   506 void CAknFepVkbCompositionField::SetNormalColor(const TRgb& aColor) 
       
   507     {
       
   508     iNormalColor = aColor;
       
   509     }    
       
   510 
       
   511 // ---------------------------------------------------------
       
   512 // Insert a key
       
   513 // ---------------------------------------------------------
       
   514 //
       
   515 void CAknFepVkbCompositionField::HandleInsertL(const TDesC& aKey)
       
   516     {
       
   517     CCompositionElement *element = CCompositionElement::NewLC(aKey);
       
   518     
       
   519     iCurrentPos = DisplayPosToInternaPos( iSelectedCompositionText.iCursorPos );              
       
   520     
       
   521     TBool updateText = EFalse;  
       
   522     //remove selection first
       
   523     if( iSelectedCompositionText.Length() > 0)
       
   524         {
       
   525         RemoveSelection();
       
   526         updateText = ETrue;
       
   527         }
       
   528         
       
   529     if (IsAllowedInsert(element))
       
   530         {
       
   531         InsertElementL(element);
       
   532         CleanupStack::Pop(element);
       
   533         SendAnalysisRequestL();
       
   534         updateText = EFalse;
       
   535         }
       
   536     else
       
   537         {
       
   538         // If select all the chars in composition and input an invalid char,
       
   539         // go to standby status.
       
   540         if(Length() == 0)
       
   541             {
       
   542             ReportEvent(EVkbEventCompFieldNoChars);
       
   543             ClearTextL();
       
   544             }
       
   545         else
       
   546             {
       
   547             SendAnalysisRequestL();
       
   548             }
       
   549             
       
   550         CleanupStack::PopAndDestroy(element);
       
   551         }
       
   552         
       
   553     if( updateText )
       
   554         {
       
   555         UpdateTextL();
       
   556         }
       
   557     }
       
   558 
       
   559 // ---------------------------------------------------------
       
   560 // Insert an element
       
   561 // ---------------------------------------------------------
       
   562 //
       
   563 //insert is only insert 
       
   564 void CAknFepVkbCompositionField::InsertElementL(const CCompositionElement* aElement)
       
   565     {
       
   566     if( IsReplaceFront(aElement) )
       
   567         {
       
   568         Remove(iCurrentPos - 1, 1);        
       
   569         }
       
   570     else if( IsReplaceBack(aElement) )
       
   571         {
       
   572         Remove(iCurrentPos, 1);        
       
   573         }      
       
   574 
       
   575     InsertL(iCurrentPos, aElement);  
       
   576     }
       
   577     
       
   578 // ---------------------------------------------------------
       
   579 // Clear text
       
   580 // ---------------------------------------------------------
       
   581 //
       
   582 void CAknFepVkbCompositionField::ClearTextL()
       
   583     {
       
   584     Clear();
       
   585     
       
   586     UpdateTextL();
       
   587     
       
   588     iNeedCreateWord = EFalse;
       
   589     iConvertedElement = 0;
       
   590     iIsValidSpells = ETrue;
       
   591     }
       
   592 
       
   593 // ---------------------------------------------------------
       
   594 // Submit all text
       
   595 // ---------------------------------------------------------
       
   596 //
       
   597 void CAknFepVkbCompositionField::HandleFlushL()
       
   598     {
       
   599     // Don't response when CangJieVkb state
       
   600     if ( iDataProvider->RequestData( EAknFepDataTypeIMLayout )  == EAknFepVkbImCnCangjie )
       
   601         {
       
   602         return;
       
   603         }
       
   604     
       
   605     HBufC* temp = HBufC::NewLC(iElements.Count());
       
   606     TPtr ptr = temp->Des();
       
   607     
       
   608     for (TInt i = 0; i < iElements.Count(); i++)
       
   609         {
       
   610         if (!iElements[i]->IsTypeOf(EElementTypeAutoSeparator))
       
   611             {
       
   612             ptr.Append(*iElements[i]->Key());
       
   613             }
       
   614         }
       
   615         
       
   616     if (ptr.Length() > 0)
       
   617         {
       
   618         ReportEvent(EVkbEventCompFieldDataFlush, *temp);
       
   619         ClearTextL();
       
   620         }
       
   621         
       
   622     CleanupStack::PopAndDestroy(temp);
       
   623     }
       
   624     
       
   625 // ---------------------------------------------------------
       
   626 // Handle back key
       
   627 // ---------------------------------------------------------
       
   628 //
       
   629 void CAknFepVkbCompositionField::HandleBackL()
       
   630     {
       
   631     if (Length() == 0)
       
   632         {
       
   633         return;
       
   634         }
       
   635     
       
   636     iCurrentPos = DisplayPosToInternaPos( iSelectedCompositionText.iCursorPos );
       
   637     
       
   638     if(iSelectedCompositionText.Length() > 0)
       
   639         {
       
   640         // update cursor position
       
   641         RemoveSelection();
       
   642         }
       
   643     else
       
   644         {
       
   645         TInt pos = iCurrentPos - 1;
       
   646         if ( iCurrentPos == 0 )
       
   647             {//nothing to delete
       
   648             return;
       
   649             }
       
   650             
       
   651         //assure the element before cursor is not an auto separator
       
   652         //cursor can not be put right after an auto separator
       
   653         ASSERT(!iElements[pos]->IsAutoSeparator());
       
   654 
       
   655         if (!iElements[pos]->IsTypeOf(EElementTypeConvertedChar))
       
   656             {
       
   657             Remove(pos, 1, ETrue);
       
   658             ReFomatAfterDelete();
       
   659             }
       
   660         else
       
   661             {
       
   662             //current element is converted element, undo convert 
       
   663             TInt len = iElements[pos]->UndoConvertL(this, pos);
       
   664             iCurrentPos -= ( len + 1 );
       
   665             if ( iCurrentPos < 0 )
       
   666                 {
       
   667                 iCurrentPos = 0;
       
   668                 }
       
   669             //remove the converted element
       
   670             Remove(pos + len, 1);
       
   671             iConvertedElement--;
       
   672             if( iConvertedElement == 0 && iNeedCreateWord)
       
   673                 {
       
   674                 iNeedCreateWord = EFalse;
       
   675                 }
       
   676             }
       
   677         }
       
   678 
       
   679     if (Length() == 0)
       
   680         {
       
   681         ReportEvent(EVkbEventCompFieldNoChars);
       
   682         ClearTextL();
       
   683         }
       
   684     else
       
   685         {
       
   686         //no composition to analysis
       
   687         if (IsFinishComposition())
       
   688             {
       
   689             UpdateTextL();
       
   690             ReportEvent(EVkbEventCompFieldSubmit, iDisplayText);
       
   691             ClearTextL();
       
   692             }
       
   693         else
       
   694             {
       
   695             SendAnalysisRequestL();
       
   696             }
       
   697         }
       
   698     }
       
   699     
       
   700 // ---------------------------------------------------------
       
   701 // Handle analysis response
       
   702 // ---------------------------------------------------------
       
   703 //
       
   704 void CAknFepVkbCompositionField::HandleAnalysisResponseL(const TDesC& aCompText)
       
   705     {
       
   706     
       
   707     if ( ( iDataProvider->RequestData( EAknFepDataTypeIMLayout )  == EAknFepVkbImCnZhuyin
       
   708         || iDataProvider->RequestData( EAknFepDataTypeIMLayout )  == EAknFepVkbImCnPinyin ) )
       
   709     {
       
   710     if( iIsValidSpells )
       
   711         {
       
   712         SetTextColor(iNormalColor);
       
   713         }
       
   714     else
       
   715         {
       
   716         SetTextColor(iWarningColor);    
       
   717         }
       
   718     }
       
   719             
       
   720     if ( iDataProvider->RequestData( EAknFepDataTypeIMLayout )  == EAknFepVkbImCnCangjie
       
   721         || iDataProvider->RequestData( EAknFepDataTypeIMLayout )  == EAknFepVkbImCnStroke )
       
   722     {
       
   723     if ( aCompText.Length() == 0 )
       
   724         {
       
   725         iIsValidSpells  = EFalse;
       
   726         SetTextColor(iWarningColor);
       
   727         }
       
   728     else
       
   729         {
       
   730         iIsValidSpells  = ETrue;
       
   731         SetTextColor(iNormalColor);
       
   732         }
       
   733 
       
   734     }
       
   735             
       
   736     if (aCompText.Length() > 0)
       
   737         {
       
   738         //merge the original elements with engine returned strings
       
   739         //remove auto separator in orignal elements and insert auto separator
       
   740         //add by engine 
       
   741         TInt origin = iFirstSegmentOffset;
       
   742         TInt engine = 0;
       
   743         while( engine < aCompText.Length() && origin < iElements.Count() )
       
   744             {
       
   745             if( *(iElements[origin]) == aCompText[engine] )
       
   746                 {
       
   747                 origin++;
       
   748                 engine++;
       
   749                 }
       
   750             else if( iElements[origin]->IsAutoSeparator() )
       
   751                 {
       
   752                 Remove(origin, 1);
       
   753                 iFirstSegmentLength--;
       
   754                 }
       
   755             else if( IsKeyAutoSeparator(aCompText.Mid(engine,1)) )
       
   756                 {
       
   757                 if( !iElements[origin]->IsManualSeparator() )
       
   758                     {
       
   759                 	CCompositionElement* element = 
       
   760                                              CCompositionElement::NewLC(aCompText.Mid(engine, 1));
       
   761                     InsertL(origin, element);
       
   762                     CleanupStack::Pop(element);
       
   763                     iFirstSegmentLength++;
       
   764                     }
       
   765                 origin++;
       
   766                 engine++;
       
   767                 }
       
   768             else
       
   769                 {
       
   770                 ASSERT(0);                
       
   771                 }
       
   772             }
       
   773         //judge if invalid tone mark exist in iElements
       
   774         if(aCompText.Length() < iElements.Count() - iFirstSegmentOffset)
       
   775             {
       
   776             if(origin <= iElements.Count() - 1 && iElements[origin]->IsTonemark())
       
   777                 {
       
   778                 iIsValidSpells  = EFalse;
       
   779                 SetTextColor(iWarningColor);                
       
   780                 }
       
   781             }
       
   782         }
       
   783 
       
   784     UpdateTextL();
       
   785     Draw();
       
   786     UpdateArea(Rect(),EFalse);
       
   787     }
       
   788     
       
   789 // ---------------------------------------------------------
       
   790 // Handle converted result
       
   791 // ---------------------------------------------------------
       
   792 //
       
   793 void CAknFepVkbCompositionField::HandleConvertedResultL(const TDesC& aConvertedText)
       
   794     {
       
   795     TInt index = iFirstSegmentOffset;
       
   796     
       
   797     //the last aConvertedText is the cell No of candidate list
       
   798     for (TInt i = 0; i < aConvertedText.Length() - 1; i ++)
       
   799         {
       
   800         CCompositionConvertedElement* element = 
       
   801                                      CCompositionConvertedElement::NewLC(aConvertedText.Mid(i, 1));
       
   802         
       
   803         TBool goOn = ETrue;
       
   804                 
       
   805         while (index < Length() && !iElements[index]->IsTypeOf(EElementTypeConvertedChar) && goOn)
       
   806             {
       
   807             goOn = !iElements[index]->IsAuxilian();
       
   808             
       
   809             if( iElements[index]->IsAutoSeparator() )
       
   810                 {
       
   811                 Remove(index, 1); //remove automatic separator
       
   812                 }
       
   813             else
       
   814                 {
       
   815                 element->AppendOriginal(iElements[index]); //transfer ownership to converted element                    
       
   816                 Remove(index, 1, EFalse); //remove the original element
       
   817                 }
       
   818             }
       
   819 
       
   820         //insert the converted element
       
   821         InsertL(index, element);
       
   822         iCurrentPos = index + 1;
       
   823         iConvertedElement++;
       
   824         
       
   825         CleanupStack::Pop(element);
       
   826         index ++;
       
   827         }
       
   828 
       
   829     if( IsFinishComposition() )
       
   830         {
       
   831         UpdateTextL();
       
   832         ReportEvent(EVkbEventCompFieldSubmit, *iBuffer);
       
   833         ClearTextL();
       
   834         }
       
   835     else
       
   836         {
       
   837         //user takes part in composition
       
   838         iNeedCreateWord = ETrue;
       
   839         SendAnalysisRequestL();
       
   840         }
       
   841     }
       
   842     
       
   843 // ---------------------------------------------------------
       
   844 // Is there need to create new word
       
   845 // ---------------------------------------------------------
       
   846 //
       
   847 TBool CAknFepVkbCompositionField::NeedCreateWord()
       
   848 	{
       
   849 	return iNeedCreateWord && iElements.Count() <= KCpiMaxInputPhraseLen;
       
   850 	}
       
   851     
       
   852 // ---------------------------------------------------------
       
   853 // Remove elements
       
   854 // ---------------------------------------------------------
       
   855 //
       
   856 void CAknFepVkbCompositionField::Remove(TInt aStartPos, TInt aLength, TBool aDestroy)
       
   857     {
       
   858     ASSERT (aStartPos >= 0 && aStartPos < Length());
       
   859         
       
   860     TInt index = Min(aStartPos + aLength - 1, Length() -1);
       
   861 
       
   862     //adjust cursor position if necessary
       
   863     if( iCurrentPos > aStartPos)
       
   864         {
       
   865         iCurrentPos -= index - aStartPos + 1;    
       
   866         }
       
   867             
       
   868     for (TInt i = index; i >= aStartPos; i --)    
       
   869         {
       
   870         if (aDestroy)
       
   871             {
       
   872             delete iElements[i];
       
   873             }
       
   874             
       
   875         iElements.Remove(i);
       
   876         }          
       
   877     }
       
   878 
       
   879 // ---------------------------------------------------------
       
   880 // Insert an element
       
   881 // ---------------------------------------------------------
       
   882 //
       
   883 void CAknFepVkbCompositionField::InsertL(TInt aPos, const CCompositionElement* aElement)
       
   884     {
       
   885     ASSERT (aPos >=0 && aPos <= Length());
       
   886     iElements.Insert(aElement, aPos);    
       
   887     if( iCurrentPos >= aPos )
       
   888         {
       
   889         iCurrentPos ++;
       
   890         }
       
   891     }
       
   892 
       
   893 // ---------------------------------------------------------
       
   894 // Clear element
       
   895 // ---------------------------------------------------------
       
   896 //
       
   897 void CAknFepVkbCompositionField::Clear()
       
   898     {
       
   899     if (Length() == 0)
       
   900         {
       
   901         return;
       
   902         }
       
   903     
       
   904     iCurrentPos = 0;
       
   905     iElements.ResetAndDestroy();
       
   906     }
       
   907         
       
   908 // ---------------------------------------------------------
       
   909 // Generate first segment
       
   910 // ---------------------------------------------------------
       
   911 //
       
   912 void CAknFepVkbCompositionField::GetFirstSegmentL()
       
   913     {    
       
   914     delete iFirstSegment;
       
   915     iFirstSegment = NULL;
       
   916     iFirstSegment = HBufC::NewL(Length());
       
   917     TPtr ptr = iFirstSegment->Des();
       
   918 
       
   919     iFirstSegmentOffset = 0;
       
   920     iFirstSegmentLength = 0;
       
   921     
       
   922     TInt i = 0;
       
   923     for (i = 0; i < Length(); i++)
       
   924         {
       
   925         //start from the first unconverted element
       
   926         if (!iElements[i]->IsTypeOf(EElementTypeConvertedChar) &&
       
   927             !iElements[i]->IsSeparator() )
       
   928             {
       
   929             iFirstSegmentOffset = i;
       
   930             ptr.Append((*iElements[i++]->Key()));
       
   931             iFirstSegmentLength++;
       
   932             while( i < Length() && !iElements[i]->IsTypeOf(EElementTypeConvertedChar)  )
       
   933                 {
       
   934                 if( !iElements[i]->IsAutoSeparator() )
       
   935                     {
       
   936                     ptr.Append(*(iElements[i]->Key()));
       
   937                     }
       
   938                     
       
   939                 i++;
       
   940                 }
       
   941             
       
   942             break;
       
   943             }
       
   944         }
       
   945     
       
   946     iFirstSegmentLength = i - iFirstSegmentOffset;
       
   947     if( ptr.Length() > 0 && 
       
   948         IsKeyManualSeparator(ptr.Right(1)) )
       
   949         {
       
   950         ptr.SetLength(ptr.Length() - 1);
       
   951         iFirstSegmentLength--;
       
   952         }
       
   953     }
       
   954 
       
   955 // ---------------------------------------------------------
       
   956 // Update editbase cursor and text
       
   957 // ---------------------------------------------------------
       
   958 // assume the current all elements are valid
       
   959 void CAknFepVkbCompositionField::UpdateTextL()
       
   960     {
       
   961     HBufC* displayText = HBufC::NewLC(iElements.Count());
       
   962     //adjust cursor to avoid autosepartor
       
   963     if( iCurrentPos > 0 && iElements[iCurrentPos - 1]->IsAutoSeparator() )
       
   964         {
       
   965         iCurrentPos--;
       
   966         }
       
   967         
       
   968     TInt pos = iCurrentPos;
       
   969     for( TInt i = 0; i < iElements.Count(); ++i )
       
   970         {
       
   971         //deal with manual separator 
       
   972         if( iElements[i]->IsManualSeparator() )
       
   973             {
       
   974             //valid format ensure i > 0
       
   975             if( iElements[i - 1]->IsTypeOf(EElementTypeConvertedChar))
       
   976                 {
       
   977                 iElements[i]->Hide(ETrue);
       
   978                 }
       
   979             else if( i + 1 < iElements.Count() && 
       
   980                      iElements[i + 1]->IsTypeOf(EElementTypeConvertedChar) )
       
   981                 {
       
   982                 iElements[i]->Hide(ETrue);
       
   983                 }
       
   984             else
       
   985                 {
       
   986                 iElements[i]->Hide(EFalse);
       
   987                 }
       
   988             }
       
   989         //maybe other things
       
   990         if(iElements[i]->IsVisible())
       
   991             {
       
   992                 {
       
   993                 displayText->Des().Append(iElements[i]->Key()->Left(1));
       
   994                 }
       
   995             }
       
   996         else if( i < iCurrentPos)
       
   997             {
       
   998             pos--;
       
   999             }
       
  1000         }
       
  1001     
       
  1002     TFepInputContextFieldData data;
       
  1003     data.iCmd = EPeninputICFInitial;
       
  1004     data.iStartPos = 0;
       
  1005     data.iLength = displayText->Length();
       
  1006     data.iMidPos = -1;
       
  1007     data.iText.Set( *displayText );
       
  1008     data.iCurSel = TCursorSelection(pos, pos);
       
  1009     data.iCursorVisibility = ETrue;
       
  1010     data.iCursorSelVisible = ETrue;
       
  1011     SetTextL( data );
       
  1012     
       
  1013     CleanupStack::PopAndDestroy(displayText);
       
  1014     }
       
  1015 
       
  1016 // ---------------------------------------------------------
       
  1017 // Adjust cursor when pen down
       
  1018 // ---------------------------------------------------------
       
  1019 //
       
  1020 void CAknFepVkbCompositionField::AdjustSelectedCompositionText(
       
  1021                                               TInt& aPositionOfInsertionPointInBuffer)
       
  1022     {
       
  1023     TInt pos = DisplayPosToInternaPos(aPositionOfInsertionPointInBuffer);
       
  1024     pos--;
       
  1025     if (pos >=0 && pos < Length() && iElements[pos]->IsAutoSeparator())
       
  1026         {
       
  1027         aPositionOfInsertionPointInBuffer --;
       
  1028         }
       
  1029 
       
  1030     if (aPositionOfInsertionPointInBuffer < 0)
       
  1031         {
       
  1032         aPositionOfInsertionPointInBuffer = 0;
       
  1033         }
       
  1034     }
       
  1035     
       
  1036 // ---------------------------------------------------------
       
  1037 // Update edit base content when scrolling
       
  1038 // ---------------------------------------------------------
       
  1039 //
       
  1040 void CAknFepVkbCompositionField::UpdateContent(const TCursorSelection& aCursorSel)
       
  1041     {
       
  1042     TInt cursorPos = aCursorSel.iCursorPos;
       
  1043     if (cursorPos < 0 )
       
  1044         {
       
  1045         cursorPos = 0;
       
  1046         }
       
  1047     else if (cursorPos > iBuffer->Length())
       
  1048         {
       
  1049         cursorPos = iBuffer->Length();
       
  1050         }
       
  1051         
       
  1052     UpdateCursorSelection(TCursorSelection(cursorPos, aCursorSel.iAnchorPos));
       
  1053     }
       
  1054     
       
  1055 // ---------------------------------------------------------
       
  1056 // Is allowed insert
       
  1057 // ---------------------------------------------------------
       
  1058 //
       
  1059 TBool CAknFepVkbCompositionField::IsAllowedInsert(const CCompositionElement* aElement)
       
  1060     {
       
  1061     if( (iCurrentPos == 0 ||
       
  1062          iElements[iCurrentPos - 1]->IsTypeOf(EElementTypeConvertedChar)) &&
       
  1063         aElement->IsAuxilian() )
       
  1064         {
       
  1065         return EFalse;
       
  1066         }
       
  1067     
       
  1068     if (aElement->IsManualSeparator())
       
  1069     	{
       
  1070     	//cursor must be larger than zero
       
  1071     	if (iElements[iCurrentPos - 1]->IsTonemark() ||
       
  1072     	    iElements[iCurrentPos - 1]->IsManualSeparator())
       
  1073     		{
       
  1074     		return EFalse;
       
  1075     		}    	
       
  1076     	if ( (iElements.Count() >= iCurrentPos + 1) && 
       
  1077     	     (iElements[iCurrentPos]->IsTonemark() ||
       
  1078     	      iElements[iCurrentPos]->IsTypeOf(EElementTypeConvertedChar) ||
       
  1079     	      iElements[iCurrentPos]->IsManualSeparator()) )
       
  1080     		{
       
  1081     		return EFalse;
       
  1082     		}
       
  1083     	}
       
  1084 
       
  1085     if ( IsReplaceFront(aElement) || 
       
  1086          IsReplaceBack(aElement))
       
  1087         {
       
  1088         return ETrue;
       
  1089         }
       
  1090         
       
  1091     TInt count = 0;    
       
  1092     for (TInt i = 0; i <Length(); i++)
       
  1093         {
       
  1094         count += iElements[i]->OriginalCount();
       
  1095         }
       
  1096         
       
  1097     return (count < iMaxLength);
       
  1098     }
       
  1099 
       
  1100 // ---------------------------------------------------------
       
  1101 // Send analysis request
       
  1102 // ---------------------------------------------------------
       
  1103 //
       
  1104 void CAknFepVkbCompositionField::SendAnalysisRequestL()
       
  1105     {
       
  1106     GetFirstSegmentL();
       
  1107     CAknFepVkbPinyinAnalyser* pAnalyser = NULL;
       
  1108     
       
  1109     if( iDataProvider->RequestData( EAknFepDataTypeIMLayout )  == EAknFepVkbImCnZhuyin )
       
  1110         {
       
  1111         pAnalyser = iZhuyinAnalyser;
       
  1112         }
       
  1113     else if ( iDataProvider->RequestData( EAknFepDataTypeIMLayout ) == EAknFepVkbImCnPinyin )
       
  1114         {
       
  1115         pAnalyser = iPinyinAnalyser;
       
  1116         }
       
  1117     
       
  1118     if ( pAnalyser )
       
  1119         {
       
  1120         iIsValidSpells = pAnalyser->AnalyzeL( *iFirstSegment );
       
  1121     
       
  1122         TPtrC compText( *pAnalyser->LastAnalysisResult() );
       
  1123         TInt origin = iFirstSegmentOffset;
       
  1124         TInt engine = 0;
       
  1125         while( engine < compText.Length() && origin < iElements.Count() )
       
  1126             {
       
  1127             if( *(iElements[origin]) == compText[engine] )
       
  1128                 {
       
  1129                 origin++;
       
  1130                 engine++;
       
  1131                 }
       
  1132             else if( iElements[origin]->IsAutoSeparator() )
       
  1133                 {
       
  1134                 Remove(origin, 1);
       
  1135                 iFirstSegmentLength--;
       
  1136                 }
       
  1137             else if( IsKeyAutoSeparator(compText.Mid(engine,1)) )
       
  1138                 {
       
  1139                 if( !iElements[origin]->IsManualSeparator() )
       
  1140                     {
       
  1141                 	CCompositionElement* element = CCompositionElement::NewLC(compText.Mid(engine, 1));
       
  1142                     InsertL(origin, element);
       
  1143                     CleanupStack::Pop(element);
       
  1144                     iFirstSegmentLength++;
       
  1145                     }
       
  1146                 origin++;
       
  1147                 engine++;
       
  1148                 }
       
  1149             else
       
  1150                 {
       
  1151                 ASSERT(0);                
       
  1152                 }
       
  1153         }
       
  1154         
       
  1155         ReportEvent(EVkbEventCompFieldAnalysisReq, *pAnalyser->LastAnalysisResult() );
       
  1156         }
       
  1157     else
       
  1158         {
       
  1159         ReportEvent(EVkbEventCompFieldAnalysisReq, *iFirstSegment);
       
  1160         }
       
  1161     }
       
  1162 
       
  1163 // ---------------------------------------------------------
       
  1164 // To test whether the all input keys are converted
       
  1165 // ---------------------------------------------------------
       
  1166 //
       
  1167 TBool CAknFepVkbCompositionField::IsFinishComposition()
       
  1168     {
       
  1169     for (TInt i = 0; i < Length(); i++)
       
  1170         {
       
  1171         if (!iElements[i]->IsTypeOf(EElementTypeConvertedChar))
       
  1172             {
       
  1173             return EFalse;
       
  1174             }
       
  1175         }
       
  1176         
       
  1177     return ETrue;        
       
  1178     }
       
  1179 
       
  1180 // ---------------------------------------------------------
       
  1181 // To test whether current pos element should be replaced by input one
       
  1182 // ---------------------------------------------------------
       
  1183 //
       
  1184 TBool CAknFepVkbCompositionField::IsReplacePosition(const CCompositionElement* aElement,
       
  1185                                                    TInt aPos)
       
  1186     {
       
  1187     if( aElement->IsTonemark() )
       
  1188         {
       
  1189         return iElements[aPos]->IsTonemark() || 
       
  1190                iElements[aPos]->IsSeparator();
       
  1191         }
       
  1192     else if(aElement->IsManualSeparator() )
       
  1193         {
       
  1194         return iElements[aPos]->IsAutoSeparator();
       
  1195         }
       
  1196     else
       
  1197         {
       
  1198         return EFalse;
       
  1199         }
       
  1200     }
       
  1201 
       
  1202 // ---------------------------------------------------------
       
  1203 // To test whether the one before current pos element should be replaced by input one
       
  1204 // ---------------------------------------------------------
       
  1205 //
       
  1206 TBool CAknFepVkbCompositionField::IsReplaceFront(const CCompositionElement* aElement)
       
  1207     {
       
  1208     if( iCurrentPos > 0 )
       
  1209         {
       
  1210         return IsReplacePosition(aElement, iCurrentPos - 1);
       
  1211         }
       
  1212         
       
  1213     return EFalse;
       
  1214     }
       
  1215     
       
  1216 // ---------------------------------------------------------
       
  1217 // To test whether current pos element should be replaced by input one
       
  1218 // ---------------------------------------------------------
       
  1219 //
       
  1220 TBool CAknFepVkbCompositionField::IsReplaceBack(const CCompositionElement* aElement)
       
  1221     {
       
  1222     if( iCurrentPos <= iElements.Count() - 1 )
       
  1223         {
       
  1224         return IsReplacePosition(aElement, iCurrentPos);
       
  1225         }
       
  1226         
       
  1227     return EFalse;
       
  1228     }
       
  1229 
       
  1230 // ---------------------------------------------------------
       
  1231 // Redo the format after deletion
       
  1232 // ---------------------------------------------------------
       
  1233 //
       
  1234 void CAknFepVkbCompositionField::ReFomatAfterDelete()
       
  1235     {
       
  1236 //assumption
       
  1237 //1. delete only happen in cursor position
       
  1238 //2. before deletion, the format is OK
       
  1239     if( iElements.Count() == 0 )
       
  1240         {
       
  1241         return;
       
  1242         }
       
  1243         
       
  1244     if( iCurrentPos == 0 )
       
  1245         {
       
  1246         if( iElements[0]->IsSeparator() || 
       
  1247             iElements[0]->IsTonemark())
       
  1248             {
       
  1249             Remove(0, 1, ETrue);
       
  1250             }
       
  1251         }
       
  1252     else if( iCurrentPos <= iElements.Count() - 1)
       
  1253         {
       
  1254         if(iElements[iCurrentPos - 1]->IsAuxilian() &&
       
  1255            iElements[iCurrentPos]->IsAuxilian() )
       
  1256             { //one of two is need to be removed
       
  1257             if(iElements[iCurrentPos]->IsTonemark() ||
       
  1258                iElements[iCurrentPos]->IsManualSeparator() )
       
  1259                 {//remove the one before cursor
       
  1260                 Remove(iCurrentPos - 1, 1, ETrue);
       
  1261                 //to simulate remove + insert opertion
       
  1262                 iCurrentPos++;
       
  1263                 }
       
  1264             else
       
  1265                 {//remove the one on the cursor        
       
  1266                 Remove(iCurrentPos, 1, ETrue);
       
  1267                 }
       
  1268             }
       
  1269         else if( iElements[iCurrentPos - 1]->IsAutoSeparator() &&
       
  1270                  iElements[iCurrentPos]->IsTypeOf(EElementTypeConvertedChar) )
       
  1271             {
       
  1272             //remove auto separator before convert char
       
  1273             Remove(iCurrentPos - 1, 1, ETrue);
       
  1274             }
       
  1275         else if( iElements[iCurrentPos]->IsAutoSeparator() &&
       
  1276                  iElements[iCurrentPos - 1]->IsTypeOf(EElementTypeConvertedChar) )
       
  1277             {
       
  1278             //remove auto separator before convert char
       
  1279             Remove(iCurrentPos, 1, ETrue);
       
  1280             }
       
  1281         }
       
  1282     else //if( iCurrentPos == iElements.Count() )
       
  1283         {
       
  1284         if( iElements[iCurrentPos - 1]->IsAutoSeparator() )
       
  1285             {
       
  1286             Remove(iCurrentPos - 1, 1);
       
  1287             }
       
  1288         }
       
  1289     }
       
  1290 
       
  1291 // ---------------------------------------------------------
       
  1292 // Get display cursor positon by internal cursor position
       
  1293 // ---------------------------------------------------------
       
  1294 //
       
  1295 TInt CAknFepVkbCompositionField::InternalPosToDisplayPos(TInt aInternalPos)
       
  1296     {
       
  1297     for(TInt i = 0; i < aInternalPos; i++)
       
  1298         {
       
  1299         if( !iElements[i]->IsVisible() )
       
  1300             {
       
  1301             aInternalPos--;
       
  1302             }
       
  1303         }
       
  1304     
       
  1305     return aInternalPos;
       
  1306     }
       
  1307 
       
  1308 // ---------------------------------------------------------
       
  1309 // Get internal cursor positon by display cursor position
       
  1310 // ---------------------------------------------------------
       
  1311 //
       
  1312 TInt CAknFepVkbCompositionField::DisplayPosToInternaPos(TInt aDisplayPos)
       
  1313     {
       
  1314     TInt pos = 0;
       
  1315     TInt i = 0;
       
  1316     
       
  1317     for( i = 0; i < iElements.Count() && pos < aDisplayPos; i++ )
       
  1318         {
       
  1319         if( iElements[i]->IsVisible() )
       
  1320             {
       
  1321             pos++;
       
  1322             }        
       
  1323         }
       
  1324     for( i++; i < iElements.Count(); i++ )
       
  1325         {
       
  1326         if( iElements[i]->IsVisible() )
       
  1327             {
       
  1328             break;
       
  1329             }
       
  1330         }
       
  1331     
       
  1332     return --i;
       
  1333     }
       
  1334 
       
  1335 // ---------------------------------------------------------
       
  1336 // Remove the selected text
       
  1337 // ---------------------------------------------------------
       
  1338 //
       
  1339 void CAknFepVkbCompositionField::RemoveSelection()
       
  1340     {
       
  1341     TInt lower = DisplayPosToInternaPos( iSelectedCompositionText.LowerPos() );
       
  1342     TInt upper = DisplayPosToInternaPos( iSelectedCompositionText.HigherPos() ); 
       
  1343     Remove(lower, upper - lower);    
       
  1344     ReFomatAfterDelete();    
       
  1345     }
       
  1346 
       
  1347 // ---------------------------------------------------------------------------
       
  1348 // CAknFepVkbCompositionField::GetCreatedWordSpell
       
  1349 // (other items were commented in a header)
       
  1350 // ---------------------------------------------------------------------------
       
  1351 //
       
  1352 const TInt KSpellSpace = 8; // private protocol for PtiCpiCore   
       
  1353 TPtrC CAknFepVkbCompositionField::GetCreatedWordSpell()
       
  1354     {
       
  1355     iCreateWordSpellBuffer.SetLength( 0 );
       
  1356     //TUint16 bufText[10] = {0};
       
  1357     //TUint16 bufSpell[100] = {0};    
       
  1358     
       
  1359     if( iNeedCreateWord )
       
  1360         {
       
  1361         //for()
       
  1362         iCreateWordSpellBuffer.SetLength( KSpellSpace * iElements.Count() );
       
  1363         iCreateWordSpellBuffer.FillZ();
       
  1364         for ( int i = 0; i < iElements.Count(); i++ )
       
  1365             {
       
  1366             //bufText[i] = ( *( iElements[i]->Key() ) )[0];
       
  1367 
       
  1368             TUint16 temp  = ( *( iElements[i]->Key() ) )[0];
       
  1369             iCreateWordSpellBuffer[KSpellSpace*i] = ( *( iElements[i]->Key() ) )[0];
       
  1370             for( int j=0; j < iElements[i]->OriginalCount(); j++ )
       
  1371                 {
       
  1372                 const CCompositionElement* element = iElements[i]->OriginalContent( j );
       
  1373                 if( element && !element->IsSeparator() )
       
  1374                     {
       
  1375                     //bufSpell[ i*KSpellSpace + j] = ( *( element->Key() ) )[0];
       
  1376                     iCreateWordSpellBuffer[KSpellSpace*i + j + 1] = ( *( element->Key() ) )[0];;
       
  1377                     }
       
  1378                 }
       
  1379             }
       
  1380         }
       
  1381     
       
  1382     return iCreateWordSpellBuffer;
       
  1383     }
       
  1384     
       
  1385 // ---------------------------------------------------------------------------
       
  1386 // CAknFepVkbCompositionField::IsValidSpell
       
  1387 // (other items were commented in a header)
       
  1388 // ---------------------------------------------------------------------------
       
  1389 //
       
  1390 TBool CAknFepVkbCompositionField::IsValidSpell()
       
  1391     {
       
  1392     // no just verify the Zhuyin & Pinyin spell, stoke&cangjie verify later
       
  1393     if (  iDataProvider->RequestData( EAknFepDataTypeIMLayout )  == EAknFepVkbImCnZhuyin
       
  1394         || iDataProvider->RequestData( EAknFepDataTypeIMLayout )  == EAknFepVkbImCnPinyin )
       
  1395             {
       
  1396             return iIsValidSpells;
       
  1397             }
       
  1398     if( ( iDataProvider->RequestData( EAknFepDataTypeIMLayout ) ==  EAknFepVkbImCnStroke
       
  1399         || iDataProvider->RequestData( EAknFepDataTypeIMLayout ) ==  EAknFepVkbImCnCangjie ) )
       
  1400         {
       
  1401         return iIsValidSpells;
       
  1402         }
       
  1403     return ETrue;
       
  1404     }
       
  1405     
       
  1406 void CAknFepVkbCompositionField::ConstructFromResourceL()
       
  1407     {    
       
  1408     if (iResourceId == KInvalidResId)
       
  1409     	{
       
  1410         User::Leave(KErrArgument);
       
  1411     	}
       
  1412 
       
  1413     TResourceReader reader;
       
  1414     CCoeEnv::Static()->CreateResourceReaderLC(reader, iResourceId);
       
  1415 
       
  1416 
       
  1417     TPtrC bmpFileName = reader.ReadTPtrC();  
       
  1418     TInt32 imgMajorSkinId = reader.ReadInt32();
       
  1419 
       
  1420     TAknsItemID id;
       
  1421     TInt skinitemid;
       
  1422     
       
  1423     MAknsSkinInstance* skininstance = AknsUtils::SkinInstance();
       
  1424 
       
  1425     const TInt16 compositionbgId = reader.ReadInt16();
       
  1426     const TInt16 compositionbgIdmaskId = reader.ReadInt16();
       
  1427     skinitemid = reader.ReadInt16();
       
  1428 
       
  1429     id.Set( TInt( imgMajorSkinId ), skinitemid );
       
  1430     
       
  1431     if ( compositionbgId != KInvalidImg )
       
  1432     	{
       
  1433         CFbsBitmap* compositionImg = NULL;
       
  1434 
       
  1435         if (compositionbgIdmaskId != KInvalidImg)
       
  1436             {
       
  1437             CFbsBitmap* compositionmaskImg = NULL;
       
  1438             
       
  1439             AknsUtils::CreateIconL(skininstance,
       
  1440                                    id,
       
  1441                                    compositionImg,
       
  1442                                    compositionmaskImg,
       
  1443                                    bmpFileName,
       
  1444                                    compositionbgId,
       
  1445                                    compositionbgIdmaskId);
       
  1446             
       
  1447             AknIconUtils::SetSize(compositionmaskImg, TSize(1,1), EAspectRatioNotPreserved);
       
  1448             SetBackgroundMaskBitmapL(compositionmaskImg);
       
  1449             }
       
  1450         else
       
  1451             {
       
  1452             AknsUtils::CreateIconL(skininstance,
       
  1453                                    id,
       
  1454                                    compositionImg,
       
  1455                                    bmpFileName,
       
  1456                                    compositionbgId);
       
  1457             }
       
  1458     	
       
  1459     	AknIconUtils::SetSize(compositionImg, TSize(1,1), EAspectRatioNotPreserved);
       
  1460     	SetBackgroundBitmapL(compositionImg);
       
  1461     	}
       
  1462 
       
  1463     CleanupStack::PopAndDestroy(); // reader
       
  1464     
       
  1465     }
       
  1466     
       
  1467 void CAknFepVkbCompositionField::SizeChanged(TRect aRect)
       
  1468 	{
       
  1469 	CFepLayoutEditAreaBase::SetRect(aRect);
       
  1470     if( BackgroundBmp() )
       
  1471         {
       
  1472         CFbsBitmap* bmp = BackgroundBmp();
       
  1473         if( aRect.Size() != bmp->SizeInPixels() )
       
  1474             {
       
  1475             AknIconUtils::SetSize(bmp, aRect.Size(), EAspectRatioNotPreserved);            
       
  1476             }
       
  1477         }
       
  1478 	}
       
  1479 // End Of File